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