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