1 /**
2 ******************************************************************************
3 * @file stm32c0xx_hal_uart.c
4 * @author MCD Application Team
5 * @brief UART HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART).
8 * + Initialization and de-initialization functions
9 * + IO operation functions
10 * + Peripheral Control functions
11 *
12 *
13 ******************************************************************************
14 * @attention
15 *
16 * Copyright (c) 2022 STMicroelectronics.
17 * All rights reserved.
18 *
19 * This software is licensed under terms that can be found in the LICENSE file
20 * in the root directory of this software component.
21 * If no LICENSE file comes with this software, it is provided AS-IS.
22 *
23 ******************************************************************************
24 @verbatim
25 ===============================================================================
26 ##### How to use this driver #####
27 ===============================================================================
28 [..]
29 The UART HAL driver can be used as follows:
30
31 (#) Declare a UART_HandleTypeDef handle structure (eg. UART_HandleTypeDef huart).
32 (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API:
33 (++) Enable the USARTx interface clock.
34 (++) UART pins configuration:
35 (+++) Enable the clock for the UART GPIOs.
36 (+++) Configure these UART pins as alternate function pull-up.
37 (++) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT()
38 and HAL_UART_Receive_IT() APIs):
39 (+++) Configure the USARTx interrupt priority.
40 (+++) Enable the NVIC USART IRQ handle.
41 (++) UART interrupts handling:
42 -@@- The specific UART interrupts (Transmission complete interrupt,
43 RXNE interrupt, RX/TX FIFOs related interrupts and Error Interrupts)
44 are managed using the macros __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT()
45 inside the transmit and receive processes.
46 (++) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
47 and HAL_UART_Receive_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 UART DMA Tx/Rx handle.
53 (+++) Configure the priority and enable the NVIC for the transfer complete
54 interrupt on the DMA Tx/Rx channel.
55
56 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Prescaler value , Hardware
57 flow control and Mode (Receiver/Transmitter) in the huart handle Init structure.
58
59 (#) If required, program UART advanced features (TX/RX pins swap, auto Baud rate detection,...)
60 in the huart handle AdvancedInit structure.
61
62 (#) For the UART asynchronous mode, initialize the UART registers by calling
63 the HAL_UART_Init() API.
64
65 (#) For the UART Half duplex mode, initialize the UART registers by calling
66 the HAL_HalfDuplex_Init() API.
67
68 (#) For the UART LIN (Local Interconnection Network) mode, initialize the UART registers
69 by calling the HAL_LIN_Init() API.
70
71 (#) For the UART Multiprocessor mode, initialize the UART registers
72 by calling the HAL_MultiProcessor_Init() API.
73
74 (#) For the UART RS485 Driver Enabled mode, initialize the UART registers
75 by calling the HAL_RS485Ex_Init() API.
76
77 [..]
78 (@) These API's (HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init(), HAL_MultiProcessor_Init(),
79 also configure the low level Hardware GPIO, CLOCK, CORTEX...etc) by
80 calling the customized HAL_UART_MspInit() API.
81
82 ##### Callback registration #####
83 ==================================
84
85 [..]
86 The compilation define USE_HAL_UART_REGISTER_CALLBACKS when set to 1
87 allows the user to configure dynamically the driver callbacks.
88
89 [..]
90 Use Function HAL_UART_RegisterCallback() to register a user callback.
91 Function HAL_UART_RegisterCallback() allows to register following callbacks:
92 (+) TxHalfCpltCallback : Tx Half Complete Callback.
93 (+) TxCpltCallback : Tx Complete Callback.
94 (+) RxHalfCpltCallback : Rx Half Complete Callback.
95 (+) RxCpltCallback : Rx Complete Callback.
96 (+) ErrorCallback : Error Callback.
97 (+) AbortCpltCallback : Abort Complete Callback.
98 (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
99 (+) AbortReceiveCpltCallback : Abort Receive Complete Callback.
100 (+) WakeupCallback : Wakeup Callback.
101 (+) RxFifoFullCallback : Rx Fifo Full Callback.
102 (+) TxFifoEmptyCallback : Tx Fifo Empty Callback.
103 (+) MspInitCallback : UART MspInit.
104 (+) MspDeInitCallback : UART MspDeInit.
105 This function takes as parameters the HAL peripheral handle, the Callback ID
106 and a pointer to the user callback function.
107
108 [..]
109 Use function HAL_UART_UnRegisterCallback() to reset a callback to the default
110 weak function.
111 HAL_UART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
112 and the Callback ID.
113 This function allows to reset following callbacks:
114 (+) TxHalfCpltCallback : Tx Half Complete Callback.
115 (+) TxCpltCallback : Tx Complete Callback.
116 (+) RxHalfCpltCallback : Rx Half Complete Callback.
117 (+) RxCpltCallback : Rx Complete Callback.
118 (+) ErrorCallback : Error Callback.
119 (+) AbortCpltCallback : Abort Complete Callback.
120 (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
121 (+) AbortReceiveCpltCallback : Abort Receive Complete Callback.
122 (+) WakeupCallback : Wakeup Callback.
123 (+) RxFifoFullCallback : Rx Fifo Full Callback.
124 (+) TxFifoEmptyCallback : Tx Fifo Empty Callback.
125 (+) MspInitCallback : UART MspInit.
126 (+) MspDeInitCallback : UART MspDeInit.
127
128 [..]
129 For specific callback RxEventCallback, use dedicated registration/reset functions:
130 respectively HAL_UART_RegisterRxEventCallback() , HAL_UART_UnRegisterRxEventCallback().
131
132 [..]
133 By default, after the HAL_UART_Init() and when the state is HAL_UART_STATE_RESET
134 all callbacks are set to the corresponding weak functions:
135 examples HAL_UART_TxCpltCallback(), HAL_UART_RxHalfCpltCallback().
136 Exception done for MspInit and MspDeInit functions that are respectively
137 reset to the legacy weak functions in the HAL_UART_Init()
138 and HAL_UART_DeInit() only when these callbacks are null (not registered beforehand).
139 If not, MspInit or MspDeInit are not null, the HAL_UART_Init() and HAL_UART_DeInit()
140 keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
141
142 [..]
143 Callbacks can be registered/unregistered in HAL_UART_STATE_READY state only.
144 Exception done MspInit/MspDeInit that can be registered/unregistered
145 in HAL_UART_STATE_READY or HAL_UART_STATE_RESET state, thus registered (user)
146 MspInit/DeInit callbacks can be used during the Init/DeInit.
147 In that case first register the MspInit/MspDeInit user callbacks
148 using HAL_UART_RegisterCallback() before calling HAL_UART_DeInit()
149 or HAL_UART_Init() function.
150
151 [..]
152 When The compilation define USE_HAL_UART_REGISTER_CALLBACKS is set to 0 or
153 not defined, the callback registration feature is not available
154 and weak callbacks are used.
155
156
157 @endverbatim
158 ******************************************************************************
159 */
160
161 /* Includes ------------------------------------------------------------------*/
162 #include "stm32c0xx_hal.h"
163
164 /** @addtogroup STM32C0xx_HAL_Driver
165 * @{
166 */
167
168 /** @defgroup UART UART
169 * @brief HAL UART module driver
170 * @{
171 */
172
173 #ifdef HAL_UART_MODULE_ENABLED
174
175 /* Private typedef -----------------------------------------------------------*/
176 /* Private define ------------------------------------------------------------*/
177 /** @defgroup UART_Private_Constants UART Private Constants
178 * @{
179 */
180 #define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | \
181 USART_CR1_OVER8 | USART_CR1_FIFOEN)) /*!< UART or USART CR1 fields of parameters set by UART_SetConfig API */
182
183 #define USART_CR3_FIELDS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT | USART_CR3_TXFTCFG | \
184 USART_CR3_RXFTCFG)) /*!< UART or USART CR3 fields of parameters set by UART_SetConfig API */
185
186
187 #define UART_BRR_MIN 0x10U /* UART BRR minimum authorized value */
188 #define UART_BRR_MAX 0x0000FFFFU /* UART BRR maximum authorized value */
189 /**
190 * @}
191 */
192
193 /* Private macros ------------------------------------------------------------*/
194 /* Private function prototypes -----------------------------------------------*/
195 /** @addtogroup UART_Private_Functions
196 * @{
197 */
198 static void UART_EndRxTransfer(UART_HandleTypeDef *huart);
199 #if defined(HAL_DMA_MODULE_ENABLED)
200 static void UART_EndTxTransfer(UART_HandleTypeDef *huart);
201 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
202 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
203 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
204 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
205 static void UART_DMAError(DMA_HandleTypeDef *hdma);
206 static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
207 static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
208 static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
209 static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
210 static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
211 #endif /* HAL_DMA_MODULE_ENABLED */
212 static void UART_TxISR_8BIT(UART_HandleTypeDef *huart);
213 static void UART_TxISR_16BIT(UART_HandleTypeDef *huart);
214 static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart);
215 static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart);
216 static void UART_EndTransmit_IT(UART_HandleTypeDef *huart);
217 static void UART_RxISR_8BIT(UART_HandleTypeDef *huart);
218 static void UART_RxISR_16BIT(UART_HandleTypeDef *huart);
219 static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart);
220 static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart);
221 /**
222 * @}
223 */
224
225 /* Private variables ---------------------------------------------------------*/
226 /** @addtogroup UART_Private_variables
227 * @{
228 */
229 const uint16_t UARTPrescTable[12] = {1U, 2U, 4U, 6U, 8U, 10U, 12U, 16U, 32U, 64U, 128U, 256U};
230 /**
231 * @}
232 */
233
234 /* Exported Constants --------------------------------------------------------*/
235 /* Exported functions --------------------------------------------------------*/
236
237 /** @defgroup UART_Exported_Functions UART Exported Functions
238 * @{
239 */
240
241 /** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
242 * @brief Initialization and Configuration functions
243 *
244 @verbatim
245 ===============================================================================
246 ##### Initialization and Configuration functions #####
247 ===============================================================================
248 [..]
249 This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
250 in asynchronous mode.
251 (+) For the asynchronous mode the parameters below can be configured:
252 (++) Baud Rate
253 (++) Word Length
254 (++) Stop Bit
255 (++) Parity: If the parity is enabled, then the MSB bit of the data written
256 in the data register is transmitted but is changed by the parity bit.
257 (++) Hardware flow control
258 (++) Receiver/transmitter modes
259 (++) Over Sampling Method
260 (++) One-Bit Sampling Method
261 (+) For the asynchronous mode, the following advanced features can be configured as well:
262 (++) TX and/or RX pin level inversion
263 (++) data logical level inversion
264 (++) RX and TX pins swap
265 (++) RX overrun detection disabling
266 (++) DMA disabling on RX error
267 (++) MSB first on communication line
268 (++) auto Baud rate detection
269 [..]
270 The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init()and HAL_MultiProcessor_Init()API
271 follow respectively the UART asynchronous, UART Half duplex, UART LIN mode
272 and UART multiprocessor mode configuration procedures (details for the procedures
273 are available in reference manual).
274
275 @endverbatim
276
277 Depending on the frame length defined by the M1 and M0 bits (7-bit,
278 8-bit or 9-bit), the possible UART formats are listed in the
279 following table.
280
281 Table 1. UART frame format.
282 +-----------------------------------------------------------------------+
283 | M1 bit | M0 bit | PCE bit | UART frame |
284 |---------|---------|-----------|---------------------------------------|
285 | 0 | 0 | 0 | | SB | 8 bit data | STB | |
286 |---------|---------|-----------|---------------------------------------|
287 | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | |
288 |---------|---------|-----------|---------------------------------------|
289 | 0 | 1 | 0 | | SB | 9 bit data | STB | |
290 |---------|---------|-----------|---------------------------------------|
291 | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | |
292 |---------|---------|-----------|---------------------------------------|
293 | 1 | 0 | 0 | | SB | 7 bit data | STB | |
294 |---------|---------|-----------|---------------------------------------|
295 | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | |
296 +-----------------------------------------------------------------------+
297
298 * @{
299 */
300
301 /**
302 * @brief Initialize the UART mode according to the specified
303 * parameters in the UART_InitTypeDef and initialize the associated handle.
304 * @param huart UART handle.
305 * @retval HAL status
306 */
HAL_UART_Init(UART_HandleTypeDef * huart)307 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
308 {
309 /* Check the UART handle allocation */
310 if (huart == NULL)
311 {
312 return HAL_ERROR;
313 }
314
315 if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
316 {
317 /* Check the parameters */
318 assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
319 }
320 else
321 {
322 /* Check the parameters */
323 assert_param(IS_UART_INSTANCE(huart->Instance));
324 }
325
326 if (huart->gState == HAL_UART_STATE_RESET)
327 {
328 /* Allocate lock resource and initialize it */
329 huart->Lock = HAL_UNLOCKED;
330
331 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
332 UART_InitCallbacksToDefault(huart);
333
334 if (huart->MspInitCallback == NULL)
335 {
336 huart->MspInitCallback = HAL_UART_MspInit;
337 }
338
339 /* Init the low level hardware */
340 huart->MspInitCallback(huart);
341 #else
342 /* Init the low level hardware : GPIO, CLOCK */
343 HAL_UART_MspInit(huart);
344 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
345 }
346
347 huart->gState = HAL_UART_STATE_BUSY;
348
349 __HAL_UART_DISABLE(huart);
350
351 /* Perform advanced settings configuration */
352 /* For some items, configuration requires to be done prior TE and RE bits are set */
353 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
354 {
355 UART_AdvFeatureConfig(huart);
356 }
357
358 /* Set the UART Communication parameters */
359 if (UART_SetConfig(huart) == HAL_ERROR)
360 {
361 return HAL_ERROR;
362 }
363
364 /* In asynchronous mode, the following bits must be kept cleared:
365 - LINEN and CLKEN bits in the USART_CR2 register,
366 - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
367 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
368 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
369
370 __HAL_UART_ENABLE(huart);
371
372 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
373 return (UART_CheckIdleState(huart));
374 }
375
376 /**
377 * @brief Initialize the half-duplex mode according to the specified
378 * parameters in the UART_InitTypeDef and creates the associated handle.
379 * @param huart UART handle.
380 * @retval HAL status
381 */
HAL_HalfDuplex_Init(UART_HandleTypeDef * huart)382 HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart)
383 {
384 /* Check the UART handle allocation */
385 if (huart == NULL)
386 {
387 return HAL_ERROR;
388 }
389
390 /* Check UART instance */
391 assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance));
392
393 if (huart->gState == HAL_UART_STATE_RESET)
394 {
395 /* Allocate lock resource and initialize it */
396 huart->Lock = HAL_UNLOCKED;
397
398 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
399 UART_InitCallbacksToDefault(huart);
400
401 if (huart->MspInitCallback == NULL)
402 {
403 huart->MspInitCallback = HAL_UART_MspInit;
404 }
405
406 /* Init the low level hardware */
407 huart->MspInitCallback(huart);
408 #else
409 /* Init the low level hardware : GPIO, CLOCK */
410 HAL_UART_MspInit(huart);
411 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
412 }
413
414 huart->gState = HAL_UART_STATE_BUSY;
415
416 __HAL_UART_DISABLE(huart);
417
418 /* Perform advanced settings configuration */
419 /* For some items, configuration requires to be done prior TE and RE bits are set */
420 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
421 {
422 UART_AdvFeatureConfig(huart);
423 }
424
425 /* Set the UART Communication parameters */
426 if (UART_SetConfig(huart) == HAL_ERROR)
427 {
428 return HAL_ERROR;
429 }
430
431 /* In half-duplex mode, the following bits must be kept cleared:
432 - LINEN and CLKEN bits in the USART_CR2 register,
433 - SCEN and IREN bits in the USART_CR3 register.*/
434 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
435 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN));
436
437 /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
438 SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
439
440 __HAL_UART_ENABLE(huart);
441
442 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
443 return (UART_CheckIdleState(huart));
444 }
445
446
447 /**
448 * @brief Initialize the LIN mode according to the specified
449 * parameters in the UART_InitTypeDef and creates the associated handle.
450 * @param huart UART handle.
451 * @param BreakDetectLength Specifies the LIN break detection length.
452 * This parameter can be one of the following values:
453 * @arg @ref UART_LINBREAKDETECTLENGTH_10B 10-bit break detection
454 * @arg @ref UART_LINBREAKDETECTLENGTH_11B 11-bit break detection
455 * @retval HAL status
456 */
HAL_LIN_Init(UART_HandleTypeDef * huart,uint32_t BreakDetectLength)457 HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength)
458 {
459 /* Check the UART handle allocation */
460 if (huart == NULL)
461 {
462 return HAL_ERROR;
463 }
464
465 /* Check the LIN UART instance */
466 assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
467 /* Check the Break detection length parameter */
468 assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength));
469
470 /* LIN mode limited to 16-bit oversampling only */
471 if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
472 {
473 return HAL_ERROR;
474 }
475 /* LIN mode limited to 8-bit data length */
476 if (huart->Init.WordLength != UART_WORDLENGTH_8B)
477 {
478 return HAL_ERROR;
479 }
480
481 if (huart->gState == HAL_UART_STATE_RESET)
482 {
483 /* Allocate lock resource and initialize it */
484 huart->Lock = HAL_UNLOCKED;
485
486 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
487 UART_InitCallbacksToDefault(huart);
488
489 if (huart->MspInitCallback == NULL)
490 {
491 huart->MspInitCallback = HAL_UART_MspInit;
492 }
493
494 /* Init the low level hardware */
495 huart->MspInitCallback(huart);
496 #else
497 /* Init the low level hardware : GPIO, CLOCK */
498 HAL_UART_MspInit(huart);
499 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
500 }
501
502 huart->gState = HAL_UART_STATE_BUSY;
503
504 __HAL_UART_DISABLE(huart);
505
506 /* Perform advanced settings configuration */
507 /* For some items, configuration requires to be done prior TE and RE bits are set */
508 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
509 {
510 UART_AdvFeatureConfig(huart);
511 }
512
513 /* Set the UART Communication parameters */
514 if (UART_SetConfig(huart) == HAL_ERROR)
515 {
516 return HAL_ERROR;
517 }
518
519 /* In LIN mode, the following bits must be kept cleared:
520 - LINEN and CLKEN bits in the USART_CR2 register,
521 - SCEN and IREN bits in the USART_CR3 register.*/
522 CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN);
523 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN));
524
525 /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
526 SET_BIT(huart->Instance->CR2, USART_CR2_LINEN);
527
528 /* Set the USART LIN Break detection length. */
529 MODIFY_REG(huart->Instance->CR2, USART_CR2_LBDL, BreakDetectLength);
530
531 __HAL_UART_ENABLE(huart);
532
533 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
534 return (UART_CheckIdleState(huart));
535 }
536
537
538 /**
539 * @brief Initialize the multiprocessor mode according to the specified
540 * parameters in the UART_InitTypeDef and initialize the associated handle.
541 * @param huart UART handle.
542 * @param Address UART node address (4-, 6-, 7- or 8-bit long).
543 * @param WakeUpMethod Specifies the UART wakeup method.
544 * This parameter can be one of the following values:
545 * @arg @ref UART_WAKEUPMETHOD_IDLELINE WakeUp by an idle line detection
546 * @arg @ref UART_WAKEUPMETHOD_ADDRESSMARK WakeUp by an address mark
547 * @note If the user resorts to idle line detection wake up, the Address parameter
548 * is useless and ignored by the initialization function.
549 * @note If the user resorts to address mark wake up, the address length detection
550 * is configured by default to 4 bits only. For the UART to be able to
551 * manage 6-, 7- or 8-bit long addresses detection, the API
552 * HAL_MultiProcessorEx_AddressLength_Set() must be called after
553 * HAL_MultiProcessor_Init().
554 * @retval HAL status
555 */
HAL_MultiProcessor_Init(UART_HandleTypeDef * huart,uint8_t Address,uint32_t WakeUpMethod)556 HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod)
557 {
558 /* Check the UART handle allocation */
559 if (huart == NULL)
560 {
561 return HAL_ERROR;
562 }
563
564 /* Check the wake up method parameter */
565 assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod));
566
567 if (huart->gState == HAL_UART_STATE_RESET)
568 {
569 /* Allocate lock resource and initialize it */
570 huart->Lock = HAL_UNLOCKED;
571
572 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
573 UART_InitCallbacksToDefault(huart);
574
575 if (huart->MspInitCallback == NULL)
576 {
577 huart->MspInitCallback = HAL_UART_MspInit;
578 }
579
580 /* Init the low level hardware */
581 huart->MspInitCallback(huart);
582 #else
583 /* Init the low level hardware : GPIO, CLOCK */
584 HAL_UART_MspInit(huart);
585 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
586 }
587
588 huart->gState = HAL_UART_STATE_BUSY;
589
590 __HAL_UART_DISABLE(huart);
591
592 /* Perform advanced settings configuration */
593 /* For some items, configuration requires to be done prior TE and RE bits are set */
594 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
595 {
596 UART_AdvFeatureConfig(huart);
597 }
598
599 /* Set the UART Communication parameters */
600 if (UART_SetConfig(huart) == HAL_ERROR)
601 {
602 return HAL_ERROR;
603 }
604
605 /* In multiprocessor mode, the following bits must be kept cleared:
606 - LINEN and CLKEN bits in the USART_CR2 register,
607 - SCEN, HDSEL and IREN bits in the USART_CR3 register. */
608 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
609 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
610
611 if (WakeUpMethod == UART_WAKEUPMETHOD_ADDRESSMARK)
612 {
613 /* If address mark wake up method is chosen, set the USART address node */
614 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)Address << UART_CR2_ADDRESS_LSB_POS));
615 }
616
617 /* Set the wake up method by setting the WAKE bit in the CR1 register */
618 MODIFY_REG(huart->Instance->CR1, USART_CR1_WAKE, WakeUpMethod);
619
620 __HAL_UART_ENABLE(huart);
621
622 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
623 return (UART_CheckIdleState(huart));
624 }
625
626
627 /**
628 * @brief DeInitialize the UART peripheral.
629 * @param huart UART handle.
630 * @retval HAL status
631 */
HAL_UART_DeInit(UART_HandleTypeDef * huart)632 HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
633 {
634 /* Check the UART handle allocation */
635 if (huart == NULL)
636 {
637 return HAL_ERROR;
638 }
639
640 /* Check the parameters */
641 assert_param(IS_UART_INSTANCE(huart->Instance));
642
643 huart->gState = HAL_UART_STATE_BUSY;
644
645 __HAL_UART_DISABLE(huart);
646
647 huart->Instance->CR1 = 0x0U;
648 huart->Instance->CR2 = 0x0U;
649 huart->Instance->CR3 = 0x0U;
650
651 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
652 if (huart->MspDeInitCallback == NULL)
653 {
654 huart->MspDeInitCallback = HAL_UART_MspDeInit;
655 }
656 /* DeInit the low level hardware */
657 huart->MspDeInitCallback(huart);
658 #else
659 /* DeInit the low level hardware */
660 HAL_UART_MspDeInit(huart);
661 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
662
663 huart->ErrorCode = HAL_UART_ERROR_NONE;
664 huart->gState = HAL_UART_STATE_RESET;
665 huart->RxState = HAL_UART_STATE_RESET;
666 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
667 huart->RxEventType = HAL_UART_RXEVENT_TC;
668
669 __HAL_UNLOCK(huart);
670
671 return HAL_OK;
672 }
673
674 /**
675 * @brief Initialize the UART MSP.
676 * @param huart UART handle.
677 * @retval None
678 */
HAL_UART_MspInit(UART_HandleTypeDef * huart)679 __weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
680 {
681 /* Prevent unused argument(s) compilation warning */
682 UNUSED(huart);
683
684 /* NOTE : This function should not be modified, when the callback is needed,
685 the HAL_UART_MspInit can be implemented in the user file
686 */
687 }
688
689 /**
690 * @brief DeInitialize the UART MSP.
691 * @param huart UART handle.
692 * @retval None
693 */
HAL_UART_MspDeInit(UART_HandleTypeDef * huart)694 __weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
695 {
696 /* Prevent unused argument(s) compilation warning */
697 UNUSED(huart);
698
699 /* NOTE : This function should not be modified, when the callback is needed,
700 the HAL_UART_MspDeInit can be implemented in the user file
701 */
702 }
703
704 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
705 /**
706 * @brief Register a User UART Callback
707 * To be used to override the weak predefined callback
708 * @note The HAL_UART_RegisterCallback() may be called before HAL_UART_Init(), HAL_HalfDuplex_Init(),
709 * HAL_LIN_Init(), HAL_MultiProcessor_Init() or HAL_RS485Ex_Init() in HAL_UART_STATE_RESET to register
710 * callbacks for HAL_UART_MSPINIT_CB_ID and HAL_UART_MSPDEINIT_CB_ID
711 * @param huart uart handle
712 * @param CallbackID ID of the callback to be registered
713 * This parameter can be one of the following values:
714 * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
715 * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
716 * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
717 * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
718 * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
719 * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
720 * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
721 * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
722 * @arg @ref HAL_UART_WAKEUP_CB_ID Wakeup Callback ID
723 * @arg @ref HAL_UART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
724 * @arg @ref HAL_UART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
725 * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
726 * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
727 * @param pCallback pointer to the Callback function
728 * @retval HAL status
729 */
HAL_UART_RegisterCallback(UART_HandleTypeDef * huart,HAL_UART_CallbackIDTypeDef CallbackID,pUART_CallbackTypeDef pCallback)730 HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID,
731 pUART_CallbackTypeDef pCallback)
732 {
733 HAL_StatusTypeDef status = HAL_OK;
734
735 if (pCallback == NULL)
736 {
737 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
738
739 return HAL_ERROR;
740 }
741
742 if (huart->gState == HAL_UART_STATE_READY)
743 {
744 switch (CallbackID)
745 {
746 case HAL_UART_TX_HALFCOMPLETE_CB_ID :
747 huart->TxHalfCpltCallback = pCallback;
748 break;
749
750 case HAL_UART_TX_COMPLETE_CB_ID :
751 huart->TxCpltCallback = pCallback;
752 break;
753
754 case HAL_UART_RX_HALFCOMPLETE_CB_ID :
755 huart->RxHalfCpltCallback = pCallback;
756 break;
757
758 case HAL_UART_RX_COMPLETE_CB_ID :
759 huart->RxCpltCallback = pCallback;
760 break;
761
762 case HAL_UART_ERROR_CB_ID :
763 huart->ErrorCallback = pCallback;
764 break;
765
766 case HAL_UART_ABORT_COMPLETE_CB_ID :
767 huart->AbortCpltCallback = pCallback;
768 break;
769
770 case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
771 huart->AbortTransmitCpltCallback = pCallback;
772 break;
773
774 case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
775 huart->AbortReceiveCpltCallback = pCallback;
776 break;
777
778 case HAL_UART_WAKEUP_CB_ID :
779 huart->WakeupCallback = pCallback;
780 break;
781
782 case HAL_UART_RX_FIFO_FULL_CB_ID :
783 huart->RxFifoFullCallback = pCallback;
784 break;
785
786 case HAL_UART_TX_FIFO_EMPTY_CB_ID :
787 huart->TxFifoEmptyCallback = pCallback;
788 break;
789
790 case HAL_UART_MSPINIT_CB_ID :
791 huart->MspInitCallback = pCallback;
792 break;
793
794 case HAL_UART_MSPDEINIT_CB_ID :
795 huart->MspDeInitCallback = pCallback;
796 break;
797
798 default :
799 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
800
801 status = HAL_ERROR;
802 break;
803 }
804 }
805 else if (huart->gState == HAL_UART_STATE_RESET)
806 {
807 switch (CallbackID)
808 {
809 case HAL_UART_MSPINIT_CB_ID :
810 huart->MspInitCallback = pCallback;
811 break;
812
813 case HAL_UART_MSPDEINIT_CB_ID :
814 huart->MspDeInitCallback = pCallback;
815 break;
816
817 default :
818 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
819
820 status = HAL_ERROR;
821 break;
822 }
823 }
824 else
825 {
826 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
827
828 status = HAL_ERROR;
829 }
830
831 return status;
832 }
833
834 /**
835 * @brief Unregister an UART Callback
836 * UART callaback is redirected to the weak predefined callback
837 * @note The HAL_UART_UnRegisterCallback() may be called before HAL_UART_Init(), HAL_HalfDuplex_Init(),
838 * HAL_LIN_Init(), HAL_MultiProcessor_Init() or HAL_RS485Ex_Init() in HAL_UART_STATE_RESET to un-register
839 * callbacks for HAL_UART_MSPINIT_CB_ID and HAL_UART_MSPDEINIT_CB_ID
840 * @param huart uart handle
841 * @param CallbackID ID of the callback to be unregistered
842 * This parameter can be one of the following values:
843 * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
844 * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
845 * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
846 * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
847 * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
848 * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
849 * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
850 * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
851 * @arg @ref HAL_UART_WAKEUP_CB_ID Wakeup Callback ID
852 * @arg @ref HAL_UART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
853 * @arg @ref HAL_UART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
854 * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
855 * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
856 * @retval HAL status
857 */
HAL_UART_UnRegisterCallback(UART_HandleTypeDef * huart,HAL_UART_CallbackIDTypeDef CallbackID)858 HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID)
859 {
860 HAL_StatusTypeDef status = HAL_OK;
861
862 if (HAL_UART_STATE_READY == huart->gState)
863 {
864 switch (CallbackID)
865 {
866 case HAL_UART_TX_HALFCOMPLETE_CB_ID :
867 huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
868 break;
869
870 case HAL_UART_TX_COMPLETE_CB_ID :
871 huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */
872 break;
873
874 case HAL_UART_RX_HALFCOMPLETE_CB_ID :
875 huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
876 break;
877
878 case HAL_UART_RX_COMPLETE_CB_ID :
879 huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */
880 break;
881
882 case HAL_UART_ERROR_CB_ID :
883 huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */
884 break;
885
886 case HAL_UART_ABORT_COMPLETE_CB_ID :
887 huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
888 break;
889
890 case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
891 huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak
892 AbortTransmitCpltCallback */
893 break;
894
895 case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
896 huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak
897 AbortReceiveCpltCallback */
898 break;
899
900 case HAL_UART_WAKEUP_CB_ID :
901 huart->WakeupCallback = HAL_UARTEx_WakeupCallback; /* Legacy weak WakeupCallback */
902 break;
903
904 case HAL_UART_RX_FIFO_FULL_CB_ID :
905 huart->RxFifoFullCallback = HAL_UARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */
906 break;
907
908 case HAL_UART_TX_FIFO_EMPTY_CB_ID :
909 huart->TxFifoEmptyCallback = HAL_UARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */
910 break;
911
912 case HAL_UART_MSPINIT_CB_ID :
913 huart->MspInitCallback = HAL_UART_MspInit; /* Legacy weak MspInitCallback */
914 break;
915
916 case HAL_UART_MSPDEINIT_CB_ID :
917 huart->MspDeInitCallback = HAL_UART_MspDeInit; /* Legacy weak MspDeInitCallback */
918 break;
919
920 default :
921 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
922
923 status = HAL_ERROR;
924 break;
925 }
926 }
927 else if (HAL_UART_STATE_RESET == huart->gState)
928 {
929 switch (CallbackID)
930 {
931 case HAL_UART_MSPINIT_CB_ID :
932 huart->MspInitCallback = HAL_UART_MspInit;
933 break;
934
935 case HAL_UART_MSPDEINIT_CB_ID :
936 huart->MspDeInitCallback = HAL_UART_MspDeInit;
937 break;
938
939 default :
940 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
941
942 status = HAL_ERROR;
943 break;
944 }
945 }
946 else
947 {
948 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
949
950 status = HAL_ERROR;
951 }
952
953 return status;
954 }
955
956 /**
957 * @brief Register a User UART Rx Event Callback
958 * To be used instead of the weak predefined callback
959 * @param huart Uart handle
960 * @param pCallback Pointer to the Rx Event Callback function
961 * @retval HAL status
962 */
HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef * huart,pUART_RxEventCallbackTypeDef pCallback)963 HAL_StatusTypeDef HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef *huart, pUART_RxEventCallbackTypeDef pCallback)
964 {
965 HAL_StatusTypeDef status = HAL_OK;
966
967 if (pCallback == NULL)
968 {
969 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
970
971 return HAL_ERROR;
972 }
973
974 /* Process locked */
975 __HAL_LOCK(huart);
976
977 if (huart->gState == HAL_UART_STATE_READY)
978 {
979 huart->RxEventCallback = pCallback;
980 }
981 else
982 {
983 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
984
985 status = HAL_ERROR;
986 }
987
988 /* Release Lock */
989 __HAL_UNLOCK(huart);
990
991 return status;
992 }
993
994 /**
995 * @brief UnRegister the UART Rx Event Callback
996 * UART Rx Event Callback is redirected to the weak HAL_UARTEx_RxEventCallback() predefined callback
997 * @param huart Uart handle
998 * @retval HAL status
999 */
HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef * huart)1000 HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart)
1001 {
1002 HAL_StatusTypeDef status = HAL_OK;
1003
1004 /* Process locked */
1005 __HAL_LOCK(huart);
1006
1007 if (huart->gState == HAL_UART_STATE_READY)
1008 {
1009 huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak UART Rx Event Callback */
1010 }
1011 else
1012 {
1013 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
1014
1015 status = HAL_ERROR;
1016 }
1017
1018 /* Release Lock */
1019 __HAL_UNLOCK(huart);
1020 return status;
1021 }
1022
1023 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
1024
1025 /**
1026 * @}
1027 */
1028
1029 /** @defgroup UART_Exported_Functions_Group2 IO operation functions
1030 * @brief UART Transmit/Receive functions
1031 *
1032 @verbatim
1033 ===============================================================================
1034 ##### IO operation functions #####
1035 ===============================================================================
1036 This subsection provides a set of functions allowing to manage the UART asynchronous
1037 and Half duplex data transfers.
1038
1039 (#) There are two mode of transfer:
1040 (+) Blocking mode: The communication is performed in polling mode.
1041 The HAL status of all data processing is returned by the same function
1042 after finishing transfer.
1043 (+) Non-Blocking mode: The communication is performed using Interrupts
1044 or DMA, These API's return the HAL status.
1045 The end of the data processing will be indicated through the
1046 dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
1047 using DMA mode.
1048 The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
1049 will be executed respectively at the end of the transmit or Receive process
1050 The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected
1051
1052 (#) Blocking mode API's are :
1053 (+) HAL_UART_Transmit()
1054 (+) HAL_UART_Receive()
1055
1056 (#) Non-Blocking mode API's with Interrupt are :
1057 (+) HAL_UART_Transmit_IT()
1058 (+) HAL_UART_Receive_IT()
1059 (+) HAL_UART_IRQHandler()
1060
1061 (#) Non-Blocking mode API's with DMA are :
1062 (+) HAL_UART_Transmit_DMA()
1063 (+) HAL_UART_Receive_DMA()
1064 (+) HAL_UART_DMAPause()
1065 (+) HAL_UART_DMAResume()
1066 (+) HAL_UART_DMAStop()
1067
1068 (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
1069 (+) HAL_UART_TxHalfCpltCallback()
1070 (+) HAL_UART_TxCpltCallback()
1071 (+) HAL_UART_RxHalfCpltCallback()
1072 (+) HAL_UART_RxCpltCallback()
1073 (+) HAL_UART_ErrorCallback()
1074
1075 (#) Non-Blocking mode transfers could be aborted using Abort API's :
1076 (+) HAL_UART_Abort()
1077 (+) HAL_UART_AbortTransmit()
1078 (+) HAL_UART_AbortReceive()
1079 (+) HAL_UART_Abort_IT()
1080 (+) HAL_UART_AbortTransmit_IT()
1081 (+) HAL_UART_AbortReceive_IT()
1082
1083 (#) For Abort services based on interrupts (HAL_UART_Abortxxx_IT), a set of Abort Complete Callbacks are provided:
1084 (+) HAL_UART_AbortCpltCallback()
1085 (+) HAL_UART_AbortTransmitCpltCallback()
1086 (+) HAL_UART_AbortReceiveCpltCallback()
1087
1088 (#) A Rx Event Reception Callback (Rx event notification) is available for Non_Blocking modes of enhanced
1089 reception services:
1090 (+) HAL_UARTEx_RxEventCallback()
1091
1092 (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
1093 Errors are handled as follows :
1094 (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
1095 to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error
1096 in Interrupt mode reception .
1097 Received character is then retrieved and stored in Rx buffer, Error code is set to allow user
1098 to identify error type, and HAL_UART_ErrorCallback() user callback is executed.
1099 Transfer is kept ongoing on UART side.
1100 If user wants to abort it, Abort services should be called by user.
1101 (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
1102 This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
1103 Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback()
1104 user callback is executed.
1105
1106 -@- In the Half duplex communication, it is forbidden to run the transmit
1107 and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful.
1108
1109 @endverbatim
1110 * @{
1111 */
1112
1113 /**
1114 * @brief Send an amount of data in blocking mode.
1115 * @note When UART 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 pData.
1118 * @note When FIFO mode is enabled, writing a data in the TDR register adds one
1119 * data to the TXFIFO. Write operations to the TDR register are performed
1120 * when TXFNF flag is set. From hardware perspective, TXFNF flag and
1121 * TXE are mapped on the same bit-field.
1122 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1123 * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits)
1124 * (as sent data will be handled using u16 pointer cast). Depending on compilation chain,
1125 * use of specific alignment compilation directives or pragmas might be required
1126 * to ensure proper alignment for pData.
1127 * @param huart UART handle.
1128 * @param pData Pointer to data buffer (u8 or u16 data elements).
1129 * @param Size Amount of data elements (u8 or u16) to be sent.
1130 * @param Timeout Timeout duration.
1131 * @retval HAL status
1132 */
HAL_UART_Transmit(UART_HandleTypeDef * huart,const uint8_t * pData,uint16_t Size,uint32_t Timeout)1133 HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
1134 {
1135 const uint8_t *pdata8bits;
1136 const uint16_t *pdata16bits;
1137 uint32_t tickstart;
1138
1139 /* Check that a Tx process is not already ongoing */
1140 if (huart->gState == HAL_UART_STATE_READY)
1141 {
1142 if ((pData == NULL) || (Size == 0U))
1143 {
1144 return HAL_ERROR;
1145 }
1146
1147 /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1148 should be aligned on a u16 frontier, as data to be filled into TDR will be
1149 handled through a u16 cast. */
1150 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1151 {
1152 if ((((uint32_t)pData) & 1U) != 0U)
1153 {
1154 return HAL_ERROR;
1155 }
1156 }
1157
1158 huart->ErrorCode = HAL_UART_ERROR_NONE;
1159 huart->gState = HAL_UART_STATE_BUSY_TX;
1160
1161 /* Init tickstart for timeout management */
1162 tickstart = HAL_GetTick();
1163
1164 huart->TxXferSize = Size;
1165 huart->TxXferCount = Size;
1166
1167 /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
1168 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1169 {
1170 pdata8bits = NULL;
1171 pdata16bits = (const uint16_t *) pData;
1172 }
1173 else
1174 {
1175 pdata8bits = pData;
1176 pdata16bits = NULL;
1177 }
1178
1179 while (huart->TxXferCount > 0U)
1180 {
1181 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
1182 {
1183
1184 huart->gState = HAL_UART_STATE_READY;
1185
1186 return HAL_TIMEOUT;
1187 }
1188 if (pdata8bits == NULL)
1189 {
1190 huart->Instance->TDR = (uint16_t)(*pdata16bits & 0x01FFU);
1191 pdata16bits++;
1192 }
1193 else
1194 {
1195 huart->Instance->TDR = (uint8_t)(*pdata8bits & 0xFFU);
1196 pdata8bits++;
1197 }
1198 huart->TxXferCount--;
1199 }
1200
1201 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
1202 {
1203 huart->gState = HAL_UART_STATE_READY;
1204
1205 return HAL_TIMEOUT;
1206 }
1207
1208 /* At end of Tx process, restore huart->gState to Ready */
1209 huart->gState = HAL_UART_STATE_READY;
1210
1211 return HAL_OK;
1212 }
1213 else
1214 {
1215 return HAL_BUSY;
1216 }
1217 }
1218
1219 /**
1220 * @brief Receive an amount of data in blocking mode.
1221 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1222 * the received data is handled as a set of u16. In this case, Size must indicate the number
1223 * of u16 available through pData.
1224 * @note When FIFO mode is enabled, the RXFNE flag is set as long as the RXFIFO
1225 * is not empty. Read operations from the RDR register are performed when
1226 * RXFNE flag is set. From hardware perspective, RXFNE flag and
1227 * RXNE are mapped on the same bit-field.
1228 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1229 * address of user data buffer for storing data to be received, should be aligned on a half word frontier
1230 * (16 bits) (as received data will be handled using u16 pointer cast). Depending on compilation chain,
1231 * use of specific alignment compilation directives or pragmas might be required
1232 * to ensure proper alignment for pData.
1233 * @param huart UART handle.
1234 * @param pData Pointer to data buffer (u8 or u16 data elements).
1235 * @param Size Amount of data elements (u8 or u16) to be received.
1236 * @param Timeout Timeout duration.
1237 * @retval HAL status
1238 */
HAL_UART_Receive(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size,uint32_t Timeout)1239 HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
1240 {
1241 uint8_t *pdata8bits;
1242 uint16_t *pdata16bits;
1243 uint16_t uhMask;
1244 uint32_t tickstart;
1245
1246 /* Check that a Rx process is not already ongoing */
1247 if (huart->RxState == HAL_UART_STATE_READY)
1248 {
1249 if ((pData == NULL) || (Size == 0U))
1250 {
1251 return HAL_ERROR;
1252 }
1253
1254 /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1255 should be aligned on a u16 frontier, as data to be received from RDR will be
1256 handled through a u16 cast. */
1257 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1258 {
1259 if ((((uint32_t)pData) & 1U) != 0U)
1260 {
1261 return HAL_ERROR;
1262 }
1263 }
1264
1265 huart->ErrorCode = HAL_UART_ERROR_NONE;
1266 huart->RxState = HAL_UART_STATE_BUSY_RX;
1267 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
1268
1269 /* Init tickstart for timeout management */
1270 tickstart = HAL_GetTick();
1271
1272 huart->RxXferSize = Size;
1273 huart->RxXferCount = Size;
1274
1275 /* Computation of UART mask to apply to RDR register */
1276 UART_MASK_COMPUTATION(huart);
1277 uhMask = huart->Mask;
1278
1279 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
1280 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1281 {
1282 pdata8bits = NULL;
1283 pdata16bits = (uint16_t *) pData;
1284 }
1285 else
1286 {
1287 pdata8bits = pData;
1288 pdata16bits = NULL;
1289 }
1290
1291 /* as long as data have to be received */
1292 while (huart->RxXferCount > 0U)
1293 {
1294 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
1295 {
1296 huart->RxState = HAL_UART_STATE_READY;
1297
1298 return HAL_TIMEOUT;
1299 }
1300 if (pdata8bits == NULL)
1301 {
1302 *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask);
1303 pdata16bits++;
1304 }
1305 else
1306 {
1307 *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
1308 pdata8bits++;
1309 }
1310 huart->RxXferCount--;
1311 }
1312
1313 /* At end of Rx process, restore huart->RxState to Ready */
1314 huart->RxState = HAL_UART_STATE_READY;
1315
1316 return HAL_OK;
1317 }
1318 else
1319 {
1320 return HAL_BUSY;
1321 }
1322 }
1323
1324 /**
1325 * @brief Send an amount of data in interrupt mode.
1326 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1327 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1328 * of u16 provided through pData.
1329 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1330 * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits)
1331 * (as sent data will be handled using u16 pointer cast). Depending on compilation chain,
1332 * use of specific alignment compilation directives or pragmas might be required
1333 * to ensure proper alignment for pData.
1334 * @param huart UART handle.
1335 * @param pData Pointer to data buffer (u8 or u16 data elements).
1336 * @param Size Amount of data elements (u8 or u16) to be sent.
1337 * @retval HAL status
1338 */
HAL_UART_Transmit_IT(UART_HandleTypeDef * huart,const uint8_t * pData,uint16_t Size)1339 HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
1340 {
1341 /* Check that a Tx process is not already ongoing */
1342 if (huart->gState == HAL_UART_STATE_READY)
1343 {
1344 if ((pData == NULL) || (Size == 0U))
1345 {
1346 return HAL_ERROR;
1347 }
1348
1349 /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1350 should be aligned on a u16 frontier, as data to be filled into TDR will be
1351 handled through a u16 cast. */
1352 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1353 {
1354 if ((((uint32_t)pData) & 1U) != 0U)
1355 {
1356 return HAL_ERROR;
1357 }
1358 }
1359
1360 huart->pTxBuffPtr = pData;
1361 huart->TxXferSize = Size;
1362 huart->TxXferCount = Size;
1363 huart->TxISR = NULL;
1364
1365 huart->ErrorCode = HAL_UART_ERROR_NONE;
1366 huart->gState = HAL_UART_STATE_BUSY_TX;
1367
1368 /* Configure Tx interrupt processing */
1369 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1370 {
1371 /* Set the Tx ISR function pointer according to the data word length */
1372 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1373 {
1374 huart->TxISR = UART_TxISR_16BIT_FIFOEN;
1375 }
1376 else
1377 {
1378 huart->TxISR = UART_TxISR_8BIT_FIFOEN;
1379 }
1380
1381 /* Enable the TX FIFO threshold interrupt */
1382 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
1383 }
1384 else
1385 {
1386 /* Set the Tx ISR function pointer according to the data word length */
1387 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1388 {
1389 huart->TxISR = UART_TxISR_16BIT;
1390 }
1391 else
1392 {
1393 huart->TxISR = UART_TxISR_8BIT;
1394 }
1395
1396 /* Enable the Transmit Data Register Empty interrupt */
1397 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
1398 }
1399
1400 return HAL_OK;
1401 }
1402 else
1403 {
1404 return HAL_BUSY;
1405 }
1406 }
1407
1408 /**
1409 * @brief Receive an amount of data in interrupt mode.
1410 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1411 * the received data is handled as a set of u16. In this case, Size must indicate the number
1412 * of u16 available through pData.
1413 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1414 * address of user data buffer for storing data to be received, should be aligned on a half word frontier
1415 * (16 bits) (as received data will be handled using u16 pointer cast). Depending on compilation chain,
1416 * use of specific alignment compilation directives or pragmas might be required
1417 * to ensure proper alignment for pData.
1418 * @param huart UART handle.
1419 * @param pData Pointer to data buffer (u8 or u16 data elements).
1420 * @param Size Amount of data elements (u8 or u16) to be received.
1421 * @retval HAL status
1422 */
HAL_UART_Receive_IT(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)1423 HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1424 {
1425 /* Check that a Rx process is not already ongoing */
1426 if (huart->RxState == HAL_UART_STATE_READY)
1427 {
1428 if ((pData == NULL) || (Size == 0U))
1429 {
1430 return HAL_ERROR;
1431 }
1432
1433 /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1434 should be aligned on a u16 frontier, as data to be received from RDR will be
1435 handled through a u16 cast. */
1436 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1437 {
1438 if ((((uint32_t)pData) & 1U) != 0U)
1439 {
1440 return HAL_ERROR;
1441 }
1442 }
1443
1444 /* Set Reception type to Standard reception */
1445 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
1446
1447 /* Check that USART RTOEN bit is set */
1448 if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
1449 {
1450 /* Enable the UART Receiver Timeout Interrupt */
1451 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
1452 }
1453
1454 return (UART_Start_Receive_IT(huart, pData, Size));
1455 }
1456 else
1457 {
1458 return HAL_BUSY;
1459 }
1460 }
1461
1462 #if defined(HAL_DMA_MODULE_ENABLED)
1463 /**
1464 * @brief Send an amount of data in DMA mode.
1465 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1466 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1467 * of u16 provided through pData.
1468 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1469 * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits)
1470 * (as sent data will be handled by DMA from halfword frontier). Depending on compilation chain,
1471 * use of specific alignment compilation directives or pragmas might be required
1472 * to ensure proper alignment for pData.
1473 * @param huart UART handle.
1474 * @param pData Pointer to data buffer (u8 or u16 data elements).
1475 * @param Size Amount of data elements (u8 or u16) to be sent.
1476 * @retval HAL status
1477 */
HAL_UART_Transmit_DMA(UART_HandleTypeDef * huart,const uint8_t * pData,uint16_t Size)1478 HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
1479 {
1480 /* Check that a Tx process is not already ongoing */
1481 if (huart->gState == HAL_UART_STATE_READY)
1482 {
1483 if ((pData == NULL) || (Size == 0U))
1484 {
1485 return HAL_ERROR;
1486 }
1487
1488 /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1489 should be aligned on a u16 frontier, as data copy into TDR will be
1490 handled by DMA from a u16 frontier. */
1491 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1492 {
1493 if ((((uint32_t)pData) & 1U) != 0U)
1494 {
1495 return HAL_ERROR;
1496 }
1497 }
1498
1499 huart->pTxBuffPtr = pData;
1500 huart->TxXferSize = Size;
1501 huart->TxXferCount = Size;
1502
1503 huart->ErrorCode = HAL_UART_ERROR_NONE;
1504 huart->gState = HAL_UART_STATE_BUSY_TX;
1505
1506 if (huart->hdmatx != NULL)
1507 {
1508 /* Set the UART DMA transfer complete callback */
1509 huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
1510
1511 /* Set the UART DMA Half transfer complete callback */
1512 huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
1513
1514 /* Set the DMA error callback */
1515 huart->hdmatx->XferErrorCallback = UART_DMAError;
1516
1517 /* Set the DMA abort callback */
1518 huart->hdmatx->XferAbortCallback = NULL;
1519
1520 /* Enable the UART transmit DMA channel */
1521 if (HAL_DMA_Start_IT(huart->hdmatx, (uint32_t)huart->pTxBuffPtr, (uint32_t)&huart->Instance->TDR, Size) != HAL_OK)
1522 {
1523 /* Set error code to DMA */
1524 huart->ErrorCode = HAL_UART_ERROR_DMA;
1525
1526 /* Restore huart->gState to ready */
1527 huart->gState = HAL_UART_STATE_READY;
1528
1529 return HAL_ERROR;
1530 }
1531 }
1532 /* Clear the TC flag in the ICR register */
1533 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF);
1534
1535 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1536 in the UART CR3 register */
1537 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1538
1539 return HAL_OK;
1540 }
1541 else
1542 {
1543 return HAL_BUSY;
1544 }
1545 }
1546
1547 /**
1548 * @brief Receive an amount of data in DMA mode.
1549 * @note When the UART parity is enabled (PCE = 1), the received data contain
1550 * the parity bit (MSB position).
1551 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1552 * the received data is handled as a set of u16. In this case, Size must indicate the number
1553 * of u16 available through pData.
1554 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1555 * address of user data buffer for storing data to be received, should be aligned on a half word frontier
1556 * (16 bits) (as received data will be handled by DMA from halfword frontier). Depending on compilation chain,
1557 * use of specific alignment compilation directives or pragmas might be required
1558 * to ensure proper alignment for pData.
1559 * @param huart UART handle.
1560 * @param pData Pointer to data buffer (u8 or u16 data elements).
1561 * @param Size Amount of data elements (u8 or u16) to be received.
1562 * @retval HAL status
1563 */
HAL_UART_Receive_DMA(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)1564 HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1565 {
1566 /* Check that a Rx process is not already ongoing */
1567 if (huart->RxState == HAL_UART_STATE_READY)
1568 {
1569 if ((pData == NULL) || (Size == 0U))
1570 {
1571 return HAL_ERROR;
1572 }
1573
1574 /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1575 should be aligned on a u16 frontier, as data copy from RDR will be
1576 handled by DMA from a u16 frontier. */
1577 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1578 {
1579 if ((((uint32_t)pData) & 1U) != 0U)
1580 {
1581 return HAL_ERROR;
1582 }
1583 }
1584
1585 /* Set Reception type to Standard reception */
1586 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
1587
1588 /* Check that USART RTOEN bit is set */
1589 if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
1590 {
1591 /* Enable the UART Receiver Timeout Interrupt */
1592 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
1593 }
1594
1595 return (UART_Start_Receive_DMA(huart, pData, Size));
1596 }
1597 else
1598 {
1599 return HAL_BUSY;
1600 }
1601 }
1602
1603 /**
1604 * @brief Pause the DMA Transfer.
1605 * @param huart UART handle.
1606 * @retval HAL status
1607 */
HAL_UART_DMAPause(UART_HandleTypeDef * huart)1608 HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
1609 {
1610 const HAL_UART_StateTypeDef gstate = huart->gState;
1611 const HAL_UART_StateTypeDef rxstate = huart->RxState;
1612
1613 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
1614 (gstate == HAL_UART_STATE_BUSY_TX))
1615 {
1616 /* Disable the UART DMA Tx request */
1617 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1618 }
1619 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
1620 (rxstate == HAL_UART_STATE_BUSY_RX))
1621 {
1622 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
1623 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1624 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
1625
1626 /* Disable the UART DMA Rx request */
1627 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1628 }
1629
1630 return HAL_OK;
1631 }
1632
1633 /**
1634 * @brief Resume the DMA Transfer.
1635 * @param huart UART handle.
1636 * @retval HAL status
1637 */
HAL_UART_DMAResume(UART_HandleTypeDef * huart)1638 HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
1639 {
1640 if (huart->gState == HAL_UART_STATE_BUSY_TX)
1641 {
1642 /* Enable the UART DMA Tx request */
1643 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1644 }
1645 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
1646 {
1647 /* Clear the Overrun flag before resuming the Rx transfer */
1648 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
1649
1650 /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */
1651 if (huart->Init.Parity != UART_PARITY_NONE)
1652 {
1653 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1654 }
1655 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
1656
1657 /* Enable the UART DMA Rx request */
1658 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1659 }
1660
1661 return HAL_OK;
1662 }
1663
1664 /**
1665 * @brief Stop the DMA Transfer.
1666 * @param huart UART handle.
1667 * @retval HAL status
1668 */
HAL_UART_DMAStop(UART_HandleTypeDef * huart)1669 HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
1670 {
1671 /* The Lock is not implemented on this API to allow the user application
1672 to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() /
1673 HAL_UART_TxHalfCpltCallback / HAL_UART_RxHalfCpltCallback:
1674 indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
1675 interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
1676 the stream and the corresponding call back is executed. */
1677
1678 const HAL_UART_StateTypeDef gstate = huart->gState;
1679 const HAL_UART_StateTypeDef rxstate = huart->RxState;
1680
1681 /* Stop UART DMA Tx request if ongoing */
1682 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
1683 (gstate == HAL_UART_STATE_BUSY_TX))
1684 {
1685 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1686
1687 /* Abort the UART DMA Tx channel */
1688 if (huart->hdmatx != NULL)
1689 {
1690 if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
1691 {
1692 if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1693 {
1694 /* Set error code to DMA */
1695 huart->ErrorCode = HAL_UART_ERROR_DMA;
1696
1697 return HAL_TIMEOUT;
1698 }
1699 }
1700 }
1701
1702 UART_EndTxTransfer(huart);
1703 }
1704
1705 /* Stop UART DMA Rx request if ongoing */
1706 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
1707 (rxstate == HAL_UART_STATE_BUSY_RX))
1708 {
1709 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1710
1711 /* Abort the UART DMA Rx channel */
1712 if (huart->hdmarx != NULL)
1713 {
1714 if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
1715 {
1716 if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1717 {
1718 /* Set error code to DMA */
1719 huart->ErrorCode = HAL_UART_ERROR_DMA;
1720
1721 return HAL_TIMEOUT;
1722 }
1723 }
1724 }
1725
1726 UART_EndRxTransfer(huart);
1727 }
1728
1729 return HAL_OK;
1730 }
1731 #endif /* HAL_DMA_MODULE_ENABLED */
1732
1733 /**
1734 * @brief Abort ongoing transfers (blocking mode).
1735 * @param huart UART handle.
1736 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1737 * This procedure performs following operations :
1738 * - Disable UART Interrupts (Tx and Rx)
1739 * - Disable the DMA transfer in the peripheral register (if enabled)
1740 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1741 * - Set handle State to READY
1742 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1743 * @retval HAL status
1744 */
HAL_UART_Abort(UART_HandleTypeDef * huart)1745 HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart)
1746 {
1747 /* Disable TXE, TC, RXNE, PE, RXFT, TXFT and ERR (Frame error, noise error, overrun error) interrupts */
1748 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE |
1749 USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
1750 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE);
1751
1752 /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
1753 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
1754 {
1755 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
1756 }
1757
1758 #if defined(HAL_DMA_MODULE_ENABLED)
1759 /* Abort the UART DMA Tx channel if enabled */
1760 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1761 {
1762 /* Disable the UART DMA Tx request if enabled */
1763 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1764
1765 /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
1766 if (huart->hdmatx != NULL)
1767 {
1768 /* Set the UART DMA Abort callback to Null.
1769 No call back execution at end of DMA abort procedure */
1770 huart->hdmatx->XferAbortCallback = NULL;
1771
1772 if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
1773 {
1774 if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1775 {
1776 /* Set error code to DMA */
1777 huart->ErrorCode = HAL_UART_ERROR_DMA;
1778
1779 return HAL_TIMEOUT;
1780 }
1781 }
1782 }
1783 }
1784
1785 /* Abort the UART DMA Rx channel if enabled */
1786 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1787 {
1788 /* Disable the UART DMA Rx request if enabled */
1789 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1790
1791 /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
1792 if (huart->hdmarx != NULL)
1793 {
1794 /* Set the UART DMA Abort callback to Null.
1795 No call back execution at end of DMA abort procedure */
1796 huart->hdmarx->XferAbortCallback = NULL;
1797
1798 if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
1799 {
1800 if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1801 {
1802 /* Set error code to DMA */
1803 huart->ErrorCode = HAL_UART_ERROR_DMA;
1804
1805 return HAL_TIMEOUT;
1806 }
1807 }
1808 }
1809 }
1810 #endif /* HAL_DMA_MODULE_ENABLED */
1811
1812 /* Reset Tx and Rx transfer counters */
1813 huart->TxXferCount = 0U;
1814 huart->RxXferCount = 0U;
1815
1816 /* Clear the Error flags in the ICR register */
1817 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
1818
1819 /* Flush the whole TX FIFO (if needed) */
1820 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1821 {
1822 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
1823 }
1824
1825 /* Discard the received data */
1826 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
1827
1828 /* Restore huart->gState and huart->RxState to Ready */
1829 huart->gState = HAL_UART_STATE_READY;
1830 huart->RxState = HAL_UART_STATE_READY;
1831 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
1832
1833 huart->ErrorCode = HAL_UART_ERROR_NONE;
1834
1835 return HAL_OK;
1836 }
1837
1838 /**
1839 * @brief Abort ongoing Transmit transfer (blocking mode).
1840 * @param huart UART handle.
1841 * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
1842 * This procedure performs following operations :
1843 * - Disable UART Interrupts (Tx)
1844 * - Disable the DMA transfer in the peripheral register (if enabled)
1845 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1846 * - Set handle State to READY
1847 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1848 * @retval HAL status
1849 */
HAL_UART_AbortTransmit(UART_HandleTypeDef * huart)1850 HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart)
1851 {
1852 /* Disable TCIE, TXEIE and TXFTIE interrupts */
1853 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE));
1854 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
1855
1856 #if defined(HAL_DMA_MODULE_ENABLED)
1857 /* Abort the UART DMA Tx channel if enabled */
1858 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1859 {
1860 /* Disable the UART DMA Tx request if enabled */
1861 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1862
1863 /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
1864 if (huart->hdmatx != NULL)
1865 {
1866 /* Set the UART DMA Abort callback to Null.
1867 No call back execution at end of DMA abort procedure */
1868 huart->hdmatx->XferAbortCallback = NULL;
1869
1870 if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
1871 {
1872 if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1873 {
1874 /* Set error code to DMA */
1875 huart->ErrorCode = HAL_UART_ERROR_DMA;
1876
1877 return HAL_TIMEOUT;
1878 }
1879 }
1880 }
1881 }
1882 #endif /* HAL_DMA_MODULE_ENABLED */
1883
1884 /* Reset Tx transfer counter */
1885 huart->TxXferCount = 0U;
1886
1887 /* Flush the whole TX FIFO (if needed) */
1888 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1889 {
1890 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
1891 }
1892
1893 /* Restore huart->gState to Ready */
1894 huart->gState = HAL_UART_STATE_READY;
1895
1896 return HAL_OK;
1897 }
1898
1899 /**
1900 * @brief Abort ongoing Receive transfer (blocking mode).
1901 * @param huart UART handle.
1902 * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
1903 * This procedure performs following operations :
1904 * - Disable UART Interrupts (Rx)
1905 * - Disable the DMA transfer in the peripheral register (if enabled)
1906 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1907 * - Set handle State to READY
1908 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1909 * @retval HAL status
1910 */
HAL_UART_AbortReceive(UART_HandleTypeDef * huart)1911 HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart)
1912 {
1913 /* Disable PEIE, EIE, RXNEIE and RXFTIE interrupts */
1914 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE));
1915 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE);
1916
1917 /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
1918 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
1919 {
1920 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
1921 }
1922
1923 #if defined(HAL_DMA_MODULE_ENABLED)
1924 /* Abort the UART DMA Rx channel if enabled */
1925 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1926 {
1927 /* Disable the UART DMA Rx request if enabled */
1928 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1929
1930 /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
1931 if (huart->hdmarx != NULL)
1932 {
1933 /* Set the UART DMA Abort callback to Null.
1934 No call back execution at end of DMA abort procedure */
1935 huart->hdmarx->XferAbortCallback = NULL;
1936
1937 if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
1938 {
1939 if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1940 {
1941 /* Set error code to DMA */
1942 huart->ErrorCode = HAL_UART_ERROR_DMA;
1943
1944 return HAL_TIMEOUT;
1945 }
1946 }
1947 }
1948 }
1949 #endif /* HAL_DMA_MODULE_ENABLED */
1950
1951 /* Reset Rx transfer counter */
1952 huart->RxXferCount = 0U;
1953
1954 /* Clear the Error flags in the ICR register */
1955 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
1956
1957 /* Discard the received data */
1958 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
1959
1960 /* Restore huart->RxState to Ready */
1961 huart->RxState = HAL_UART_STATE_READY;
1962 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
1963
1964 return HAL_OK;
1965 }
1966
1967 /**
1968 * @brief Abort ongoing transfers (Interrupt mode).
1969 * @param huart UART handle.
1970 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1971 * This procedure performs following operations :
1972 * - Disable UART Interrupts (Tx and Rx)
1973 * - Disable the DMA transfer in the peripheral register (if enabled)
1974 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1975 * - Set handle State to READY
1976 * - At abort completion, call user abort complete callback
1977 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
1978 * considered as completed only when user abort complete callback is executed (not when exiting function).
1979 * @retval HAL status
1980 */
HAL_UART_Abort_IT(UART_HandleTypeDef * huart)1981 HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart)
1982 {
1983 uint32_t abortcplt = 1U;
1984
1985 /* Disable interrupts */
1986 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_TCIE | USART_CR1_RXNEIE_RXFNEIE |
1987 USART_CR1_TXEIE_TXFNFIE));
1988 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
1989
1990 /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
1991 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
1992 {
1993 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
1994 }
1995
1996 #if defined(HAL_DMA_MODULE_ENABLED)
1997 /* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised
1998 before any call to DMA Abort functions */
1999 /* DMA Tx Handle is valid */
2000 if (huart->hdmatx != NULL)
2001 {
2002 /* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
2003 Otherwise, set it to NULL */
2004 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
2005 {
2006 huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback;
2007 }
2008 else
2009 {
2010 huart->hdmatx->XferAbortCallback = NULL;
2011 }
2012 }
2013 /* DMA Rx Handle is valid */
2014 if (huart->hdmarx != NULL)
2015 {
2016 /* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
2017 Otherwise, set it to NULL */
2018 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2019 {
2020 huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback;
2021 }
2022 else
2023 {
2024 huart->hdmarx->XferAbortCallback = NULL;
2025 }
2026 }
2027
2028 /* Abort the UART DMA Tx channel if enabled */
2029 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
2030 {
2031 /* Disable DMA Tx at UART level */
2032 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
2033
2034 /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
2035 if (huart->hdmatx != NULL)
2036 {
2037 /* UART Tx DMA Abort callback has already been initialised :
2038 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2039
2040 /* Abort DMA TX */
2041 if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
2042 {
2043 huart->hdmatx->XferAbortCallback = NULL;
2044 }
2045 else
2046 {
2047 abortcplt = 0U;
2048 }
2049 }
2050 }
2051
2052 /* Abort the UART DMA Rx channel if enabled */
2053 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2054 {
2055 /* Disable the UART DMA Rx request if enabled */
2056 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2057
2058 /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
2059 if (huart->hdmarx != NULL)
2060 {
2061 /* UART Rx DMA Abort callback has already been initialised :
2062 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2063
2064 /* Abort DMA RX */
2065 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
2066 {
2067 huart->hdmarx->XferAbortCallback = NULL;
2068 abortcplt = 1U;
2069 }
2070 else
2071 {
2072 abortcplt = 0U;
2073 }
2074 }
2075 }
2076 #endif /* HAL_DMA_MODULE_ENABLED */
2077
2078 /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
2079 if (abortcplt == 1U)
2080 {
2081 /* Reset Tx and Rx transfer counters */
2082 huart->TxXferCount = 0U;
2083 huart->RxXferCount = 0U;
2084
2085 /* Clear ISR function pointers */
2086 huart->RxISR = NULL;
2087 huart->TxISR = NULL;
2088
2089 /* Reset errorCode */
2090 huart->ErrorCode = HAL_UART_ERROR_NONE;
2091
2092 /* Clear the Error flags in the ICR register */
2093 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
2094
2095 /* Flush the whole TX FIFO (if needed) */
2096 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
2097 {
2098 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
2099 }
2100
2101 /* Discard the received data */
2102 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
2103
2104 /* Restore huart->gState and huart->RxState to Ready */
2105 huart->gState = HAL_UART_STATE_READY;
2106 huart->RxState = HAL_UART_STATE_READY;
2107 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2108
2109 /* As no DMA to be aborted, call directly user Abort complete callback */
2110 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2111 /* Call registered Abort complete callback */
2112 huart->AbortCpltCallback(huart);
2113 #else
2114 /* Call legacy weak Abort complete callback */
2115 HAL_UART_AbortCpltCallback(huart);
2116 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2117 }
2118
2119 return HAL_OK;
2120 }
2121
2122 /**
2123 * @brief Abort ongoing Transmit transfer (Interrupt mode).
2124 * @param huart UART handle.
2125 * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
2126 * This procedure performs following operations :
2127 * - Disable UART Interrupts (Tx)
2128 * - Disable the DMA transfer in the peripheral register (if enabled)
2129 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
2130 * - Set handle State to READY
2131 * - At abort completion, call user abort complete callback
2132 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
2133 * considered as completed only when user abort complete callback is executed (not when exiting function).
2134 * @retval HAL status
2135 */
HAL_UART_AbortTransmit_IT(UART_HandleTypeDef * huart)2136 HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart)
2137 {
2138 /* Disable interrupts */
2139 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE));
2140 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
2141
2142 #if defined(HAL_DMA_MODULE_ENABLED)
2143 /* Abort the UART DMA Tx channel if enabled */
2144 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
2145 {
2146 /* Disable the UART DMA Tx request if enabled */
2147 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
2148
2149 /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
2150 if (huart->hdmatx != NULL)
2151 {
2152 /* Set the UART DMA Abort callback :
2153 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2154 huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback;
2155
2156 /* Abort DMA TX */
2157 if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
2158 {
2159 /* Call Directly huart->hdmatx->XferAbortCallback function in case of error */
2160 huart->hdmatx->XferAbortCallback(huart->hdmatx);
2161 }
2162 }
2163 else
2164 {
2165 /* Reset Tx transfer counter */
2166 huart->TxXferCount = 0U;
2167
2168 /* Clear TxISR function pointers */
2169 huart->TxISR = NULL;
2170
2171 /* Restore huart->gState to Ready */
2172 huart->gState = HAL_UART_STATE_READY;
2173
2174 /* As no DMA to be aborted, call directly user Abort complete callback */
2175 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2176 /* Call registered Abort Transmit Complete Callback */
2177 huart->AbortTransmitCpltCallback(huart);
2178 #else
2179 /* Call legacy weak Abort Transmit Complete Callback */
2180 HAL_UART_AbortTransmitCpltCallback(huart);
2181 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2182 }
2183 }
2184 else
2185 #endif /* HAL_DMA_MODULE_ENABLED */
2186 {
2187 /* Reset Tx transfer counter */
2188 huart->TxXferCount = 0U;
2189
2190 /* Clear TxISR function pointers */
2191 huart->TxISR = NULL;
2192
2193 /* Flush the whole TX FIFO (if needed) */
2194 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
2195 {
2196 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
2197 }
2198
2199 /* Restore huart->gState to Ready */
2200 huart->gState = HAL_UART_STATE_READY;
2201
2202 /* As no DMA to be aborted, call directly user Abort complete callback */
2203 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2204 /* Call registered Abort Transmit Complete Callback */
2205 huart->AbortTransmitCpltCallback(huart);
2206 #else
2207 /* Call legacy weak Abort Transmit Complete Callback */
2208 HAL_UART_AbortTransmitCpltCallback(huart);
2209 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2210 }
2211
2212 return HAL_OK;
2213 }
2214
2215 /**
2216 * @brief Abort ongoing Receive transfer (Interrupt mode).
2217 * @param huart UART handle.
2218 * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
2219 * This procedure performs following operations :
2220 * - Disable UART Interrupts (Rx)
2221 * - Disable the DMA transfer in the peripheral register (if enabled)
2222 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
2223 * - Set handle State to READY
2224 * - At abort completion, call user abort complete callback
2225 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
2226 * considered as completed only when user abort complete callback is executed (not when exiting function).
2227 * @retval HAL status
2228 */
HAL_UART_AbortReceive_IT(UART_HandleTypeDef * huart)2229 HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart)
2230 {
2231 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
2232 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE));
2233 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
2234
2235 /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
2236 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
2237 {
2238 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
2239 }
2240
2241 #if defined(HAL_DMA_MODULE_ENABLED)
2242 /* Abort the UART DMA Rx channel if enabled */
2243 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2244 {
2245 /* Disable the UART DMA Rx request if enabled */
2246 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2247
2248 /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
2249 if (huart->hdmarx != NULL)
2250 {
2251 /* Set the UART DMA Abort callback :
2252 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2253 huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback;
2254
2255 /* Abort DMA RX */
2256 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
2257 {
2258 /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
2259 huart->hdmarx->XferAbortCallback(huart->hdmarx);
2260 }
2261 }
2262 else
2263 {
2264 /* Reset Rx transfer counter */
2265 huart->RxXferCount = 0U;
2266
2267 /* Clear RxISR function pointer */
2268 huart->pRxBuffPtr = NULL;
2269
2270 /* Clear the Error flags in the ICR register */
2271 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
2272
2273 /* Discard the received data */
2274 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
2275
2276 /* Restore huart->RxState to Ready */
2277 huart->RxState = HAL_UART_STATE_READY;
2278 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2279
2280 /* As no DMA to be aborted, call directly user Abort complete callback */
2281 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2282 /* Call registered Abort Receive Complete Callback */
2283 huart->AbortReceiveCpltCallback(huart);
2284 #else
2285 /* Call legacy weak Abort Receive Complete Callback */
2286 HAL_UART_AbortReceiveCpltCallback(huart);
2287 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2288 }
2289 }
2290 else
2291 #endif /* HAL_DMA_MODULE_ENABLED */
2292 {
2293 /* Reset Rx transfer counter */
2294 huart->RxXferCount = 0U;
2295
2296 /* Clear RxISR function pointer */
2297 huart->pRxBuffPtr = NULL;
2298
2299 /* Clear the Error flags in the ICR register */
2300 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
2301
2302 /* Restore huart->RxState to Ready */
2303 huart->RxState = HAL_UART_STATE_READY;
2304 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2305
2306 /* As no DMA to be aborted, call directly user Abort complete callback */
2307 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2308 /* Call registered Abort Receive Complete Callback */
2309 huart->AbortReceiveCpltCallback(huart);
2310 #else
2311 /* Call legacy weak Abort Receive Complete Callback */
2312 HAL_UART_AbortReceiveCpltCallback(huart);
2313 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2314 }
2315
2316 return HAL_OK;
2317 }
2318
2319 /**
2320 * @brief Handle UART interrupt request.
2321 * @param huart UART handle.
2322 * @retval None
2323 */
HAL_UART_IRQHandler(UART_HandleTypeDef * huart)2324 void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
2325 {
2326 uint32_t isrflags = READ_REG(huart->Instance->ISR);
2327 uint32_t cr1its = READ_REG(huart->Instance->CR1);
2328 uint32_t cr3its = READ_REG(huart->Instance->CR3);
2329
2330 uint32_t errorflags;
2331 uint32_t errorcode;
2332
2333 /* If no error occurs */
2334 errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF));
2335 if (errorflags == 0U)
2336 {
2337 /* UART in mode Receiver ---------------------------------------------------*/
2338 if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
2339 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
2340 || ((cr3its & USART_CR3_RXFTIE) != 0U)))
2341 {
2342 if (huart->RxISR != NULL)
2343 {
2344 huart->RxISR(huart);
2345 }
2346 return;
2347 }
2348 }
2349
2350 /* If some errors occur */
2351 if ((errorflags != 0U)
2352 && ((((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)
2353 || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_RTOIE)) != 0U))))
2354 {
2355 /* UART parity error interrupt occurred -------------------------------------*/
2356 if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
2357 {
2358 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
2359
2360 huart->ErrorCode |= HAL_UART_ERROR_PE;
2361 }
2362
2363 /* UART frame error interrupt occurred --------------------------------------*/
2364 if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2365 {
2366 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
2367
2368 huart->ErrorCode |= HAL_UART_ERROR_FE;
2369 }
2370
2371 /* UART noise error interrupt occurred --------------------------------------*/
2372 if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2373 {
2374 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
2375
2376 huart->ErrorCode |= HAL_UART_ERROR_NE;
2377 }
2378
2379 /* UART Over-Run interrupt occurred -----------------------------------------*/
2380 if (((isrflags & USART_ISR_ORE) != 0U)
2381 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) ||
2382 ((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)))
2383 {
2384 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
2385
2386 huart->ErrorCode |= HAL_UART_ERROR_ORE;
2387 }
2388
2389 /* UART Receiver Timeout interrupt occurred ---------------------------------*/
2390 if (((isrflags & USART_ISR_RTOF) != 0U) && ((cr1its & USART_CR1_RTOIE) != 0U))
2391 {
2392 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);
2393
2394 huart->ErrorCode |= HAL_UART_ERROR_RTO;
2395 }
2396
2397 /* Call UART Error Call back function if need be ----------------------------*/
2398 if (huart->ErrorCode != HAL_UART_ERROR_NONE)
2399 {
2400 /* UART in mode Receiver --------------------------------------------------*/
2401 if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
2402 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
2403 || ((cr3its & USART_CR3_RXFTIE) != 0U)))
2404 {
2405 if (huart->RxISR != NULL)
2406 {
2407 huart->RxISR(huart);
2408 }
2409 }
2410
2411 /* If Error is to be considered as blocking :
2412 - Receiver Timeout error in Reception
2413 - Overrun error in Reception
2414 - any error occurs in DMA mode reception
2415 */
2416 errorcode = huart->ErrorCode;
2417 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) ||
2418 ((errorcode & (HAL_UART_ERROR_RTO | HAL_UART_ERROR_ORE)) != 0U))
2419 {
2420 /* Blocking error : transfer is aborted
2421 Set the UART state ready to be able to start again the process,
2422 Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
2423 UART_EndRxTransfer(huart);
2424
2425 #if defined(HAL_DMA_MODULE_ENABLED)
2426 /* Abort the UART DMA Rx channel if enabled */
2427 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2428 {
2429 /* Disable the UART DMA Rx request if enabled */
2430 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2431
2432 /* Abort the UART DMA Rx channel */
2433 if (huart->hdmarx != NULL)
2434 {
2435 /* Set the UART DMA Abort callback :
2436 will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */
2437 huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;
2438
2439 /* Abort DMA RX */
2440 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
2441 {
2442 /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
2443 huart->hdmarx->XferAbortCallback(huart->hdmarx);
2444 }
2445 }
2446 else
2447 {
2448 /* Call user error callback */
2449 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2450 /*Call registered error callback*/
2451 huart->ErrorCallback(huart);
2452 #else
2453 /*Call legacy weak error callback*/
2454 HAL_UART_ErrorCallback(huart);
2455 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2456
2457 }
2458 }
2459 else
2460 #endif /* HAL_DMA_MODULE_ENABLED */
2461 {
2462 /* Call user error callback */
2463 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2464 /*Call registered error callback*/
2465 huart->ErrorCallback(huart);
2466 #else
2467 /*Call legacy weak error callback*/
2468 HAL_UART_ErrorCallback(huart);
2469 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2470 }
2471 }
2472 else
2473 {
2474 /* Non Blocking error : transfer could go on.
2475 Error is notified to user through user error callback */
2476 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2477 /*Call registered error callback*/
2478 huart->ErrorCallback(huart);
2479 #else
2480 /*Call legacy weak error callback*/
2481 HAL_UART_ErrorCallback(huart);
2482 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2483 huart->ErrorCode = HAL_UART_ERROR_NONE;
2484 }
2485 }
2486 return;
2487
2488 } /* End if some error occurs */
2489
2490 /* Check current reception Mode :
2491 If Reception till IDLE event has been selected : */
2492 if ((huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
2493 && ((isrflags & USART_ISR_IDLE) != 0U)
2494 && ((cr1its & USART_ISR_IDLE) != 0U))
2495 {
2496 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
2497
2498 #if defined(HAL_DMA_MODULE_ENABLED)
2499 /* Check if DMA mode is enabled in UART */
2500 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2501 {
2502 /* DMA mode enabled */
2503 /* Check received length : If all expected data are received, do nothing,
2504 (DMA cplt callback will be called).
2505 Otherwise, if at least one data has already been received, IDLE event is to be notified to user */
2506 uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(huart->hdmarx);
2507 if ((nb_remaining_rx_data > 0U)
2508 && (nb_remaining_rx_data < huart->RxXferSize))
2509 {
2510 /* Reception is not complete */
2511 huart->RxXferCount = nb_remaining_rx_data;
2512
2513 /* In Normal mode, end DMA xfer and HAL UART Rx process*/
2514 if (HAL_IS_BIT_CLR(huart->hdmarx->Instance->CCR, DMA_CCR_CIRC))
2515 {
2516 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
2517 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
2518 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
2519
2520 /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
2521 in the UART CR3 register */
2522 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2523
2524 /* At end of Rx process, restore huart->RxState to Ready */
2525 huart->RxState = HAL_UART_STATE_READY;
2526 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2527
2528 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
2529
2530 /* Last bytes received, so no need as the abort is immediate */
2531 (void)HAL_DMA_Abort(huart->hdmarx);
2532 }
2533
2534 /* Initialize type of RxEvent that correspond to RxEvent callback execution;
2535 In this case, Rx Event type is Idle Event */
2536 huart->RxEventType = HAL_UART_RXEVENT_IDLE;
2537
2538 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2539 /*Call registered Rx Event callback*/
2540 huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
2541 #else
2542 /*Call legacy weak Rx Event callback*/
2543 HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
2544 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
2545 }
2546 return;
2547 }
2548 else
2549 {
2550 #endif /* HAL_DMA_MODULE_ENABLED */
2551 /* DMA mode not enabled */
2552 /* Check received length : If all expected data are received, do nothing.
2553 Otherwise, if at least one data has already been received, IDLE event is to be notified to user */
2554 uint16_t nb_rx_data = huart->RxXferSize - huart->RxXferCount;
2555 if ((huart->RxXferCount > 0U)
2556 && (nb_rx_data > 0U))
2557 {
2558 /* Disable the UART Parity Error Interrupt and RXNE interrupts */
2559 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
2560
2561 /* Disable the UART Error Interrupt:(Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */
2562 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
2563
2564 /* Rx process is completed, restore huart->RxState to Ready */
2565 huart->RxState = HAL_UART_STATE_READY;
2566 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2567
2568 /* Clear RxISR function pointer */
2569 huart->RxISR = NULL;
2570
2571 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
2572
2573 /* Initialize type of RxEvent that correspond to RxEvent callback execution;
2574 In this case, Rx Event type is Idle Event */
2575 huart->RxEventType = HAL_UART_RXEVENT_IDLE;
2576
2577 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2578 /*Call registered Rx complete callback*/
2579 huart->RxEventCallback(huart, nb_rx_data);
2580 #else
2581 /*Call legacy weak Rx Event callback*/
2582 HAL_UARTEx_RxEventCallback(huart, nb_rx_data);
2583 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
2584 }
2585 return;
2586 #if defined(HAL_DMA_MODULE_ENABLED)
2587 }
2588 #endif /* HAL_DMA_MODULE_ENABLED */
2589 }
2590
2591 /* UART wakeup from Stop mode interrupt occurred ---------------------------*/
2592 if (((isrflags & USART_ISR_WUF) != 0U) && ((cr3its & USART_CR3_WUFIE) != 0U))
2593 {
2594 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_WUF);
2595
2596 /* UART Rx state is not reset as a reception process might be ongoing.
2597 If UART handle state fields need to be reset to READY, this could be done in Wakeup callback */
2598
2599 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2600 /* Call registered Wakeup Callback */
2601 huart->WakeupCallback(huart);
2602 #else
2603 /* Call legacy weak Wakeup Callback */
2604 HAL_UARTEx_WakeupCallback(huart);
2605 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2606 return;
2607 }
2608
2609 /* UART in mode Transmitter ------------------------------------------------*/
2610 if (((isrflags & USART_ISR_TXE_TXFNF) != 0U)
2611 && (((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U)
2612 || ((cr3its & USART_CR3_TXFTIE) != 0U)))
2613 {
2614 if (huart->TxISR != NULL)
2615 {
2616 huart->TxISR(huart);
2617 }
2618 return;
2619 }
2620
2621 /* UART in mode Transmitter (transmission end) -----------------------------*/
2622 if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
2623 {
2624 UART_EndTransmit_IT(huart);
2625 return;
2626 }
2627
2628 /* UART TX Fifo Empty occurred ----------------------------------------------*/
2629 if (((isrflags & USART_ISR_TXFE) != 0U) && ((cr1its & USART_CR1_TXFEIE) != 0U))
2630 {
2631 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2632 /* Call registered Tx Fifo Empty Callback */
2633 huart->TxFifoEmptyCallback(huart);
2634 #else
2635 /* Call legacy weak Tx Fifo Empty Callback */
2636 HAL_UARTEx_TxFifoEmptyCallback(huart);
2637 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2638 return;
2639 }
2640
2641 /* UART RX Fifo Full occurred ----------------------------------------------*/
2642 if (((isrflags & USART_ISR_RXFF) != 0U) && ((cr1its & USART_CR1_RXFFIE) != 0U))
2643 {
2644 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2645 /* Call registered Rx Fifo Full Callback */
2646 huart->RxFifoFullCallback(huart);
2647 #else
2648 /* Call legacy weak Rx Fifo Full Callback */
2649 HAL_UARTEx_RxFifoFullCallback(huart);
2650 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2651 return;
2652 }
2653 }
2654
2655 /**
2656 * @brief Tx Transfer completed callback.
2657 * @param huart UART handle.
2658 * @retval None
2659 */
HAL_UART_TxCpltCallback(UART_HandleTypeDef * huart)2660 __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
2661 {
2662 /* Prevent unused argument(s) compilation warning */
2663 UNUSED(huart);
2664
2665 /* NOTE : This function should not be modified, when the callback is needed,
2666 the HAL_UART_TxCpltCallback can be implemented in the user file.
2667 */
2668 }
2669
2670 /**
2671 * @brief Tx Half Transfer completed callback.
2672 * @param huart UART handle.
2673 * @retval None
2674 */
HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef * huart)2675 __weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
2676 {
2677 /* Prevent unused argument(s) compilation warning */
2678 UNUSED(huart);
2679
2680 /* NOTE: This function should not be modified, when the callback is needed,
2681 the HAL_UART_TxHalfCpltCallback can be implemented in the user file.
2682 */
2683 }
2684
2685 /**
2686 * @brief Rx Transfer completed callback.
2687 * @param huart UART handle.
2688 * @retval None
2689 */
HAL_UART_RxCpltCallback(UART_HandleTypeDef * huart)2690 __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
2691 {
2692 /* Prevent unused argument(s) compilation warning */
2693 UNUSED(huart);
2694
2695 /* NOTE : This function should not be modified, when the callback is needed,
2696 the HAL_UART_RxCpltCallback can be implemented in the user file.
2697 */
2698 }
2699
2700 /**
2701 * @brief Rx Half Transfer completed callback.
2702 * @param huart UART handle.
2703 * @retval None
2704 */
HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef * huart)2705 __weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
2706 {
2707 /* Prevent unused argument(s) compilation warning */
2708 UNUSED(huart);
2709
2710 /* NOTE: This function should not be modified, when the callback is needed,
2711 the HAL_UART_RxHalfCpltCallback can be implemented in the user file.
2712 */
2713 }
2714
2715 /**
2716 * @brief UART error callback.
2717 * @param huart UART handle.
2718 * @retval None
2719 */
HAL_UART_ErrorCallback(UART_HandleTypeDef * huart)2720 __weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
2721 {
2722 /* Prevent unused argument(s) compilation warning */
2723 UNUSED(huart);
2724
2725 /* NOTE : This function should not be modified, when the callback is needed,
2726 the HAL_UART_ErrorCallback can be implemented in the user file.
2727 */
2728 }
2729
2730 /**
2731 * @brief UART Abort Complete callback.
2732 * @param huart UART handle.
2733 * @retval None
2734 */
HAL_UART_AbortCpltCallback(UART_HandleTypeDef * huart)2735 __weak void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart)
2736 {
2737 /* Prevent unused argument(s) compilation warning */
2738 UNUSED(huart);
2739
2740 /* NOTE : This function should not be modified, when the callback is needed,
2741 the HAL_UART_AbortCpltCallback can be implemented in the user file.
2742 */
2743 }
2744
2745 /**
2746 * @brief UART Abort Complete callback.
2747 * @param huart UART handle.
2748 * @retval None
2749 */
HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef * huart)2750 __weak void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart)
2751 {
2752 /* Prevent unused argument(s) compilation warning */
2753 UNUSED(huart);
2754
2755 /* NOTE : This function should not be modified, when the callback is needed,
2756 the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file.
2757 */
2758 }
2759
2760 /**
2761 * @brief UART Abort Receive Complete callback.
2762 * @param huart UART handle.
2763 * @retval None
2764 */
HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef * huart)2765 __weak void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart)
2766 {
2767 /* Prevent unused argument(s) compilation warning */
2768 UNUSED(huart);
2769
2770 /* NOTE : This function should not be modified, when the callback is needed,
2771 the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file.
2772 */
2773 }
2774
2775 /**
2776 * @brief Reception Event Callback (Rx event notification called after use of advanced reception service).
2777 * @param huart UART handle
2778 * @param Size Number of data available in application reception buffer (indicates a position in
2779 * reception buffer until which, data are available)
2780 * @retval None
2781 */
HAL_UARTEx_RxEventCallback(UART_HandleTypeDef * huart,uint16_t Size)2782 __weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
2783 {
2784 /* Prevent unused argument(s) compilation warning */
2785 UNUSED(huart);
2786 UNUSED(Size);
2787
2788 /* NOTE : This function should not be modified, when the callback is needed,
2789 the HAL_UARTEx_RxEventCallback can be implemented in the user file.
2790 */
2791 }
2792
2793 /**
2794 * @}
2795 */
2796
2797 /** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions
2798 * @brief UART control functions
2799 *
2800 @verbatim
2801 ===============================================================================
2802 ##### Peripheral Control functions #####
2803 ===============================================================================
2804 [..]
2805 This subsection provides a set of functions allowing to control the UART.
2806 (+) HAL_UART_ReceiverTimeout_Config() API allows to configure the receiver timeout value on the fly
2807 (+) HAL_UART_EnableReceiverTimeout() API enables the receiver timeout feature
2808 (+) HAL_UART_DisableReceiverTimeout() API disables the receiver timeout feature
2809 (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode
2810 (+) HAL_MultiProcessor_DisableMuteMode() API disables mute mode
2811 (+) HAL_MultiProcessor_EnterMuteMode() API enters mute mode
2812 (+) UART_SetConfig() API configures the UART peripheral
2813 (+) UART_AdvFeatureConfig() API optionally configures the UART advanced features
2814 (+) UART_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization
2815 (+) HAL_HalfDuplex_EnableTransmitter() API disables receiver and enables transmitter
2816 (+) HAL_HalfDuplex_EnableReceiver() API disables transmitter and enables receiver
2817 (+) HAL_LIN_SendBreak() API transmits the break characters
2818 @endverbatim
2819 * @{
2820 */
2821
2822 /**
2823 * @brief Update on the fly the receiver timeout value in RTOR register.
2824 * @param huart Pointer to a UART_HandleTypeDef structure that contains
2825 * the configuration information for the specified UART module.
2826 * @param TimeoutValue receiver timeout value in number of baud blocks. The timeout
2827 * value must be less or equal to 0x0FFFFFFFF.
2828 * @retval None
2829 */
HAL_UART_ReceiverTimeout_Config(UART_HandleTypeDef * huart,uint32_t TimeoutValue)2830 void HAL_UART_ReceiverTimeout_Config(UART_HandleTypeDef *huart, uint32_t TimeoutValue)
2831 {
2832 assert_param(IS_UART_RECEIVER_TIMEOUT_VALUE(TimeoutValue));
2833 MODIFY_REG(huart->Instance->RTOR, USART_RTOR_RTO, TimeoutValue);
2834 }
2835
2836 /**
2837 * @brief Enable the UART receiver timeout feature.
2838 * @param huart Pointer to a UART_HandleTypeDef structure that contains
2839 * the configuration information for the specified UART module.
2840 * @retval HAL status
2841 */
HAL_UART_EnableReceiverTimeout(UART_HandleTypeDef * huart)2842 HAL_StatusTypeDef HAL_UART_EnableReceiverTimeout(UART_HandleTypeDef *huart)
2843 {
2844 if (huart->gState == HAL_UART_STATE_READY)
2845 {
2846 /* Process Locked */
2847 __HAL_LOCK(huart);
2848
2849 huart->gState = HAL_UART_STATE_BUSY;
2850
2851 /* Set the USART RTOEN bit */
2852 SET_BIT(huart->Instance->CR2, USART_CR2_RTOEN);
2853
2854 huart->gState = HAL_UART_STATE_READY;
2855
2856 /* Process Unlocked */
2857 __HAL_UNLOCK(huart);
2858
2859 return HAL_OK;
2860 }
2861 else
2862 {
2863 return HAL_BUSY;
2864 }
2865 }
2866
2867 /**
2868 * @brief Disable the UART receiver timeout feature.
2869 * @param huart Pointer to a UART_HandleTypeDef structure that contains
2870 * the configuration information for the specified UART module.
2871 * @retval HAL status
2872 */
HAL_UART_DisableReceiverTimeout(UART_HandleTypeDef * huart)2873 HAL_StatusTypeDef HAL_UART_DisableReceiverTimeout(UART_HandleTypeDef *huart)
2874 {
2875 if (huart->gState == HAL_UART_STATE_READY)
2876 {
2877 /* Process Locked */
2878 __HAL_LOCK(huart);
2879
2880 huart->gState = HAL_UART_STATE_BUSY;
2881
2882 /* Clear the USART RTOEN bit */
2883 CLEAR_BIT(huart->Instance->CR2, USART_CR2_RTOEN);
2884
2885 huart->gState = HAL_UART_STATE_READY;
2886
2887 /* Process Unlocked */
2888 __HAL_UNLOCK(huart);
2889
2890 return HAL_OK;
2891 }
2892 else
2893 {
2894 return HAL_BUSY;
2895 }
2896 }
2897
2898 /**
2899 * @brief Enable UART in mute mode (does not mean UART enters mute mode;
2900 * to enter mute mode, HAL_MultiProcessor_EnterMuteMode() API must be called).
2901 * @param huart UART handle.
2902 * @retval HAL status
2903 */
HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef * huart)2904 HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart)
2905 {
2906 __HAL_LOCK(huart);
2907
2908 huart->gState = HAL_UART_STATE_BUSY;
2909
2910 /* Enable USART mute mode by setting the MME bit in the CR1 register */
2911 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_MME);
2912
2913 huart->gState = HAL_UART_STATE_READY;
2914
2915 return (UART_CheckIdleState(huart));
2916 }
2917
2918 /**
2919 * @brief Disable UART mute mode (does not mean the UART actually exits mute mode
2920 * as it may not have been in mute mode at this very moment).
2921 * @param huart UART handle.
2922 * @retval HAL status
2923 */
HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef * huart)2924 HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart)
2925 {
2926 __HAL_LOCK(huart);
2927
2928 huart->gState = HAL_UART_STATE_BUSY;
2929
2930 /* Disable USART mute mode by clearing the MME bit in the CR1 register */
2931 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_MME);
2932
2933 huart->gState = HAL_UART_STATE_READY;
2934
2935 return (UART_CheckIdleState(huart));
2936 }
2937
2938 /**
2939 * @brief Enter UART mute mode (means UART actually enters mute mode).
2940 * @note To exit from mute mode, HAL_MultiProcessor_DisableMuteMode() API must be called.
2941 * @param huart UART handle.
2942 * @retval None
2943 */
HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef * huart)2944 void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart)
2945 {
2946 __HAL_UART_SEND_REQ(huart, UART_MUTE_MODE_REQUEST);
2947 }
2948
2949 /**
2950 * @brief Enable the UART transmitter and disable the UART receiver.
2951 * @param huart UART handle.
2952 * @retval HAL status
2953 */
HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef * huart)2954 HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
2955 {
2956 __HAL_LOCK(huart);
2957 huart->gState = HAL_UART_STATE_BUSY;
2958
2959 /* Clear TE and RE bits */
2960 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
2961
2962 /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
2963 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TE);
2964
2965 huart->gState = HAL_UART_STATE_READY;
2966
2967 __HAL_UNLOCK(huart);
2968
2969 return HAL_OK;
2970 }
2971
2972 /**
2973 * @brief Enable the UART receiver and disable the UART transmitter.
2974 * @param huart UART handle.
2975 * @retval HAL status.
2976 */
HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef * huart)2977 HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart)
2978 {
2979 __HAL_LOCK(huart);
2980 huart->gState = HAL_UART_STATE_BUSY;
2981
2982 /* Clear TE and RE bits */
2983 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
2984
2985 /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
2986 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RE);
2987
2988 huart->gState = HAL_UART_STATE_READY;
2989
2990 __HAL_UNLOCK(huart);
2991
2992 return HAL_OK;
2993 }
2994
2995
2996 /**
2997 * @brief Transmit break characters.
2998 * @param huart UART handle.
2999 * @retval HAL status
3000 */
HAL_LIN_SendBreak(UART_HandleTypeDef * huart)3001 HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
3002 {
3003 /* Check the parameters */
3004 assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
3005
3006 __HAL_LOCK(huart);
3007
3008 huart->gState = HAL_UART_STATE_BUSY;
3009
3010 /* Send break characters */
3011 __HAL_UART_SEND_REQ(huart, UART_SENDBREAK_REQUEST);
3012
3013 huart->gState = HAL_UART_STATE_READY;
3014
3015 __HAL_UNLOCK(huart);
3016
3017 return HAL_OK;
3018 }
3019
3020 /**
3021 * @}
3022 */
3023
3024 /** @defgroup UART_Exported_Functions_Group4 Peripheral State and Error functions
3025 * @brief UART Peripheral State functions
3026 *
3027 @verbatim
3028 ==============================================================================
3029 ##### Peripheral State and Error functions #####
3030 ==============================================================================
3031 [..]
3032 This subsection provides functions allowing to :
3033 (+) Return the UART handle state.
3034 (+) Return the UART handle error code
3035
3036 @endverbatim
3037 * @{
3038 */
3039
3040 /**
3041 * @brief Return the UART handle state.
3042 * @param huart Pointer to a UART_HandleTypeDef structure that contains
3043 * the configuration information for the specified UART.
3044 * @retval HAL state
3045 */
HAL_UART_GetState(const UART_HandleTypeDef * huart)3046 HAL_UART_StateTypeDef HAL_UART_GetState(const UART_HandleTypeDef *huart)
3047 {
3048 uint32_t temp1;
3049 uint32_t temp2;
3050 temp1 = huart->gState;
3051 temp2 = huart->RxState;
3052
3053 return (HAL_UART_StateTypeDef)(temp1 | temp2);
3054 }
3055
3056 /**
3057 * @brief Return the UART handle error code.
3058 * @param huart Pointer to a UART_HandleTypeDef structure that contains
3059 * the configuration information for the specified UART.
3060 * @retval UART Error Code
3061 */
HAL_UART_GetError(const UART_HandleTypeDef * huart)3062 uint32_t HAL_UART_GetError(const UART_HandleTypeDef *huart)
3063 {
3064 return huart->ErrorCode;
3065 }
3066 /**
3067 * @}
3068 */
3069
3070 /**
3071 * @}
3072 */
3073
3074 /** @defgroup UART_Private_Functions UART Private Functions
3075 * @{
3076 */
3077
3078 /**
3079 * @brief Initialize the callbacks to their default values.
3080 * @param huart UART handle.
3081 * @retval none
3082 */
3083 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
UART_InitCallbacksToDefault(UART_HandleTypeDef * huart)3084 void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart)
3085 {
3086 /* Init the UART Callback settings */
3087 huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
3088 huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */
3089 huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
3090 huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */
3091 huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */
3092 huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
3093 huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
3094 huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
3095 huart->WakeupCallback = HAL_UARTEx_WakeupCallback; /* Legacy weak WakeupCallback */
3096 huart->RxFifoFullCallback = HAL_UARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */
3097 huart->TxFifoEmptyCallback = HAL_UARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */
3098 huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak RxEventCallback */
3099
3100 }
3101 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3102
3103 /**
3104 * @brief Configure the UART peripheral.
3105 * @param huart UART handle.
3106 * @retval HAL status
3107 */
UART_SetConfig(UART_HandleTypeDef * huart)3108 HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart)
3109 {
3110 uint32_t tmpreg;
3111 uint16_t brrtemp;
3112 UART_ClockSourceTypeDef clocksource;
3113 uint32_t usartdiv;
3114 HAL_StatusTypeDef ret = HAL_OK;
3115 uint32_t pclk;
3116
3117 /* Check the parameters */
3118 assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
3119 assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
3120 assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
3121 assert_param(IS_UART_ONE_BIT_SAMPLE(huart->Init.OneBitSampling));
3122
3123 assert_param(IS_UART_PARITY(huart->Init.Parity));
3124 assert_param(IS_UART_MODE(huart->Init.Mode));
3125 assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
3126 assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
3127 assert_param(IS_UART_PRESCALER(huart->Init.ClockPrescaler));
3128
3129 /*-------------------------- USART CR1 Configuration -----------------------*/
3130 /* Clear M, PCE, PS, TE, RE and OVER8 bits and configure
3131 * the UART Word Length, Parity, Mode and oversampling:
3132 * set the M bits according to huart->Init.WordLength value
3133 * set PCE and PS bits according to huart->Init.Parity value
3134 * set TE and RE bits according to huart->Init.Mode value
3135 * set OVER8 bit according to huart->Init.OverSampling value */
3136 tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling ;
3137 MODIFY_REG(huart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
3138
3139 /*-------------------------- USART CR2 Configuration -----------------------*/
3140 /* Configure the UART Stop Bits: Set STOP[13:12] bits according
3141 * to huart->Init.StopBits value */
3142 MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
3143
3144 /*-------------------------- USART CR3 Configuration -----------------------*/
3145 /* Configure
3146 * - UART HardWare Flow Control: set CTSE and RTSE bits according
3147 * to huart->Init.HwFlowCtl value
3148 * - one-bit sampling method versus three samples' majority rule according
3149 * to huart->Init.OneBitSampling (not applicable to LPUART) */
3150 tmpreg = (uint32_t)huart->Init.HwFlowCtl;
3151
3152 tmpreg |= huart->Init.OneBitSampling;
3153 MODIFY_REG(huart->Instance->CR3, USART_CR3_FIELDS, tmpreg);
3154
3155 /*-------------------------- USART PRESC Configuration -----------------------*/
3156 /* Configure
3157 * - UART Clock Prescaler : set PRESCALER according to huart->Init.ClockPrescaler value */
3158 MODIFY_REG(huart->Instance->PRESC, USART_PRESC_PRESCALER, huart->Init.ClockPrescaler);
3159
3160 /*-------------------------- USART BRR Configuration -----------------------*/
3161 UART_GETCLOCKSOURCE(huart, clocksource);
3162
3163 if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
3164 {
3165 switch (clocksource)
3166 {
3167 case UART_CLOCKSOURCE_PCLK1:
3168 pclk = HAL_RCC_GetPCLK1Freq();
3169 break;
3170 case UART_CLOCKSOURCE_HSI:
3171 pclk = (HSI_VALUE / ((__HAL_RCC_GET_HSIKER_DIVIDER() >> RCC_CR_HSIKERDIV_Pos) + 1U));
3172 break;
3173 case UART_CLOCKSOURCE_SYSCLK:
3174 pclk = HAL_RCC_GetSysClockFreq();
3175 break;
3176 case UART_CLOCKSOURCE_LSE:
3177 pclk = (uint32_t) LSE_VALUE;
3178 break;
3179 default:
3180 pclk = 0U;
3181 ret = HAL_ERROR;
3182 break;
3183 }
3184
3185 /* USARTDIV must be greater than or equal to 0d16 */
3186 if (pclk != 0U)
3187 {
3188 usartdiv = (uint32_t)(UART_DIV_SAMPLING8(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3189 if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
3190 {
3191 brrtemp = (uint16_t)(usartdiv & 0xFFF0U);
3192 brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U);
3193 huart->Instance->BRR = brrtemp;
3194 }
3195 else
3196 {
3197 ret = HAL_ERROR;
3198 }
3199 }
3200 }
3201 else
3202 {
3203 switch (clocksource)
3204 {
3205 case UART_CLOCKSOURCE_PCLK1:
3206 pclk = HAL_RCC_GetPCLK1Freq();
3207 break;
3208 case UART_CLOCKSOURCE_HSI:
3209 pclk = (HSI_VALUE / ((__HAL_RCC_GET_HSIKER_DIVIDER() >> RCC_CR_HSIKERDIV_Pos) + 1U));
3210 break;
3211 case UART_CLOCKSOURCE_SYSCLK:
3212 pclk = HAL_RCC_GetSysClockFreq();
3213 break;
3214 case UART_CLOCKSOURCE_LSE:
3215 pclk = (uint32_t) LSE_VALUE;
3216 break;
3217 default:
3218 pclk = 0U;
3219 ret = HAL_ERROR;
3220 break;
3221 }
3222
3223 if (pclk != 0U)
3224 {
3225 /* USARTDIV must be greater than or equal to 0d16 */
3226 usartdiv = (uint32_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3227 if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
3228 {
3229 huart->Instance->BRR = (uint16_t)usartdiv;
3230 }
3231 else
3232 {
3233 ret = HAL_ERROR;
3234 }
3235 }
3236 }
3237
3238 /* Initialize the number of data to process during RX/TX ISR execution */
3239 huart->NbTxDataToProcess = 1;
3240 huart->NbRxDataToProcess = 1;
3241
3242 /* Clear ISR function pointers */
3243 huart->RxISR = NULL;
3244 huart->TxISR = NULL;
3245
3246 return ret;
3247 }
3248
3249 /**
3250 * @brief Configure the UART peripheral advanced features.
3251 * @param huart UART handle.
3252 * @retval None
3253 */
UART_AdvFeatureConfig(UART_HandleTypeDef * huart)3254 void UART_AdvFeatureConfig(UART_HandleTypeDef *huart)
3255 {
3256 /* Check whether the set of advanced features to configure is properly set */
3257 assert_param(IS_UART_ADVFEATURE_INIT(huart->AdvancedInit.AdvFeatureInit));
3258
3259 /* if required, configure RX/TX pins swap */
3260 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_SWAP_INIT))
3261 {
3262 assert_param(IS_UART_ADVFEATURE_SWAP(huart->AdvancedInit.Swap));
3263 MODIFY_REG(huart->Instance->CR2, USART_CR2_SWAP, huart->AdvancedInit.Swap);
3264 }
3265
3266 /* if required, configure TX pin active level inversion */
3267 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_TXINVERT_INIT))
3268 {
3269 assert_param(IS_UART_ADVFEATURE_TXINV(huart->AdvancedInit.TxPinLevelInvert));
3270 MODIFY_REG(huart->Instance->CR2, USART_CR2_TXINV, huart->AdvancedInit.TxPinLevelInvert);
3271 }
3272
3273 /* if required, configure RX pin active level inversion */
3274 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXINVERT_INIT))
3275 {
3276 assert_param(IS_UART_ADVFEATURE_RXINV(huart->AdvancedInit.RxPinLevelInvert));
3277 MODIFY_REG(huart->Instance->CR2, USART_CR2_RXINV, huart->AdvancedInit.RxPinLevelInvert);
3278 }
3279
3280 /* if required, configure data inversion */
3281 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DATAINVERT_INIT))
3282 {
3283 assert_param(IS_UART_ADVFEATURE_DATAINV(huart->AdvancedInit.DataInvert));
3284 MODIFY_REG(huart->Instance->CR2, USART_CR2_DATAINV, huart->AdvancedInit.DataInvert);
3285 }
3286
3287 /* if required, configure RX overrun detection disabling */
3288 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXOVERRUNDISABLE_INIT))
3289 {
3290 assert_param(IS_UART_OVERRUN(huart->AdvancedInit.OverrunDisable));
3291 MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, huart->AdvancedInit.OverrunDisable);
3292 }
3293
3294 #if defined(HAL_DMA_MODULE_ENABLED)
3295 /* if required, configure DMA disabling on reception error */
3296 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DMADISABLEONERROR_INIT))
3297 {
3298 assert_param(IS_UART_ADVFEATURE_DMAONRXERROR(huart->AdvancedInit.DMADisableonRxError));
3299 MODIFY_REG(huart->Instance->CR3, USART_CR3_DDRE, huart->AdvancedInit.DMADisableonRxError);
3300 }
3301 #endif /* HAL_DMA_MODULE_ENABLED */
3302
3303 /* if required, configure auto Baud rate detection scheme */
3304 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT))
3305 {
3306 assert_param(IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(huart->Instance));
3307 assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable));
3308 MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable);
3309 /* set auto Baudrate detection parameters if detection is enabled */
3310 if (huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)
3311 {
3312 assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode));
3313 MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode);
3314 }
3315 }
3316
3317 /* if required, configure MSB first on communication line */
3318 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_MSBFIRST_INIT))
3319 {
3320 assert_param(IS_UART_ADVFEATURE_MSBFIRST(huart->AdvancedInit.MSBFirst));
3321 MODIFY_REG(huart->Instance->CR2, USART_CR2_MSBFIRST, huart->AdvancedInit.MSBFirst);
3322 }
3323 }
3324
3325 /**
3326 * @brief Check the UART Idle State.
3327 * @param huart UART handle.
3328 * @retval HAL status
3329 */
UART_CheckIdleState(UART_HandleTypeDef * huart)3330 HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart)
3331 {
3332 uint32_t tickstart;
3333
3334 /* Initialize the UART ErrorCode */
3335 huart->ErrorCode = HAL_UART_ERROR_NONE;
3336
3337 /* Init tickstart for timeout management */
3338 tickstart = HAL_GetTick();
3339
3340 /* Check if the Transmitter is enabled */
3341 if ((huart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
3342 {
3343 /* Wait until TEACK flag is set */
3344 if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
3345 {
3346 /* Disable TXE interrupt for the interrupt process */
3347 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE));
3348
3349 huart->gState = HAL_UART_STATE_READY;
3350
3351 __HAL_UNLOCK(huart);
3352
3353 /* Timeout occurred */
3354 return HAL_TIMEOUT;
3355 }
3356 }
3357
3358 /* Check if the Receiver is enabled */
3359 if ((huart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
3360 {
3361 /* Wait until REACK flag is set */
3362 if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
3363 {
3364 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error)
3365 interrupts for the interrupt process */
3366 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3367 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3368
3369 huart->RxState = HAL_UART_STATE_READY;
3370
3371 __HAL_UNLOCK(huart);
3372
3373 /* Timeout occurred */
3374 return HAL_TIMEOUT;
3375 }
3376 }
3377
3378 /* Initialize the UART State */
3379 huart->gState = HAL_UART_STATE_READY;
3380 huart->RxState = HAL_UART_STATE_READY;
3381 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
3382 huart->RxEventType = HAL_UART_RXEVENT_TC;
3383
3384 __HAL_UNLOCK(huart);
3385
3386 return HAL_OK;
3387 }
3388
3389 /**
3390 * @brief This function handles UART Communication Timeout. It waits
3391 * until a flag is no longer in the specified status.
3392 * @param huart UART handle.
3393 * @param Flag Specifies the UART flag to check
3394 * @param Status The actual Flag status (SET or RESET)
3395 * @param Tickstart Tick start value
3396 * @param Timeout Timeout duration
3397 * @retval HAL status
3398 */
UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef * huart,uint32_t Flag,FlagStatus Status,uint32_t Tickstart,uint32_t Timeout)3399 HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status,
3400 uint32_t Tickstart, uint32_t Timeout)
3401 {
3402 /* Wait until flag is set */
3403 while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status)
3404 {
3405 /* Check for the Timeout */
3406 if (Timeout != HAL_MAX_DELAY)
3407 {
3408 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
3409 {
3410
3411 return HAL_TIMEOUT;
3412 }
3413
3414 if (READ_BIT(huart->Instance->CR1, USART_CR1_RE) != 0U)
3415 {
3416 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) == SET)
3417 {
3418 /* Clear Overrun Error flag*/
3419 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
3420
3421 /* Blocking error : transfer is aborted
3422 Set the UART state ready to be able to start again the process,
3423 Disable Rx Interrupts if ongoing */
3424 UART_EndRxTransfer(huart);
3425
3426 huart->ErrorCode = HAL_UART_ERROR_ORE;
3427
3428 /* Process Unlocked */
3429 __HAL_UNLOCK(huart);
3430
3431 return HAL_ERROR;
3432 }
3433 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RTOF) == SET)
3434 {
3435 /* Clear Receiver Timeout flag*/
3436 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);
3437
3438 /* Blocking error : transfer is aborted
3439 Set the UART state ready to be able to start again the process,
3440 Disable Rx Interrupts if ongoing */
3441 UART_EndRxTransfer(huart);
3442
3443 huart->ErrorCode = HAL_UART_ERROR_RTO;
3444
3445 /* Process Unlocked */
3446 __HAL_UNLOCK(huart);
3447
3448 return HAL_TIMEOUT;
3449 }
3450 }
3451 }
3452 }
3453 return HAL_OK;
3454 }
3455
3456 /**
3457 * @brief Start Receive operation in interrupt mode.
3458 * @note This function could be called by all HAL UART API providing reception in Interrupt mode.
3459 * @note When calling this function, parameters validity is considered as already checked,
3460 * i.e. Rx State, buffer address, ...
3461 * UART Handle is assumed as Locked.
3462 * @param huart UART handle.
3463 * @param pData Pointer to data buffer (u8 or u16 data elements).
3464 * @param Size Amount of data elements (u8 or u16) to be received.
3465 * @retval HAL status
3466 */
UART_Start_Receive_IT(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)3467 HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
3468 {
3469 huart->pRxBuffPtr = pData;
3470 huart->RxXferSize = Size;
3471 huart->RxXferCount = Size;
3472 huart->RxISR = NULL;
3473
3474 /* Computation of UART mask to apply to RDR register */
3475 UART_MASK_COMPUTATION(huart);
3476
3477 huart->ErrorCode = HAL_UART_ERROR_NONE;
3478 huart->RxState = HAL_UART_STATE_BUSY_RX;
3479
3480 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
3481 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
3482
3483 /* Configure Rx interrupt processing */
3484 if ((huart->FifoMode == UART_FIFOMODE_ENABLE) && (Size >= huart->NbRxDataToProcess))
3485 {
3486 /* Set the Rx ISR function pointer according to the data word length */
3487 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
3488 {
3489 huart->RxISR = UART_RxISR_16BIT_FIFOEN;
3490 }
3491 else
3492 {
3493 huart->RxISR = UART_RxISR_8BIT_FIFOEN;
3494 }
3495
3496 /* Enable the UART Parity Error interrupt and RX FIFO Threshold interrupt */
3497 if (huart->Init.Parity != UART_PARITY_NONE)
3498 {
3499 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
3500 }
3501 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
3502 }
3503 else
3504 {
3505 /* Set the Rx ISR function pointer according to the data word length */
3506 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
3507 {
3508 huart->RxISR = UART_RxISR_16BIT;
3509 }
3510 else
3511 {
3512 huart->RxISR = UART_RxISR_8BIT;
3513 }
3514
3515 /* Enable the UART Parity Error interrupt and Data Register Not Empty interrupt */
3516 if (huart->Init.Parity != UART_PARITY_NONE)
3517 {
3518 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
3519 }
3520 else
3521 {
3522 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
3523 }
3524 }
3525 return HAL_OK;
3526 }
3527
3528 #if defined(HAL_DMA_MODULE_ENABLED)
3529 /**
3530 * @brief Start Receive operation in DMA mode.
3531 * @note This function could be called by all HAL UART API providing reception in DMA mode.
3532 * @note When calling this function, parameters validity is considered as already checked,
3533 * i.e. Rx State, buffer address, ...
3534 * UART Handle is assumed as Locked.
3535 * @param huart UART handle.
3536 * @param pData Pointer to data buffer (u8 or u16 data elements).
3537 * @param Size Amount of data elements (u8 or u16) to be received.
3538 * @retval HAL status
3539 */
UART_Start_Receive_DMA(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)3540 HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
3541 {
3542 huart->pRxBuffPtr = pData;
3543 huart->RxXferSize = Size;
3544
3545 huart->ErrorCode = HAL_UART_ERROR_NONE;
3546 huart->RxState = HAL_UART_STATE_BUSY_RX;
3547
3548 if (huart->hdmarx != NULL)
3549 {
3550 /* Set the UART DMA transfer complete callback */
3551 huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
3552
3553 /* Set the UART DMA Half transfer complete callback */
3554 huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
3555
3556 /* Set the DMA error callback */
3557 huart->hdmarx->XferErrorCallback = UART_DMAError;
3558
3559 /* Set the DMA abort callback */
3560 huart->hdmarx->XferAbortCallback = NULL;
3561
3562 /* Enable the DMA channel */
3563 if (HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, (uint32_t)huart->pRxBuffPtr, Size) != HAL_OK)
3564 {
3565 /* Set error code to DMA */
3566 huart->ErrorCode = HAL_UART_ERROR_DMA;
3567
3568 /* Restore huart->RxState to ready */
3569 huart->RxState = HAL_UART_STATE_READY;
3570
3571 return HAL_ERROR;
3572 }
3573 }
3574
3575 /* Enable the UART Parity Error Interrupt */
3576 if (huart->Init.Parity != UART_PARITY_NONE)
3577 {
3578 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
3579 }
3580
3581 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
3582 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
3583
3584 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
3585 in the UART CR3 register */
3586 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
3587
3588 return HAL_OK;
3589 }
3590
3591
3592 /**
3593 * @brief End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion).
3594 * @param huart UART handle.
3595 * @retval None
3596 */
UART_EndTxTransfer(UART_HandleTypeDef * huart)3597 static void UART_EndTxTransfer(UART_HandleTypeDef *huart)
3598 {
3599 /* Disable TXEIE, TCIE, TXFT interrupts */
3600 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
3601 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_TXFTIE));
3602
3603 /* At end of Tx process, restore huart->gState to Ready */
3604 huart->gState = HAL_UART_STATE_READY;
3605 }
3606 #endif /* HAL_DMA_MODULE_ENABLED */
3607
3608
3609 /**
3610 * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
3611 * @param huart UART handle.
3612 * @retval None
3613 */
UART_EndRxTransfer(UART_HandleTypeDef * huart)3614 static void UART_EndRxTransfer(UART_HandleTypeDef *huart)
3615 {
3616 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
3617 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3618 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
3619
3620 /* In case of reception waiting for IDLE event, disable also the IDLE IE interrupt source */
3621 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3622 {
3623 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
3624 }
3625
3626 /* At end of Rx process, restore huart->RxState to Ready */
3627 huart->RxState = HAL_UART_STATE_READY;
3628 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
3629
3630 /* Reset RxIsr function pointer */
3631 huart->RxISR = NULL;
3632 }
3633
3634
3635 #if defined(HAL_DMA_MODULE_ENABLED)
3636 /**
3637 * @brief DMA UART transmit process complete callback.
3638 * @param hdma DMA handle.
3639 * @retval None
3640 */
UART_DMATransmitCplt(DMA_HandleTypeDef * hdma)3641 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
3642 {
3643 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3644
3645 /* DMA Normal mode */
3646 if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
3647 {
3648 huart->TxXferCount = 0U;
3649
3650 /* Disable the DMA transfer for transmit request by resetting the DMAT bit
3651 in the UART CR3 register */
3652 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
3653
3654 /* Enable the UART Transmit Complete Interrupt */
3655 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3656 }
3657 /* DMA Circular mode */
3658 else
3659 {
3660 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3661 /*Call registered Tx complete callback*/
3662 huart->TxCpltCallback(huart);
3663 #else
3664 /*Call legacy weak Tx complete callback*/
3665 HAL_UART_TxCpltCallback(huart);
3666 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3667 }
3668 }
3669
3670 /**
3671 * @brief DMA UART transmit process half complete callback.
3672 * @param hdma DMA handle.
3673 * @retval None
3674 */
UART_DMATxHalfCplt(DMA_HandleTypeDef * hdma)3675 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
3676 {
3677 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3678
3679 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3680 /*Call registered Tx Half complete callback*/
3681 huart->TxHalfCpltCallback(huart);
3682 #else
3683 /*Call legacy weak Tx Half complete callback*/
3684 HAL_UART_TxHalfCpltCallback(huart);
3685 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3686 }
3687
3688 /**
3689 * @brief DMA UART receive process complete callback.
3690 * @param hdma DMA handle.
3691 * @retval None
3692 */
UART_DMAReceiveCplt(DMA_HandleTypeDef * hdma)3693 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
3694 {
3695 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3696
3697 /* DMA Normal mode */
3698 if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
3699 {
3700 huart->RxXferCount = 0U;
3701
3702 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
3703 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
3704 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3705
3706 /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
3707 in the UART CR3 register */
3708 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
3709
3710 /* At end of Rx process, restore huart->RxState to Ready */
3711 huart->RxState = HAL_UART_STATE_READY;
3712
3713 /* If Reception till IDLE event has been selected, Disable IDLE Interrupt */
3714 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3715 {
3716 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
3717 }
3718 }
3719
3720 /* Initialize type of RxEvent that correspond to RxEvent callback execution;
3721 In this case, Rx Event type is Transfer Complete */
3722 huart->RxEventType = HAL_UART_RXEVENT_TC;
3723
3724 /* Check current reception Mode :
3725 If Reception till IDLE event has been selected : use Rx Event callback */
3726 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3727 {
3728 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3729 /*Call registered Rx Event callback*/
3730 huart->RxEventCallback(huart, huart->RxXferSize);
3731 #else
3732 /*Call legacy weak Rx Event callback*/
3733 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
3734 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3735 }
3736 else
3737 {
3738 /* In other cases : use Rx Complete callback */
3739 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3740 /*Call registered Rx complete callback*/
3741 huart->RxCpltCallback(huart);
3742 #else
3743 /*Call legacy weak Rx complete callback*/
3744 HAL_UART_RxCpltCallback(huart);
3745 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3746 }
3747 }
3748
3749 /**
3750 * @brief DMA UART receive process half complete callback.
3751 * @param hdma DMA handle.
3752 * @retval None
3753 */
UART_DMARxHalfCplt(DMA_HandleTypeDef * hdma)3754 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
3755 {
3756 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3757
3758 /* Initialize type of RxEvent that correspond to RxEvent callback execution;
3759 In this case, Rx Event type is Half Transfer */
3760 huart->RxEventType = HAL_UART_RXEVENT_HT;
3761
3762 /* Check current reception Mode :
3763 If Reception till IDLE event has been selected : use Rx Event callback */
3764 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3765 {
3766 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3767 /*Call registered Rx Event callback*/
3768 huart->RxEventCallback(huart, huart->RxXferSize / 2U);
3769 #else
3770 /*Call legacy weak Rx Event callback*/
3771 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize / 2U);
3772 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3773 }
3774 else
3775 {
3776 /* In other cases : use Rx Half Complete callback */
3777 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3778 /*Call registered Rx Half complete callback*/
3779 huart->RxHalfCpltCallback(huart);
3780 #else
3781 /*Call legacy weak Rx Half complete callback*/
3782 HAL_UART_RxHalfCpltCallback(huart);
3783 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3784 }
3785 }
3786
3787 /**
3788 * @brief DMA UART communication error callback.
3789 * @param hdma DMA handle.
3790 * @retval None
3791 */
UART_DMAError(DMA_HandleTypeDef * hdma)3792 static void UART_DMAError(DMA_HandleTypeDef *hdma)
3793 {
3794 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3795
3796 const HAL_UART_StateTypeDef gstate = huart->gState;
3797 const HAL_UART_StateTypeDef rxstate = huart->RxState;
3798
3799 /* Stop UART DMA Tx request if ongoing */
3800 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
3801 (gstate == HAL_UART_STATE_BUSY_TX))
3802 {
3803 huart->TxXferCount = 0U;
3804 UART_EndTxTransfer(huart);
3805 }
3806
3807 /* Stop UART DMA Rx request if ongoing */
3808 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
3809 (rxstate == HAL_UART_STATE_BUSY_RX))
3810 {
3811 huart->RxXferCount = 0U;
3812 UART_EndRxTransfer(huart);
3813 }
3814
3815 huart->ErrorCode |= HAL_UART_ERROR_DMA;
3816
3817 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3818 /*Call registered error callback*/
3819 huart->ErrorCallback(huart);
3820 #else
3821 /*Call legacy weak error callback*/
3822 HAL_UART_ErrorCallback(huart);
3823 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3824 }
3825
3826 /**
3827 * @brief DMA UART communication abort callback, when initiated by HAL services on Error
3828 * (To be called at end of DMA Abort procedure following error occurrence).
3829 * @param hdma DMA handle.
3830 * @retval None
3831 */
UART_DMAAbortOnError(DMA_HandleTypeDef * hdma)3832 static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
3833 {
3834 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3835 huart->RxXferCount = 0U;
3836 huart->TxXferCount = 0U;
3837
3838 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3839 /*Call registered error callback*/
3840 huart->ErrorCallback(huart);
3841 #else
3842 /*Call legacy weak error callback*/
3843 HAL_UART_ErrorCallback(huart);
3844 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3845 }
3846
3847 /**
3848 * @brief DMA UART Tx communication abort callback, when initiated by user
3849 * (To be called at end of DMA Tx Abort procedure following user abort request).
3850 * @note When this callback is executed, User Abort complete call back is called only if no
3851 * Abort still ongoing for Rx DMA Handle.
3852 * @param hdma DMA handle.
3853 * @retval None
3854 */
UART_DMATxAbortCallback(DMA_HandleTypeDef * hdma)3855 static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
3856 {
3857 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3858
3859 huart->hdmatx->XferAbortCallback = NULL;
3860
3861 /* Check if an Abort process is still ongoing */
3862 if (huart->hdmarx != NULL)
3863 {
3864 if (huart->hdmarx->XferAbortCallback != NULL)
3865 {
3866 return;
3867 }
3868 }
3869
3870 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
3871 huart->TxXferCount = 0U;
3872 huart->RxXferCount = 0U;
3873
3874 /* Reset errorCode */
3875 huart->ErrorCode = HAL_UART_ERROR_NONE;
3876
3877 /* Clear the Error flags in the ICR register */
3878 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3879
3880 /* Flush the whole TX FIFO (if needed) */
3881 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
3882 {
3883 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
3884 }
3885
3886 /* Restore huart->gState and huart->RxState to Ready */
3887 huart->gState = HAL_UART_STATE_READY;
3888 huart->RxState = HAL_UART_STATE_READY;
3889 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
3890
3891 /* Call user Abort complete callback */
3892 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3893 /* Call registered Abort complete callback */
3894 huart->AbortCpltCallback(huart);
3895 #else
3896 /* Call legacy weak Abort complete callback */
3897 HAL_UART_AbortCpltCallback(huart);
3898 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3899 }
3900
3901
3902 /**
3903 * @brief DMA UART Rx communication abort callback, when initiated by user
3904 * (To be called at end of DMA Rx Abort procedure following user abort request).
3905 * @note When this callback is executed, User Abort complete call back is called only if no
3906 * Abort still ongoing for Tx DMA Handle.
3907 * @param hdma DMA handle.
3908 * @retval None
3909 */
UART_DMARxAbortCallback(DMA_HandleTypeDef * hdma)3910 static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
3911 {
3912 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3913
3914 huart->hdmarx->XferAbortCallback = NULL;
3915
3916 /* Check if an Abort process is still ongoing */
3917 if (huart->hdmatx != NULL)
3918 {
3919 if (huart->hdmatx->XferAbortCallback != NULL)
3920 {
3921 return;
3922 }
3923 }
3924
3925 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
3926 huart->TxXferCount = 0U;
3927 huart->RxXferCount = 0U;
3928
3929 /* Reset errorCode */
3930 huart->ErrorCode = HAL_UART_ERROR_NONE;
3931
3932 /* Clear the Error flags in the ICR register */
3933 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3934
3935 /* Discard the received data */
3936 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3937
3938 /* Restore huart->gState and huart->RxState to Ready */
3939 huart->gState = HAL_UART_STATE_READY;
3940 huart->RxState = HAL_UART_STATE_READY;
3941 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
3942
3943 /* Call user Abort complete callback */
3944 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3945 /* Call registered Abort complete callback */
3946 huart->AbortCpltCallback(huart);
3947 #else
3948 /* Call legacy weak Abort complete callback */
3949 HAL_UART_AbortCpltCallback(huart);
3950 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3951 }
3952
3953
3954 /**
3955 * @brief DMA UART Tx communication abort callback, when initiated by user by a call to
3956 * HAL_UART_AbortTransmit_IT API (Abort only Tx transfer)
3957 * (This callback is executed at end of DMA Tx Abort procedure following user abort request,
3958 * and leads to user Tx Abort Complete callback execution).
3959 * @param hdma DMA handle.
3960 * @retval None
3961 */
UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef * hdma)3962 static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
3963 {
3964 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3965
3966 huart->TxXferCount = 0U;
3967
3968 /* Flush the whole TX FIFO (if needed) */
3969 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
3970 {
3971 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
3972 }
3973
3974 /* Restore huart->gState to Ready */
3975 huart->gState = HAL_UART_STATE_READY;
3976
3977 /* Call user Abort complete callback */
3978 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3979 /* Call registered Abort Transmit Complete Callback */
3980 huart->AbortTransmitCpltCallback(huart);
3981 #else
3982 /* Call legacy weak Abort Transmit Complete Callback */
3983 HAL_UART_AbortTransmitCpltCallback(huart);
3984 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3985 }
3986
3987 /**
3988 * @brief DMA UART Rx communication abort callback, when initiated by user by a call to
3989 * HAL_UART_AbortReceive_IT API (Abort only Rx transfer)
3990 * (This callback is executed at end of DMA Rx Abort procedure following user abort request,
3991 * and leads to user Rx Abort Complete callback execution).
3992 * @param hdma DMA handle.
3993 * @retval None
3994 */
UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef * hdma)3995 static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
3996 {
3997 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3998
3999 huart->RxXferCount = 0U;
4000
4001 /* Clear the Error flags in the ICR register */
4002 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
4003
4004 /* Discard the received data */
4005 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4006
4007 /* Restore huart->RxState to Ready */
4008 huart->RxState = HAL_UART_STATE_READY;
4009 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
4010
4011 /* Call user Abort complete callback */
4012 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4013 /* Call registered Abort Receive Complete Callback */
4014 huart->AbortReceiveCpltCallback(huart);
4015 #else
4016 /* Call legacy weak Abort Receive Complete Callback */
4017 HAL_UART_AbortReceiveCpltCallback(huart);
4018 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4019 }
4020 #endif /* HAL_DMA_MODULE_ENABLED */
4021
4022 /**
4023 * @brief TX interrupt handler for 7 or 8 bits data word length .
4024 * @note Function is called under interruption only, once
4025 * interruptions have been enabled by HAL_UART_Transmit_IT().
4026 * @param huart UART handle.
4027 * @retval None
4028 */
UART_TxISR_8BIT(UART_HandleTypeDef * huart)4029 static void UART_TxISR_8BIT(UART_HandleTypeDef *huart)
4030 {
4031 /* Check that a Tx process is ongoing */
4032 if (huart->gState == HAL_UART_STATE_BUSY_TX)
4033 {
4034 if (huart->TxXferCount == 0U)
4035 {
4036 /* Disable the UART Transmit Data Register Empty Interrupt */
4037 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
4038
4039 /* Enable the UART Transmit Complete Interrupt */
4040 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
4041 }
4042 else
4043 {
4044 huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF);
4045 huart->pTxBuffPtr++;
4046 huart->TxXferCount--;
4047 }
4048 }
4049 }
4050
4051 /**
4052 * @brief TX interrupt handler for 9 bits data word length.
4053 * @note Function is called under interruption only, once
4054 * interruptions have been enabled by HAL_UART_Transmit_IT().
4055 * @param huart UART handle.
4056 * @retval None
4057 */
UART_TxISR_16BIT(UART_HandleTypeDef * huart)4058 static void UART_TxISR_16BIT(UART_HandleTypeDef *huart)
4059 {
4060 const uint16_t *tmp;
4061
4062 /* Check that a Tx process is ongoing */
4063 if (huart->gState == HAL_UART_STATE_BUSY_TX)
4064 {
4065 if (huart->TxXferCount == 0U)
4066 {
4067 /* Disable the UART Transmit Data Register Empty Interrupt */
4068 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
4069
4070 /* Enable the UART Transmit Complete Interrupt */
4071 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
4072 }
4073 else
4074 {
4075 tmp = (const uint16_t *) huart->pTxBuffPtr;
4076 huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL);
4077 huart->pTxBuffPtr += 2U;
4078 huart->TxXferCount--;
4079 }
4080 }
4081 }
4082
4083 /**
4084 * @brief TX interrupt handler for 7 or 8 bits data word length and FIFO mode is enabled.
4085 * @note Function is called under interruption only, once
4086 * interruptions have been enabled by HAL_UART_Transmit_IT().
4087 * @param huart UART handle.
4088 * @retval None
4089 */
UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef * huart)4090 static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart)
4091 {
4092 uint16_t nb_tx_data;
4093
4094 /* Check that a Tx process is ongoing */
4095 if (huart->gState == HAL_UART_STATE_BUSY_TX)
4096 {
4097 for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
4098 {
4099 if (huart->TxXferCount == 0U)
4100 {
4101 /* Disable the TX FIFO threshold interrupt */
4102 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
4103
4104 /* Enable the UART Transmit Complete Interrupt */
4105 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
4106
4107 break; /* force exit loop */
4108 }
4109 else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U)
4110 {
4111 huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF);
4112 huart->pTxBuffPtr++;
4113 huart->TxXferCount--;
4114 }
4115 else
4116 {
4117 /* Nothing to do */
4118 }
4119 }
4120 }
4121 }
4122
4123 /**
4124 * @brief TX interrupt handler for 9 bits data word length and FIFO mode is enabled.
4125 * @note Function is called under interruption only, once
4126 * interruptions have been enabled by HAL_UART_Transmit_IT().
4127 * @param huart UART handle.
4128 * @retval None
4129 */
UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef * huart)4130 static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart)
4131 {
4132 const uint16_t *tmp;
4133 uint16_t nb_tx_data;
4134
4135 /* Check that a Tx process is ongoing */
4136 if (huart->gState == HAL_UART_STATE_BUSY_TX)
4137 {
4138 for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
4139 {
4140 if (huart->TxXferCount == 0U)
4141 {
4142 /* Disable the TX FIFO threshold interrupt */
4143 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
4144
4145 /* Enable the UART Transmit Complete Interrupt */
4146 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
4147
4148 break; /* force exit loop */
4149 }
4150 else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U)
4151 {
4152 tmp = (const uint16_t *) huart->pTxBuffPtr;
4153 huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL);
4154 huart->pTxBuffPtr += 2U;
4155 huart->TxXferCount--;
4156 }
4157 else
4158 {
4159 /* Nothing to do */
4160 }
4161 }
4162 }
4163 }
4164
4165 /**
4166 * @brief Wrap up transmission in non-blocking mode.
4167 * @param huart pointer to a UART_HandleTypeDef structure that contains
4168 * the configuration information for the specified UART module.
4169 * @retval None
4170 */
UART_EndTransmit_IT(UART_HandleTypeDef * huart)4171 static void UART_EndTransmit_IT(UART_HandleTypeDef *huart)
4172 {
4173 /* Disable the UART Transmit Complete Interrupt */
4174 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TCIE);
4175
4176 /* Tx process is ended, restore huart->gState to Ready */
4177 huart->gState = HAL_UART_STATE_READY;
4178
4179 /* Cleat TxISR function pointer */
4180 huart->TxISR = NULL;
4181
4182 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4183 /*Call registered Tx complete callback*/
4184 huart->TxCpltCallback(huart);
4185 #else
4186 /*Call legacy weak Tx complete callback*/
4187 HAL_UART_TxCpltCallback(huart);
4188 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4189 }
4190
4191 /**
4192 * @brief RX interrupt handler for 7 or 8 bits data word length .
4193 * @param huart UART handle.
4194 * @retval None
4195 */
UART_RxISR_8BIT(UART_HandleTypeDef * huart)4196 static void UART_RxISR_8BIT(UART_HandleTypeDef *huart)
4197 {
4198 uint16_t uhMask = huart->Mask;
4199 uint16_t uhdata;
4200
4201 /* Check that a Rx process is ongoing */
4202 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
4203 {
4204 uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
4205 *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
4206 huart->pRxBuffPtr++;
4207 huart->RxXferCount--;
4208
4209 if (huart->RxXferCount == 0U)
4210 {
4211 /* Disable the UART Parity Error Interrupt and RXNE interrupts */
4212 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
4213
4214 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
4215 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
4216
4217 /* Rx process is completed, restore huart->RxState to Ready */
4218 huart->RxState = HAL_UART_STATE_READY;
4219
4220 /* Clear RxISR function pointer */
4221 huart->RxISR = NULL;
4222
4223 /* Initialize type of RxEvent to Transfer Complete */
4224 huart->RxEventType = HAL_UART_RXEVENT_TC;
4225
4226 /* Check that USART RTOEN bit is set */
4227 if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
4228 {
4229 /* Enable the UART Receiver Timeout Interrupt */
4230 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
4231 }
4232
4233 /* Check current reception Mode :
4234 If Reception till IDLE event has been selected : */
4235 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
4236 {
4237 /* Set reception type to Standard */
4238 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
4239
4240 /* Disable IDLE interrupt */
4241 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
4242
4243 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
4244 {
4245 /* Clear IDLE Flag */
4246 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
4247 }
4248
4249 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4250 /*Call registered Rx Event callback*/
4251 huart->RxEventCallback(huart, huart->RxXferSize);
4252 #else
4253 /*Call legacy weak Rx Event callback*/
4254 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
4255 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
4256 }
4257 else
4258 {
4259 /* Standard reception API called */
4260 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4261 /*Call registered Rx complete callback*/
4262 huart->RxCpltCallback(huart);
4263 #else
4264 /*Call legacy weak Rx complete callback*/
4265 HAL_UART_RxCpltCallback(huart);
4266 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4267 }
4268 }
4269 }
4270 else
4271 {
4272 /* Clear RXNE interrupt flag */
4273 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4274 }
4275 }
4276
4277 /**
4278 * @brief RX interrupt handler for 9 bits data word length .
4279 * @note Function is called under interruption only, once
4280 * interruptions have been enabled by HAL_UART_Receive_IT()
4281 * @param huart UART handle.
4282 * @retval None
4283 */
UART_RxISR_16BIT(UART_HandleTypeDef * huart)4284 static void UART_RxISR_16BIT(UART_HandleTypeDef *huart)
4285 {
4286 uint16_t *tmp;
4287 uint16_t uhMask = huart->Mask;
4288 uint16_t uhdata;
4289
4290 /* Check that a Rx process is ongoing */
4291 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
4292 {
4293 uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
4294 tmp = (uint16_t *) huart->pRxBuffPtr ;
4295 *tmp = (uint16_t)(uhdata & uhMask);
4296 huart->pRxBuffPtr += 2U;
4297 huart->RxXferCount--;
4298
4299 if (huart->RxXferCount == 0U)
4300 {
4301 /* Disable the UART Parity Error Interrupt and RXNE interrupt*/
4302 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
4303
4304 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
4305 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
4306
4307 /* Rx process is completed, restore huart->RxState to Ready */
4308 huart->RxState = HAL_UART_STATE_READY;
4309
4310 /* Clear RxISR function pointer */
4311 huart->RxISR = NULL;
4312
4313 /* Initialize type of RxEvent to Transfer Complete */
4314 huart->RxEventType = HAL_UART_RXEVENT_TC;
4315
4316 /* Check that USART RTOEN bit is set */
4317 if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
4318 {
4319 /* Enable the UART Receiver Timeout Interrupt */
4320 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
4321 }
4322
4323 /* Check current reception Mode :
4324 If Reception till IDLE event has been selected : */
4325 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
4326 {
4327 /* Set reception type to Standard */
4328 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
4329
4330 /* Disable IDLE interrupt */
4331 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
4332
4333 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
4334 {
4335 /* Clear IDLE Flag */
4336 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
4337 }
4338
4339 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4340 /*Call registered Rx Event callback*/
4341 huart->RxEventCallback(huart, huart->RxXferSize);
4342 #else
4343 /*Call legacy weak Rx Event callback*/
4344 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
4345 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
4346 }
4347 else
4348 {
4349 /* Standard reception API called */
4350 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4351 /*Call registered Rx complete callback*/
4352 huart->RxCpltCallback(huart);
4353 #else
4354 /*Call legacy weak Rx complete callback*/
4355 HAL_UART_RxCpltCallback(huart);
4356 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4357 }
4358 }
4359 }
4360 else
4361 {
4362 /* Clear RXNE interrupt flag */
4363 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4364 }
4365 }
4366
4367 /**
4368 * @brief RX interrupt handler for 7 or 8 bits data word length and FIFO mode is enabled.
4369 * @note Function is called under interruption only, once
4370 * interruptions have been enabled by HAL_UART_Receive_IT()
4371 * @param huart UART handle.
4372 * @retval None
4373 */
UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef * huart)4374 static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart)
4375 {
4376 uint16_t uhMask = huart->Mask;
4377 uint16_t uhdata;
4378 uint16_t nb_rx_data;
4379 uint16_t rxdatacount;
4380 uint32_t isrflags = READ_REG(huart->Instance->ISR);
4381 uint32_t cr1its = READ_REG(huart->Instance->CR1);
4382 uint32_t cr3its = READ_REG(huart->Instance->CR3);
4383
4384 /* Check that a Rx process is ongoing */
4385 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
4386 {
4387 nb_rx_data = huart->NbRxDataToProcess;
4388 while ((nb_rx_data > 0U) && ((isrflags & USART_ISR_RXNE_RXFNE) != 0U))
4389 {
4390 uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
4391 *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
4392 huart->pRxBuffPtr++;
4393 huart->RxXferCount--;
4394 isrflags = READ_REG(huart->Instance->ISR);
4395
4396 /* If some non blocking errors occurred */
4397 if ((isrflags & (USART_ISR_PE | USART_ISR_FE | USART_ISR_NE)) != 0U)
4398 {
4399 /* UART parity error interrupt occurred -------------------------------------*/
4400 if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
4401 {
4402 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
4403
4404 huart->ErrorCode |= HAL_UART_ERROR_PE;
4405 }
4406
4407 /* UART frame error interrupt occurred --------------------------------------*/
4408 if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
4409 {
4410 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
4411
4412 huart->ErrorCode |= HAL_UART_ERROR_FE;
4413 }
4414
4415 /* UART noise error interrupt occurred --------------------------------------*/
4416 if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
4417 {
4418 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
4419
4420 huart->ErrorCode |= HAL_UART_ERROR_NE;
4421 }
4422
4423 /* Call UART Error Call back function if need be ----------------------------*/
4424 if (huart->ErrorCode != HAL_UART_ERROR_NONE)
4425 {
4426 /* Non Blocking error : transfer could go on.
4427 Error is notified to user through user error callback */
4428 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4429 /*Call registered error callback*/
4430 huart->ErrorCallback(huart);
4431 #else
4432 /*Call legacy weak error callback*/
4433 HAL_UART_ErrorCallback(huart);
4434 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4435 huart->ErrorCode = HAL_UART_ERROR_NONE;
4436 }
4437 }
4438
4439 if (huart->RxXferCount == 0U)
4440 {
4441 /* Disable the UART Parity Error Interrupt and RXFT interrupt*/
4442 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
4443
4444 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error)
4445 and RX FIFO Threshold interrupt */
4446 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
4447
4448 /* Rx process is completed, restore huart->RxState to Ready */
4449 huart->RxState = HAL_UART_STATE_READY;
4450
4451 /* Clear RxISR function pointer */
4452 huart->RxISR = NULL;
4453
4454 /* Initialize type of RxEvent to Transfer Complete */
4455 huart->RxEventType = HAL_UART_RXEVENT_TC;
4456
4457 /* Check that USART RTOEN bit is set */
4458 if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
4459 {
4460 /* Enable the UART Receiver Timeout Interrupt */
4461 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
4462 }
4463
4464 /* Check current reception Mode :
4465 If Reception till IDLE event has been selected : */
4466 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
4467 {
4468 /* Set reception type to Standard */
4469 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
4470
4471 /* Disable IDLE interrupt */
4472 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
4473
4474 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
4475 {
4476 /* Clear IDLE Flag */
4477 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
4478 }
4479
4480 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4481 /*Call registered Rx Event callback*/
4482 huart->RxEventCallback(huart, huart->RxXferSize);
4483 #else
4484 /*Call legacy weak Rx Event callback*/
4485 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
4486 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
4487 }
4488 else
4489 {
4490 /* Standard reception API called */
4491 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4492 /*Call registered Rx complete callback*/
4493 huart->RxCpltCallback(huart);
4494 #else
4495 /*Call legacy weak Rx complete callback*/
4496 HAL_UART_RxCpltCallback(huart);
4497 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4498 }
4499 }
4500 }
4501
4502 /* When remaining number of bytes to receive is less than the RX FIFO
4503 threshold, next incoming frames are processed as if FIFO mode was
4504 disabled (i.e. one interrupt per received frame).
4505 */
4506 rxdatacount = huart->RxXferCount;
4507 if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess))
4508 {
4509 /* Disable the UART RXFT interrupt*/
4510 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
4511
4512 /* Update the RxISR function pointer */
4513 huart->RxISR = UART_RxISR_8BIT;
4514
4515 /* Enable the UART Data Register Not Empty interrupt */
4516 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
4517 }
4518 }
4519 else
4520 {
4521 /* Clear RXNE interrupt flag */
4522 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4523 }
4524 }
4525
4526 /**
4527 * @brief RX interrupt handler for 9 bits data word length and FIFO mode is enabled.
4528 * @note Function is called under interruption only, once
4529 * interruptions have been enabled by HAL_UART_Receive_IT()
4530 * @param huart UART handle.
4531 * @retval None
4532 */
UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef * huart)4533 static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart)
4534 {
4535 uint16_t *tmp;
4536 uint16_t uhMask = huart->Mask;
4537 uint16_t uhdata;
4538 uint16_t nb_rx_data;
4539 uint16_t rxdatacount;
4540 uint32_t isrflags = READ_REG(huart->Instance->ISR);
4541 uint32_t cr1its = READ_REG(huart->Instance->CR1);
4542 uint32_t cr3its = READ_REG(huart->Instance->CR3);
4543
4544 /* Check that a Rx process is ongoing */
4545 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
4546 {
4547 nb_rx_data = huart->NbRxDataToProcess;
4548 while ((nb_rx_data > 0U) && ((isrflags & USART_ISR_RXNE_RXFNE) != 0U))
4549 {
4550 uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
4551 tmp = (uint16_t *) huart->pRxBuffPtr ;
4552 *tmp = (uint16_t)(uhdata & uhMask);
4553 huart->pRxBuffPtr += 2U;
4554 huart->RxXferCount--;
4555 isrflags = READ_REG(huart->Instance->ISR);
4556
4557 /* If some non blocking errors occurred */
4558 if ((isrflags & (USART_ISR_PE | USART_ISR_FE | USART_ISR_NE)) != 0U)
4559 {
4560 /* UART parity error interrupt occurred -------------------------------------*/
4561 if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
4562 {
4563 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
4564
4565 huart->ErrorCode |= HAL_UART_ERROR_PE;
4566 }
4567
4568 /* UART frame error interrupt occurred --------------------------------------*/
4569 if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
4570 {
4571 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
4572
4573 huart->ErrorCode |= HAL_UART_ERROR_FE;
4574 }
4575
4576 /* UART noise error interrupt occurred --------------------------------------*/
4577 if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
4578 {
4579 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
4580
4581 huart->ErrorCode |= HAL_UART_ERROR_NE;
4582 }
4583
4584 /* Call UART Error Call back function if need be ----------------------------*/
4585 if (huart->ErrorCode != HAL_UART_ERROR_NONE)
4586 {
4587 /* Non Blocking error : transfer could go on.
4588 Error is notified to user through user error callback */
4589 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4590 /*Call registered error callback*/
4591 huart->ErrorCallback(huart);
4592 #else
4593 /*Call legacy weak error callback*/
4594 HAL_UART_ErrorCallback(huart);
4595 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4596 huart->ErrorCode = HAL_UART_ERROR_NONE;
4597 }
4598 }
4599
4600 if (huart->RxXferCount == 0U)
4601 {
4602 /* Disable the UART Parity Error Interrupt and RXFT interrupt*/
4603 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
4604
4605 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error)
4606 and RX FIFO Threshold interrupt */
4607 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
4608
4609 /* Rx process is completed, restore huart->RxState to Ready */
4610 huart->RxState = HAL_UART_STATE_READY;
4611
4612 /* Clear RxISR function pointer */
4613 huart->RxISR = NULL;
4614
4615 /* Initialize type of RxEvent to Transfer Complete */
4616 huart->RxEventType = HAL_UART_RXEVENT_TC;
4617
4618 /* Check that USART RTOEN bit is set */
4619 if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
4620 {
4621 /* Enable the UART Receiver Timeout Interrupt */
4622 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
4623 }
4624
4625 /* Check current reception Mode :
4626 If Reception till IDLE event has been selected : */
4627 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
4628 {
4629 /* Set reception type to Standard */
4630 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
4631
4632 /* Disable IDLE interrupt */
4633 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
4634
4635 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
4636 {
4637 /* Clear IDLE Flag */
4638 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
4639 }
4640
4641 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4642 /*Call registered Rx Event callback*/
4643 huart->RxEventCallback(huart, huart->RxXferSize);
4644 #else
4645 /*Call legacy weak Rx Event callback*/
4646 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
4647 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
4648 }
4649 else
4650 {
4651 /* Standard reception API called */
4652 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4653 /*Call registered Rx complete callback*/
4654 huart->RxCpltCallback(huart);
4655 #else
4656 /*Call legacy weak Rx complete callback*/
4657 HAL_UART_RxCpltCallback(huart);
4658 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4659 }
4660 }
4661 }
4662
4663 /* When remaining number of bytes to receive is less than the RX FIFO
4664 threshold, next incoming frames are processed as if FIFO mode was
4665 disabled (i.e. one interrupt per received frame).
4666 */
4667 rxdatacount = huart->RxXferCount;
4668 if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess))
4669 {
4670 /* Disable the UART RXFT interrupt*/
4671 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
4672
4673 /* Update the RxISR function pointer */
4674 huart->RxISR = UART_RxISR_16BIT;
4675
4676 /* Enable the UART Data Register Not Empty interrupt */
4677 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
4678 }
4679 }
4680 else
4681 {
4682 /* Clear RXNE interrupt flag */
4683 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4684 }
4685 }
4686
4687 /**
4688 * @}
4689 */
4690
4691 #endif /* HAL_UART_MODULE_ENABLED */
4692 /**
4693 * @}
4694 */
4695
4696 /**
4697 * @}
4698 */
4699
4700