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