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