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