1 /**
2   ******************************************************************************
3   * @file    stm32u5xx_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) 2019 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 
57     (#) For PSSI IO operations, two operation modes are available within this driver :
58 
59     *** Polling mode IO operation ***
60     =================================
61     [..]
62       (+) Transmit an amount of data by byte in blocking mode using @ref HAL_PSSI_Transmit()
63       (+) Receive an amount of data by byte in blocking mode using @ref HAL_PSSI_Receive()
64 
65     *** DMA mode IO operation ***
66     ==============================
67     [..]
68       (+) Transmit an amount of data in non-blocking mode (DMA) using
69           @ref HAL_PSSI_Transmit_DMA()
70       (+) At transmission end of transfer, @ref HAL_PSSI_TxCpltCallback() is executed and user can
71            add his own code by customization of function pointer @ref HAL_PSSI_TxCpltCallback()
72       (+) Receive an amount of data in non-blocking mode (DMA) using
73           @ref HAL_PSSI_Receive_DMA()
74       (+) At reception end of transfer, @ref HAL_PSSI_RxCpltCallback() is executed and user can
75            add his own code by customization of function pointer @ref HAL_PSSI_RxCpltCallback()
76       (+) In case of transfer Error, @ref HAL_PSSI_ErrorCallback() function is executed and user can
77            add his own code by customization of function pointer @ref HAL_PSSI_ErrorCallback()
78       (+) Abort a  PSSI process communication with Interrupt using @ref HAL_PSSI_Abort_IT()
79       (+) End of abort process, @ref HAL_PSSI_AbortCpltCallback() is executed and user can
80            add his own code by customization of function pointer @ref HAL_PSSI_AbortCpltCallback()
81 
82      *** PSSI HAL driver macros list ***
83      ==================================
84      [..]
85        Below the list of most used macros in PSSI HAL driver.
86 
87       (+) @ref HAL_PSSI_ENABLE     : Enable the PSSI peripheral
88       (+) @ref HAL_PSSI_DISABLE    : Disable the PSSI peripheral
89       (+) @ref HAL_PSSI_GET_FLAG   : Check whether the specified PSSI flag is set or not
90       (+) @ref HAL_PSSI_CLEAR_FLAG : Clear the specified PSSI pending flag
91       (+) @ref HAL_PSSI_ENABLE_IT  : Enable the specified PSSI interrupt
92       (+) @ref HAL_PSSI_DISABLE_IT : Disable the specified PSSI interrupt
93 
94      *** Callback registration ***
95      =============================================
96      Use Functions @ref HAL_PSSI_RegisterCallback() or @ref HAL_PSSI_RegisterAddrCallback()
97      to register an interrupt callback.
98 
99      Function @ref HAL_PSSI_RegisterCallback() allows to register following callbacks:
100        (+) TxCpltCallback       : callback for transmission end of transfer.
101        (+) RxCpltCallback       : callback for reception end of transfer.
102        (+) ErrorCallback        : callback for error detection.
103        (+) AbortCpltCallback    : callback for abort completion process.
104        (+) MspInitCallback      : callback for Msp Init.
105        (+) MspDeInitCallback    : callback for Msp DeInit.
106      This function takes as parameters the HAL peripheral handle, the Callback ID
107      and a pointer to the user callback function.
108 
109 
110      Use function @ref HAL_PSSI_UnRegisterCallback to reset a callback to the default
111      weak function.
112      @ref HAL_PSSI_UnRegisterCallback takes as parameters the HAL peripheral handle,
113      and the Callback ID.
114      This function allows to reset following callbacks:
115        (+) TxCpltCallback       : callback for transmission end of transfer.
116        (+) RxCpltCallback       : callback for reception end of transfer.
117        (+) ErrorCallback        : callback for error detection.
118        (+) AbortCpltCallback    : callback for abort completion process.
119        (+) MspInitCallback      : callback for Msp Init.
120        (+) MspDeInitCallback    : callback for Msp DeInit.
121 
122 
123      By default, after the @ref HAL_PSSI_Init() and when the state is @ref HAL_PSSI_STATE_RESET
124      all callbacks are set to the corresponding weak functions:
125      examples @ref HAL_PSSI_TxCpltCallback(), @ref HAL_PSSI_RxCpltCallback().
126      Exception done for MspInit and MspDeInit functions that are
127      reset to the legacy weak functions in the @ref HAL_PSSI_Init()/ @ref HAL_PSSI_DeInit() only when
128      these callbacks are null (not registered beforehand).
129      If MspInit or MspDeInit are not null, the @ref HAL_PSSI_Init()/ @ref HAL_PSSI_DeInit()
130      keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
131 
132      Callbacks can be registered/unregistered in @ref HAL_PSSI_STATE_READY state only.
133      Exception done MspInit/MspDeInit functions that can be registered/unregistered
134      in @ref HAL_PSSI_STATE_READY or @ref HAL_PSSI_STATE_RESET state,
135      thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
136      Then, the user first registers the MspInit/MspDeInit user callbacks
137      using @ref HAL_PSSI_RegisterCallback() before calling @ref HAL_PSSI_DeInit()
138      or @ref HAL_PSSI_Init() function.
139 
140 
141      [..]
142        (@) You can refer to the PSSI HAL driver header file for more useful macros
143 
144   @endverbatim
145   */
146 
147 /* Includes ------------------------------------------------------------------*/
148 #include "stm32u5xx_hal.h"
149 
150 /** @addtogroup STM32U5xx_HAL_Driver
151   * @{
152   */
153 
154 /** @defgroup PSSI PSSI
155   * @brief PSSI HAL module driver
156   * @{
157   */
158 
159 #ifdef HAL_PSSI_MODULE_ENABLED
160 #if defined(PSSI)
161 /* Private typedef -----------------------------------------------------------*/
162 /* Private define ------------------------------------------------------------*/
163 
164 /** @defgroup PSSI_Private_Define PSSI Private Define
165   * @{
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     hpssi->Instance->CR |= PSSI_CR_OUTEN_OUTPUT |
655                            ((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     hpssi->Instance->CR |= PSSI_CR_OUTEN_INPUT |
808                            ((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->hdmatx->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 /**
1553   * @}
1554   */
1555 
1556 /** @addtogroup PSSI_Private_Functions
1557   * @{
1558   */
1559 
1560 /**
1561   * @brief  PSSI Errors process.
1562   * @param  hpssi PSSI handle.
1563   * @param  ErrorCode Error code to handle.
1564   * @retval None
1565   */
PSSI_Error(PSSI_HandleTypeDef * hpssi,uint32_t ErrorCode)1566 static void PSSI_Error(PSSI_HandleTypeDef *hpssi, uint32_t ErrorCode)
1567 {
1568   /* Reset handle parameters */
1569   hpssi->XferCount     = 0U;
1570 
1571   /* Set new error code */
1572   hpssi->ErrorCode |= ErrorCode;
1573 
1574   /* Disable all interrupts */
1575   HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1576 
1577 #if defined(HAL_DMA_MODULE_ENABLED)
1578   /* Abort DMA TX transfer if any */
1579   if ((hpssi->Instance->CR & PSSI_CR_DMAEN) == PSSI_CR_DMAEN)
1580   {
1581     if (hpssi->State == HAL_PSSI_STATE_BUSY_TX)
1582     {
1583       hpssi->Instance->CR &= ~PSSI_CR_DMAEN;
1584 
1585       if (hpssi->hdmatx != NULL)
1586       {
1587         /* Set the PSSI DMA Abort callback :
1588         will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */
1589         hpssi->hdmatx->XferAbortCallback = PSSI_DMAAbort;
1590 
1591         /* Process Unlocked */
1592         __HAL_UNLOCK(hpssi);
1593 
1594         /* Abort DMA TX */
1595         if (HAL_DMA_Abort_IT(hpssi->hdmatx) != HAL_OK)
1596         {
1597           /* Call Directly XferAbortCallback function in case of error */
1598           hpssi->hdmatx->XferAbortCallback(hpssi->hdmatx);
1599         }
1600       }
1601     }
1602     /* Abort DMA RX transfer if any */
1603     else if (hpssi->State == HAL_PSSI_STATE_BUSY_RX)
1604     {
1605       hpssi->Instance->CR &= ~PSSI_CR_DMAEN;
1606 
1607       if (hpssi->hdmarx != NULL)
1608       {
1609         /* Set the PSSI DMA Abort callback :
1610         will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */
1611         hpssi->hdmarx->XferAbortCallback = PSSI_DMAAbort;
1612 
1613         /* Process Unlocked */
1614         __HAL_UNLOCK(hpssi);
1615 
1616         /* Abort DMA RX */
1617         if (HAL_DMA_Abort_IT(hpssi->hdmarx) != HAL_OK)
1618         {
1619           /* Call Directly hpssi->hdma->XferAbortCallback function in case of error */
1620           hpssi->hdmarx->XferAbortCallback(hpssi->hdmarx);
1621         }
1622       }
1623     }
1624     else
1625     {
1626       /*Nothing to do*/
1627     }
1628   }
1629 #endif /*HAL_DMA_MODULE_ENABLED*/
1630 
1631   /* If state is an abort treatment on going, don't change state */
1632   if (hpssi->State == HAL_PSSI_STATE_ABORT)
1633   {
1634     hpssi->State = HAL_PSSI_STATE_READY;
1635 
1636     /* Process Unlocked */
1637     __HAL_UNLOCK(hpssi);
1638 
1639     /* Call the corresponding callback to inform upper layer of End of Transfer */
1640 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
1641     hpssi->AbortCpltCallback(hpssi);
1642 #else
1643     HAL_PSSI_AbortCpltCallback(hpssi);
1644 #endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */
1645   }
1646   else
1647   {
1648     /* Set HAL_PSSI_STATE_READY */
1649     hpssi->State = HAL_PSSI_STATE_READY;
1650 
1651     /* Process Unlocked */
1652     __HAL_UNLOCK(hpssi);
1653 
1654     /* Call the corresponding callback to inform upper layer of End of Transfer */
1655 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
1656     hpssi->ErrorCallback(hpssi);
1657 #else
1658     HAL_PSSI_ErrorCallback(hpssi);
1659 #endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */
1660   }
1661 }
1662 
1663 #if defined(HAL_DMA_MODULE_ENABLED)
1664 /**
1665   * @brief  DMA PSSI slave transmit process complete callback.
1666   * @param  hdma DMA handle
1667   * @retval None
1668   */
PSSI_DMATransmitCplt(DMA_HandleTypeDef * hdma)1669 void PSSI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1670 {
1671   /* Derogation MISRAC2012-Rule-11.5 */
1672   PSSI_HandleTypeDef *hpssi = (PSSI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
1673 
1674   uint32_t tmperror;
1675 
1676   /* Disable Interrupts */
1677   HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1678 
1679   /* Store current volatile hpssi->ErrorCode, misra rule */
1680   tmperror = hpssi->ErrorCode;
1681 
1682   /* Call the corresponding callback to inform upper layer of End of Transfer */
1683   if ((hpssi->State == HAL_PSSI_STATE_ABORT) || (tmperror != HAL_PSSI_ERROR_NONE))
1684   {
1685     /* Call the corresponding callback to inform upper layer of End of Transfer */
1686     PSSI_Error(hpssi, hpssi->ErrorCode);
1687   }
1688   /* hpssi->State == HAL_PSSI_STATE_BUSY_TX */
1689   else
1690   {
1691     hpssi->State = HAL_PSSI_STATE_READY;
1692 
1693     /* Process Unlocked */
1694     __HAL_UNLOCK(hpssi);
1695 
1696     /* Call the corresponding callback to inform upper layer of End of Transfer */
1697 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
1698     hpssi->TxCpltCallback(hpssi);
1699 #else
1700     HAL_PSSI_TxCpltCallback(hpssi);
1701 #endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */
1702   }
1703 }
1704 
1705 /**
1706   * @brief DMA PSSI master receive process complete callback.
1707   * @param  hdma DMA handle
1708   * @retval None
1709   */
PSSI_DMAReceiveCplt(DMA_HandleTypeDef * hdma)1710 void PSSI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1711 {
1712   /* Derogation MISRAC2012-Rule-11.5 */
1713   PSSI_HandleTypeDef *hpssi = (PSSI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
1714 
1715   uint32_t tmperror;
1716 
1717   /* Disable Interrupts */
1718   HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1719 
1720   /* Store current volatile hpssi->ErrorCode, misra rule */
1721   tmperror = hpssi->ErrorCode;
1722 
1723   /* Call the corresponding callback to inform upper layer of End of Transfer */
1724   if ((hpssi->State == HAL_PSSI_STATE_ABORT) || (tmperror != HAL_PSSI_ERROR_NONE))
1725   {
1726     /* Call the corresponding callback to inform upper layer of End of Transfer */
1727     PSSI_Error(hpssi, hpssi->ErrorCode);
1728   }
1729   /* hpssi->State == HAL_PSSI_STATE_BUSY_RX */
1730   else
1731   {
1732     hpssi->State = HAL_PSSI_STATE_READY;
1733 
1734     /* Process Unlocked */
1735     __HAL_UNLOCK(hpssi);
1736 
1737     /* Call the corresponding callback to inform upper layer of End of Transfer */
1738 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
1739     hpssi->RxCpltCallback(hpssi);
1740 #else
1741     HAL_PSSI_RxCpltCallback(hpssi);
1742 #endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */
1743   }
1744 }
1745 
1746 /**
1747   * @brief DMA PSSI communication abort callback
1748   *        (To be called at end of DMA Abort procedure).
1749   * @param hdma DMA handle.
1750   * @retval None
1751   */
PSSI_DMAAbort(DMA_HandleTypeDef * hdma)1752 void PSSI_DMAAbort(DMA_HandleTypeDef *hdma)
1753 {
1754   /* Derogation MISRAC2012-Rule-11.5 */
1755   PSSI_HandleTypeDef *hpssi = (PSSI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
1756 
1757   /* Reset AbortCpltCallback */
1758   hpssi->hdmatx->XferAbortCallback = NULL;
1759   hpssi->hdmarx->XferAbortCallback = NULL;
1760 
1761   /* Check if come from abort from user */
1762   if (hpssi->State == HAL_PSSI_STATE_ABORT)
1763   {
1764     hpssi->State = HAL_PSSI_STATE_READY;
1765 
1766     /* Call the corresponding callback to inform upper layer of End of Transfer */
1767 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
1768     hpssi->AbortCpltCallback(hpssi);
1769 #else
1770     HAL_PSSI_AbortCpltCallback(hpssi);
1771 #endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */
1772   }
1773   else
1774   {
1775     /* Call the corresponding callback to inform upper layer of End of Transfer */
1776 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
1777     hpssi->ErrorCallback(hpssi);
1778 #else
1779     HAL_PSSI_ErrorCallback(hpssi);
1780 #endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */
1781   }
1782 }
1783 #endif /*HAL_DMA_MODULE_ENABLED*/
1784 
1785 /**
1786   * @brief  This function handles PSSI Communication Timeout.
1787   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1788   *                the configuration information for the specified PSSI.
1789   * @param  Flag Specifies the PSSI flag to check.
1790   * @param  Status The new Flag status (SET or RESET).
1791   * @param  Timeout Timeout duration
1792   * @param  Tickstart Tick start value
1793   * @retval HAL status
1794   */
PSSI_WaitOnStatusUntilTimeout(PSSI_HandleTypeDef * hpssi,uint32_t Flag,FlagStatus Status,uint32_t Timeout,uint32_t Tickstart)1795 static HAL_StatusTypeDef PSSI_WaitOnStatusUntilTimeout(PSSI_HandleTypeDef *hpssi, uint32_t Flag, FlagStatus Status,
1796                                                        uint32_t Timeout, uint32_t Tickstart)
1797 {
1798   while ((HAL_PSSI_GET_STATUS(hpssi, Flag) & Flag) == (uint32_t)Status)
1799   {
1800     /* Check for the Timeout */
1801     if (Timeout != HAL_MAX_DELAY)
1802     {
1803       if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
1804       {
1805         hpssi->ErrorCode |= HAL_PSSI_ERROR_TIMEOUT;
1806         hpssi->State = HAL_PSSI_STATE_READY;
1807 
1808         /* Process Unlocked */
1809         __HAL_UNLOCK(hpssi);
1810 
1811         return HAL_ERROR;
1812       }
1813     }
1814   }
1815   return HAL_OK;
1816 }
1817 
1818 #if defined(HAL_DMA_MODULE_ENABLED)
PSSI_DMAError(DMA_HandleTypeDef * hdma)1819 void PSSI_DMAError(DMA_HandleTypeDef *hdma)
1820 {
1821   /* Derogation MISRAC2012-Rule-11.5 */
1822   PSSI_HandleTypeDef *hpssi = (PSSI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
1823 
1824   uint32_t tmperror;
1825 
1826   /* Disable the selected PSSI peripheral */
1827   HAL_PSSI_DISABLE(hpssi);
1828 
1829   /* Disable Interrupts */
1830   HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1831 
1832   /* Store current volatile hpssi->ErrorCode, misra rule */
1833   tmperror = hpssi->ErrorCode;
1834 
1835   /* Call the corresponding callback to inform upper layer of End of Transfer */
1836   if ((hpssi->State == HAL_PSSI_STATE_ABORT) || (tmperror != HAL_PSSI_ERROR_NONE))
1837   {
1838     /* Call the corresponding callback to inform upper layer of End of Transfer */
1839     PSSI_Error(hpssi, hpssi->ErrorCode);
1840   }
1841   else
1842   {
1843     hpssi->State = HAL_PSSI_STATE_READY;
1844 
1845     /* Process Unlocked */
1846     __HAL_UNLOCK(hpssi);
1847 
1848     /* Call the corresponding callback to inform upper layer of End of Transfer */
1849 #if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1)
1850     hpssi->ErrorCallback(hpssi);
1851 #else
1852     HAL_PSSI_ErrorCallback(hpssi);
1853 #endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */
1854   }
1855 }
1856 #endif /*HAL_DMA_MODULE_ENABLED*/
1857 
1858 
1859 /**
1860   * @}
1861   */
1862 #endif /* PSSI */
1863 #endif /* HAL_PSSI_MODULE_ENABLED */
1864 /**
1865   * @}
1866   */
1867 
1868 /**
1869   * @}
1870   */
1871