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