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