1 /**
2   ******************************************************************************
3   * @file    stm32n6xx_hal_pssi.c
4   * @author  MCD Application Team
5   * @brief   PSSI HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Parallel Synchronous Slave Interface (PSSI) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + IO operation functions
10   *           + Peripheral State and Errors functions
11   *
12   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2023 STMicroelectronics.
16   * All rights reserved.
17   *
18   * This software is licensed under terms that can be found in the LICENSE file
19   * in the root directory of this software component.
20   * If no LICENSE file comes with this software, it is provided AS-IS.
21   *
22   ******************************************************************************
23   @verbatim
24   ==============================================================================
25                         ##### How to use this driver #####
26   ==============================================================================
27     [..]
28     The PSSI HAL driver can be used as follows:
29 
30     (#) Declare a PSSI_HandleTypeDef handle structure, for example:
31         PSSI_HandleTypeDef  hpssi;
32 
33     (#) Initialize the PSSI low level resources by implementing the @ref HAL_PSSI_MspInit() API:
34         (##) Enable the PSSIx interface clock
35         (##) PSSI pins configuration
36             (+++) Enable the clock for the PSSI GPIOs
37             (+++) Configure PSSI pins as alternate function open-drain
38         (##) NVIC configuration if you need to use interrupt process
39             (+++) Configure the PSSIx interrupt priority
40             (+++) Enable the NVIC PSSI IRQ Channel
41         (##) DMA Configuration if you need to use DMA process
42             (+++) Declare  DMA_HandleTypeDef handles structure for the transmit and receive
43             (+++) Enable the DMAx interface clock
44             (+++) Configure the DMA handle parameters
45             (+++) Configure the DMA Tx and Rx
46             (+++) Associate the initialized DMA handle to the hpssi DMA Tx and Rx handle
47             (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on
48                   the DMA Tx and Rx
49 
50     (#) Configure the Communication Bus Width,  Control Signals, Input Polarity and Output Polarity
51          in the hpssi Init structure.
52 
53     (#) Initialize the PSSI registers by calling the @ref HAL_PSSI_Init(), configure also the low level Hardware
54         (GPIO, CLOCK, NVIC...etc) by calling the customized @ref HAL_PSSI_MspInit(&hpssi) API.
55 
56     (#) Configure the PSSI clock as internal or external by calling the @ref HAL_PSSI_ClockConfig().
57 
58     (#) For PSSI IO operations, two operation modes are available within this driver :
59 
60     *** Polling mode IO operation ***
61     =================================
62     [..]
63       (+) Transmit an amount of data by byte in blocking mode using @ref HAL_PSSI_Transmit()
64       (+) Receive an amount of data by byte in blocking mode using @ref HAL_PSSI_Receive()
65 
66     *** DMA mode IO operation ***
67     ==============================
68     [..]
69       (+) Transmit an amount of data in non-blocking mode (DMA) using
70           @ref HAL_PSSI_Transmit_DMA()
71       (+) At transmission end of transfer, @ref HAL_PSSI_TxCpltCallback() is executed and user can
72            add his own code by customization of function pointer @ref HAL_PSSI_TxCpltCallback()
73       (+) Receive an amount of data in non-blocking mode (DMA) using
74           @ref HAL_PSSI_Receive_DMA()
75       (+) At reception end of transfer, @ref HAL_PSSI_RxCpltCallback() is executed and user can
76            add his own code by customization of function pointer @ref HAL_PSSI_RxCpltCallback()
77       (+) In case of transfer Error, @ref HAL_PSSI_ErrorCallback() function is executed and user can
78            add his own code by customization of function pointer @ref HAL_PSSI_ErrorCallback()
79       (+) Abort a  PSSI process communication with Interrupt using @ref HAL_PSSI_Abort_IT()
80       (+) End of abort process, @ref HAL_PSSI_AbortCpltCallback() is executed and user can
81            add his own code by customization of function pointer @ref HAL_PSSI_AbortCpltCallback()
82 
83      *** PSSI HAL driver macros list ***
84      ==================================
85      [..]
86        Below the list of most used macros in PSSI HAL driver.
87 
88       (+) @ref HAL_PSSI_ENABLE     : Enable the PSSI peripheral
89       (+) @ref HAL_PSSI_DISABLE    : Disable the PSSI peripheral
90       (+) @ref HAL_PSSI_GET_FLAG   : Check whether the specified PSSI flag is set or not
91       (+) @ref HAL_PSSI_CLEAR_FLAG : Clear the specified PSSI pending flag
92       (+) @ref HAL_PSSI_ENABLE_IT  : Enable the specified PSSI interrupt
93       (+) @ref HAL_PSSI_DISABLE_IT : Disable the specified PSSI interrupt
94 
95      *** Callback registration ***
96      =============================================
97      Use Functions @ref HAL_PSSI_RegisterCallback() or @ref HAL_PSSI_RegisterAddrCallback()
98      to register an interrupt callback.
99 
100      Function @ref HAL_PSSI_RegisterCallback() allows to register following callbacks:
101        (+) TxCpltCallback       : callback for transmission end of transfer.
102        (+) RxCpltCallback       : callback for reception end of transfer.
103        (+) ErrorCallback        : callback for error detection.
104        (+) AbortCpltCallback    : callback for abort completion process.
105        (+) MspInitCallback      : callback for Msp Init.
106        (+) MspDeInitCallback    : callback for Msp DeInit.
107      This function takes as parameters the HAL peripheral handle, the Callback ID
108      and a pointer to the user callback function.
109 
110 
111      Use function @ref HAL_PSSI_UnRegisterCallback to reset a callback to the default
112      weak function.
113      @ref HAL_PSSI_UnRegisterCallback takes as parameters the HAL peripheral handle,
114      and the Callback ID.
115      This function allows to reset following callbacks:
116        (+) TxCpltCallback       : callback for transmission end of transfer.
117        (+) RxCpltCallback       : callback for reception end of transfer.
118        (+) ErrorCallback        : callback for error detection.
119        (+) AbortCpltCallback    : callback for abort completion process.
120        (+) MspInitCallback      : callback for Msp Init.
121        (+) MspDeInitCallback    : callback for Msp DeInit.
122 
123 
124      By default, after the @ref HAL_PSSI_Init() and when the state is @ref HAL_PSSI_STATE_RESET
125      all callbacks are set to the corresponding weak functions:
126      examples @ref HAL_PSSI_TxCpltCallback(), @ref HAL_PSSI_RxCpltCallback().
127      Exception done for MspInit and MspDeInit functions that are
128      reset to the legacy weak functions in the @ref HAL_PSSI_Init()/ @ref HAL_PSSI_DeInit() only when
129      these callbacks are null (not registered beforehand).
130      If MspInit or MspDeInit are not null, the @ref HAL_PSSI_Init()/ @ref HAL_PSSI_DeInit()
131      keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
132 
133      Callbacks can be registered/unregistered in @ref HAL_PSSI_STATE_READY state only.
134      Exception done MspInit/MspDeInit functions that can be registered/unregistered
135      in @ref HAL_PSSI_STATE_READY or @ref HAL_PSSI_STATE_RESET state,
136      thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
137      Then, the user first registers the MspInit/MspDeInit user callbacks
138      using @ref HAL_PSSI_RegisterCallback() before calling @ref HAL_PSSI_DeInit()
139      or @ref HAL_PSSI_Init() function.
140 
141 
142      [..]
143        (@) You can refer to the PSSI HAL driver header file for more useful macros
144 
145   @endverbatim
146   */
147 
148 /* Includes ------------------------------------------------------------------*/
149 #include "stm32n6xx_hal.h"
150 
151 /** @addtogroup STM32N6xx_HAL_Driver
152   * @{
153   */
154 
155 /** @defgroup PSSI PSSI
156   * @brief PSSI HAL module driver
157   * @{
158   */
159 
160 #ifdef HAL_PSSI_MODULE_ENABLED
161 #if defined(PSSI)
162 /* Private typedef -----------------------------------------------------------*/
163 /* Private define ------------------------------------------------------------*/
164 
165 /** @defgroup PSSI_Private_Define PSSI Private Define
166   * @{
167   */
168 
169 
170 /**
171   * @}
172   */
173 
174 /* Private macro -------------------------------------------------------------*/
175 /* Private variables ---------------------------------------------------------*/
176 /* Private function prototypes -----------------------------------------------*/
177 
178 /** @defgroup PSSI_Private_Functions PSSI Private Functions
179   * @{
180   */
181 /* Private functions to handle DMA transfer */
182 #if defined(HAL_DMA_MODULE_ENABLED)
183 void PSSI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
184 void PSSI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
185 void PSSI_DMAError(DMA_HandleTypeDef *hdma);
186 void PSSI_DMAAbort(DMA_HandleTypeDef *hdma);
187 #endif /*HAL_DMA_MODULE_ENABLED*/
188 
189 /* Private functions to handle IT transfer */
190 static void PSSI_Error(PSSI_HandleTypeDef *hpssi, uint32_t ErrorCode);
191 
192 
193 /* Private functions for PSSI transfer IRQ handler */
194 
195 
196 /* Private functions to handle flags during polling transfer */
197 static HAL_StatusTypeDef PSSI_WaitOnStatusUntilTimeout(PSSI_HandleTypeDef *hpssi, uint32_t Flag, FlagStatus Status,
198                                                        uint32_t Timeout, uint32_t Tickstart);
199 
200 /* Private functions to centralize the enable/disable of Interrupts */
201 
202 
203 /**
204   * @}
205   */
206 
207 /* Exported functions --------------------------------------------------------*/
208 
209 /** @defgroup PSSI_Exported_Functions PSSI Exported Functions
210   * @{
211   */
212 
213 /** @defgroup PSSI_Exported_Functions_Group1 Initialization and de-initialization functions
214   *  @brief    Initialization and Configuration functions
215   *
216 @verbatim
217  ===============================================================================
218               ##### Initialization and de-initialization functions #####
219  ===============================================================================
220     [..]  This subsection provides a set of functions allowing to initialize and
221           deinitialize the PSSIx peripheral:
222 
223       (+) User must implement HAL_PSSI_MspInit() function in which he configures
224           all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
225 
226       (+) Call the function HAL_PSSI_Init() to configure the selected device with
227           the selected configuration:
228         (++) Data Width
229         (++) Control Signals
230         (++) Input Clock polarity
231         (++) Output Clock polarity
232 
233       (+) Call the function HAL_PSSI_DeInit() to restore the default configuration
234           of the selected PSSIx peripheral.
235 
236 @endverbatim
237   * @{
238   */
239 
240 /**
241   * @brief  Initializes the PSSI according to the specified parameters
242   *         in the PSSI_InitTypeDef and initialize the associated handle.
243   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
244   *                the configuration information for the specified PSSI.
245   * @retval HAL status
246   */
HAL_PSSI_Init(PSSI_HandleTypeDef * hpssi)247 HAL_StatusTypeDef HAL_PSSI_Init(PSSI_HandleTypeDef *hpssi)
248 {
249   /* Check the PSSI handle allocation */
250   if (hpssi == NULL)
251   {
252     return HAL_ERROR;
253   }
254 
255   /* Check the parameters */
256   assert_param(IS_PSSI_ALL_INSTANCE(hpssi->Instance));
257   assert_param(IS_PSSI_CONTROL_SIGNAL(hpssi->Init.ControlSignal));
258   assert_param(IS_PSSI_BUSWIDTH(hpssi->Init.BusWidth));
259   assert_param(IS_PSSI_CLOCK_POLARITY(hpssi->Init.ClockPolarity));
260   assert_param(IS_PSSI_DE_POLARITY(hpssi->Init.DataEnablePolarity));
261   assert_param(IS_PSSI_RDY_POLARITY(hpssi->Init.ReadyPolarity));
262 
263   if (hpssi->State == HAL_PSSI_STATE_RESET)
264   {
265     /* Allocate lock resource and initialize it */
266     hpssi->Lock = HAL_UNLOCKED;
267 
268 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
269     /* Init the PSSI Callback settings */
270     hpssi->TxCpltCallback = HAL_PSSI_TxCpltCallback; /* Legacy weak TxCpltCallback */
271     hpssi->RxCpltCallback = HAL_PSSI_RxCpltCallback; /* Legacy weak RxCpltCallback */
272     hpssi->ErrorCallback        = HAL_PSSI_ErrorCallback;        /* Legacy weak ErrorCallback        */
273     hpssi->AbortCpltCallback    = HAL_PSSI_AbortCpltCallback;    /* Legacy weak AbortCpltCallback    */
274 
275     if (hpssi->MspInitCallback == NULL)
276     {
277       hpssi->MspInitCallback = HAL_PSSI_MspInit; /* Legacy weak MspInit  */
278     }
279 
280     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
281     hpssi->MspInitCallback(hpssi);
282 #else
283     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
284     HAL_PSSI_MspInit(hpssi);
285 #endif /*USE_HAL_PSSI_REGISTER_CALLBACKS*/
286   }
287 
288   hpssi->State = HAL_PSSI_STATE_BUSY;
289 
290   /* Disable the selected PSSI peripheral */
291   HAL_PSSI_DISABLE(hpssi);
292 
293   /*---------------------------- PSSIx CR Configuration ----------------------*/
294   /* Configure PSSIx: Control Signal and Bus Width*/
295 
296   MODIFY_REG(hpssi->Instance->CR, PSSI_CR_DERDYCFG | PSSI_CR_EDM | PSSI_CR_DEPOL | PSSI_CR_RDYPOL,
297              hpssi->Init.ControlSignal | hpssi->Init.DataEnablePolarity |
298              hpssi->Init.ReadyPolarity | hpssi->Init.BusWidth);
299 
300   hpssi->ErrorCode = HAL_PSSI_ERROR_NONE;
301   hpssi->State = HAL_PSSI_STATE_READY;
302 
303   return HAL_OK;
304 }
305 
306 /**
307   * @brief  DeInitialize the PSSI peripheral.
308   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
309   *                the configuration information for the specified PSSI.
310   * @retval HAL status
311   */
HAL_PSSI_DeInit(PSSI_HandleTypeDef * hpssi)312 HAL_StatusTypeDef HAL_PSSI_DeInit(PSSI_HandleTypeDef *hpssi)
313 {
314   /* Check the PSSI handle allocation */
315   if (hpssi == NULL)
316   {
317     return HAL_ERROR;
318   }
319 
320   /* Check the parameters */
321   assert_param(IS_PSSI_ALL_INSTANCE(hpssi->Instance));
322 
323   hpssi->State = HAL_PSSI_STATE_BUSY;
324 
325   /* Disable the PSSI Peripheral Clock */
326   HAL_PSSI_DISABLE(hpssi);
327 
328 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
329   if (hpssi->MspDeInitCallback == NULL)
330   {
331     hpssi->MspDeInitCallback = HAL_PSSI_MspDeInit; /* Legacy weak MspDeInit  */
332   }
333 
334   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
335   hpssi->MspDeInitCallback(hpssi);
336 #else
337   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
338   HAL_PSSI_MspDeInit(hpssi);
339 #endif /*USE_HAL_PSSI_REGISTER_CALLBACKS*/
340 
341   hpssi->ErrorCode = HAL_PSSI_ERROR_NONE;
342   hpssi->State = HAL_PSSI_STATE_RESET;
343 
344   /* Release Lock */
345   __HAL_UNLOCK(hpssi);
346 
347   return HAL_OK;
348 }
349 
350 /**
351   * @brief Initialize the PSSI MSP.
352   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
353   *                the configuration information for the specified PSSI.
354   * @retval None
355   */
HAL_PSSI_MspInit(PSSI_HandleTypeDef * hpssi)356 __weak void HAL_PSSI_MspInit(PSSI_HandleTypeDef *hpssi)
357 {
358   /* Prevent unused argument(s) compilation warning */
359   UNUSED(hpssi);
360 
361   /* NOTE : This function should not be modified, when the callback is needed,
362             the HAL_PSSI_MspInit can be implemented in the user file
363    */
364 }
365 
366 /**
367   * @brief De-Initialize the PSSI MSP.
368   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
369   *                the configuration information for the specified PSSI.
370   * @retval None
371   */
HAL_PSSI_MspDeInit(PSSI_HandleTypeDef * hpssi)372 __weak void HAL_PSSI_MspDeInit(PSSI_HandleTypeDef *hpssi)
373 {
374   /* Prevent unused argument(s) compilation warning */
375   UNUSED(hpssi);
376 
377   /* NOTE : This function should not be modified; when the callback is needed,
378             the HAL_PSSI_MspDeInit can be implemented in the user file
379    */
380 }
381 
382 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
383 /**
384   * @brief  Register a User PSSI Callback
385   *         To be used instead of the weak predefined callback
386   * @note   The HAL_PSSI_RegisterCallback() may be called before HAL_PSSI_Init() in
387   *         HAL_PSSI_STATE_RESET to register callbacks for HAL_PSSI_MSPINIT_CB_ID
388   *         and HAL_PSSI_MSPDEINIT_CB_ID.
389   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
390   *                the configuration information for the specified PSSI.
391   * @param  CallbackID ID of the callback to be registered
392   *         This parameter can be one of the following values:
393   *          @arg @ref HAL_PSSI_TX_COMPLETE_CB_ID  Tx Transfer completed callback ID
394   *          @arg @ref HAL_PSSI_RX_COMPLETE_CB_ID  Rx Transfer completed callback ID
395   *          @arg @ref HAL_PSSI_ERROR_CB_ID Error callback ID
396   *          @arg @ref HAL_PSSI_ABORT_CB_ID Abort callback ID
397   *          @arg @ref HAL_PSSI_MSPINIT_CB_ID MspInit callback ID
398   *          @arg @ref HAL_PSSI_MSPDEINIT_CB_ID MspDeInit callback ID
399   * @param  pCallback pointer to the Callback function
400   * @retval HAL status
401   */
HAL_PSSI_RegisterCallback(PSSI_HandleTypeDef * hpssi,HAL_PSSI_CallbackIDTypeDef CallbackID,pPSSI_CallbackTypeDef pCallback)402 HAL_StatusTypeDef HAL_PSSI_RegisterCallback(PSSI_HandleTypeDef *hpssi, HAL_PSSI_CallbackIDTypeDef CallbackID,
403                                             pPSSI_CallbackTypeDef pCallback)
404 {
405   HAL_StatusTypeDef status = HAL_OK;
406 
407   if (pCallback == NULL)
408   {
409     /* Update the error code */
410     hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
411 
412     return HAL_ERROR;
413   }
414 
415   if (HAL_PSSI_STATE_READY == hpssi->State)
416   {
417     switch (CallbackID)
418     {
419       case HAL_PSSI_TX_COMPLETE_CB_ID :
420         hpssi->TxCpltCallback = pCallback;
421         break;
422 
423       case HAL_PSSI_RX_COMPLETE_CB_ID :
424         hpssi->RxCpltCallback = pCallback;
425         break;
426 
427       case HAL_PSSI_ERROR_CB_ID :
428         hpssi->ErrorCallback = pCallback;
429         break;
430 
431       case HAL_PSSI_ABORT_CB_ID :
432         hpssi->AbortCpltCallback = pCallback;
433         break;
434 
435       case HAL_PSSI_MSPINIT_CB_ID :
436         hpssi->MspInitCallback = pCallback;
437         break;
438 
439       case HAL_PSSI_MSPDEINIT_CB_ID :
440         hpssi->MspDeInitCallback = pCallback;
441         break;
442 
443       default :
444         /* Update the error code */
445         hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
446 
447         /* Return error status */
448         status =  HAL_ERROR;
449         break;
450     }
451   }
452   else if (HAL_PSSI_STATE_RESET == hpssi->State)
453   {
454     switch (CallbackID)
455     {
456       case HAL_PSSI_MSPINIT_CB_ID :
457         hpssi->MspInitCallback = pCallback;
458         break;
459 
460       case HAL_PSSI_MSPDEINIT_CB_ID :
461         hpssi->MspDeInitCallback = pCallback;
462         break;
463 
464       default :
465         /* Update the error code */
466         hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
467 
468         /* Return error status */
469         status =  HAL_ERROR;
470         break;
471     }
472   }
473   else
474   {
475     /* Update the error code */
476     hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
477 
478     /* Return error status */
479     status =  HAL_ERROR;
480   }
481 
482   return status;
483 }
484 
485 /**
486   * @brief  Unregister an PSSI Callback
487   *         PSSI callback is redirected to the weak predefined callback
488   * @note   The HAL_PSSI_UnRegisterCallback() may be called before HAL_PSSI_Init() in
489   *         HAL_PSSI_STATE_RESET to un-register callbacks for HAL_PSSI_MSPINIT_CB_ID
490   *         and HAL_PSSI_MSPDEINIT_CB_ID.
491   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
492   *                the configuration information for the specified PSSI.
493   * @param  CallbackID ID of the callback to be unregistered
494   *         This parameter can be one of the following values:
495   *          @arg @ref HAL_PSSI_TX_COMPLETE_CB_ID  Tx Transfer completed callback ID
496   *          @arg @ref HAL_PSSI_RX_COMPLETE_CB_ID  Rx Transfer completed callback ID
497   *          @arg @ref HAL_PSSI_ERROR_CB_ID Error callback ID
498   *          @arg @ref HAL_PSSI_ABORT_CB_ID Abort callback ID
499   *          @arg @ref HAL_PSSI_MSPINIT_CB_ID MspInit callback ID
500   *          @arg @ref HAL_PSSI_MSPDEINIT_CB_ID MspDeInit callback ID
501   * @retval HAL status
502   */
HAL_PSSI_UnRegisterCallback(PSSI_HandleTypeDef * hpssi,HAL_PSSI_CallbackIDTypeDef CallbackID)503 HAL_StatusTypeDef HAL_PSSI_UnRegisterCallback(PSSI_HandleTypeDef *hpssi, HAL_PSSI_CallbackIDTypeDef CallbackID)
504 {
505   HAL_StatusTypeDef status = HAL_OK;
506 
507   if (HAL_PSSI_STATE_READY == hpssi->State)
508   {
509     switch (CallbackID)
510     {
511       case HAL_PSSI_TX_COMPLETE_CB_ID :
512         hpssi->TxCpltCallback = HAL_PSSI_TxCpltCallback;             /* Legacy weak TxCpltCallback     */
513         break;
514 
515       case HAL_PSSI_RX_COMPLETE_CB_ID :
516         hpssi->RxCpltCallback = HAL_PSSI_RxCpltCallback;             /* Legacy weak RxCpltCallback     */
517         break;
518 
519       case HAL_PSSI_ERROR_CB_ID :
520         hpssi->ErrorCallback = HAL_PSSI_ErrorCallback;               /* Legacy weak ErrorCallback      */
521         break;
522 
523       case HAL_PSSI_ABORT_CB_ID :
524         hpssi->AbortCpltCallback = HAL_PSSI_AbortCpltCallback;       /* Legacy weak AbortCpltCallback  */
525         break;
526 
527       case HAL_PSSI_MSPINIT_CB_ID :
528         hpssi->MspInitCallback = HAL_PSSI_MspInit;                   /* Legacy weak MspInit            */
529         break;
530 
531       case HAL_PSSI_MSPDEINIT_CB_ID :
532         hpssi->MspDeInitCallback = HAL_PSSI_MspDeInit;               /* Legacy weak MspDeInit          */
533         break;
534 
535       default :
536         /* Update the error code */
537         hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
538 
539         /* Return error status */
540         status =  HAL_ERROR;
541         break;
542     }
543   }
544   else if (HAL_PSSI_STATE_RESET == hpssi->State)
545   {
546     switch (CallbackID)
547     {
548       case HAL_PSSI_MSPINIT_CB_ID :
549         hpssi->MspInitCallback = HAL_PSSI_MspInit;                   /* Legacy weak MspInit            */
550         break;
551 
552       case HAL_PSSI_MSPDEINIT_CB_ID :
553         hpssi->MspDeInitCallback = HAL_PSSI_MspDeInit;               /* Legacy weak MspDeInit          */
554         break;
555 
556       default :
557         /* Update the error code */
558         hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
559 
560         /* Return error status */
561         status =  HAL_ERROR;
562         break;
563     }
564   }
565   else
566   {
567     /* Update the error code */
568     hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
569 
570     /* Return error status */
571     status =  HAL_ERROR;
572   }
573 
574   return status;
575 }
576 
577 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
578 
579 /**
580   * @}
581   */
582 
583 /** @defgroup PSSI_Exported_Functions_Group2 Input and Output operation functions
584   *  @brief   Data transfers functions
585   *
586 @verbatim
587  ===============================================================================
588                       ##### IO operation functions #####
589  ===============================================================================
590     [..]
591     This subsection provides a set of functions allowing to manage the PSSI data
592     transfers.
593 
594     (#) There are two modes of transfer:
595        (++) Blocking mode : The communication is performed in the polling mode.
596             The status of all data processing is returned by the same function
597             after finishing transfer.
598        (++) No-Blocking mode : The communication is performed using DMA.
599             These functions return the status of the transfer startup.
600             The end of the data processing will be indicated through the
601             dedicated  the DMA IRQ .
602 
603     (#) Blocking mode functions are :
604         (++) HAL_PSSI_Transmit()
605         (++) HAL_PSSI_Receive()
606 
607     (#) No-Blocking mode functions with DMA are :
608         (++) HAL_PSSI_Transmit_DMA()
609         (++) HAL_PSSI_Receive_DMA()
610 
611     (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
612         (++) HAL_PSSI_TxCpltCallback()
613         (++) HAL_PSSI_RxCpltCallback()
614         (++) HAL_PSSI_ErrorCallback()
615         (++) HAL_PSSI_AbortCpltCallback()
616 
617 @endverbatim
618   * @{
619   */
620 
621 /**
622   * @brief  Transmits in master mode an amount of data in blocking mode.
623   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
624   *                the configuration information for the specified PSSI.
625   * @param  pData Pointer to data buffer
626   * @param  Size Amount of data to be sent (in bytes)
627   * @param  Timeout Timeout duration
628   * @retval HAL status
629   */
HAL_PSSI_Transmit(PSSI_HandleTypeDef * hpssi,uint8_t * pData,uint32_t Size,uint32_t Timeout)630 HAL_StatusTypeDef HAL_PSSI_Transmit(PSSI_HandleTypeDef *hpssi, uint8_t *pData, uint32_t Size, uint32_t Timeout)
631 {
632   uint32_t tickstart;
633   uint32_t  transfer_size = Size;
634 
635   if (((hpssi->Init.DataWidth == HAL_PSSI_8BITS) && (hpssi->Init.BusWidth != HAL_PSSI_8LINES)) ||
636       ((hpssi->Init.DataWidth == HAL_PSSI_16BITS) && ((Size % 2U) != 0U)) ||
637       ((hpssi->Init.DataWidth == HAL_PSSI_32BITS) && ((Size % 4U) != 0U)))
638   {
639     hpssi->ErrorCode = HAL_PSSI_ERROR_NOT_SUPPORTED;
640     return HAL_ERROR;
641   }
642   if (hpssi->State == HAL_PSSI_STATE_READY)
643   {
644     /* Process Locked */
645     __HAL_LOCK(hpssi);
646 
647     hpssi->State     = HAL_PSSI_STATE_BUSY;
648     hpssi->ErrorCode = HAL_PSSI_ERROR_NONE;
649 
650     /* Disable the selected PSSI peripheral */
651     HAL_PSSI_DISABLE(hpssi);
652 
653     /* Configure transfer parameters */
654     MODIFY_REG(hpssi->Instance->CR, (PSSI_CR_OUTEN | PSSI_CR_CKPOL),
655                (PSSI_CR_OUTEN_OUTPUT | ((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE) ? 0U : PSSI_CR_CKPOL)));
656 
657 #if defined(HAL_DMA_MODULE_ENABLED)
658     /* DMA Disable */
659     hpssi->Instance->CR &= PSSI_CR_DMA_DISABLE;
660 #endif /*HAL_DMA_MODULE_ENABLED*/
661 
662     /* Enable the selected PSSI peripheral */
663     HAL_PSSI_ENABLE(hpssi);
664 
665     if (hpssi->Init.DataWidth == HAL_PSSI_8BITS)
666     {
667       uint8_t *pbuffer = pData;
668       while (transfer_size > 0U)
669       {
670         /* Init tickstart for timeout management*/
671         tickstart = HAL_GetTick();
672         /* Wait until Fifo is ready to transfer one byte flag is set */
673         if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT1B, RESET, Timeout, tickstart) != HAL_OK)
674         {
675           hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT;
676           hpssi->State = HAL_PSSI_STATE_READY;
677           /* Process Unlocked */
678           __HAL_UNLOCK(hpssi);
679           return HAL_ERROR;
680         }
681         /* Write data to DR */
682         *(__IO uint8_t *)(&hpssi->Instance->DR) = *(uint8_t *)pbuffer;
683 
684         /* Increment Buffer pointer */
685         pbuffer++;
686 
687         transfer_size--;
688       }
689     }
690     else if (hpssi->Init.DataWidth == HAL_PSSI_16BITS)
691     {
692       uint16_t *pbuffer = (uint16_t *)pData;
693       __IO uint16_t *dr = (__IO uint16_t *)(&hpssi->Instance->DR);
694 
695       while (transfer_size > 0U)
696       {
697         /* Init tickstart for timeout management*/
698         tickstart = HAL_GetTick();
699         /* Wait until Fifo is ready to transfer four bytes flag is set */
700         if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT4B, RESET, Timeout, tickstart) != HAL_OK)
701         {
702           hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT;
703           hpssi->State = HAL_PSSI_STATE_READY;
704           /* Process Unlocked */
705           __HAL_UNLOCK(hpssi);
706           return HAL_ERROR;
707         }
708         /* Write data to DR */
709         *dr = *pbuffer;
710 
711         /* Increment Buffer pointer */
712         pbuffer++;
713         transfer_size -= 2U;
714       }
715     }
716     else if (hpssi->Init.DataWidth == HAL_PSSI_32BITS)
717     {
718       uint32_t *pbuffer = (uint32_t *)pData;
719       while (transfer_size > 0U)
720       {
721         /* Init tickstart for timeout management*/
722         tickstart = HAL_GetTick();
723         /* Wait until Fifo is ready to transfer four bytes flag is set */
724         if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT4B, RESET, Timeout, tickstart) != HAL_OK)
725         {
726           hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT;
727           hpssi->State = HAL_PSSI_STATE_READY;
728           /* Process Unlocked */
729           __HAL_UNLOCK(hpssi);
730           return HAL_ERROR;
731         }
732         /* Write data to DR */
733         *(__IO uint32_t *)(&hpssi->Instance->DR) = *pbuffer;
734 
735         /* Increment Buffer pointer */
736         pbuffer++;
737         transfer_size -= 4U;
738       }
739     }
740     else
741     {
742       hpssi->ErrorCode = HAL_PSSI_ERROR_NOT_SUPPORTED;
743       hpssi->State = HAL_PSSI_STATE_READY;
744       /* Process Unlocked */
745       __HAL_UNLOCK(hpssi);
746       return HAL_ERROR;
747     }
748 
749     /* Check Errors Flags */
750     if (HAL_PSSI_GET_FLAG(hpssi, PSSI_FLAG_OVR_RIS) != 0U)
751     {
752       HAL_PSSI_CLEAR_FLAG(hpssi, PSSI_FLAG_OVR_RIS);
753       HAL_PSSI_DISABLE(hpssi);
754       hpssi->ErrorCode = HAL_PSSI_ERROR_UNDER_RUN;
755       hpssi->State = HAL_PSSI_STATE_READY;
756       /* Process Unlocked */
757       __HAL_UNLOCK(hpssi);
758       return HAL_ERROR;
759     }
760 
761     hpssi->State = HAL_PSSI_STATE_READY;
762 
763     /* Process Unlocked */
764     __HAL_UNLOCK(hpssi);
765 
766     return HAL_OK;
767   }
768   else
769   {
770     return HAL_BUSY;
771   }
772 }
773 
774 /**
775   * @brief  Receives an amount of data in blocking mode.
776   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
777   *                the configuration information for the specified PSSI.
778   * @param  pData Pointer to data buffer
779   * @param  Size Amount of data to be received (in bytes)
780   * @param  Timeout Timeout duration
781   * @retval HAL status
782   */
HAL_PSSI_Receive(PSSI_HandleTypeDef * hpssi,uint8_t * pData,uint32_t Size,uint32_t Timeout)783 HAL_StatusTypeDef HAL_PSSI_Receive(PSSI_HandleTypeDef *hpssi, uint8_t *pData, uint32_t Size, uint32_t Timeout)
784 {
785   uint32_t tickstart;
786   uint32_t  transfer_size = Size;
787 
788   if (((hpssi->Init.DataWidth == HAL_PSSI_8BITS) && (hpssi->Init.BusWidth != HAL_PSSI_8LINES)) ||
789       ((hpssi->Init.DataWidth == HAL_PSSI_16BITS) && ((Size % 2U) != 0U)) ||
790       ((hpssi->Init.DataWidth == HAL_PSSI_32BITS) && ((Size % 4U) != 0U)))
791   {
792     hpssi->ErrorCode = HAL_PSSI_ERROR_NOT_SUPPORTED;
793     return HAL_ERROR;
794   }
795 
796   if (hpssi->State == HAL_PSSI_STATE_READY)
797   {
798     /* Process Locked */
799     __HAL_LOCK(hpssi);
800 
801     hpssi->State     = HAL_PSSI_STATE_BUSY;
802     hpssi->ErrorCode = HAL_PSSI_ERROR_NONE;
803 
804     /* Disable the selected PSSI peripheral */
805     HAL_PSSI_DISABLE(hpssi);
806     /* Configure transfer parameters */
807     MODIFY_REG(hpssi->Instance->CR, (PSSI_CR_OUTEN | PSSI_CR_CKPOL),
808                (PSSI_CR_OUTEN_INPUT | ((hpssi->Init.ClockPolarity == HAL_PSSI_FALLING_EDGE) ? 0U : PSSI_CR_CKPOL)));
809 
810 #if defined(HAL_DMA_MODULE_ENABLED)
811     /* DMA Disable */
812     hpssi->Instance->CR &= PSSI_CR_DMA_DISABLE;
813 #endif /*HAL_DMA_MODULE_ENABLED*/
814 
815     /* Enable the selected PSSI peripheral */
816     HAL_PSSI_ENABLE(hpssi);
817     if (hpssi->Init.DataWidth == HAL_PSSI_8BITS)
818     {
819       uint8_t *pbuffer = pData;
820 
821       while (transfer_size > 0U)
822       {
823         /* Init tickstart for timeout management*/
824         tickstart = HAL_GetTick();
825         /* Wait until Fifo is ready to receive one byte flag is set */
826         if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT1B, RESET, Timeout, tickstart) != HAL_OK)
827         {
828           hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT;
829           hpssi->State = HAL_PSSI_STATE_READY;
830           /* Process Unlocked */
831           __HAL_UNLOCK(hpssi);
832           return HAL_ERROR;
833         }
834         /* Read data from DR */
835         *pbuffer = *(__IO uint8_t *)(&hpssi->Instance->DR);
836         pbuffer++;
837         transfer_size--;
838       }
839     }
840     else if (hpssi->Init.DataWidth == HAL_PSSI_16BITS)
841     {
842       uint16_t *pbuffer = (uint16_t *)pData;
843       __IO uint16_t *dr = (__IO uint16_t *)(&hpssi->Instance->DR);
844 
845       while (transfer_size > 0U)
846       {
847         /* Init tickstart for timeout management*/
848         tickstart = HAL_GetTick();
849         /* Wait until Fifo is ready to receive four bytes flag is set */
850         if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT4B, RESET, Timeout, tickstart) != HAL_OK)
851         {
852           hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT;
853           hpssi->State = HAL_PSSI_STATE_READY;
854           /* Process Unlocked */
855           __HAL_UNLOCK(hpssi);
856           return HAL_ERROR;
857         }
858 
859         /* Read data from DR */
860         *pbuffer = *dr;
861         pbuffer++;
862         transfer_size -= 2U;
863       }
864     }
865     else if (hpssi->Init.DataWidth == HAL_PSSI_32BITS)
866     {
867       uint32_t *pbuffer = (uint32_t *)pData;
868 
869       while (transfer_size > 0U)
870       {
871         /* Init tickstart for timeout management*/
872         tickstart = HAL_GetTick();
873         /* Wait until Fifo is ready to receive four bytes flag is set */
874         if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT4B, RESET, Timeout, tickstart) != HAL_OK)
875         {
876           hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT;
877           hpssi->State = HAL_PSSI_STATE_READY;
878           /* Process Unlocked */
879           __HAL_UNLOCK(hpssi);
880           return HAL_ERROR;
881         }
882 
883         /* Read data from DR */
884         *pbuffer = *(__IO uint32_t *)(&hpssi->Instance->DR);
885         pbuffer++;
886         transfer_size -= 4U;
887       }
888     }
889     else
890     {
891       hpssi->ErrorCode = HAL_PSSI_ERROR_NOT_SUPPORTED;
892       hpssi->State = HAL_PSSI_STATE_READY;
893       /* Process Unlocked */
894       __HAL_UNLOCK(hpssi);
895       return HAL_ERROR;
896     }
897     /* Check Errors Flags */
898 
899     if (HAL_PSSI_GET_FLAG(hpssi, PSSI_FLAG_OVR_RIS) != 0U)
900     {
901       HAL_PSSI_CLEAR_FLAG(hpssi, PSSI_FLAG_OVR_RIS);
902       hpssi->ErrorCode = HAL_PSSI_ERROR_OVER_RUN;
903       __HAL_UNLOCK(hpssi);
904       return HAL_ERROR;
905     }
906 
907     hpssi->State = HAL_PSSI_STATE_READY;
908 
909     /* Process Unlocked */
910     __HAL_UNLOCK(hpssi);
911 
912     return HAL_OK;
913   }
914   else
915   {
916     return HAL_BUSY;
917   }
918 }
919 
920 #if defined(HAL_DMA_MODULE_ENABLED)
921 /**
922   * @brief  Transmit an amount of data in non-blocking mode with DMA
923   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
924   *                the configuration information for the specified PSSI.
925   * @param  pData Pointer to data buffer
926   * @param  Size Amount of data to be sent (in bytes)
927   * @retval HAL status
928   */
HAL_PSSI_Transmit_DMA(PSSI_HandleTypeDef * hpssi,uint32_t * pData,uint32_t Size)929 HAL_StatusTypeDef HAL_PSSI_Transmit_DMA(PSSI_HandleTypeDef *hpssi, uint32_t *pData, uint32_t Size)
930 {
931   HAL_StatusTypeDef dmaxferstatus;
932 
933   if (hpssi->State == HAL_PSSI_STATE_READY)
934   {
935 
936     /* Process Locked */
937     __HAL_LOCK(hpssi);
938 
939     hpssi->State       = HAL_PSSI_STATE_BUSY_TX;
940     hpssi->ErrorCode   = HAL_PSSI_ERROR_NONE;
941 
942     /* Disable the selected PSSI peripheral */
943     HAL_PSSI_DISABLE(hpssi);
944 
945     /* Prepare transfer parameters */
946     hpssi->pBuffPtr    = pData;
947     hpssi->XferCount   = Size;
948 
949     if (hpssi->XferCount > PSSI_MAX_NBYTE_SIZE)
950     {
951       hpssi->XferSize = PSSI_MAX_NBYTE_SIZE;
952     }
953     else
954     {
955       hpssi->XferSize = hpssi->XferCount;
956     }
957 
958     if (hpssi->XferSize > 0U)
959     {
960       if (hpssi->hdmatx != NULL)
961       {
962 
963         /* Configure BusWidth */
964         if (hpssi->hdmatx->Init.DestDataWidth == DMA_DEST_DATAWIDTH_BYTE)
965         {
966           MODIFY_REG(hpssi->Instance->CR, PSSI_CR_DMAEN | PSSI_CR_OUTEN | PSSI_CR_CKPOL,
967                      PSSI_CR_DMA_ENABLE | PSSI_CR_OUTEN_OUTPUT |
968                      ((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE) ? 0U : PSSI_CR_CKPOL));
969         }
970         else
971         {
972           MODIFY_REG(hpssi->Instance->CR, PSSI_CR_DMAEN | PSSI_CR_OUTEN | PSSI_CR_CKPOL,
973                      PSSI_CR_DMA_ENABLE | hpssi->Init.BusWidth | PSSI_CR_OUTEN_OUTPUT |
974                      ((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE) ? 0U : PSSI_CR_CKPOL));
975         }
976 
977         /* Set the PSSI DMA transfer complete callback */
978         hpssi->hdmatx->XferCpltCallback = PSSI_DMATransmitCplt;
979 
980         /* Set the DMA error callback */
981         hpssi->hdmatx->XferErrorCallback = PSSI_DMAError;
982 
983         /* Set the unused DMA callbacks to NULL */
984         hpssi->hdmatx->XferHalfCpltCallback = NULL;
985         hpssi->hdmatx->XferAbortCallback = NULL;
986 
987         /* Enable the DMA  */
988         if ((hpssi->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
989         {
990           if (hpssi->hdmatx->LinkedListQueue != NULL)
991           {
992             /* Enable the DMA channel */
993             /* Set DMA data size */
994             hpssi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hpssi->XferSize;
995             /* Set DMA source address */
996             hpssi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pData;
997             /* Set DMA destination address */
998             hpssi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] =
999               (uint32_t)&hpssi->Instance->DR;
1000 
1001             dmaxferstatus = HAL_DMAEx_List_Start_IT(hpssi->hdmatx);
1002           }
1003           else
1004           {
1005             /* Return error status */
1006             return HAL_ERROR;
1007           }
1008         }
1009         else
1010         {
1011           dmaxferstatus = HAL_DMA_Start_IT(hpssi->hdmatx, (uint32_t)pData, (uint32_t)&hpssi->Instance->DR,
1012                                            hpssi->XferSize);
1013         }
1014       }
1015       else
1016       {
1017         /* Update PSSI state */
1018         hpssi->State     = HAL_PSSI_STATE_READY;
1019 
1020         /* Update PSSI error code */
1021         hpssi->ErrorCode |= HAL_PSSI_ERROR_DMA;
1022 
1023         /* Process Unlocked */
1024         __HAL_UNLOCK(hpssi);
1025 
1026         return HAL_ERROR;
1027       }
1028 
1029       if (dmaxferstatus == HAL_OK)
1030       {
1031         /* Update XferCount value */
1032         hpssi->XferCount -= hpssi->XferSize;
1033 
1034         /* Process Unlocked */
1035         __HAL_UNLOCK(hpssi);
1036 
1037         /* Note : The PSSI interrupts must be enabled after unlocking current process
1038                   to avoid the risk of PSSI interrupt handle execution before current
1039                   process unlock */
1040         /* Enable ERR interrupt */
1041         HAL_PSSI_ENABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1042 
1043         /* Enable DMA Request */
1044         hpssi->Instance->CR |= PSSI_CR_DMA_ENABLE;
1045         /* Enable the selected PSSI peripheral */
1046         HAL_PSSI_ENABLE(hpssi);
1047       }
1048       else
1049       {
1050         /* Update PSSI state */
1051         hpssi->State     = HAL_PSSI_STATE_READY;
1052 
1053         /* Update PSSI error code */
1054         hpssi->ErrorCode |= HAL_PSSI_ERROR_DMA;
1055 
1056         /* Process Unlocked */
1057         __HAL_UNLOCK(hpssi);
1058 
1059         return HAL_ERROR;
1060       }
1061     }
1062     else
1063     {
1064       /* Process Unlocked */
1065       __HAL_UNLOCK(hpssi);
1066 
1067       /* Note : The PSSI interrupts must be enabled after unlocking current process
1068                 to avoid the risk of PSSI interrupt handle execution before current
1069                 process unlock */
1070       /* Enable ERRinterrupt */
1071       /* possible to enable all of these */
1072 
1073       HAL_PSSI_ENABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1074     }
1075     return HAL_OK;
1076   }
1077   else
1078   {
1079     return HAL_BUSY;
1080   }
1081 }
1082 
1083 /**
1084   * @brief  Receive an amount of data in non-blocking mode with DMA
1085   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1086   *                the configuration information for the specified PSSI.
1087   * @param  pData Pointer to data buffer
1088   * @param  Size Amount of data to be received (in bytes)
1089   * @retval HAL status
1090   */
HAL_PSSI_Receive_DMA(PSSI_HandleTypeDef * hpssi,uint32_t * pData,uint32_t Size)1091 HAL_StatusTypeDef HAL_PSSI_Receive_DMA(PSSI_HandleTypeDef *hpssi, uint32_t *pData, uint32_t Size)
1092 {
1093 
1094   HAL_StatusTypeDef dmaxferstatus;
1095 
1096   if (hpssi->State == HAL_PSSI_STATE_READY)
1097   {
1098 
1099     /* Disable the selected PSSI peripheral */
1100     HAL_PSSI_DISABLE(hpssi);
1101     /* Process Locked */
1102     __HAL_LOCK(hpssi);
1103 
1104     hpssi->State       = HAL_PSSI_STATE_BUSY_RX;
1105     hpssi->ErrorCode   = HAL_PSSI_ERROR_NONE;
1106 
1107     /* Prepare transfer parameters */
1108     hpssi->pBuffPtr    = pData;
1109     hpssi->XferCount   = Size;
1110 
1111     if (hpssi->XferCount > PSSI_MAX_NBYTE_SIZE)
1112     {
1113       hpssi->XferSize = PSSI_MAX_NBYTE_SIZE;
1114     }
1115     else
1116     {
1117       hpssi->XferSize = hpssi->XferCount;
1118     }
1119 
1120     if (hpssi->XferSize > 0U)
1121     {
1122       if (hpssi->hdmarx != NULL)
1123       {
1124         /* Configure BusWidth */
1125         if (hpssi->hdmarx->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_BYTE)
1126         {
1127           MODIFY_REG(hpssi->Instance->CR, PSSI_CR_DMAEN | PSSI_CR_OUTEN | PSSI_CR_CKPOL, PSSI_CR_DMA_ENABLE |
1128                      ((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE) ? PSSI_CR_CKPOL : 0U));
1129         }
1130         else
1131         {
1132           MODIFY_REG(hpssi->Instance->CR, PSSI_CR_DMAEN | PSSI_CR_OUTEN | PSSI_CR_CKPOL,
1133                      PSSI_CR_DMA_ENABLE | hpssi->Init.BusWidth |
1134                      ((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE) ? PSSI_CR_CKPOL : 0U));
1135         }
1136 
1137         /* Set the PSSI DMA transfer complete callback */
1138         hpssi->hdmarx->XferCpltCallback = PSSI_DMAReceiveCplt;
1139 
1140         /* Set the DMA error callback */
1141         hpssi->hdmarx->XferErrorCallback = PSSI_DMAError;
1142 
1143         /* Set the unused DMA callbacks to NULL */
1144         hpssi->hdmarx->XferHalfCpltCallback = NULL;
1145         hpssi->hdmarx->XferAbortCallback = NULL;
1146 
1147         /* Enable the DMA  */
1148         if ((hpssi->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1149         {
1150           if (hpssi->hdmarx->LinkedListQueue != NULL)
1151           {
1152             /* Enable the DMA channel */
1153             /* Set DMA data size */
1154             hpssi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hpssi->XferSize;
1155             /* Set DMA source address */
1156             hpssi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] =
1157               (uint32_t)&hpssi->Instance->DR;
1158             /* Set DMA destination address */
1159             hpssi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pData;
1160 
1161             dmaxferstatus = HAL_DMAEx_List_Start_IT(hpssi->hdmarx);
1162           }
1163           else
1164           {
1165             /* Return error status */
1166             return HAL_ERROR;
1167           }
1168         }
1169         else
1170         {
1171           dmaxferstatus = HAL_DMA_Start_IT(hpssi->hdmarx, (uint32_t)&hpssi->Instance->DR, (uint32_t)pData,
1172                                            hpssi->XferSize);
1173         }
1174       }
1175       else
1176       {
1177         /* Update PSSI state */
1178         hpssi->State     = HAL_PSSI_STATE_READY;
1179 
1180         /* Update PSSI error code */
1181         hpssi->ErrorCode |= HAL_PSSI_ERROR_DMA;
1182 
1183         /* Process Unlocked */
1184         __HAL_UNLOCK(hpssi);
1185 
1186         return HAL_ERROR;
1187       }
1188 
1189       if (dmaxferstatus == HAL_OK)
1190       {
1191         /* Update XferCount value */
1192         hpssi->XferCount -= hpssi->XferSize;
1193 
1194         /* Process Unlocked */
1195         __HAL_UNLOCK(hpssi);
1196 
1197         /* Note : The PSSI interrupts must be enabled after unlocking current process
1198                   to avoid the risk of PSSI interrupt handle execution before current
1199                   process unlock */
1200         /* Enable ERR  interrupt */
1201         HAL_PSSI_ENABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1202 
1203         /* Enable DMA Request */
1204         hpssi->Instance->CR |= PSSI_CR_DMA_ENABLE;
1205         /* Enable the selected PSSI peripheral */
1206         HAL_PSSI_ENABLE(hpssi);
1207       }
1208       else
1209       {
1210         /* Update PSSI state */
1211         hpssi->State     = HAL_PSSI_STATE_READY;
1212 
1213         /* Update PSSI error code */
1214         hpssi->ErrorCode |= HAL_PSSI_ERROR_DMA;
1215 
1216         /* Process Unlocked */
1217         __HAL_UNLOCK(hpssi);
1218 
1219         return HAL_ERROR;
1220       }
1221     }
1222     else
1223     {
1224       /* Process Unlocked */
1225       __HAL_UNLOCK(hpssi);
1226 
1227       /* Enable ERR,interrupt */
1228       HAL_PSSI_ENABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1229     }
1230 
1231     return HAL_OK;
1232   }
1233   else
1234   {
1235     return HAL_BUSY;
1236   }
1237 }
1238 
1239 /**
1240   * @brief  Abort a DMA process communication with Interrupt.
1241   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1242   *                the configuration information for the specified PSSI.
1243   * @retval HAL status
1244   */
HAL_PSSI_Abort_DMA(PSSI_HandleTypeDef * hpssi)1245 HAL_StatusTypeDef HAL_PSSI_Abort_DMA(PSSI_HandleTypeDef *hpssi)
1246 {
1247   /* Process Locked */
1248   __HAL_LOCK(hpssi);
1249 
1250   /* Disable Interrupts */
1251   HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1252 
1253   /* Set State at HAL_PSSI_STATE_ABORT */
1254   hpssi->State = HAL_PSSI_STATE_ABORT;
1255 
1256   /* Abort DMA TX transfer if any */
1257   if ((hpssi->Instance->CR & PSSI_CR_DMAEN) == PSSI_CR_DMAEN)
1258   {
1259     if (hpssi->State == HAL_PSSI_STATE_BUSY_TX)
1260     {
1261       hpssi->Instance->CR &= ~PSSI_CR_DMAEN;
1262 
1263       if (hpssi->hdmatx != NULL)
1264       {
1265         /* Set the PSSI DMA Abort callback :
1266         will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */
1267         hpssi->hdmatx->XferAbortCallback = PSSI_DMAAbort;
1268 
1269         /* Abort DMA TX */
1270         if (HAL_DMA_Abort_IT(hpssi->hdmatx) != HAL_OK)
1271         {
1272           /* Call Directly XferAbortCallback function in case of error */
1273           hpssi->hdmatx->XferAbortCallback(hpssi->hdmatx);
1274         }
1275       }
1276     }
1277     /* Abort DMA RX transfer if any */
1278     else if (hpssi->State == HAL_PSSI_STATE_BUSY_RX)
1279     {
1280       hpssi->Instance->CR &= ~PSSI_CR_DMAEN;
1281 
1282       if (hpssi->hdmarx != NULL)
1283       {
1284         /* Set the PSSI DMA Abort callback :
1285         will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */
1286         hpssi->hdmarx->XferAbortCallback = PSSI_DMAAbort;
1287 
1288         /* Abort DMA RX */
1289         if (HAL_DMA_Abort_IT(hpssi->hdmarx) != HAL_OK)
1290         {
1291           /* Call Directly hpssi->hdma->XferAbortCallback function in case of error */
1292           hpssi->hdmarx->XferAbortCallback(hpssi->hdmarx);
1293         }
1294       }
1295     }
1296     else
1297     {
1298 
1299       /* Call the error callback */
1300 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
1301       hpssi->ErrorCallback(hpssi);
1302 #else
1303       HAL_PSSI_ErrorCallback(hpssi);
1304 #endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */
1305     }
1306   }
1307 
1308   /* Process Unlocked */
1309   __HAL_UNLOCK(hpssi);
1310 
1311   /* Note : The PSSI interrupts must be enabled after unlocking current process
1312             to avoid the risk of PSSI interrupt handle execution before current
1313             process unlock */
1314   HAL_PSSI_ENABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1315 
1316   return HAL_OK;
1317 }
1318 #endif /*HAL_DMA_MODULE_ENABLED*/
1319 
1320 /**
1321   * @}
1322   */
1323 
1324 /** @addtogroup PSSI_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
1325   * @{
1326   */
1327 
1328 /**
1329   * @brief  This function handles PSSI event interrupt request.
1330   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1331   *                the configuration information for the specified PSSI.
1332   * @retval None
1333   */
HAL_PSSI_IRQHandler(PSSI_HandleTypeDef * hpssi)1334 void HAL_PSSI_IRQHandler(PSSI_HandleTypeDef *hpssi)
1335 {
1336   /* Overrun/ Underrun Errors */
1337   if (HAL_PSSI_GET_FLAG(hpssi, PSSI_FLAG_OVR_MIS) != 0U)
1338   {
1339     /* Reset handle parameters */
1340     hpssi->XferCount     = 0U;
1341 
1342     /* Disable all interrupts */
1343     HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1344 
1345 #if defined(HAL_DMA_MODULE_ENABLED)
1346     /* Abort DMA TX transfer if any */
1347     if ((hpssi->Instance->CR & PSSI_CR_DMAEN) == PSSI_CR_DMAEN)
1348     {
1349       if (hpssi->State == HAL_PSSI_STATE_BUSY_TX)
1350       {
1351         /* Set new error code */
1352         hpssi->ErrorCode |= HAL_PSSI_ERROR_UNDER_RUN;
1353 
1354         hpssi->Instance->CR &= ~PSSI_CR_DMAEN;
1355 
1356         if (hpssi->hdmatx != NULL)
1357         {
1358           /* Set the PSSI DMA Abort callback :
1359           will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */
1360           hpssi->hdmatx->XferAbortCallback = PSSI_DMAAbort;
1361 
1362           /* Process Unlocked */
1363           __HAL_UNLOCK(hpssi);
1364 
1365           /* Abort DMA TX */
1366           if (HAL_DMA_Abort_IT(hpssi->hdmatx) != HAL_OK)
1367           {
1368             /* Call Directly XferAbortCallback function in case of error */
1369             hpssi->hdmatx->XferAbortCallback(hpssi->hdmatx);
1370           }
1371         }
1372       }
1373       /* Abort DMA RX transfer if any */
1374       else if (hpssi->State == HAL_PSSI_STATE_BUSY_RX)
1375       {
1376         /* Set new error code */
1377         hpssi->ErrorCode |= HAL_PSSI_ERROR_OVER_RUN;
1378 
1379         hpssi->Instance->CR &= ~PSSI_CR_DMAEN;
1380 
1381         if (hpssi->hdmarx != NULL)
1382         {
1383           /* Set the PSSI DMA Abort callback :
1384           will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */
1385           hpssi->hdmarx->XferAbortCallback = PSSI_DMAAbort;
1386 
1387           /* Process Unlocked */
1388           __HAL_UNLOCK(hpssi);
1389 
1390           /* Abort DMA RX */
1391           if (HAL_DMA_Abort_IT(hpssi->hdmarx) != HAL_OK)
1392           {
1393             /* Call Directly hpssi->hdma->XferAbortCallback function in case of error */
1394             hpssi->hdmarx->XferAbortCallback(hpssi->hdmarx);
1395           }
1396         }
1397       }
1398       else
1399       {
1400 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
1401         /* Call the corresponding callback to inform upper layer of the error */
1402         hpssi->ErrorCallback(hpssi);
1403 #else
1404         HAL_PSSI_ErrorCallback(hpssi);
1405 #endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */
1406       }
1407     }
1408 #endif /*HAL_DMA_MODULE_ENABLED*/
1409 
1410     /* If state is an abort treatment on going, don't change state */
1411     if (hpssi->State == HAL_PSSI_STATE_ABORT)
1412     {
1413       hpssi->State = HAL_PSSI_STATE_READY;
1414 
1415       /* Process Unlocked */
1416       __HAL_UNLOCK(hpssi);
1417 
1418 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
1419       /* Call the corresponding callback to inform upper layer of End of Transfer */
1420       hpssi->AbortCpltCallback(hpssi);
1421 #else
1422       HAL_PSSI_AbortCpltCallback(hpssi);
1423 #endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */
1424     }
1425     else
1426     {
1427       /* Set HAL_PSSI_STATE_READY */
1428       hpssi->State         = HAL_PSSI_STATE_READY;
1429       /* Process Unlocked */
1430       __HAL_UNLOCK(hpssi);
1431 
1432 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
1433       /* Call the corresponding callback to inform upper layer of End of Transfer */
1434       hpssi->ErrorCallback(hpssi);
1435 #else
1436       HAL_PSSI_ErrorCallback(hpssi);
1437 #endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */
1438     }
1439   }
1440 }
1441 
1442 /**
1443   * @brief   Tx Transfer complete callback.
1444   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1445   *                the configuration information for the specified PSSI.
1446   * @retval None
1447   */
HAL_PSSI_TxCpltCallback(PSSI_HandleTypeDef * hpssi)1448 __weak void HAL_PSSI_TxCpltCallback(PSSI_HandleTypeDef *hpssi)
1449 {
1450   /* Prevent unused argument(s) compilation warning */
1451   UNUSED(hpssi);
1452 
1453   /* NOTE : This function should not be modified, when the callback is needed,
1454             the HAL_PSSI_TxCpltCallback can be implemented in the user file
1455    */
1456 }
1457 
1458 /**
1459   * @brief   Rx Transfer complete callback.
1460   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1461   *                the configuration information for the specified PSSI.
1462   * @retval None
1463   */
HAL_PSSI_RxCpltCallback(PSSI_HandleTypeDef * hpssi)1464 __weak void HAL_PSSI_RxCpltCallback(PSSI_HandleTypeDef *hpssi)
1465 {
1466   /* Prevent unused argument(s) compilation warning */
1467   UNUSED(hpssi);
1468 
1469   /* NOTE : This function should not be modified, when the callback is needed,
1470             the HAL_PSSI_RxCpltCallback can be implemented in the user file
1471    */
1472 }
1473 
1474 /**
1475   * @brief  PSSI error callback.
1476   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1477   *                the configuration information for the specified PSSI.
1478   * @retval None
1479   */
HAL_PSSI_ErrorCallback(PSSI_HandleTypeDef * hpssi)1480 __weak void HAL_PSSI_ErrorCallback(PSSI_HandleTypeDef *hpssi)
1481 {
1482   /* Prevent unused argument(s) compilation warning */
1483   UNUSED(hpssi);
1484 
1485   /* NOTE : This function should not be modified, when the callback is needed,
1486             the HAL_PSSI_ErrorCallback could be implemented in the user file
1487    */
1488 }
1489 
1490 /**
1491   * @brief  PSSI abort callback.
1492   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1493   *                the configuration information for the specified PSSI.
1494   * @retval None
1495   */
HAL_PSSI_AbortCpltCallback(PSSI_HandleTypeDef * hpssi)1496 __weak void HAL_PSSI_AbortCpltCallback(PSSI_HandleTypeDef *hpssi)
1497 {
1498   /* Prevent unused argument(s) compilation warning */
1499   UNUSED(hpssi);
1500 
1501   /* NOTE : This function should not be modified, when the callback is needed,
1502             the HAL_PSSI_AbortCpltCallback could be implemented in the user file
1503    */
1504 }
1505 
1506 /**
1507   * @}
1508   */
1509 
1510 /** @defgroup PSSI_Exported_Functions_Group3 Peripheral State and Error functions
1511   *  @brief   Peripheral State, Mode and Error functions
1512   *
1513 @verbatim
1514  ===============================================================================
1515             ##### Peripheral State, Mode and Error functions #####
1516  ===============================================================================
1517     [..]
1518     This subsection permit to get in run-time the status of the peripheral
1519     and the data flow.
1520 
1521 @endverbatim
1522   * @{
1523   */
1524 
1525 /**
1526   * @brief  Return the PSSI handle state.
1527   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1528   *                the configuration information for the specified PSSI.
1529   * @retval HAL state
1530   */
HAL_PSSI_GetState(const PSSI_HandleTypeDef * hpssi)1531 HAL_PSSI_StateTypeDef HAL_PSSI_GetState(const PSSI_HandleTypeDef *hpssi)
1532 {
1533   /* Return PSSI handle state */
1534   return hpssi->State;
1535 }
1536 
1537 /**
1538   * @brief  Return the PSSI error code.
1539   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1540   *              the configuration information for the specified PSSI.
1541   * @retval PSSI Error Code
1542   */
HAL_PSSI_GetError(const PSSI_HandleTypeDef * hpssi)1543 uint32_t HAL_PSSI_GetError(const PSSI_HandleTypeDef *hpssi)
1544 {
1545   return hpssi->ErrorCode;
1546 }
1547 
1548 /**
1549   * @}
1550   */
1551 
1552 /** @defgroup PSSI_Exported_Functions_Group4 Clock Source Selection function
1553   *  @brief   Clock Source Selection function to pick between an internal or
1554   *           external clock.
1555   *
1556 @verbatim
1557  ===============================================================================
1558                   ##### Clock Source Selection function #####
1559  ===============================================================================
1560     [..] This subsection provides a function allowing to:
1561       (+) Configure Clock source
1562        (++) The clock source could be external (default) or internal (the clock
1563             is generated by the device RCC).
1564        (++) The AHB clock frequency must be at least 2.5 times higher than the
1565             PSSI_PDCK frequency
1566 
1567 @endverbatim
1568   * @{
1569   */
1570 
1571 /**
1572   * @brief  Configure PSSI Clock Source.
1573   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1574   *                the configuration information for the specified PSSI peripheral.
1575   * @param  ClockSource New Clock Configuration.
1576   * @retval HAL status
1577   */
HAL_PSSI_ClockConfig(PSSI_HandleTypeDef * hpssi,uint32_t ClockSource)1578 HAL_StatusTypeDef HAL_PSSI_ClockConfig(PSSI_HandleTypeDef *hpssi, uint32_t ClockSource)
1579 {
1580   /* Check the parameter */
1581   assert_param(IS_PSSI_CLOCK_SOURCE(ClockSource));
1582 
1583   if (hpssi->State == HAL_PSSI_STATE_READY)
1584   {
1585     /* Process Locked */
1586     __HAL_LOCK(hpssi);
1587 
1588     HAL_PSSI_DISABLE(hpssi);
1589 
1590     /* Set CKSRC to ClockSource */
1591     MODIFY_REG(hpssi->Instance->CR, PSSI_CR_CKSRC, ClockSource);
1592 
1593     HAL_PSSI_ENABLE(hpssi);
1594 
1595     /* Process Unlocked */
1596     __HAL_UNLOCK(hpssi);
1597 
1598     return HAL_OK;
1599   }
1600   else
1601   {
1602     return HAL_BUSY;
1603   }
1604 }
1605 
1606 /**
1607   * @}
1608   */
1609 
1610 /**
1611   * @}
1612   */
1613 
1614 /** @addtogroup PSSI_Private_Functions
1615   * @{
1616   */
1617 
1618 /**
1619   * @brief  PSSI Errors process.
1620   * @param  hpssi PSSI handle.
1621   * @param  ErrorCode Error code to handle.
1622   * @retval None
1623   */
PSSI_Error(PSSI_HandleTypeDef * hpssi,uint32_t ErrorCode)1624 static void PSSI_Error(PSSI_HandleTypeDef *hpssi, uint32_t ErrorCode)
1625 {
1626   /* Reset handle parameters */
1627   hpssi->XferCount     = 0U;
1628 
1629   /* Set new error code */
1630   hpssi->ErrorCode |= ErrorCode;
1631 
1632   /* Disable all interrupts */
1633   HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1634 
1635 #if defined(HAL_DMA_MODULE_ENABLED)
1636   /* Abort DMA TX transfer if any */
1637   if ((hpssi->Instance->CR & PSSI_CR_DMAEN) == PSSI_CR_DMAEN)
1638   {
1639     if (hpssi->State == HAL_PSSI_STATE_BUSY_TX)
1640     {
1641       hpssi->Instance->CR &= ~PSSI_CR_DMAEN;
1642 
1643       if (hpssi->hdmatx != NULL)
1644       {
1645         /* Set the PSSI DMA Abort callback :
1646         will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */
1647         hpssi->hdmatx->XferAbortCallback = PSSI_DMAAbort;
1648 
1649         /* Process Unlocked */
1650         __HAL_UNLOCK(hpssi);
1651 
1652         /* Abort DMA TX */
1653         if (HAL_DMA_Abort_IT(hpssi->hdmatx) != HAL_OK)
1654         {
1655           /* Call Directly XferAbortCallback function in case of error */
1656           hpssi->hdmatx->XferAbortCallback(hpssi->hdmatx);
1657         }
1658       }
1659     }
1660     /* Abort DMA RX transfer if any */
1661     else if (hpssi->State == HAL_PSSI_STATE_BUSY_RX)
1662     {
1663       hpssi->Instance->CR &= ~PSSI_CR_DMAEN;
1664 
1665       if (hpssi->hdmarx != NULL)
1666       {
1667         /* Set the PSSI DMA Abort callback :
1668         will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */
1669         hpssi->hdmarx->XferAbortCallback = PSSI_DMAAbort;
1670 
1671         /* Process Unlocked */
1672         __HAL_UNLOCK(hpssi);
1673 
1674         /* Abort DMA RX */
1675         if (HAL_DMA_Abort_IT(hpssi->hdmarx) != HAL_OK)
1676         {
1677           /* Call Directly hpssi->hdma->XferAbortCallback function in case of error */
1678           hpssi->hdmarx->XferAbortCallback(hpssi->hdmarx);
1679         }
1680       }
1681     }
1682     else
1683     {
1684       /*Nothing to do*/
1685     }
1686   }
1687 #endif /*HAL_DMA_MODULE_ENABLED*/
1688 
1689   /* If state is an abort treatment on going, don't change state */
1690   if (hpssi->State == HAL_PSSI_STATE_ABORT)
1691   {
1692     hpssi->State = HAL_PSSI_STATE_READY;
1693 
1694     /* Process Unlocked */
1695     __HAL_UNLOCK(hpssi);
1696 
1697     /* Call the corresponding callback to inform upper layer of End of Transfer */
1698 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
1699     hpssi->AbortCpltCallback(hpssi);
1700 #else
1701     HAL_PSSI_AbortCpltCallback(hpssi);
1702 #endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */
1703   }
1704   else
1705   {
1706     /* Set HAL_PSSI_STATE_READY */
1707     hpssi->State = HAL_PSSI_STATE_READY;
1708 
1709     /* Process Unlocked */
1710     __HAL_UNLOCK(hpssi);
1711 
1712     /* Call the corresponding callback to inform upper layer of End of Transfer */
1713 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
1714     hpssi->ErrorCallback(hpssi);
1715 #else
1716     HAL_PSSI_ErrorCallback(hpssi);
1717 #endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */
1718   }
1719 }
1720 
1721 #if defined(HAL_DMA_MODULE_ENABLED)
1722 /**
1723   * @brief  DMA PSSI slave transmit process complete callback.
1724   * @param  hdma DMA handle
1725   * @retval None
1726   */
PSSI_DMATransmitCplt(DMA_HandleTypeDef * hdma)1727 void PSSI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1728 {
1729   /* Derogation MISRAC2012-Rule-11.5 */
1730   PSSI_HandleTypeDef *hpssi = (PSSI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
1731 
1732   uint32_t tmperror;
1733 
1734   /* Disable Interrupts */
1735   HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1736 
1737   /* Store current volatile hpssi->ErrorCode, misra rule */
1738   tmperror = hpssi->ErrorCode;
1739 
1740   /* Call the corresponding callback to inform upper layer of End of Transfer */
1741   if ((hpssi->State == HAL_PSSI_STATE_ABORT) || (tmperror != HAL_PSSI_ERROR_NONE))
1742   {
1743     /* Call the corresponding callback to inform upper layer of End of Transfer */
1744     PSSI_Error(hpssi, hpssi->ErrorCode);
1745   }
1746   /* hpssi->State == HAL_PSSI_STATE_BUSY_TX */
1747   else
1748   {
1749     hpssi->State = HAL_PSSI_STATE_READY;
1750 
1751     /* Process Unlocked */
1752     __HAL_UNLOCK(hpssi);
1753 
1754     /* Call the corresponding callback to inform upper layer of End of Transfer */
1755 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
1756     hpssi->TxCpltCallback(hpssi);
1757 #else
1758     HAL_PSSI_TxCpltCallback(hpssi);
1759 #endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */
1760   }
1761 }
1762 
1763 /**
1764   * @brief DMA PSSI master receive process complete callback.
1765   * @param  hdma DMA handle
1766   * @retval None
1767   */
PSSI_DMAReceiveCplt(DMA_HandleTypeDef * hdma)1768 void PSSI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1769 {
1770   /* Derogation MISRAC2012-Rule-11.5 */
1771   PSSI_HandleTypeDef *hpssi = (PSSI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
1772 
1773   uint32_t tmperror;
1774 
1775   /* Disable Interrupts */
1776   HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1777 
1778   /* Store current volatile hpssi->ErrorCode, misra rule */
1779   tmperror = hpssi->ErrorCode;
1780 
1781   /* Call the corresponding callback to inform upper layer of End of Transfer */
1782   if ((hpssi->State == HAL_PSSI_STATE_ABORT) || (tmperror != HAL_PSSI_ERROR_NONE))
1783   {
1784     /* Call the corresponding callback to inform upper layer of End of Transfer */
1785     PSSI_Error(hpssi, hpssi->ErrorCode);
1786   }
1787   /* hpssi->State == HAL_PSSI_STATE_BUSY_RX */
1788   else
1789   {
1790     hpssi->State = HAL_PSSI_STATE_READY;
1791 
1792     /* Process Unlocked */
1793     __HAL_UNLOCK(hpssi);
1794 
1795     /* Call the corresponding callback to inform upper layer of End of Transfer */
1796 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
1797     hpssi->RxCpltCallback(hpssi);
1798 #else
1799     HAL_PSSI_RxCpltCallback(hpssi);
1800 #endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */
1801   }
1802 }
1803 
1804 /**
1805   * @brief DMA PSSI communication abort callback
1806   *        (To be called at end of DMA Abort procedure).
1807   * @param hdma DMA handle.
1808   * @retval None
1809   */
PSSI_DMAAbort(DMA_HandleTypeDef * hdma)1810 void PSSI_DMAAbort(DMA_HandleTypeDef *hdma)
1811 {
1812   /* Derogation MISRAC2012-Rule-11.5 */
1813   PSSI_HandleTypeDef *hpssi = (PSSI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
1814 
1815   /* Reset AbortCpltCallback */
1816   hpssi->hdmatx->XferAbortCallback = NULL;
1817   hpssi->hdmarx->XferAbortCallback = NULL;
1818 
1819   /* Check if come from abort from user */
1820   if (hpssi->State == HAL_PSSI_STATE_ABORT)
1821   {
1822     hpssi->State = HAL_PSSI_STATE_READY;
1823 
1824     /* Call the corresponding callback to inform upper layer of End of Transfer */
1825 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
1826     hpssi->AbortCpltCallback(hpssi);
1827 #else
1828     HAL_PSSI_AbortCpltCallback(hpssi);
1829 #endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */
1830   }
1831   else
1832   {
1833     /* Call the corresponding callback to inform upper layer of End of Transfer */
1834 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
1835     hpssi->ErrorCallback(hpssi);
1836 #else
1837     HAL_PSSI_ErrorCallback(hpssi);
1838 #endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */
1839   }
1840 }
1841 #endif /*HAL_DMA_MODULE_ENABLED*/
1842 
1843 /**
1844   * @brief  This function handles PSSI Communication Timeout.
1845   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1846   *                the configuration information for the specified PSSI.
1847   * @param  Flag Specifies the PSSI flag to check.
1848   * @param  Status The new Flag status (SET or RESET).
1849   * @param  Timeout Timeout duration
1850   * @param  Tickstart Tick start value
1851   * @retval HAL status
1852   */
PSSI_WaitOnStatusUntilTimeout(PSSI_HandleTypeDef * hpssi,uint32_t Flag,FlagStatus Status,uint32_t Timeout,uint32_t Tickstart)1853 static HAL_StatusTypeDef PSSI_WaitOnStatusUntilTimeout(PSSI_HandleTypeDef *hpssi, uint32_t Flag, FlagStatus Status,
1854                                                        uint32_t Timeout, uint32_t Tickstart)
1855 {
1856   while ((HAL_PSSI_GET_STATUS(hpssi, Flag) & Flag) == (uint32_t)Status)
1857   {
1858     /* Check for the Timeout */
1859     if (Timeout != HAL_MAX_DELAY)
1860     {
1861       if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
1862       {
1863         hpssi->ErrorCode |= HAL_PSSI_ERROR_TIMEOUT;
1864         hpssi->State = HAL_PSSI_STATE_READY;
1865 
1866         /* Process Unlocked */
1867         __HAL_UNLOCK(hpssi);
1868 
1869         return HAL_ERROR;
1870       }
1871     }
1872   }
1873   return HAL_OK;
1874 }
1875 
1876 #if defined(HAL_DMA_MODULE_ENABLED)
PSSI_DMAError(DMA_HandleTypeDef * hdma)1877 void PSSI_DMAError(DMA_HandleTypeDef *hdma)
1878 {
1879   /* Derogation MISRAC2012-Rule-11.5 */
1880   PSSI_HandleTypeDef *hpssi = (PSSI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
1881 
1882   uint32_t tmperror;
1883 
1884   /* Disable the selected PSSI peripheral */
1885   HAL_PSSI_DISABLE(hpssi);
1886 
1887   /* Disable Interrupts */
1888   HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1889 
1890   /* Store current volatile hpssi->ErrorCode, misra rule */
1891   tmperror = hpssi->ErrorCode;
1892 
1893   /* Call the corresponding callback to inform upper layer of End of Transfer */
1894   if ((hpssi->State == HAL_PSSI_STATE_ABORT) || (tmperror != HAL_PSSI_ERROR_NONE))
1895   {
1896     /* Call the corresponding callback to inform upper layer of End of Transfer */
1897     PSSI_Error(hpssi, hpssi->ErrorCode);
1898   }
1899   else
1900   {
1901     hpssi->State = HAL_PSSI_STATE_READY;
1902 
1903     /* Process Unlocked */
1904     __HAL_UNLOCK(hpssi);
1905 
1906     /* Call the corresponding callback to inform upper layer of End of Transfer */
1907 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
1908     hpssi->ErrorCallback(hpssi);
1909 #else
1910     HAL_PSSI_ErrorCallback(hpssi);
1911 #endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */
1912   }
1913 }
1914 #endif /*HAL_DMA_MODULE_ENABLED*/
1915 
1916 
1917 /**
1918   * @}
1919   */
1920 #endif /* PSSI */
1921 #endif /* HAL_PSSI_MODULE_ENABLED */
1922 /**
1923   * @}
1924   */
1925 
1926 /**
1927   * @}
1928   */
1929