1 /**
2 ******************************************************************************
3 * @file stm32wbaxx_hal_usart.c
4 * @author MCD Application Team
5 * @brief USART HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Universal Synchronous/Asynchronous Receiver Transmitter
8 * Peripheral (USART).
9 * + Initialization and de-initialization functions
10 * + IO operation functions
11 * + Peripheral Control functions
12 * + Peripheral State and Error functions
13 *
14 ******************************************************************************
15 * @attention
16 *
17 * Copyright (c) 2022 STMicroelectronics.
18 * All rights reserved.
19 *
20 * This software is licensed under terms that can be found in the LICENSE file
21 * in the root directory of this software component.
22 * If no LICENSE file comes with this software, it is provided AS-IS.
23 *
24 ******************************************************************************
25 @verbatim
26 ===============================================================================
27 ##### How to use this driver #####
28 ===============================================================================
29 [..]
30 The USART HAL driver can be used as follows:
31
32 (#) Declare a USART_HandleTypeDef handle structure (eg. USART_HandleTypeDef husart).
33 (#) Initialize the USART low level resources by implementing the HAL_USART_MspInit() API:
34 (++) Enable the USARTx interface clock.
35 (++) USART pins configuration:
36 (+++) Enable the clock for the USART GPIOs.
37 (+++) Configure these USART pins as alternate function pull-up.
38 (++) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
39 HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
40 (+++) Configure the USARTx interrupt priority.
41 (+++) Enable the NVIC USART IRQ handle.
42 (++) USART interrupts handling:
43 -@@- The specific USART interrupts (Transmission complete interrupt,
44 RXNE interrupt and Error Interrupts) will be managed using the macros
45 __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process.
46 (++) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA()
47 HAL_USART_Receive_DMA() and HAL_USART_TransmitReceive_DMA() APIs):
48 (+++) Declare a DMA handle structure for the Tx/Rx channel.
49 (+++) Enable the DMAx interface clock.
50 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
51 (+++) Configure the DMA Tx/Rx channel.
52 (+++) Associate the initialized DMA handle to the USART DMA Tx/Rx handle.
53 (+++) Configure the priority and enable the NVIC for the transfer
54 complete interrupt on the DMA Tx/Rx channel.
55
56 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, and Mode
57 (Receiver/Transmitter) in the husart handle Init structure.
58
59 (#) Initialize the USART registers by calling the HAL_USART_Init() API:
60 (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
61 by calling the customized HAL_USART_MspInit(&husart) API.
62
63 [..]
64 (@) To configure and enable/disable the USART to wake up the MCU from stop mode, resort to UART API's
65 HAL_UARTEx_StopModeWakeUpSourceConfig(), HAL_UARTEx_EnableStopMode() and
66 HAL_UARTEx_DisableStopMode() in casting the USART handle to UART type UART_HandleTypeDef.
67
68 ##### Callback registration #####
69 ==================================
70
71 [..]
72 The compilation define USE_HAL_USART_REGISTER_CALLBACKS when set to 1
73 allows the user to configure dynamically the driver callbacks.
74
75 [..]
76 Use Function HAL_USART_RegisterCallback() to register a user callback.
77 Function HAL_USART_RegisterCallback() allows to register following callbacks:
78 (+) TxHalfCpltCallback : Tx Half Complete Callback.
79 (+) TxCpltCallback : Tx Complete Callback.
80 (+) RxHalfCpltCallback : Rx Half Complete Callback.
81 (+) RxCpltCallback : Rx Complete Callback.
82 (+) TxRxCpltCallback : Tx Rx Complete Callback.
83 (+) ErrorCallback : Error Callback.
84 (+) AbortCpltCallback : Abort Complete Callback.
85 (+) RxFifoFullCallback : Rx Fifo Full Callback.
86 (+) TxFifoEmptyCallback : Tx Fifo Empty Callback.
87 (+) MspInitCallback : USART MspInit.
88 (+) MspDeInitCallback : USART MspDeInit.
89 This function takes as parameters the HAL peripheral handle, the Callback ID
90 and a pointer to the user callback function.
91
92 [..]
93 Use function HAL_USART_UnRegisterCallback() to reset a callback to the default
94 weak function.
95 HAL_USART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
96 and the Callback ID.
97 This function allows to reset following callbacks:
98 (+) TxHalfCpltCallback : Tx Half Complete Callback.
99 (+) TxCpltCallback : Tx Complete Callback.
100 (+) RxHalfCpltCallback : Rx Half Complete Callback.
101 (+) RxCpltCallback : Rx Complete Callback.
102 (+) TxRxCpltCallback : Tx Rx Complete Callback.
103 (+) ErrorCallback : Error Callback.
104 (+) AbortCpltCallback : Abort Complete Callback.
105 (+) RxFifoFullCallback : Rx Fifo Full Callback.
106 (+) TxFifoEmptyCallback : Tx Fifo Empty Callback.
107 (+) MspInitCallback : USART MspInit.
108 (+) MspDeInitCallback : USART MspDeInit.
109
110 [..]
111 By default, after the HAL_USART_Init() and when the state is HAL_USART_STATE_RESET
112 all callbacks are set to the corresponding weak functions:
113 examples HAL_USART_TxCpltCallback(), HAL_USART_RxHalfCpltCallback().
114 Exception done for MspInit and MspDeInit functions that are respectively
115 reset to the legacy weak functions in the HAL_USART_Init()
116 and HAL_USART_DeInit() only when these callbacks are null (not registered beforehand).
117 If not, MspInit or MspDeInit are not null, the HAL_USART_Init() and HAL_USART_DeInit()
118 keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
119
120 [..]
121 Callbacks can be registered/unregistered in HAL_USART_STATE_READY state only.
122 Exception done MspInit/MspDeInit that can be registered/unregistered
123 in HAL_USART_STATE_READY or HAL_USART_STATE_RESET state, thus registered (user)
124 MspInit/DeInit callbacks can be used during the Init/DeInit.
125 In that case first register the MspInit/MspDeInit user callbacks
126 using HAL_USART_RegisterCallback() before calling HAL_USART_DeInit()
127 or HAL_USART_Init() function.
128
129 [..]
130 When The compilation define USE_HAL_USART_REGISTER_CALLBACKS is set to 0 or
131 not defined, the callback registration feature is not available
132 and weak callbacks are used.
133
134
135 @endverbatim
136 ******************************************************************************
137 */
138
139 /* Includes ------------------------------------------------------------------*/
140 #include "stm32wbaxx_hal.h"
141
142 /** @addtogroup STM32WBAxx_HAL_Driver
143 * @{
144 */
145
146 /** @defgroup USART USART
147 * @brief HAL USART Synchronous module driver
148 * @{
149 */
150
151 #ifdef HAL_USART_MODULE_ENABLED
152
153 /* Private typedef -----------------------------------------------------------*/
154 /* Private define ------------------------------------------------------------*/
155 /** @defgroup USART_Private_Constants USART Private Constants
156 * @{
157 */
158 #define USART_DUMMY_DATA ((uint16_t) 0xFFFF) /*!< USART transmitted dummy data */
159 #define USART_TEACK_REACK_TIMEOUT 1000U /*!< USART TX or RX enable acknowledge time-out value */
160 #define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
161 USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8 | \
162 USART_CR1_FIFOEN )) /*!< USART CR1 fields of parameters set by USART_SetConfig API */
163
164 #define USART_CR2_FIELDS ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | \
165 USART_CR2_LBCL | USART_CR2_STOP | USART_CR2_SLVEN | \
166 USART_CR2_DIS_NSS)) /*!< USART CR2 fields of parameters set by USART_SetConfig API */
167
168 #define USART_CR3_FIELDS ((uint32_t)(USART_CR3_TXFTCFG | USART_CR3_RXFTCFG )) /*!< USART or USART CR3 fields of parameters set by USART_SetConfig API */
169
170 #define USART_BRR_MIN 0x10U /* USART BRR minimum authorized value */
171 #define USART_BRR_MAX 0xFFFFU /* USART BRR maximum authorized value */
172 /**
173 * @}
174 */
175
176 /* Private macros ------------------------------------------------------------*/
177 /* Private variables ---------------------------------------------------------*/
178 /* Private function prototypes -----------------------------------------------*/
179 /** @addtogroup USART_Private_Functions
180 * @{
181 */
182 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
183 void USART_InitCallbacksToDefault(USART_HandleTypeDef *husart);
184 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
185 static void USART_EndTransfer(USART_HandleTypeDef *husart);
186 #if defined(HAL_DMA_MODULE_ENABLED)
187 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
188 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
189 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
190 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
191 static void USART_DMAError(DMA_HandleTypeDef *hdma);
192 static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
193 static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
194 static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
195 #endif /* HAL_DMA_MODULE_ENABLED */
196 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status,
197 uint32_t Tickstart, uint32_t Timeout);
198 static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart);
199 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart);
200 static void USART_TxISR_8BIT(USART_HandleTypeDef *husart);
201 static void USART_TxISR_16BIT(USART_HandleTypeDef *husart);
202 static void USART_TxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart);
203 static void USART_TxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart);
204 static void USART_EndTransmit_IT(USART_HandleTypeDef *husart);
205 static void USART_RxISR_8BIT(USART_HandleTypeDef *husart);
206 static void USART_RxISR_16BIT(USART_HandleTypeDef *husart);
207 static void USART_RxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart);
208 static void USART_RxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart);
209
210
211 /**
212 * @}
213 */
214
215 /* Exported functions --------------------------------------------------------*/
216
217 /** @defgroup USART_Exported_Functions USART Exported Functions
218 * @{
219 */
220
221 /** @defgroup USART_Exported_Functions_Group1 Initialization and de-initialization functions
222 * @brief Initialization and Configuration functions
223 *
224 @verbatim
225 ===============================================================================
226 ##### Initialization and Configuration functions #####
227 ===============================================================================
228 [..]
229 This subsection provides a set of functions allowing to initialize the USART
230 in asynchronous and in synchronous modes.
231 (+) For the asynchronous mode only these parameters can be configured:
232 (++) Baud Rate
233 (++) Word Length
234 (++) Stop Bit
235 (++) Parity: If the parity is enabled, then the MSB bit of the data written
236 in the data register is transmitted but is changed by the parity bit.
237 (++) USART polarity
238 (++) USART phase
239 (++) USART LastBit
240 (++) Receiver/transmitter modes
241
242 [..]
243 The HAL_USART_Init() function follows the USART synchronous configuration
244 procedure (details for the procedure are available in reference manual).
245
246 @endverbatim
247
248 Depending on the frame length defined by the M1 and M0 bits (7-bit,
249 8-bit or 9-bit), the possible USART formats are listed in the
250 following table.
251
252 Table 1. USART frame format.
253 +-----------------------------------------------------------------------+
254 | M1 bit | M0 bit | PCE bit | USART frame |
255 |---------|---------|-----------|---------------------------------------|
256 | 0 | 0 | 0 | | SB | 8 bit data | STB | |
257 |---------|---------|-----------|---------------------------------------|
258 | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | |
259 |---------|---------|-----------|---------------------------------------|
260 | 0 | 1 | 0 | | SB | 9 bit data | STB | |
261 |---------|---------|-----------|---------------------------------------|
262 | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | |
263 |---------|---------|-----------|---------------------------------------|
264 | 1 | 0 | 0 | | SB | 7 bit data | STB | |
265 |---------|---------|-----------|---------------------------------------|
266 | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | |
267 +-----------------------------------------------------------------------+
268
269 * @{
270 */
271
272 /**
273 * @brief Initialize the USART mode according to the specified
274 * parameters in the USART_InitTypeDef and initialize the associated handle.
275 * @param husart USART handle.
276 * @retval HAL status
277 */
HAL_USART_Init(USART_HandleTypeDef * husart)278 HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
279 {
280 /* Check the USART handle allocation */
281 if (husart == NULL)
282 {
283 return HAL_ERROR;
284 }
285
286 /* Check the parameters */
287 assert_param(IS_USART_INSTANCE(husart->Instance));
288
289 if (husart->State == HAL_USART_STATE_RESET)
290 {
291 /* Allocate lock resource and initialize it */
292 husart->Lock = HAL_UNLOCKED;
293
294 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
295 USART_InitCallbacksToDefault(husart);
296
297 if (husart->MspInitCallback == NULL)
298 {
299 husart->MspInitCallback = HAL_USART_MspInit;
300 }
301
302 /* Init the low level hardware */
303 husart->MspInitCallback(husart);
304 #else
305 /* Init the low level hardware : GPIO, CLOCK */
306 HAL_USART_MspInit(husart);
307 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
308 }
309
310 husart->State = HAL_USART_STATE_BUSY;
311
312 /* Disable the Peripheral */
313 __HAL_USART_DISABLE(husart);
314
315 /* Set the Usart Communication parameters */
316 if (USART_SetConfig(husart) == HAL_ERROR)
317 {
318 return HAL_ERROR;
319 }
320
321 /* In Synchronous mode, the following bits must be kept cleared:
322 - LINEN bit in the USART_CR2 register
323 - HDSEL, SCEN and IREN bits in the USART_CR3 register.
324 */
325 husart->Instance->CR2 &= ~USART_CR2_LINEN;
326 husart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
327
328 /* Enable the Peripheral */
329 __HAL_USART_ENABLE(husart);
330
331 /* TEACK and/or REACK to check before moving husart->State to Ready */
332 return (USART_CheckIdleState(husart));
333 }
334
335 /**
336 * @brief DeInitialize the USART peripheral.
337 * @param husart USART handle.
338 * @retval HAL status
339 */
HAL_USART_DeInit(USART_HandleTypeDef * husart)340 HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart)
341 {
342 /* Check the USART handle allocation */
343 if (husart == NULL)
344 {
345 return HAL_ERROR;
346 }
347
348 /* Check the parameters */
349 assert_param(IS_USART_INSTANCE(husart->Instance));
350
351 husart->State = HAL_USART_STATE_BUSY;
352
353 husart->Instance->CR1 = 0x0U;
354 husart->Instance->CR2 = 0x0U;
355 husart->Instance->CR3 = 0x0U;
356
357 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
358 if (husart->MspDeInitCallback == NULL)
359 {
360 husart->MspDeInitCallback = HAL_USART_MspDeInit;
361 }
362 /* DeInit the low level hardware */
363 husart->MspDeInitCallback(husart);
364 #else
365 /* DeInit the low level hardware */
366 HAL_USART_MspDeInit(husart);
367 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
368
369 husart->ErrorCode = HAL_USART_ERROR_NONE;
370 husart->State = HAL_USART_STATE_RESET;
371
372 /* Process Unlock */
373 __HAL_UNLOCK(husart);
374
375 return HAL_OK;
376 }
377
378 /**
379 * @brief Initialize the USART MSP.
380 * @param husart USART handle.
381 * @retval None
382 */
HAL_USART_MspInit(USART_HandleTypeDef * husart)383 __weak void HAL_USART_MspInit(USART_HandleTypeDef *husart)
384 {
385 /* Prevent unused argument(s) compilation warning */
386 UNUSED(husart);
387
388 /* NOTE : This function should not be modified, when the callback is needed,
389 the HAL_USART_MspInit can be implemented in the user file
390 */
391 }
392
393 /**
394 * @brief DeInitialize the USART MSP.
395 * @param husart USART handle.
396 * @retval None
397 */
HAL_USART_MspDeInit(USART_HandleTypeDef * husart)398 __weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart)
399 {
400 /* Prevent unused argument(s) compilation warning */
401 UNUSED(husart);
402
403 /* NOTE : This function should not be modified, when the callback is needed,
404 the HAL_USART_MspDeInit can be implemented in the user file
405 */
406 }
407
408 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
409 /**
410 * @brief Register a User USART Callback
411 * To be used to override the weak predefined callback
412 * @note The HAL_USART_RegisterCallback() may be called before HAL_USART_Init() in HAL_USART_STATE_RESET
413 * to register callbacks for HAL_USART_MSPINIT_CB_ID and HAL_USART_MSPDEINIT_CB_ID
414 * @param husart usart 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_USART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
418 * @arg @ref HAL_USART_TX_COMPLETE_CB_ID Tx Complete Callback ID
419 * @arg @ref HAL_USART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
420 * @arg @ref HAL_USART_RX_COMPLETE_CB_ID Rx Complete Callback ID
421 * @arg @ref HAL_USART_TX_RX_COMPLETE_CB_ID Rx Complete Callback ID
422 * @arg @ref HAL_USART_ERROR_CB_ID Error Callback ID
423 * @arg @ref HAL_USART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
424 * @arg @ref HAL_USART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
425 * @arg @ref HAL_USART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
426 * @arg @ref HAL_USART_MSPINIT_CB_ID MspInit Callback ID
427 * @arg @ref HAL_USART_MSPDEINIT_CB_ID MspDeInit Callback ID
428 * @param pCallback pointer to the Callback function
429 * @retval HAL status
430 + */
HAL_USART_RegisterCallback(USART_HandleTypeDef * husart,HAL_USART_CallbackIDTypeDef CallbackID,pUSART_CallbackTypeDef pCallback)431 HAL_StatusTypeDef HAL_USART_RegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID,
432 pUSART_CallbackTypeDef pCallback)
433 {
434 HAL_StatusTypeDef status = HAL_OK;
435
436 if (pCallback == NULL)
437 {
438 /* Update the error code */
439 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
440
441 return HAL_ERROR;
442 }
443
444 if (husart->State == HAL_USART_STATE_READY)
445 {
446 switch (CallbackID)
447 {
448 case HAL_USART_TX_HALFCOMPLETE_CB_ID :
449 husart->TxHalfCpltCallback = pCallback;
450 break;
451
452 case HAL_USART_TX_COMPLETE_CB_ID :
453 husart->TxCpltCallback = pCallback;
454 break;
455
456 case HAL_USART_RX_HALFCOMPLETE_CB_ID :
457 husart->RxHalfCpltCallback = pCallback;
458 break;
459
460 case HAL_USART_RX_COMPLETE_CB_ID :
461 husart->RxCpltCallback = pCallback;
462 break;
463
464 case HAL_USART_TX_RX_COMPLETE_CB_ID :
465 husart->TxRxCpltCallback = pCallback;
466 break;
467
468 case HAL_USART_ERROR_CB_ID :
469 husart->ErrorCallback = pCallback;
470 break;
471
472 case HAL_USART_ABORT_COMPLETE_CB_ID :
473 husart->AbortCpltCallback = pCallback;
474 break;
475
476 case HAL_USART_RX_FIFO_FULL_CB_ID :
477 husart->RxFifoFullCallback = pCallback;
478 break;
479
480 case HAL_USART_TX_FIFO_EMPTY_CB_ID :
481 husart->TxFifoEmptyCallback = pCallback;
482 break;
483
484 case HAL_USART_MSPINIT_CB_ID :
485 husart->MspInitCallback = pCallback;
486 break;
487
488 case HAL_USART_MSPDEINIT_CB_ID :
489 husart->MspDeInitCallback = pCallback;
490 break;
491
492 default :
493 /* Update the error code */
494 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
495
496 /* Return error status */
497 status = HAL_ERROR;
498 break;
499 }
500 }
501 else if (husart->State == HAL_USART_STATE_RESET)
502 {
503 switch (CallbackID)
504 {
505 case HAL_USART_MSPINIT_CB_ID :
506 husart->MspInitCallback = pCallback;
507 break;
508
509 case HAL_USART_MSPDEINIT_CB_ID :
510 husart->MspDeInitCallback = pCallback;
511 break;
512
513 default :
514 /* Update the error code */
515 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
516
517 /* Return error status */
518 status = HAL_ERROR;
519 break;
520 }
521 }
522 else
523 {
524 /* Update the error code */
525 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
526
527 /* Return error status */
528 status = HAL_ERROR;
529 }
530
531 return status;
532 }
533
534 /**
535 * @brief Unregister an USART Callback
536 * USART callaback is redirected to the weak predefined callback
537 * @note The HAL_USART_UnRegisterCallback() may be called before HAL_USART_Init() in HAL_USART_STATE_RESET
538 * to un-register callbacks for HAL_USART_MSPINIT_CB_ID and HAL_USART_MSPDEINIT_CB_ID
539 * @param husart usart handle
540 * @param CallbackID ID of the callback to be unregistered
541 * This parameter can be one of the following values:
542 * @arg @ref HAL_USART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
543 * @arg @ref HAL_USART_TX_COMPLETE_CB_ID Tx Complete Callback ID
544 * @arg @ref HAL_USART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
545 * @arg @ref HAL_USART_RX_COMPLETE_CB_ID Rx Complete Callback ID
546 * @arg @ref HAL_USART_TX_RX_COMPLETE_CB_ID Rx Complete Callback ID
547 * @arg @ref HAL_USART_ERROR_CB_ID Error Callback ID
548 * @arg @ref HAL_USART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
549 * @arg @ref HAL_USART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
550 * @arg @ref HAL_USART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
551 * @arg @ref HAL_USART_MSPINIT_CB_ID MspInit Callback ID
552 * @arg @ref HAL_USART_MSPDEINIT_CB_ID MspDeInit Callback ID
553 * @retval HAL status
554 */
HAL_USART_UnRegisterCallback(USART_HandleTypeDef * husart,HAL_USART_CallbackIDTypeDef CallbackID)555 HAL_StatusTypeDef HAL_USART_UnRegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID)
556 {
557 HAL_StatusTypeDef status = HAL_OK;
558
559 if (HAL_USART_STATE_READY == husart->State)
560 {
561 switch (CallbackID)
562 {
563 case HAL_USART_TX_HALFCOMPLETE_CB_ID :
564 husart->TxHalfCpltCallback = HAL_USART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
565 break;
566
567 case HAL_USART_TX_COMPLETE_CB_ID :
568 husart->TxCpltCallback = HAL_USART_TxCpltCallback; /* Legacy weak TxCpltCallback */
569 break;
570
571 case HAL_USART_RX_HALFCOMPLETE_CB_ID :
572 husart->RxHalfCpltCallback = HAL_USART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
573 break;
574
575 case HAL_USART_RX_COMPLETE_CB_ID :
576 husart->RxCpltCallback = HAL_USART_RxCpltCallback; /* Legacy weak RxCpltCallback */
577 break;
578
579 case HAL_USART_TX_RX_COMPLETE_CB_ID :
580 husart->TxRxCpltCallback = HAL_USART_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */
581 break;
582
583 case HAL_USART_ERROR_CB_ID :
584 husart->ErrorCallback = HAL_USART_ErrorCallback; /* Legacy weak ErrorCallback */
585 break;
586
587 case HAL_USART_ABORT_COMPLETE_CB_ID :
588 husart->AbortCpltCallback = HAL_USART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
589 break;
590
591 case HAL_USART_RX_FIFO_FULL_CB_ID :
592 husart->RxFifoFullCallback = HAL_USARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */
593 break;
594
595 case HAL_USART_TX_FIFO_EMPTY_CB_ID :
596 husart->TxFifoEmptyCallback = HAL_USARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */
597 break;
598
599 case HAL_USART_MSPINIT_CB_ID :
600 husart->MspInitCallback = HAL_USART_MspInit; /* Legacy weak MspInitCallback */
601 break;
602
603 case HAL_USART_MSPDEINIT_CB_ID :
604 husart->MspDeInitCallback = HAL_USART_MspDeInit; /* Legacy weak MspDeInitCallback */
605 break;
606
607 default :
608 /* Update the error code */
609 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
610
611 /* Return error status */
612 status = HAL_ERROR;
613 break;
614 }
615 }
616 else if (HAL_USART_STATE_RESET == husart->State)
617 {
618 switch (CallbackID)
619 {
620 case HAL_USART_MSPINIT_CB_ID :
621 husart->MspInitCallback = HAL_USART_MspInit;
622 break;
623
624 case HAL_USART_MSPDEINIT_CB_ID :
625 husart->MspDeInitCallback = HAL_USART_MspDeInit;
626 break;
627
628 default :
629 /* Update the error code */
630 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
631
632 /* Return error status */
633 status = HAL_ERROR;
634 break;
635 }
636 }
637 else
638 {
639 /* Update the error code */
640 husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
641
642 /* Return error status */
643 status = HAL_ERROR;
644 }
645
646 return status;
647 }
648 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
649
650
651 /**
652 * @}
653 */
654
655 /** @defgroup USART_Exported_Functions_Group2 IO operation functions
656 * @brief USART Transmit and Receive functions
657 *
658 @verbatim
659 ===============================================================================
660 ##### IO operation functions #####
661 ===============================================================================
662 [..] This subsection provides a set of functions allowing to manage the USART synchronous
663 data transfers.
664
665 [..] The USART supports master mode only: it cannot receive or send data related to an input
666 clock (SCLK is always an output).
667
668 [..]
669
670 (#) There are two modes of transfer:
671 (++) Blocking mode: The communication is performed in polling mode.
672 The HAL status of all data processing is returned by the same function
673 after finishing transfer.
674 (++) No-Blocking mode: The communication is performed using Interrupts
675 or DMA, These API's return the HAL status.
676 The end of the data processing will be indicated through the
677 dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
678 using DMA mode.
679 The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() user callbacks
680 will be executed respectively at the end of the transmit or Receive process
681 The HAL_USART_ErrorCallback()user callback will be executed when a communication error is detected
682
683 (#) Blocking mode API's are :
684 (++) HAL_USART_Transmit() in simplex mode
685 (++) HAL_USART_Receive() in full duplex receive only
686 (++) HAL_USART_TransmitReceive() in full duplex mode
687
688 (#) Non-Blocking mode API's with Interrupt are :
689 (++) HAL_USART_Transmit_IT() in simplex mode
690 (++) HAL_USART_Receive_IT() in full duplex receive only
691 (++) HAL_USART_TransmitReceive_IT() in full duplex mode
692 (++) HAL_USART_IRQHandler()
693
694 (#) No-Blocking mode API's with DMA are :
695 (++) HAL_USART_Transmit_DMA() in simplex mode
696 (++) HAL_USART_Receive_DMA() in full duplex receive only
697 (++) HAL_USART_TransmitReceive_DMA() in full duplex mode
698 (++) HAL_USART_DMAPause()
699 (++) HAL_USART_DMAResume()
700 (++) HAL_USART_DMAStop()
701
702 (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
703 (++) HAL_USART_TxCpltCallback()
704 (++) HAL_USART_RxCpltCallback()
705 (++) HAL_USART_TxHalfCpltCallback()
706 (++) HAL_USART_RxHalfCpltCallback()
707 (++) HAL_USART_ErrorCallback()
708 (++) HAL_USART_TxRxCpltCallback()
709
710 (#) Non-Blocking mode transfers could be aborted using Abort API's :
711 (++) HAL_USART_Abort()
712 (++) HAL_USART_Abort_IT()
713
714 (#) For Abort services based on interrupts (HAL_USART_Abort_IT), a Abort Complete Callbacks is provided:
715 (++) HAL_USART_AbortCpltCallback()
716
717 (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
718 Errors are handled as follows :
719 (++) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
720 to be evaluated by user : this concerns Frame Error,
721 Parity Error or Noise Error in Interrupt mode reception .
722 Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify
723 error type, and HAL_USART_ErrorCallback() user callback is executed.
724 Transfer is kept ongoing on USART side.
725 If user wants to abort it, Abort services should be called by user.
726 (++) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
727 This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
728 Error code is set to allow user to identify error type,
729 and HAL_USART_ErrorCallback() user callback is executed.
730
731 @endverbatim
732 * @{
733 */
734
735 /**
736 * @brief Simplex send an amount of data in blocking mode.
737 * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
738 * the sent data is handled as a set of u16. In this case, Size must indicate the number
739 * of u16 provided through pTxData.
740 * @param husart USART handle.
741 * @param pTxData Pointer to data buffer (u8 or u16 data elements).
742 * @param Size Amount of data elements (u8 or u16) to be sent.
743 * @param Timeout Timeout duration.
744 * @retval HAL status
745 */
HAL_USART_Transmit(USART_HandleTypeDef * husart,const uint8_t * pTxData,uint16_t Size,uint32_t Timeout)746 HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size,
747 uint32_t Timeout)
748 {
749 const uint8_t *ptxdata8bits;
750 const uint16_t *ptxdata16bits;
751 uint32_t tickstart;
752
753 if (husart->State == HAL_USART_STATE_READY)
754 {
755 if ((pTxData == NULL) || (Size == 0U))
756 {
757 return HAL_ERROR;
758 }
759
760 /* Process Locked */
761 __HAL_LOCK(husart);
762
763 husart->ErrorCode = HAL_USART_ERROR_NONE;
764 husart->State = HAL_USART_STATE_BUSY_TX;
765
766 /* Init tickstart for timeout management */
767 tickstart = HAL_GetTick();
768
769 husart->TxXferSize = Size;
770 husart->TxXferCount = Size;
771
772 /* In case of 9bits/No Parity transfer, pTxData needs to be handled as a uint16_t pointer */
773 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
774 {
775 ptxdata8bits = NULL;
776 ptxdata16bits = (const uint16_t *) pTxData;
777 }
778 else
779 {
780 ptxdata8bits = pTxData;
781 ptxdata16bits = NULL;
782 }
783
784 /* Check the remaining data to be sent */
785 while (husart->TxXferCount > 0U)
786 {
787 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
788 {
789 return HAL_TIMEOUT;
790 }
791 if (ptxdata8bits == NULL)
792 {
793 husart->Instance->TDR = (uint16_t)(*ptxdata16bits & 0x01FFU);
794 ptxdata16bits++;
795 }
796 else
797 {
798 husart->Instance->TDR = (uint8_t)(*ptxdata8bits & 0xFFU);
799 ptxdata8bits++;
800 }
801
802 husart->TxXferCount--;
803 }
804
805 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
806 {
807 return HAL_TIMEOUT;
808 }
809
810 /* Clear Transmission Complete Flag */
811 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
812
813 /* Clear overrun flag and discard the received data */
814 __HAL_USART_CLEAR_OREFLAG(husart);
815 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
816 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
817
818 /* At end of Tx process, restore husart->State to Ready */
819 husart->State = HAL_USART_STATE_READY;
820
821 /* Process Unlocked */
822 __HAL_UNLOCK(husart);
823
824 return HAL_OK;
825 }
826 else
827 {
828 return HAL_BUSY;
829 }
830 }
831
832 /**
833 * @brief Receive an amount of data in blocking mode.
834 * @note To receive synchronous data, dummy data are simultaneously transmitted.
835 * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
836 * the received data is handled as a set of u16. In this case, Size must indicate the number
837 * of u16 available through pRxData.
838 * @param husart USART handle.
839 * @param pRxData Pointer to data buffer (u8 or u16 data elements).
840 * @param Size Amount of data elements (u8 or u16) to be received.
841 * @param Timeout Timeout duration.
842 * @retval HAL status
843 */
HAL_USART_Receive(USART_HandleTypeDef * husart,uint8_t * pRxData,uint16_t Size,uint32_t Timeout)844 HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
845 {
846 uint8_t *prxdata8bits;
847 uint16_t *prxdata16bits;
848 uint16_t uhMask;
849 uint32_t tickstart;
850
851 if (husart->State == HAL_USART_STATE_READY)
852 {
853 if ((pRxData == NULL) || (Size == 0U))
854 {
855 return HAL_ERROR;
856 }
857
858 /* Process Locked */
859 __HAL_LOCK(husart);
860
861 husart->ErrorCode = HAL_USART_ERROR_NONE;
862 husart->State = HAL_USART_STATE_BUSY_RX;
863
864 /* Init tickstart for timeout management */
865 tickstart = HAL_GetTick();
866
867 husart->RxXferSize = Size;
868 husart->RxXferCount = Size;
869
870 /* Computation of USART mask to apply to RDR register */
871 USART_MASK_COMPUTATION(husart);
872 uhMask = husart->Mask;
873
874 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
875 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
876 {
877 prxdata8bits = NULL;
878 prxdata16bits = (uint16_t *) pRxData;
879 }
880 else
881 {
882 prxdata8bits = pRxData;
883 prxdata16bits = NULL;
884 }
885
886 /* as long as data have to be received */
887 while (husart->RxXferCount > 0U)
888 {
889 if (husart->SlaveMode == USART_SLAVEMODE_DISABLE)
890 {
891 /* Wait until TXE flag is set to send dummy byte in order to generate the
892 * clock for the slave to send data.
893 * Whatever the frame length (7, 8 or 9-bit long), the same dummy value
894 * can be written for all the cases. */
895 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
896 {
897 return HAL_TIMEOUT;
898 }
899 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x0FF);
900 }
901
902 /* Wait for RXNE Flag */
903 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
904 {
905 return HAL_TIMEOUT;
906 }
907
908 if (prxdata8bits == NULL)
909 {
910 *prxdata16bits = (uint16_t)(husart->Instance->RDR & uhMask);
911 prxdata16bits++;
912 }
913 else
914 {
915 *prxdata8bits = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
916 prxdata8bits++;
917 }
918
919 husart->RxXferCount--;
920
921 }
922
923 /* Clear SPI slave underrun flag and discard transmit data */
924 if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
925 {
926 __HAL_USART_CLEAR_UDRFLAG(husart);
927 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
928 }
929
930 /* At end of Rx process, restore husart->State to Ready */
931 husart->State = HAL_USART_STATE_READY;
932
933 /* Process Unlocked */
934 __HAL_UNLOCK(husart);
935
936 return HAL_OK;
937 }
938 else
939 {
940 return HAL_BUSY;
941 }
942 }
943
944 /**
945 * @brief Full-Duplex Send and Receive an amount of data in blocking mode.
946 * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
947 * the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
948 * of u16 available through pTxData and through pRxData.
949 * @param husart USART handle.
950 * @param pTxData pointer to TX data buffer (u8 or u16 data elements).
951 * @param pRxData pointer to RX data buffer (u8 or u16 data elements).
952 * @param Size amount of data elements (u8 or u16) to be sent (same amount to be received).
953 * @param Timeout Timeout duration.
954 * @retval HAL status
955 */
HAL_USART_TransmitReceive(USART_HandleTypeDef * husart,const uint8_t * pTxData,uint8_t * pRxData,uint16_t Size,uint32_t Timeout)956 HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData,
957 uint16_t Size, uint32_t Timeout)
958 {
959 uint8_t *prxdata8bits;
960 uint16_t *prxdata16bits;
961 const uint8_t *ptxdata8bits;
962 const uint16_t *ptxdata16bits;
963 uint16_t uhMask;
964 uint16_t rxdatacount;
965 uint32_t tickstart;
966
967 if (husart->State == HAL_USART_STATE_READY)
968 {
969 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
970 {
971 return HAL_ERROR;
972 }
973
974 /* Process Locked */
975 __HAL_LOCK(husart);
976
977 husart->ErrorCode = HAL_USART_ERROR_NONE;
978 husart->State = HAL_USART_STATE_BUSY_RX;
979
980 /* Init tickstart for timeout management */
981 tickstart = HAL_GetTick();
982
983 husart->RxXferSize = Size;
984 husart->TxXferSize = Size;
985 husart->TxXferCount = Size;
986 husart->RxXferCount = Size;
987
988 /* Computation of USART mask to apply to RDR register */
989 USART_MASK_COMPUTATION(husart);
990 uhMask = husart->Mask;
991
992 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
993 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
994 {
995 prxdata8bits = NULL;
996 ptxdata8bits = NULL;
997 ptxdata16bits = (const uint16_t *) pTxData;
998 prxdata16bits = (uint16_t *) pRxData;
999 }
1000 else
1001 {
1002 prxdata8bits = pRxData;
1003 ptxdata8bits = pTxData;
1004 ptxdata16bits = NULL;
1005 prxdata16bits = NULL;
1006 }
1007
1008 if ((husart->TxXferCount == 0x01U) || (husart->SlaveMode == USART_SLAVEMODE_ENABLE))
1009 {
1010 /* Wait until TXE flag is set to send data */
1011 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
1012 {
1013 return HAL_TIMEOUT;
1014 }
1015 if (ptxdata8bits == NULL)
1016 {
1017 husart->Instance->TDR = (uint16_t)(*ptxdata16bits & uhMask);
1018 ptxdata16bits++;
1019 }
1020 else
1021 {
1022 husart->Instance->TDR = (uint8_t)(*ptxdata8bits & (uint8_t)(uhMask & 0xFFU));
1023 ptxdata8bits++;
1024 }
1025
1026 husart->TxXferCount--;
1027 }
1028
1029 /* Check the remain data to be sent */
1030 /* rxdatacount is a temporary variable for MISRAC2012-Rule-13.5 */
1031 rxdatacount = husart->RxXferCount;
1032 while ((husart->TxXferCount > 0U) || (rxdatacount > 0U))
1033 {
1034 if (husart->TxXferCount > 0U)
1035 {
1036 /* Wait until TXE flag is set to send data */
1037 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
1038 {
1039 return HAL_TIMEOUT;
1040 }
1041 if (ptxdata8bits == NULL)
1042 {
1043 husart->Instance->TDR = (uint16_t)(*ptxdata16bits & uhMask);
1044 ptxdata16bits++;
1045 }
1046 else
1047 {
1048 husart->Instance->TDR = (uint8_t)(*ptxdata8bits & (uint8_t)(uhMask & 0xFFU));
1049 ptxdata8bits++;
1050 }
1051
1052 husart->TxXferCount--;
1053 }
1054
1055 if (husart->RxXferCount > 0U)
1056 {
1057 /* Wait for RXNE Flag */
1058 if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
1059 {
1060 return HAL_TIMEOUT;
1061 }
1062
1063 if (prxdata8bits == NULL)
1064 {
1065 *prxdata16bits = (uint16_t)(husart->Instance->RDR & uhMask);
1066 prxdata16bits++;
1067 }
1068 else
1069 {
1070 *prxdata8bits = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
1071 prxdata8bits++;
1072 }
1073
1074 husart->RxXferCount--;
1075 }
1076 rxdatacount = husart->RxXferCount;
1077 }
1078
1079 /* At end of TxRx process, restore husart->State to Ready */
1080 husart->State = HAL_USART_STATE_READY;
1081
1082 /* Process Unlocked */
1083 __HAL_UNLOCK(husart);
1084
1085 return HAL_OK;
1086 }
1087 else
1088 {
1089 return HAL_BUSY;
1090 }
1091 }
1092
1093 /**
1094 * @brief Send an amount of data in interrupt mode.
1095 * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1096 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1097 * of u16 provided through pTxData.
1098 * @param husart USART handle.
1099 * @param pTxData pointer to data buffer (u8 or u16 data elements).
1100 * @param Size amount of data elements (u8 or u16) to be sent.
1101 * @retval HAL status
1102 */
HAL_USART_Transmit_IT(USART_HandleTypeDef * husart,const uint8_t * pTxData,uint16_t Size)1103 HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size)
1104 {
1105 if (husart->State == HAL_USART_STATE_READY)
1106 {
1107 if ((pTxData == NULL) || (Size == 0U))
1108 {
1109 return HAL_ERROR;
1110 }
1111
1112 /* Process Locked */
1113 __HAL_LOCK(husart);
1114
1115 husart->pTxBuffPtr = pTxData;
1116 husart->TxXferSize = Size;
1117 husart->TxXferCount = Size;
1118 husart->TxISR = NULL;
1119
1120 husart->ErrorCode = HAL_USART_ERROR_NONE;
1121 husart->State = HAL_USART_STATE_BUSY_TX;
1122
1123 /* The USART Error Interrupts: (Frame error, noise error, overrun error)
1124 are not managed by the USART Transmit Process to avoid the overrun interrupt
1125 when the usart mode is configured for transmit and receive "USART_MODE_TX_RX"
1126 to benefit for the frame error and noise interrupts the usart mode should be
1127 configured only for transmit "USART_MODE_TX" */
1128
1129 /* Configure Tx interrupt processing */
1130 if (husart->FifoMode == USART_FIFOMODE_ENABLE)
1131 {
1132 /* Set the Tx ISR function pointer according to the data word length */
1133 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1134 {
1135 husart->TxISR = USART_TxISR_16BIT_FIFOEN;
1136 }
1137 else
1138 {
1139 husart->TxISR = USART_TxISR_8BIT_FIFOEN;
1140 }
1141
1142 /* Process Unlocked */
1143 __HAL_UNLOCK(husart);
1144
1145 /* Enable the TX FIFO threshold interrupt */
1146 __HAL_USART_ENABLE_IT(husart, USART_IT_TXFT);
1147 }
1148 else
1149 {
1150 /* Set the Tx ISR function pointer according to the data word length */
1151 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1152 {
1153 husart->TxISR = USART_TxISR_16BIT;
1154 }
1155 else
1156 {
1157 husart->TxISR = USART_TxISR_8BIT;
1158 }
1159
1160 /* Process Unlocked */
1161 __HAL_UNLOCK(husart);
1162
1163 /* Enable the USART Transmit Data Register Empty Interrupt */
1164 __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
1165 }
1166
1167 return HAL_OK;
1168 }
1169 else
1170 {
1171 return HAL_BUSY;
1172 }
1173 }
1174
1175 /**
1176 * @brief Receive an amount of data in interrupt mode.
1177 * @note To receive synchronous data, dummy data are simultaneously transmitted.
1178 * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1179 * the received data is handled as a set of u16. In this case, Size must indicate the number
1180 * of u16 available through pRxData.
1181 * @param husart USART handle.
1182 * @param pRxData pointer to data buffer (u8 or u16 data elements).
1183 * @param Size amount of data elements (u8 or u16) to be received.
1184 * @retval HAL status
1185 */
HAL_USART_Receive_IT(USART_HandleTypeDef * husart,uint8_t * pRxData,uint16_t Size)1186 HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
1187 {
1188 uint16_t nb_dummy_data;
1189
1190 if (husart->State == HAL_USART_STATE_READY)
1191 {
1192 if ((pRxData == NULL) || (Size == 0U))
1193 {
1194 return HAL_ERROR;
1195 }
1196
1197 /* Process Locked */
1198 __HAL_LOCK(husart);
1199
1200 husart->pRxBuffPtr = pRxData;
1201 husart->RxXferSize = Size;
1202 husart->RxXferCount = Size;
1203 husart->RxISR = NULL;
1204
1205 USART_MASK_COMPUTATION(husart);
1206
1207 husart->ErrorCode = HAL_USART_ERROR_NONE;
1208 husart->State = HAL_USART_STATE_BUSY_RX;
1209
1210 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1211 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1212
1213 /* Configure Rx interrupt processing */
1214 if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess))
1215 {
1216 /* Set the Rx ISR function pointer according to the data word length */
1217 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1218 {
1219 husart->RxISR = USART_RxISR_16BIT_FIFOEN;
1220 }
1221 else
1222 {
1223 husart->RxISR = USART_RxISR_8BIT_FIFOEN;
1224 }
1225
1226 /* Process Unlocked */
1227 __HAL_UNLOCK(husart);
1228
1229 /* Enable the USART Parity Error interrupt and RX FIFO Threshold interrupt */
1230 if (husart->Init.Parity != USART_PARITY_NONE)
1231 {
1232 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1233 }
1234 SET_BIT(husart->Instance->CR3, USART_CR3_RXFTIE);
1235 }
1236 else
1237 {
1238 /* Set the Rx ISR function pointer according to the data word length */
1239 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1240 {
1241 husart->RxISR = USART_RxISR_16BIT;
1242 }
1243 else
1244 {
1245 husart->RxISR = USART_RxISR_8BIT;
1246 }
1247
1248 /* Process Unlocked */
1249 __HAL_UNLOCK(husart);
1250
1251 /* Enable the USART Parity Error and Data Register not empty Interrupts */
1252 if (husart->Init.Parity != USART_PARITY_NONE)
1253 {
1254 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
1255 }
1256 else
1257 {
1258 SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
1259 }
1260 }
1261
1262 if (husart->SlaveMode == USART_SLAVEMODE_DISABLE)
1263 {
1264 /* Send dummy data in order to generate the clock for the Slave to send the next data.
1265 When FIFO mode is disabled only one data must be transferred.
1266 When FIFO mode is enabled data must be transmitted until the RX FIFO reaches its threshold.
1267 */
1268 if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess))
1269 {
1270 for (nb_dummy_data = husart->NbRxDataToProcess ; nb_dummy_data > 0U ; nb_dummy_data--)
1271 {
1272 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
1273 }
1274 }
1275 else
1276 {
1277 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
1278 }
1279 }
1280
1281 return HAL_OK;
1282 }
1283 else
1284 {
1285 return HAL_BUSY;
1286 }
1287 }
1288
1289 /**
1290 * @brief Full-Duplex Send and Receive an amount of data in interrupt mode.
1291 * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1292 * the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
1293 * of u16 available through pTxData and through pRxData.
1294 * @param husart USART handle.
1295 * @param pTxData pointer to TX data buffer (u8 or u16 data elements).
1296 * @param pRxData pointer to RX data buffer (u8 or u16 data elements).
1297 * @param Size amount of data elements (u8 or u16) to be sent (same amount to be received).
1298 * @retval HAL status
1299 */
HAL_USART_TransmitReceive_IT(USART_HandleTypeDef * husart,const uint8_t * pTxData,uint8_t * pRxData,uint16_t Size)1300 HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData,
1301 uint16_t Size)
1302 {
1303
1304 if (husart->State == HAL_USART_STATE_READY)
1305 {
1306 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1307 {
1308 return HAL_ERROR;
1309 }
1310
1311 /* Process Locked */
1312 __HAL_LOCK(husart);
1313
1314 husart->pRxBuffPtr = pRxData;
1315 husart->RxXferSize = Size;
1316 husart->RxXferCount = Size;
1317 husart->pTxBuffPtr = pTxData;
1318 husart->TxXferSize = Size;
1319 husart->TxXferCount = Size;
1320
1321 /* Computation of USART mask to apply to RDR register */
1322 USART_MASK_COMPUTATION(husart);
1323
1324 husart->ErrorCode = HAL_USART_ERROR_NONE;
1325 husart->State = HAL_USART_STATE_BUSY_TX_RX;
1326
1327 /* Configure TxRx interrupt processing */
1328 if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess))
1329 {
1330 /* Set the Rx ISR function pointer according to the data word length */
1331 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1332 {
1333 husart->TxISR = USART_TxISR_16BIT_FIFOEN;
1334 husart->RxISR = USART_RxISR_16BIT_FIFOEN;
1335 }
1336 else
1337 {
1338 husart->TxISR = USART_TxISR_8BIT_FIFOEN;
1339 husart->RxISR = USART_RxISR_8BIT_FIFOEN;
1340 }
1341
1342 /* Process Locked */
1343 __HAL_UNLOCK(husart);
1344
1345 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1346 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1347
1348 if (husart->Init.Parity != USART_PARITY_NONE)
1349 {
1350 /* Enable the USART Parity Error interrupt */
1351 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1352 }
1353
1354 /* Enable the TX and RX FIFO Threshold interrupts */
1355 SET_BIT(husart->Instance->CR3, (USART_CR3_TXFTIE | USART_CR3_RXFTIE));
1356 }
1357 else
1358 {
1359 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1360 {
1361 husart->TxISR = USART_TxISR_16BIT;
1362 husart->RxISR = USART_RxISR_16BIT;
1363 }
1364 else
1365 {
1366 husart->TxISR = USART_TxISR_8BIT;
1367 husart->RxISR = USART_RxISR_8BIT;
1368 }
1369
1370 /* Process Locked */
1371 __HAL_UNLOCK(husart);
1372
1373 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1374 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1375
1376 /* Enable the USART Parity Error and USART Data Register not empty Interrupts */
1377 if (husart->Init.Parity != USART_PARITY_NONE)
1378 {
1379 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
1380 }
1381 else
1382 {
1383 SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
1384 }
1385
1386 /* Enable the USART Transmit Data Register Empty Interrupt */
1387 SET_BIT(husart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
1388 }
1389
1390 return HAL_OK;
1391 }
1392 else
1393 {
1394 return HAL_BUSY;
1395 }
1396 }
1397
1398 #if defined(HAL_DMA_MODULE_ENABLED)
1399 /**
1400 * @brief Send an amount of data in DMA mode.
1401 * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1402 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1403 * of u16 provided through pTxData.
1404 * @param husart USART handle.
1405 * @param pTxData pointer to data buffer (u8 or u16 data elements).
1406 * @param Size amount of data elements (u8 or u16) to be sent.
1407 * @retval HAL status
1408 */
HAL_USART_Transmit_DMA(USART_HandleTypeDef * husart,const uint8_t * pTxData,uint16_t Size)1409 HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size)
1410 {
1411 HAL_StatusTypeDef status = HAL_OK;
1412 const uint32_t *tmp;
1413 uint16_t nbByte = Size;
1414
1415 if (husart->State == HAL_USART_STATE_READY)
1416 {
1417 if ((pTxData == NULL) || (Size == 0U))
1418 {
1419 return HAL_ERROR;
1420 }
1421
1422 /* Process Locked */
1423 __HAL_LOCK(husart);
1424
1425 husart->pTxBuffPtr = pTxData;
1426 husart->TxXferSize = Size;
1427 husart->TxXferCount = Size;
1428
1429 husart->ErrorCode = HAL_USART_ERROR_NONE;
1430 husart->State = HAL_USART_STATE_BUSY_TX;
1431
1432 if (husart->hdmatx != NULL)
1433 {
1434 /* Set the USART DMA transfer complete callback */
1435 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
1436
1437 /* Set the USART DMA Half transfer complete callback */
1438 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
1439
1440 /* Set the DMA error callback */
1441 husart->hdmatx->XferErrorCallback = USART_DMAError;
1442
1443 /* In case of 9bits/No Parity transfer, pTxData buffer provided as input parameter
1444 should be aligned on a u16 frontier, so nbByte should be equal to Size multiplied by 2 */
1445 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1446 {
1447 nbByte = Size * 2U;
1448 }
1449
1450 tmp = (const uint32_t *)&pTxData;
1451
1452 /* Check linked list mode */
1453 if ((husart->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1454 {
1455 if ((husart->hdmatx->LinkedListQueue != NULL) && (husart->hdmatx->LinkedListQueue->Head != NULL))
1456 {
1457 /* Set DMA data size */
1458 husart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = nbByte;
1459
1460 /* Set DMA source address */
1461 husart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = *(const uint32_t *)tmp;
1462
1463 /* Set DMA destination address */
1464 husart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] =
1465 (uint32_t)&husart->Instance->TDR;
1466
1467 /* Enable the USART transmit DMA channel */
1468 status = HAL_DMAEx_List_Start_IT(husart->hdmatx);
1469 }
1470 else
1471 {
1472 /* Update status */
1473 status = HAL_ERROR;
1474 }
1475 }
1476 else
1477 {
1478 /* Enable the USART transmit DMA channel */
1479 status = HAL_DMA_Start_IT(husart->hdmatx, *(const uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, nbByte);
1480 }
1481 }
1482
1483 if (status == HAL_OK)
1484 {
1485 /* Clear the TC flag in the ICR register */
1486 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
1487
1488 /* Process Unlocked */
1489 __HAL_UNLOCK(husart);
1490
1491 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1492 in the USART CR3 register */
1493 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1494
1495 return HAL_OK;
1496 }
1497 else
1498 {
1499 /* Set error code to DMA */
1500 husart->ErrorCode = HAL_USART_ERROR_DMA;
1501
1502 /* Process Unlocked */
1503 __HAL_UNLOCK(husart);
1504
1505 /* Restore husart->State to ready */
1506 husart->State = HAL_USART_STATE_READY;
1507
1508 return HAL_ERROR;
1509 }
1510 }
1511 else
1512 {
1513 return HAL_BUSY;
1514 }
1515 }
1516
1517 /**
1518 * @brief Receive an amount of data in DMA mode.
1519 * @note When the USART parity is enabled (PCE = 1), the received data contain
1520 * the parity bit (MSB position).
1521 * @note The USART DMA transmit channel must be configured in order to generate the clock for the slave.
1522 * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1523 * the received data is handled as a set of u16. In this case, Size must indicate the number
1524 * of u16 available through pRxData.
1525 * @param husart USART handle.
1526 * @param pRxData pointer to data buffer (u8 or u16 data elements).
1527 * @param Size amount of data elements (u8 or u16) to be received.
1528 * @retval HAL status
1529 */
HAL_USART_Receive_DMA(USART_HandleTypeDef * husart,uint8_t * pRxData,uint16_t Size)1530 HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
1531 {
1532 HAL_StatusTypeDef status = HAL_OK;
1533 uint32_t *tmp = (uint32_t *)&pRxData;
1534 uint16_t nbByte = Size;
1535
1536 /* Check that a Rx process is not already ongoing */
1537 if (husart->State == HAL_USART_STATE_READY)
1538 {
1539 if ((pRxData == NULL) || (Size == 0U))
1540 {
1541 return HAL_ERROR;
1542 }
1543
1544 /* Process Locked */
1545 __HAL_LOCK(husart);
1546
1547 husart->pRxBuffPtr = pRxData;
1548 husart->RxXferSize = Size;
1549 husart->pTxBuffPtr = pRxData;
1550 husart->TxXferSize = Size;
1551
1552 husart->ErrorCode = HAL_USART_ERROR_NONE;
1553 husart->State = HAL_USART_STATE_BUSY_RX;
1554
1555 if (husart->hdmarx != NULL)
1556 {
1557 /* Set the USART DMA Rx transfer complete callback */
1558 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
1559
1560 /* Set the USART DMA Half transfer complete callback */
1561 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
1562
1563 /* Set the USART DMA Rx transfer error callback */
1564 husart->hdmarx->XferErrorCallback = USART_DMAError;
1565
1566 /* In case of 9bits/No Parity transfer, pTxData buffer provided as input parameter
1567 should be aligned on a u16 frontier, so nbByte should be equal to Size multiplied by 2 */
1568 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1569 {
1570 nbByte = Size * 2U;
1571 }
1572
1573 /* Check linked list mode */
1574 if ((husart->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1575 {
1576 if ((husart->hdmarx->LinkedListQueue != NULL) && (husart->hdmarx->LinkedListQueue->Head != NULL))
1577 {
1578 /* Set DMA data size */
1579 husart->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = nbByte;
1580
1581 /* Set DMA source address */
1582 husart->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] =
1583 (uint32_t)&husart->Instance->RDR;
1584
1585 /* Set DMA destination address */
1586 husart->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = *(uint32_t *)tmp;
1587
1588 /* Enable the USART receive DMA channel */
1589 status = HAL_DMAEx_List_Start_IT(husart->hdmarx);
1590 }
1591 else
1592 {
1593 /* Update status */
1594 status = HAL_ERROR;
1595 }
1596 }
1597 else
1598 {
1599 /* Enable the USART receive DMA channel */
1600 status = HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t *)tmp, nbByte);
1601 }
1602 }
1603
1604 if ((status == HAL_OK) &&
1605 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
1606 {
1607 /* Enable the USART transmit DMA channel: the transmit channel is used in order
1608 to generate in the non-blocking mode the clock to the slave device,
1609 this mode isn't a simplex receive mode but a full-duplex receive mode */
1610
1611 /* Set the USART DMA Tx Complete and Error callback to Null */
1612 if (husart->hdmatx != NULL)
1613 {
1614 husart->hdmatx->XferErrorCallback = NULL;
1615 husart->hdmatx->XferHalfCpltCallback = NULL;
1616 husart->hdmatx->XferCpltCallback = NULL;
1617
1618 /* Check linked list mode */
1619 if ((husart->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1620 {
1621 if ((husart->hdmatx->LinkedListQueue != NULL) && (husart->hdmatx->LinkedListQueue->Head != NULL))
1622 {
1623 /* Set DMA data size */
1624 husart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = nbByte;
1625
1626 /* Set DMA source address */
1627 husart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = *(uint32_t *)tmp;
1628
1629 /* Set DMA destination address */
1630 husart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] =
1631 (uint32_t)&husart->Instance->TDR;
1632
1633 /* Enable the USART transmit DMA channel */
1634 status = HAL_DMAEx_List_Start_IT(husart->hdmatx);
1635 }
1636 else
1637 {
1638 /* Update status */
1639 status = HAL_ERROR;
1640 }
1641 }
1642 else
1643 {
1644 status = HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, nbByte);
1645 }
1646 }
1647 }
1648
1649 if (status == HAL_OK)
1650 {
1651 /* Process Unlocked */
1652 __HAL_UNLOCK(husart);
1653
1654 if (husart->Init.Parity != USART_PARITY_NONE)
1655 {
1656 /* Enable the USART Parity Error Interrupt */
1657 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1658 }
1659
1660 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1661 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1662
1663 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1664 in the USART CR3 register */
1665 SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1666
1667 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1668 in the USART CR3 register */
1669 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1670
1671 return HAL_OK;
1672 }
1673 else
1674 {
1675 if ((husart->hdmarx != NULL) && ((husart->hdmarx->Mode & DMA_LINKEDLIST) != DMA_LINKEDLIST))
1676 {
1677 status = HAL_DMA_Abort(husart->hdmarx);
1678 }
1679
1680 /* No need to check on error code */
1681 UNUSED(status);
1682
1683 /* Set error code to DMA */
1684 husart->ErrorCode = HAL_USART_ERROR_DMA;
1685
1686 /* Process Unlocked */
1687 __HAL_UNLOCK(husart);
1688
1689 /* Restore husart->State to ready */
1690 husart->State = HAL_USART_STATE_READY;
1691
1692 return HAL_ERROR;
1693 }
1694 }
1695 else
1696 {
1697 return HAL_BUSY;
1698 }
1699 }
1700
1701 /**
1702 * @brief Full-Duplex Transmit Receive an amount of data in non-blocking mode.
1703 * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
1704 * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1705 * the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
1706 * of u16 available through pTxData and through pRxData.
1707 * @param husart USART handle.
1708 * @param pTxData pointer to TX data buffer (u8 or u16 data elements).
1709 * @param pRxData pointer to RX data buffer (u8 or u16 data elements).
1710 * @param Size amount of data elements (u8 or u16) to be received/sent.
1711 * @retval HAL status
1712 */
HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef * husart,const uint8_t * pTxData,uint8_t * pRxData,uint16_t Size)1713 HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData,
1714 uint16_t Size)
1715 {
1716 HAL_StatusTypeDef status;
1717 const uint32_t *tmp;
1718 uint16_t nbByte = Size;
1719
1720 if (husart->State == HAL_USART_STATE_READY)
1721 {
1722 if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1723 {
1724 return HAL_ERROR;
1725 }
1726
1727 /* Process Locked */
1728 __HAL_LOCK(husart);
1729
1730 husart->pRxBuffPtr = pRxData;
1731 husart->RxXferSize = Size;
1732 husart->pTxBuffPtr = pTxData;
1733 husart->TxXferSize = Size;
1734
1735 husart->ErrorCode = HAL_USART_ERROR_NONE;
1736 husart->State = HAL_USART_STATE_BUSY_TX_RX;
1737
1738 if ((husart->hdmarx != NULL) && (husart->hdmatx != NULL))
1739 {
1740 /* Set the USART DMA Rx transfer complete callback */
1741 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
1742
1743 /* Set the USART DMA Half transfer complete callback */
1744 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
1745
1746 /* Set the USART DMA Tx transfer complete callback */
1747 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
1748
1749 /* Set the USART DMA Half transfer complete callback */
1750 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
1751
1752 /* Set the USART DMA Tx transfer error callback */
1753 husart->hdmatx->XferErrorCallback = USART_DMAError;
1754
1755 /* Set the USART DMA Rx transfer error callback */
1756 husart->hdmarx->XferErrorCallback = USART_DMAError;
1757
1758 /* In case of 9bits/No Parity transfer, pTxData buffer provided as input parameter
1759 should be aligned on a u16 frontier, so nbByte should be equal to Size multiplied by 2 */
1760 if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1761 {
1762 nbByte = Size * 2U;
1763 }
1764
1765 /* Check linked list mode */
1766 tmp = (uint32_t *)&pRxData;
1767 if ((husart->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1768 {
1769 if ((husart->hdmarx->LinkedListQueue != NULL) && (husart->hdmarx->LinkedListQueue->Head != NULL))
1770 {
1771 /* Set DMA data size */
1772 husart->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = nbByte;
1773
1774 /* Set DMA source address */
1775 husart->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] =
1776 (uint32_t)&husart->Instance->RDR;
1777
1778 /* Set DMA destination address */
1779 husart->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = *(const uint32_t *)tmp;
1780
1781 /* Enable the USART receive DMA channel */
1782 status = HAL_DMAEx_List_Start_IT(husart->hdmarx);
1783 }
1784 else
1785 {
1786 /* Update status */
1787 status = HAL_ERROR;
1788 }
1789 }
1790 else
1791 {
1792 /* Enable the USART receive DMA channel */
1793 status = HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(const uint32_t *)tmp, nbByte);
1794 }
1795
1796 /* Enable the USART transmit DMA channel */
1797 if (status == HAL_OK)
1798 {
1799 tmp = (const uint32_t *)&pTxData;
1800
1801 /* Check linked list mode */
1802 if ((husart->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1803 {
1804 if ((husart->hdmatx->LinkedListQueue != NULL) && (husart->hdmatx->LinkedListQueue->Head != NULL))
1805 {
1806 /* Set DMA data size */
1807 husart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = nbByte;
1808
1809 /* Set DMA source address */
1810 husart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = *(const uint32_t *)tmp;
1811
1812 /* Set DMA destination address */
1813 husart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] =
1814 (uint32_t)&husart->Instance->TDR;
1815
1816 /* Enable the USART transmit DMA channel */
1817 status = HAL_DMAEx_List_Start_IT(husart->hdmatx);
1818 }
1819 else
1820 {
1821 /* Update status */
1822 status = HAL_ERROR;
1823 }
1824 }
1825 else
1826 {
1827 status = HAL_DMA_Start_IT(husart->hdmatx, *(const uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, nbByte);
1828 }
1829 }
1830 }
1831 else
1832 {
1833 status = HAL_ERROR;
1834 }
1835
1836 if (status == HAL_OK)
1837 {
1838 /* Process Unlocked */
1839 __HAL_UNLOCK(husart);
1840
1841 if (husart->Init.Parity != USART_PARITY_NONE)
1842 {
1843 /* Enable the USART Parity Error Interrupt */
1844 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1845 }
1846
1847 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1848 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1849
1850 /* Clear the TC flag in the ICR register */
1851 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
1852
1853 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1854 in the USART CR3 register */
1855 SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1856
1857 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1858 in the USART CR3 register */
1859 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1860
1861 return HAL_OK;
1862 }
1863 else
1864 {
1865 if ((husart->hdmarx != NULL) && ((husart->hdmarx->Mode & DMA_LINKEDLIST) != DMA_LINKEDLIST))
1866 {
1867 status = HAL_DMA_Abort(husart->hdmarx);
1868 }
1869
1870 /* No need to check on error code */
1871 UNUSED(status);
1872
1873 /* Set error code to DMA */
1874 husart->ErrorCode = HAL_USART_ERROR_DMA;
1875
1876 /* Process Unlocked */
1877 __HAL_UNLOCK(husart);
1878
1879 /* Restore husart->State to ready */
1880 husart->State = HAL_USART_STATE_READY;
1881
1882 return HAL_ERROR;
1883 }
1884 }
1885 else
1886 {
1887 return HAL_BUSY;
1888 }
1889 }
1890
1891 /**
1892 * @brief Pause the DMA Transfer.
1893 * @param husart USART handle.
1894 * @retval HAL status
1895 */
HAL_USART_DMAPause(USART_HandleTypeDef * husart)1896 HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart)
1897 {
1898 const HAL_USART_StateTypeDef state = husart->State;
1899
1900 /* Process Locked */
1901 __HAL_LOCK(husart);
1902
1903 if ((HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)) &&
1904 (state == HAL_USART_STATE_BUSY_TX))
1905 {
1906 /* Suspend the USART DMA Tx channel : use blocking DMA Suspend API (no callback) */
1907 if (husart->hdmatx != NULL)
1908 {
1909 /* Set the USART DMA Suspend callback to Null.
1910 No call back execution at end of DMA Suspend procedure */
1911 husart->hdmatx->XferSuspendCallback = NULL;
1912
1913 if (HAL_DMAEx_Suspend(husart->hdmatx) != HAL_OK)
1914 {
1915 if (HAL_DMA_GetError(husart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1916 {
1917 /* Set error code to DMA */
1918 husart->ErrorCode = HAL_USART_ERROR_DMA;
1919
1920 return HAL_TIMEOUT;
1921 }
1922 }
1923 }
1924 }
1925 else if ((state == HAL_USART_STATE_BUSY_RX) ||
1926 (state == HAL_USART_STATE_BUSY_TX_RX))
1927 {
1928 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
1929 CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1930 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
1931
1932 /* Set the USART DMA Suspend callback to Null.
1933 No call back execution at end of DMA Suspend procedure */
1934 husart->hdmarx->XferSuspendCallback = NULL;
1935
1936 if (HAL_DMAEx_Suspend(husart->hdmarx) != HAL_OK)
1937 {
1938 if (HAL_DMA_GetError(husart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1939 {
1940 /* Set error code to DMA */
1941 husart->ErrorCode = HAL_USART_ERROR_DMA;
1942
1943 return HAL_TIMEOUT;
1944 }
1945 }
1946
1947 if (state == HAL_USART_STATE_BUSY_TX_RX)
1948 {
1949 /* Set the USART DMA Suspend callback to Null.
1950 No call back execution at end of DMA Suspend procedure */
1951 husart->hdmatx->XferSuspendCallback = NULL;
1952
1953 if (HAL_DMAEx_Suspend(husart->hdmatx) != HAL_OK)
1954 {
1955 if (HAL_DMA_GetError(husart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1956 {
1957 /* Set error code to DMA */
1958 husart->ErrorCode = HAL_USART_ERROR_DMA;
1959
1960 return HAL_TIMEOUT;
1961 }
1962 }
1963 }
1964 }
1965 else
1966 {
1967 /* Nothing to do */
1968 }
1969
1970 /* Process Unlocked */
1971 __HAL_UNLOCK(husart);
1972
1973 return HAL_OK;
1974 }
1975
1976 /**
1977 * @brief Resume the DMA Transfer.
1978 * @param husart USART handle.
1979 * @retval HAL status
1980 */
HAL_USART_DMAResume(USART_HandleTypeDef * husart)1981 HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart)
1982 {
1983 const HAL_USART_StateTypeDef state = husart->State;
1984
1985 /* Process Locked */
1986 __HAL_LOCK(husart);
1987
1988 if (state == HAL_USART_STATE_BUSY_TX)
1989 {
1990 /* Resume the USART DMA Tx channel */
1991 if (husart->hdmatx != NULL)
1992 {
1993 if (HAL_DMAEx_Resume(husart->hdmatx) != HAL_OK)
1994 {
1995 /* Set error code to DMA */
1996 husart->ErrorCode = HAL_USART_ERROR_DMA;
1997
1998 return HAL_ERROR;
1999 }
2000 }
2001 }
2002 else if ((state == HAL_USART_STATE_BUSY_RX) ||
2003 (state == HAL_USART_STATE_BUSY_TX_RX))
2004 {
2005 /* Clear the Overrun flag before resuming the Rx transfer*/
2006 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF);
2007
2008 /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */
2009 if (husart->Init.Parity != USART_PARITY_NONE)
2010 {
2011 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
2012 }
2013 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
2014
2015 /* Resume the USART DMA Rx channel */
2016 if (husart->hdmarx != NULL)
2017 {
2018 if (HAL_DMAEx_Resume(husart->hdmarx) != HAL_OK)
2019 {
2020 /* Set error code to DMA */
2021 husart->ErrorCode = HAL_USART_ERROR_DMA;
2022
2023 return HAL_ERROR;
2024 }
2025 }
2026
2027 if (state == HAL_USART_STATE_BUSY_TX_RX)
2028 {
2029 /* Resume the USART DMA Tx channel */
2030 if (husart->hdmatx != NULL)
2031 {
2032 if (HAL_DMAEx_Resume(husart->hdmatx) != HAL_OK)
2033 {
2034 /* Set error code to DMA */
2035 husart->ErrorCode = HAL_USART_ERROR_DMA;
2036
2037 return HAL_ERROR;
2038 }
2039 }
2040 }
2041 }
2042 else
2043 {
2044 /* Nothing to do */
2045 }
2046
2047 /* Process Unlocked */
2048 __HAL_UNLOCK(husart);
2049
2050 return HAL_OK;
2051 }
2052
2053 /**
2054 * @brief Stop the DMA Transfer.
2055 * @param husart USART handle.
2056 * @retval HAL status
2057 */
HAL_USART_DMAStop(USART_HandleTypeDef * husart)2058 HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart)
2059 {
2060 /* The Lock is not implemented on this API to allow the user application
2061 to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback() /
2062 HAL_USART_TxHalfCpltCallback / HAL_USART_RxHalfCpltCallback:
2063 indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
2064 interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
2065 the stream and the corresponding call back is executed. */
2066
2067 /* Disable the USART Tx/Rx DMA requests */
2068 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
2069 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
2070
2071 /* Abort the USART DMA tx channel */
2072 if (husart->hdmatx != NULL)
2073 {
2074 if (HAL_DMA_Abort(husart->hdmatx) != HAL_OK)
2075 {
2076 if (HAL_DMA_GetError(husart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
2077 {
2078 /* Set error code to DMA */
2079 husart->ErrorCode = HAL_USART_ERROR_DMA;
2080
2081 return HAL_TIMEOUT;
2082 }
2083 }
2084 }
2085 /* Abort the USART DMA rx channel */
2086 if (husart->hdmarx != NULL)
2087 {
2088 if (HAL_DMA_Abort(husart->hdmarx) != HAL_OK)
2089 {
2090 if (HAL_DMA_GetError(husart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
2091 {
2092 /* Set error code to DMA */
2093 husart->ErrorCode = HAL_USART_ERROR_DMA;
2094
2095 return HAL_TIMEOUT;
2096 }
2097 }
2098 }
2099
2100 USART_EndTransfer(husart);
2101 husart->State = HAL_USART_STATE_READY;
2102
2103 return HAL_OK;
2104 }
2105 #endif /* HAL_DMA_MODULE_ENABLED */
2106
2107 /**
2108 * @brief Abort ongoing transfers (blocking mode).
2109 * @param husart USART handle.
2110 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
2111 * This procedure performs following operations :
2112 * - Disable USART Interrupts (Tx and Rx)
2113 * - Disable the DMA transfer in the peripheral register (if enabled)
2114 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
2115 * - Set handle State to READY
2116 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
2117 * @retval HAL status
2118 */
HAL_USART_Abort(USART_HandleTypeDef * husart)2119 HAL_StatusTypeDef HAL_USART_Abort(USART_HandleTypeDef *husart)
2120 {
2121 /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */
2122 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE |
2123 USART_CR1_TCIE));
2124 CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
2125
2126 #if defined(HAL_DMA_MODULE_ENABLED)
2127 /* Abort the USART DMA Tx channel if enabled */
2128 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
2129 {
2130 /* Disable the USART DMA Tx request if enabled */
2131 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
2132
2133 /* Abort the USART DMA Tx channel : use blocking DMA Abort API (no callback) */
2134 if (husart->hdmatx != NULL)
2135 {
2136 /* Set the USART DMA Abort callback to Null.
2137 No call back execution at end of DMA abort procedure */
2138 husart->hdmatx->XferAbortCallback = NULL;
2139
2140 if (HAL_DMA_Abort(husart->hdmatx) != HAL_OK)
2141 {
2142 if (HAL_DMA_GetError(husart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
2143 {
2144 /* Set error code to DMA */
2145 husart->ErrorCode = HAL_USART_ERROR_DMA;
2146
2147 return HAL_TIMEOUT;
2148 }
2149 }
2150 }
2151 }
2152
2153 /* Abort the USART DMA Rx channel if enabled */
2154 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
2155 {
2156 /* Disable the USART DMA Rx request if enabled */
2157 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
2158
2159 /* Abort the USART DMA Rx channel : use blocking DMA Abort API (no callback) */
2160 if (husart->hdmarx != NULL)
2161 {
2162 /* Set the USART DMA Abort callback to Null.
2163 No call back execution at end of DMA abort procedure */
2164 husart->hdmarx->XferAbortCallback = NULL;
2165
2166 if (HAL_DMA_Abort(husart->hdmarx) != HAL_OK)
2167 {
2168 if (HAL_DMA_GetError(husart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
2169 {
2170 /* Set error code to DMA */
2171 husart->ErrorCode = HAL_USART_ERROR_DMA;
2172
2173 return HAL_TIMEOUT;
2174 }
2175 }
2176 }
2177 }
2178 #endif /* HAL_DMA_MODULE_ENABLED */
2179
2180 /* Reset Tx and Rx transfer counters */
2181 husart->TxXferCount = 0U;
2182 husart->RxXferCount = 0U;
2183
2184 /* Clear the Error flags in the ICR register */
2185 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
2186
2187 /* Flush the whole TX FIFO (if needed) */
2188 if (husart->FifoMode == USART_FIFOMODE_ENABLE)
2189 {
2190 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
2191 }
2192
2193 /* Discard the received data */
2194 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
2195
2196 /* Restore husart->State to Ready */
2197 husart->State = HAL_USART_STATE_READY;
2198
2199 /* Reset Handle ErrorCode to No Error */
2200 husart->ErrorCode = HAL_USART_ERROR_NONE;
2201
2202 return HAL_OK;
2203 }
2204
2205 /**
2206 * @brief Abort ongoing transfers (Interrupt mode).
2207 * @param husart USART handle.
2208 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
2209 * This procedure performs following operations :
2210 * - Disable USART Interrupts (Tx and Rx)
2211 * - Disable the DMA transfer in the peripheral register (if enabled)
2212 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
2213 * - Set handle State to READY
2214 * - At abort completion, call user abort complete callback
2215 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
2216 * considered as completed only when user abort complete callback is executed (not when exiting function).
2217 * @retval HAL status
2218 */
HAL_USART_Abort_IT(USART_HandleTypeDef * husart)2219 HAL_StatusTypeDef HAL_USART_Abort_IT(USART_HandleTypeDef *husart)
2220 {
2221 uint32_t abortcplt = 1U;
2222
2223 /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */
2224 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE |
2225 USART_CR1_TCIE));
2226 CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
2227
2228 #if defined(HAL_DMA_MODULE_ENABLED)
2229 /* If DMA Tx and/or DMA Rx Handles are associated to USART Handle, DMA Abort complete callbacks should be initialised
2230 before any call to DMA Abort functions */
2231 /* DMA Tx Handle is valid */
2232 if (husart->hdmatx != NULL)
2233 {
2234 /* Set DMA Abort Complete callback if USART DMA Tx request if enabled.
2235 Otherwise, set it to NULL */
2236 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
2237 {
2238 husart->hdmatx->XferAbortCallback = USART_DMATxAbortCallback;
2239 }
2240 else
2241 {
2242 husart->hdmatx->XferAbortCallback = NULL;
2243 }
2244 }
2245 /* DMA Rx Handle is valid */
2246 if (husart->hdmarx != NULL)
2247 {
2248 /* Set DMA Abort Complete callback if USART DMA Rx request if enabled.
2249 Otherwise, set it to NULL */
2250 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
2251 {
2252 husart->hdmarx->XferAbortCallback = USART_DMARxAbortCallback;
2253 }
2254 else
2255 {
2256 husart->hdmarx->XferAbortCallback = NULL;
2257 }
2258 }
2259
2260 /* Abort the USART DMA Tx channel if enabled */
2261 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
2262 {
2263 /* Disable DMA Tx at USART level */
2264 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
2265
2266 /* Abort the USART DMA Tx channel : use non blocking DMA Abort API (callback) */
2267 if (husart->hdmatx != NULL)
2268 {
2269 /* USART Tx DMA Abort callback has already been initialised :
2270 will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
2271
2272 /* Abort DMA TX */
2273 if (HAL_DMA_Abort_IT(husart->hdmatx) != HAL_OK)
2274 {
2275 husart->hdmatx->XferAbortCallback = NULL;
2276 }
2277 else
2278 {
2279 abortcplt = 0U;
2280 }
2281 }
2282 }
2283
2284 /* Abort the USART DMA Rx channel if enabled */
2285 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
2286 {
2287 /* Disable the USART DMA Rx request if enabled */
2288 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
2289
2290 /* Abort the USART DMA Rx channel : use non blocking DMA Abort API (callback) */
2291 if (husart->hdmarx != NULL)
2292 {
2293 /* USART Rx DMA Abort callback has already been initialised :
2294 will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
2295
2296 /* Abort DMA RX */
2297 if (HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
2298 {
2299 husart->hdmarx->XferAbortCallback = NULL;
2300 abortcplt = 1U;
2301 }
2302 else
2303 {
2304 abortcplt = 0U;
2305 }
2306 }
2307 }
2308 #endif /* HAL_DMA_MODULE_ENABLED */
2309
2310 /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
2311 if (abortcplt == 1U)
2312 {
2313 /* Reset Tx and Rx transfer counters */
2314 husart->TxXferCount = 0U;
2315 husart->RxXferCount = 0U;
2316
2317 /* Reset errorCode */
2318 husart->ErrorCode = HAL_USART_ERROR_NONE;
2319
2320 /* Clear the Error flags in the ICR register */
2321 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
2322
2323 /* Flush the whole TX FIFO (if needed) */
2324 if (husart->FifoMode == USART_FIFOMODE_ENABLE)
2325 {
2326 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
2327 }
2328
2329 /* Discard the received data */
2330 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
2331
2332 /* Restore husart->State to Ready */
2333 husart->State = HAL_USART_STATE_READY;
2334
2335 /* As no DMA to be aborted, call directly user Abort complete callback */
2336 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2337 /* Call registered Abort Complete Callback */
2338 husart->AbortCpltCallback(husart);
2339 #else
2340 /* Call legacy weak Abort Complete Callback */
2341 HAL_USART_AbortCpltCallback(husart);
2342 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2343 }
2344
2345 return HAL_OK;
2346 }
2347
2348 /**
2349 * @brief Handle USART interrupt request.
2350 * @param husart USART handle.
2351 * @retval None
2352 */
HAL_USART_IRQHandler(USART_HandleTypeDef * husart)2353 void HAL_USART_IRQHandler(USART_HandleTypeDef *husart)
2354 {
2355 uint32_t isrflags = READ_REG(husart->Instance->ISR);
2356 uint32_t cr1its = READ_REG(husart->Instance->CR1);
2357 uint32_t cr3its = READ_REG(husart->Instance->CR3);
2358
2359 uint32_t errorflags;
2360 uint32_t errorcode;
2361
2362 /* If no error occurs */
2363 errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF |
2364 USART_ISR_UDR));
2365 if (errorflags == 0U)
2366 {
2367 /* USART in mode Receiver ---------------------------------------------------*/
2368 if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
2369 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
2370 || ((cr3its & USART_CR3_RXFTIE) != 0U)))
2371 {
2372 if (husart->RxISR != NULL)
2373 {
2374 husart->RxISR(husart);
2375 }
2376 return;
2377 }
2378 }
2379
2380 /* If some errors occur */
2381 if ((errorflags != 0U)
2382 && (((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)
2383 || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)) != 0U)))
2384 {
2385 /* USART parity error interrupt occurred -------------------------------------*/
2386 if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
2387 {
2388 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_PEF);
2389
2390 husart->ErrorCode |= HAL_USART_ERROR_PE;
2391 }
2392
2393 /* USART frame error interrupt occurred --------------------------------------*/
2394 if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2395 {
2396 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_FEF);
2397
2398 husart->ErrorCode |= HAL_USART_ERROR_FE;
2399 }
2400
2401 /* USART noise error interrupt occurred --------------------------------------*/
2402 if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2403 {
2404 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_NEF);
2405
2406 husart->ErrorCode |= HAL_USART_ERROR_NE;
2407 }
2408
2409 /* USART Over-Run interrupt occurred -----------------------------------------*/
2410 if (((isrflags & USART_ISR_ORE) != 0U)
2411 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) ||
2412 ((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)))
2413 {
2414 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF);
2415
2416 husart->ErrorCode |= HAL_USART_ERROR_ORE;
2417 }
2418
2419 /* USART Receiver Timeout interrupt occurred ---------------------------------*/
2420 if (((isrflags & USART_ISR_RTOF) != 0U) && ((cr1its & USART_CR1_RTOIE) != 0U))
2421 {
2422 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_RTOF);
2423
2424 husart->ErrorCode |= HAL_USART_ERROR_RTO;
2425 }
2426
2427 /* USART SPI slave underrun error interrupt occurred -------------------------*/
2428 if (((isrflags & USART_ISR_UDR) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2429 {
2430 /* Ignore SPI slave underrun errors when reception is going on */
2431 if (husart->State == HAL_USART_STATE_BUSY_RX)
2432 {
2433 __HAL_USART_CLEAR_UDRFLAG(husart);
2434 return;
2435 }
2436 else
2437 {
2438 __HAL_USART_CLEAR_UDRFLAG(husart);
2439 husart->ErrorCode |= HAL_USART_ERROR_UDR;
2440 }
2441 }
2442
2443 /* Call USART Error Call back function if need be --------------------------*/
2444 if (husart->ErrorCode != HAL_USART_ERROR_NONE)
2445 {
2446 /* USART in mode Receiver ---------------------------------------------------*/
2447 if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
2448 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
2449 || ((cr3its & USART_CR3_RXFTIE) != 0U)))
2450 {
2451 if (husart->RxISR != NULL)
2452 {
2453 husart->RxISR(husart);
2454 }
2455 }
2456
2457 /* If Overrun error occurs, or if any error occurs in DMA mode reception,
2458 consider error as blocking */
2459 errorcode = husart->ErrorCode & HAL_USART_ERROR_ORE;
2460 if ((HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) ||
2461 (errorcode != 0U))
2462 {
2463 /* Blocking error : transfer is aborted
2464 Set the USART state ready to be able to start again the process,
2465 Disable Interrupts, and disable DMA requests, if ongoing */
2466 USART_EndTransfer(husart);
2467
2468 #if defined(HAL_DMA_MODULE_ENABLED)
2469 /* Abort the USART DMA Rx channel if enabled */
2470 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
2471 {
2472 /* Disable the USART DMA Rx request if enabled */
2473 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR | USART_CR3_DMAR);
2474
2475 /* Abort the USART DMA Tx channel */
2476 if (husart->hdmatx != NULL)
2477 {
2478 /* Set the USART Tx DMA Abort callback to NULL : no callback
2479 executed at end of DMA abort procedure */
2480 husart->hdmatx->XferAbortCallback = NULL;
2481
2482 /* Abort DMA TX */
2483 (void)HAL_DMA_Abort_IT(husart->hdmatx);
2484 }
2485
2486 /* Abort the USART DMA Rx channel */
2487 if (husart->hdmarx != NULL)
2488 {
2489 /* Set the USART Rx DMA Abort callback :
2490 will lead to call HAL_USART_ErrorCallback() at end of DMA abort procedure */
2491 husart->hdmarx->XferAbortCallback = USART_DMAAbortOnError;
2492
2493 /* Abort DMA RX */
2494 if (HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
2495 {
2496 /* Call Directly husart->hdmarx->XferAbortCallback function in case of error */
2497 husart->hdmarx->XferAbortCallback(husart->hdmarx);
2498 }
2499 }
2500 else
2501 {
2502 /* Call user error callback */
2503 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2504 /* Call registered Error Callback */
2505 husart->ErrorCallback(husart);
2506 #else
2507 /* Call legacy weak Error Callback */
2508 HAL_USART_ErrorCallback(husart);
2509 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2510 }
2511 }
2512 else
2513 #endif /* HAL_DMA_MODULE_ENABLED */
2514 {
2515 /* Call user error callback */
2516 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2517 /* Call registered Error Callback */
2518 husart->ErrorCallback(husart);
2519 #else
2520 /* Call legacy weak Error Callback */
2521 HAL_USART_ErrorCallback(husart);
2522 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2523 }
2524 }
2525 else
2526 {
2527 /* Non Blocking error : transfer could go on.
2528 Error is notified to user through user error callback */
2529 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2530 /* Call registered Error Callback */
2531 husart->ErrorCallback(husart);
2532 #else
2533 /* Call legacy weak Error Callback */
2534 HAL_USART_ErrorCallback(husart);
2535 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2536 husart->ErrorCode = HAL_USART_ERROR_NONE;
2537 }
2538 }
2539 return;
2540
2541 } /* End if some error occurs */
2542
2543
2544 /* USART in mode Transmitter ------------------------------------------------*/
2545 if (((isrflags & USART_ISR_TXE_TXFNF) != 0U)
2546 && (((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U)
2547 || ((cr3its & USART_CR3_TXFTIE) != 0U)))
2548 {
2549 if (husart->TxISR != NULL)
2550 {
2551 husart->TxISR(husart);
2552 }
2553 return;
2554 }
2555
2556 /* USART in mode Transmitter (transmission end) -----------------------------*/
2557 if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
2558 {
2559 USART_EndTransmit_IT(husart);
2560 return;
2561 }
2562
2563 /* USART TX Fifo Empty occurred ----------------------------------------------*/
2564 if (((isrflags & USART_ISR_TXFE) != 0U) && ((cr1its & USART_CR1_TXFEIE) != 0U))
2565 {
2566 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2567 /* Call registered Tx Fifo Empty Callback */
2568 husart->TxFifoEmptyCallback(husart);
2569 #else
2570 /* Call legacy weak Tx Fifo Empty Callback */
2571 HAL_USARTEx_TxFifoEmptyCallback(husart);
2572 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2573 return;
2574 }
2575
2576 /* USART RX Fifo Full occurred ----------------------------------------------*/
2577 if (((isrflags & USART_ISR_RXFF) != 0U) && ((cr1its & USART_CR1_RXFFIE) != 0U))
2578 {
2579 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2580 /* Call registered Rx Fifo Full Callback */
2581 husart->RxFifoFullCallback(husart);
2582 #else
2583 /* Call legacy weak Rx Fifo Full Callback */
2584 HAL_USARTEx_RxFifoFullCallback(husart);
2585 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2586 return;
2587 }
2588 }
2589
2590 /**
2591 * @brief Tx Transfer completed callback.
2592 * @param husart USART handle.
2593 * @retval None
2594 */
HAL_USART_TxCpltCallback(USART_HandleTypeDef * husart)2595 __weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart)
2596 {
2597 /* Prevent unused argument(s) compilation warning */
2598 UNUSED(husart);
2599
2600 /* NOTE : This function should not be modified, when the callback is needed,
2601 the HAL_USART_TxCpltCallback can be implemented in the user file.
2602 */
2603 }
2604
2605 /**
2606 * @brief Tx Half Transfer completed callback.
2607 * @param husart USART handle.
2608 * @retval None
2609 */
HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef * husart)2610 __weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart)
2611 {
2612 /* Prevent unused argument(s) compilation warning */
2613 UNUSED(husart);
2614
2615 /* NOTE: This function should not be modified, when the callback is needed,
2616 the HAL_USART_TxHalfCpltCallback can be implemented in the user file.
2617 */
2618 }
2619
2620 /**
2621 * @brief Rx Transfer completed callback.
2622 * @param husart USART handle.
2623 * @retval None
2624 */
HAL_USART_RxCpltCallback(USART_HandleTypeDef * husart)2625 __weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart)
2626 {
2627 /* Prevent unused argument(s) compilation warning */
2628 UNUSED(husart);
2629
2630 /* NOTE: This function should not be modified, when the callback is needed,
2631 the HAL_USART_RxCpltCallback can be implemented in the user file.
2632 */
2633 }
2634
2635 /**
2636 * @brief Rx Half Transfer completed callback.
2637 * @param husart USART handle.
2638 * @retval None
2639 */
HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef * husart)2640 __weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart)
2641 {
2642 /* Prevent unused argument(s) compilation warning */
2643 UNUSED(husart);
2644
2645 /* NOTE : This function should not be modified, when the callback is needed,
2646 the HAL_USART_RxHalfCpltCallback can be implemented in the user file
2647 */
2648 }
2649
2650 /**
2651 * @brief Tx/Rx Transfers completed callback for the non-blocking process.
2652 * @param husart USART handle.
2653 * @retval None
2654 */
HAL_USART_TxRxCpltCallback(USART_HandleTypeDef * husart)2655 __weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart)
2656 {
2657 /* Prevent unused argument(s) compilation warning */
2658 UNUSED(husart);
2659
2660 /* NOTE : This function should not be modified, when the callback is needed,
2661 the HAL_USART_TxRxCpltCallback can be implemented in the user file
2662 */
2663 }
2664
2665 /**
2666 * @brief USART error callback.
2667 * @param husart USART handle.
2668 * @retval None
2669 */
HAL_USART_ErrorCallback(USART_HandleTypeDef * husart)2670 __weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart)
2671 {
2672 /* Prevent unused argument(s) compilation warning */
2673 UNUSED(husart);
2674
2675 /* NOTE : This function should not be modified, when the callback is needed,
2676 the HAL_USART_ErrorCallback can be implemented in the user file.
2677 */
2678 }
2679
2680 /**
2681 * @brief USART Abort Complete callback.
2682 * @param husart USART handle.
2683 * @retval None
2684 */
HAL_USART_AbortCpltCallback(USART_HandleTypeDef * husart)2685 __weak void HAL_USART_AbortCpltCallback(USART_HandleTypeDef *husart)
2686 {
2687 /* Prevent unused argument(s) compilation warning */
2688 UNUSED(husart);
2689
2690 /* NOTE : This function should not be modified, when the callback is needed,
2691 the HAL_USART_AbortCpltCallback can be implemented in the user file.
2692 */
2693 }
2694
2695 /**
2696 * @}
2697 */
2698
2699 /** @defgroup USART_Exported_Functions_Group4 Peripheral State and Error functions
2700 * @brief USART Peripheral State and Error functions
2701 *
2702 @verbatim
2703 ==============================================================================
2704 ##### Peripheral State and Error functions #####
2705 ==============================================================================
2706 [..]
2707 This subsection provides functions allowing to :
2708 (+) Return the USART handle state
2709 (+) Return the USART handle error code
2710
2711 @endverbatim
2712 * @{
2713 */
2714
2715
2716 /**
2717 * @brief Return the USART handle state.
2718 * @param husart pointer to a USART_HandleTypeDef structure that contains
2719 * the configuration information for the specified USART.
2720 * @retval USART handle state
2721 */
HAL_USART_GetState(const USART_HandleTypeDef * husart)2722 HAL_USART_StateTypeDef HAL_USART_GetState(const USART_HandleTypeDef *husart)
2723 {
2724 return husart->State;
2725 }
2726
2727 /**
2728 * @brief Return the USART error code.
2729 * @param husart pointer to a USART_HandleTypeDef structure that contains
2730 * the configuration information for the specified USART.
2731 * @retval USART handle Error Code
2732 */
HAL_USART_GetError(const USART_HandleTypeDef * husart)2733 uint32_t HAL_USART_GetError(const USART_HandleTypeDef *husart)
2734 {
2735 return husart->ErrorCode;
2736 }
2737
2738 /**
2739 * @}
2740 */
2741
2742 /**
2743 * @}
2744 */
2745
2746 /** @defgroup USART_Private_Functions USART Private Functions
2747 * @{
2748 */
2749
2750 /**
2751 * @brief Initialize the callbacks to their default values.
2752 * @param husart USART handle.
2753 * @retval none
2754 */
2755 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
USART_InitCallbacksToDefault(USART_HandleTypeDef * husart)2756 void USART_InitCallbacksToDefault(USART_HandleTypeDef *husart)
2757 {
2758 /* Init the USART Callback settings */
2759 husart->TxHalfCpltCallback = HAL_USART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
2760 husart->TxCpltCallback = HAL_USART_TxCpltCallback; /* Legacy weak TxCpltCallback */
2761 husart->RxHalfCpltCallback = HAL_USART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
2762 husart->RxCpltCallback = HAL_USART_RxCpltCallback; /* Legacy weak RxCpltCallback */
2763 husart->TxRxCpltCallback = HAL_USART_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */
2764 husart->ErrorCallback = HAL_USART_ErrorCallback; /* Legacy weak ErrorCallback */
2765 husart->AbortCpltCallback = HAL_USART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
2766 husart->RxFifoFullCallback = HAL_USARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */
2767 husart->TxFifoEmptyCallback = HAL_USARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */
2768 }
2769 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2770
2771 /**
2772 * @brief End ongoing transfer on USART peripheral (following error detection or Transfer completion).
2773 * @param husart USART handle.
2774 * @retval None
2775 */
USART_EndTransfer(USART_HandleTypeDef * husart)2776 static void USART_EndTransfer(USART_HandleTypeDef *husart)
2777 {
2778 /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */
2779 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE |
2780 USART_CR1_TCIE));
2781 CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
2782
2783 /* At end of process, restore husart->State to Ready */
2784 husart->State = HAL_USART_STATE_READY;
2785 }
2786
2787 #if defined(HAL_DMA_MODULE_ENABLED)
2788 /**
2789 * @brief DMA USART transmit process complete callback.
2790 * @param hdma DMA handle.
2791 * @retval None
2792 */
USART_DMATransmitCplt(DMA_HandleTypeDef * hdma)2793 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2794 {
2795 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2796
2797 /* Check if DMA in circular mode */
2798 if (hdma->Mode != DMA_LINKEDLIST_CIRCULAR)
2799 {
2800 husart->TxXferCount = 0U;
2801
2802 if (husart->State == HAL_USART_STATE_BUSY_TX)
2803 {
2804 /* Disable the DMA transfer for transmit request by resetting the DMAT bit
2805 in the USART CR3 register */
2806 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
2807
2808 /* Enable the USART Transmit Complete Interrupt */
2809 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
2810 }
2811 }
2812 /* DMA Circular mode */
2813 else
2814 {
2815 if (husart->State == HAL_USART_STATE_BUSY_TX)
2816 {
2817 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2818 /* Call registered Tx Complete Callback */
2819 husart->TxCpltCallback(husart);
2820 #else
2821 /* Call legacy weak Tx Complete Callback */
2822 HAL_USART_TxCpltCallback(husart);
2823 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2824 }
2825 }
2826 }
2827
2828 /**
2829 * @brief DMA USART transmit process half complete callback.
2830 * @param hdma DMA handle.
2831 * @retval None
2832 */
USART_DMATxHalfCplt(DMA_HandleTypeDef * hdma)2833 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
2834 {
2835 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2836
2837 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2838 /* Call registered Tx Half Complete Callback */
2839 husart->TxHalfCpltCallback(husart);
2840 #else
2841 /* Call legacy weak Tx Half Complete Callback */
2842 HAL_USART_TxHalfCpltCallback(husart);
2843 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2844 }
2845
2846 /**
2847 * @brief DMA USART receive process complete callback.
2848 * @param hdma DMA handle.
2849 * @retval None
2850 */
USART_DMAReceiveCplt(DMA_HandleTypeDef * hdma)2851 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2852 {
2853 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2854
2855 /* Check if DMA in circular mode*/
2856 if (hdma->Mode != DMA_LINKEDLIST_CIRCULAR)
2857 {
2858 husart->RxXferCount = 0U;
2859
2860 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
2861 CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
2862 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
2863
2864 /* Disable the DMA RX transfer for the receiver request by resetting the DMAR bit
2865 in USART CR3 register */
2866 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
2867 /* similarly, disable the DMA TX transfer that was started to provide the
2868 clock to the slave device */
2869 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
2870
2871 if (husart->State == HAL_USART_STATE_BUSY_RX)
2872 {
2873 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2874 /* Call registered Rx Complete Callback */
2875 husart->RxCpltCallback(husart);
2876 #else
2877 /* Call legacy weak Rx Complete Callback */
2878 HAL_USART_RxCpltCallback(husart);
2879 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2880 }
2881 /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
2882 else
2883 {
2884 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2885 /* Call registered Tx Rx Complete Callback */
2886 husart->TxRxCpltCallback(husart);
2887 #else
2888 /* Call legacy weak Tx Rx Complete Callback */
2889 HAL_USART_TxRxCpltCallback(husart);
2890 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2891 }
2892 husart->State = HAL_USART_STATE_READY;
2893 }
2894 /* DMA circular mode */
2895 else
2896 {
2897 if (husart->State == HAL_USART_STATE_BUSY_RX)
2898 {
2899 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2900 /* Call registered Rx Complete Callback */
2901 husart->RxCpltCallback(husart);
2902 #else
2903 /* Call legacy weak Rx Complete Callback */
2904 HAL_USART_RxCpltCallback(husart);
2905 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2906 }
2907 /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
2908 else
2909 {
2910 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2911 /* Call registered Tx Rx Complete Callback */
2912 husart->TxRxCpltCallback(husart);
2913 #else
2914 /* Call legacy weak Tx Rx Complete Callback */
2915 HAL_USART_TxRxCpltCallback(husart);
2916 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2917 }
2918 }
2919 }
2920
2921 /**
2922 * @brief DMA USART receive process half complete callback.
2923 * @param hdma DMA handle.
2924 * @retval None
2925 */
USART_DMARxHalfCplt(DMA_HandleTypeDef * hdma)2926 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
2927 {
2928 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2929
2930 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2931 /* Call registered Rx Half Complete Callback */
2932 husart->RxHalfCpltCallback(husart);
2933 #else
2934 /* Call legacy weak Rx Half Complete Callback */
2935 HAL_USART_RxHalfCpltCallback(husart);
2936 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2937 }
2938
2939 /**
2940 * @brief DMA USART communication error callback.
2941 * @param hdma DMA handle.
2942 * @retval None
2943 */
USART_DMAError(DMA_HandleTypeDef * hdma)2944 static void USART_DMAError(DMA_HandleTypeDef *hdma)
2945 {
2946 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2947
2948 husart->RxXferCount = 0U;
2949 husart->TxXferCount = 0U;
2950 USART_EndTransfer(husart);
2951
2952 husart->ErrorCode |= HAL_USART_ERROR_DMA;
2953 husart->State = HAL_USART_STATE_READY;
2954
2955 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2956 /* Call registered Error Callback */
2957 husart->ErrorCallback(husart);
2958 #else
2959 /* Call legacy weak Error Callback */
2960 HAL_USART_ErrorCallback(husart);
2961 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2962 }
2963
2964 /**
2965 * @brief DMA USART communication abort callback, when initiated by HAL services on Error
2966 * (To be called at end of DMA Abort procedure following error occurrence).
2967 * @param hdma DMA handle.
2968 * @retval None
2969 */
USART_DMAAbortOnError(DMA_HandleTypeDef * hdma)2970 static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
2971 {
2972 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2973 husart->RxXferCount = 0U;
2974 husart->TxXferCount = 0U;
2975
2976 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2977 /* Call registered Error Callback */
2978 husart->ErrorCallback(husart);
2979 #else
2980 /* Call legacy weak Error Callback */
2981 HAL_USART_ErrorCallback(husart);
2982 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2983 }
2984
2985 /**
2986 * @brief DMA USART Tx communication abort callback, when initiated by user
2987 * (To be called at end of DMA Tx Abort procedure following user abort request).
2988 * @note When this callback is executed, User Abort complete call back is called only if no
2989 * Abort still ongoing for Rx DMA Handle.
2990 * @param hdma DMA handle.
2991 * @retval None
2992 */
USART_DMATxAbortCallback(DMA_HandleTypeDef * hdma)2993 static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
2994 {
2995 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
2996
2997 husart->hdmatx->XferAbortCallback = NULL;
2998
2999 /* Check if an Abort process is still ongoing */
3000 if (husart->hdmarx != NULL)
3001 {
3002 if (husart->hdmarx->XferAbortCallback != NULL)
3003 {
3004 return;
3005 }
3006 }
3007
3008 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
3009 husart->TxXferCount = 0U;
3010 husart->RxXferCount = 0U;
3011
3012 /* Reset errorCode */
3013 husart->ErrorCode = HAL_USART_ERROR_NONE;
3014
3015 /* Clear the Error flags in the ICR register */
3016 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
3017
3018 /* Restore husart->State to Ready */
3019 husart->State = HAL_USART_STATE_READY;
3020
3021 /* Call user Abort complete callback */
3022 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3023 /* Call registered Abort Complete Callback */
3024 husart->AbortCpltCallback(husart);
3025 #else
3026 /* Call legacy weak Abort Complete Callback */
3027 HAL_USART_AbortCpltCallback(husart);
3028 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3029
3030 }
3031
3032
3033 /**
3034 * @brief DMA USART Rx communication abort callback, when initiated by user
3035 * (To be called at end of DMA Rx Abort procedure following user abort request).
3036 * @note When this callback is executed, User Abort complete call back is called only if no
3037 * Abort still ongoing for Tx DMA Handle.
3038 * @param hdma DMA handle.
3039 * @retval None
3040 */
USART_DMARxAbortCallback(DMA_HandleTypeDef * hdma)3041 static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
3042 {
3043 USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
3044
3045 husart->hdmarx->XferAbortCallback = NULL;
3046
3047 /* Check if an Abort process is still ongoing */
3048 if (husart->hdmatx != NULL)
3049 {
3050 if (husart->hdmatx->XferAbortCallback != NULL)
3051 {
3052 return;
3053 }
3054 }
3055
3056 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
3057 husart->TxXferCount = 0U;
3058 husart->RxXferCount = 0U;
3059
3060 /* Reset errorCode */
3061 husart->ErrorCode = HAL_USART_ERROR_NONE;
3062
3063 /* Clear the Error flags in the ICR register */
3064 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
3065
3066 /* Restore husart->State to Ready */
3067 husart->State = HAL_USART_STATE_READY;
3068
3069 /* Call user Abort complete callback */
3070 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3071 /* Call registered Abort Complete Callback */
3072 husart->AbortCpltCallback(husart);
3073 #else
3074 /* Call legacy weak Abort Complete Callback */
3075 HAL_USART_AbortCpltCallback(husart);
3076 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3077 }
3078
3079 #endif /* HAL_DMA_MODULE_ENABLED */
3080
3081 /**
3082 * @brief Handle USART Communication Timeout. It waits
3083 * until a flag is no longer in the specified status.
3084 * @param husart USART handle.
3085 * @param Flag Specifies the USART flag to check.
3086 * @param Status the actual Flag status (SET or RESET).
3087 * @param Tickstart Tick start value
3088 * @param Timeout timeout duration.
3089 * @retval HAL status
3090 */
USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef * husart,uint32_t Flag,FlagStatus Status,uint32_t Tickstart,uint32_t Timeout)3091 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status,
3092 uint32_t Tickstart, uint32_t Timeout)
3093 {
3094 /* Wait until flag is set */
3095 while ((__HAL_USART_GET_FLAG(husart, Flag) ? SET : RESET) == Status)
3096 {
3097 /* Check for the Timeout */
3098 if (Timeout != HAL_MAX_DELAY)
3099 {
3100 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
3101 {
3102 husart->State = HAL_USART_STATE_READY;
3103
3104 /* Process Unlocked */
3105 __HAL_UNLOCK(husart);
3106
3107 return HAL_TIMEOUT;
3108 }
3109 }
3110 }
3111 return HAL_OK;
3112 }
3113
3114 /**
3115 * @brief Configure the USART peripheral.
3116 * @param husart USART handle.
3117 * @retval HAL status
3118 */
USART_SetConfig(USART_HandleTypeDef * husart)3119 static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart)
3120 {
3121 uint32_t tmpreg;
3122 USART_ClockSourceTypeDef clocksource;
3123 HAL_StatusTypeDef ret = HAL_OK;
3124 uint16_t brrtemp;
3125 uint32_t usartdiv = 0x00000000;
3126 uint32_t pclk;
3127
3128 /* Check the parameters */
3129 assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity));
3130 assert_param(IS_USART_PHASE(husart->Init.CLKPhase));
3131 assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit));
3132 assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate));
3133 assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength));
3134 assert_param(IS_USART_STOPBITS(husart->Init.StopBits));
3135 assert_param(IS_USART_PARITY(husart->Init.Parity));
3136 assert_param(IS_USART_MODE(husart->Init.Mode));
3137 assert_param(IS_USART_PRESCALER(husart->Init.ClockPrescaler));
3138
3139 /*-------------------------- USART CR1 Configuration -----------------------*/
3140 /* Clear M, PCE, PS, TE and RE bits and configure
3141 * the USART Word Length, Parity and Mode:
3142 * set the M bits according to husart->Init.WordLength value
3143 * set PCE and PS bits according to husart->Init.Parity value
3144 * set TE and RE bits according to husart->Init.Mode value
3145 * force OVER8 to 1 to allow to reach the maximum speed (Fclock/8) */
3146 tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8;
3147 MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
3148
3149 /*---------------------------- USART CR2 Configuration ---------------------*/
3150 /* Clear and configure the USART Clock, CPOL, CPHA, LBCL STOP and SLVEN bits:
3151 * set CPOL bit according to husart->Init.CLKPolarity value
3152 * set CPHA bit according to husart->Init.CLKPhase value
3153 * set LBCL bit according to husart->Init.CLKLastBit value (used in SPI master mode only)
3154 * set STOP[13:12] bits according to husart->Init.StopBits value */
3155 tmpreg = (uint32_t)(USART_CLOCK_ENABLE);
3156 tmpreg |= (uint32_t)husart->Init.CLKLastBit;
3157 tmpreg |= ((uint32_t)husart->Init.CLKPolarity | (uint32_t)husart->Init.CLKPhase);
3158 tmpreg |= (uint32_t)husart->Init.StopBits;
3159 MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg);
3160
3161 /*-------------------------- USART PRESC Configuration -----------------------*/
3162 /* Configure
3163 * - USART Clock Prescaler : set PRESCALER according to husart->Init.ClockPrescaler value */
3164 MODIFY_REG(husart->Instance->PRESC, USART_PRESC_PRESCALER, husart->Init.ClockPrescaler);
3165
3166 /*-------------------------- USART BRR Configuration -----------------------*/
3167 /* BRR is filled-up according to OVER8 bit setting which is forced to 1 */
3168 USART_GETCLOCKSOURCE(husart, clocksource);
3169
3170 switch (clocksource)
3171 {
3172 case USART_CLOCKSOURCE_PCLK1:
3173 pclk = HAL_RCC_GetPCLK1Freq();
3174 usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler));
3175 break;
3176 case USART_CLOCKSOURCE_PCLK2:
3177 pclk = HAL_RCC_GetPCLK2Freq();
3178 usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler));
3179 break;
3180 case USART_CLOCKSOURCE_HSI:
3181 usartdiv = (uint32_t)(USART_DIV_SAMPLING8(HSI_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler));
3182 break;
3183 case USART_CLOCKSOURCE_SYSCLK:
3184 pclk = HAL_RCC_GetSysClockFreq();
3185 usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler));
3186 break;
3187 case USART_CLOCKSOURCE_LSE:
3188 usartdiv = (uint32_t)(USART_DIV_SAMPLING8(LSE_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler));
3189 break;
3190 default:
3191 ret = HAL_ERROR;
3192 break;
3193 }
3194
3195 /* USARTDIV must be greater than or equal to 0d16 and smaller than or equal to ffff */
3196 if ((usartdiv >= USART_BRR_MIN) && (usartdiv <= USART_BRR_MAX))
3197 {
3198 brrtemp = (uint16_t)(usartdiv & 0xFFF0U);
3199 brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U);
3200 husart->Instance->BRR = brrtemp;
3201 }
3202 else
3203 {
3204 ret = HAL_ERROR;
3205 }
3206
3207 /* Initialize the number of data to process during RX/TX ISR execution */
3208 husart->NbTxDataToProcess = 1U;
3209 husart->NbRxDataToProcess = 1U;
3210
3211 /* Clear ISR function pointers */
3212 husart->RxISR = NULL;
3213 husart->TxISR = NULL;
3214
3215 return ret;
3216 }
3217
3218 /**
3219 * @brief Check the USART Idle State.
3220 * @param husart USART handle.
3221 * @retval HAL status
3222 */
USART_CheckIdleState(USART_HandleTypeDef * husart)3223 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart)
3224 {
3225 uint32_t tickstart;
3226
3227 /* Initialize the USART ErrorCode */
3228 husart->ErrorCode = HAL_USART_ERROR_NONE;
3229
3230 /* Init tickstart for timeout management */
3231 tickstart = HAL_GetTick();
3232
3233 /* Check if the Transmitter is enabled */
3234 if ((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
3235 {
3236 /* Wait until TEACK flag is set */
3237 if (USART_WaitOnFlagUntilTimeout(husart, USART_ISR_TEACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK)
3238 {
3239 /* Timeout occurred */
3240 return HAL_TIMEOUT;
3241 }
3242 }
3243 /* Check if the Receiver is enabled */
3244 if ((husart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
3245 {
3246 /* Wait until REACK flag is set */
3247 if (USART_WaitOnFlagUntilTimeout(husart, USART_ISR_REACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK)
3248 {
3249 /* Timeout occurred */
3250 return HAL_TIMEOUT;
3251 }
3252 }
3253
3254 /* Initialize the USART state*/
3255 husart->State = HAL_USART_STATE_READY;
3256
3257 /* Process Unlocked */
3258 __HAL_UNLOCK(husart);
3259
3260 return HAL_OK;
3261 }
3262
3263 /**
3264 * @brief Simplex send an amount of data in non-blocking mode.
3265 * @note Function called under interruption only, once
3266 * interruptions have been enabled by HAL_USART_Transmit_IT().
3267 * @note The USART errors are not managed to avoid the overrun error.
3268 * @note ISR function executed when FIFO mode is disabled and when the
3269 * data word length is less than 9 bits long.
3270 * @param husart USART handle.
3271 * @retval None
3272 */
USART_TxISR_8BIT(USART_HandleTypeDef * husart)3273 static void USART_TxISR_8BIT(USART_HandleTypeDef *husart)
3274 {
3275 const HAL_USART_StateTypeDef state = husart->State;
3276
3277 /* Check that a Tx process is ongoing */
3278 if ((state == HAL_USART_STATE_BUSY_TX) ||
3279 (state == HAL_USART_STATE_BUSY_TX_RX))
3280 {
3281 if (husart->TxXferCount == 0U)
3282 {
3283 /* Disable the USART Transmit data register empty interrupt */
3284 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
3285
3286 /* Enable the USART Transmit Complete Interrupt */
3287 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3288 }
3289 else
3290 {
3291 husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr & (uint8_t)0xFF);
3292 husart->pTxBuffPtr++;
3293 husart->TxXferCount--;
3294 }
3295 }
3296 }
3297
3298 /**
3299 * @brief Simplex send an amount of data in non-blocking mode.
3300 * @note Function called under interruption only, once
3301 * interruptions have been enabled by HAL_USART_Transmit_IT().
3302 * @note The USART errors are not managed to avoid the overrun error.
3303 * @note ISR function executed when FIFO mode is disabled and when the
3304 * data word length is 9 bits long.
3305 * @param husart USART handle.
3306 * @retval None
3307 */
USART_TxISR_16BIT(USART_HandleTypeDef * husart)3308 static void USART_TxISR_16BIT(USART_HandleTypeDef *husart)
3309 {
3310 const HAL_USART_StateTypeDef state = husart->State;
3311 const uint16_t *tmp;
3312
3313 if ((state == HAL_USART_STATE_BUSY_TX) ||
3314 (state == HAL_USART_STATE_BUSY_TX_RX))
3315 {
3316 if (husart->TxXferCount == 0U)
3317 {
3318 /* Disable the USART Transmit data register empty interrupt */
3319 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
3320
3321 /* Enable the USART Transmit Complete Interrupt */
3322 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3323 }
3324 else
3325 {
3326 tmp = (const uint16_t *) husart->pTxBuffPtr;
3327 husart->Instance->TDR = (uint16_t)(*tmp & 0x01FFU);
3328 husart->pTxBuffPtr += 2U;
3329 husart->TxXferCount--;
3330 }
3331 }
3332 }
3333
3334 /**
3335 * @brief Simplex send an amount of data in non-blocking mode.
3336 * @note Function called under interruption only, once
3337 * interruptions have been enabled by HAL_USART_Transmit_IT().
3338 * @note The USART errors are not managed to avoid the overrun error.
3339 * @note ISR function executed when FIFO mode is enabled and when the
3340 * data word length is less than 9 bits long.
3341 * @param husart USART handle.
3342 * @retval None
3343 */
USART_TxISR_8BIT_FIFOEN(USART_HandleTypeDef * husart)3344 static void USART_TxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart)
3345 {
3346 const HAL_USART_StateTypeDef state = husart->State;
3347 uint16_t nb_tx_data;
3348
3349 /* Check that a Tx process is ongoing */
3350 if ((state == HAL_USART_STATE_BUSY_TX) ||
3351 (state == HAL_USART_STATE_BUSY_TX_RX))
3352 {
3353 for (nb_tx_data = husart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
3354 {
3355 if (husart->TxXferCount == 0U)
3356 {
3357 /* Disable the TX FIFO threshold interrupt */
3358 __HAL_USART_DISABLE_IT(husart, USART_IT_TXFT);
3359
3360 /* Enable the USART Transmit Complete Interrupt */
3361 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3362
3363 break; /* force exit loop */
3364 }
3365 else if (__HAL_USART_GET_FLAG(husart, USART_FLAG_TXFNF) == SET)
3366 {
3367 husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr & (uint8_t)0xFF);
3368 husart->pTxBuffPtr++;
3369 husart->TxXferCount--;
3370 }
3371 else
3372 {
3373 /* Nothing to do */
3374 }
3375 }
3376 }
3377 }
3378
3379 /**
3380 * @brief Simplex send an amount of data in non-blocking mode.
3381 * @note Function called under interruption only, once
3382 * interruptions have been enabled by HAL_USART_Transmit_IT().
3383 * @note The USART errors are not managed to avoid the overrun error.
3384 * @note ISR function executed when FIFO mode is enabled and when the
3385 * data word length is 9 bits long.
3386 * @param husart USART handle.
3387 * @retval None
3388 */
USART_TxISR_16BIT_FIFOEN(USART_HandleTypeDef * husart)3389 static void USART_TxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart)
3390 {
3391 const HAL_USART_StateTypeDef state = husart->State;
3392 const uint16_t *tmp;
3393 uint16_t nb_tx_data;
3394
3395 /* Check that a Tx process is ongoing */
3396 if ((state == HAL_USART_STATE_BUSY_TX) ||
3397 (state == HAL_USART_STATE_BUSY_TX_RX))
3398 {
3399 for (nb_tx_data = husart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
3400 {
3401 if (husart->TxXferCount == 0U)
3402 {
3403 /* Disable the TX FIFO threshold interrupt */
3404 __HAL_USART_DISABLE_IT(husart, USART_IT_TXFT);
3405
3406 /* Enable the USART Transmit Complete Interrupt */
3407 __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
3408
3409 break; /* force exit loop */
3410 }
3411 else if (__HAL_USART_GET_FLAG(husart, USART_FLAG_TXFNF) == SET)
3412 {
3413 tmp = (const uint16_t *) husart->pTxBuffPtr;
3414 husart->Instance->TDR = (uint16_t)(*tmp & 0x01FFU);
3415 husart->pTxBuffPtr += 2U;
3416 husart->TxXferCount--;
3417 }
3418 else
3419 {
3420 /* Nothing to do */
3421 }
3422 }
3423 }
3424 }
3425
3426 /**
3427 * @brief Wraps up transmission in non-blocking mode.
3428 * @param husart Pointer to a USART_HandleTypeDef structure that contains
3429 * the configuration information for the specified USART module.
3430 * @retval None
3431 */
USART_EndTransmit_IT(USART_HandleTypeDef * husart)3432 static void USART_EndTransmit_IT(USART_HandleTypeDef *husart)
3433 {
3434 /* Disable the USART Transmit Complete Interrupt */
3435 __HAL_USART_DISABLE_IT(husart, USART_IT_TC);
3436
3437 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3438 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
3439
3440 /* Clear TxISR function pointer */
3441 husart->TxISR = NULL;
3442
3443 if (husart->State == HAL_USART_STATE_BUSY_TX)
3444 {
3445 /* Clear overrun flag and discard the received data */
3446 __HAL_USART_CLEAR_OREFLAG(husart);
3447 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
3448
3449 /* Tx process is completed, restore husart->State to Ready */
3450 husart->State = HAL_USART_STATE_READY;
3451
3452 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3453 /* Call registered Tx Complete Callback */
3454 husart->TxCpltCallback(husart);
3455 #else
3456 /* Call legacy weak Tx Complete Callback */
3457 HAL_USART_TxCpltCallback(husart);
3458 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3459 }
3460 else if (husart->RxXferCount == 0U)
3461 {
3462 /* TxRx process is completed, restore husart->State to Ready */
3463 husart->State = HAL_USART_STATE_READY;
3464
3465 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3466 /* Call registered Tx Rx Complete Callback */
3467 husart->TxRxCpltCallback(husart);
3468 #else
3469 /* Call legacy weak Tx Rx Complete Callback */
3470 HAL_USART_TxRxCpltCallback(husart);
3471 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3472 }
3473 else
3474 {
3475 /* Nothing to do */
3476 }
3477 }
3478
3479
3480 /**
3481 * @brief Simplex receive an amount of data in non-blocking mode.
3482 * @note Function called under interruption only, once
3483 * interruptions have been enabled by HAL_USART_Receive_IT().
3484 * @note ISR function executed when FIFO mode is disabled and when the
3485 * data word length is less than 9 bits long.
3486 * @param husart USART handle
3487 * @retval None
3488 */
USART_RxISR_8BIT(USART_HandleTypeDef * husart)3489 static void USART_RxISR_8BIT(USART_HandleTypeDef *husart)
3490 {
3491 const HAL_USART_StateTypeDef state = husart->State;
3492 uint16_t txdatacount;
3493 uint16_t uhMask = husart->Mask;
3494 uint32_t txftie;
3495
3496 if ((state == HAL_USART_STATE_BUSY_RX) ||
3497 (state == HAL_USART_STATE_BUSY_TX_RX))
3498 {
3499 *husart->pRxBuffPtr = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
3500 husart->pRxBuffPtr++;
3501 husart->RxXferCount--;
3502
3503 if (husart->RxXferCount == 0U)
3504 {
3505 /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
3506 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3507
3508 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3509 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
3510
3511 /* Clear RxISR function pointer */
3512 husart->RxISR = NULL;
3513
3514 /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3515 txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
3516 txdatacount = husart->TxXferCount;
3517
3518 if (state == HAL_USART_STATE_BUSY_RX)
3519 {
3520 /* Clear SPI slave underrun flag and discard transmit data */
3521 if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3522 {
3523 __HAL_USART_CLEAR_UDRFLAG(husart);
3524 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3525 }
3526
3527 /* Rx process is completed, restore husart->State to Ready */
3528 husart->State = HAL_USART_STATE_READY;
3529
3530 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3531 /* Call registered Rx Complete Callback */
3532 husart->RxCpltCallback(husart);
3533 #else
3534 /* Call legacy weak Rx Complete Callback */
3535 HAL_USART_RxCpltCallback(husart);
3536 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3537 }
3538 else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3539 (txftie != USART_CR3_TXFTIE) &&
3540 (txdatacount == 0U))
3541 {
3542 /* TxRx process is completed, restore husart->State to Ready */
3543 husart->State = HAL_USART_STATE_READY;
3544
3545 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3546 /* Call registered Tx Rx Complete Callback */
3547 husart->TxRxCpltCallback(husart);
3548 #else
3549 /* Call legacy weak Tx Rx Complete Callback */
3550 HAL_USART_TxRxCpltCallback(husart);
3551 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3552 }
3553 else
3554 {
3555 /* Nothing to do */
3556 }
3557 }
3558 else if ((state == HAL_USART_STATE_BUSY_RX) &&
3559 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3560 {
3561 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3562 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3563 }
3564 else
3565 {
3566 /* Nothing to do */
3567 }
3568 }
3569 }
3570
3571 /**
3572 * @brief Simplex receive an amount of data in non-blocking mode.
3573 * @note Function called under interruption only, once
3574 * interruptions have been enabled by HAL_USART_Receive_IT().
3575 * @note ISR function executed when FIFO mode is disabled and when the
3576 * data word length is 9 bits long.
3577 * @param husart USART handle
3578 * @retval None
3579 */
USART_RxISR_16BIT(USART_HandleTypeDef * husart)3580 static void USART_RxISR_16BIT(USART_HandleTypeDef *husart)
3581 {
3582 const HAL_USART_StateTypeDef state = husart->State;
3583 uint16_t txdatacount;
3584 uint16_t *tmp;
3585 uint16_t uhMask = husart->Mask;
3586 uint32_t txftie;
3587
3588 if ((state == HAL_USART_STATE_BUSY_RX) ||
3589 (state == HAL_USART_STATE_BUSY_TX_RX))
3590 {
3591 tmp = (uint16_t *) husart->pRxBuffPtr;
3592 *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
3593 husart->pRxBuffPtr += 2U;
3594 husart->RxXferCount--;
3595
3596 if (husart->RxXferCount == 0U)
3597 {
3598 /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
3599 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3600
3601 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3602 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
3603
3604 /* Clear RxISR function pointer */
3605 husart->RxISR = NULL;
3606
3607 /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3608 txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
3609 txdatacount = husart->TxXferCount;
3610
3611 if (state == HAL_USART_STATE_BUSY_RX)
3612 {
3613 /* Clear SPI slave underrun flag and discard transmit data */
3614 if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3615 {
3616 __HAL_USART_CLEAR_UDRFLAG(husart);
3617 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3618 }
3619
3620 /* Rx process is completed, restore husart->State to Ready */
3621 husart->State = HAL_USART_STATE_READY;
3622
3623 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3624 /* Call registered Rx Complete Callback */
3625 husart->RxCpltCallback(husart);
3626 #else
3627 /* Call legacy weak Rx Complete Callback */
3628 HAL_USART_RxCpltCallback(husart);
3629 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3630 }
3631 else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3632 (txftie != USART_CR3_TXFTIE) &&
3633 (txdatacount == 0U))
3634 {
3635 /* TxRx process is completed, restore husart->State to Ready */
3636 husart->State = HAL_USART_STATE_READY;
3637
3638 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3639 /* Call registered Tx Rx Complete Callback */
3640 husart->TxRxCpltCallback(husart);
3641 #else
3642 /* Call legacy weak Tx Rx Complete Callback */
3643 HAL_USART_TxRxCpltCallback(husart);
3644 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3645 }
3646 else
3647 {
3648 /* Nothing to do */
3649 }
3650 }
3651 else if ((state == HAL_USART_STATE_BUSY_RX) &&
3652 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3653 {
3654 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3655 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3656 }
3657 else
3658 {
3659 /* Nothing to do */
3660 }
3661 }
3662 }
3663
3664 /**
3665 * @brief Simplex receive an amount of data in non-blocking mode.
3666 * @note Function called under interruption only, once
3667 * interruptions have been enabled by HAL_USART_Receive_IT().
3668 * @note ISR function executed when FIFO mode is enabled and when the
3669 * data word length is less than 9 bits long.
3670 * @param husart USART handle
3671 * @retval None
3672 */
USART_RxISR_8BIT_FIFOEN(USART_HandleTypeDef * husart)3673 static void USART_RxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart)
3674 {
3675 HAL_USART_StateTypeDef state = husart->State;
3676 uint16_t txdatacount;
3677 uint16_t rxdatacount;
3678 uint16_t uhMask = husart->Mask;
3679 uint16_t nb_rx_data;
3680 uint32_t txftie;
3681
3682 /* Check that a Rx process is ongoing */
3683 if ((state == HAL_USART_STATE_BUSY_RX) ||
3684 (state == HAL_USART_STATE_BUSY_TX_RX))
3685 {
3686 for (nb_rx_data = husart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--)
3687 {
3688 if (__HAL_USART_GET_FLAG(husart, USART_FLAG_RXFNE) == SET)
3689 {
3690 *husart->pRxBuffPtr = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
3691 husart->pRxBuffPtr++;
3692 husart->RxXferCount--;
3693
3694 if (husart->RxXferCount == 0U)
3695 {
3696 /* Disable the USART Parity Error Interrupt */
3697 CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
3698
3699 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error)
3700 and RX FIFO Threshold interrupt */
3701 CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
3702
3703 /* Clear RxISR function pointer */
3704 husart->RxISR = NULL;
3705
3706 /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3707 txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
3708 txdatacount = husart->TxXferCount;
3709
3710 if (state == HAL_USART_STATE_BUSY_RX)
3711 {
3712 /* Clear SPI slave underrun flag and discard transmit data */
3713 if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3714 {
3715 __HAL_USART_CLEAR_UDRFLAG(husart);
3716 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3717 }
3718
3719 /* Rx process is completed, restore husart->State to Ready */
3720 husart->State = HAL_USART_STATE_READY;
3721 state = HAL_USART_STATE_READY;
3722
3723 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3724 /* Call registered Rx Complete Callback */
3725 husart->RxCpltCallback(husart);
3726 #else
3727 /* Call legacy weak Rx Complete Callback */
3728 HAL_USART_RxCpltCallback(husart);
3729 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3730 }
3731 else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3732 (txftie != USART_CR3_TXFTIE) &&
3733 (txdatacount == 0U))
3734 {
3735 /* TxRx process is completed, restore husart->State to Ready */
3736 husart->State = HAL_USART_STATE_READY;
3737 state = HAL_USART_STATE_READY;
3738
3739 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3740 /* Call registered Tx Rx Complete Callback */
3741 husart->TxRxCpltCallback(husart);
3742 #else
3743 /* Call legacy weak Tx Rx Complete Callback */
3744 HAL_USART_TxRxCpltCallback(husart);
3745 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3746 }
3747 else
3748 {
3749 /* Nothing to do */
3750 }
3751 }
3752 else if ((state == HAL_USART_STATE_BUSY_RX) &&
3753 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3754 {
3755 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3756 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3757 }
3758 else
3759 {
3760 /* Nothing to do */
3761 }
3762 }
3763 }
3764
3765 /* When remaining number of bytes to receive is less than the RX FIFO
3766 threshold, next incoming frames are processed as if FIFO mode was
3767 disabled (i.e. one interrupt per received frame).
3768 */
3769 rxdatacount = husart->RxXferCount;
3770 if (((rxdatacount != 0U)) && (rxdatacount < husart->NbRxDataToProcess))
3771 {
3772 /* Disable the USART RXFT interrupt*/
3773 CLEAR_BIT(husart->Instance->CR3, USART_CR3_RXFTIE);
3774
3775 /* Update the RxISR function pointer */
3776 husart->RxISR = USART_RxISR_8BIT;
3777
3778 /* Enable the USART Data Register Not Empty interrupt */
3779 SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
3780
3781 if ((husart->TxXferCount == 0U) &&
3782 (state == HAL_USART_STATE_BUSY_TX_RX) &&
3783 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3784 {
3785 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3786 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3787 }
3788 }
3789 }
3790 else
3791 {
3792 /* Clear RXNE interrupt flag */
3793 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
3794 }
3795 }
3796
3797 /**
3798 * @brief Simplex receive an amount of data in non-blocking mode.
3799 * @note Function called under interruption only, once
3800 * interruptions have been enabled by HAL_USART_Receive_IT().
3801 * @note ISR function executed when FIFO mode is enabled and when the
3802 * data word length is 9 bits long.
3803 * @param husart USART handle
3804 * @retval None
3805 */
USART_RxISR_16BIT_FIFOEN(USART_HandleTypeDef * husart)3806 static void USART_RxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart)
3807 {
3808 HAL_USART_StateTypeDef state = husart->State;
3809 uint16_t txdatacount;
3810 uint16_t rxdatacount;
3811 uint16_t *tmp;
3812 uint16_t uhMask = husart->Mask;
3813 uint16_t nb_rx_data;
3814 uint32_t txftie;
3815
3816 /* Check that a Tx process is ongoing */
3817 if ((state == HAL_USART_STATE_BUSY_RX) ||
3818 (state == HAL_USART_STATE_BUSY_TX_RX))
3819 {
3820 for (nb_rx_data = husart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--)
3821 {
3822 if (__HAL_USART_GET_FLAG(husart, USART_FLAG_RXFNE) == SET)
3823 {
3824 tmp = (uint16_t *) husart->pRxBuffPtr;
3825 *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
3826 husart->pRxBuffPtr += 2U;
3827 husart->RxXferCount--;
3828
3829 if (husart->RxXferCount == 0U)
3830 {
3831 /* Disable the USART Parity Error Interrupt */
3832 CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
3833
3834 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error)
3835 and RX FIFO Threshold interrupt */
3836 CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
3837
3838 /* Clear RxISR function pointer */
3839 husart->RxISR = NULL;
3840
3841 /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3842 txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
3843 txdatacount = husart->TxXferCount;
3844
3845 if (state == HAL_USART_STATE_BUSY_RX)
3846 {
3847 /* Clear SPI slave underrun flag and discard transmit data */
3848 if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
3849 {
3850 __HAL_USART_CLEAR_UDRFLAG(husart);
3851 __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
3852 }
3853
3854 /* Rx process is completed, restore husart->State to Ready */
3855 husart->State = HAL_USART_STATE_READY;
3856 state = HAL_USART_STATE_READY;
3857
3858 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3859 /* Call registered Rx Complete Callback */
3860 husart->RxCpltCallback(husart);
3861 #else
3862 /* Call legacy weak Rx Complete Callback */
3863 HAL_USART_RxCpltCallback(husart);
3864 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3865 }
3866 else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
3867 (txftie != USART_CR3_TXFTIE) &&
3868 (txdatacount == 0U))
3869 {
3870 /* TxRx process is completed, restore husart->State to Ready */
3871 husart->State = HAL_USART_STATE_READY;
3872 state = HAL_USART_STATE_READY;
3873
3874 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3875 /* Call registered Tx Rx Complete Callback */
3876 husart->TxRxCpltCallback(husart);
3877 #else
3878 /* Call legacy weak Tx Rx Complete Callback */
3879 HAL_USART_TxRxCpltCallback(husart);
3880 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3881 }
3882 else
3883 {
3884 /* Nothing to do */
3885 }
3886 }
3887 else if ((state == HAL_USART_STATE_BUSY_RX) &&
3888 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3889 {
3890 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3891 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3892 }
3893 else
3894 {
3895 /* Nothing to do */
3896 }
3897 }
3898 }
3899
3900 /* When remaining number of bytes to receive is less than the RX FIFO
3901 threshold, next incoming frames are processed as if FIFO mode was
3902 disabled (i.e. one interrupt per received frame).
3903 */
3904 rxdatacount = husart->RxXferCount;
3905 if (((rxdatacount != 0U)) && (rxdatacount < husart->NbRxDataToProcess))
3906 {
3907 /* Disable the USART RXFT interrupt*/
3908 CLEAR_BIT(husart->Instance->CR3, USART_CR3_RXFTIE);
3909
3910 /* Update the RxISR function pointer */
3911 husart->RxISR = USART_RxISR_16BIT;
3912
3913 /* Enable the USART Data Register Not Empty interrupt */
3914 SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
3915
3916 if ((husart->TxXferCount == 0U) &&
3917 (state == HAL_USART_STATE_BUSY_TX_RX) &&
3918 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
3919 {
3920 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3921 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
3922 }
3923 }
3924 }
3925 else
3926 {
3927 /* Clear RXNE interrupt flag */
3928 __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
3929 }
3930 }
3931
3932 /**
3933 * @}
3934 */
3935
3936 #endif /* HAL_USART_MODULE_ENABLED */
3937 /**
3938 * @}
3939 */
3940
3941 /**
3942 * @}
3943 */
3944
3945