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