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