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