Updated and Validated
[betaflight.git] / lib / main / STM32H7 / Drivers / STM32H7xx_HAL_Driver / Src / stm32h7xx_hal_pssi.c
blob19f0a69362d561ed84db55f8c6fed86dd0db0912
1 /**
2 ******************************************************************************
3 * @file stm32h7xx_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
12 @verbatim
13 ==============================================================================
14 ##### How to use this driver #####
15 ==============================================================================
16 [..]
17 The PSSI HAL driver can be used as follows:
19 (#) Declare a PSSI_HandleTypeDef handle structure, for example:
20 PSSI_HandleTypeDef hpssi;
22 (#) Initialize the PSSI low level resources by implementing the @ref HAL_PSSI_MspInit() API:
23 (##) Enable the PSSIx interface clock
24 (##) PSSI pins configuration
25 (+++) Enable the clock for the PSSI GPIOs
26 (+++) Configure PSSI pins as alternate function open-drain
27 (##) NVIC configuration if you need to use interrupt process
28 (+++) Configure the PSSIx interrupt priority
29 (+++) Enable the NVIC PSSI IRQ Channel
30 (##) DMA Configuration if you need to use DMA process
31 (+++) Declare DMA_HandleTypeDef handles structure for the transmit and receive
32 (+++) Enable the DMAx interface clock
33 (+++) Configure the DMA handle parameters
34 (+++) Configure the DMA Tx and Rx
35 (+++) Associate the initialized DMA handle to the hpssi DMA Tx and Rx handle
36 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on
37 the DMA Tx and Rx
39 (#) Configure the Communication Bus Width, Control Signals, Input Polarity and Output Polarity
40 in the hpssi Init structure.
42 (#) Initialize the PSSI registers by calling the @ref HAL_PSSI_Init(), configure also the low level Hardware
43 (GPIO, CLOCK, NVIC...etc) by calling the customized @ref HAL_PSSI_MspInit(&hpssi) API.
46 (#) For PSSI IO operations, two operation modes are available within this driver :
48 *** Polling mode IO operation ***
49 =================================
50 [..]
51 (+) Transmit an amount of data by byte in blocking mode using @ref HAL_PSSI_Transmit()
52 (+) Receive an amount of data by byte in blocking mode using @ref HAL_PSSI_Receive()
54 *** DMA mode IO operation ***
55 ==============================
56 [..]
57 (+) Transmit an amount of data in non-blocking mode (DMA) using
58 @ref HAL_PSSI_Transmit_DMA()
59 (+) At transmission end of transfer, @ref HAL_PSSI_TxCpltCallback() is executed and user can
60 add his own code by customization of function pointer @ref HAL_PSSI_TxCpltCallback()
61 (+) Receive an amount of data in non-blocking mode (DMA) using
62 @ref HAL_PSSI_Receive_DMA()
63 (+) At reception end of transfer, @ref HAL_PSSI_RxCpltCallback() is executed and user can
64 add his own code by customization of function pointer @ref HAL_PSSI_RxCpltCallback()
65 (+) In case of transfer Error, @ref HAL_PSSI_ErrorCallback() function is executed and user can
66 add his own code by customization of function pointer @ref HAL_PSSI_ErrorCallback()
67 (+) Abort a PSSI process communication with Interrupt using @ref HAL_PSSI_Abort_IT()
68 (+) End of abort process, @ref HAL_PSSI_AbortCpltCallback() is executed and user can
69 add his own code by customization of function pointer @ref HAL_PSSI_AbortCpltCallback()
71 *** PSSI HAL driver macros list ***
72 ==================================
73 [..]
74 Below the list of most used macros in PSSI HAL driver.
76 (+) @ref HAL_PSSI_ENABLE : Enable the PSSI peripheral
77 (+) @ref HAL_PSSI_DISABLE : Disable the PSSI peripheral
78 (+) @ref HAL_PSSI_GET_FLAG : Check whether the specified PSSI flag is set or not
79 (+) @ref HAL_PSSI_CLEAR_FLAG : Clear the specified PSSI pending flag
80 (+) @ref HAL_PSSI_ENABLE_IT : Enable the specified PSSI interrupt
81 (+) @ref HAL_PSSI_DISABLE_IT : Disable the specified PSSI interrupt
83 *** Callback registration ***
84 =============================================
85 Use Functions @ref HAL_PSSI_RegisterCallback() or @ref HAL_PSSI_RegisterAddrCallback()
86 to register an interrupt callback.
88 Function @ref HAL_PSSI_RegisterCallback() allows to register following callbacks:
89 (+) TxCpltCallback : callback for transmission end of transfer.
90 (+) RxCpltCallback : callback for reception end of transfer.
91 (+) ErrorCallback : callback for error detection.
92 (+) AbortCpltCallback : callback for abort completion process.
93 (+) MspInitCallback : callback for Msp Init.
94 (+) MspDeInitCallback : callback for Msp DeInit.
95 This function takes as parameters the HAL peripheral handle, the Callback ID
96 and a pointer to the user callback function.
99 Use function @ref HAL_PSSI_UnRegisterCallback to reset a callback to the default
100 weak function.
101 @ref HAL_PSSI_UnRegisterCallback takes as parameters the HAL peripheral handle,
102 and the Callback ID.
103 This function allows to reset following callbacks:
104 (+) TxCpltCallback : callback for transmission end of transfer.
105 (+) RxCpltCallback : callback for reception end of transfer.
106 (+) ErrorCallback : callback for error detection.
107 (+) AbortCpltCallback : callback for abort completion process.
108 (+) MspInitCallback : callback for Msp Init.
109 (+) MspDeInitCallback : callback for Msp DeInit.
112 By default, after the @ref HAL_PSSI_Init() and when the state is @ref HAL_PSSI_STATE_RESET
113 all callbacks are set to the corresponding weak functions:
114 examples @ref HAL_PSSI_TxCpltCallback(), @ref HAL_PSSI_RxCpltCallback().
115 Exception done for MspInit and MspDeInit functions that are
116 reset to the legacy weak functions in the @ref HAL_PSSI_Init()/ @ref HAL_PSSI_DeInit() only when
117 these callbacks are null (not registered beforehand).
118 If MspInit or MspDeInit are not null, the @ref HAL_PSSI_Init()/ @ref HAL_PSSI_DeInit()
119 keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
121 Callbacks can be registered/unregistered in @ref HAL_PSSI_STATE_READY state only.
122 Exception done MspInit/MspDeInit functions that can be registered/unregistered
123 in @ref HAL_PSSI_STATE_READY or @ref HAL_PSSI_STATE_RESET state,
124 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
125 Then, the user first registers the MspInit/MspDeInit user callbacks
126 using @ref HAL_PSSI_RegisterCallback() before calling @ref HAL_PSSI_DeInit()
127 or @ref HAL_PSSI_Init() function.
130 [..]
131 (@) You can refer to the PSSI HAL driver header file for more useful macros
133 @endverbatim
134 ******************************************************************************
135 * @attention
137 * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
138 * All rights reserved.</center></h2>
140 * This software component is licensed by ST under BSD 3-Clause license,
141 * the "License"; You may not use this file except in compliance with the
142 * License. You may obtain a copy of the License at:
143 * opensource.org/licenses/BSD-3-Clause
145 ******************************************************************************
148 /* Includes ------------------------------------------------------------------*/
149 #include "stm32h7xx_hal.h"
151 /** @addtogroup STM32H7xx_HAL_Driver
152 * @{
155 /** @defgroup PSSI PSSI
156 * @brief PSSI HAL module driver
157 * @{
160 #ifdef HAL_PSSI_MODULE_ENABLED
161 #if defined(PSSI)
162 /* Private typedef -----------------------------------------------------------*/
163 /* Private define ------------------------------------------------------------*/
165 /** @defgroup PSSI_Private_Define PSSI Private Define
166 * @{
172 * @}
175 /* Private macro -------------------------------------------------------------*/
176 /* Private variables ---------------------------------------------------------*/
177 /* Private function prototypes -----------------------------------------------*/
179 /** @defgroup PSSI_Private_Functions PSSI Private Functions
180 * @{
182 /* Private functions to handle DMA transfer */
183 void PSSI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
184 void PSSI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
185 void PSSI_DMAError(DMA_HandleTypeDef *hdma);
186 void PSSI_DMAAbort(DMA_HandleTypeDef *hdma);
189 /* Private functions to handle IT transfer */
190 static void PSSI_Error(PSSI_HandleTypeDef *hpssi, uint32_t ErrorCode);
192 /* Private functions to handle flags during polling transfer */
193 static HAL_StatusTypeDef PSSI_WaitOnStatusUntilTimeout(PSSI_HandleTypeDef *hpssi, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart);
196 * @}
199 /* Exported functions --------------------------------------------------------*/
201 /** @defgroup PSSI_Exported_Functions PSSI Exported Functions
202 * @{
205 /** @defgroup PSSI_Exported_Functions_Group1 Initialization and de-initialization functions
206 * @brief Initialization and Configuration functions
208 @verbatim
209 ===============================================================================
210 ##### Initialization and de-initialization functions #####
211 ===============================================================================
212 [..] This subsection provides a set of functions allowing to initialize and
213 deinitialize the PSSIx peripheral:
215 (+) User must implement HAL_PSSI_MspInit() function in which he configures
216 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
218 (+) Call the function HAL_PSSI_Init() to configure the selected device with
219 the selected configuration:
220 (++) Data Width
221 (++) Control Signals
222 (++) Input Clock polarity
223 (++) Output Clock polarity
225 (+) Call the function HAL_PSSI_DeInit() to restore the default configuration
226 of the selected PSSIx peripheral.
228 @endverbatim
229 * @{
233 * @brief Initializes the PSSI according to the specified parameters
234 * in the PSSI_InitTypeDef and initialize the associated handle.
235 * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains
236 * the configuration information for the specified PSSI.
237 * @retval HAL status
239 HAL_StatusTypeDef HAL_PSSI_Init(PSSI_HandleTypeDef *hpssi)
241 /* Check the PSSI handle allocation */
242 if (hpssi == NULL)
244 return HAL_ERROR;
247 /* Check the parameters */
248 assert_param(IS_PSSI_ALL_INSTANCE(hpssi->Instance));
249 assert_param(IS_PSSI_CONTROL_SIGNAL(hpssi->Init.ControlSignal));
250 assert_param(IS_PSSI_BUSWIDTH(hpssi->Init.BusWidth));
251 assert_param(IS_PSSI_CLOCK_POLARITY(hpssi->Init.ClockPolarity));
252 assert_param(IS_PSSI_DE_POLARITY(hpssi->Init.DataEnablePolarity));
253 assert_param(IS_PSSI_RDY_POLARITY(hpssi->Init.ReadyPolarity));
255 if (hpssi->State == HAL_PSSI_STATE_RESET)
257 /* Allocate lock resource and initialize it */
258 hpssi->Lock = HAL_UNLOCKED;
260 /* Init the PSSI Callback settings */
261 hpssi->TxCpltCallback = HAL_PSSI_TxCpltCallback; /* Legacy weak TxCpltCallback */
262 hpssi->RxCpltCallback = HAL_PSSI_RxCpltCallback; /* Legacy weak RxCpltCallback */
263 hpssi->ErrorCallback = HAL_PSSI_ErrorCallback; /* Legacy weak ErrorCallback */
264 hpssi->AbortCpltCallback = HAL_PSSI_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
266 if (hpssi->MspInitCallback == NULL)
268 hpssi->MspInitCallback = HAL_PSSI_MspInit; /* Legacy weak MspInit */
271 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
272 hpssi->MspInitCallback(hpssi);
276 hpssi->State = HAL_PSSI_STATE_BUSY;
278 /* Disable the selected PSSI peripheral */
279 HAL_PSSI_DISABLE(hpssi);
281 /*---------------------------- PSSIx CR Configuration ----------------------*/
282 /* Configure PSSIx: Control Signal and Bus Width*/
284 MODIFY_REG(hpssi->Instance->CR,PSSI_CR_DERDYCFG|PSSI_CR_EDM|PSSI_CR_DEPOL|PSSI_CR_RDYPOL,
285 hpssi->Init.ControlSignal|hpssi->Init.DataEnablePolarity|hpssi->Init.ReadyPolarity|hpssi->Init.BusWidth);
287 hpssi->ErrorCode = HAL_PSSI_ERROR_NONE;
288 hpssi->State = HAL_PSSI_STATE_READY;
290 return HAL_OK;
294 * @brief DeInitialize the PSSI peripheral.
295 * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains
296 * the configuration information for the specified PSSI.
297 * @retval HAL status
299 HAL_StatusTypeDef HAL_PSSI_DeInit(PSSI_HandleTypeDef *hpssi)
301 /* Check the PSSI handle allocation */
302 if (hpssi == NULL)
304 return HAL_ERROR;
307 /* Check the parameters */
308 assert_param(IS_PSSI_ALL_INSTANCE(hpssi->Instance));
310 hpssi->State = HAL_PSSI_STATE_BUSY;
312 /* Disable the PSSI Peripheral Clock */
313 HAL_PSSI_DISABLE(hpssi);
315 if (hpssi->MspDeInitCallback == NULL)
317 hpssi->MspDeInitCallback = HAL_PSSI_MspDeInit; /* Legacy weak MspDeInit */
320 /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
321 hpssi->MspDeInitCallback(hpssi);
323 hpssi->ErrorCode = HAL_PSSI_ERROR_NONE;
324 hpssi->State = HAL_PSSI_STATE_RESET;
326 /* Release Lock */
327 __HAL_UNLOCK(hpssi);
329 return HAL_OK;
333 * @brief Initialize the PSSI MSP.
334 * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains
335 * the configuration information for the specified PSSI.
336 * @retval None
338 __weak void HAL_PSSI_MspInit(PSSI_HandleTypeDef *hpssi)
340 /* Prevent unused argument(s) compilation warning */
341 UNUSED(hpssi);
343 /* NOTE : This function should not be modified, when the callback is needed,
344 the HAL_PSSI_MspInit can be implemented in the user file
349 * @brief DeInitialize 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
354 __weak void HAL_PSSI_MspDeInit(PSSI_HandleTypeDef *hpssi)
356 /* Prevent unused argument(s) compilation warning */
357 UNUSED(hpssi);
359 /* NOTE : This function should not be modified, when the callback is needed,
360 the HAL_PSSI_MspDeInit can be implemented in the user file
365 * @brief Register a User PSSI Callback
366 * To be used instead of the weak predefined callback
367 * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains
368 * the configuration information for the specified PSSI.
369 * @param CallbackID ID of the callback to be registered
370 * This parameter can be one of the following values:
371 * @arg @ref HAL_PSSI_TX_COMPLETE_CB_ID Tx Transfer completed callback ID
372 * @arg @ref HAL_PSSI_RX_COMPLETE_CB_ID Rx Transfer completed callback ID
373 * @arg @ref HAL_PSSI_ERROR_CB_ID Error callback ID
374 * @arg @ref HAL_PSSI_ABORT_CB_ID Abort callback ID
375 * @arg @ref HAL_PSSI_MSPINIT_CB_ID MspInit callback ID
376 * @arg @ref HAL_PSSI_MSPDEINIT_CB_ID MspDeInit callback ID
377 * @param pCallback pointer to the Callback function
378 * @retval HAL status
380 HAL_StatusTypeDef HAL_PSSI_RegisterCallback(PSSI_HandleTypeDef *hpssi, HAL_PSSI_CallbackIDTypeDef CallbackID, pPSSI_CallbackTypeDef pCallback)
382 HAL_StatusTypeDef status = HAL_OK;
384 if (pCallback == NULL)
386 /* Update the error code */
387 hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
389 return HAL_ERROR;
391 /* Process locked */
392 __HAL_LOCK(hpssi);
394 if (HAL_PSSI_STATE_READY == hpssi->State)
396 switch (CallbackID)
398 case HAL_PSSI_TX_COMPLETE_CB_ID :
399 hpssi->TxCpltCallback = pCallback;
400 break;
402 case HAL_PSSI_RX_COMPLETE_CB_ID :
403 hpssi->RxCpltCallback = pCallback;
404 break;
406 case HAL_PSSI_ERROR_CB_ID :
407 hpssi->ErrorCallback = pCallback;
408 break;
410 case HAL_PSSI_ABORT_CB_ID :
411 hpssi->AbortCpltCallback = pCallback;
412 break;
414 case HAL_PSSI_MSPINIT_CB_ID :
415 hpssi->MspInitCallback = pCallback;
416 break;
418 case HAL_PSSI_MSPDEINIT_CB_ID :
419 hpssi->MspDeInitCallback = pCallback;
420 break;
422 default :
423 /* Update the error code */
424 hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
426 /* Return error status */
427 status = HAL_ERROR;
428 break;
431 else if (HAL_PSSI_STATE_RESET == hpssi->State)
433 switch (CallbackID)
435 case HAL_PSSI_MSPINIT_CB_ID :
436 hpssi->MspInitCallback = pCallback;
437 break;
439 case HAL_PSSI_MSPDEINIT_CB_ID :
440 hpssi->MspDeInitCallback = pCallback;
441 break;
443 default :
444 /* Update the error code */
445 hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
447 /* Return error status */
448 status = HAL_ERROR;
449 break;
452 else
454 /* Update the error code */
455 hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
457 /* Return error status */
458 status = HAL_ERROR;
461 /* Release Lock */
462 __HAL_UNLOCK(hpssi);
463 return status;
467 * @brief Unregister an PSSI Callback
468 * PSSI callback is redirected to the weak predefined callback
469 * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains
470 * the configuration information for the specified PSSI.
471 * @param CallbackID ID of the callback to be unregistered
472 * This parameter can be one of the following values:
473 * @arg @ref HAL_PSSI_TX_COMPLETE_CB_ID Tx Transfer completed callback ID
474 * @arg @ref HAL_PSSI_RX_COMPLETE_CB_ID Rx Transfer completed callback ID
475 * @arg @ref HAL_PSSI_ERROR_CB_ID Error callback ID
476 * @arg @ref HAL_PSSI_ABORT_CB_ID Abort callback ID
477 * @arg @ref HAL_PSSI_MSPINIT_CB_ID MspInit callback ID
478 * @arg @ref HAL_PSSI_MSPDEINIT_CB_ID MspDeInit callback ID
479 * @retval HAL status
481 HAL_StatusTypeDef HAL_PSSI_UnRegisterCallback(PSSI_HandleTypeDef *hpssi, HAL_PSSI_CallbackIDTypeDef CallbackID)
483 HAL_StatusTypeDef status = HAL_OK;
485 /* Process locked */
486 __HAL_LOCK(hpssi);
488 if (HAL_PSSI_STATE_READY == hpssi->State)
490 switch (CallbackID)
492 case HAL_PSSI_TX_COMPLETE_CB_ID :
493 hpssi->TxCpltCallback = HAL_PSSI_TxCpltCallback; /* Legacy weak TxCpltCallback */
494 break;
496 case HAL_PSSI_RX_COMPLETE_CB_ID :
497 hpssi->RxCpltCallback = HAL_PSSI_RxCpltCallback; /* Legacy weak RxCpltCallback */
498 break;
500 case HAL_PSSI_ERROR_CB_ID :
501 hpssi->ErrorCallback = HAL_PSSI_ErrorCallback; /* Legacy weak ErrorCallback */
502 break;
504 case HAL_PSSI_ABORT_CB_ID :
505 hpssi->AbortCpltCallback = HAL_PSSI_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
506 break;
508 case HAL_PSSI_MSPINIT_CB_ID :
509 hpssi->MspInitCallback = HAL_PSSI_MspInit; /* Legacy weak MspInit */
510 break;
512 case HAL_PSSI_MSPDEINIT_CB_ID :
513 hpssi->MspDeInitCallback = HAL_PSSI_MspDeInit; /* Legacy weak MspDeInit */
514 break;
516 default :
517 /* Update the error code */
518 hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
520 /* Return error status */
521 status = HAL_ERROR;
522 break;
525 else if (HAL_PSSI_STATE_RESET == hpssi->State)
527 switch (CallbackID)
529 case HAL_PSSI_MSPINIT_CB_ID :
530 hpssi->MspInitCallback = HAL_PSSI_MspInit; /* Legacy weak MspInit */
531 break;
533 case HAL_PSSI_MSPDEINIT_CB_ID :
534 hpssi->MspDeInitCallback = HAL_PSSI_MspDeInit; /* Legacy weak MspDeInit */
535 break;
537 default :
538 /* Update the error code */
539 hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
541 /* Return error status */
542 status = HAL_ERROR;
543 break;
546 else
548 /* Update the error code */
549 hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK;
551 /* Return error status */
552 status = HAL_ERROR;
555 /* Release Lock */
556 __HAL_UNLOCK(hpssi);
557 return status;
562 * @}
565 /** @defgroup PSSI_Exported_Functions_Group2 Input and Output operation functions
566 * @brief Data transfers functions
568 @verbatim
569 ===============================================================================
570 ##### IO operation functions #####
571 ===============================================================================
572 [..]
573 This subsection provides a set of functions allowing to manage the PSSI data
574 transfers.
576 (#) There are two modes of transfer:
577 (++) Blocking mode : The communication is performed in the polling mode.
578 The status of all data processing is returned by the same function
579 after finishing transfer.
580 (++) No-Blocking mode : The communication is performed using DMA.
581 These functions return the status of the transfer startup.
582 The end of the data processing will be indicated through the
583 dedicated the DMA IRQ .
585 (#) Blocking mode functions are :
586 (++) HAL_PSSI_Transmit()
587 (++) HAL_PSSI_Receive()
589 (#) No-Blocking mode functions with DMA are :
590 (++) HAL_PSSI_Transmit_DMA()
591 (++) HAL_PSSI_Receive_DMA()
593 (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
594 (++) HAL_PSSI_TxCpltCallback()
595 (++) HAL_PSSI_RxCpltCallback()
596 (++) HAL_PSSI_ErrorCallback()
597 (++) HAL_PSSI_AbortCpltCallback()
599 @endverbatim
600 * @{
604 * @brief Transmits in master mode an amount of data in blocking mode.
605 * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains
606 * the configuration information for the specified PSSI.
607 * @param pData Pointer to data buffer
608 * @param Size Amount of data to be sent (in bytes)
609 * @param Timeout Timeout duration
610 * @retval HAL status
612 HAL_StatusTypeDef HAL_PSSI_Transmit(PSSI_HandleTypeDef *hpssi, uint8_t *pData, uint32_t Size, uint32_t Timeout)
614 uint32_t tickstart;
615 uint32_t transfer_size = Size;
617 #if defined (__GNUC__)
618 __IO uint16_t *pdr_16bits = (__IO uint16_t *)(&(hpssi->Instance->DR));
619 #endif /* __GNUC__ */
621 if (((hpssi->Init.DataWidth == HAL_PSSI_8BITS) && (hpssi->Init.BusWidth != HAL_PSSI_8LINES)) ||
622 ((hpssi->Init.DataWidth == HAL_PSSI_16BITS) && ((Size%2U) != 0U)) ||
623 ((hpssi->Init.DataWidth == HAL_PSSI_32BITS) && ((Size%4U) != 0U)))
625 hpssi->ErrorCode = HAL_PSSI_ERROR_NOT_SUPPORTED;
626 return HAL_ERROR;
628 if (hpssi->State == HAL_PSSI_STATE_READY)
630 /* Process Locked */
631 __HAL_LOCK(hpssi);
633 hpssi->State = HAL_PSSI_STATE_BUSY;
634 hpssi->ErrorCode = HAL_PSSI_ERROR_NONE;
636 /* Disable the selected PSSI peripheral */
637 HAL_PSSI_DISABLE(hpssi);
639 /* Configure transfer parameters */
640 hpssi->Instance->CR |= PSSI_CR_OUTEN_OUTPUT |
641 ((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE)?0U:PSSI_CR_CKPOL);
642 /* DMA Disable */
643 hpssi->Instance->CR &= PSSI_CR_DMA_DISABLE;
645 /* Enable the selected PSSI peripheral */
646 HAL_PSSI_ENABLE(hpssi);
648 if (hpssi->Init.DataWidth == HAL_PSSI_8BITS)
650 uint8_t *pbuffer = pData;
651 while (transfer_size > 0U)
653 /* Init tickstart for timeout management*/
654 tickstart = HAL_GetTick();
655 /* Wait until Fifo is ready to transfer one byte flag is set */
656 if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT1B, RESET, Timeout, tickstart) != HAL_OK)
658 hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT;
659 hpssi->State = HAL_PSSI_STATE_READY;
660 /* Process Unlocked */
661 __HAL_UNLOCK(hpssi);
662 return HAL_ERROR;
664 /* Write data to DR */
665 *(__IO uint8_t *)(&hpssi->Instance->DR) = *(uint8_t *)pbuffer;
667 /* Increment Buffer pointer */
668 pbuffer++;
670 transfer_size--;
673 else if (hpssi->Init.DataWidth == HAL_PSSI_16BITS)
675 uint16_t *pbuffer = (uint16_t *)pData;
676 while (transfer_size > 0U)
678 /* Init tickstart for timeout management*/
679 tickstart = HAL_GetTick();
680 /* Wait until Fifo is ready to transfer four bytes flag is set */
681 if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT4B, RESET, Timeout, tickstart) != HAL_OK)
683 hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT;
684 hpssi->State = HAL_PSSI_STATE_READY;
685 /* Process Unlocked */
686 __HAL_UNLOCK(hpssi);
687 return HAL_ERROR;
689 /* Write data to DR */
690 #if defined (__GNUC__)
691 *pdr_16bits = *pbuffer;
692 #else
693 *(__IO uint16_t *)((uint32_t)(&hpssi->Instance->DR)) = *pbuffer;
694 #endif /* __GNUC__ */
696 /* Increment Buffer pointer */
697 pbuffer++;
698 transfer_size -= 2U;
702 else if (hpssi->Init.DataWidth == HAL_PSSI_32BITS)
704 uint32_t *pbuffer = (uint32_t *)pData;
705 while (transfer_size > 0U)
707 /* Init tickstart for timeout management*/
708 tickstart = HAL_GetTick();
709 /* Wait until Fifo is ready to transfer four bytes flag is set */
710 if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT4B, RESET, Timeout, tickstart) != HAL_OK)
712 hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT;
713 hpssi->State = HAL_PSSI_STATE_READY;
714 /* Process Unlocked */
715 __HAL_UNLOCK(hpssi);
716 return HAL_ERROR;
718 /* Write data to DR */
719 *(__IO uint32_t *)(&hpssi->Instance->DR) = *pbuffer;
721 /* Increment Buffer pointer */
722 pbuffer++;
723 transfer_size -= 4U;
727 else
729 hpssi->ErrorCode = HAL_PSSI_ERROR_NOT_SUPPORTED;
730 hpssi->State = HAL_PSSI_STATE_READY;
731 /* Process Unlocked */
732 __HAL_UNLOCK(hpssi);
733 return HAL_ERROR;
736 /* Check Errors Flags */
737 if (HAL_PSSI_GET_FLAG(hpssi, PSSI_FLAG_OVR_RIS) != 0U)
739 HAL_PSSI_CLEAR_FLAG(hpssi, PSSI_FLAG_OVR_RIS);
740 HAL_PSSI_DISABLE(hpssi);
741 hpssi->ErrorCode = HAL_PSSI_ERROR_UNDER_RUN;
742 hpssi->State = HAL_PSSI_STATE_READY;
743 /* Process Unlocked */
744 __HAL_UNLOCK(hpssi);
745 return HAL_ERROR;
748 hpssi->State = HAL_PSSI_STATE_READY;
750 /* Process Unlocked */
751 __HAL_UNLOCK(hpssi);
753 return HAL_OK;
755 else
757 return HAL_BUSY;
763 * @brief Receives an amount of data in blocking mode.
764 * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains
765 * the configuration information for the specified PSSI.
766 * @param pData Pointer to data buffer
767 * @param Size Amount of data to be received (in bytes)
768 * @param Timeout Timeout duration
769 * @retval HAL status
771 HAL_StatusTypeDef HAL_PSSI_Receive(PSSI_HandleTypeDef *hpssi, uint8_t *pData, uint32_t Size, uint32_t Timeout)
773 uint32_t tickstart;
774 uint32_t transfer_size = Size;
775 #if defined (__GNUC__)
776 __IO uint16_t *pdr_16bits = (__IO uint16_t *)(&(hpssi->Instance->DR));
777 #endif /* __GNUC__ */
779 if (((hpssi->Init.DataWidth == HAL_PSSI_8BITS) && (hpssi->Init.BusWidth != HAL_PSSI_8LINES)) ||
780 ((hpssi->Init.DataWidth == HAL_PSSI_16BITS) && ((Size%2U) != 0U)) ||
781 ((hpssi->Init.DataWidth == HAL_PSSI_32BITS) && ((Size%4U) != 0U)))
783 hpssi->ErrorCode = HAL_PSSI_ERROR_NOT_SUPPORTED;
784 return HAL_ERROR;
787 if (hpssi->State == HAL_PSSI_STATE_READY)
789 /* Process Locked */
790 __HAL_LOCK(hpssi);
792 hpssi->State = HAL_PSSI_STATE_BUSY;
793 hpssi->ErrorCode = HAL_PSSI_ERROR_NONE;
795 /* Disable the selected PSSI peripheral */
796 HAL_PSSI_DISABLE(hpssi);
797 /* Configure transfer parameters */
798 hpssi->Instance->CR |= PSSI_CR_OUTEN_INPUT |((hpssi->Init.ClockPolarity == HAL_PSSI_FALLING_EDGE)?0U:PSSI_CR_CKPOL);
801 /* DMA Disable */
802 hpssi->Instance->CR &= PSSI_CR_DMA_DISABLE;
804 /* Enable the selected PSSI peripheral */
805 HAL_PSSI_ENABLE(hpssi);
806 if (hpssi->Init.DataWidth == HAL_PSSI_8BITS)
808 uint8_t *pbuffer = pData;
810 while (transfer_size > 0U)
812 /* Init tickstart for timeout management*/
813 tickstart = HAL_GetTick();
814 /* Wait until Fifo is ready to receive one byte flag is set */
815 if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT1B, RESET, Timeout, tickstart) != HAL_OK)
817 hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT;
818 hpssi->State = HAL_PSSI_STATE_READY;
819 /* Process Unlocked */
820 __HAL_UNLOCK(hpssi);
821 return HAL_ERROR;
823 /* Read data from DR */
824 *pbuffer = *(__IO uint8_t *)(&hpssi->Instance->DR);
825 pbuffer++;
826 transfer_size--;
829 else if (hpssi->Init.DataWidth == HAL_PSSI_16BITS)
831 uint16_t *pbuffer = (uint16_t *)pData;
833 while (transfer_size > 0U)
835 /* Init tickstart for timeout management*/
836 tickstart = HAL_GetTick();
837 /* Wait until Fifo is ready to receive four bytes flag is set */
838 if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT4B, RESET, Timeout, tickstart) != HAL_OK)
840 hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT;
841 hpssi->State = HAL_PSSI_STATE_READY;
842 /* Process Unlocked */
843 __HAL_UNLOCK(hpssi);
844 return HAL_ERROR;
847 /* Read data from DR */
848 #if defined (__GNUC__)
849 *pbuffer = *pdr_16bits;
850 #else
851 *pbuffer = *(__IO uint16_t *)((uint32_t)&hpssi->Instance->DR);
852 #endif /* __GNUC__ */
854 pbuffer++;
855 transfer_size -= 2U;
859 else if (hpssi->Init.DataWidth == HAL_PSSI_32BITS)
861 uint32_t *pbuffer = (uint32_t *)pData;
863 while (transfer_size > 0U)
865 /* Init tickstart for timeout management*/
866 tickstart = HAL_GetTick();
867 /* Wait until Fifo is ready to receive four bytes flag is set */
868 if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT4B, RESET, Timeout, tickstart) != HAL_OK)
870 hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT;
871 hpssi->State = HAL_PSSI_STATE_READY;
872 /* Process Unlocked */
873 __HAL_UNLOCK(hpssi);
874 return HAL_ERROR;
877 /* Read data from DR */
878 *pbuffer = *(__IO uint32_t *)(&hpssi->Instance->DR);
879 pbuffer++;
880 transfer_size -= 4U;
884 else
886 hpssi->ErrorCode = HAL_PSSI_ERROR_NOT_SUPPORTED;
887 hpssi->State = HAL_PSSI_STATE_READY;
888 /* Process Unlocked */
889 __HAL_UNLOCK(hpssi);
890 return HAL_ERROR;
892 /* Check Errors Flags */
894 if (HAL_PSSI_GET_FLAG(hpssi, PSSI_FLAG_OVR_RIS) != 0U)
896 HAL_PSSI_CLEAR_FLAG(hpssi, PSSI_FLAG_OVR_RIS);
897 hpssi->ErrorCode = HAL_PSSI_ERROR_OVER_RUN;
898 __HAL_UNLOCK(hpssi);
899 return HAL_ERROR;
903 hpssi->State = HAL_PSSI_STATE_READY;
905 /* Process Unlocked */
906 __HAL_UNLOCK(hpssi);
908 return HAL_OK;
910 else
912 return HAL_BUSY;
917 * @brief Transmit an amount of data in non-blocking mode with DMA
918 * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains
919 * the configuration information for the specified PSSI.
920 * @param pData Pointer to data buffer
921 * @param Size Amount of data to be sent (in bytes)
922 * @retval HAL status
924 HAL_StatusTypeDef HAL_PSSI_Transmit_DMA(PSSI_HandleTypeDef *hpssi, uint32_t *pData, uint32_t Size)
926 HAL_StatusTypeDef dmaxferstatus;
928 if (hpssi->State == HAL_PSSI_STATE_READY)
931 /* Process Locked */
932 __HAL_LOCK(hpssi);
934 hpssi->State = HAL_PSSI_STATE_BUSY_TX;
935 hpssi->ErrorCode = HAL_PSSI_ERROR_NONE;
937 /* Disable the selected PSSI peripheral */
938 HAL_PSSI_DISABLE(hpssi);
940 /* Prepare transfer parameters */
941 hpssi->pBuffPtr = pData;
942 hpssi->XferCount = Size;
944 if (hpssi->XferCount > PSSI_MAX_NBYTE_SIZE)
946 hpssi->XferSize = PSSI_MAX_NBYTE_SIZE;
948 else
950 hpssi->XferSize = hpssi->XferCount;
953 if (hpssi->XferSize > 0U)
955 if (hpssi->hdmatx != NULL)
958 /* Configure BusWidth */
959 if( hpssi->hdmatx->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
961 MODIFY_REG(hpssi->Instance->CR,PSSI_CR_DMAEN|PSSI_CR_OUTEN|PSSI_CR_CKPOL,PSSI_CR_DMA_ENABLE | PSSI_CR_OUTEN_OUTPUT |
962 ((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE)?0U:PSSI_CR_CKPOL));
964 else
966 MODIFY_REG(hpssi->Instance->CR,PSSI_CR_DMAEN|PSSI_CR_OUTEN|PSSI_CR_CKPOL,PSSI_CR_DMA_ENABLE | hpssi->Init.BusWidth | PSSI_CR_OUTEN_OUTPUT |
967 ((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE)?0U:PSSI_CR_CKPOL));
970 /* Set the PSSI DMA transfer complete callback */
971 hpssi->hdmatx->XferCpltCallback = PSSI_DMATransmitCplt;
973 /* Set the DMA error callback */
974 hpssi->hdmatx->XferErrorCallback = PSSI_DMAError;
976 /* Set the unused DMA callbacks to NULL */
977 hpssi->hdmatx->XferHalfCpltCallback = NULL;
978 hpssi->hdmatx->XferAbortCallback = NULL;
980 /* Enable the DMA */
981 dmaxferstatus = HAL_DMA_Start_IT(hpssi->hdmatx, (uint32_t)pData, (uint32_t)&hpssi->Instance->DR, hpssi->XferSize);
983 else
985 /* Update PSSI state */
986 hpssi->State = HAL_PSSI_STATE_READY;
988 /* Update PSSI error code */
989 hpssi->ErrorCode |= HAL_PSSI_ERROR_DMA;
991 /* Process Unlocked */
992 __HAL_UNLOCK(hpssi);
994 return HAL_ERROR;
997 if (dmaxferstatus == HAL_OK)
1001 /* Update XferCount value */
1002 hpssi->XferCount -= hpssi->XferSize;
1004 /* Process Unlocked */
1005 __HAL_UNLOCK(hpssi);
1007 /* Note : The PSSI interrupts must be enabled after unlocking current process
1008 to avoid the risk of PSSI interrupt handle execution before current
1009 process unlock */
1010 /* Enable ERR interrupt */
1011 HAL_PSSI_ENABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1013 /* Enable DMA Request */
1014 hpssi->Instance->CR |= PSSI_CR_DMA_ENABLE;
1015 /* Enable the selected PSSI peripheral */
1016 HAL_PSSI_ENABLE(hpssi);
1018 else
1020 /* Update PSSI state */
1021 hpssi->State = HAL_PSSI_STATE_READY;
1023 /* Update PSSI error code */
1024 hpssi->ErrorCode |= HAL_PSSI_ERROR_DMA;
1026 /* Process Unlocked */
1027 __HAL_UNLOCK(hpssi);
1029 return HAL_ERROR;
1032 else
1034 /* Process Unlocked */
1035 __HAL_UNLOCK(hpssi);
1037 /* Note : The PSSI interrupts must be enabled after unlocking current process
1038 to avoid the risk of PSSI interrupt handle execution before current
1039 process unlock */
1040 /* Enable ERRinterrupt */
1041 /* possible to enable all of these */
1043 HAL_PSSI_ENABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1046 return HAL_OK;
1048 else
1050 return HAL_BUSY;
1055 * @brief Receive an amount of data in non-blocking mode with DMA
1056 * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1057 * the configuration information for the specified PSSI.
1058 * @param pData Pointer to data buffer
1059 * @param Size Amount of data to be received (in bytes)
1060 * @retval HAL status
1062 HAL_StatusTypeDef HAL_PSSI_Receive_DMA(PSSI_HandleTypeDef *hpssi, uint32_t *pData, uint32_t Size)
1065 HAL_StatusTypeDef dmaxferstatus;
1067 if (hpssi->State == HAL_PSSI_STATE_READY)
1070 /* Disable the selected PSSI peripheral */
1071 HAL_PSSI_DISABLE(hpssi);
1072 /* Process Locked */
1073 __HAL_LOCK(hpssi);
1075 hpssi->State = HAL_PSSI_STATE_BUSY_RX;
1076 hpssi->ErrorCode = HAL_PSSI_ERROR_NONE;
1078 /* Prepare transfer parameters */
1079 hpssi->pBuffPtr = pData;
1080 hpssi->XferCount = Size;
1082 if (hpssi->XferCount > PSSI_MAX_NBYTE_SIZE)
1084 hpssi->XferSize = PSSI_MAX_NBYTE_SIZE;
1086 else
1088 hpssi->XferSize = hpssi->XferCount;
1091 if (hpssi->XferSize > 0U)
1093 if (hpssi->hdmarx != NULL)
1096 /* Configure BusWidth */
1097 if( hpssi->hdmatx->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
1099 MODIFY_REG(hpssi->Instance->CR,PSSI_CR_DMAEN|PSSI_CR_OUTEN|PSSI_CR_CKPOL,PSSI_CR_DMA_ENABLE |
1100 ((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE)?PSSI_CR_CKPOL:0U));
1102 else
1104 MODIFY_REG(hpssi->Instance->CR,PSSI_CR_DMAEN|PSSI_CR_OUTEN|PSSI_CR_CKPOL,PSSI_CR_DMA_ENABLE | hpssi->Init.BusWidth |
1105 ((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE)?PSSI_CR_CKPOL:0U));
1108 /* Set the PSSI DMA transfer complete callback */
1109 hpssi->hdmarx->XferCpltCallback = PSSI_DMAReceiveCplt;
1111 /* Set the DMA error callback */
1112 hpssi->hdmarx->XferErrorCallback = PSSI_DMAError;
1114 /* Set the unused DMA callbacks to NULL */
1115 hpssi->hdmarx->XferHalfCpltCallback = NULL;
1116 hpssi->hdmarx->XferAbortCallback = NULL;
1118 /* Enable the DMA */
1119 dmaxferstatus = HAL_DMA_Start_IT(hpssi->hdmarx, (uint32_t)&hpssi->Instance->DR, (uint32_t)pData, hpssi->XferSize);
1121 else
1123 /* Update PSSI state */
1124 hpssi->State = HAL_PSSI_STATE_READY;
1126 /* Update PSSI error code */
1127 hpssi->ErrorCode |= HAL_PSSI_ERROR_DMA;
1129 /* Process Unlocked */
1130 __HAL_UNLOCK(hpssi);
1132 return HAL_ERROR;
1135 if (dmaxferstatus == HAL_OK)
1137 /* Update XferCount value */
1138 hpssi->XferCount -= hpssi->XferSize;
1140 /* Process Unlocked */
1141 __HAL_UNLOCK(hpssi);
1143 /* Note : The PSSI interrupts must be enabled after unlocking current process
1144 to avoid the risk of PSSI interrupt handle execution before current
1145 process unlock */
1146 /* Enable ERR interrupt */
1147 HAL_PSSI_ENABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1149 /* Enable DMA Request */
1150 hpssi->Instance->CR |= PSSI_CR_DMA_ENABLE;
1151 /* Enable the selected PSSI peripheral */
1152 HAL_PSSI_ENABLE(hpssi);
1154 else
1156 /* Update PSSI state */
1157 hpssi->State = HAL_PSSI_STATE_READY;
1159 /* Update PSSI error code */
1160 hpssi->ErrorCode |= HAL_PSSI_ERROR_DMA;
1162 /* Process Unlocked */
1163 __HAL_UNLOCK(hpssi);
1165 return HAL_ERROR;
1168 else
1171 /* Process Unlocked */
1172 __HAL_UNLOCK(hpssi);
1174 /* Enable ERR,interrupt */
1175 HAL_PSSI_ENABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1178 return HAL_OK;
1180 else
1182 return HAL_BUSY;
1189 * @brief Abort a DMA process communication with Interrupt.
1190 * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1191 * the configuration information for the specified PSSI.
1192 * @retval HAL status
1194 HAL_StatusTypeDef HAL_PSSI_Abort_DMA(PSSI_HandleTypeDef *hpssi)
1197 /* Process Locked */
1198 __HAL_LOCK(hpssi);
1200 /* Disable Interrupts */
1201 HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1203 /* Set State at HAL_PSSI_STATE_ABORT */
1204 hpssi->State = HAL_PSSI_STATE_ABORT;
1206 /* Abort DMA TX transfer if any */
1207 if ((hpssi->Instance->CR & PSSI_CR_DMAEN) == PSSI_CR_DMAEN)
1209 if (hpssi->State == HAL_PSSI_STATE_BUSY_TX)
1212 hpssi->Instance->CR &= ~PSSI_CR_DMAEN;
1214 if (hpssi->hdmatx != NULL)
1216 /* Set the PSSI DMA Abort callback :
1217 will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */
1218 hpssi->hdmatx->XferAbortCallback = PSSI_DMAAbort;
1220 /* Abort DMA TX */
1221 if (HAL_DMA_Abort_IT(hpssi->hdmatx) != HAL_OK)
1223 /* Call Directly XferAbortCallback function in case of error */
1224 hpssi->hdmatx->XferAbortCallback(hpssi->hdmatx);
1229 /* Abort DMA RX transfer if any */
1230 else if (hpssi->State == HAL_PSSI_STATE_BUSY_RX)
1233 hpssi->Instance->CR &= ~PSSI_CR_DMAEN;
1235 if (hpssi->hdmarx != NULL)
1237 /* Set the PSSI DMA Abort callback :
1238 will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */
1239 hpssi->hdmarx->XferAbortCallback = PSSI_DMAAbort;
1241 /* Abort DMA RX */
1242 if (HAL_DMA_Abort_IT(hpssi->hdmarx) != HAL_OK)
1244 /* Call Directly hpssi->hdma->XferAbortCallback function in case of error */
1245 hpssi->hdmarx->XferAbortCallback(hpssi->hdmarx);
1249 else
1251 /* Call the error callback */
1252 hpssi->ErrorCallback(hpssi);
1257 /* Process Unlocked */
1258 __HAL_UNLOCK(hpssi);
1260 /* Note : The PSSI interrupts must be enabled after unlocking current process
1261 to avoid the risk of PSSI interrupt handle execution before current
1262 process unlock */
1263 HAL_PSSI_ENABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1265 return HAL_OK;
1270 * @}
1273 /** @defgroup PSSI_Exported_Functions_Group3 IRQ Handler and Callbacks
1274 * @{
1278 * @brief This function handles PSSI event interrupt request.
1279 * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1280 * the configuration information for the specified PSSI.
1281 * @retval None
1283 void HAL_PSSI_IRQHandler(PSSI_HandleTypeDef *hpssi)
1285 /* Overrun/ Underrun Errors */
1286 if (HAL_PSSI_GET_FLAG(hpssi, PSSI_FLAG_OVR_MIS) != 0U)
1288 /* Reset handle parameters */
1290 hpssi->XferCount = 0U;
1292 /* Disable all interrupts */
1293 HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1296 /* Abort DMA TX transfer if any */
1297 if ((hpssi->Instance->CR & PSSI_CR_DMAEN) == PSSI_CR_DMAEN)
1299 if (hpssi->State == HAL_PSSI_STATE_BUSY_TX)
1301 /* Set new error code */
1302 hpssi->ErrorCode |= HAL_PSSI_ERROR_UNDER_RUN;
1304 hpssi->Instance->CR &= ~PSSI_CR_DMAEN;
1306 if (hpssi->hdmatx != NULL)
1308 /* Set the PSSI DMA Abort callback :
1309 will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */
1310 hpssi->hdmatx->XferAbortCallback = PSSI_DMAAbort;
1312 /* Process Unlocked */
1313 __HAL_UNLOCK(hpssi);
1315 /* Abort DMA TX */
1316 if (HAL_DMA_Abort_IT(hpssi->hdmatx) != HAL_OK)
1318 /* Call Directly XferAbortCallback function in case of error */
1319 hpssi->hdmatx->XferAbortCallback(hpssi->hdmatx);
1324 /* Abort DMA RX transfer if any */
1325 else if (hpssi->State == HAL_PSSI_STATE_BUSY_RX)
1327 /* Set new error code */
1328 hpssi->ErrorCode |= HAL_PSSI_ERROR_OVER_RUN;
1330 hpssi->Instance->CR &= ~PSSI_CR_DMAEN;
1332 if (hpssi->hdmarx != NULL)
1334 /* Set the PSSI DMA Abort callback :
1335 will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */
1336 hpssi->hdmarx->XferAbortCallback = PSSI_DMAAbort;
1338 /* Process Unlocked */
1339 __HAL_UNLOCK(hpssi);
1341 /* Abort DMA RX */
1342 if (HAL_DMA_Abort_IT(hpssi->hdmarx) != HAL_OK)
1344 /* Call Directly hpssi->hdma->XferAbortCallback function in case of error */
1345 hpssi->hdmarx->XferAbortCallback(hpssi->hdmarx);
1349 else
1351 /* Call the corresponding callback to inform upper layer of the error */
1352 hpssi->ErrorCallback(hpssi);
1356 /* If state is an abort treatment on going, don't change state */
1357 if (hpssi->State == HAL_PSSI_STATE_ABORT)
1359 hpssi->State = HAL_PSSI_STATE_READY;
1361 /* Process Unlocked */
1362 __HAL_UNLOCK(hpssi);
1364 /* Call the corresponding callback to inform upper layer of End of Transfer */
1365 hpssi->AbortCpltCallback(hpssi);
1368 else
1370 /* Set HAL_PSSI_STATE_READY */
1371 hpssi->State = HAL_PSSI_STATE_READY;
1372 /* Process Unlocked */
1373 __HAL_UNLOCK(hpssi);
1375 /* Call the corresponding callback to inform upper layer of End of Transfer */
1376 hpssi->ErrorCallback(hpssi);
1385 * @brief Tx Transfer complete callback.
1386 * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1387 * the configuration information for the specified PSSI.
1388 * @retval None
1390 __weak void HAL_PSSI_TxCpltCallback(PSSI_HandleTypeDef *hpssi)
1392 /* Prevent unused argument(s) compilation warning */
1393 UNUSED(hpssi);
1395 /* NOTE : This function should not be modified, when the callback is needed,
1396 the HAL_PSSI_TxCpltCallback can be implemented in the user file
1401 * @brief Rx Transfer complete callback.
1402 * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1403 * the configuration information for the specified PSSI.
1404 * @retval None
1406 __weak void HAL_PSSI_RxCpltCallback(PSSI_HandleTypeDef *hpssi)
1408 /* Prevent unused argument(s) compilation warning */
1409 UNUSED(hpssi);
1411 /* NOTE : This function should not be modified, when the callback is needed,
1412 the HAL_PSSI_RxCpltCallback can be implemented in the user file
1418 * @brief PSSI error callback.
1419 * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1420 * the configuration information for the specified PSSI.
1421 * @retval None
1423 __weak void HAL_PSSI_ErrorCallback(PSSI_HandleTypeDef *hpssi)
1425 /* Prevent unused argument(s) compilation warning */
1426 UNUSED(hpssi);
1428 /* NOTE : This function should not be modified, when the callback is needed,
1429 the HAL_PSSI_ErrorCallback could be implemented in the user file
1434 * @brief PSSI abort callback.
1435 * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1436 * the configuration information for the specified PSSI.
1437 * @retval None
1439 __weak void HAL_PSSI_AbortCpltCallback(PSSI_HandleTypeDef *hpssi)
1441 /* Prevent unused argument(s) compilation warning */
1442 UNUSED(hpssi);
1444 /* NOTE : This function should not be modified, when the callback is needed,
1445 the HAL_PSSI_AbortCpltCallback could be implemented in the user file
1450 * @}
1453 /** @defgroup PSSI_Exported_Functions_Group4 Peripheral State, Mode and Error functions
1454 * @brief Peripheral State, Mode and Error functions
1456 @verbatim
1457 ===============================================================================
1458 ##### Peripheral State, Mode and Error functions #####
1459 ===============================================================================
1460 [..]
1461 This subsection permit to get in run-time the status of the peripheral
1462 and the data flow.
1464 @endverbatim
1465 * @{
1469 * @brief Return the PSSI handle state.
1470 * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1471 * the configuration information for the specified PSSI.
1472 * @retval HAL state
1474 HAL_PSSI_StateTypeDef HAL_PSSI_GetState(PSSI_HandleTypeDef *hpssi)
1476 /* Return PSSI handle state */
1477 return hpssi->State;
1482 * @brief Return the PSSI error code.
1483 * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1484 * the configuration information for the specified PSSI.
1485 * @retval PSSI Error Code
1487 uint32_t HAL_PSSI_GetError(PSSI_HandleTypeDef *hpssi)
1489 return hpssi->ErrorCode;
1493 * @}
1497 * @}
1500 /** @addtogroup PSSI_Private_Functions
1501 * @{
1505 * @brief PSSI Errors process.
1506 * @param hpssi PSSI handle.
1507 * @param ErrorCode Error code to handle.
1508 * @retval None
1510 static void PSSI_Error(PSSI_HandleTypeDef *hpssi, uint32_t ErrorCode)
1513 /* Reset handle parameters */
1515 hpssi->XferCount = 0U;
1517 /* Set new error code */
1518 hpssi->ErrorCode |= ErrorCode;
1520 /* Disable all interrupts */
1521 HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1524 /* Abort DMA TX transfer if any */
1525 if ((hpssi->Instance->CR & PSSI_CR_DMAEN) == PSSI_CR_DMAEN)
1527 if (hpssi->State == HAL_PSSI_STATE_BUSY_TX)
1529 hpssi->Instance->CR &= ~PSSI_CR_DMAEN;
1531 if (hpssi->hdmatx != NULL)
1533 /* Set the PSSI DMA Abort callback :
1534 will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */
1535 hpssi->hdmatx->XferAbortCallback = PSSI_DMAAbort;
1537 /* Process Unlocked */
1538 __HAL_UNLOCK(hpssi);
1540 /* Abort DMA TX */
1541 if (HAL_DMA_Abort_IT(hpssi->hdmatx) != HAL_OK)
1543 /* Call Directly XferAbortCallback function in case of error */
1544 hpssi->hdmatx->XferAbortCallback(hpssi->hdmatx);
1549 /* Abort DMA RX transfer if any */
1550 else if (hpssi->State == HAL_PSSI_STATE_BUSY_RX)
1552 hpssi->Instance->CR &= ~PSSI_CR_DMAEN;
1554 if (hpssi->hdmarx != NULL)
1556 /* Set the PSSI DMA Abort callback :
1557 will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */
1558 hpssi->hdmarx->XferAbortCallback = PSSI_DMAAbort;
1560 /* Process Unlocked */
1561 __HAL_UNLOCK(hpssi);
1563 /* Abort DMA RX */
1564 if (HAL_DMA_Abort_IT(hpssi->hdmarx) != HAL_OK)
1566 /* Call Directly hpssi->hdma->XferAbortCallback function in case of error */
1567 hpssi->hdmarx->XferAbortCallback(hpssi->hdmarx);
1571 else
1573 /*Nothing to do*/
1577 /* If state is an abort treatment on going, don't change state */
1578 if (hpssi->State == HAL_PSSI_STATE_ABORT)
1580 hpssi->State = HAL_PSSI_STATE_READY;
1582 /* Process Unlocked */
1583 __HAL_UNLOCK(hpssi);
1585 /* Call the corresponding callback to inform upper layer of End of Transfer */
1587 hpssi->AbortCpltCallback(hpssi);
1590 else
1592 /* Set HAL_PSSI_STATE_READY */
1593 hpssi->State = HAL_PSSI_STATE_READY;
1595 /* Process Unlocked */
1596 __HAL_UNLOCK(hpssi);
1598 /* Call the corresponding callback to inform upper layer of End of Transfer */
1599 hpssi->ErrorCallback(hpssi);
1605 * @brief DMA PSSI slave transmit process complete callback.
1606 * @param hdma DMA handle
1607 * @retval None
1609 void PSSI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1611 PSSI_HandleTypeDef *hpssi = (PSSI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
1613 uint32_t tmperror;
1616 /* Disable Interrupts */
1617 HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1619 /* Store current volatile hpssi->ErrorCode, misra rule */
1620 tmperror = hpssi->ErrorCode;
1622 /* Call the corresponding callback to inform upper layer of End of Transfer */
1623 if ((hpssi->State == HAL_PSSI_STATE_ABORT) || (tmperror != HAL_PSSI_ERROR_NONE))
1625 /* Call the corresponding callback to inform upper layer of End of Transfer */
1626 PSSI_Error(hpssi, hpssi->ErrorCode);
1628 /* hpssi->State == HAL_PSSI_STATE_BUSY_TX */
1629 else
1631 hpssi->State = HAL_PSSI_STATE_READY;
1633 /* Process Unlocked */
1634 __HAL_UNLOCK(hpssi);
1636 /* Call the corresponding callback to inform upper layer of End of Transfer */
1638 hpssi->TxCpltCallback(hpssi);
1646 * @brief DMA PSSI master receive process complete callback.
1647 * @param hdma DMA handle
1648 * @retval None
1650 void PSSI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1652 PSSI_HandleTypeDef *hpssi = (PSSI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
1654 uint32_t tmperror;
1657 /* Disable Interrupts */
1658 HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1660 /* Store current volatile hpssi->ErrorCode, misra rule */
1661 tmperror = hpssi->ErrorCode;
1663 /* Call the corresponding callback to inform upper layer of End of Transfer */
1664 if ((hpssi->State == HAL_PSSI_STATE_ABORT) || (tmperror != HAL_PSSI_ERROR_NONE))
1666 /* Call the corresponding callback to inform upper layer of End of Transfer */
1667 PSSI_Error(hpssi, hpssi->ErrorCode);
1669 /* hpssi->State == HAL_PSSI_STATE_BUSY_RX */
1670 else
1672 hpssi->State = HAL_PSSI_STATE_READY;
1674 /* Process Unlocked */
1675 __HAL_UNLOCK(hpssi);
1677 /* Call the corresponding callback to inform upper layer of End of Transfer */
1678 hpssi->RxCpltCallback(hpssi);
1686 * @brief DMA PSSI communication abort callback
1687 * (To be called at end of DMA Abort procedure).
1688 * @param hdma DMA handle.
1689 * @retval None
1691 void PSSI_DMAAbort(DMA_HandleTypeDef *hdma)
1693 PSSI_HandleTypeDef *hpssi = (PSSI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
1695 /* Reset AbortCpltCallback */
1696 hpssi->hdmatx->XferAbortCallback = NULL;
1697 hpssi->hdmarx->XferAbortCallback = NULL;
1699 /* Check if come from abort from user */
1700 if (hpssi->State == HAL_PSSI_STATE_ABORT)
1702 hpssi->State = HAL_PSSI_STATE_READY;
1704 /* Call the corresponding callback to inform upper layer of End of Transfer */
1706 hpssi->AbortCpltCallback(hpssi);
1709 else
1711 /* Call the corresponding callback to inform upper layer of End of Transfer */
1712 hpssi->ErrorCallback(hpssi);
1717 * @brief This function handles PSSI Communication Timeout.
1718 * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains
1719 * the configuration information for the specified PSSI.
1720 * @param Flag Specifies the PSSI flag to check.
1721 * @param Status The new Flag status (SET or RESET).
1722 * @param Timeout Timeout duration
1723 * @param Tickstart Tick start value
1724 * @retval HAL status
1726 static HAL_StatusTypeDef PSSI_WaitOnStatusUntilTimeout(PSSI_HandleTypeDef *hpssi, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart)
1728 while ((HAL_PSSI_GET_STATUS(hpssi, Flag) & Flag) == (uint32_t)Status)
1730 /* Check for the Timeout */
1731 if (Timeout != HAL_MAX_DELAY)
1733 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
1735 hpssi->ErrorCode |= HAL_PSSI_ERROR_TIMEOUT;
1736 hpssi->State = HAL_PSSI_STATE_READY;
1738 /* Process Unlocked */
1739 __HAL_UNLOCK(hpssi);
1741 return HAL_ERROR;
1745 return HAL_OK;
1747 void PSSI_DMAError(DMA_HandleTypeDef *hdma)
1749 PSSI_HandleTypeDef *hpssi = (PSSI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
1751 uint32_t tmperror;
1754 /* Disable the selected PSSI peripheral */
1755 HAL_PSSI_DISABLE(hpssi);
1757 /* Disable Interrupts */
1758 HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS);
1760 /* Store current volatile hpssi->ErrorCode, misra rule */
1761 tmperror = hpssi->ErrorCode;
1763 /* Call the corresponding callback to inform upper layer of End of Transfer */
1764 if ((hpssi->State == HAL_PSSI_STATE_ABORT) || (tmperror != HAL_PSSI_ERROR_NONE))
1766 /* Call the corresponding callback to inform upper layer of End of Transfer */
1767 PSSI_Error(hpssi, hpssi->ErrorCode);
1769 else
1771 hpssi->State = HAL_PSSI_STATE_READY;
1773 /* Process Unlocked */
1774 __HAL_UNLOCK(hpssi);
1776 /* Call the corresponding callback to inform upper layer of End of Transfer */
1777 hpssi->ErrorCallback(hpssi);
1786 * @}
1788 #endif /* PSSI */
1789 #endif /* HAL_PSSI_MODULE_ENABLED */
1791 * @}
1795 * @}
1798 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/