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