1 /**
2   ******************************************************************************
3   * @file    stm32h5xx_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) 2022 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 "stm32h5xx_hal.h"
149 
150 /** @addtogroup STM32H5xx_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     /* Init the PSSI Callback settings */
269     hpssi->TxCpltCallback = HAL_PSSI_TxCpltCallback; /* Legacy weak TxCpltCallback */
270     hpssi->RxCpltCallback = HAL_PSSI_RxCpltCallback; /* Legacy weak RxCpltCallback */
271     hpssi->ErrorCallback        = HAL_PSSI_ErrorCallback;        /* Legacy weak ErrorCallback        */
272     hpssi->AbortCpltCallback    = HAL_PSSI_AbortCpltCallback;    /* Legacy weak AbortCpltCallback    */
273 
274     if (hpssi->MspInitCallback == NULL)
275     {
276       hpssi->MspInitCallback = HAL_PSSI_MspInit; /* Legacy weak MspInit  */
277     }
278 
279     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
280     hpssi->MspInitCallback(hpssi);
281 
282   }
283 
284   hpssi->State = HAL_PSSI_STATE_BUSY;
285 
286   /* Disable the selected PSSI peripheral */
287   HAL_PSSI_DISABLE(hpssi);
288 
289   /*---------------------------- PSSIx CR Configuration ----------------------*/
290   /* Configure PSSIx: Control Signal and Bus Width*/
291 
292   MODIFY_REG(hpssi->Instance->CR, PSSI_CR_DERDYCFG | PSSI_CR_EDM | PSSI_CR_DEPOL | PSSI_CR_RDYPOL,
293              hpssi->Init.ControlSignal | hpssi->Init.DataEnablePolarity |
294              hpssi->Init.ReadyPolarity | hpssi->Init.BusWidth);
295 
296   hpssi->ErrorCode = HAL_PSSI_ERROR_NONE;
297   hpssi->State = HAL_PSSI_STATE_READY;
298 
299   return HAL_OK;
300 }
301 
302 /**
303   * @brief  DeInitialize the PSSI peripheral.
304   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
305   *                the configuration information for the specified PSSI.
306   * @retval HAL status
307   */
HAL_PSSI_DeInit(PSSI_HandleTypeDef * hpssi)308 HAL_StatusTypeDef HAL_PSSI_DeInit(PSSI_HandleTypeDef *hpssi)
309 {
310   /* Check the PSSI handle allocation */
311   if (hpssi == NULL)
312   {
313     return HAL_ERROR;
314   }
315 
316   /* Check the parameters */
317   assert_param(IS_PSSI_ALL_INSTANCE(hpssi->Instance));
318 
319   hpssi->State = HAL_PSSI_STATE_BUSY;
320 
321   /* Disable the PSSI Peripheral Clock */
322   HAL_PSSI_DISABLE(hpssi);
323 
324   if (hpssi->MspDeInitCallback == NULL)
325   {
326     hpssi->MspDeInitCallback = HAL_PSSI_MspDeInit; /* Legacy weak MspDeInit  */
327   }
328 
329   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
330   hpssi->MspDeInitCallback(hpssi);
331 
332   hpssi->ErrorCode = HAL_PSSI_ERROR_NONE;
333   hpssi->State = HAL_PSSI_STATE_RESET;
334 
335   /* Release Lock */
336   __HAL_UNLOCK(hpssi);
337 
338   return HAL_OK;
339 }
340 
341 /**
342   * @brief Initialize the PSSI MSP.
343   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
344   *                the configuration information for the specified PSSI.
345   * @retval None
346   */
HAL_PSSI_MspInit(PSSI_HandleTypeDef * hpssi)347 __weak void HAL_PSSI_MspInit(PSSI_HandleTypeDef *hpssi)
348 {
349   /* Prevent unused argument(s) compilation warning */
350   UNUSED(hpssi);
351 
352   /* NOTE : This function should not be modified, when the callback is needed,
353             the HAL_PSSI_MspInit can be implemented in the user file
354    */
355 }
356 
357 /**
358   * @brief De-Initialize the PSSI MSP.
359   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
360   *                the configuration information for the specified PSSI.
361   * @retval None
362   */
HAL_PSSI_MspDeInit(PSSI_HandleTypeDef * hpssi)363 __weak void HAL_PSSI_MspDeInit(PSSI_HandleTypeDef *hpssi)
364 {
365   /* Prevent unused argument(s) compilation warning */
366   UNUSED(hpssi);
367 
368   /* NOTE : This function should not be modified; when the callback is needed,
369             the HAL_PSSI_MspDeInit can be implemented in the user file
370    */
371 }
372 
373 /**
374   * @brief  Register a User PSSI Callback
375   *         To be used instead of the weak predefined callback
376   * @note   The HAL_PSSI_RegisterCallback() may be called before HAL_PSSI_Init() in
377   *         HAL_PSSI_STATE_RESET to register callbacks for HAL_PSSI_MSPINIT_CB_ID
378   *         and HAL_PSSI_MSPDEINIT_CB_ID.
379   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
380   *                the configuration information for the specified PSSI.
381   * @param  CallbackID ID of the callback to be registered
382   *         This parameter can be one of the following values:
383   *          @arg @ref HAL_PSSI_TX_COMPLETE_CB_ID  Tx Transfer completed callback ID
384   *          @arg @ref HAL_PSSI_RX_COMPLETE_CB_ID  Rx Transfer completed callback ID
385   *          @arg @ref HAL_PSSI_ERROR_CB_ID Error callback ID
386   *          @arg @ref HAL_PSSI_ABORT_CB_ID Abort callback ID
387   *          @arg @ref HAL_PSSI_MSPINIT_CB_ID MspInit callback ID
388   *          @arg @ref HAL_PSSI_MSPDEINIT_CB_ID MspDeInit callback ID
389   * @param  pCallback pointer to the Callback function
390   * @retval HAL status
391   */
HAL_PSSI_RegisterCallback(PSSI_HandleTypeDef * hpssi,HAL_PSSI_CallbackIDTypeDef CallbackID,pPSSI_CallbackTypeDef pCallback)392 HAL_StatusTypeDef HAL_PSSI_RegisterCallback(PSSI_HandleTypeDef *hpssi, HAL_PSSI_CallbackIDTypeDef CallbackID,
393                                             pPSSI_CallbackTypeDef pCallback)
394 {
395   HAL_StatusTypeDef status = HAL_OK;
396 
397   if (pCallback == NULL)
398   {
399     /* Update the error code */
400     hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
401 
402     return HAL_ERROR;
403   }
404 
405   if (HAL_PSSI_STATE_READY == hpssi->State)
406   {
407     switch (CallbackID)
408     {
409       case HAL_PSSI_TX_COMPLETE_CB_ID :
410         hpssi->TxCpltCallback = pCallback;
411         break;
412 
413       case HAL_PSSI_RX_COMPLETE_CB_ID :
414         hpssi->RxCpltCallback = pCallback;
415         break;
416 
417       case HAL_PSSI_ERROR_CB_ID :
418         hpssi->ErrorCallback = pCallback;
419         break;
420 
421       case HAL_PSSI_ABORT_CB_ID :
422         hpssi->AbortCpltCallback = pCallback;
423         break;
424 
425       case HAL_PSSI_MSPINIT_CB_ID :
426         hpssi->MspInitCallback = pCallback;
427         break;
428 
429       case HAL_PSSI_MSPDEINIT_CB_ID :
430         hpssi->MspDeInitCallback = pCallback;
431         break;
432 
433       default :
434         /* Update the error code */
435         hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
436 
437         /* Return error status */
438         status =  HAL_ERROR;
439         break;
440     }
441   }
442   else if (HAL_PSSI_STATE_RESET == hpssi->State)
443   {
444     switch (CallbackID)
445     {
446       case HAL_PSSI_MSPINIT_CB_ID :
447         hpssi->MspInitCallback = pCallback;
448         break;
449 
450       case HAL_PSSI_MSPDEINIT_CB_ID :
451         hpssi->MspDeInitCallback = pCallback;
452         break;
453 
454       default :
455         /* Update the error code */
456         hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
457 
458         /* Return error status */
459         status =  HAL_ERROR;
460         break;
461     }
462   }
463   else
464   {
465     /* Update the error code */
466     hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
467 
468     /* Return error status */
469     status =  HAL_ERROR;
470   }
471 
472   return status;
473 }
474 
475 /**
476   * @brief  Unregister an PSSI Callback
477   *         PSSI callback is redirected to the weak predefined callback
478   * @note   The HAL_PSSI_UnRegisterCallback() may be called before HAL_PSSI_Init() in
479   *         HAL_PSSI_STATE_RESET to un-register callbacks for HAL_PSSI_MSPINIT_CB_ID
480   *         and HAL_PSSI_MSPDEINIT_CB_ID.
481   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
482   *                the configuration information for the specified PSSI.
483   * @param  CallbackID ID of the callback to be unregistered
484   *         This parameter can be one of the following values:
485   *          @arg @ref HAL_PSSI_TX_COMPLETE_CB_ID  Tx Transfer completed callback ID
486   *          @arg @ref HAL_PSSI_RX_COMPLETE_CB_ID  Rx Transfer completed callback ID
487   *          @arg @ref HAL_PSSI_ERROR_CB_ID Error callback ID
488   *          @arg @ref HAL_PSSI_ABORT_CB_ID Abort callback ID
489   *          @arg @ref HAL_PSSI_MSPINIT_CB_ID MspInit callback ID
490   *          @arg @ref HAL_PSSI_MSPDEINIT_CB_ID MspDeInit callback ID
491   * @retval HAL status
492   */
HAL_PSSI_UnRegisterCallback(PSSI_HandleTypeDef * hpssi,HAL_PSSI_CallbackIDTypeDef CallbackID)493 HAL_StatusTypeDef HAL_PSSI_UnRegisterCallback(PSSI_HandleTypeDef *hpssi, HAL_PSSI_CallbackIDTypeDef CallbackID)
494 {
495   HAL_StatusTypeDef status = HAL_OK;
496 
497   if (HAL_PSSI_STATE_READY == hpssi->State)
498   {
499     switch (CallbackID)
500     {
501       case HAL_PSSI_TX_COMPLETE_CB_ID :
502         hpssi->TxCpltCallback = HAL_PSSI_TxCpltCallback;             /* Legacy weak TxCpltCallback     */
503         break;
504 
505       case HAL_PSSI_RX_COMPLETE_CB_ID :
506         hpssi->RxCpltCallback = HAL_PSSI_RxCpltCallback;             /* Legacy weak RxCpltCallback     */
507         break;
508 
509       case HAL_PSSI_ERROR_CB_ID :
510         hpssi->ErrorCallback = HAL_PSSI_ErrorCallback;               /* Legacy weak ErrorCallback      */
511         break;
512 
513       case HAL_PSSI_ABORT_CB_ID :
514         hpssi->AbortCpltCallback = HAL_PSSI_AbortCpltCallback;       /* Legacy weak AbortCpltCallback  */
515         break;
516 
517       case HAL_PSSI_MSPINIT_CB_ID :
518         hpssi->MspInitCallback = HAL_PSSI_MspInit;                   /* Legacy weak MspInit            */
519         break;
520 
521       case HAL_PSSI_MSPDEINIT_CB_ID :
522         hpssi->MspDeInitCallback = HAL_PSSI_MspDeInit;               /* Legacy weak MspDeInit          */
523         break;
524 
525       default :
526         /* Update the error code */
527         hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
528 
529         /* Return error status */
530         status =  HAL_ERROR;
531         break;
532     }
533   }
534   else if (HAL_PSSI_STATE_RESET == hpssi->State)
535   {
536     switch (CallbackID)
537     {
538       case HAL_PSSI_MSPINIT_CB_ID :
539         hpssi->MspInitCallback = HAL_PSSI_MspInit;                   /* Legacy weak MspInit            */
540         break;
541 
542       case HAL_PSSI_MSPDEINIT_CB_ID :
543         hpssi->MspDeInitCallback = HAL_PSSI_MspDeInit;               /* Legacy weak MspDeInit          */
544         break;
545 
546       default :
547         /* Update the error code */
548         hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
549 
550         /* Return error status */
551         status =  HAL_ERROR;
552         break;
553     }
554   }
555   else
556   {
557     /* Update the error code */
558     hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
559 
560     /* Return error status */
561     status =  HAL_ERROR;
562   }
563 
564   return status;
565 }
566 
567 /**
568   * @}
569   */
570 
571 /** @defgroup PSSI_Exported_Functions_Group2 Input and Output operation functions
572   *  @brief   Data transfers functions
573   *
574 @verbatim
575  ===============================================================================
576                       ##### IO operation functions #####
577  ===============================================================================
578     [..]
579     This subsection provides a set of functions allowing to manage the PSSI data
580     transfers.
581 
582     (#) There are two modes of transfer:
583        (++) Blocking mode : The communication is performed in the polling mode.
584             The status of all data processing is returned by the same function
585             after finishing transfer.
586        (++) No-Blocking mode : The communication is performed using DMA.
587             These functions return the status of the transfer startup.
588             The end of the data processing will be indicated through the
589             dedicated  the DMA IRQ .
590 
591     (#) Blocking mode functions are :
592         (++) HAL_PSSI_Transmit()
593         (++) HAL_PSSI_Receive()
594 
595     (#) No-Blocking mode functions with DMA are :
596         (++) HAL_PSSI_Transmit_DMA()
597         (++) HAL_PSSI_Receive_DMA()
598 
599     (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
600         (++) HAL_PSSI_TxCpltCallback()
601         (++) HAL_PSSI_RxCpltCallback()
602         (++) HAL_PSSI_ErrorCallback()
603         (++) HAL_PSSI_AbortCpltCallback()
604 
605 @endverbatim
606   * @{
607   */
608 
609 /**
610   * @brief  Transmits in master mode an amount of data in blocking mode.
611   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
612   *                the configuration information for the specified PSSI.
613   * @param  pData Pointer to data buffer
614   * @param  Size Amount of data to be sent (in bytes)
615   * @param  Timeout Timeout duration
616   * @retval HAL status
617   */
HAL_PSSI_Transmit(PSSI_HandleTypeDef * hpssi,uint8_t * pData,uint32_t Size,uint32_t Timeout)618 HAL_StatusTypeDef HAL_PSSI_Transmit(PSSI_HandleTypeDef *hpssi, uint8_t *pData, uint32_t Size, uint32_t Timeout)
619 {
620   uint32_t tickstart;
621   uint32_t  transfer_size = Size;
622 
623   if (((hpssi->Init.DataWidth == HAL_PSSI_8BITS) && (hpssi->Init.BusWidth != HAL_PSSI_8LINES)) ||
624       ((hpssi->Init.DataWidth == HAL_PSSI_16BITS) && ((Size % 2U) != 0U)) ||
625       ((hpssi->Init.DataWidth == HAL_PSSI_32BITS) && ((Size % 4U) != 0U)))
626   {
627     hpssi->ErrorCode = HAL_PSSI_ERROR_NOT_SUPPORTED;
628     return HAL_ERROR;
629   }
630   if (hpssi->State == HAL_PSSI_STATE_READY)
631   {
632     /* Process Locked */
633     __HAL_LOCK(hpssi);
634 
635     hpssi->State     = HAL_PSSI_STATE_BUSY;
636     hpssi->ErrorCode = HAL_PSSI_ERROR_NONE;
637 
638     /* Disable the selected PSSI peripheral */
639     HAL_PSSI_DISABLE(hpssi);
640 
641     /* Configure transfer parameters */
642     hpssi->Instance->CR |= PSSI_CR_OUTEN_OUTPUT |
643                            ((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE) ? 0U : PSSI_CR_CKPOL);
644 
645 #if defined(HAL_DMA_MODULE_ENABLED)
646     /* DMA Disable */
647     hpssi->Instance->CR &= PSSI_CR_DMA_DISABLE;
648 #endif /*HAL_DMA_MODULE_ENABLED*/
649 
650     /* Enable the selected PSSI peripheral */
651     HAL_PSSI_ENABLE(hpssi);
652 
653     if (hpssi->Init.DataWidth == HAL_PSSI_8BITS)
654     {
655       uint8_t *pbuffer = pData;
656       while (transfer_size > 0U)
657       {
658         /* Init tickstart for timeout management*/
659         tickstart = HAL_GetTick();
660         /* Wait until Fifo is ready to transfer one byte flag is set */
661         if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT1B, RESET, Timeout, tickstart) != HAL_OK)
662         {
663           hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT;
664           hpssi->State = HAL_PSSI_STATE_READY;
665           /* Process Unlocked */
666           __HAL_UNLOCK(hpssi);
667           return HAL_ERROR;
668         }
669         /* Write data to DR */
670         *(__IO uint8_t *)(&hpssi->Instance->DR) = *(uint8_t *)pbuffer;
671 
672         /* Increment Buffer pointer */
673         pbuffer++;
674 
675         transfer_size--;
676       }
677     }
678     else if (hpssi->Init.DataWidth == HAL_PSSI_16BITS)
679     {
680       uint16_t *pbuffer = (uint16_t *)pData;
681       __IO uint16_t *dr = (__IO uint16_t *)(&hpssi->Instance->DR);
682 
683       while (transfer_size > 0U)
684       {
685         /* Init tickstart for timeout management*/
686         tickstart = HAL_GetTick();
687         /* Wait until Fifo is ready to transfer four bytes flag is set */
688         if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT4B, RESET, Timeout, tickstart) != HAL_OK)
689         {
690           hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT;
691           hpssi->State = HAL_PSSI_STATE_READY;
692           /* Process Unlocked */
693           __HAL_UNLOCK(hpssi);
694           return HAL_ERROR;
695         }
696         /* Write data to DR */
697         *dr = *pbuffer;
698 
699         /* Increment Buffer pointer */
700         pbuffer++;
701         transfer_size -= 2U;
702       }
703     }
704     else if (hpssi->Init.DataWidth == HAL_PSSI_32BITS)
705     {
706       uint32_t *pbuffer = (uint32_t *)pData;
707       while (transfer_size > 0U)
708       {
709         /* Init tickstart for timeout management*/
710         tickstart = HAL_GetTick();
711         /* Wait until Fifo is ready to transfer four bytes flag is set */
712         if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT4B, RESET, Timeout, tickstart) != HAL_OK)
713         {
714           hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT;
715           hpssi->State = HAL_PSSI_STATE_READY;
716           /* Process Unlocked */
717           __HAL_UNLOCK(hpssi);
718           return HAL_ERROR;
719         }
720         /* Write data to DR */
721         *(__IO uint32_t *)(&hpssi->Instance->DR) = *pbuffer;
722 
723         /* Increment Buffer pointer */
724         pbuffer++;
725         transfer_size -= 4U;
726       }
727     }
728     else
729     {
730       hpssi->ErrorCode = HAL_PSSI_ERROR_NOT_SUPPORTED;
731       hpssi->State = HAL_PSSI_STATE_READY;
732       /* Process Unlocked */
733       __HAL_UNLOCK(hpssi);
734       return HAL_ERROR;
735     }
736 
737     /* Check Errors Flags */
738     if (HAL_PSSI_GET_FLAG(hpssi, PSSI_FLAG_OVR_RIS) != 0U)
739     {
740       HAL_PSSI_CLEAR_FLAG(hpssi, PSSI_FLAG_OVR_RIS);
741       HAL_PSSI_DISABLE(hpssi);
742       hpssi->ErrorCode = HAL_PSSI_ERROR_UNDER_RUN;
743       hpssi->State = HAL_PSSI_STATE_READY;
744       /* Process Unlocked */
745       __HAL_UNLOCK(hpssi);
746       return HAL_ERROR;
747     }
748 
749     hpssi->State = HAL_PSSI_STATE_READY;
750 
751     /* Process Unlocked */
752     __HAL_UNLOCK(hpssi);
753 
754     return HAL_OK;
755   }
756   else
757   {
758     return HAL_BUSY;
759   }
760 }
761 
762 /**
763   * @brief  Receives an amount of data in blocking mode.
764   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
765   *                the configuration information for the specified PSSI.
766   * @param  pData Pointer to data buffer
767   * @param  Size Amount of data to be received (in bytes)
768   * @param  Timeout Timeout duration
769   * @retval HAL status
770   */
HAL_PSSI_Receive(PSSI_HandleTypeDef * hpssi,uint8_t * pData,uint32_t Size,uint32_t Timeout)771 HAL_StatusTypeDef HAL_PSSI_Receive(PSSI_HandleTypeDef *hpssi, uint8_t *pData, uint32_t Size, uint32_t Timeout)
772 {
773   uint32_t tickstart;
774   uint32_t  transfer_size = Size;
775 
776   if (((hpssi->Init.DataWidth == HAL_PSSI_8BITS) && (hpssi->Init.BusWidth != HAL_PSSI_8LINES)) ||
777       ((hpssi->Init.DataWidth == HAL_PSSI_16BITS) && ((Size % 2U) != 0U)) ||
778       ((hpssi->Init.DataWidth == HAL_PSSI_32BITS) && ((Size % 4U) != 0U)))
779   {
780     hpssi->ErrorCode = HAL_PSSI_ERROR_NOT_SUPPORTED;
781     return HAL_ERROR;
782   }
783 
784   if (hpssi->State == HAL_PSSI_STATE_READY)
785   {
786     /* Process Locked */
787     __HAL_LOCK(hpssi);
788 
789     hpssi->State     = HAL_PSSI_STATE_BUSY;
790     hpssi->ErrorCode = HAL_PSSI_ERROR_NONE;
791 
792     /* Disable the selected PSSI peripheral */
793     HAL_PSSI_DISABLE(hpssi);
794     /* Configure transfer parameters */
795     hpssi->Instance->CR |= PSSI_CR_OUTEN_INPUT |
796                            ((hpssi->Init.ClockPolarity == HAL_PSSI_FALLING_EDGE) ? 0U : PSSI_CR_CKPOL);
797 
798 #if defined(HAL_DMA_MODULE_ENABLED)
799     /* DMA Disable */
800     hpssi->Instance->CR &= PSSI_CR_DMA_DISABLE;
801 #endif /*HAL_DMA_MODULE_ENABLED*/
802 
803     /* Enable the selected PSSI peripheral */
804     HAL_PSSI_ENABLE(hpssi);
805     if (hpssi->Init.DataWidth == HAL_PSSI_8BITS)
806     {
807       uint8_t *pbuffer = pData;
808 
809       while (transfer_size > 0U)
810       {
811         /* Init tickstart for timeout management*/
812         tickstart = HAL_GetTick();
813         /* Wait until Fifo is ready to receive one byte flag is set */
814         if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT1B, RESET, Timeout, tickstart) != HAL_OK)
815         {
816           hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT;
817           hpssi->State = HAL_PSSI_STATE_READY;
818           /* Process Unlocked */
819           __HAL_UNLOCK(hpssi);
820           return HAL_ERROR;
821         }
822         /* Read data from DR */
823         *pbuffer = *(__IO uint8_t *)(&hpssi->Instance->DR);
824         pbuffer++;
825         transfer_size--;
826       }
827     }
828     else if (hpssi->Init.DataWidth == HAL_PSSI_16BITS)
829     {
830       uint16_t *pbuffer = (uint16_t *)pData;
831       __IO uint16_t *dr = (__IO uint16_t *)(&hpssi->Instance->DR);
832 
833       while (transfer_size > 0U)
834       {
835         /* Init tickstart for timeout management*/
836         tickstart = HAL_GetTick();
837         /* Wait until Fifo is ready to receive four bytes flag is set */
838         if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT4B, RESET, Timeout, tickstart) != HAL_OK)
839         {
840           hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT;
841           hpssi->State = HAL_PSSI_STATE_READY;
842           /* Process Unlocked */
843           __HAL_UNLOCK(hpssi);
844           return HAL_ERROR;
845         }
846 
847         /* Read data from DR */
848         *pbuffer = *dr;
849         pbuffer++;
850         transfer_size -= 2U;
851       }
852     }
853     else if (hpssi->Init.DataWidth == HAL_PSSI_32BITS)
854     {
855       uint32_t *pbuffer = (uint32_t *)pData;
856 
857       while (transfer_size > 0U)
858       {
859         /* Init tickstart for timeout management*/
860         tickstart = HAL_GetTick();
861         /* Wait until Fifo is ready to receive four bytes flag is set */
862         if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT4B, RESET, Timeout, tickstart) != HAL_OK)
863         {
864           hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT;
865           hpssi->State = HAL_PSSI_STATE_READY;
866           /* Process Unlocked */
867           __HAL_UNLOCK(hpssi);
868           return HAL_ERROR;
869         }
870 
871         /* Read data from DR */
872         *pbuffer = *(__IO uint32_t *)(&hpssi->Instance->DR);
873         pbuffer++;
874         transfer_size -= 4U;
875       }
876     }
877     else
878     {
879       hpssi->ErrorCode = HAL_PSSI_ERROR_NOT_SUPPORTED;
880       hpssi->State = HAL_PSSI_STATE_READY;
881       /* Process Unlocked */
882       __HAL_UNLOCK(hpssi);
883       return HAL_ERROR;
884     }
885     /* Check Errors Flags */
886 
887     if (HAL_PSSI_GET_FLAG(hpssi, PSSI_FLAG_OVR_RIS) != 0U)
888     {
889       HAL_PSSI_CLEAR_FLAG(hpssi, PSSI_FLAG_OVR_RIS);
890       hpssi->ErrorCode = HAL_PSSI_ERROR_OVER_RUN;
891       __HAL_UNLOCK(hpssi);
892       return HAL_ERROR;
893     }
894 
895     hpssi->State = HAL_PSSI_STATE_READY;
896 
897     /* Process Unlocked */
898     __HAL_UNLOCK(hpssi);
899 
900     return HAL_OK;
901   }
902   else
903   {
904     return HAL_BUSY;
905   }
906 }
907 
908 #if defined(HAL_DMA_MODULE_ENABLED)
909 /**
910   * @brief  Transmit an amount of data in non-blocking mode with DMA
911   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
912   *                the configuration information for the specified PSSI.
913   * @param  pData Pointer to data buffer
914   * @param  Size Amount of data to be sent (in bytes)
915   * @retval HAL status
916   */
HAL_PSSI_Transmit_DMA(PSSI_HandleTypeDef * hpssi,uint32_t * pData,uint32_t Size)917 HAL_StatusTypeDef HAL_PSSI_Transmit_DMA(PSSI_HandleTypeDef *hpssi, uint32_t *pData, uint32_t Size)
918 {
919   HAL_StatusTypeDef dmaxferstatus;
920 
921   if (hpssi->State == HAL_PSSI_STATE_READY)
922   {
923 
924     /* Process Locked */
925     __HAL_LOCK(hpssi);
926 
927     hpssi->State       = HAL_PSSI_STATE_BUSY_TX;
928     hpssi->ErrorCode   = HAL_PSSI_ERROR_NONE;
929 
930     /* Disable the selected PSSI peripheral */
931     HAL_PSSI_DISABLE(hpssi);
932 
933     /* Prepare transfer parameters */
934     hpssi->pBuffPtr    = pData;
935     hpssi->XferCount   = Size;
936 
937     if (hpssi->XferCount > PSSI_MAX_NBYTE_SIZE)
938     {
939       hpssi->XferSize = PSSI_MAX_NBYTE_SIZE;
940     }
941     else
942     {
943       hpssi->XferSize = hpssi->XferCount;
944     }
945 
946     if (hpssi->XferSize > 0U)
947     {
948       if (hpssi->hdmatx != NULL)
949       {
950 
951         /* Configure BusWidth */
952         if (hpssi->hdmatx->Init.DestDataWidth == DMA_DEST_DATAWIDTH_BYTE)
953           {
954             MODIFY_REG(hpssi->Instance->CR, PSSI_CR_DMAEN | PSSI_CR_OUTEN | PSSI_CR_CKPOL,
955                        PSSI_CR_DMA_ENABLE | PSSI_CR_OUTEN_OUTPUT |
956                        ((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE) ? 0U : PSSI_CR_CKPOL));
957           }
958           else
959           {
960             MODIFY_REG(hpssi->Instance->CR, PSSI_CR_DMAEN | PSSI_CR_OUTEN | PSSI_CR_CKPOL,
961                        PSSI_CR_DMA_ENABLE | hpssi->Init.BusWidth | PSSI_CR_OUTEN_OUTPUT |
962                        ((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE) ? 0U : PSSI_CR_CKPOL));
963           }
964 
965         /* Set the PSSI DMA transfer complete callback */
966         hpssi->hdmatx->XferCpltCallback = PSSI_DMATransmitCplt;
967 
968         /* Set the DMA error callback */
969         hpssi->hdmatx->XferErrorCallback = PSSI_DMAError;
970 
971         /* Set the unused DMA callbacks to NULL */
972         hpssi->hdmatx->XferHalfCpltCallback = NULL;
973         hpssi->hdmatx->XferAbortCallback = NULL;
974 
975         /* Enable the DMA  */
976         if ((hpssi->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
977         {
978           if (hpssi->hdmatx->LinkedListQueue != NULL)
979           {
980             /* Enable the DMA channel */
981             /* Set DMA data size */
982             hpssi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hpssi->XferSize;
983             /* Set DMA source address */
984             hpssi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pData;
985             /* Set DMA destination address */
986             hpssi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] =
987               (uint32_t)&hpssi->Instance->DR;
988 
989             dmaxferstatus = HAL_DMAEx_List_Start_IT(hpssi->hdmatx);
990           }
991           else
992           {
993             /* Return error status */
994             return HAL_ERROR;
995           }
996         }
997         else
998         {
999           dmaxferstatus = HAL_DMA_Start_IT(hpssi->hdmatx, (uint32_t)pData, (uint32_t)&hpssi->Instance->DR,
1000                                            hpssi->XferSize);
1001         }
1002       }
1003       else
1004       {
1005         /* Update PSSI state */
1006         hpssi->State     = HAL_PSSI_STATE_READY;
1007 
1008         /* Update PSSI error code */
1009         hpssi->ErrorCode |= HAL_PSSI_ERROR_DMA;
1010 
1011         /* Process Unlocked */
1012         __HAL_UNLOCK(hpssi);
1013 
1014         return HAL_ERROR;
1015       }
1016 
1017       if (dmaxferstatus == HAL_OK)
1018       {
1019         /* Update XferCount value */
1020         hpssi->XferCount -= hpssi->XferSize;
1021 
1022         /* Process Unlocked */
1023         __HAL_UNLOCK(hpssi);
1024 
1025         /* Note : The PSSI interrupts must be enabled after unlocking current process
1026                   to avoid the risk of PSSI interrupt handle execution before current
1027                   process unlock */
1028         /* Enable ERR interrupt */
1029         HAL_PSSI_ENABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1030 
1031         /* Enable DMA Request */
1032         hpssi->Instance->CR |= PSSI_CR_DMA_ENABLE;
1033         /* Enable the selected PSSI peripheral */
1034         HAL_PSSI_ENABLE(hpssi);
1035       }
1036       else
1037       {
1038         /* Update PSSI state */
1039         hpssi->State     = HAL_PSSI_STATE_READY;
1040 
1041         /* Update PSSI error code */
1042         hpssi->ErrorCode |= HAL_PSSI_ERROR_DMA;
1043 
1044         /* Process Unlocked */
1045         __HAL_UNLOCK(hpssi);
1046 
1047         return HAL_ERROR;
1048       }
1049     }
1050     else
1051     {
1052       /* Process Unlocked */
1053       __HAL_UNLOCK(hpssi);
1054 
1055       /* Note : The PSSI interrupts must be enabled after unlocking current process
1056                 to avoid the risk of PSSI interrupt handle execution before current
1057                 process unlock */
1058       /* Enable ERRinterrupt */
1059       /* possible to enable all of these */
1060 
1061       HAL_PSSI_ENABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1062     }
1063     return HAL_OK;
1064   }
1065   else
1066   {
1067     return HAL_BUSY;
1068   }
1069 }
1070 
1071 /**
1072   * @brief  Receive an amount of data in non-blocking mode with DMA
1073   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1074   *                the configuration information for the specified PSSI.
1075   * @param  pData Pointer to data buffer
1076   * @param  Size Amount of data to be received (in bytes)
1077   * @retval HAL status
1078   */
HAL_PSSI_Receive_DMA(PSSI_HandleTypeDef * hpssi,uint32_t * pData,uint32_t Size)1079 HAL_StatusTypeDef HAL_PSSI_Receive_DMA(PSSI_HandleTypeDef *hpssi, uint32_t *pData, uint32_t Size)
1080 {
1081 
1082   HAL_StatusTypeDef dmaxferstatus;
1083 
1084   if (hpssi->State == HAL_PSSI_STATE_READY)
1085   {
1086 
1087     /* Disable the selected PSSI peripheral */
1088     HAL_PSSI_DISABLE(hpssi);
1089     /* Process Locked */
1090     __HAL_LOCK(hpssi);
1091 
1092     hpssi->State       = HAL_PSSI_STATE_BUSY_RX;
1093     hpssi->ErrorCode   = HAL_PSSI_ERROR_NONE;
1094 
1095     /* Prepare transfer parameters */
1096     hpssi->pBuffPtr    = pData;
1097     hpssi->XferCount   = Size;
1098 
1099     if (hpssi->XferCount > PSSI_MAX_NBYTE_SIZE)
1100     {
1101       hpssi->XferSize = PSSI_MAX_NBYTE_SIZE;
1102     }
1103     else
1104     {
1105       hpssi->XferSize = hpssi->XferCount;
1106     }
1107 
1108     if (hpssi->XferSize > 0U)
1109     {
1110       if (hpssi->hdmarx != NULL)
1111       {
1112         /* Configure BusWidth */
1113         if (hpssi->hdmatx->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_BYTE)
1114           {
1115             MODIFY_REG(hpssi->Instance->CR, PSSI_CR_DMAEN | PSSI_CR_OUTEN | PSSI_CR_CKPOL, PSSI_CR_DMA_ENABLE |
1116                        ((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE) ? PSSI_CR_CKPOL : 0U));
1117           }
1118           else
1119           {
1120             MODIFY_REG(hpssi->Instance->CR, PSSI_CR_DMAEN | PSSI_CR_OUTEN | PSSI_CR_CKPOL,
1121                        PSSI_CR_DMA_ENABLE | hpssi->Init.BusWidth |
1122                        ((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE) ? PSSI_CR_CKPOL : 0U));
1123           }
1124 
1125         /* Set the PSSI DMA transfer complete callback */
1126         hpssi->hdmarx->XferCpltCallback = PSSI_DMAReceiveCplt;
1127 
1128         /* Set the DMA error callback */
1129         hpssi->hdmarx->XferErrorCallback = PSSI_DMAError;
1130 
1131         /* Set the unused DMA callbacks to NULL */
1132         hpssi->hdmarx->XferHalfCpltCallback = NULL;
1133         hpssi->hdmarx->XferAbortCallback = NULL;
1134 
1135         /* Enable the DMA  */
1136         if ((hpssi->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1137         {
1138           if (hpssi->hdmarx->LinkedListQueue != NULL)
1139           {
1140             /* Enable the DMA channel */
1141             /* Set DMA data size */
1142             hpssi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hpssi->XferSize;
1143             /* Set DMA source address */
1144             hpssi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] =
1145               (uint32_t)&hpssi->Instance->DR;
1146             /* Set DMA destination address */
1147             hpssi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pData;
1148 
1149             dmaxferstatus = HAL_DMAEx_List_Start_IT(hpssi->hdmarx);
1150           }
1151           else
1152           {
1153             /* Return error status */
1154             return HAL_ERROR;
1155           }
1156         }
1157         else
1158         {
1159           dmaxferstatus = HAL_DMA_Start_IT(hpssi->hdmarx, (uint32_t)&hpssi->Instance->DR, (uint32_t)pData,
1160                                            hpssi->XferSize);
1161         }
1162       }
1163       else
1164       {
1165         /* Update PSSI state */
1166         hpssi->State     = HAL_PSSI_STATE_READY;
1167 
1168         /* Update PSSI error code */
1169         hpssi->ErrorCode |= HAL_PSSI_ERROR_DMA;
1170 
1171         /* Process Unlocked */
1172         __HAL_UNLOCK(hpssi);
1173 
1174         return HAL_ERROR;
1175       }
1176 
1177       if (dmaxferstatus == HAL_OK)
1178       {
1179         /* Update XferCount value */
1180         hpssi->XferCount -= hpssi->XferSize;
1181 
1182         /* Process Unlocked */
1183         __HAL_UNLOCK(hpssi);
1184 
1185         /* Note : The PSSI interrupts must be enabled after unlocking current process
1186                   to avoid the risk of PSSI interrupt handle execution before current
1187                   process unlock */
1188         /* Enable ERR  interrupt */
1189         HAL_PSSI_ENABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1190 
1191         /* Enable DMA Request */
1192         hpssi->Instance->CR |= PSSI_CR_DMA_ENABLE;
1193         /* Enable the selected PSSI peripheral */
1194         HAL_PSSI_ENABLE(hpssi);
1195       }
1196       else
1197       {
1198         /* Update PSSI state */
1199         hpssi->State     = HAL_PSSI_STATE_READY;
1200 
1201         /* Update PSSI error code */
1202         hpssi->ErrorCode |= HAL_PSSI_ERROR_DMA;
1203 
1204         /* Process Unlocked */
1205         __HAL_UNLOCK(hpssi);
1206 
1207         return HAL_ERROR;
1208       }
1209     }
1210     else
1211     {
1212       /* Process Unlocked */
1213       __HAL_UNLOCK(hpssi);
1214 
1215       /* Enable ERR,interrupt */
1216       HAL_PSSI_ENABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1217     }
1218 
1219     return HAL_OK;
1220   }
1221   else
1222   {
1223     return HAL_BUSY;
1224   }
1225 }
1226 
1227 /**
1228   * @brief  Abort a DMA process communication with Interrupt.
1229   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1230   *                the configuration information for the specified PSSI.
1231   * @retval HAL status
1232   */
HAL_PSSI_Abort_DMA(PSSI_HandleTypeDef * hpssi)1233 HAL_StatusTypeDef HAL_PSSI_Abort_DMA(PSSI_HandleTypeDef *hpssi)
1234 {
1235   /* Process Locked */
1236   __HAL_LOCK(hpssi);
1237 
1238   /* Disable Interrupts */
1239   HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1240 
1241   /* Set State at HAL_PSSI_STATE_ABORT */
1242   hpssi->State = HAL_PSSI_STATE_ABORT;
1243 
1244   /* Abort DMA TX transfer if any */
1245   if ((hpssi->Instance->CR & PSSI_CR_DMAEN) == PSSI_CR_DMAEN)
1246   {
1247     if (hpssi->State == HAL_PSSI_STATE_BUSY_TX)
1248     {
1249       hpssi->Instance->CR &= ~PSSI_CR_DMAEN;
1250 
1251       if (hpssi->hdmatx != NULL)
1252       {
1253         /* Set the PSSI DMA Abort callback :
1254         will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */
1255         hpssi->hdmatx->XferAbortCallback = PSSI_DMAAbort;
1256 
1257         /* Abort DMA TX */
1258         if (HAL_DMA_Abort_IT(hpssi->hdmatx) != HAL_OK)
1259         {
1260           /* Call Directly XferAbortCallback function in case of error */
1261           hpssi->hdmatx->XferAbortCallback(hpssi->hdmatx);
1262         }
1263       }
1264     }
1265     /* Abort DMA RX transfer if any */
1266     else if (hpssi->State == HAL_PSSI_STATE_BUSY_RX)
1267     {
1268       hpssi->Instance->CR &= ~PSSI_CR_DMAEN;
1269 
1270       if (hpssi->hdmarx != NULL)
1271       {
1272         /* Set the PSSI DMA Abort callback :
1273         will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */
1274         hpssi->hdmarx->XferAbortCallback = PSSI_DMAAbort;
1275 
1276         /* Abort DMA RX */
1277         if (HAL_DMA_Abort_IT(hpssi->hdmarx) != HAL_OK)
1278         {
1279           /* Call Directly hpssi->hdma->XferAbortCallback function in case of error */
1280           hpssi->hdmarx->XferAbortCallback(hpssi->hdmarx);
1281         }
1282       }
1283     }
1284     else
1285     {
1286       /* Call the error callback */
1287       hpssi->ErrorCallback(hpssi);
1288     }
1289   }
1290 
1291   /* Process Unlocked */
1292   __HAL_UNLOCK(hpssi);
1293 
1294   /* Note : The PSSI interrupts must be enabled after unlocking current process
1295             to avoid the risk of PSSI interrupt handle execution before current
1296             process unlock */
1297   HAL_PSSI_ENABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1298 
1299   return HAL_OK;
1300 }
1301 #endif /*HAL_DMA_MODULE_ENABLED*/
1302 
1303 /**
1304   * @}
1305   */
1306 
1307 /** @addtogroup PSSI_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
1308   * @{
1309   */
1310 
1311 /**
1312   * @brief  This function handles PSSI event interrupt request.
1313   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1314   *                the configuration information for the specified PSSI.
1315   * @retval None
1316   */
HAL_PSSI_IRQHandler(PSSI_HandleTypeDef * hpssi)1317 void HAL_PSSI_IRQHandler(PSSI_HandleTypeDef *hpssi)
1318 {
1319   /* Overrun/ Underrun Errors */
1320   if (HAL_PSSI_GET_FLAG(hpssi, PSSI_FLAG_OVR_MIS) != 0U)
1321   {
1322     /* Reset handle parameters */
1323     hpssi->XferCount     = 0U;
1324 
1325     /* Disable all interrupts */
1326     HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1327 
1328 #if defined(HAL_DMA_MODULE_ENABLED)
1329     /* Abort DMA TX transfer if any */
1330     if ((hpssi->Instance->CR & PSSI_CR_DMAEN) == PSSI_CR_DMAEN)
1331     {
1332       if (hpssi->State == HAL_PSSI_STATE_BUSY_TX)
1333       {
1334         /* Set new error code */
1335         hpssi->ErrorCode |= HAL_PSSI_ERROR_UNDER_RUN;
1336 
1337         hpssi->Instance->CR &= ~PSSI_CR_DMAEN;
1338 
1339         if (hpssi->hdmatx != NULL)
1340         {
1341           /* Set the PSSI DMA Abort callback :
1342           will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */
1343           hpssi->hdmatx->XferAbortCallback = PSSI_DMAAbort;
1344 
1345           /* Process Unlocked */
1346           __HAL_UNLOCK(hpssi);
1347 
1348           /* Abort DMA TX */
1349           if (HAL_DMA_Abort_IT(hpssi->hdmatx) != HAL_OK)
1350           {
1351             /* Call Directly XferAbortCallback function in case of error */
1352             hpssi->hdmatx->XferAbortCallback(hpssi->hdmatx);
1353           }
1354         }
1355       }
1356       /* Abort DMA RX transfer if any */
1357       else if (hpssi->State == HAL_PSSI_STATE_BUSY_RX)
1358       {
1359         /* Set new error code */
1360         hpssi->ErrorCode |= HAL_PSSI_ERROR_OVER_RUN;
1361 
1362         hpssi->Instance->CR &= ~PSSI_CR_DMAEN;
1363 
1364         if (hpssi->hdmarx != NULL)
1365         {
1366           /* Set the PSSI DMA Abort callback :
1367           will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */
1368           hpssi->hdmarx->XferAbortCallback = PSSI_DMAAbort;
1369 
1370           /* Process Unlocked */
1371           __HAL_UNLOCK(hpssi);
1372 
1373           /* Abort DMA RX */
1374           if (HAL_DMA_Abort_IT(hpssi->hdmarx) != HAL_OK)
1375           {
1376             /* Call Directly hpssi->hdma->XferAbortCallback function in case of error */
1377             hpssi->hdmarx->XferAbortCallback(hpssi->hdmarx);
1378           }
1379         }
1380       }
1381       else
1382       {
1383         /* Call the corresponding callback to inform upper layer of the error */
1384         hpssi->ErrorCallback(hpssi);
1385       }
1386     }
1387 #endif /*HAL_DMA_MODULE_ENABLED*/
1388 
1389     /* If state is an abort treatment on going, don't change state */
1390     if (hpssi->State == HAL_PSSI_STATE_ABORT)
1391     {
1392       hpssi->State = HAL_PSSI_STATE_READY;
1393 
1394       /* Process Unlocked */
1395       __HAL_UNLOCK(hpssi);
1396 
1397       /* Call the corresponding callback to inform upper layer of End of Transfer */
1398       hpssi->AbortCpltCallback(hpssi);
1399     }
1400     else
1401     {
1402       /* Set HAL_PSSI_STATE_READY */
1403       hpssi->State         = HAL_PSSI_STATE_READY;
1404       /* Process Unlocked */
1405       __HAL_UNLOCK(hpssi);
1406 
1407       /* Call the corresponding callback to inform upper layer of End of Transfer */
1408       hpssi->ErrorCallback(hpssi);
1409     }
1410   }
1411 }
1412 
1413 /**
1414   * @brief   Tx Transfer complete callback.
1415   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1416   *                the configuration information for the specified PSSI.
1417   * @retval None
1418   */
HAL_PSSI_TxCpltCallback(PSSI_HandleTypeDef * hpssi)1419 __weak void HAL_PSSI_TxCpltCallback(PSSI_HandleTypeDef *hpssi)
1420 {
1421   /* Prevent unused argument(s) compilation warning */
1422   UNUSED(hpssi);
1423 
1424   /* NOTE : This function should not be modified, when the callback is needed,
1425             the HAL_PSSI_TxCpltCallback can be implemented in the user file
1426    */
1427 }
1428 
1429 /**
1430   * @brief   Rx Transfer complete callback.
1431   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1432   *                the configuration information for the specified PSSI.
1433   * @retval None
1434   */
HAL_PSSI_RxCpltCallback(PSSI_HandleTypeDef * hpssi)1435 __weak void HAL_PSSI_RxCpltCallback(PSSI_HandleTypeDef *hpssi)
1436 {
1437   /* Prevent unused argument(s) compilation warning */
1438   UNUSED(hpssi);
1439 
1440   /* NOTE : This function should not be modified, when the callback is needed,
1441             the HAL_PSSI_RxCpltCallback can be implemented in the user file
1442    */
1443 }
1444 
1445 /**
1446   * @brief  PSSI error callback.
1447   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1448   *                the configuration information for the specified PSSI.
1449   * @retval None
1450   */
HAL_PSSI_ErrorCallback(PSSI_HandleTypeDef * hpssi)1451 __weak void HAL_PSSI_ErrorCallback(PSSI_HandleTypeDef *hpssi)
1452 {
1453   /* Prevent unused argument(s) compilation warning */
1454   UNUSED(hpssi);
1455 
1456   /* NOTE : This function should not be modified, when the callback is needed,
1457             the HAL_PSSI_ErrorCallback could be implemented in the user file
1458    */
1459 }
1460 
1461 /**
1462   * @brief  PSSI abort callback.
1463   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1464   *                the configuration information for the specified PSSI.
1465   * @retval None
1466   */
HAL_PSSI_AbortCpltCallback(PSSI_HandleTypeDef * hpssi)1467 __weak void HAL_PSSI_AbortCpltCallback(PSSI_HandleTypeDef *hpssi)
1468 {
1469   /* Prevent unused argument(s) compilation warning */
1470   UNUSED(hpssi);
1471 
1472   /* NOTE : This function should not be modified, when the callback is needed,
1473             the HAL_PSSI_AbortCpltCallback could be implemented in the user file
1474    */
1475 }
1476 
1477 /**
1478   * @}
1479   */
1480 
1481 /** @defgroup PSSI_Exported_Functions_Group3 Peripheral State and Error functions
1482   *  @brief   Peripheral State, Mode and Error functions
1483   *
1484 @verbatim
1485  ===============================================================================
1486             ##### Peripheral State, Mode and Error functions #####
1487  ===============================================================================
1488     [..]
1489     This subsection permit to get in run-time the status of the peripheral
1490     and the data flow.
1491 
1492 @endverbatim
1493   * @{
1494   */
1495 
1496 /**
1497   * @brief  Return the PSSI handle state.
1498   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1499   *                the configuration information for the specified PSSI.
1500   * @retval HAL state
1501   */
HAL_PSSI_GetState(PSSI_HandleTypeDef * hpssi)1502 HAL_PSSI_StateTypeDef HAL_PSSI_GetState(PSSI_HandleTypeDef *hpssi)
1503 {
1504   /* Return PSSI handle state */
1505   return hpssi->State;
1506 }
1507 
1508 /**
1509   * @brief  Return the PSSI error code.
1510   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1511   *              the configuration information for the specified PSSI.
1512   * @retval PSSI Error Code
1513   */
HAL_PSSI_GetError(PSSI_HandleTypeDef * hpssi)1514 uint32_t HAL_PSSI_GetError(PSSI_HandleTypeDef *hpssi)
1515 {
1516   return hpssi->ErrorCode;
1517 }
1518 
1519 /**
1520   * @}
1521   */
1522 
1523 /**
1524   * @}
1525   */
1526 
1527 /** @addtogroup PSSI_Private_Functions
1528   * @{
1529   */
1530 
1531 /**
1532   * @brief  PSSI Errors process.
1533   * @param  hpssi PSSI handle.
1534   * @param  ErrorCode Error code to handle.
1535   * @retval None
1536   */
PSSI_Error(PSSI_HandleTypeDef * hpssi,uint32_t ErrorCode)1537 static void PSSI_Error(PSSI_HandleTypeDef *hpssi, uint32_t ErrorCode)
1538 {
1539   /* Reset handle parameters */
1540   hpssi->XferCount     = 0U;
1541 
1542   /* Set new error code */
1543   hpssi->ErrorCode |= ErrorCode;
1544 
1545   /* Disable all interrupts */
1546   HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1547 
1548 #if defined(HAL_DMA_MODULE_ENABLED)
1549   /* Abort DMA TX transfer if any */
1550   if ((hpssi->Instance->CR & PSSI_CR_DMAEN) == PSSI_CR_DMAEN)
1551   {
1552     if (hpssi->State == HAL_PSSI_STATE_BUSY_TX)
1553     {
1554       hpssi->Instance->CR &= ~PSSI_CR_DMAEN;
1555 
1556       if (hpssi->hdmatx != NULL)
1557       {
1558         /* Set the PSSI DMA Abort callback :
1559         will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */
1560         hpssi->hdmatx->XferAbortCallback = PSSI_DMAAbort;
1561 
1562         /* Process Unlocked */
1563         __HAL_UNLOCK(hpssi);
1564 
1565         /* Abort DMA TX */
1566         if (HAL_DMA_Abort_IT(hpssi->hdmatx) != HAL_OK)
1567         {
1568           /* Call Directly XferAbortCallback function in case of error */
1569           hpssi->hdmatx->XferAbortCallback(hpssi->hdmatx);
1570         }
1571       }
1572     }
1573     /* Abort DMA RX transfer if any */
1574     else if (hpssi->State == HAL_PSSI_STATE_BUSY_RX)
1575     {
1576       hpssi->Instance->CR &= ~PSSI_CR_DMAEN;
1577 
1578       if (hpssi->hdmarx != NULL)
1579       {
1580         /* Set the PSSI DMA Abort callback :
1581         will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */
1582         hpssi->hdmarx->XferAbortCallback = PSSI_DMAAbort;
1583 
1584         /* Process Unlocked */
1585         __HAL_UNLOCK(hpssi);
1586 
1587         /* Abort DMA RX */
1588         if (HAL_DMA_Abort_IT(hpssi->hdmarx) != HAL_OK)
1589         {
1590           /* Call Directly hpssi->hdma->XferAbortCallback function in case of error */
1591           hpssi->hdmarx->XferAbortCallback(hpssi->hdmarx);
1592         }
1593       }
1594     }
1595     else
1596     {
1597       /*Nothing to do*/
1598     }
1599   }
1600 #endif /*HAL_DMA_MODULE_ENABLED*/
1601 
1602   /* If state is an abort treatment on going, don't change state */
1603   if (hpssi->State == HAL_PSSI_STATE_ABORT)
1604   {
1605     hpssi->State = HAL_PSSI_STATE_READY;
1606 
1607     /* Process Unlocked */
1608     __HAL_UNLOCK(hpssi);
1609 
1610     /* Call the corresponding callback to inform upper layer of End of Transfer */
1611 
1612     hpssi->AbortCpltCallback(hpssi);
1613   }
1614   else
1615   {
1616     /* Set HAL_PSSI_STATE_READY */
1617     hpssi->State = HAL_PSSI_STATE_READY;
1618 
1619     /* Process Unlocked */
1620     __HAL_UNLOCK(hpssi);
1621 
1622     /* Call the corresponding callback to inform upper layer of End of Transfer */
1623     hpssi->ErrorCallback(hpssi);
1624   }
1625 }
1626 
1627 #if defined(HAL_DMA_MODULE_ENABLED)
1628 /**
1629   * @brief  DMA PSSI slave transmit process complete callback.
1630   * @param  hdma DMA handle
1631   * @retval None
1632   */
PSSI_DMATransmitCplt(DMA_HandleTypeDef * hdma)1633 void PSSI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1634 {
1635   /* Derogation MISRAC2012-Rule-11.5 */
1636   PSSI_HandleTypeDef *hpssi = (PSSI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
1637 
1638   uint32_t tmperror;
1639 
1640   /* Disable Interrupts */
1641   HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1642 
1643   /* Store current volatile hpssi->ErrorCode, misra rule */
1644   tmperror = hpssi->ErrorCode;
1645 
1646   /* Call the corresponding callback to inform upper layer of End of Transfer */
1647   if ((hpssi->State == HAL_PSSI_STATE_ABORT) || (tmperror != HAL_PSSI_ERROR_NONE))
1648   {
1649     /* Call the corresponding callback to inform upper layer of End of Transfer */
1650     PSSI_Error(hpssi, hpssi->ErrorCode);
1651   }
1652   /* hpssi->State == HAL_PSSI_STATE_BUSY_TX */
1653   else
1654   {
1655     hpssi->State = HAL_PSSI_STATE_READY;
1656 
1657     /* Process Unlocked */
1658     __HAL_UNLOCK(hpssi);
1659 
1660     /* Call the corresponding callback to inform upper layer of End of Transfer */
1661 
1662     hpssi->TxCpltCallback(hpssi);
1663   }
1664 }
1665 
1666 /**
1667   * @brief DMA PSSI master receive process complete callback.
1668   * @param  hdma DMA handle
1669   * @retval None
1670   */
PSSI_DMAReceiveCplt(DMA_HandleTypeDef * hdma)1671 void PSSI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1672 {
1673   /* Derogation MISRAC2012-Rule-11.5 */
1674   PSSI_HandleTypeDef *hpssi = (PSSI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
1675 
1676   uint32_t tmperror;
1677 
1678   /* Disable Interrupts */
1679   HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1680 
1681   /* Store current volatile hpssi->ErrorCode, misra rule */
1682   tmperror = hpssi->ErrorCode;
1683 
1684   /* Call the corresponding callback to inform upper layer of End of Transfer */
1685   if ((hpssi->State == HAL_PSSI_STATE_ABORT) || (tmperror != HAL_PSSI_ERROR_NONE))
1686   {
1687     /* Call the corresponding callback to inform upper layer of End of Transfer */
1688     PSSI_Error(hpssi, hpssi->ErrorCode);
1689   }
1690   /* hpssi->State == HAL_PSSI_STATE_BUSY_RX */
1691   else
1692   {
1693     hpssi->State = HAL_PSSI_STATE_READY;
1694 
1695     /* Process Unlocked */
1696     __HAL_UNLOCK(hpssi);
1697 
1698     /* Call the corresponding callback to inform upper layer of End of Transfer */
1699     hpssi->RxCpltCallback(hpssi);
1700   }
1701 }
1702 
1703 /**
1704   * @brief DMA PSSI communication abort callback
1705   *        (To be called at end of DMA Abort procedure).
1706   * @param hdma DMA handle.
1707   * @retval None
1708   */
PSSI_DMAAbort(DMA_HandleTypeDef * hdma)1709 void PSSI_DMAAbort(DMA_HandleTypeDef *hdma)
1710 {
1711   /* Derogation MISRAC2012-Rule-11.5 */
1712   PSSI_HandleTypeDef *hpssi = (PSSI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
1713 
1714   /* Reset AbortCpltCallback */
1715   hpssi->hdmatx->XferAbortCallback = NULL;
1716   hpssi->hdmarx->XferAbortCallback = NULL;
1717 
1718   /* Check if come from abort from user */
1719   if (hpssi->State == HAL_PSSI_STATE_ABORT)
1720   {
1721     hpssi->State = HAL_PSSI_STATE_READY;
1722 
1723     /* Call the corresponding callback to inform upper layer of End of Transfer */
1724 
1725     hpssi->AbortCpltCallback(hpssi);
1726   }
1727   else
1728   {
1729     /* Call the corresponding callback to inform upper layer of End of Transfer */
1730     hpssi->ErrorCallback(hpssi);
1731   }
1732 }
1733 #endif /*HAL_DMA_MODULE_ENABLED*/
1734 
1735 /**
1736   * @brief  This function handles PSSI Communication Timeout.
1737   * @param  hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1738   *                the configuration information for the specified PSSI.
1739   * @param  Flag Specifies the PSSI flag to check.
1740   * @param  Status The new Flag status (SET or RESET).
1741   * @param  Timeout Timeout duration
1742   * @param  Tickstart Tick start value
1743   * @retval HAL status
1744   */
PSSI_WaitOnStatusUntilTimeout(PSSI_HandleTypeDef * hpssi,uint32_t Flag,FlagStatus Status,uint32_t Timeout,uint32_t Tickstart)1745 static HAL_StatusTypeDef PSSI_WaitOnStatusUntilTimeout(PSSI_HandleTypeDef *hpssi, uint32_t Flag, FlagStatus Status,
1746                                                        uint32_t Timeout, uint32_t Tickstart)
1747 {
1748   while ((HAL_PSSI_GET_STATUS(hpssi, Flag) & Flag) == (uint32_t)Status)
1749   {
1750     /* Check for the Timeout */
1751     if (Timeout != HAL_MAX_DELAY)
1752     {
1753       if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
1754       {
1755         hpssi->ErrorCode |= HAL_PSSI_ERROR_TIMEOUT;
1756         hpssi->State = HAL_PSSI_STATE_READY;
1757 
1758         /* Process Unlocked */
1759         __HAL_UNLOCK(hpssi);
1760 
1761         return HAL_ERROR;
1762       }
1763     }
1764   }
1765   return HAL_OK;
1766 }
1767 
1768 #if defined(HAL_DMA_MODULE_ENABLED)
PSSI_DMAError(DMA_HandleTypeDef * hdma)1769 void PSSI_DMAError(DMA_HandleTypeDef *hdma)
1770 {
1771   /* Derogation MISRAC2012-Rule-11.5 */
1772   PSSI_HandleTypeDef *hpssi = (PSSI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
1773 
1774   uint32_t tmperror;
1775 
1776   /* Disable the selected PSSI peripheral */
1777   HAL_PSSI_DISABLE(hpssi);
1778 
1779   /* Disable Interrupts */
1780   HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1781 
1782   /* Store current volatile hpssi->ErrorCode, misra rule */
1783   tmperror = hpssi->ErrorCode;
1784 
1785   /* Call the corresponding callback to inform upper layer of End of Transfer */
1786   if ((hpssi->State == HAL_PSSI_STATE_ABORT) || (tmperror != HAL_PSSI_ERROR_NONE))
1787   {
1788     /* Call the corresponding callback to inform upper layer of End of Transfer */
1789     PSSI_Error(hpssi, hpssi->ErrorCode);
1790   }
1791   else
1792   {
1793     hpssi->State = HAL_PSSI_STATE_READY;
1794 
1795     /* Process Unlocked */
1796     __HAL_UNLOCK(hpssi);
1797 
1798     /* Call the corresponding callback to inform upper layer of End of Transfer */
1799     hpssi->ErrorCallback(hpssi);
1800   }
1801 }
1802 #endif /*HAL_DMA_MODULE_ENABLED*/
1803 
1804 
1805 /**
1806   * @}
1807   */
1808 #endif /* PSSI */
1809 #endif /* HAL_PSSI_MODULE_ENABLED */
1810 /**
1811   * @}
1812   */
1813 
1814 /**
1815   * @}
1816   */
1817