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