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