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