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