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