1 /**
2   ******************************************************************************
3   * @file    stm32h7xx_hal_swpmi.c
4   * @author  MCD Application Team
5   * @brief   SWPMI HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Single Wire Protocol Master Interface (SWPMI).
8   *           + Initialization and Configuration
9   *           + Data transfers functions
10   *           + DMA transfers management
11   *           + Interrupts and flags management
12   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2017 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 SWPMI HAL driver can be used as follows:
29 
30     (#) Declare a SWPMI_HandleTypeDef handle structure (eg. SWPMI_HandleTypeDef hswpmi).
31 
32     (#) Initialize the SWPMI low level resources by implementing the HAL_SWPMI_MspInit() API:
33         (##) Enable the SWPMIx interface clock with __HAL_RCC_SWPMIx_CLK_ENABLE().
34         (##) SWPMI IO configuration:
35             (+++) Enable the clock for the SWPMI GPIO.
36             (+++) Configure these SWPMI pins as alternate function pull-up.
37         (##) NVIC configuration if you need to use interrupt process (HAL_SWPMI_Transmit_IT()
38              and HAL_SWPMI_Receive_IT() APIs):
39             (+++) Configure the SWPMIx interrupt priority with HAL_NVIC_SetPriority().
40             (+++) Enable the NVIC SWPMI IRQ handle with HAL_NVIC_EnableIRQ().
41 
42         (##) DMA Configuration if you need to use DMA process (HAL_SWPMI_Transmit_DMA()
43              and HAL_SWPMI_Receive_DMA() APIs):
44             (+++) Declare a DMA handle structure for the Tx/Rx streams.
45             (+++) Enable the DMAx interface clock.
46             (+++) Configure the declared DMA handle structure with the required
47                   Tx/Rx parameters.
48             (+++) Configure the DMA Tx/Rx streams and requests.
49             (+++) Associate the initialized DMA handle to the SWPMI DMA Tx/Rx handle.
50             (+++) Configure the priority and enable the NVIC for the transfer complete
51                   interrupt on the DMA Tx/Rx streams.
52 
53     (#) Program the Bite Rate, Tx Buffering mode, Rx Buffering mode in the Init structure.
54 
55     (#) Enable the SWPMI peripheral by calling the HAL_SWPMI_Init() function.
56 
57   [..]
58     Three operation modes are available within this driver :
59 
60     *** Polling mode IO operation ***
61     =================================
62     [..]
63       (+) Send an amount of data in blocking mode using HAL_SWPMI_Transmit()
64       (+) Receive an amount of data in blocking mode using HAL_SWPMI_Receive()
65 
66     *** Interrupt mode IO operation ***
67     ===================================
68     [..]
69       (+) Send an amount of data in non-blocking mode using HAL_SWPMI_Transmit_IT()
70       (+) At transmission end of transfer HAL_SWPMI_TxCpltCallback() is executed and user can
71           add his own code by customization of function pointer HAL_SWPMI_TxCpltCallback()
72       (+) Receive an amount of data in non-blocking mode using HAL_SWPMI_Receive_IT()
73       (+) At reception end of transfer HAL_SWPMI_RxCpltCallback() is executed and user can
74           add his own code by customization of function pointer HAL_SWPMI_RxCpltCallback()
75       (+) In case of flag error, HAL_SWPMI_ErrorCallback() function is executed and user can
76           add his own code by customization of function pointer HAL_SWPMI_ErrorCallback()
77 
78     *** DMA mode IO operation ***
79     =============================
80     [..]
81       (+) Send an amount of data in non-blocking mode (DMA) using HAL_SWPMI_Transmit_DMA()
82       (+) At transmission end of transfer HAL_SWPMI_TxCpltCallback() is executed and user can
83           add his own code by customization of function pointer HAL_SWPMI_TxCpltCallback()
84       (+) Receive an amount of data in non-blocking mode (DMA) using HAL_SWPMI_Receive_DMA()
85       (+) At reception end of transfer HAL_SWPMI_RxCpltCallback() is executed and user can
86           add his own code by customization of function pointer HAL_SWPMI_RxCpltCallback()
87       (+) In case of flag error, HAL_SWPMI_ErrorCallback() function is executed and user can
88           add his own code by customization of function pointer HAL_SWPMI_ErrorCallback()
89       (+) Stop the DMA Transfer using HAL_SWPMI_DMAStop()
90 
91     *** SWPMI HAL driver additional function list ***
92     ===============================================
93     [..]
94       Below the list the others API available SWPMI HAL driver :
95 
96       (+) HAL_SWPMI_EnableLoopback(): Enable the loopback mode for test purpose only
97       (+) HAL_SWPMI_DisableLoopback(): Disable the loopback mode
98 
99     *** SWPMI HAL driver macros list ***
100     ==================================
101     [..]
102       Below the list of most used macros in SWPMI HAL driver :
103 
104       (+) __HAL_SWPMI_ENABLE(): Enable the SWPMI peripheral
105       (+) __HAL_SWPMI_DISABLE(): Disable the SWPMI peripheral
106       (+) __HAL_SWPMI_TRANSCEIVER_ENABLE(): Enable the SWPMI peripheral transceiver
107       (+) __HAL_SWPMI_TRANSCEIVER_DISABLE(): Disable the SWPMI peripheral transceiver
108       (+) __HAL_SWPMI_ENABLE_IT(): Enable the specified SWPMI interrupts
109       (+) __HAL_SWPMI_DISABLE_IT(): Disable the specified SWPMI interrupts
110       (+) __HAL_SWPMI_GET_IT_SOURCE(): Check if the specified SWPMI interrupt source is
111           enabled or disabled
112       (+) __HAL_SWPMI_GET_FLAG(): Check whether the specified SWPMI flag is set or not
113 
114     *** Callback registration ***
115     =============================
116     [..]
117       The compilation define USE_HAL_SWPMI_REGISTER_CALLBACKS when set to 1
118       allows the user to configure dynamically the driver callbacks.
119     [..]
120       Use function HAL_SWPMI_RegisterCallback() to register a user callback. It allows
121       to register the following callbacks:
122       (+) RxCpltCallback     : SWPMI receive complete.
123       (+) RxHalfCpltCallback : SWPMI receive half complete.
124       (+) TxCpltCallback     : SWPMI transmit complete.
125       (+) TxHalfCpltCallback : SWPMI transmit half complete.
126       (+) ErrorCallback      : SWPMI error.
127       (+) MspInitCallback    : SWPMI MspInit.
128       (+) MspDeInitCallback  : SWPMI MspDeInit.
129     [..]
130     This function takes as parameters the HAL peripheral handle, the callback ID
131     and a pointer to the user callback function.
132     [..]
133     Use function HAL_SWPMI_UnRegisterCallback() to reset a callback to the default
134     weak (overridden) function.
135     HAL_SWPMI_UnRegisterCallback() takes as parameters the HAL peripheral handle,
136     and the callback ID.
137     This function allows to reset following callbacks:
138       (+) RxCpltCallback     : SWPMI receive complete.
139       (+) RxHalfCpltCallback : SWPMI receive half complete.
140       (+) TxCpltCallback     : SWPMI transmit complete.
141       (+) TxHalfCpltCallback : SWPMI transmit half complete.
142       (+) ErrorCallback      : SWPMI error.
143       (+) MspInitCallback    : SWPMI MspInit.
144       (+) MspDeInitCallback  : SWPMI MspDeInit.
145     [..]
146     By default, after the HAL_SWPMI_Init and if the state is HAL_SWPMI_STATE_RESET
147     all callbacks are reset to the corresponding legacy weak functions:
148     examples HAL_SWPMI_RxCpltCallback(), HAL_SWPMI_ErrorCallback().
149     Exception done for MspInit and MspDeInit callbacks that are respectively
150     reset to the legacy weak functions in the HAL_SWPMI_Init
151     and HAL_SWPMI_DeInit only when these callbacks are null (not registered beforehand).
152     If not, MspInit or MspDeInit are not null, the HAL_SWPMI_Init and HAL_SWPMI_DeInit
153     keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
154     [..]
155     Callbacks can be registered/unregistered in READY state only.
156     Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
157     in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
158     during the Init/DeInit.
159     In that case first register the MspInit/MspDeInit user callbacks
160     using HAL_SWPMI_RegisterCallback before calling HAL_SWPMI_DeInit
161     or HAL_SWPMI_Init function.
162     [..]
163     When the compilation define USE_HAL_SWPMI_REGISTER_CALLBACKS is set to 0 or
164     not defined, the callback registering feature is not available
165     and weak callbacks are used.
166 
167   @endverbatim
168   */
169 
170 /* Includes ------------------------------------------------------------------*/
171 #include "stm32h7xx_hal.h"
172 
173 /** @addtogroup STM32H7xx_HAL_Driver
174   * @{
175   */
176 
177 
178 /** @defgroup SWPMI SWPMI
179   * @brief HAL SWPMI module driver
180   * @{
181   */
182 #ifdef HAL_SWPMI_MODULE_ENABLED
183 
184 /* Private typedef -----------------------------------------------------------*/
185 /* Private define ------------------------------------------------------------*/
186 /* Private constants ---------------------------------------------------------*/
187 /** @addtogroup SWPMI_Private_Constants SWPMI Private Constants
188   * @{
189   */
190 #define SWPMI_TIMEOUT_VALUE                   22000U   /* End of transmission timeout */
191 #define SWPMI_TRANSCEIVER_RDY_TIMEOUT_VALUE    2000U   /* Transceiver ready timeout */
192 
193 /**
194   * @}
195   */
196 
197 /* Private macros ------------------------------------------------------------*/
198 /* Private variables ---------------------------------------------------------*/
199 /* Private function prototypes -----------------------------------------------*/
200 static void SWPMI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
201 static void SWPMI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
202 static void SWPMI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
203 static void SWPMI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
204 static void SWPMI_DMAError(DMA_HandleTypeDef *hdma);
205 static void SWPMI_DMAAbortOnError(DMA_HandleTypeDef *hdma);
206 static void SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi);
207 static void SWPMI_EndTransmit_IT(SWPMI_HandleTypeDef *hswpmi);
208 static void SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi);
209 static void SWPMI_EndReceive_IT(SWPMI_HandleTypeDef *hswpmi);
210 static void SWPMI_EndTransmitReceive_IT(SWPMI_HandleTypeDef *hswpmi);
211 static HAL_StatusTypeDef SWPMI_WaitOnFlagSetUntilTimeout(SWPMI_HandleTypeDef *hswpmi, uint32_t Flag, uint32_t Tickstart,
212                                                          uint32_t Timeout);
213 
214 /* Exported functions --------------------------------------------------------*/
215 
216 /** @defgroup SWPMI_Exported_Functions SWPMI Exported Functions
217   * @{
218   */
219 
220 /** @defgroup SWPMI_Exported_Group1 Initialization/de-initialization methods
221   *  @brief    Initialization and Configuration functions
222   *
223 @verbatim
224  ===============================================================================
225             ##### Initialization and Configuration functions #####
226  ===============================================================================
227     [..]  This section provides functions allowing to:
228       (+) Initialize and configure the SWPMI peripheral.
229       (+) De-initialize the SWPMI peripheral.
230 
231 @endverbatim
232   * @{
233   */
234 
235 /**
236   * @brief Initialize the SWPMI peripheral according to the specified parameters in the SWPMI_InitTypeDef.
237   * @param hswpmi SWPMI handle
238   * @retval HAL status
239   */
HAL_SWPMI_Init(SWPMI_HandleTypeDef * hswpmi)240 HAL_StatusTypeDef HAL_SWPMI_Init(SWPMI_HandleTypeDef *hswpmi)
241 {
242   HAL_StatusTypeDef status = HAL_OK;
243   uint32_t tickstart = HAL_GetTick();
244 
245   /* Check the SWPMI handle allocation */
246   if (hswpmi == NULL)
247   {
248     status = HAL_ERROR;
249   }
250   else
251   {
252     /* Check the parameters */
253     assert_param(IS_SWPMI_VOLTAGE_CLASS(hswpmi->Init.VoltageClass));
254     assert_param(IS_SWPMI_BITRATE_VALUE(hswpmi->Init.BitRate));
255     assert_param(IS_SWPMI_TX_BUFFERING_MODE(hswpmi->Init.TxBufferingMode));
256     assert_param(IS_SWPMI_RX_BUFFERING_MODE(hswpmi->Init.RxBufferingMode));
257 
258     if (hswpmi->State == HAL_SWPMI_STATE_RESET)
259     {
260       /* Allocate lock resource and initialize it */
261       hswpmi->Lock = HAL_UNLOCKED;
262 
263 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
264       /* Reset callback pointers to the weak predefined callbacks */
265       hswpmi->RxCpltCallback     = HAL_SWPMI_RxCpltCallback;
266       hswpmi->RxHalfCpltCallback = HAL_SWPMI_RxHalfCpltCallback;
267       hswpmi->TxCpltCallback     = HAL_SWPMI_TxCpltCallback;
268       hswpmi->TxHalfCpltCallback = HAL_SWPMI_TxHalfCpltCallback;
269       hswpmi->ErrorCallback      = HAL_SWPMI_ErrorCallback;
270 
271       /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
272       if (hswpmi->MspInitCallback == NULL)
273       {
274         hswpmi->MspInitCallback = HAL_SWPMI_MspInit;
275       }
276       hswpmi->MspInitCallback(hswpmi);
277 #else
278       /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
279       HAL_SWPMI_MspInit(hswpmi);
280 #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */
281     }
282 
283     hswpmi->State = HAL_SWPMI_STATE_BUSY;
284 
285     /* Disable SWPMI interface */
286     CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
287 
288     /* Clear all SWPMI interface flags */
289     WRITE_REG(hswpmi->Instance->ICR, 0x099F);
290 
291     /* Apply Voltage class selection */
292     MODIFY_REG(hswpmi->Instance->OR, SWPMI_OR_CLASS, hswpmi->Init.VoltageClass);
293 
294 
295     /* Configure the BRR register (Bitrate) */
296     WRITE_REG(hswpmi->Instance->BRR, hswpmi->Init.BitRate);
297 
298     /* Apply SWPMI CR configuration */
299     MODIFY_REG(hswpmi->Instance->CR, \
300                SWPMI_CR_RXDMA | SWPMI_CR_TXDMA  | SWPMI_CR_RXMODE | SWPMI_CR_TXMODE, \
301                hswpmi->Init.TxBufferingMode | hswpmi->Init.RxBufferingMode);
302 
303     /* Enable the SWPMI transceiver */
304     SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPEN);
305     /* Wait on RDYF flag to activate SWPMI */
306     if (SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_RDYF, tickstart,
307                                         SWPMI_TRANSCEIVER_RDY_TIMEOUT_VALUE) != HAL_OK)
308     {
309       status = HAL_TIMEOUT;
310     }
311 
312     if (status == HAL_OK)
313     {
314       hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
315       hswpmi->State = HAL_SWPMI_STATE_READY;
316 
317       /* Enable SWPMI peripheral */
318       SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
319     }
320     else
321     {
322       hswpmi->ErrorCode = HAL_SWPMI_ERROR_TRANSCEIVER_NOT_READY;
323       hswpmi->State = HAL_SWPMI_STATE_ERROR;
324     }
325   }
326 
327   return status;
328 }
329 
330 /**
331   * @brief De-initialize the SWPMI peripheral.
332   * @param hswpmi SWPMI handle
333   * @retval HAL status
334   */
HAL_SWPMI_DeInit(SWPMI_HandleTypeDef * hswpmi)335 HAL_StatusTypeDef HAL_SWPMI_DeInit(SWPMI_HandleTypeDef *hswpmi)
336 {
337   HAL_StatusTypeDef status = HAL_OK;
338 
339   /* Check the SWPMI handle allocation */
340   if (hswpmi == NULL)
341   {
342     status = HAL_ERROR;
343   }
344   else
345   {
346     /* Check the parameters */
347     assert_param(IS_SWPMI_INSTANCE(hswpmi->Instance));
348 
349     hswpmi->State = HAL_SWPMI_STATE_BUSY;
350 
351     /* Disable SWPMI interface */
352     CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
353 
354     /* Disable Loopback mode */
355     CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK);
356 
357     /* Disable SWPMI transceiver */
358     CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPEN);
359 
360 
361     /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
362 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
363     if (hswpmi->MspDeInitCallback == NULL)
364     {
365       hswpmi->MspDeInitCallback = HAL_SWPMI_MspDeInit;
366     }
367     hswpmi->MspDeInitCallback(hswpmi);
368 #else
369     HAL_SWPMI_MspDeInit(hswpmi);
370 #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */
371 
372     hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
373     hswpmi->State = HAL_SWPMI_STATE_RESET;
374 
375     /* Release Lock */
376     __HAL_UNLOCK(hswpmi);
377   }
378 
379   return status;
380 }
381 
382 /**
383   * @brief Initialize the SWPMI MSP.
384   * @param hswpmi SWPMI handle
385   * @retval None
386   */
HAL_SWPMI_MspInit(SWPMI_HandleTypeDef * hswpmi)387 __weak void HAL_SWPMI_MspInit(SWPMI_HandleTypeDef *hswpmi)
388 {
389   /* Prevent unused argument(s) compilation warning */
390   UNUSED(hswpmi);
391 
392   /* NOTE : This function should not be modified, when the callback is needed,
393             the HAL_SWPMI_MspInit can be implemented in the user file
394    */
395 }
396 
397 /**
398   * @brief DeInitialize the SWPMI MSP.
399   * @param hswpmi SWPMI handle
400   * @retval None
401   */
HAL_SWPMI_MspDeInit(SWPMI_HandleTypeDef * hswpmi)402 __weak void HAL_SWPMI_MspDeInit(SWPMI_HandleTypeDef *hswpmi)
403 {
404   /* Prevent unused argument(s) compilation warning */
405   UNUSED(hswpmi);
406 
407   /* NOTE : This function should not be modified, when the callback is needed,
408             the HAL_SWPMI_MspDeInit can be implemented in the user file
409    */
410 }
411 
412 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
413 /**
414   * @brief  Register a user SWPMI callback
415   *         To be used to override the weak predefined callback.
416   * @param  hswpmi SWPMI handle.
417   * @param  CallbackID ID of the callback to be registered.
418   *         This parameter can be one of the following values:
419   *           @arg @ref HAL_SWPMI_RX_COMPLETE_CB_ID receive complete callback ID.
420   *           @arg @ref HAL_SWPMI_RX_HALFCOMPLETE_CB_ID receive half complete callback ID.
421   *           @arg @ref HAL_SWPMI_TX_COMPLETE_CB_ID transmit complete callback ID.
422   *           @arg @ref HAL_SWPMI_TX_HALFCOMPLETE_CB_ID transmit half complete callback ID.
423   *           @arg @ref HAL_SWPMI_ERROR_CB_ID error callback ID.
424   *           @arg @ref HAL_SWPMI_MSPINIT_CB_ID MSP init callback ID.
425   *           @arg @ref HAL_SWPMI_MSPDEINIT_CB_ID MSP de-init callback ID.
426   * @param  pCallback pointer to the callback function.
427   * @retval HAL status.
428   */
HAL_SWPMI_RegisterCallback(SWPMI_HandleTypeDef * hswpmi,HAL_SWPMI_CallbackIDTypeDef CallbackID,pSWPMI_CallbackTypeDef pCallback)429 HAL_StatusTypeDef HAL_SWPMI_RegisterCallback(SWPMI_HandleTypeDef        *hswpmi,
430                                              HAL_SWPMI_CallbackIDTypeDef CallbackID,
431                                              pSWPMI_CallbackTypeDef      pCallback)
432 {
433   HAL_StatusTypeDef status = HAL_OK;
434 
435   if (pCallback == NULL)
436   {
437     /* update the error code */
438     hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
439     /* update return status */
440     status = HAL_ERROR;
441   }
442   else
443   {
444     if (hswpmi->State == HAL_SWPMI_STATE_READY)
445     {
446       switch (CallbackID)
447       {
448         case HAL_SWPMI_RX_COMPLETE_CB_ID :
449           hswpmi->RxCpltCallback = pCallback;
450           break;
451         case HAL_SWPMI_RX_HALFCOMPLETE_CB_ID :
452           hswpmi->RxHalfCpltCallback = pCallback;
453           break;
454         case HAL_SWPMI_TX_COMPLETE_CB_ID :
455           hswpmi->TxCpltCallback = pCallback;
456           break;
457         case HAL_SWPMI_TX_HALFCOMPLETE_CB_ID :
458           hswpmi->TxHalfCpltCallback = pCallback;
459           break;
460         case HAL_SWPMI_ERROR_CB_ID :
461           hswpmi->ErrorCallback = pCallback;
462           break;
463         case HAL_SWPMI_MSPINIT_CB_ID :
464           hswpmi->MspInitCallback = pCallback;
465           break;
466         case HAL_SWPMI_MSPDEINIT_CB_ID :
467           hswpmi->MspDeInitCallback = pCallback;
468           break;
469         default :
470           /* update the error code */
471           hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
472           /* update return status */
473           status = HAL_ERROR;
474           break;
475       }
476     }
477     else if (hswpmi->State == HAL_SWPMI_STATE_RESET)
478     {
479       switch (CallbackID)
480       {
481         case HAL_SWPMI_MSPINIT_CB_ID :
482           hswpmi->MspInitCallback = pCallback;
483           break;
484         case HAL_SWPMI_MSPDEINIT_CB_ID :
485           hswpmi->MspDeInitCallback = pCallback;
486           break;
487         default :
488           /* update the error code */
489           hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
490           /* update return status */
491           status = HAL_ERROR;
492           break;
493       }
494     }
495     else
496     {
497       /* update the error code */
498       hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
499       /* update return status */
500       status = HAL_ERROR;
501     }
502   }
503   return status;
504 }
505 
506 /**
507   * @brief  Unregister a user SWPMI callback.
508   *         Callback is redirected to the weak predefined callback.
509   * @param  hswpmi SWPMI handle.
510   * @param  CallbackID ID of the callback to be unregistered.
511   *         This parameter can be one of the following values:
512   *           @arg @ref HAL_SWPMI_RX_COMPLETE_CB_ID receive complete callback ID.
513   *           @arg @ref HAL_SWPMI_RX_HALFCOMPLETE_CB_ID receive half complete callback ID.
514   *           @arg @ref HAL_SWPMI_TX_COMPLETE_CB_ID transmit complete callback ID.
515   *           @arg @ref HAL_SWPMI_TX_HALFCOMPLETE_CB_ID transmit half complete callback ID.
516   *           @arg @ref HAL_SWPMI_ERROR_CB_ID error callback ID.
517   *           @arg @ref HAL_SWPMI_MSPINIT_CB_ID MSP init callback ID.
518   *           @arg @ref HAL_SWPMI_MSPDEINIT_CB_ID MSP de-init callback ID.
519   * @retval HAL status.
520   */
HAL_SWPMI_UnRegisterCallback(SWPMI_HandleTypeDef * hswpmi,HAL_SWPMI_CallbackIDTypeDef CallbackID)521 HAL_StatusTypeDef HAL_SWPMI_UnRegisterCallback(SWPMI_HandleTypeDef        *hswpmi,
522                                                HAL_SWPMI_CallbackIDTypeDef CallbackID)
523 {
524   HAL_StatusTypeDef status = HAL_OK;
525 
526   if (hswpmi->State == HAL_SWPMI_STATE_READY)
527   {
528     switch (CallbackID)
529     {
530       case HAL_SWPMI_RX_COMPLETE_CB_ID :
531         hswpmi->RxCpltCallback = HAL_SWPMI_RxCpltCallback;
532         break;
533       case HAL_SWPMI_RX_HALFCOMPLETE_CB_ID :
534         hswpmi->RxHalfCpltCallback = HAL_SWPMI_RxHalfCpltCallback;
535         break;
536       case HAL_SWPMI_TX_COMPLETE_CB_ID :
537         hswpmi->TxCpltCallback = HAL_SWPMI_TxCpltCallback;
538         break;
539       case HAL_SWPMI_TX_HALFCOMPLETE_CB_ID :
540         hswpmi->TxHalfCpltCallback = HAL_SWPMI_TxHalfCpltCallback;
541         break;
542       case HAL_SWPMI_ERROR_CB_ID :
543         hswpmi->ErrorCallback = HAL_SWPMI_ErrorCallback;
544         break;
545       case HAL_SWPMI_MSPINIT_CB_ID :
546         hswpmi->MspInitCallback = HAL_SWPMI_MspInit;
547         break;
548       case HAL_SWPMI_MSPDEINIT_CB_ID :
549         hswpmi->MspDeInitCallback = HAL_SWPMI_MspDeInit;
550         break;
551       default :
552         /* update the error code */
553         hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
554         /* update return status */
555         status = HAL_ERROR;
556         break;
557     }
558   }
559   else if (hswpmi->State == HAL_SWPMI_STATE_RESET)
560   {
561     switch (CallbackID)
562     {
563       case HAL_SWPMI_MSPINIT_CB_ID :
564         hswpmi->MspInitCallback = HAL_SWPMI_MspInit;
565         break;
566       case HAL_SWPMI_MSPDEINIT_CB_ID :
567         hswpmi->MspDeInitCallback = HAL_SWPMI_MspDeInit;
568         break;
569       default :
570         /* update the error code */
571         hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
572         /* update return status */
573         status = HAL_ERROR;
574         break;
575     }
576   }
577   else
578   {
579     /* update the error code */
580     hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
581     /* update return status */
582     status = HAL_ERROR;
583   }
584   return status;
585 }
586 #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */
587 
588 /**
589   * @}
590   */
591 
592 /** @defgroup SWPMI_Exported_Group2 IO operation methods
593   *  @brief SWPMI Transmit/Receive functions
594   *
595 @verbatim
596  ===============================================================================
597                       ##### IO operation methods #####
598  ===============================================================================
599  [..]
600     This subsection provides a set of functions allowing to manage the SWPMI
601      data transfers.
602 
603     (#) There are two modes of transfer:
604        (++) Blocking mode: The communication is performed in polling mode.
605             The HAL status of all data processing is returned by the same function
606             after finishing transfer.
607        (++) Non-Blocking mode: The communication is performed using Interrupts
608            or DMA. The end of the data processing will be indicated through the
609            dedicated SWPMI Interrupt handler (HAL_SWPMI_IRQHandler()) when using Interrupt mode or
610            the selected DMA stream interrupt handler when using DMA mode.
611            The HAL_SWPMI_TxCpltCallback(), HAL_SWPMI_RxCpltCallback() user callbacks
612            will be executed respectively at the end of the transmit or receive process.
613            The HAL_SWPMI_ErrorCallback() user callback will be executed when a communication error is detected.
614 
615     (#) Blocking mode API's are:
616         (++) HAL_SWPMI_Transmit()
617         (++) HAL_SWPMI_Receive()
618 
619     (#) Non-Blocking mode API's with Interrupt are:
620         (++) HAL_SWPMI_Transmit_IT()
621         (++) HAL_SWPMI_Receive_IT()
622         (++) HAL_SWPMI_IRQHandler()
623 
624     (#) Non-Blocking mode API's with DMA are:
625         (++) HAL_SWPMI_Transmit_DMA()
626         (++) HAL_SWPMI_Receive_DMA()
627         (++) HAL_SWPMI_DMAPause()
628         (++) HAL_SWPMI_DMAResume()
629         (++) HAL_SWPMI_DMAStop()
630 
631     (#) A set of Transfer Complete Callbacks are provided in Non-Blocking mode:
632         (++) HAL_SWPMI_TxHalfCpltCallback()
633         (++) HAL_SWPMI_TxCpltCallback()
634         (++) HAL_SWPMI_RxHalfCpltCallback()
635         (++) HAL_SWPMI_RxCpltCallback()
636         (++) HAL_SWPMI_ErrorCallback()
637 
638     (#) The capability to launch the above IO operations in loopback mode for
639         user application verification:
640         (++) HAL_SWPMI_EnableLoopback()
641         (++) HAL_SWPMI_DisableLoopback()
642 
643 @endverbatim
644   * @{
645   */
646 
647 /**
648   * @brief  Transmit an amount of data in blocking mode.
649   * @param  hswpmi pointer to a SWPMI_HandleTypeDef structure that contains
650   *                the configuration information for SWPMI module.
651   * @param  pData Pointer to data buffer
652   * @param  Size Amount of data to be sent
653   * @param  Timeout Timeout duration
654   * @retval HAL status
655   */
HAL_SWPMI_Transmit(SWPMI_HandleTypeDef * hswpmi,const uint32_t * pData,uint16_t Size,uint32_t Timeout)656 HAL_StatusTypeDef HAL_SWPMI_Transmit(SWPMI_HandleTypeDef *hswpmi, const uint32_t *pData, uint16_t Size,
657                                      uint32_t Timeout)
658 {
659   uint32_t tickstart = HAL_GetTick();
660   HAL_StatusTypeDef status = HAL_OK;
661   HAL_SWPMI_StateTypeDef tmp_state;
662   const uint32_t *ptmp_data;
663   uint32_t tmp_size;
664 
665   if ((pData == NULL) || (Size == 0U))
666   {
667     status = HAL_ERROR;
668   }
669   else
670   {
671     /* Process Locked */
672     __HAL_LOCK(hswpmi);
673 
674     tmp_state = hswpmi->State;
675     if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_RX))
676     {
677       /* Check if a non-blocking receive process is ongoing or not */
678       if (tmp_state == HAL_SWPMI_STATE_READY)
679       {
680         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
681 
682         /* Disable any transmitter interrupts */
683         __HAL_SWPMI_DISABLE_IT(hswpmi, SWPMI_IT_TCIE | SWPMI_IT_TIE | SWPMI_IT_TXUNRIE | SWPMI_IT_TXBEIE);
684 
685         /* Disable any transmitter flags */
686         __HAL_SWPMI_CLEAR_FLAG(hswpmi, SWPMI_FLAG_TXBEF | SWPMI_FLAG_TXUNRF | SWPMI_FLAG_TCF);
687 
688         /* Enable SWPMI peripheral if not */
689         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
690       }
691       else
692       {
693         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
694       }
695 
696       ptmp_data = pData;
697       tmp_size = Size;
698       do
699       {
700         /* Wait the TXE to write data */
701         if (HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_TXE))
702         {
703           hswpmi->Instance->TDR = *ptmp_data;
704           ptmp_data++;
705           tmp_size--;
706         }
707         else
708         {
709           /* Check for the Timeout */
710           if (Timeout != HAL_MAX_DELAY)
711           {
712             if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
713             {
714               status = HAL_TIMEOUT;
715               break;
716             }
717           }
718         }
719       } while (tmp_size != 0U);
720 
721       /* Wait on TXBEF flag to be able to start a second transfer */
722       if (SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_TXBEF, tickstart, Timeout) != HAL_OK)
723       {
724         /* Timeout occurred */
725         hswpmi->ErrorCode |= HAL_SWPMI_ERROR_TXBEF_TIMEOUT;
726 
727         status = HAL_TIMEOUT;
728       }
729 
730       if (status == HAL_OK)
731       {
732         /* Check if a non-blocking receive Process is ongoing or not */
733         if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
734         {
735           hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
736         }
737         else
738         {
739           hswpmi->State = HAL_SWPMI_STATE_READY;
740         }
741       }
742     }
743     else
744     {
745       status = HAL_BUSY;
746     }
747   }
748 
749   if ((status != HAL_OK) && (status != HAL_BUSY))
750   {
751     hswpmi->State = HAL_SWPMI_STATE_READY;
752   }
753   /* Process Unlocked */
754   __HAL_UNLOCK(hswpmi);
755 
756   return status;
757 }
758 
759 /**
760   * @brief  Receive an amount of data in blocking mode.
761   * @param  hswpmi pointer to a SWPMI_HandleTypeDef structure that contains
762   *                the configuration information for SWPMI module.
763   * @param  pData Pointer to data buffer
764   * @param  Size Amount of data to be received
765   * @param  Timeout Timeout duration
766   * @retval HAL status
767   */
HAL_SWPMI_Receive(SWPMI_HandleTypeDef * hswpmi,uint32_t * pData,uint16_t Size,uint32_t Timeout)768 HAL_StatusTypeDef HAL_SWPMI_Receive(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size, uint32_t Timeout)
769 {
770   uint32_t tickstart = HAL_GetTick();
771   HAL_StatusTypeDef status = HAL_OK;
772   HAL_SWPMI_StateTypeDef tmp_state;
773   uint32_t *ptmp_data;
774   uint32_t tmp_size;
775 
776   if ((pData == NULL) || (Size == 0U))
777   {
778     status = HAL_ERROR;
779   }
780   else
781   {
782     /* Process Locked */
783     __HAL_LOCK(hswpmi);
784 
785     tmp_state = hswpmi->State;
786     if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX))
787     {
788       /* Check if a non-blocking transmit process is ongoing or not */
789       if (tmp_state == HAL_SWPMI_STATE_READY)
790       {
791         hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
792 
793         /* Disable any receiver interrupts */
794         CLEAR_BIT(hswpmi->Instance->IER,
795                   SWPMI_IT_SRIE | SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);
796 
797         /* Enable SWPMI peripheral if not */
798         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
799       }
800       else
801       {
802         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
803       }
804 
805       ptmp_data = pData;
806       tmp_size = Size;
807       do
808       {
809         /* Wait the RXNE to read data */
810         if (HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXNE))
811         {
812           *ptmp_data = hswpmi->Instance->RDR;
813           ptmp_data++;
814           tmp_size--;
815         }
816         else
817         {
818           /* Check for the Timeout */
819           if (Timeout != HAL_MAX_DELAY)
820           {
821             if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
822             {
823               status = HAL_TIMEOUT;
824               break;
825             }
826           }
827         }
828       } while (tmp_size != 0U);
829 
830       if (status == HAL_OK)
831       {
832         if (HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXBFF))
833         {
834           /* Clear RXBFF at end of reception */
835           WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBFF);
836         }
837 
838         /* Check if a non-blocking transmit Process is ongoing or not */
839         if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
840         {
841           hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
842         }
843         else
844         {
845           hswpmi->State = HAL_SWPMI_STATE_READY;
846         }
847       }
848     }
849     else
850     {
851       status = HAL_BUSY;
852     }
853   }
854 
855   if ((status != HAL_OK) && (status != HAL_BUSY))
856   {
857     hswpmi->State = HAL_SWPMI_STATE_READY;
858   }
859   /* Process Unlocked */
860   __HAL_UNLOCK(hswpmi);
861 
862   return status;
863 }
864 
865 /**
866   * @brief  Transmit an amount of data in non-blocking mode with interrupt.
867   * @param  hswpmi pointer to a SWPMI_HandleTypeDef structure that contains
868   *                the configuration information for SWPMI module.
869   * @param  pData Pointer to data buffer
870   * @param  Size Amount of data to be sent
871   * @retval HAL status
872   */
HAL_SWPMI_Transmit_IT(SWPMI_HandleTypeDef * hswpmi,const uint32_t * pData,uint16_t Size)873 HAL_StatusTypeDef HAL_SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi, const uint32_t *pData, uint16_t Size)
874 {
875   HAL_StatusTypeDef status = HAL_OK;
876   HAL_SWPMI_StateTypeDef tmp_state;
877 
878   if ((pData == NULL) || (Size == 0U))
879   {
880     status =  HAL_ERROR;
881   }
882   else
883   {
884     /* Process Locked */
885     __HAL_LOCK(hswpmi);
886 
887     tmp_state = hswpmi->State;
888     if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_RX))
889     {
890       /* Update handle */
891       hswpmi->pTxBuffPtr = pData;
892       hswpmi->TxXferSize = Size;
893       hswpmi->TxXferCount = Size;
894       hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
895 
896       /* Check if a receive process is ongoing or not */
897       if (tmp_state == HAL_SWPMI_STATE_READY)
898       {
899         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
900 
901         /* Enable SWPMI peripheral if not */
902         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
903       }
904       else
905       {
906         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
907       }
908 
909       /* Enable the SWPMI transmit underrun error */
910       __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TXUNRIE);
911 
912       /* Process Unlocked */
913       __HAL_UNLOCK(hswpmi);
914 
915       /* Enable the SWPMI interrupts:      */
916       /* - Transmit data register empty    */
917       /* - Transmit buffer empty           */
918       /* - Transmit/Reception completion   */
919       __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TIE | SWPMI_IT_TXBEIE | SWPMI_IT_TCIE);
920     }
921     else
922     {
923       status =  HAL_BUSY;
924 
925       /* Process Unlocked */
926       __HAL_UNLOCK(hswpmi);
927     }
928   }
929 
930   return status;
931 }
932 
933 /**
934   * @brief  Receive an amount of data in non-blocking mode with interrupt.
935   * @param  hswpmi SWPMI handle
936   * @param  pData Pointer to data buffer
937   * @param  Size Amount of data to be received
938   * @retval HAL status
939   */
HAL_SWPMI_Receive_IT(SWPMI_HandleTypeDef * hswpmi,uint32_t * pData,uint16_t Size)940 HAL_StatusTypeDef HAL_SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
941 {
942   HAL_StatusTypeDef status = HAL_OK;
943   HAL_SWPMI_StateTypeDef tmp_state;
944 
945   if ((pData == NULL) || (Size == 0U))
946   {
947     status =  HAL_ERROR;
948   }
949   else
950   {
951     /* Process Locked */
952     __HAL_LOCK(hswpmi);
953 
954     tmp_state = hswpmi->State;
955     if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX))
956     {
957       /* Update handle */
958       hswpmi->pRxBuffPtr = pData;
959       hswpmi->RxXferSize = Size;
960       hswpmi->RxXferCount = Size;
961       hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
962 
963       /* Check if a transmit process is ongoing or not */
964       if (tmp_state == HAL_SWPMI_STATE_READY)
965       {
966         hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
967 
968         /* Enable SWPMI peripheral if not */
969         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
970       }
971       else
972       {
973         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
974       }
975 
976       /* Process Unlocked */
977       __HAL_UNLOCK(hswpmi);
978 
979       /* Enable the SWPMI slave resume */
980       /* Enable the SWPMI Data Register not empty Interrupt, receive CRC Error, receive overrun and RxBuf Interrupt */
981       /*  Enable the SWPMI Transmit/Reception completion   */
982       __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);
983     }
984     else
985     {
986       status = HAL_BUSY;
987 
988       /* Process Unlocked */
989       __HAL_UNLOCK(hswpmi);
990     }
991   }
992 
993   return status;
994 }
995 
996 /**
997   * @brief  Transmit an amount of data in non-blocking mode with DMA interrupt.
998   * @param  hswpmi SWPMI handle
999   * @param  pData Pointer to data buffer
1000   * @param  Size Amount of data to be sent
1001   * @retval HAL status
1002   */
HAL_SWPMI_Transmit_DMA(SWPMI_HandleTypeDef * hswpmi,const uint32_t * pData,uint16_t Size)1003 HAL_StatusTypeDef HAL_SWPMI_Transmit_DMA(SWPMI_HandleTypeDef *hswpmi, const uint32_t *pData, uint16_t Size)
1004 {
1005   HAL_StatusTypeDef status = HAL_OK;
1006   HAL_SWPMI_StateTypeDef tmp_state;
1007 
1008   if ((pData == NULL) || (Size == 0U))
1009   {
1010     status =  HAL_ERROR;
1011   }
1012   else
1013   {
1014     /* Process Locked */
1015     __HAL_LOCK(hswpmi);
1016 
1017     tmp_state = hswpmi->State;
1018     if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_RX))
1019     {
1020       /* Update handle */
1021       hswpmi->pTxBuffPtr = pData;
1022       hswpmi->TxXferSize = Size;
1023       hswpmi->TxXferCount = Size;
1024       hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
1025 
1026       /* Check if a receive process is ongoing or not */
1027       if (tmp_state == HAL_SWPMI_STATE_READY)
1028       {
1029         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
1030 
1031         /* Enable SWPMI peripheral if not */
1032         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1033       }
1034       else
1035       {
1036         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
1037       }
1038 
1039       /* Set the SWPMI DMA transfer complete callback */
1040       hswpmi->hdmatx->XferCpltCallback = SWPMI_DMATransmitCplt;
1041 
1042       /* Set the SWPMI DMA Half transfer complete callback */
1043       hswpmi->hdmatx->XferHalfCpltCallback = SWPMI_DMATxHalfCplt;
1044 
1045       /* Set the DMA error callback */
1046       hswpmi->hdmatx->XferErrorCallback = SWPMI_DMAError;
1047 
1048       /* Enable the SWPMI transmit DMA stream */
1049       if (HAL_DMA_Start_IT(hswpmi->hdmatx, (uint32_t)hswpmi->pTxBuffPtr,
1050                            (uint32_t)&hswpmi->Instance->TDR, Size) != HAL_OK)
1051       {
1052         hswpmi->State = tmp_state;    /* Back to previous state */
1053         hswpmi->ErrorCode = HAL_SWPMI_ERROR_DMA;
1054         status = HAL_ERROR;
1055 
1056         /* Process Unlocked */
1057         __HAL_UNLOCK(hswpmi);
1058       }
1059       else
1060       {
1061         /* Process Unlocked */
1062         __HAL_UNLOCK(hswpmi);
1063 
1064         /* Enable the SWPMI transmit underrun error */
1065         __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TXUNRIE);
1066 
1067         /* Enable the DMA transfer for transmit request by setting the TXDMA bit
1068            in the SWPMI CR register */
1069         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA);
1070       }
1071     }
1072     else
1073     {
1074       status = HAL_BUSY;
1075 
1076       /* Process Unlocked */
1077       __HAL_UNLOCK(hswpmi);
1078     }
1079   }
1080 
1081   return status;
1082 }
1083 
1084 /**
1085   * @brief  Receive an amount of data in non-blocking mode with DMA interrupt.
1086   * @param  hswpmi SWPMI handle
1087   * @param  pData Pointer to data buffer
1088   * @param  Size Amount of data to be received
1089   * @retval HAL status
1090   */
HAL_SWPMI_Receive_DMA(SWPMI_HandleTypeDef * hswpmi,uint32_t * pData,uint16_t Size)1091 HAL_StatusTypeDef HAL_SWPMI_Receive_DMA(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
1092 {
1093   HAL_StatusTypeDef status = HAL_OK;
1094   HAL_SWPMI_StateTypeDef tmp_state;
1095 
1096   if ((pData == NULL) || (Size == 0U))
1097   {
1098     status =  HAL_ERROR;
1099   }
1100   else
1101   {
1102     /* Process Locked */
1103     __HAL_LOCK(hswpmi);
1104 
1105     tmp_state = hswpmi->State;
1106     if ((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX))
1107     {
1108       /* Update handle */
1109       hswpmi->pRxBuffPtr = pData;
1110       hswpmi->RxXferSize = Size;
1111       hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
1112 
1113       /* Check if a transmit process is ongoing or not */
1114       if (tmp_state == HAL_SWPMI_STATE_READY)
1115       {
1116         hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
1117 
1118         /* Enable SWPMI peripheral if not */
1119         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1120       }
1121       else
1122       {
1123         hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
1124       }
1125 
1126       /* Set the SWPMI DMA transfer complete callback */
1127       hswpmi->hdmarx->XferCpltCallback = SWPMI_DMAReceiveCplt;
1128 
1129       /* Set the SWPMI DMA Half transfer complete callback */
1130       hswpmi->hdmarx->XferHalfCpltCallback = SWPMI_DMARxHalfCplt;
1131 
1132       /* Set the DMA error callback */
1133       hswpmi->hdmarx->XferErrorCallback = SWPMI_DMAError;
1134 
1135       /* Enable the DMA request */
1136       if (HAL_DMA_Start_IT(hswpmi->hdmarx, (uint32_t)&hswpmi->Instance->RDR,
1137                            (uint32_t)hswpmi->pRxBuffPtr, Size) != HAL_OK)
1138       {
1139         hswpmi->State = tmp_state;    /* Back to previous state */
1140         hswpmi->ErrorCode = HAL_SWPMI_ERROR_DMA;
1141         status = HAL_ERROR;
1142 
1143         /* Process Unlocked */
1144         __HAL_UNLOCK(hswpmi);
1145       }
1146       else
1147       {
1148         /* Process Unlocked */
1149         __HAL_UNLOCK(hswpmi);
1150 
1151         /* Enable the SWPMI receive CRC Error and receive overrun interrupts */
1152         __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE);
1153 
1154         /* Enable the DMA transfer for the receiver request by setting the RXDMA bit
1155            in the SWPMI CR register */
1156         SET_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA);
1157       }
1158     }
1159     else
1160     {
1161       status = HAL_BUSY;
1162 
1163       /* Process Unlocked */
1164       __HAL_UNLOCK(hswpmi);
1165     }
1166   }
1167 
1168   return status;
1169 }
1170 
1171 /**
1172   * @brief Stop all DMA transfers.
1173   * @param hswpmi SWPMI handle
1174   * @retval HAL status
1175   */
HAL_SWPMI_DMAStop(SWPMI_HandleTypeDef * hswpmi)1176 HAL_StatusTypeDef HAL_SWPMI_DMAStop(SWPMI_HandleTypeDef *hswpmi)
1177 {
1178   HAL_StatusTypeDef status = HAL_OK;
1179 
1180   /* Process Locked */
1181   __HAL_LOCK(hswpmi);
1182 
1183   /* Disable the SWPMI Tx/Rx DMA requests */
1184   CLEAR_BIT(hswpmi->Instance->CR, (SWPMI_CR_TXDMA | SWPMI_CR_RXDMA));
1185 
1186   /* Abort the SWPMI DMA tx stream */
1187   if (hswpmi->hdmatx != NULL)
1188   {
1189     if (HAL_DMA_Abort(hswpmi->hdmatx) != HAL_OK)
1190     {
1191       hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA;
1192       status = HAL_ERROR;
1193     }
1194   }
1195   /* Abort the SWPMI DMA rx stream */
1196   if (hswpmi->hdmarx != NULL)
1197   {
1198     if (HAL_DMA_Abort(hswpmi->hdmarx) != HAL_OK)
1199     {
1200       hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA;
1201       status = HAL_ERROR;
1202     }
1203   }
1204 
1205   /* Disable SWPMI interface */
1206   CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1207 
1208   hswpmi->State = HAL_SWPMI_STATE_READY;
1209 
1210   /* Process Unlocked */
1211   __HAL_UNLOCK(hswpmi);
1212 
1213   return status;
1214 }
1215 
1216 
1217 /**
1218   * @brief Enable the Loopback mode.
1219   * @param hswpmi SWPMI handle
1220   * @note  Loopback mode is to be used only for test purposes
1221   * @retval HAL_OK / HAL_BUSY
1222   */
HAL_SWPMI_EnableLoopback(SWPMI_HandleTypeDef * hswpmi)1223 HAL_StatusTypeDef HAL_SWPMI_EnableLoopback(SWPMI_HandleTypeDef *hswpmi)
1224 {
1225   HAL_StatusTypeDef  status = HAL_OK;
1226 
1227   /* Process Locked */
1228   __HAL_LOCK(hswpmi);
1229 
1230   /* Make sure the SWPMI interface is not enabled to set the loopback mode */
1231   CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1232 
1233   /* Set Loopback */
1234   SET_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK);
1235 
1236   /* Enable SWPMI interface in loopback mode */
1237   SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1238 
1239   /* Process Unlocked */
1240   __HAL_UNLOCK(hswpmi);
1241 
1242   return status;
1243 }
1244 
1245 /**
1246   * @brief Disable the Loopback mode.
1247   * @param hswpmi SWPMI handle
1248   * @note  Loopback mode is to be used only for test purposes
1249   * @retval HAL_OK / HAL_BUSY
1250   */
HAL_SWPMI_DisableLoopback(SWPMI_HandleTypeDef * hswpmi)1251 HAL_StatusTypeDef HAL_SWPMI_DisableLoopback(SWPMI_HandleTypeDef *hswpmi)
1252 {
1253   HAL_StatusTypeDef  status = HAL_OK;
1254 
1255   /* Process Locked */
1256   __HAL_LOCK(hswpmi);
1257 
1258   /* Make sure the SWPMI interface is not enabled to reset the loopback mode */
1259   CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1260 
1261   /* Reset Loopback */
1262   CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK);
1263 
1264   /* Re-enable SWPMI interface in normal mode */
1265   SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
1266 
1267   /* Process Unlocked */
1268   __HAL_UNLOCK(hswpmi);
1269 
1270   return status;
1271 }
1272 
1273 /**
1274   * @}
1275   */
1276 
1277 /** @defgroup SWPMI_Exported_Group3 SWPMI IRQ handler and callbacks
1278   *  @brief  SWPMI  IRQ handler.
1279   *
1280 @verbatim
1281   ==============================================================================
1282                       ##### SWPMI IRQ handler and callbacks  #####
1283   ==============================================================================
1284 [..]  This section provides SWPMI IRQ handler and callback functions called within
1285       the IRQ handler.
1286 
1287 @endverbatim
1288   * @{
1289   */
1290 
1291 /**
1292   * @brief Handle SWPMI interrupt request.
1293   * @param hswpmi SWPMI handle
1294   * @retval None
1295   */
HAL_SWPMI_IRQHandler(SWPMI_HandleTypeDef * hswpmi)1296 void HAL_SWPMI_IRQHandler(SWPMI_HandleTypeDef *hswpmi)
1297 {
1298   uint32_t regisr = READ_REG(hswpmi->Instance->ISR);
1299   uint32_t regier = READ_REG(hswpmi->Instance->IER);
1300   uint32_t errcode = HAL_SWPMI_ERROR_NONE;
1301 
1302   /* SWPMI CRC error interrupt occurred --------------------------------------*/
1303   if (((regisr & SWPMI_FLAG_RXBERF) != 0U) && ((regier & SWPMI_IT_RXBERIE) != 0U))
1304   {
1305     /* Disable Receive CRC interrupt */
1306     CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RXBERIE | SWPMI_IT_RXBFIE);
1307     /* Clear Receive CRC and Receive buffer full flag */
1308     WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBERF | SWPMI_FLAG_RXBFF);
1309 
1310     errcode |= HAL_SWPMI_ERROR_CRC;
1311   }
1312 
1313   /* SWPMI Over-Run interrupt occurred -----------------------------------------*/
1314   if (((regisr & SWPMI_FLAG_RXOVRF) != 0U) && ((regier & SWPMI_IT_RXOVRIE) != 0U))
1315   {
1316     /* Disable Receive overrun interrupt */
1317     CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RXOVRIE);
1318     /* Clear Receive overrun flag */
1319     WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXOVRF);
1320 
1321     errcode |= HAL_SWPMI_ERROR_OVR;
1322   }
1323 
1324   /* SWPMI Under-Run interrupt occurred -----------------------------------------*/
1325   if (((regisr & SWPMI_FLAG_TXUNRF) != 0U) && ((regier & SWPMI_IT_TXUNRIE) != 0U))
1326   {
1327     /* Disable Transmit under run interrupt */
1328     CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TXUNRIE);
1329     /* Clear Transmit under run flag */
1330     WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TXUNRF);
1331 
1332     errcode |= HAL_SWPMI_ERROR_UDR;
1333   }
1334 
1335   /* Call SWPMI Error Call back function if needed --------------------------*/
1336   if (errcode != HAL_SWPMI_ERROR_NONE)
1337   {
1338     hswpmi->ErrorCode |= errcode;
1339 
1340     if ((errcode & HAL_SWPMI_ERROR_UDR) != 0U)
1341     {
1342       /* Check TXDMA transfer to abort */
1343       if (HAL_IS_BIT_SET(hswpmi->Instance->CR, SWPMI_CR_TXDMA))
1344       {
1345         /* Disable DMA TX at SWPMI level */
1346         CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA);
1347 
1348         /* Abort the USART DMA Tx stream */
1349         if (hswpmi->hdmatx != NULL)
1350         {
1351           /* Set the SWPMI Tx DMA Abort callback :
1352              will lead to call HAL_SWPMI_ErrorCallback() at end of DMA abort procedure */
1353           hswpmi->hdmatx->XferAbortCallback = SWPMI_DMAAbortOnError;
1354           /* Abort DMA TX */
1355           if (HAL_DMA_Abort_IT(hswpmi->hdmatx) != HAL_OK)
1356           {
1357             /* Call Directly hswpmi->hdmatx->XferAbortCallback function in case of error */
1358             hswpmi->hdmatx->XferAbortCallback(hswpmi->hdmatx);
1359           }
1360         }
1361         else
1362         {
1363           /* Set the SWPMI state ready to be able to start again the process */
1364           hswpmi->State = HAL_SWPMI_STATE_READY;
1365 
1366 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1367           hswpmi->ErrorCallback(hswpmi);
1368 #else
1369           HAL_SWPMI_ErrorCallback(hswpmi);
1370 #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */
1371         }
1372       }
1373       else
1374       {
1375         /* Set the SWPMI state ready to be able to start again the process */
1376         hswpmi->State = HAL_SWPMI_STATE_READY;
1377 
1378 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1379         hswpmi->ErrorCallback(hswpmi);
1380 #else
1381         HAL_SWPMI_ErrorCallback(hswpmi);
1382 #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */
1383       }
1384     }
1385     else
1386     {
1387       /* Check RXDMA transfer to abort */
1388       if (HAL_IS_BIT_SET(hswpmi->Instance->CR, SWPMI_CR_RXDMA))
1389       {
1390         /* Disable DMA RX at SWPMI level */
1391         CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA);
1392 
1393         /* Abort the USART DMA Rx stream */
1394         if (hswpmi->hdmarx != NULL)
1395         {
1396           /* Set the SWPMI Rx DMA Abort callback :
1397              will lead to call HAL_SWPMI_ErrorCallback() at end of DMA abort procedure */
1398           hswpmi->hdmarx->XferAbortCallback = SWPMI_DMAAbortOnError;
1399           /* Abort DMA RX */
1400           if (HAL_DMA_Abort_IT(hswpmi->hdmarx) != HAL_OK)
1401           {
1402             /* Call Directly hswpmi->hdmarx->XferAbortCallback function in case of error */
1403             hswpmi->hdmarx->XferAbortCallback(hswpmi->hdmarx);
1404           }
1405         }
1406         else
1407         {
1408           /* Set the SWPMI state ready to be able to start again the process */
1409           hswpmi->State = HAL_SWPMI_STATE_READY;
1410 
1411 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1412           hswpmi->ErrorCallback(hswpmi);
1413 #else
1414           HAL_SWPMI_ErrorCallback(hswpmi);
1415 #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */
1416         }
1417       }
1418       else
1419       {
1420         /* Set the SWPMI state ready to be able to start again the process */
1421         hswpmi->State = HAL_SWPMI_STATE_READY;
1422 
1423 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1424         hswpmi->ErrorCallback(hswpmi);
1425 #else
1426         HAL_SWPMI_ErrorCallback(hswpmi);
1427 #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */
1428       }
1429     }
1430   }
1431 
1432   /* SWPMI in mode Receiver ---------------------------------------------------*/
1433   if (((regisr & SWPMI_FLAG_RXNE) != 0U) && ((regier & SWPMI_IT_RIE)  != 0U))
1434   {
1435     SWPMI_Receive_IT(hswpmi);
1436   }
1437 
1438   /* SWPMI in mode Transmitter ------------------------------------------------*/
1439   if (((regisr & SWPMI_FLAG_TXE) != 0U) && ((regier & SWPMI_IT_TIE) != 0U))
1440   {
1441     SWPMI_Transmit_IT(hswpmi);
1442   }
1443 
1444   /* SWPMI in mode Transmitter (Transmit buffer empty) ------------------------*/
1445   if (((regisr & SWPMI_FLAG_TXBEF) != 0U) && ((regier & SWPMI_IT_TXBEIE) != 0U))
1446   {
1447     SWPMI_EndTransmit_IT(hswpmi);
1448   }
1449 
1450   /* SWPMI in mode Receiver (Receive buffer full) -----------------------------*/
1451   if (((regisr & SWPMI_FLAG_RXBFF) != 0U) && ((regier & SWPMI_IT_RXBFIE) != 0U))
1452   {
1453     SWPMI_EndReceive_IT(hswpmi);
1454   }
1455 
1456   /* Both Transmission and reception complete ---------------------------------*/
1457   if (((regisr & SWPMI_FLAG_TCF) != 0U) && ((regier & SWPMI_IT_TCIE) != 0U))
1458   {
1459     SWPMI_EndTransmitReceive_IT(hswpmi);
1460   }
1461 }
1462 
1463 /**
1464   * @brief Tx Transfer completed callback.
1465   * @param hswpmi SWPMI handle
1466   * @retval None
1467   */
HAL_SWPMI_TxCpltCallback(SWPMI_HandleTypeDef * hswpmi)1468 __weak void HAL_SWPMI_TxCpltCallback(SWPMI_HandleTypeDef *hswpmi)
1469 {
1470   /* Prevent unused argument(s) compilation warning */
1471   UNUSED(hswpmi);
1472 
1473   /* NOTE : This function should not be modified, when the callback is needed,
1474             the HAL_SWPMI_TxCpltCallback is to be implemented in the user file
1475    */
1476 }
1477 
1478 /**
1479   * @brief  Tx Half Transfer completed callback.
1480   * @param  hswpmi SWPMI handle
1481   * @retval None
1482   */
HAL_SWPMI_TxHalfCpltCallback(SWPMI_HandleTypeDef * hswpmi)1483 __weak void HAL_SWPMI_TxHalfCpltCallback(SWPMI_HandleTypeDef *hswpmi)
1484 {
1485   /* Prevent unused argument(s) compilation warning */
1486   UNUSED(hswpmi);
1487 
1488   /* NOTE: This function should not be modified, when the callback is needed,
1489            the HAL_SWPMI_TxHalfCpltCallback is to be implemented in the user file
1490    */
1491 }
1492 
1493 /**
1494   * @brief Rx Transfer completed callback.
1495   * @param hswpmi SWPMI handle
1496   * @retval None
1497   */
HAL_SWPMI_RxCpltCallback(SWPMI_HandleTypeDef * hswpmi)1498 __weak void HAL_SWPMI_RxCpltCallback(SWPMI_HandleTypeDef *hswpmi)
1499 {
1500   /* Prevent unused argument(s) compilation warning */
1501   UNUSED(hswpmi);
1502 
1503   /* NOTE : This function should not be modified, when the callback is needed,
1504             the HAL_SWPMI_RxCpltCallback is to be implemented in the user file
1505    */
1506 }
1507 
1508 /**
1509   * @brief  Rx Half Transfer completed callback.
1510   * @param  hswpmi SWPMI handle
1511   * @retval None
1512   */
HAL_SWPMI_RxHalfCpltCallback(SWPMI_HandleTypeDef * hswpmi)1513 __weak void HAL_SWPMI_RxHalfCpltCallback(SWPMI_HandleTypeDef *hswpmi)
1514 {
1515   /* Prevent unused argument(s) compilation warning */
1516   UNUSED(hswpmi);
1517 
1518   /* NOTE: This function should not be modified, when the callback is needed,
1519            the HAL_SWPMI_RxHalfCpltCallback is to be implemented in the user file
1520    */
1521 }
1522 
1523 /**
1524   * @brief SWPMI error callback.
1525   * @param hswpmi SWPMI handle
1526   * @retval None
1527   */
HAL_SWPMI_ErrorCallback(SWPMI_HandleTypeDef * hswpmi)1528 __weak void HAL_SWPMI_ErrorCallback(SWPMI_HandleTypeDef *hswpmi)
1529 {
1530   /* Prevent unused argument(s) compilation warning */
1531   UNUSED(hswpmi);
1532 
1533   /* NOTE : This function should not be modified, when the callback is needed,
1534             the HAL_SWPMI_ErrorCallback is to be implemented in the user file
1535    */
1536 }
1537 
1538 /**
1539   * @}
1540   */
1541 
1542 /** @defgroup SWPMI_Exported_Group4 Peripheral Control methods
1543   *  @brief   SWPMI control functions
1544   *
1545 @verbatim
1546  ===============================================================================
1547                       ##### Peripheral Control methods #####
1548  ===============================================================================
1549     [..]
1550     This subsection provides a set of functions allowing to control the SWPMI.
1551      (+) HAL_SWPMI_GetState() API is helpful to check in run-time the state of the SWPMI peripheral
1552      (+) HAL_SWPMI_GetError() API is helpful to check in run-time the error state of the SWPMI peripheral
1553 @endverbatim
1554   * @{
1555   */
1556 
1557 /**
1558   * @brief Return the SWPMI handle state.
1559   * @param hswpmi SWPMI handle
1560   * @retval HAL state
1561   */
HAL_SWPMI_GetState(const SWPMI_HandleTypeDef * hswpmi)1562 HAL_SWPMI_StateTypeDef HAL_SWPMI_GetState(const SWPMI_HandleTypeDef *hswpmi)
1563 {
1564   /* Return SWPMI handle state */
1565   return hswpmi->State;
1566 }
1567 
1568 /**
1569   * @brief  Return the SWPMI error code.
1570   * @param  hswpmi : pointer to a SWPMI_HandleTypeDef structure that contains
1571   *              the configuration information for the specified SWPMI.
1572   * @retval SWPMI Error Code
1573   */
HAL_SWPMI_GetError(const SWPMI_HandleTypeDef * hswpmi)1574 uint32_t HAL_SWPMI_GetError(const SWPMI_HandleTypeDef *hswpmi)
1575 {
1576   return hswpmi->ErrorCode;
1577 }
1578 
1579 /**
1580   * @}
1581   */
1582 
1583 /**
1584   * @}
1585   */
1586 
1587 /* Private functions ---------------------------------------------------------*/
1588 
1589 /** @defgroup SWPMI_Private_Functions SWPMI Private Functions
1590   * @{
1591   */
1592 
1593 /**
1594   * @brief Transmit an amount of data in interrupt mode.
1595   * @note  Function called under interruption only, once interruptions have been enabled by HAL_SWPMI_Transmit_IT()
1596   * @param  hswpmi SWPMI handle
1597   * @retval None
1598   */
SWPMI_Transmit_IT(SWPMI_HandleTypeDef * hswpmi)1599 static void SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi)
1600 {
1601   HAL_SWPMI_StateTypeDef tmp_state = hswpmi->State;
1602 
1603   if ((tmp_state == HAL_SWPMI_STATE_BUSY_TX) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX_RX))
1604   {
1605     if (hswpmi->TxXferCount == 0U)
1606     {
1607       /* Disable the SWPMI TXE and Underrun Interrupts */
1608       CLEAR_BIT(hswpmi->Instance->IER, (SWPMI_IT_TIE | SWPMI_IT_TXUNRIE));
1609     }
1610     else
1611     {
1612       hswpmi->Instance->TDR = (uint32_t) * hswpmi->pTxBuffPtr;
1613       hswpmi->pTxBuffPtr++;
1614       hswpmi->TxXferCount--;
1615     }
1616   }
1617   else
1618   {
1619     /* nothing to do */
1620   }
1621 }
1622 
1623 /**
1624   * @brief  Wraps up transmission in non-blocking mode.
1625   * @param  hswpmi SWPMI handle
1626   * @retval None
1627   */
SWPMI_EndTransmit_IT(SWPMI_HandleTypeDef * hswpmi)1628 static void SWPMI_EndTransmit_IT(SWPMI_HandleTypeDef *hswpmi)
1629 {
1630   /* Clear the SWPMI Transmit buffer empty Flag */
1631   WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TXBEF);
1632   /* Disable the all SWPMI Transmit Interrupts  */
1633   CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TIE | SWPMI_IT_TXUNRIE | SWPMI_IT_TXBEIE);
1634 
1635   /* Check if a receive Process is ongoing or not */
1636   if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
1637   {
1638     hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
1639   }
1640   else
1641   {
1642     hswpmi->State = HAL_SWPMI_STATE_READY;
1643   }
1644 
1645 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1646   hswpmi->TxCpltCallback(hswpmi);
1647 #else
1648   HAL_SWPMI_TxCpltCallback(hswpmi);
1649 #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */
1650 }
1651 
1652 /**
1653   * @brief Receive an amount of data in interrupt mode.
1654   * @note  Function called under interruption only, once interruptions have been enabled by HAL_SWPMI_Receive_IT()
1655   * @param  hswpmi SWPMI handle
1656   * @retval None
1657   */
SWPMI_Receive_IT(SWPMI_HandleTypeDef * hswpmi)1658 static void SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi)
1659 {
1660   HAL_SWPMI_StateTypeDef tmp_state = hswpmi->State;
1661 
1662   if ((tmp_state == HAL_SWPMI_STATE_BUSY_RX) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX_RX))
1663   {
1664     *hswpmi->pRxBuffPtr = (uint32_t)(hswpmi->Instance->RDR);
1665     hswpmi->pRxBuffPtr++;
1666 
1667     --hswpmi->RxXferCount;
1668     if (hswpmi->RxXferCount == 0U)
1669     {
1670       /* Wait for RXBFF flag to update state */
1671 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1672       hswpmi->RxCpltCallback(hswpmi);
1673 #else
1674       HAL_SWPMI_RxCpltCallback(hswpmi);
1675 #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */
1676     }
1677   }
1678   else
1679   {
1680     /* nothing to do */
1681   }
1682 }
1683 
1684 /**
1685   * @brief  Wraps up reception in non-blocking mode.
1686   * @param  hswpmi SWPMI handle
1687   * @retval None
1688   */
SWPMI_EndReceive_IT(SWPMI_HandleTypeDef * hswpmi)1689 static void SWPMI_EndReceive_IT(SWPMI_HandleTypeDef *hswpmi)
1690 {
1691   /* Clear the SWPMI Receive buffer full Flag */
1692   WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBFF);
1693   /* Disable the all SWPMI Receive Interrupts  */
1694   CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);
1695 
1696   /* Check if a transmit Process is ongoing or not */
1697   if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
1698   {
1699     hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
1700   }
1701   else
1702   {
1703     hswpmi->State = HAL_SWPMI_STATE_READY;
1704   }
1705 }
1706 
1707 /**
1708   * @brief  Wraps up transmission and reception in non-blocking mode.
1709   * @param  hswpmi SWPMI handle
1710   * @retval None
1711   */
SWPMI_EndTransmitReceive_IT(SWPMI_HandleTypeDef * hswpmi)1712 static void SWPMI_EndTransmitReceive_IT(SWPMI_HandleTypeDef *hswpmi)
1713 {
1714   /* Clear the SWPMI Transmission Complete Flag */
1715   WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TCF);
1716   /* Disable the SWPMI Transmission  Complete Interrupt */
1717   CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TCIE);
1718 
1719   /* Check if a receive Process is ongoing or not */
1720   if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
1721   {
1722     hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
1723   }
1724   else if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX)
1725   {
1726     hswpmi->State = HAL_SWPMI_STATE_READY;
1727   }
1728   else
1729   {
1730     /* nothing to do */
1731   }
1732 }
1733 
1734 /**
1735   * @brief DMA SWPMI transmit process complete callback.
1736   * @param hdma DMA handle
1737   * @retval None
1738   */
SWPMI_DMATransmitCplt(DMA_HandleTypeDef * hdma)1739 static void SWPMI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1740 {
1741   SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1742   uint32_t tickstart;
1743 
1744   /* DMA Normal mode*/
1745   if (((((DMA_Stream_TypeDef *)hdma->Instance)->CR) & DMA_SxCR_CIRC) == 0U)
1746   {
1747     hswpmi->TxXferCount = 0U;
1748 
1749     /* Disable the DMA transfer for transmit request by setting the TXDMA bit
1750     in the SWPMI CR register */
1751     CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA);
1752 
1753     /* Init tickstart for timeout management*/
1754     tickstart = HAL_GetTick();
1755 
1756     /* Wait the TXBEF */
1757     if (SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_TXBEF, tickstart, SWPMI_TIMEOUT_VALUE) != HAL_OK)
1758     {
1759       /* Timeout occurred */
1760       hswpmi->ErrorCode |= HAL_SWPMI_ERROR_TXBEF_TIMEOUT;
1761 
1762 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1763       hswpmi->ErrorCallback(hswpmi);
1764 #else
1765       HAL_SWPMI_ErrorCallback(hswpmi);
1766 #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */
1767     }
1768     else
1769     {
1770       /* No Timeout */
1771       /* Check if a receive process is ongoing or not */
1772       if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
1773       {
1774         hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
1775       }
1776       else
1777       {
1778         hswpmi->State = HAL_SWPMI_STATE_READY;
1779       }
1780 
1781 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1782       hswpmi->TxCpltCallback(hswpmi);
1783 #else
1784       HAL_SWPMI_TxCpltCallback(hswpmi);
1785 #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */
1786     }
1787   }
1788   /* DMA Circular mode */
1789   else
1790   {
1791 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1792     hswpmi->TxCpltCallback(hswpmi);
1793 #else
1794     HAL_SWPMI_TxCpltCallback(hswpmi);
1795 #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */
1796   }
1797 }
1798 
1799 /**
1800   * @brief DMA SWPMI transmit process half complete callback.
1801   * @param hdma DMA handle
1802   * @retval None
1803   */
SWPMI_DMATxHalfCplt(DMA_HandleTypeDef * hdma)1804 static void SWPMI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1805 {
1806   SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1807 
1808 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1809   hswpmi->TxHalfCpltCallback(hswpmi);
1810 #else
1811   HAL_SWPMI_TxHalfCpltCallback(hswpmi);
1812 #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */
1813 }
1814 
1815 
1816 /**
1817   * @brief DMA SWPMI receive process complete callback.
1818   * @param hdma DMA handle
1819   * @retval None
1820   */
SWPMI_DMAReceiveCplt(DMA_HandleTypeDef * hdma)1821 static void SWPMI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1822 {
1823   SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1824 
1825   /* DMA Normal mode*/
1826   if (((((DMA_Stream_TypeDef *)hdma->Instance)->CR) & DMA_SxCR_CIRC) == 0U)
1827   {
1828     hswpmi->RxXferCount = 0U;
1829 
1830     /* Disable the DMA transfer for the receiver request by setting the RXDMA bit
1831     in the SWPMI CR register */
1832     CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA);
1833 
1834     /* Check if a transmit Process is ongoing or not */
1835     if (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
1836     {
1837       hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
1838     }
1839     else
1840     {
1841       hswpmi->State = HAL_SWPMI_STATE_READY;
1842     }
1843   }
1844 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1845   hswpmi->RxCpltCallback(hswpmi);
1846 #else
1847   HAL_SWPMI_RxCpltCallback(hswpmi);
1848 #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */
1849 }
1850 
1851 /**
1852   * @brief DMA SWPMI receive process half complete callback.
1853   * @param hdma DMA handle
1854   * @retval None
1855   */
SWPMI_DMARxHalfCplt(DMA_HandleTypeDef * hdma)1856 static void SWPMI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1857 {
1858   SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1859 
1860 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1861   hswpmi->RxHalfCpltCallback(hswpmi);
1862 #else
1863   HAL_SWPMI_RxHalfCpltCallback(hswpmi);
1864 #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */
1865 }
1866 
1867 /**
1868   * @brief DMA SWPMI communication error callback.
1869   * @param hdma DMA handle
1870   * @retval None
1871   */
SWPMI_DMAError(DMA_HandleTypeDef * hdma)1872 static void SWPMI_DMAError(DMA_HandleTypeDef *hdma)
1873 {
1874   SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1875 
1876   /* Update handle */
1877   hswpmi->RxXferCount = 0U;
1878   hswpmi->TxXferCount = 0U;
1879   hswpmi->State = HAL_SWPMI_STATE_READY;
1880   hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA;
1881 
1882 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1883   hswpmi->ErrorCallback(hswpmi);
1884 #else
1885   HAL_SWPMI_ErrorCallback(hswpmi);
1886 #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */
1887 }
1888 
1889 /**
1890   * @brief DMA SWPMI communication abort callback.
1891   * @param hdma DMA handle
1892   * @retval None
1893   */
SWPMI_DMAAbortOnError(DMA_HandleTypeDef * hdma)1894 static void SWPMI_DMAAbortOnError(DMA_HandleTypeDef *hdma)
1895 {
1896   SWPMI_HandleTypeDef *hswpmi = (SWPMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1897 
1898   /* Update handle */
1899   hswpmi->RxXferCount = 0U;
1900   hswpmi->TxXferCount = 0U;
1901   hswpmi->State = HAL_SWPMI_STATE_READY;
1902 
1903 #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
1904   hswpmi->ErrorCallback(hswpmi);
1905 #else
1906   HAL_SWPMI_ErrorCallback(hswpmi);
1907 #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */
1908 }
1909 
1910 /**
1911   * @brief  Handle SWPMI Communication Timeout.
1912   * @param  hswpmi SWPMI handle
1913   * @param  Flag specifies the SWPMI flag to check.
1914   * @param  Tickstart Tick start value
1915   * @param  Timeout timeout duration.
1916   * @retval HAL status
1917   */
SWPMI_WaitOnFlagSetUntilTimeout(SWPMI_HandleTypeDef * hswpmi,uint32_t Flag,uint32_t Tickstart,uint32_t Timeout)1918 static HAL_StatusTypeDef SWPMI_WaitOnFlagSetUntilTimeout(SWPMI_HandleTypeDef *hswpmi, uint32_t Flag, uint32_t Tickstart,
1919                                                          uint32_t Timeout)
1920 {
1921   HAL_StatusTypeDef status = HAL_OK;
1922 
1923   /* Wait until flag is set */
1924   while (!(HAL_IS_BIT_SET(hswpmi->Instance->ISR, Flag)))
1925   {
1926     /* Check for the Timeout */
1927     if ((((HAL_GetTick() - Tickstart) >  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
1928     {
1929       /* Set the SWPMI state ready to be able to start again the process */
1930       hswpmi->State = HAL_SWPMI_STATE_READY;
1931 
1932       status = HAL_TIMEOUT;
1933       break;
1934     }
1935   }
1936 
1937   return status;
1938 }
1939 
1940 /**
1941   * @}
1942   */
1943 
1944 #endif /* HAL_SWPMI_MODULE_ENABLED */
1945 
1946 /**
1947   * @}
1948   */
1949 
1950 
1951 /**
1952   * @}
1953   */
1954