1 /**
2 ******************************************************************************
3 * @file stm32g0xx_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) 2018 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 "stm32g0xx_hal.h"
163
164 /** @addtogroup STM32G0xx_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 (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
1082 Errors are handled as follows :
1083 (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
1084 to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error
1085 in Interrupt mode reception .
1086 Received character is then retrieved and stored in Rx buffer, Error code is set to allow user
1087 to identify error type, and HAL_UART_ErrorCallback() user callback is executed.
1088 Transfer is kept ongoing on UART side.
1089 If user wants to abort it, Abort services should be called by user.
1090 (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
1091 This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
1092 Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback()
1093 user callback is executed.
1094
1095 -@- In the Half duplex communication, it is forbidden to run the transmit
1096 and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful.
1097
1098 @endverbatim
1099 * @{
1100 */
1101
1102 /**
1103 * @brief Send an amount of data in blocking mode.
1104 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1105 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1106 * of u16 provided through pData.
1107 * @note When FIFO mode is enabled, writing a data in the TDR register adds one
1108 * data to the TXFIFO. Write operations to the TDR register are performed
1109 * when TXFNF flag is set. From hardware perspective, TXFNF flag and
1110 * TXE are mapped on the same bit-field.
1111 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1112 * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits)
1113 * (as sent data will be handled using u16 pointer cast). Depending on compilation chain,
1114 * use of specific alignment compilation directives or pragmas might be required
1115 * to ensure proper alignment for pData.
1116 * @param huart UART handle.
1117 * @param pData Pointer to data buffer (u8 or u16 data elements).
1118 * @param Size Amount of data elements (u8 or u16) to be sent.
1119 * @param Timeout Timeout duration.
1120 * @retval HAL status
1121 */
HAL_UART_Transmit(UART_HandleTypeDef * huart,const uint8_t * pData,uint16_t Size,uint32_t Timeout)1122 HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
1123 {
1124 const uint8_t *pdata8bits;
1125 const uint16_t *pdata16bits;
1126 uint32_t tickstart;
1127
1128 /* Check that a Tx process is not already ongoing */
1129 if (huart->gState == HAL_UART_STATE_READY)
1130 {
1131 if ((pData == NULL) || (Size == 0U))
1132 {
1133 return HAL_ERROR;
1134 }
1135
1136 /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1137 should be aligned on a u16 frontier, as data to be filled into TDR will be
1138 handled through a u16 cast. */
1139 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1140 {
1141 if ((((uint32_t)pData) & 1U) != 0U)
1142 {
1143 return HAL_ERROR;
1144 }
1145 }
1146
1147 huart->ErrorCode = HAL_UART_ERROR_NONE;
1148 huart->gState = HAL_UART_STATE_BUSY_TX;
1149
1150 /* Init tickstart for timeout management */
1151 tickstart = HAL_GetTick();
1152
1153 huart->TxXferSize = Size;
1154 huart->TxXferCount = Size;
1155
1156 /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
1157 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1158 {
1159 pdata8bits = NULL;
1160 pdata16bits = (const uint16_t *) pData;
1161 }
1162 else
1163 {
1164 pdata8bits = pData;
1165 pdata16bits = NULL;
1166 }
1167
1168 while (huart->TxXferCount > 0U)
1169 {
1170 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
1171 {
1172
1173 huart->gState = HAL_UART_STATE_READY;
1174
1175 return HAL_TIMEOUT;
1176 }
1177 if (pdata8bits == NULL)
1178 {
1179 huart->Instance->TDR = (uint16_t)(*pdata16bits & 0x01FFU);
1180 pdata16bits++;
1181 }
1182 else
1183 {
1184 huart->Instance->TDR = (uint8_t)(*pdata8bits & 0xFFU);
1185 pdata8bits++;
1186 }
1187 huart->TxXferCount--;
1188 }
1189
1190 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
1191 {
1192 huart->gState = HAL_UART_STATE_READY;
1193
1194 return HAL_TIMEOUT;
1195 }
1196
1197 /* At end of Tx process, restore huart->gState to Ready */
1198 huart->gState = HAL_UART_STATE_READY;
1199
1200 return HAL_OK;
1201 }
1202 else
1203 {
1204 return HAL_BUSY;
1205 }
1206 }
1207
1208 /**
1209 * @brief Receive an amount of data in blocking mode.
1210 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1211 * the received data is handled as a set of u16. In this case, Size must indicate the number
1212 * of u16 available through pData.
1213 * @note When FIFO mode is enabled, the RXFNE flag is set as long as the RXFIFO
1214 * is not empty. Read operations from the RDR register are performed when
1215 * RXFNE flag is set. From hardware perspective, RXFNE flag and
1216 * RXNE are mapped on the same bit-field.
1217 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1218 * address of user data buffer for storing data to be received, should be aligned on a half word frontier
1219 * (16 bits) (as received data will be handled using u16 pointer cast). Depending on compilation chain,
1220 * use of specific alignment compilation directives or pragmas might be required
1221 * to ensure proper alignment for pData.
1222 * @param huart UART handle.
1223 * @param pData Pointer to data buffer (u8 or u16 data elements).
1224 * @param Size Amount of data elements (u8 or u16) to be received.
1225 * @param Timeout Timeout duration.
1226 * @retval HAL status
1227 */
HAL_UART_Receive(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size,uint32_t Timeout)1228 HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
1229 {
1230 uint8_t *pdata8bits;
1231 uint16_t *pdata16bits;
1232 uint16_t uhMask;
1233 uint32_t tickstart;
1234
1235 /* Check that a Rx process is not already ongoing */
1236 if (huart->RxState == HAL_UART_STATE_READY)
1237 {
1238 if ((pData == NULL) || (Size == 0U))
1239 {
1240 return HAL_ERROR;
1241 }
1242
1243 /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1244 should be aligned on a u16 frontier, as data to be received from RDR will be
1245 handled through a u16 cast. */
1246 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1247 {
1248 if ((((uint32_t)pData) & 1U) != 0U)
1249 {
1250 return HAL_ERROR;
1251 }
1252 }
1253
1254 huart->ErrorCode = HAL_UART_ERROR_NONE;
1255 huart->RxState = HAL_UART_STATE_BUSY_RX;
1256 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
1257
1258 /* Init tickstart for timeout management */
1259 tickstart = HAL_GetTick();
1260
1261 huart->RxXferSize = Size;
1262 huart->RxXferCount = Size;
1263
1264 /* Computation of UART mask to apply to RDR register */
1265 UART_MASK_COMPUTATION(huart);
1266 uhMask = huart->Mask;
1267
1268 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
1269 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1270 {
1271 pdata8bits = NULL;
1272 pdata16bits = (uint16_t *) pData;
1273 }
1274 else
1275 {
1276 pdata8bits = pData;
1277 pdata16bits = NULL;
1278 }
1279
1280 /* as long as data have to be received */
1281 while (huart->RxXferCount > 0U)
1282 {
1283 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
1284 {
1285 huart->RxState = HAL_UART_STATE_READY;
1286
1287 return HAL_TIMEOUT;
1288 }
1289 if (pdata8bits == NULL)
1290 {
1291 *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask);
1292 pdata16bits++;
1293 }
1294 else
1295 {
1296 *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
1297 pdata8bits++;
1298 }
1299 huart->RxXferCount--;
1300 }
1301
1302 /* At end of Rx process, restore huart->RxState to Ready */
1303 huart->RxState = HAL_UART_STATE_READY;
1304
1305 return HAL_OK;
1306 }
1307 else
1308 {
1309 return HAL_BUSY;
1310 }
1311 }
1312
1313 /**
1314 * @brief Send an amount of data in interrupt mode.
1315 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1316 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1317 * of u16 provided through pData.
1318 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1319 * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits)
1320 * (as sent data will be handled using u16 pointer cast). Depending on compilation chain,
1321 * use of specific alignment compilation directives or pragmas might be required
1322 * to ensure proper alignment for pData.
1323 * @param huart UART handle.
1324 * @param pData Pointer to data buffer (u8 or u16 data elements).
1325 * @param Size Amount of data elements (u8 or u16) to be sent.
1326 * @retval HAL status
1327 */
HAL_UART_Transmit_IT(UART_HandleTypeDef * huart,const uint8_t * pData,uint16_t Size)1328 HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
1329 {
1330 /* Check that a Tx process is not already ongoing */
1331 if (huart->gState == HAL_UART_STATE_READY)
1332 {
1333 if ((pData == NULL) || (Size == 0U))
1334 {
1335 return HAL_ERROR;
1336 }
1337
1338 /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1339 should be aligned on a u16 frontier, as data to be filled into TDR will be
1340 handled through a u16 cast. */
1341 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1342 {
1343 if ((((uint32_t)pData) & 1U) != 0U)
1344 {
1345 return HAL_ERROR;
1346 }
1347 }
1348
1349 huart->pTxBuffPtr = pData;
1350 huart->TxXferSize = Size;
1351 huart->TxXferCount = Size;
1352 huart->TxISR = NULL;
1353
1354 huart->ErrorCode = HAL_UART_ERROR_NONE;
1355 huart->gState = HAL_UART_STATE_BUSY_TX;
1356
1357 /* Configure Tx interrupt processing */
1358 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1359 {
1360 /* Set the Tx ISR function pointer according to the data word length */
1361 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1362 {
1363 huart->TxISR = UART_TxISR_16BIT_FIFOEN;
1364 }
1365 else
1366 {
1367 huart->TxISR = UART_TxISR_8BIT_FIFOEN;
1368 }
1369
1370 /* Enable the TX FIFO threshold interrupt */
1371 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
1372 }
1373 else
1374 {
1375 /* Set the Tx ISR function pointer according to the data word length */
1376 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1377 {
1378 huart->TxISR = UART_TxISR_16BIT;
1379 }
1380 else
1381 {
1382 huart->TxISR = UART_TxISR_8BIT;
1383 }
1384
1385 /* Enable the Transmit Data Register Empty interrupt */
1386 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
1387 }
1388
1389 return HAL_OK;
1390 }
1391 else
1392 {
1393 return HAL_BUSY;
1394 }
1395 }
1396
1397 /**
1398 * @brief Receive an amount of data in interrupt mode.
1399 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1400 * the received data is handled as a set of u16. In this case, Size must indicate the number
1401 * of u16 available through pData.
1402 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1403 * address of user data buffer for storing data to be received, should be aligned on a half word frontier
1404 * (16 bits) (as received data will be handled using u16 pointer cast). Depending on compilation chain,
1405 * use of specific alignment compilation directives or pragmas might be required
1406 * to ensure proper alignment for pData.
1407 * @param huart UART handle.
1408 * @param pData Pointer to data buffer (u8 or u16 data elements).
1409 * @param Size Amount of data elements (u8 or u16) to be received.
1410 * @retval HAL status
1411 */
HAL_UART_Receive_IT(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)1412 HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1413 {
1414 /* Check that a Rx process is not already ongoing */
1415 if (huart->RxState == HAL_UART_STATE_READY)
1416 {
1417 if ((pData == NULL) || (Size == 0U))
1418 {
1419 return HAL_ERROR;
1420 }
1421
1422 /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1423 should be aligned on a u16 frontier, as data to be received from RDR will be
1424 handled through a u16 cast. */
1425 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1426 {
1427 if ((((uint32_t)pData) & 1U) != 0U)
1428 {
1429 return HAL_ERROR;
1430 }
1431 }
1432
1433 /* Set Reception type to Standard reception */
1434 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
1435
1436 if (!(IS_LPUART_INSTANCE(huart->Instance)))
1437 {
1438 /* Check that USART RTOEN bit is set */
1439 if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
1440 {
1441 /* Enable the UART Receiver Timeout Interrupt */
1442 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
1443 }
1444 }
1445
1446 return (UART_Start_Receive_IT(huart, pData, Size));
1447 }
1448 else
1449 {
1450 return HAL_BUSY;
1451 }
1452 }
1453
1454 /**
1455 * @brief Send an amount of data in DMA mode.
1456 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1457 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1458 * of u16 provided through pData.
1459 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1460 * address of user data buffer containing data to be sent, should be aligned on a half word frontier (16 bits)
1461 * (as sent data will be handled by DMA from halfword frontier). Depending on compilation chain,
1462 * use of specific alignment compilation directives or pragmas might be required
1463 * to ensure proper alignment for pData.
1464 * @param huart UART handle.
1465 * @param pData Pointer to data buffer (u8 or u16 data elements).
1466 * @param Size Amount of data elements (u8 or u16) to be sent.
1467 * @retval HAL status
1468 */
HAL_UART_Transmit_DMA(UART_HandleTypeDef * huart,const uint8_t * pData,uint16_t Size)1469 HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
1470 {
1471 /* Check that a Tx process is not already ongoing */
1472 if (huart->gState == HAL_UART_STATE_READY)
1473 {
1474 if ((pData == NULL) || (Size == 0U))
1475 {
1476 return HAL_ERROR;
1477 }
1478
1479 /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1480 should be aligned on a u16 frontier, as data copy into TDR will be
1481 handled by DMA from a u16 frontier. */
1482 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1483 {
1484 if ((((uint32_t)pData) & 1U) != 0U)
1485 {
1486 return HAL_ERROR;
1487 }
1488 }
1489
1490 huart->pTxBuffPtr = pData;
1491 huart->TxXferSize = Size;
1492 huart->TxXferCount = Size;
1493
1494 huart->ErrorCode = HAL_UART_ERROR_NONE;
1495 huart->gState = HAL_UART_STATE_BUSY_TX;
1496
1497 if (huart->hdmatx != NULL)
1498 {
1499 /* Set the UART DMA transfer complete callback */
1500 huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
1501
1502 /* Set the UART DMA Half transfer complete callback */
1503 huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
1504
1505 /* Set the DMA error callback */
1506 huart->hdmatx->XferErrorCallback = UART_DMAError;
1507
1508 /* Set the DMA abort callback */
1509 huart->hdmatx->XferAbortCallback = NULL;
1510
1511 /* Enable the UART transmit DMA channel */
1512 if (HAL_DMA_Start_IT(huart->hdmatx, (uint32_t)huart->pTxBuffPtr, (uint32_t)&huart->Instance->TDR, Size) != HAL_OK)
1513 {
1514 /* Set error code to DMA */
1515 huart->ErrorCode = HAL_UART_ERROR_DMA;
1516
1517 /* Restore huart->gState to ready */
1518 huart->gState = HAL_UART_STATE_READY;
1519
1520 return HAL_ERROR;
1521 }
1522 }
1523 /* Clear the TC flag in the ICR register */
1524 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF);
1525
1526 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1527 in the UART CR3 register */
1528 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1529
1530 return HAL_OK;
1531 }
1532 else
1533 {
1534 return HAL_BUSY;
1535 }
1536 }
1537
1538 /**
1539 * @brief Receive an amount of data in DMA mode.
1540 * @note When the UART parity is enabled (PCE = 1), the received data contain
1541 * the parity bit (MSB position).
1542 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1543 * the received data is handled as a set of u16. In this case, Size must indicate the number
1544 * of u16 available through pData.
1545 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1546 * address of user data buffer for storing data to be received, should be aligned on a half word frontier
1547 * (16 bits) (as received data will be handled by DMA from halfword frontier). Depending on compilation chain,
1548 * use of specific alignment compilation directives or pragmas might be required
1549 * to ensure proper alignment for pData.
1550 * @param huart UART handle.
1551 * @param pData Pointer to data buffer (u8 or u16 data elements).
1552 * @param Size Amount of data elements (u8 or u16) to be received.
1553 * @retval HAL status
1554 */
HAL_UART_Receive_DMA(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)1555 HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1556 {
1557 /* Check that a Rx process is not already ongoing */
1558 if (huart->RxState == HAL_UART_STATE_READY)
1559 {
1560 if ((pData == NULL) || (Size == 0U))
1561 {
1562 return HAL_ERROR;
1563 }
1564
1565 /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
1566 should be aligned on a u16 frontier, as data copy from RDR will be
1567 handled by DMA from a u16 frontier. */
1568 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1569 {
1570 if ((((uint32_t)pData) & 1U) != 0U)
1571 {
1572 return HAL_ERROR;
1573 }
1574 }
1575
1576 /* Set Reception type to Standard reception */
1577 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
1578
1579 if (!(IS_LPUART_INSTANCE(huart->Instance)))
1580 {
1581 /* Check that USART RTOEN bit is set */
1582 if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
1583 {
1584 /* Enable the UART Receiver Timeout Interrupt */
1585 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
1586 }
1587 }
1588
1589 return (UART_Start_Receive_DMA(huart, pData, Size));
1590 }
1591 else
1592 {
1593 return HAL_BUSY;
1594 }
1595 }
1596
1597 /**
1598 * @brief Pause the DMA Transfer.
1599 * @param huart UART handle.
1600 * @retval HAL status
1601 */
HAL_UART_DMAPause(UART_HandleTypeDef * huart)1602 HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
1603 {
1604 const HAL_UART_StateTypeDef gstate = huart->gState;
1605 const HAL_UART_StateTypeDef rxstate = huart->RxState;
1606
1607 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
1608 (gstate == HAL_UART_STATE_BUSY_TX))
1609 {
1610 /* Disable the UART DMA Tx request */
1611 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1612 }
1613 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
1614 (rxstate == HAL_UART_STATE_BUSY_RX))
1615 {
1616 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
1617 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1618 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
1619
1620 /* Disable the UART DMA Rx request */
1621 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1622 }
1623
1624 return HAL_OK;
1625 }
1626
1627 /**
1628 * @brief Resume the DMA Transfer.
1629 * @param huart UART handle.
1630 * @retval HAL status
1631 */
HAL_UART_DMAResume(UART_HandleTypeDef * huart)1632 HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
1633 {
1634 if (huart->gState == HAL_UART_STATE_BUSY_TX)
1635 {
1636 /* Enable the UART DMA Tx request */
1637 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1638 }
1639 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
1640 {
1641 /* Clear the Overrun flag before resuming the Rx transfer */
1642 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
1643
1644 /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */
1645 if (huart->Init.Parity != UART_PARITY_NONE)
1646 {
1647 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1648 }
1649 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
1650
1651 /* Enable the UART DMA Rx request */
1652 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1653 }
1654
1655 return HAL_OK;
1656 }
1657
1658 /**
1659 * @brief Stop the DMA Transfer.
1660 * @param huart UART handle.
1661 * @retval HAL status
1662 */
HAL_UART_DMAStop(UART_HandleTypeDef * huart)1663 HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
1664 {
1665 /* The Lock is not implemented on this API to allow the user application
1666 to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() /
1667 HAL_UART_TxHalfCpltCallback / HAL_UART_RxHalfCpltCallback:
1668 indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
1669 interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
1670 the stream and the corresponding call back is executed. */
1671
1672 const HAL_UART_StateTypeDef gstate = huart->gState;
1673 const HAL_UART_StateTypeDef rxstate = huart->RxState;
1674
1675 /* Stop UART DMA Tx request if ongoing */
1676 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
1677 (gstate == HAL_UART_STATE_BUSY_TX))
1678 {
1679 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1680
1681 /* Abort the UART DMA Tx channel */
1682 if (huart->hdmatx != NULL)
1683 {
1684 if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
1685 {
1686 if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1687 {
1688 /* Set error code to DMA */
1689 huart->ErrorCode = HAL_UART_ERROR_DMA;
1690
1691 return HAL_TIMEOUT;
1692 }
1693 }
1694 }
1695
1696 UART_EndTxTransfer(huart);
1697 }
1698
1699 /* Stop UART DMA Rx request if ongoing */
1700 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
1701 (rxstate == HAL_UART_STATE_BUSY_RX))
1702 {
1703 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1704
1705 /* Abort the UART DMA Rx channel */
1706 if (huart->hdmarx != NULL)
1707 {
1708 if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
1709 {
1710 if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1711 {
1712 /* Set error code to DMA */
1713 huart->ErrorCode = HAL_UART_ERROR_DMA;
1714
1715 return HAL_TIMEOUT;
1716 }
1717 }
1718 }
1719
1720 UART_EndRxTransfer(huart);
1721 }
1722
1723 return HAL_OK;
1724 }
1725
1726 /**
1727 * @brief Abort ongoing transfers (blocking mode).
1728 * @param huart UART handle.
1729 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1730 * This procedure performs following operations :
1731 * - Disable UART Interrupts (Tx and Rx)
1732 * - Disable the DMA transfer in the peripheral register (if enabled)
1733 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1734 * - Set handle State to READY
1735 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1736 * @retval HAL status
1737 */
HAL_UART_Abort(UART_HandleTypeDef * huart)1738 HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart)
1739 {
1740 /* Disable TXE, TC, RXNE, PE, RXFT, TXFT and ERR (Frame error, noise error, overrun error) interrupts */
1741 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE |
1742 USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
1743 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE);
1744
1745 /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
1746 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
1747 {
1748 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
1749 }
1750
1751 /* Abort the UART DMA Tx channel if enabled */
1752 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1753 {
1754 /* Disable the UART DMA Tx request if enabled */
1755 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1756
1757 /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
1758 if (huart->hdmatx != NULL)
1759 {
1760 /* Set the UART DMA Abort callback to Null.
1761 No call back execution at end of DMA abort procedure */
1762 huart->hdmatx->XferAbortCallback = NULL;
1763
1764 if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
1765 {
1766 if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1767 {
1768 /* Set error code to DMA */
1769 huart->ErrorCode = HAL_UART_ERROR_DMA;
1770
1771 return HAL_TIMEOUT;
1772 }
1773 }
1774 }
1775 }
1776
1777 /* Abort the UART DMA Rx channel if enabled */
1778 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1779 {
1780 /* Disable the UART DMA Rx request if enabled */
1781 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1782
1783 /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
1784 if (huart->hdmarx != NULL)
1785 {
1786 /* Set the UART DMA Abort callback to Null.
1787 No call back execution at end of DMA abort procedure */
1788 huart->hdmarx->XferAbortCallback = NULL;
1789
1790 if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
1791 {
1792 if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1793 {
1794 /* Set error code to DMA */
1795 huart->ErrorCode = HAL_UART_ERROR_DMA;
1796
1797 return HAL_TIMEOUT;
1798 }
1799 }
1800 }
1801 }
1802
1803 /* Reset Tx and Rx transfer counters */
1804 huart->TxXferCount = 0U;
1805 huart->RxXferCount = 0U;
1806
1807 /* Clear the Error flags in the ICR register */
1808 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
1809
1810 /* Flush the whole TX FIFO (if needed) */
1811 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1812 {
1813 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
1814 }
1815
1816 /* Discard the received data */
1817 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
1818
1819 /* Restore huart->gState and huart->RxState to Ready */
1820 huart->gState = HAL_UART_STATE_READY;
1821 huart->RxState = HAL_UART_STATE_READY;
1822 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
1823
1824 huart->ErrorCode = HAL_UART_ERROR_NONE;
1825
1826 return HAL_OK;
1827 }
1828
1829 /**
1830 * @brief Abort ongoing Transmit transfer (blocking mode).
1831 * @param huart UART handle.
1832 * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
1833 * This procedure performs following operations :
1834 * - Disable UART Interrupts (Tx)
1835 * - Disable the DMA transfer in the peripheral register (if enabled)
1836 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1837 * - Set handle State to READY
1838 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1839 * @retval HAL status
1840 */
HAL_UART_AbortTransmit(UART_HandleTypeDef * huart)1841 HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart)
1842 {
1843 /* Disable TCIE, TXEIE and TXFTIE interrupts */
1844 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE));
1845 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
1846
1847 /* Abort the UART DMA Tx channel if enabled */
1848 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1849 {
1850 /* Disable the UART DMA Tx request if enabled */
1851 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1852
1853 /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
1854 if (huart->hdmatx != NULL)
1855 {
1856 /* Set the UART DMA Abort callback to Null.
1857 No call back execution at end of DMA abort procedure */
1858 huart->hdmatx->XferAbortCallback = NULL;
1859
1860 if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
1861 {
1862 if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
1863 {
1864 /* Set error code to DMA */
1865 huart->ErrorCode = HAL_UART_ERROR_DMA;
1866
1867 return HAL_TIMEOUT;
1868 }
1869 }
1870 }
1871 }
1872
1873 /* Reset Tx transfer counter */
1874 huart->TxXferCount = 0U;
1875
1876 /* Flush the whole TX FIFO (if needed) */
1877 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1878 {
1879 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
1880 }
1881
1882 /* Restore huart->gState to Ready */
1883 huart->gState = HAL_UART_STATE_READY;
1884
1885 return HAL_OK;
1886 }
1887
1888 /**
1889 * @brief Abort ongoing Receive transfer (blocking mode).
1890 * @param huart UART handle.
1891 * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
1892 * This procedure performs following operations :
1893 * - Disable UART Interrupts (Rx)
1894 * - Disable the DMA transfer in the peripheral register (if enabled)
1895 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1896 * - Set handle State to READY
1897 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1898 * @retval HAL status
1899 */
HAL_UART_AbortReceive(UART_HandleTypeDef * huart)1900 HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart)
1901 {
1902 /* Disable PEIE, EIE, RXNEIE and RXFTIE interrupts */
1903 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE));
1904 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE);
1905
1906 /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
1907 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
1908 {
1909 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
1910 }
1911
1912 /* Abort the UART DMA Rx channel if enabled */
1913 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1914 {
1915 /* Disable the UART DMA Rx request if enabled */
1916 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1917
1918 /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
1919 if (huart->hdmarx != NULL)
1920 {
1921 /* Set the UART DMA Abort callback to Null.
1922 No call back execution at end of DMA abort procedure */
1923 huart->hdmarx->XferAbortCallback = NULL;
1924
1925 if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
1926 {
1927 if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
1928 {
1929 /* Set error code to DMA */
1930 huart->ErrorCode = HAL_UART_ERROR_DMA;
1931
1932 return HAL_TIMEOUT;
1933 }
1934 }
1935 }
1936 }
1937
1938 /* Reset Rx transfer counter */
1939 huart->RxXferCount = 0U;
1940
1941 /* Clear the Error flags in the ICR register */
1942 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
1943
1944 /* Discard the received data */
1945 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
1946
1947 /* Restore huart->RxState to Ready */
1948 huart->RxState = HAL_UART_STATE_READY;
1949 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
1950
1951 return HAL_OK;
1952 }
1953
1954 /**
1955 * @brief Abort ongoing transfers (Interrupt mode).
1956 * @param huart UART handle.
1957 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1958 * This procedure performs following operations :
1959 * - Disable UART Interrupts (Tx and Rx)
1960 * - Disable the DMA transfer in the peripheral register (if enabled)
1961 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1962 * - Set handle State to READY
1963 * - At abort completion, call user abort complete callback
1964 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
1965 * considered as completed only when user abort complete callback is executed (not when exiting function).
1966 * @retval HAL status
1967 */
HAL_UART_Abort_IT(UART_HandleTypeDef * huart)1968 HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart)
1969 {
1970 uint32_t abortcplt = 1U;
1971
1972 /* Disable interrupts */
1973 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_TCIE | USART_CR1_RXNEIE_RXFNEIE |
1974 USART_CR1_TXEIE_TXFNFIE));
1975 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
1976
1977 /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
1978 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
1979 {
1980 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
1981 }
1982
1983 /* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised
1984 before any call to DMA Abort functions */
1985 /* DMA Tx Handle is valid */
1986 if (huart->hdmatx != NULL)
1987 {
1988 /* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
1989 Otherwise, set it to NULL */
1990 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1991 {
1992 huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback;
1993 }
1994 else
1995 {
1996 huart->hdmatx->XferAbortCallback = NULL;
1997 }
1998 }
1999 /* DMA Rx Handle is valid */
2000 if (huart->hdmarx != NULL)
2001 {
2002 /* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
2003 Otherwise, set it to NULL */
2004 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2005 {
2006 huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback;
2007 }
2008 else
2009 {
2010 huart->hdmarx->XferAbortCallback = NULL;
2011 }
2012 }
2013
2014 /* Abort the UART DMA Tx channel if enabled */
2015 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
2016 {
2017 /* Disable DMA Tx at UART level */
2018 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
2019
2020 /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
2021 if (huart->hdmatx != NULL)
2022 {
2023 /* UART Tx DMA Abort callback has already been initialised :
2024 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2025
2026 /* Abort DMA TX */
2027 if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
2028 {
2029 huart->hdmatx->XferAbortCallback = NULL;
2030 }
2031 else
2032 {
2033 abortcplt = 0U;
2034 }
2035 }
2036 }
2037
2038 /* Abort the UART DMA Rx channel if enabled */
2039 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2040 {
2041 /* Disable the UART DMA Rx request if enabled */
2042 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2043
2044 /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
2045 if (huart->hdmarx != NULL)
2046 {
2047 /* UART Rx DMA Abort callback has already been initialised :
2048 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2049
2050 /* Abort DMA RX */
2051 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
2052 {
2053 huart->hdmarx->XferAbortCallback = NULL;
2054 abortcplt = 1U;
2055 }
2056 else
2057 {
2058 abortcplt = 0U;
2059 }
2060 }
2061 }
2062
2063 /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
2064 if (abortcplt == 1U)
2065 {
2066 /* Reset Tx and Rx transfer counters */
2067 huart->TxXferCount = 0U;
2068 huart->RxXferCount = 0U;
2069
2070 /* Clear ISR function pointers */
2071 huart->RxISR = NULL;
2072 huart->TxISR = NULL;
2073
2074 /* Reset errorCode */
2075 huart->ErrorCode = HAL_UART_ERROR_NONE;
2076
2077 /* Clear the Error flags in the ICR register */
2078 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
2079
2080 /* Flush the whole TX FIFO (if needed) */
2081 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
2082 {
2083 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
2084 }
2085
2086 /* Discard the received data */
2087 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
2088
2089 /* Restore huart->gState and huart->RxState to Ready */
2090 huart->gState = HAL_UART_STATE_READY;
2091 huart->RxState = HAL_UART_STATE_READY;
2092 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2093
2094 /* As no DMA to be aborted, call directly user Abort complete callback */
2095 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2096 /* Call registered Abort complete callback */
2097 huart->AbortCpltCallback(huart);
2098 #else
2099 /* Call legacy weak Abort complete callback */
2100 HAL_UART_AbortCpltCallback(huart);
2101 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2102 }
2103
2104 return HAL_OK;
2105 }
2106
2107 /**
2108 * @brief Abort ongoing Transmit transfer (Interrupt mode).
2109 * @param huart UART handle.
2110 * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
2111 * This procedure performs following operations :
2112 * - Disable UART Interrupts (Tx)
2113 * - Disable the DMA transfer in the peripheral register (if enabled)
2114 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
2115 * - Set handle State to READY
2116 * - At abort completion, call user abort complete callback
2117 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
2118 * considered as completed only when user abort complete callback is executed (not when exiting function).
2119 * @retval HAL status
2120 */
HAL_UART_AbortTransmit_IT(UART_HandleTypeDef * huart)2121 HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart)
2122 {
2123 /* Disable interrupts */
2124 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE));
2125 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
2126
2127 /* Abort the UART DMA Tx channel if enabled */
2128 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
2129 {
2130 /* Disable the UART DMA Tx request if enabled */
2131 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
2132
2133 /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
2134 if (huart->hdmatx != NULL)
2135 {
2136 /* Set the UART DMA Abort callback :
2137 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2138 huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback;
2139
2140 /* Abort DMA TX */
2141 if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
2142 {
2143 /* Call Directly huart->hdmatx->XferAbortCallback function in case of error */
2144 huart->hdmatx->XferAbortCallback(huart->hdmatx);
2145 }
2146 }
2147 else
2148 {
2149 /* Reset Tx transfer counter */
2150 huart->TxXferCount = 0U;
2151
2152 /* Clear TxISR function pointers */
2153 huart->TxISR = NULL;
2154
2155 /* Restore huart->gState to Ready */
2156 huart->gState = HAL_UART_STATE_READY;
2157
2158 /* As no DMA to be aborted, call directly user Abort complete callback */
2159 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2160 /* Call registered Abort Transmit Complete Callback */
2161 huart->AbortTransmitCpltCallback(huart);
2162 #else
2163 /* Call legacy weak Abort Transmit Complete Callback */
2164 HAL_UART_AbortTransmitCpltCallback(huart);
2165 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2166 }
2167 }
2168 else
2169 {
2170 /* Reset Tx transfer counter */
2171 huart->TxXferCount = 0U;
2172
2173 /* Clear TxISR function pointers */
2174 huart->TxISR = NULL;
2175
2176 /* Flush the whole TX FIFO (if needed) */
2177 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
2178 {
2179 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
2180 }
2181
2182 /* Restore huart->gState to Ready */
2183 huart->gState = HAL_UART_STATE_READY;
2184
2185 /* As no DMA to be aborted, call directly user Abort complete callback */
2186 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2187 /* Call registered Abort Transmit Complete Callback */
2188 huart->AbortTransmitCpltCallback(huart);
2189 #else
2190 /* Call legacy weak Abort Transmit Complete Callback */
2191 HAL_UART_AbortTransmitCpltCallback(huart);
2192 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2193 }
2194
2195 return HAL_OK;
2196 }
2197
2198 /**
2199 * @brief Abort ongoing Receive transfer (Interrupt mode).
2200 * @param huart UART handle.
2201 * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
2202 * This procedure performs following operations :
2203 * - Disable UART Interrupts (Rx)
2204 * - Disable the DMA transfer in the peripheral register (if enabled)
2205 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
2206 * - Set handle State to READY
2207 * - At abort completion, call user abort complete callback
2208 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
2209 * considered as completed only when user abort complete callback is executed (not when exiting function).
2210 * @retval HAL status
2211 */
HAL_UART_AbortReceive_IT(UART_HandleTypeDef * huart)2212 HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart)
2213 {
2214 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
2215 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE));
2216 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
2217
2218 /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
2219 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
2220 {
2221 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
2222 }
2223
2224 /* Abort the UART DMA Rx channel if enabled */
2225 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2226 {
2227 /* Disable the UART DMA Rx request if enabled */
2228 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2229
2230 /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
2231 if (huart->hdmarx != NULL)
2232 {
2233 /* Set the UART DMA Abort callback :
2234 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2235 huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback;
2236
2237 /* Abort DMA RX */
2238 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
2239 {
2240 /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
2241 huart->hdmarx->XferAbortCallback(huart->hdmarx);
2242 }
2243 }
2244 else
2245 {
2246 /* Reset Rx transfer counter */
2247 huart->RxXferCount = 0U;
2248
2249 /* Clear RxISR function pointer */
2250 huart->pRxBuffPtr = NULL;
2251
2252 /* Clear the Error flags in the ICR register */
2253 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
2254
2255 /* Discard the received data */
2256 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
2257
2258 /* Restore huart->RxState to Ready */
2259 huart->RxState = HAL_UART_STATE_READY;
2260 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2261
2262 /* As no DMA to be aborted, call directly user Abort complete callback */
2263 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2264 /* Call registered Abort Receive Complete Callback */
2265 huart->AbortReceiveCpltCallback(huart);
2266 #else
2267 /* Call legacy weak Abort Receive Complete Callback */
2268 HAL_UART_AbortReceiveCpltCallback(huart);
2269 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2270 }
2271 }
2272 else
2273 {
2274 /* Reset Rx transfer counter */
2275 huart->RxXferCount = 0U;
2276
2277 /* Clear RxISR function pointer */
2278 huart->pRxBuffPtr = NULL;
2279
2280 /* Clear the Error flags in the ICR register */
2281 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
2282
2283 /* Restore huart->RxState to Ready */
2284 huart->RxState = HAL_UART_STATE_READY;
2285 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2286
2287 /* As no DMA to be aborted, call directly user Abort complete callback */
2288 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2289 /* Call registered Abort Receive Complete Callback */
2290 huart->AbortReceiveCpltCallback(huart);
2291 #else
2292 /* Call legacy weak Abort Receive Complete Callback */
2293 HAL_UART_AbortReceiveCpltCallback(huart);
2294 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2295 }
2296
2297 return HAL_OK;
2298 }
2299
2300 /**
2301 * @brief Handle UART interrupt request.
2302 * @param huart UART handle.
2303 * @retval None
2304 */
HAL_UART_IRQHandler(UART_HandleTypeDef * huart)2305 void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
2306 {
2307 uint32_t isrflags = READ_REG(huart->Instance->ISR);
2308 uint32_t cr1its = READ_REG(huart->Instance->CR1);
2309 uint32_t cr3its = READ_REG(huart->Instance->CR3);
2310
2311 uint32_t errorflags;
2312 uint32_t errorcode;
2313
2314 /* If no error occurs */
2315 errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF));
2316 if (errorflags == 0U)
2317 {
2318 /* UART in mode Receiver ---------------------------------------------------*/
2319 if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
2320 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
2321 || ((cr3its & USART_CR3_RXFTIE) != 0U)))
2322 {
2323 if (huart->RxISR != NULL)
2324 {
2325 huart->RxISR(huart);
2326 }
2327 return;
2328 }
2329 }
2330
2331 /* If some errors occur */
2332 if ((errorflags != 0U)
2333 && ((((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)
2334 || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_RTOIE)) != 0U))))
2335 {
2336 /* UART parity error interrupt occurred -------------------------------------*/
2337 if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
2338 {
2339 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
2340
2341 huart->ErrorCode |= HAL_UART_ERROR_PE;
2342 }
2343
2344 /* UART frame error interrupt occurred --------------------------------------*/
2345 if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2346 {
2347 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
2348
2349 huart->ErrorCode |= HAL_UART_ERROR_FE;
2350 }
2351
2352 /* UART noise error interrupt occurred --------------------------------------*/
2353 if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
2354 {
2355 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
2356
2357 huart->ErrorCode |= HAL_UART_ERROR_NE;
2358 }
2359
2360 /* UART Over-Run interrupt occurred -----------------------------------------*/
2361 if (((isrflags & USART_ISR_ORE) != 0U)
2362 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) ||
2363 ((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)))
2364 {
2365 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
2366
2367 huart->ErrorCode |= HAL_UART_ERROR_ORE;
2368 }
2369
2370 /* UART Receiver Timeout interrupt occurred ---------------------------------*/
2371 if (((isrflags & USART_ISR_RTOF) != 0U) && ((cr1its & USART_CR1_RTOIE) != 0U))
2372 {
2373 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);
2374
2375 huart->ErrorCode |= HAL_UART_ERROR_RTO;
2376 }
2377
2378 /* Call UART Error Call back function if need be ----------------------------*/
2379 if (huart->ErrorCode != HAL_UART_ERROR_NONE)
2380 {
2381 /* UART in mode Receiver --------------------------------------------------*/
2382 if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
2383 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
2384 || ((cr3its & USART_CR3_RXFTIE) != 0U)))
2385 {
2386 if (huart->RxISR != NULL)
2387 {
2388 huart->RxISR(huart);
2389 }
2390 }
2391
2392 /* If Error is to be considered as blocking :
2393 - Receiver Timeout error in Reception
2394 - Overrun error in Reception
2395 - any error occurs in DMA mode reception
2396 */
2397 errorcode = huart->ErrorCode;
2398 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) ||
2399 ((errorcode & (HAL_UART_ERROR_RTO | HAL_UART_ERROR_ORE)) != 0U))
2400 {
2401 /* Blocking error : transfer is aborted
2402 Set the UART state ready to be able to start again the process,
2403 Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
2404 UART_EndRxTransfer(huart);
2405
2406 /* Abort the UART DMA Rx channel if enabled */
2407 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2408 {
2409 /* Disable the UART DMA Rx request if enabled */
2410 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2411
2412 /* Abort the UART DMA Rx channel */
2413 if (huart->hdmarx != NULL)
2414 {
2415 /* Set the UART DMA Abort callback :
2416 will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */
2417 huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;
2418
2419 /* Abort DMA RX */
2420 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
2421 {
2422 /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
2423 huart->hdmarx->XferAbortCallback(huart->hdmarx);
2424 }
2425 }
2426 else
2427 {
2428 /* Call user error callback */
2429 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2430 /*Call registered error callback*/
2431 huart->ErrorCallback(huart);
2432 #else
2433 /*Call legacy weak error callback*/
2434 HAL_UART_ErrorCallback(huart);
2435 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2436
2437 }
2438 }
2439 else
2440 {
2441 /* Call user error callback */
2442 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2443 /*Call registered error callback*/
2444 huart->ErrorCallback(huart);
2445 #else
2446 /*Call legacy weak error callback*/
2447 HAL_UART_ErrorCallback(huart);
2448 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2449 }
2450 }
2451 else
2452 {
2453 /* Non Blocking error : transfer could go on.
2454 Error is notified to user through user error callback */
2455 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2456 /*Call registered error callback*/
2457 huart->ErrorCallback(huart);
2458 #else
2459 /*Call legacy weak error callback*/
2460 HAL_UART_ErrorCallback(huart);
2461 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2462 huart->ErrorCode = HAL_UART_ERROR_NONE;
2463 }
2464 }
2465 return;
2466
2467 } /* End if some error occurs */
2468
2469 /* Check current reception Mode :
2470 If Reception till IDLE event has been selected : */
2471 if ((huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
2472 && ((isrflags & USART_ISR_IDLE) != 0U)
2473 && ((cr1its & USART_ISR_IDLE) != 0U))
2474 {
2475 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
2476
2477 /* Check if DMA mode is enabled in UART */
2478 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2479 {
2480 /* DMA mode enabled */
2481 /* Check received length : If all expected data are received, do nothing,
2482 (DMA cplt callback will be called).
2483 Otherwise, if at least one data has already been received, IDLE event is to be notified to user */
2484 uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(huart->hdmarx);
2485 if ((nb_remaining_rx_data > 0U)
2486 && (nb_remaining_rx_data < huart->RxXferSize))
2487 {
2488 /* Reception is not complete */
2489 huart->RxXferCount = nb_remaining_rx_data;
2490
2491 /* In Normal mode, end DMA xfer and HAL UART Rx process*/
2492 if (HAL_IS_BIT_CLR(huart->hdmarx->Instance->CCR, DMA_CCR_CIRC))
2493 {
2494 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
2495 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
2496 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
2497
2498 /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
2499 in the UART CR3 register */
2500 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2501
2502 /* At end of Rx process, restore huart->RxState to Ready */
2503 huart->RxState = HAL_UART_STATE_READY;
2504 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2505
2506 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
2507
2508 /* Last bytes received, so no need as the abort is immediate */
2509 (void)HAL_DMA_Abort(huart->hdmarx);
2510 }
2511
2512 /* Initialize type of RxEvent that correspond to RxEvent callback execution;
2513 In this case, Rx Event type is Idle Event */
2514 huart->RxEventType = HAL_UART_RXEVENT_IDLE;
2515
2516 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2517 /*Call registered Rx Event callback*/
2518 huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
2519 #else
2520 /*Call legacy weak Rx Event callback*/
2521 HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
2522 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
2523 }
2524 return;
2525 }
2526 else
2527 {
2528 /* DMA mode not enabled */
2529 /* Check received length : If all expected data are received, do nothing.
2530 Otherwise, if at least one data has already been received, IDLE event is to be notified to user */
2531 uint16_t nb_rx_data = huart->RxXferSize - huart->RxXferCount;
2532 if ((huart->RxXferCount > 0U)
2533 && (nb_rx_data > 0U))
2534 {
2535 /* Disable the UART Parity Error Interrupt and RXNE interrupts */
2536 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
2537
2538 /* Disable the UART Error Interrupt:(Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */
2539 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
2540
2541 /* Rx process is completed, restore huart->RxState to Ready */
2542 huart->RxState = HAL_UART_STATE_READY;
2543 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
2544
2545 /* Clear RxISR function pointer */
2546 huart->RxISR = NULL;
2547
2548 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
2549
2550 /* Initialize type of RxEvent that correspond to RxEvent callback execution;
2551 In this case, Rx Event type is Idle Event */
2552 huart->RxEventType = HAL_UART_RXEVENT_IDLE;
2553
2554 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2555 /*Call registered Rx complete callback*/
2556 huart->RxEventCallback(huart, nb_rx_data);
2557 #else
2558 /*Call legacy weak Rx Event callback*/
2559 HAL_UARTEx_RxEventCallback(huart, nb_rx_data);
2560 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
2561 }
2562 return;
2563 }
2564 }
2565
2566 /* UART wakeup from Stop mode interrupt occurred ---------------------------*/
2567 if (((isrflags & USART_ISR_WUF) != 0U) && ((cr3its & USART_CR3_WUFIE) != 0U))
2568 {
2569 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_WUF);
2570
2571 /* UART Rx state is not reset as a reception process might be ongoing.
2572 If UART handle state fields need to be reset to READY, this could be done in Wakeup callback */
2573
2574 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2575 /* Call registered Wakeup Callback */
2576 huart->WakeupCallback(huart);
2577 #else
2578 /* Call legacy weak Wakeup Callback */
2579 HAL_UARTEx_WakeupCallback(huart);
2580 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2581 return;
2582 }
2583
2584 /* UART in mode Transmitter ------------------------------------------------*/
2585 if (((isrflags & USART_ISR_TXE_TXFNF) != 0U)
2586 && (((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U)
2587 || ((cr3its & USART_CR3_TXFTIE) != 0U)))
2588 {
2589 if (huart->TxISR != NULL)
2590 {
2591 huart->TxISR(huart);
2592 }
2593 return;
2594 }
2595
2596 /* UART in mode Transmitter (transmission end) -----------------------------*/
2597 if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
2598 {
2599 UART_EndTransmit_IT(huart);
2600 return;
2601 }
2602
2603 /* UART TX Fifo Empty occurred ----------------------------------------------*/
2604 if (((isrflags & USART_ISR_TXFE) != 0U) && ((cr1its & USART_CR1_TXFEIE) != 0U))
2605 {
2606 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2607 /* Call registered Tx Fifo Empty Callback */
2608 huart->TxFifoEmptyCallback(huart);
2609 #else
2610 /* Call legacy weak Tx Fifo Empty Callback */
2611 HAL_UARTEx_TxFifoEmptyCallback(huart);
2612 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2613 return;
2614 }
2615
2616 /* UART RX Fifo Full occurred ----------------------------------------------*/
2617 if (((isrflags & USART_ISR_RXFF) != 0U) && ((cr1its & USART_CR1_RXFFIE) != 0U))
2618 {
2619 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2620 /* Call registered Rx Fifo Full Callback */
2621 huart->RxFifoFullCallback(huart);
2622 #else
2623 /* Call legacy weak Rx Fifo Full Callback */
2624 HAL_UARTEx_RxFifoFullCallback(huart);
2625 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2626 return;
2627 }
2628 }
2629
2630 /**
2631 * @brief Tx Transfer completed callback.
2632 * @param huart UART handle.
2633 * @retval None
2634 */
HAL_UART_TxCpltCallback(UART_HandleTypeDef * huart)2635 __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
2636 {
2637 /* Prevent unused argument(s) compilation warning */
2638 UNUSED(huart);
2639
2640 /* NOTE : This function should not be modified, when the callback is needed,
2641 the HAL_UART_TxCpltCallback can be implemented in the user file.
2642 */
2643 }
2644
2645 /**
2646 * @brief Tx Half Transfer completed callback.
2647 * @param huart UART handle.
2648 * @retval None
2649 */
HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef * huart)2650 __weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
2651 {
2652 /* Prevent unused argument(s) compilation warning */
2653 UNUSED(huart);
2654
2655 /* NOTE: This function should not be modified, when the callback is needed,
2656 the HAL_UART_TxHalfCpltCallback can be implemented in the user file.
2657 */
2658 }
2659
2660 /**
2661 * @brief Rx Transfer completed callback.
2662 * @param huart UART handle.
2663 * @retval None
2664 */
HAL_UART_RxCpltCallback(UART_HandleTypeDef * huart)2665 __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
2666 {
2667 /* Prevent unused argument(s) compilation warning */
2668 UNUSED(huart);
2669
2670 /* NOTE : This function should not be modified, when the callback is needed,
2671 the HAL_UART_RxCpltCallback can be implemented in the user file.
2672 */
2673 }
2674
2675 /**
2676 * @brief Rx Half Transfer completed callback.
2677 * @param huart UART handle.
2678 * @retval None
2679 */
HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef * huart)2680 __weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
2681 {
2682 /* Prevent unused argument(s) compilation warning */
2683 UNUSED(huart);
2684
2685 /* NOTE: This function should not be modified, when the callback is needed,
2686 the HAL_UART_RxHalfCpltCallback can be implemented in the user file.
2687 */
2688 }
2689
2690 /**
2691 * @brief UART error callback.
2692 * @param huart UART handle.
2693 * @retval None
2694 */
HAL_UART_ErrorCallback(UART_HandleTypeDef * huart)2695 __weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
2696 {
2697 /* Prevent unused argument(s) compilation warning */
2698 UNUSED(huart);
2699
2700 /* NOTE : This function should not be modified, when the callback is needed,
2701 the HAL_UART_ErrorCallback can be implemented in the user file.
2702 */
2703 }
2704
2705 /**
2706 * @brief UART Abort Complete callback.
2707 * @param huart UART handle.
2708 * @retval None
2709 */
HAL_UART_AbortCpltCallback(UART_HandleTypeDef * huart)2710 __weak void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart)
2711 {
2712 /* Prevent unused argument(s) compilation warning */
2713 UNUSED(huart);
2714
2715 /* NOTE : This function should not be modified, when the callback is needed,
2716 the HAL_UART_AbortCpltCallback can be implemented in the user file.
2717 */
2718 }
2719
2720 /**
2721 * @brief UART Abort Complete callback.
2722 * @param huart UART handle.
2723 * @retval None
2724 */
HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef * huart)2725 __weak void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart)
2726 {
2727 /* Prevent unused argument(s) compilation warning */
2728 UNUSED(huart);
2729
2730 /* NOTE : This function should not be modified, when the callback is needed,
2731 the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file.
2732 */
2733 }
2734
2735 /**
2736 * @brief UART Abort Receive Complete callback.
2737 * @param huart UART handle.
2738 * @retval None
2739 */
HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef * huart)2740 __weak void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart)
2741 {
2742 /* Prevent unused argument(s) compilation warning */
2743 UNUSED(huart);
2744
2745 /* NOTE : This function should not be modified, when the callback is needed,
2746 the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file.
2747 */
2748 }
2749
2750 /**
2751 * @brief Reception Event Callback (Rx event notification called after use of advanced reception service).
2752 * @param huart UART handle
2753 * @param Size Number of data available in application reception buffer (indicates a position in
2754 * reception buffer until which, data are available)
2755 * @retval None
2756 */
HAL_UARTEx_RxEventCallback(UART_HandleTypeDef * huart,uint16_t Size)2757 __weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
2758 {
2759 /* Prevent unused argument(s) compilation warning */
2760 UNUSED(huart);
2761 UNUSED(Size);
2762
2763 /* NOTE : This function should not be modified, when the callback is needed,
2764 the HAL_UARTEx_RxEventCallback can be implemented in the user file.
2765 */
2766 }
2767
2768 /**
2769 * @}
2770 */
2771
2772 /** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions
2773 * @brief UART control functions
2774 *
2775 @verbatim
2776 ===============================================================================
2777 ##### Peripheral Control functions #####
2778 ===============================================================================
2779 [..]
2780 This subsection provides a set of functions allowing to control the UART.
2781 (+) HAL_UART_ReceiverTimeout_Config() API allows to configure the receiver timeout value on the fly
2782 (+) HAL_UART_EnableReceiverTimeout() API enables the receiver timeout feature
2783 (+) HAL_UART_DisableReceiverTimeout() API disables the receiver timeout feature
2784 (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode
2785 (+) HAL_MultiProcessor_DisableMuteMode() API disables mute mode
2786 (+) HAL_MultiProcessor_EnterMuteMode() API enters mute mode
2787 (+) UART_SetConfig() API configures the UART peripheral
2788 (+) UART_AdvFeatureConfig() API optionally configures the UART advanced features
2789 (+) UART_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization
2790 (+) HAL_HalfDuplex_EnableTransmitter() API disables receiver and enables transmitter
2791 (+) HAL_HalfDuplex_EnableReceiver() API disables transmitter and enables receiver
2792 (+) HAL_LIN_SendBreak() API transmits the break characters
2793 @endverbatim
2794 * @{
2795 */
2796
2797 /**
2798 * @brief Update on the fly the receiver timeout value in RTOR register.
2799 * @param huart Pointer to a UART_HandleTypeDef structure that contains
2800 * the configuration information for the specified UART module.
2801 * @param TimeoutValue receiver timeout value in number of baud blocks. The timeout
2802 * value must be less or equal to 0x0FFFFFFFF.
2803 * @retval None
2804 */
HAL_UART_ReceiverTimeout_Config(UART_HandleTypeDef * huart,uint32_t TimeoutValue)2805 void HAL_UART_ReceiverTimeout_Config(UART_HandleTypeDef *huart, uint32_t TimeoutValue)
2806 {
2807 if (!(IS_LPUART_INSTANCE(huart->Instance)))
2808 {
2809 assert_param(IS_UART_RECEIVER_TIMEOUT_VALUE(TimeoutValue));
2810 MODIFY_REG(huart->Instance->RTOR, USART_RTOR_RTO, TimeoutValue);
2811 }
2812 }
2813
2814 /**
2815 * @brief Enable the UART receiver timeout feature.
2816 * @param huart Pointer to a UART_HandleTypeDef structure that contains
2817 * the configuration information for the specified UART module.
2818 * @retval HAL status
2819 */
HAL_UART_EnableReceiverTimeout(UART_HandleTypeDef * huart)2820 HAL_StatusTypeDef HAL_UART_EnableReceiverTimeout(UART_HandleTypeDef *huart)
2821 {
2822 if (!(IS_LPUART_INSTANCE(huart->Instance)))
2823 {
2824 if (huart->gState == HAL_UART_STATE_READY)
2825 {
2826 /* Process Locked */
2827 __HAL_LOCK(huart);
2828
2829 huart->gState = HAL_UART_STATE_BUSY;
2830
2831 /* Set the USART RTOEN bit */
2832 SET_BIT(huart->Instance->CR2, USART_CR2_RTOEN);
2833
2834 huart->gState = HAL_UART_STATE_READY;
2835
2836 /* Process Unlocked */
2837 __HAL_UNLOCK(huart);
2838
2839 return HAL_OK;
2840 }
2841 else
2842 {
2843 return HAL_BUSY;
2844 }
2845 }
2846 else
2847 {
2848 return HAL_ERROR;
2849 }
2850 }
2851
2852 /**
2853 * @brief Disable the UART receiver timeout feature.
2854 * @param huart Pointer to a UART_HandleTypeDef structure that contains
2855 * the configuration information for the specified UART module.
2856 * @retval HAL status
2857 */
HAL_UART_DisableReceiverTimeout(UART_HandleTypeDef * huart)2858 HAL_StatusTypeDef HAL_UART_DisableReceiverTimeout(UART_HandleTypeDef *huart)
2859 {
2860 if (!(IS_LPUART_INSTANCE(huart->Instance)))
2861 {
2862 if (huart->gState == HAL_UART_STATE_READY)
2863 {
2864 /* Process Locked */
2865 __HAL_LOCK(huart);
2866
2867 huart->gState = HAL_UART_STATE_BUSY;
2868
2869 /* Clear the USART RTOEN bit */
2870 CLEAR_BIT(huart->Instance->CR2, USART_CR2_RTOEN);
2871
2872 huart->gState = HAL_UART_STATE_READY;
2873
2874 /* Process Unlocked */
2875 __HAL_UNLOCK(huart);
2876
2877 return HAL_OK;
2878 }
2879 else
2880 {
2881 return HAL_BUSY;
2882 }
2883 }
2884 else
2885 {
2886 return HAL_ERROR;
2887 }
2888 }
2889
2890 /**
2891 * @brief Enable UART in mute mode (does not mean UART enters mute mode;
2892 * to enter mute mode, HAL_MultiProcessor_EnterMuteMode() API must be called).
2893 * @param huart UART handle.
2894 * @retval HAL status
2895 */
HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef * huart)2896 HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart)
2897 {
2898 __HAL_LOCK(huart);
2899
2900 huart->gState = HAL_UART_STATE_BUSY;
2901
2902 /* Enable USART mute mode by setting the MME bit in the CR1 register */
2903 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_MME);
2904
2905 huart->gState = HAL_UART_STATE_READY;
2906
2907 return (UART_CheckIdleState(huart));
2908 }
2909
2910 /**
2911 * @brief Disable UART mute mode (does not mean the UART actually exits mute mode
2912 * as it may not have been in mute mode at this very moment).
2913 * @param huart UART handle.
2914 * @retval HAL status
2915 */
HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef * huart)2916 HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart)
2917 {
2918 __HAL_LOCK(huart);
2919
2920 huart->gState = HAL_UART_STATE_BUSY;
2921
2922 /* Disable USART mute mode by clearing the MME bit in the CR1 register */
2923 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_MME);
2924
2925 huart->gState = HAL_UART_STATE_READY;
2926
2927 return (UART_CheckIdleState(huart));
2928 }
2929
2930 /**
2931 * @brief Enter UART mute mode (means UART actually enters mute mode).
2932 * @note To exit from mute mode, HAL_MultiProcessor_DisableMuteMode() API must be called.
2933 * @param huart UART handle.
2934 * @retval None
2935 */
HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef * huart)2936 void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart)
2937 {
2938 __HAL_UART_SEND_REQ(huart, UART_MUTE_MODE_REQUEST);
2939 }
2940
2941 /**
2942 * @brief Enable the UART transmitter and disable the UART receiver.
2943 * @param huart UART handle.
2944 * @retval HAL status
2945 */
HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef * huart)2946 HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
2947 {
2948 __HAL_LOCK(huart);
2949 huart->gState = HAL_UART_STATE_BUSY;
2950
2951 /* Clear TE and RE bits */
2952 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
2953
2954 /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
2955 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TE);
2956
2957 huart->gState = HAL_UART_STATE_READY;
2958
2959 __HAL_UNLOCK(huart);
2960
2961 return HAL_OK;
2962 }
2963
2964 /**
2965 * @brief Enable the UART receiver and disable the UART transmitter.
2966 * @param huart UART handle.
2967 * @retval HAL status.
2968 */
HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef * huart)2969 HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart)
2970 {
2971 __HAL_LOCK(huart);
2972 huart->gState = HAL_UART_STATE_BUSY;
2973
2974 /* Clear TE and RE bits */
2975 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
2976
2977 /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
2978 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RE);
2979
2980 huart->gState = HAL_UART_STATE_READY;
2981
2982 __HAL_UNLOCK(huart);
2983
2984 return HAL_OK;
2985 }
2986
2987
2988 /**
2989 * @brief Transmit break characters.
2990 * @param huart UART handle.
2991 * @retval HAL status
2992 */
HAL_LIN_SendBreak(UART_HandleTypeDef * huart)2993 HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
2994 {
2995 /* Check the parameters */
2996 assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
2997
2998 __HAL_LOCK(huart);
2999
3000 huart->gState = HAL_UART_STATE_BUSY;
3001
3002 /* Send break characters */
3003 __HAL_UART_SEND_REQ(huart, UART_SENDBREAK_REQUEST);
3004
3005 huart->gState = HAL_UART_STATE_READY;
3006
3007 __HAL_UNLOCK(huart);
3008
3009 return HAL_OK;
3010 }
3011
3012 /**
3013 * @}
3014 */
3015
3016 /** @defgroup UART_Exported_Functions_Group4 Peripheral State and Error functions
3017 * @brief UART Peripheral State functions
3018 *
3019 @verbatim
3020 ==============================================================================
3021 ##### Peripheral State and Error functions #####
3022 ==============================================================================
3023 [..]
3024 This subsection provides functions allowing to :
3025 (+) Return the UART handle state.
3026 (+) Return the UART handle error code
3027
3028 @endverbatim
3029 * @{
3030 */
3031
3032 /**
3033 * @brief Return the UART handle state.
3034 * @param huart Pointer to a UART_HandleTypeDef structure that contains
3035 * the configuration information for the specified UART.
3036 * @retval HAL state
3037 */
HAL_UART_GetState(const UART_HandleTypeDef * huart)3038 HAL_UART_StateTypeDef HAL_UART_GetState(const UART_HandleTypeDef *huart)
3039 {
3040 uint32_t temp1;
3041 uint32_t temp2;
3042 temp1 = huart->gState;
3043 temp2 = huart->RxState;
3044
3045 return (HAL_UART_StateTypeDef)(temp1 | temp2);
3046 }
3047
3048 /**
3049 * @brief Return the UART handle error code.
3050 * @param huart Pointer to a UART_HandleTypeDef structure that contains
3051 * the configuration information for the specified UART.
3052 * @retval UART Error Code
3053 */
HAL_UART_GetError(const UART_HandleTypeDef * huart)3054 uint32_t HAL_UART_GetError(const UART_HandleTypeDef *huart)
3055 {
3056 return huart->ErrorCode;
3057 }
3058 /**
3059 * @}
3060 */
3061
3062 /**
3063 * @}
3064 */
3065
3066 /** @defgroup UART_Private_Functions UART Private Functions
3067 * @{
3068 */
3069
3070 /**
3071 * @brief Initialize the callbacks to their default values.
3072 * @param huart UART handle.
3073 * @retval none
3074 */
3075 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
UART_InitCallbacksToDefault(UART_HandleTypeDef * huart)3076 void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart)
3077 {
3078 /* Init the UART Callback settings */
3079 huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
3080 huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */
3081 huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
3082 huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */
3083 huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */
3084 huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
3085 huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
3086 huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
3087 huart->WakeupCallback = HAL_UARTEx_WakeupCallback; /* Legacy weak WakeupCallback */
3088 huart->RxFifoFullCallback = HAL_UARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */
3089 huart->TxFifoEmptyCallback = HAL_UARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */
3090 huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak RxEventCallback */
3091
3092 }
3093 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3094
3095 /**
3096 * @brief Configure the UART peripheral.
3097 * @param huart UART handle.
3098 * @retval HAL status
3099 */
UART_SetConfig(UART_HandleTypeDef * huart)3100 HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart)
3101 {
3102 uint32_t tmpreg;
3103 uint16_t brrtemp;
3104 UART_ClockSourceTypeDef clocksource;
3105 uint32_t usartdiv;
3106 HAL_StatusTypeDef ret = HAL_OK;
3107 uint32_t lpuart_ker_ck_pres;
3108 uint32_t pclk;
3109
3110 /* Check the parameters */
3111 assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
3112 assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
3113 if (UART_INSTANCE_LOWPOWER(huart))
3114 {
3115 assert_param(IS_LPUART_STOPBITS(huart->Init.StopBits));
3116 }
3117 else
3118 {
3119 assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
3120 assert_param(IS_UART_ONE_BIT_SAMPLE(huart->Init.OneBitSampling));
3121 }
3122
3123 assert_param(IS_UART_PARITY(huart->Init.Parity));
3124 assert_param(IS_UART_MODE(huart->Init.Mode));
3125 assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
3126 assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
3127 assert_param(IS_UART_PRESCALER(huart->Init.ClockPrescaler));
3128
3129 /*-------------------------- USART CR1 Configuration -----------------------*/
3130 /* Clear M, PCE, PS, TE, RE and OVER8 bits and configure
3131 * the UART Word Length, Parity, Mode and oversampling:
3132 * set the M bits according to huart->Init.WordLength value
3133 * set PCE and PS bits according to huart->Init.Parity value
3134 * set TE and RE bits according to huart->Init.Mode value
3135 * set OVER8 bit according to huart->Init.OverSampling value */
3136 tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling ;
3137 MODIFY_REG(huart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
3138
3139 /*-------------------------- USART CR2 Configuration -----------------------*/
3140 /* Configure the UART Stop Bits: Set STOP[13:12] bits according
3141 * to huart->Init.StopBits value */
3142 MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
3143
3144 /*-------------------------- USART CR3 Configuration -----------------------*/
3145 /* Configure
3146 * - UART HardWare Flow Control: set CTSE and RTSE bits according
3147 * to huart->Init.HwFlowCtl value
3148 * - one-bit sampling method versus three samples' majority rule according
3149 * to huart->Init.OneBitSampling (not applicable to LPUART) */
3150 tmpreg = (uint32_t)huart->Init.HwFlowCtl;
3151
3152 if (!(UART_INSTANCE_LOWPOWER(huart)))
3153 {
3154 tmpreg |= huart->Init.OneBitSampling;
3155 }
3156 MODIFY_REG(huart->Instance->CR3, USART_CR3_FIELDS, tmpreg);
3157
3158 /*-------------------------- USART PRESC Configuration -----------------------*/
3159 /* Configure
3160 * - UART Clock Prescaler : set PRESCALER according to huart->Init.ClockPrescaler value */
3161 MODIFY_REG(huart->Instance->PRESC, USART_PRESC_PRESCALER, huart->Init.ClockPrescaler);
3162
3163 /*-------------------------- USART BRR Configuration -----------------------*/
3164 UART_GETCLOCKSOURCE(huart, clocksource);
3165
3166 /* Check LPUART instance */
3167 if (UART_INSTANCE_LOWPOWER(huart))
3168 {
3169 /* Retrieve frequency clock */
3170 switch (clocksource)
3171 {
3172 case UART_CLOCKSOURCE_PCLK1:
3173 pclk = HAL_RCC_GetPCLK1Freq();
3174 break;
3175 case UART_CLOCKSOURCE_HSI:
3176 pclk = (uint32_t) HSI_VALUE;
3177 break;
3178 case UART_CLOCKSOURCE_SYSCLK:
3179 pclk = HAL_RCC_GetSysClockFreq();
3180 break;
3181 case UART_CLOCKSOURCE_LSE:
3182 pclk = (uint32_t) LSE_VALUE;
3183 break;
3184 default:
3185 pclk = 0U;
3186 ret = HAL_ERROR;
3187 break;
3188 }
3189
3190 /* If proper clock source reported */
3191 if (pclk != 0U)
3192 {
3193 /* Compute clock after Prescaler */
3194 lpuart_ker_ck_pres = (pclk / UARTPrescTable[huart->Init.ClockPrescaler]);
3195
3196 /* Ensure that Frequency clock is in the range [3 * baudrate, 4096 * baudrate] */
3197 if ((lpuart_ker_ck_pres < (3U * huart->Init.BaudRate)) ||
3198 (lpuart_ker_ck_pres > (4096U * huart->Init.BaudRate)))
3199 {
3200 ret = HAL_ERROR;
3201 }
3202 else
3203 {
3204 /* Check computed UsartDiv value is in allocated range
3205 (it is forbidden to write values lower than 0x300 in the LPUART_BRR register) */
3206 usartdiv = (uint32_t)(UART_DIV_LPUART(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3207 if ((usartdiv >= LPUART_BRR_MIN) && (usartdiv <= LPUART_BRR_MAX))
3208 {
3209 huart->Instance->BRR = usartdiv;
3210 }
3211 else
3212 {
3213 ret = HAL_ERROR;
3214 }
3215 } /* if ( (lpuart_ker_ck_pres < (3 * huart->Init.BaudRate) ) ||
3216 (lpuart_ker_ck_pres > (4096 * huart->Init.BaudRate) )) */
3217 } /* if (pclk != 0) */
3218 }
3219 /* Check UART Over Sampling to set Baud Rate Register */
3220 else if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
3221 {
3222 switch (clocksource)
3223 {
3224 case UART_CLOCKSOURCE_PCLK1:
3225 pclk = HAL_RCC_GetPCLK1Freq();
3226 break;
3227 case UART_CLOCKSOURCE_HSI:
3228 pclk = (uint32_t) HSI_VALUE;
3229 break;
3230 case UART_CLOCKSOURCE_SYSCLK:
3231 pclk = HAL_RCC_GetSysClockFreq();
3232 break;
3233 case UART_CLOCKSOURCE_LSE:
3234 pclk = (uint32_t) LSE_VALUE;
3235 break;
3236 default:
3237 pclk = 0U;
3238 ret = HAL_ERROR;
3239 break;
3240 }
3241
3242 /* USARTDIV must be greater than or equal to 0d16 */
3243 if (pclk != 0U)
3244 {
3245 usartdiv = (uint32_t)(UART_DIV_SAMPLING8(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3246 if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
3247 {
3248 brrtemp = (uint16_t)(usartdiv & 0xFFF0U);
3249 brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U);
3250 huart->Instance->BRR = brrtemp;
3251 }
3252 else
3253 {
3254 ret = HAL_ERROR;
3255 }
3256 }
3257 }
3258 else
3259 {
3260 switch (clocksource)
3261 {
3262 case UART_CLOCKSOURCE_PCLK1:
3263 pclk = HAL_RCC_GetPCLK1Freq();
3264 break;
3265 case UART_CLOCKSOURCE_HSI:
3266 pclk = (uint32_t) HSI_VALUE;
3267 break;
3268 case UART_CLOCKSOURCE_SYSCLK:
3269 pclk = HAL_RCC_GetSysClockFreq();
3270 break;
3271 case UART_CLOCKSOURCE_LSE:
3272 pclk = (uint32_t) LSE_VALUE;
3273 break;
3274 default:
3275 pclk = 0U;
3276 ret = HAL_ERROR;
3277 break;
3278 }
3279
3280 if (pclk != 0U)
3281 {
3282 /* USARTDIV must be greater than or equal to 0d16 */
3283 usartdiv = (uint32_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3284 if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
3285 {
3286 huart->Instance->BRR = (uint16_t)usartdiv;
3287 }
3288 else
3289 {
3290 ret = HAL_ERROR;
3291 }
3292 }
3293 }
3294
3295 /* Initialize the number of data to process during RX/TX ISR execution */
3296 huart->NbTxDataToProcess = 1;
3297 huart->NbRxDataToProcess = 1;
3298
3299 /* Clear ISR function pointers */
3300 huart->RxISR = NULL;
3301 huart->TxISR = NULL;
3302
3303 return ret;
3304 }
3305
3306 /**
3307 * @brief Configure the UART peripheral advanced features.
3308 * @param huart UART handle.
3309 * @retval None
3310 */
UART_AdvFeatureConfig(UART_HandleTypeDef * huart)3311 void UART_AdvFeatureConfig(UART_HandleTypeDef *huart)
3312 {
3313 /* Check whether the set of advanced features to configure is properly set */
3314 assert_param(IS_UART_ADVFEATURE_INIT(huart->AdvancedInit.AdvFeatureInit));
3315
3316 /* if required, configure RX/TX pins swap */
3317 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_SWAP_INIT))
3318 {
3319 assert_param(IS_UART_ADVFEATURE_SWAP(huart->AdvancedInit.Swap));
3320 MODIFY_REG(huart->Instance->CR2, USART_CR2_SWAP, huart->AdvancedInit.Swap);
3321 }
3322
3323 /* if required, configure TX pin active level inversion */
3324 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_TXINVERT_INIT))
3325 {
3326 assert_param(IS_UART_ADVFEATURE_TXINV(huart->AdvancedInit.TxPinLevelInvert));
3327 MODIFY_REG(huart->Instance->CR2, USART_CR2_TXINV, huart->AdvancedInit.TxPinLevelInvert);
3328 }
3329
3330 /* if required, configure RX pin active level inversion */
3331 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXINVERT_INIT))
3332 {
3333 assert_param(IS_UART_ADVFEATURE_RXINV(huart->AdvancedInit.RxPinLevelInvert));
3334 MODIFY_REG(huart->Instance->CR2, USART_CR2_RXINV, huart->AdvancedInit.RxPinLevelInvert);
3335 }
3336
3337 /* if required, configure data inversion */
3338 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DATAINVERT_INIT))
3339 {
3340 assert_param(IS_UART_ADVFEATURE_DATAINV(huart->AdvancedInit.DataInvert));
3341 MODIFY_REG(huart->Instance->CR2, USART_CR2_DATAINV, huart->AdvancedInit.DataInvert);
3342 }
3343
3344 /* if required, configure RX overrun detection disabling */
3345 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXOVERRUNDISABLE_INIT))
3346 {
3347 assert_param(IS_UART_OVERRUN(huart->AdvancedInit.OverrunDisable));
3348 MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, huart->AdvancedInit.OverrunDisable);
3349 }
3350
3351 /* if required, configure DMA disabling on reception error */
3352 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DMADISABLEONERROR_INIT))
3353 {
3354 assert_param(IS_UART_ADVFEATURE_DMAONRXERROR(huart->AdvancedInit.DMADisableonRxError));
3355 MODIFY_REG(huart->Instance->CR3, USART_CR3_DDRE, huart->AdvancedInit.DMADisableonRxError);
3356 }
3357
3358 /* if required, configure auto Baud rate detection scheme */
3359 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT))
3360 {
3361 assert_param(IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(huart->Instance));
3362 assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable));
3363 MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable);
3364 /* set auto Baudrate detection parameters if detection is enabled */
3365 if (huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)
3366 {
3367 assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode));
3368 MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode);
3369 }
3370 }
3371
3372 /* if required, configure MSB first on communication line */
3373 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_MSBFIRST_INIT))
3374 {
3375 assert_param(IS_UART_ADVFEATURE_MSBFIRST(huart->AdvancedInit.MSBFirst));
3376 MODIFY_REG(huart->Instance->CR2, USART_CR2_MSBFIRST, huart->AdvancedInit.MSBFirst);
3377 }
3378 }
3379
3380 /**
3381 * @brief Check the UART Idle State.
3382 * @param huart UART handle.
3383 * @retval HAL status
3384 */
UART_CheckIdleState(UART_HandleTypeDef * huart)3385 HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart)
3386 {
3387 uint32_t tickstart;
3388
3389 /* Initialize the UART ErrorCode */
3390 huart->ErrorCode = HAL_UART_ERROR_NONE;
3391
3392 /* Init tickstart for timeout management */
3393 tickstart = HAL_GetTick();
3394
3395 /* Check if the Transmitter is enabled */
3396 if ((huart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
3397 {
3398 /* Wait until TEACK flag is set */
3399 if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
3400 {
3401 /* Disable TXE interrupt for the interrupt process */
3402 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE));
3403
3404 huart->gState = HAL_UART_STATE_READY;
3405
3406 __HAL_UNLOCK(huart);
3407
3408 /* Timeout occurred */
3409 return HAL_TIMEOUT;
3410 }
3411 }
3412
3413 /* Check if the Receiver is enabled */
3414 if ((huart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
3415 {
3416 /* Wait until REACK flag is set */
3417 if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
3418 {
3419 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error)
3420 interrupts for the interrupt process */
3421 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3422 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3423
3424 huart->RxState = HAL_UART_STATE_READY;
3425
3426 __HAL_UNLOCK(huart);
3427
3428 /* Timeout occurred */
3429 return HAL_TIMEOUT;
3430 }
3431 }
3432
3433 /* Initialize the UART State */
3434 huart->gState = HAL_UART_STATE_READY;
3435 huart->RxState = HAL_UART_STATE_READY;
3436 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
3437 huart->RxEventType = HAL_UART_RXEVENT_TC;
3438
3439 __HAL_UNLOCK(huart);
3440
3441 return HAL_OK;
3442 }
3443
3444 /**
3445 * @brief This function handles UART Communication Timeout. It waits
3446 * until a flag is no longer in the specified status.
3447 * @param huart UART handle.
3448 * @param Flag Specifies the UART flag to check
3449 * @param Status The actual Flag status (SET or RESET)
3450 * @param Tickstart Tick start value
3451 * @param Timeout Timeout duration
3452 * @retval HAL status
3453 */
UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef * huart,uint32_t Flag,FlagStatus Status,uint32_t Tickstart,uint32_t Timeout)3454 HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status,
3455 uint32_t Tickstart, uint32_t Timeout)
3456 {
3457 /* Wait until flag is set */
3458 while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status)
3459 {
3460 /* Check for the Timeout */
3461 if (Timeout != HAL_MAX_DELAY)
3462 {
3463 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
3464 {
3465
3466 return HAL_TIMEOUT;
3467 }
3468
3469 if ((READ_BIT(huart->Instance->CR1, USART_CR1_RE) != 0U) && (Flag != UART_FLAG_TXE) && (Flag != UART_FLAG_TC))
3470 {
3471 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) == SET)
3472 {
3473 /* Clear Overrun Error flag*/
3474 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
3475
3476 /* Blocking error : transfer is aborted
3477 Set the UART state ready to be able to start again the process,
3478 Disable Rx Interrupts if ongoing */
3479 UART_EndRxTransfer(huart);
3480
3481 huart->ErrorCode = HAL_UART_ERROR_ORE;
3482
3483 /* Process Unlocked */
3484 __HAL_UNLOCK(huart);
3485
3486 return HAL_ERROR;
3487 }
3488 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RTOF) == SET)
3489 {
3490 /* Clear Receiver Timeout flag*/
3491 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);
3492
3493 /* Blocking error : transfer is aborted
3494 Set the UART state ready to be able to start again the process,
3495 Disable Rx Interrupts if ongoing */
3496 UART_EndRxTransfer(huart);
3497
3498 huart->ErrorCode = HAL_UART_ERROR_RTO;
3499
3500 /* Process Unlocked */
3501 __HAL_UNLOCK(huart);
3502
3503 return HAL_TIMEOUT;
3504 }
3505 }
3506 }
3507 }
3508 return HAL_OK;
3509 }
3510
3511 /**
3512 * @brief Start Receive operation in interrupt mode.
3513 * @note This function could be called by all HAL UART API providing reception in Interrupt mode.
3514 * @note When calling this function, parameters validity is considered as already checked,
3515 * i.e. Rx State, buffer address, ...
3516 * UART Handle is assumed as Locked.
3517 * @param huart UART handle.
3518 * @param pData Pointer to data buffer (u8 or u16 data elements).
3519 * @param Size Amount of data elements (u8 or u16) to be received.
3520 * @retval HAL status
3521 */
UART_Start_Receive_IT(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)3522 HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
3523 {
3524 huart->pRxBuffPtr = pData;
3525 huart->RxXferSize = Size;
3526 huart->RxXferCount = Size;
3527 huart->RxISR = NULL;
3528
3529 /* Computation of UART mask to apply to RDR register */
3530 UART_MASK_COMPUTATION(huart);
3531
3532 huart->ErrorCode = HAL_UART_ERROR_NONE;
3533 huart->RxState = HAL_UART_STATE_BUSY_RX;
3534
3535 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
3536 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
3537
3538 /* Configure Rx interrupt processing */
3539 if ((huart->FifoMode == UART_FIFOMODE_ENABLE) && (Size >= huart->NbRxDataToProcess))
3540 {
3541 /* Set the Rx ISR function pointer according to the data word length */
3542 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
3543 {
3544 huart->RxISR = UART_RxISR_16BIT_FIFOEN;
3545 }
3546 else
3547 {
3548 huart->RxISR = UART_RxISR_8BIT_FIFOEN;
3549 }
3550
3551 /* Enable the UART Parity Error interrupt and RX FIFO Threshold interrupt */
3552 if (huart->Init.Parity != UART_PARITY_NONE)
3553 {
3554 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
3555 }
3556 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
3557 }
3558 else
3559 {
3560 /* Set the Rx ISR function pointer according to the data word length */
3561 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
3562 {
3563 huart->RxISR = UART_RxISR_16BIT;
3564 }
3565 else
3566 {
3567 huart->RxISR = UART_RxISR_8BIT;
3568 }
3569
3570 /* Enable the UART Parity Error interrupt and Data Register Not Empty interrupt */
3571 if (huart->Init.Parity != UART_PARITY_NONE)
3572 {
3573 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
3574 }
3575 else
3576 {
3577 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
3578 }
3579 }
3580 return HAL_OK;
3581 }
3582
3583 /**
3584 * @brief Start Receive operation in DMA mode.
3585 * @note This function could be called by all HAL UART API providing reception in DMA mode.
3586 * @note When calling this function, parameters validity is considered as already checked,
3587 * i.e. Rx State, buffer address, ...
3588 * UART Handle is assumed as Locked.
3589 * @param huart UART handle.
3590 * @param pData Pointer to data buffer (u8 or u16 data elements).
3591 * @param Size Amount of data elements (u8 or u16) to be received.
3592 * @retval HAL status
3593 */
UART_Start_Receive_DMA(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)3594 HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
3595 {
3596 huart->pRxBuffPtr = pData;
3597 huart->RxXferSize = Size;
3598
3599 huart->ErrorCode = HAL_UART_ERROR_NONE;
3600 huart->RxState = HAL_UART_STATE_BUSY_RX;
3601
3602 if (huart->hdmarx != NULL)
3603 {
3604 /* Set the UART DMA transfer complete callback */
3605 huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
3606
3607 /* Set the UART DMA Half transfer complete callback */
3608 huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
3609
3610 /* Set the DMA error callback */
3611 huart->hdmarx->XferErrorCallback = UART_DMAError;
3612
3613 /* Set the DMA abort callback */
3614 huart->hdmarx->XferAbortCallback = NULL;
3615
3616 /* Enable the DMA channel */
3617 if (HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, (uint32_t)huart->pRxBuffPtr, Size) != HAL_OK)
3618 {
3619 /* Set error code to DMA */
3620 huart->ErrorCode = HAL_UART_ERROR_DMA;
3621
3622 /* Restore huart->RxState to ready */
3623 huart->RxState = HAL_UART_STATE_READY;
3624
3625 return HAL_ERROR;
3626 }
3627 }
3628
3629 /* Enable the UART Parity Error Interrupt */
3630 if (huart->Init.Parity != UART_PARITY_NONE)
3631 {
3632 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
3633 }
3634
3635 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
3636 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
3637
3638 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
3639 in the UART CR3 register */
3640 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
3641
3642 return HAL_OK;
3643 }
3644
3645
3646 /**
3647 * @brief End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion).
3648 * @param huart UART handle.
3649 * @retval None
3650 */
UART_EndTxTransfer(UART_HandleTypeDef * huart)3651 static void UART_EndTxTransfer(UART_HandleTypeDef *huart)
3652 {
3653 /* Disable TXEIE, TCIE, TXFT interrupts */
3654 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
3655 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_TXFTIE));
3656
3657 /* At end of Tx process, restore huart->gState to Ready */
3658 huart->gState = HAL_UART_STATE_READY;
3659 }
3660
3661
3662 /**
3663 * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
3664 * @param huart UART handle.
3665 * @retval None
3666 */
UART_EndRxTransfer(UART_HandleTypeDef * huart)3667 static void UART_EndRxTransfer(UART_HandleTypeDef *huart)
3668 {
3669 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
3670 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3671 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
3672
3673 /* In case of reception waiting for IDLE event, disable also the IDLE IE interrupt source */
3674 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3675 {
3676 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
3677 }
3678
3679 /* At end of Rx process, restore huart->RxState to Ready */
3680 huart->RxState = HAL_UART_STATE_READY;
3681 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
3682
3683 /* Reset RxIsr function pointer */
3684 huart->RxISR = NULL;
3685 }
3686
3687
3688 /**
3689 * @brief DMA UART transmit process complete callback.
3690 * @param hdma DMA handle.
3691 * @retval None
3692 */
UART_DMATransmitCplt(DMA_HandleTypeDef * hdma)3693 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
3694 {
3695 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3696
3697 /* DMA Normal mode */
3698 if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
3699 {
3700 huart->TxXferCount = 0U;
3701
3702 /* Disable the DMA transfer for transmit request by resetting the DMAT bit
3703 in the UART CR3 register */
3704 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
3705
3706 /* Enable the UART Transmit Complete Interrupt */
3707 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3708 }
3709 /* DMA Circular mode */
3710 else
3711 {
3712 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3713 /*Call registered Tx complete callback*/
3714 huart->TxCpltCallback(huart);
3715 #else
3716 /*Call legacy weak Tx complete callback*/
3717 HAL_UART_TxCpltCallback(huart);
3718 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3719 }
3720 }
3721
3722 /**
3723 * @brief DMA UART transmit process half complete callback.
3724 * @param hdma DMA handle.
3725 * @retval None
3726 */
UART_DMATxHalfCplt(DMA_HandleTypeDef * hdma)3727 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
3728 {
3729 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3730
3731 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3732 /*Call registered Tx Half complete callback*/
3733 huart->TxHalfCpltCallback(huart);
3734 #else
3735 /*Call legacy weak Tx Half complete callback*/
3736 HAL_UART_TxHalfCpltCallback(huart);
3737 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3738 }
3739
3740 /**
3741 * @brief DMA UART receive process complete callback.
3742 * @param hdma DMA handle.
3743 * @retval None
3744 */
UART_DMAReceiveCplt(DMA_HandleTypeDef * hdma)3745 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
3746 {
3747 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3748
3749 /* DMA Normal mode */
3750 if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
3751 {
3752 huart->RxXferCount = 0U;
3753
3754 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
3755 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
3756 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3757
3758 /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
3759 in the UART CR3 register */
3760 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
3761
3762 /* At end of Rx process, restore huart->RxState to Ready */
3763 huart->RxState = HAL_UART_STATE_READY;
3764
3765 /* If Reception till IDLE event has been selected, Disable IDLE Interrupt */
3766 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3767 {
3768 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
3769 }
3770 }
3771
3772 /* Initialize type of RxEvent that correspond to RxEvent callback execution;
3773 In this case, Rx Event type is Transfer Complete */
3774 huart->RxEventType = HAL_UART_RXEVENT_TC;
3775
3776 /* Check current reception Mode :
3777 If Reception till IDLE event has been selected : use Rx Event callback */
3778 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3779 {
3780 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3781 /*Call registered Rx Event callback*/
3782 huart->RxEventCallback(huart, huart->RxXferSize);
3783 #else
3784 /*Call legacy weak Rx Event callback*/
3785 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
3786 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3787 }
3788 else
3789 {
3790 /* In other cases : use Rx Complete callback */
3791 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3792 /*Call registered Rx complete callback*/
3793 huart->RxCpltCallback(huart);
3794 #else
3795 /*Call legacy weak Rx complete callback*/
3796 HAL_UART_RxCpltCallback(huart);
3797 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3798 }
3799 }
3800
3801 /**
3802 * @brief DMA UART receive process half complete callback.
3803 * @param hdma DMA handle.
3804 * @retval None
3805 */
UART_DMARxHalfCplt(DMA_HandleTypeDef * hdma)3806 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
3807 {
3808 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3809
3810 /* Initialize type of RxEvent that correspond to RxEvent callback execution;
3811 In this case, Rx Event type is Half Transfer */
3812 huart->RxEventType = HAL_UART_RXEVENT_HT;
3813
3814 /* Check current reception Mode :
3815 If Reception till IDLE event has been selected : use Rx Event callback */
3816 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
3817 {
3818 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3819 /*Call registered Rx Event callback*/
3820 huart->RxEventCallback(huart, huart->RxXferSize / 2U);
3821 #else
3822 /*Call legacy weak Rx Event callback*/
3823 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize / 2U);
3824 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3825 }
3826 else
3827 {
3828 /* In other cases : use Rx Half Complete callback */
3829 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3830 /*Call registered Rx Half complete callback*/
3831 huart->RxHalfCpltCallback(huart);
3832 #else
3833 /*Call legacy weak Rx Half complete callback*/
3834 HAL_UART_RxHalfCpltCallback(huart);
3835 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3836 }
3837 }
3838
3839 /**
3840 * @brief DMA UART communication error callback.
3841 * @param hdma DMA handle.
3842 * @retval None
3843 */
UART_DMAError(DMA_HandleTypeDef * hdma)3844 static void UART_DMAError(DMA_HandleTypeDef *hdma)
3845 {
3846 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3847
3848 const HAL_UART_StateTypeDef gstate = huart->gState;
3849 const HAL_UART_StateTypeDef rxstate = huart->RxState;
3850
3851 /* Stop UART DMA Tx request if ongoing */
3852 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
3853 (gstate == HAL_UART_STATE_BUSY_TX))
3854 {
3855 huart->TxXferCount = 0U;
3856 UART_EndTxTransfer(huart);
3857 }
3858
3859 /* Stop UART DMA Rx request if ongoing */
3860 if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
3861 (rxstate == HAL_UART_STATE_BUSY_RX))
3862 {
3863 huart->RxXferCount = 0U;
3864 UART_EndRxTransfer(huart);
3865 }
3866
3867 huart->ErrorCode |= HAL_UART_ERROR_DMA;
3868
3869 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3870 /*Call registered error callback*/
3871 huart->ErrorCallback(huart);
3872 #else
3873 /*Call legacy weak error callback*/
3874 HAL_UART_ErrorCallback(huart);
3875 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3876 }
3877
3878 /**
3879 * @brief DMA UART communication abort callback, when initiated by HAL services on Error
3880 * (To be called at end of DMA Abort procedure following error occurrence).
3881 * @param hdma DMA handle.
3882 * @retval None
3883 */
UART_DMAAbortOnError(DMA_HandleTypeDef * hdma)3884 static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
3885 {
3886 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3887 huart->RxXferCount = 0U;
3888 huart->TxXferCount = 0U;
3889
3890 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3891 /*Call registered error callback*/
3892 huart->ErrorCallback(huart);
3893 #else
3894 /*Call legacy weak error callback*/
3895 HAL_UART_ErrorCallback(huart);
3896 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3897 }
3898
3899 /**
3900 * @brief DMA UART Tx communication abort callback, when initiated by user
3901 * (To be called at end of DMA Tx Abort procedure following user abort request).
3902 * @note When this callback is executed, User Abort complete call back is called only if no
3903 * Abort still ongoing for Rx DMA Handle.
3904 * @param hdma DMA handle.
3905 * @retval None
3906 */
UART_DMATxAbortCallback(DMA_HandleTypeDef * hdma)3907 static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
3908 {
3909 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3910
3911 huart->hdmatx->XferAbortCallback = NULL;
3912
3913 /* Check if an Abort process is still ongoing */
3914 if (huart->hdmarx != NULL)
3915 {
3916 if (huart->hdmarx->XferAbortCallback != NULL)
3917 {
3918 return;
3919 }
3920 }
3921
3922 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
3923 huart->TxXferCount = 0U;
3924 huart->RxXferCount = 0U;
3925
3926 /* Reset errorCode */
3927 huart->ErrorCode = HAL_UART_ERROR_NONE;
3928
3929 /* Clear the Error flags in the ICR register */
3930 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3931
3932 /* Flush the whole TX FIFO (if needed) */
3933 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
3934 {
3935 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
3936 }
3937
3938 /* Restore huart->gState and huart->RxState to Ready */
3939 huart->gState = HAL_UART_STATE_READY;
3940 huart->RxState = HAL_UART_STATE_READY;
3941 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
3942
3943 /* Call user Abort complete callback */
3944 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3945 /* Call registered Abort complete callback */
3946 huart->AbortCpltCallback(huart);
3947 #else
3948 /* Call legacy weak Abort complete callback */
3949 HAL_UART_AbortCpltCallback(huart);
3950 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3951 }
3952
3953
3954 /**
3955 * @brief DMA UART Rx communication abort callback, when initiated by user
3956 * (To be called at end of DMA Rx Abort procedure following user abort request).
3957 * @note When this callback is executed, User Abort complete call back is called only if no
3958 * Abort still ongoing for Tx DMA Handle.
3959 * @param hdma DMA handle.
3960 * @retval None
3961 */
UART_DMARxAbortCallback(DMA_HandleTypeDef * hdma)3962 static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
3963 {
3964 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3965
3966 huart->hdmarx->XferAbortCallback = NULL;
3967
3968 /* Check if an Abort process is still ongoing */
3969 if (huart->hdmatx != NULL)
3970 {
3971 if (huart->hdmatx->XferAbortCallback != NULL)
3972 {
3973 return;
3974 }
3975 }
3976
3977 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
3978 huart->TxXferCount = 0U;
3979 huart->RxXferCount = 0U;
3980
3981 /* Reset errorCode */
3982 huart->ErrorCode = HAL_UART_ERROR_NONE;
3983
3984 /* Clear the Error flags in the ICR register */
3985 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3986
3987 /* Discard the received data */
3988 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3989
3990 /* Restore huart->gState and huart->RxState to Ready */
3991 huart->gState = HAL_UART_STATE_READY;
3992 huart->RxState = HAL_UART_STATE_READY;
3993 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
3994
3995 /* Call user Abort complete callback */
3996 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3997 /* Call registered Abort complete callback */
3998 huart->AbortCpltCallback(huart);
3999 #else
4000 /* Call legacy weak Abort complete callback */
4001 HAL_UART_AbortCpltCallback(huart);
4002 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4003 }
4004
4005
4006 /**
4007 * @brief DMA UART Tx communication abort callback, when initiated by user by a call to
4008 * HAL_UART_AbortTransmit_IT API (Abort only Tx transfer)
4009 * (This callback is executed at end of DMA Tx Abort procedure following user abort request,
4010 * and leads to user Tx Abort Complete callback execution).
4011 * @param hdma DMA handle.
4012 * @retval None
4013 */
UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef * hdma)4014 static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
4015 {
4016 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
4017
4018 huart->TxXferCount = 0U;
4019
4020 /* Flush the whole TX FIFO (if needed) */
4021 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
4022 {
4023 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
4024 }
4025
4026 /* Restore huart->gState to Ready */
4027 huart->gState = HAL_UART_STATE_READY;
4028
4029 /* Call user Abort complete callback */
4030 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4031 /* Call registered Abort Transmit Complete Callback */
4032 huart->AbortTransmitCpltCallback(huart);
4033 #else
4034 /* Call legacy weak Abort Transmit Complete Callback */
4035 HAL_UART_AbortTransmitCpltCallback(huart);
4036 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4037 }
4038
4039 /**
4040 * @brief DMA UART Rx communication abort callback, when initiated by user by a call to
4041 * HAL_UART_AbortReceive_IT API (Abort only Rx transfer)
4042 * (This callback is executed at end of DMA Rx Abort procedure following user abort request,
4043 * and leads to user Rx Abort Complete callback execution).
4044 * @param hdma DMA handle.
4045 * @retval None
4046 */
UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef * hdma)4047 static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
4048 {
4049 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
4050
4051 huart->RxXferCount = 0U;
4052
4053 /* Clear the Error flags in the ICR register */
4054 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
4055
4056 /* Discard the received data */
4057 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4058
4059 /* Restore huart->RxState to Ready */
4060 huart->RxState = HAL_UART_STATE_READY;
4061 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
4062
4063 /* Call user Abort complete callback */
4064 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4065 /* Call registered Abort Receive Complete Callback */
4066 huart->AbortReceiveCpltCallback(huart);
4067 #else
4068 /* Call legacy weak Abort Receive Complete Callback */
4069 HAL_UART_AbortReceiveCpltCallback(huart);
4070 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4071 }
4072
4073 /**
4074 * @brief TX interrupt handler for 7 or 8 bits data word length .
4075 * @note Function is called under interruption only, once
4076 * interruptions have been enabled by HAL_UART_Transmit_IT().
4077 * @param huart UART handle.
4078 * @retval None
4079 */
UART_TxISR_8BIT(UART_HandleTypeDef * huart)4080 static void UART_TxISR_8BIT(UART_HandleTypeDef *huart)
4081 {
4082 /* Check that a Tx process is ongoing */
4083 if (huart->gState == HAL_UART_STATE_BUSY_TX)
4084 {
4085 if (huart->TxXferCount == 0U)
4086 {
4087 /* Disable the UART Transmit Data Register Empty Interrupt */
4088 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
4089
4090 /* Enable the UART Transmit Complete Interrupt */
4091 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
4092 }
4093 else
4094 {
4095 huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF);
4096 huart->pTxBuffPtr++;
4097 huart->TxXferCount--;
4098 }
4099 }
4100 }
4101
4102 /**
4103 * @brief TX interrupt handler for 9 bits data word length.
4104 * @note Function is called under interruption only, once
4105 * interruptions have been enabled by HAL_UART_Transmit_IT().
4106 * @param huart UART handle.
4107 * @retval None
4108 */
UART_TxISR_16BIT(UART_HandleTypeDef * huart)4109 static void UART_TxISR_16BIT(UART_HandleTypeDef *huart)
4110 {
4111 const uint16_t *tmp;
4112
4113 /* Check that a Tx process is ongoing */
4114 if (huart->gState == HAL_UART_STATE_BUSY_TX)
4115 {
4116 if (huart->TxXferCount == 0U)
4117 {
4118 /* Disable the UART Transmit Data Register Empty Interrupt */
4119 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
4120
4121 /* Enable the UART Transmit Complete Interrupt */
4122 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
4123 }
4124 else
4125 {
4126 tmp = (const uint16_t *) huart->pTxBuffPtr;
4127 huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL);
4128 huart->pTxBuffPtr += 2U;
4129 huart->TxXferCount--;
4130 }
4131 }
4132 }
4133
4134 /**
4135 * @brief TX interrupt handler for 7 or 8 bits data word length and FIFO mode is enabled.
4136 * @note Function is called under interruption only, once
4137 * interruptions have been enabled by HAL_UART_Transmit_IT().
4138 * @param huart UART handle.
4139 * @retval None
4140 */
UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef * huart)4141 static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart)
4142 {
4143 uint16_t nb_tx_data;
4144
4145 /* Check that a Tx process is ongoing */
4146 if (huart->gState == HAL_UART_STATE_BUSY_TX)
4147 {
4148 for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
4149 {
4150 if (huart->TxXferCount == 0U)
4151 {
4152 /* Disable the TX FIFO threshold interrupt */
4153 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
4154
4155 /* Enable the UART Transmit Complete Interrupt */
4156 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
4157
4158 break; /* force exit loop */
4159 }
4160 else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U)
4161 {
4162 huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF);
4163 huart->pTxBuffPtr++;
4164 huart->TxXferCount--;
4165 }
4166 else
4167 {
4168 /* Nothing to do */
4169 }
4170 }
4171 }
4172 }
4173
4174 /**
4175 * @brief TX interrupt handler for 9 bits data word length and FIFO mode is enabled.
4176 * @note Function is called under interruption only, once
4177 * interruptions have been enabled by HAL_UART_Transmit_IT().
4178 * @param huart UART handle.
4179 * @retval None
4180 */
UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef * huart)4181 static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart)
4182 {
4183 const uint16_t *tmp;
4184 uint16_t nb_tx_data;
4185
4186 /* Check that a Tx process is ongoing */
4187 if (huart->gState == HAL_UART_STATE_BUSY_TX)
4188 {
4189 for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
4190 {
4191 if (huart->TxXferCount == 0U)
4192 {
4193 /* Disable the TX FIFO threshold interrupt */
4194 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
4195
4196 /* Enable the UART Transmit Complete Interrupt */
4197 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
4198
4199 break; /* force exit loop */
4200 }
4201 else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U)
4202 {
4203 tmp = (const uint16_t *) huart->pTxBuffPtr;
4204 huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL);
4205 huart->pTxBuffPtr += 2U;
4206 huart->TxXferCount--;
4207 }
4208 else
4209 {
4210 /* Nothing to do */
4211 }
4212 }
4213 }
4214 }
4215
4216 /**
4217 * @brief Wrap up transmission in non-blocking mode.
4218 * @param huart pointer to a UART_HandleTypeDef structure that contains
4219 * the configuration information for the specified UART module.
4220 * @retval None
4221 */
UART_EndTransmit_IT(UART_HandleTypeDef * huart)4222 static void UART_EndTransmit_IT(UART_HandleTypeDef *huart)
4223 {
4224 /* Disable the UART Transmit Complete Interrupt */
4225 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TCIE);
4226
4227 /* Tx process is ended, restore huart->gState to Ready */
4228 huart->gState = HAL_UART_STATE_READY;
4229
4230 /* Cleat TxISR function pointer */
4231 huart->TxISR = NULL;
4232
4233 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4234 /*Call registered Tx complete callback*/
4235 huart->TxCpltCallback(huart);
4236 #else
4237 /*Call legacy weak Tx complete callback*/
4238 HAL_UART_TxCpltCallback(huart);
4239 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4240 }
4241
4242 /**
4243 * @brief RX interrupt handler for 7 or 8 bits data word length .
4244 * @param huart UART handle.
4245 * @retval None
4246 */
UART_RxISR_8BIT(UART_HandleTypeDef * huart)4247 static void UART_RxISR_8BIT(UART_HandleTypeDef *huart)
4248 {
4249 uint16_t uhMask = huart->Mask;
4250 uint16_t uhdata;
4251
4252 /* Check that a Rx process is ongoing */
4253 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
4254 {
4255 uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
4256 *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
4257 huart->pRxBuffPtr++;
4258 huart->RxXferCount--;
4259
4260 if (huart->RxXferCount == 0U)
4261 {
4262 /* Disable the UART Parity Error Interrupt and RXNE interrupts */
4263 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
4264
4265 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
4266 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
4267
4268 /* Rx process is completed, restore huart->RxState to Ready */
4269 huart->RxState = HAL_UART_STATE_READY;
4270
4271 /* Clear RxISR function pointer */
4272 huart->RxISR = NULL;
4273
4274 /* Initialize type of RxEvent to Transfer Complete */
4275 huart->RxEventType = HAL_UART_RXEVENT_TC;
4276
4277 if (!(IS_LPUART_INSTANCE(huart->Instance)))
4278 {
4279 /* Check that USART RTOEN bit is set */
4280 if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
4281 {
4282 /* Enable the UART Receiver Timeout Interrupt */
4283 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
4284 }
4285 }
4286
4287 /* Check current reception Mode :
4288 If Reception till IDLE event has been selected : */
4289 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
4290 {
4291 /* Set reception type to Standard */
4292 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
4293
4294 /* Disable IDLE interrupt */
4295 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
4296
4297 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
4298 {
4299 /* Clear IDLE Flag */
4300 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
4301 }
4302
4303 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4304 /*Call registered Rx Event callback*/
4305 huart->RxEventCallback(huart, huart->RxXferSize);
4306 #else
4307 /*Call legacy weak Rx Event callback*/
4308 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
4309 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
4310 }
4311 else
4312 {
4313 /* Standard reception API called */
4314 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4315 /*Call registered Rx complete callback*/
4316 huart->RxCpltCallback(huart);
4317 #else
4318 /*Call legacy weak Rx complete callback*/
4319 HAL_UART_RxCpltCallback(huart);
4320 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4321 }
4322 }
4323 }
4324 else
4325 {
4326 /* Clear RXNE interrupt flag */
4327 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4328 }
4329 }
4330
4331 /**
4332 * @brief RX interrupt handler for 9 bits data word length .
4333 * @note Function is called under interruption only, once
4334 * interruptions have been enabled by HAL_UART_Receive_IT()
4335 * @param huart UART handle.
4336 * @retval None
4337 */
UART_RxISR_16BIT(UART_HandleTypeDef * huart)4338 static void UART_RxISR_16BIT(UART_HandleTypeDef *huart)
4339 {
4340 uint16_t *tmp;
4341 uint16_t uhMask = huart->Mask;
4342 uint16_t uhdata;
4343
4344 /* Check that a Rx process is ongoing */
4345 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
4346 {
4347 uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
4348 tmp = (uint16_t *) huart->pRxBuffPtr ;
4349 *tmp = (uint16_t)(uhdata & uhMask);
4350 huart->pRxBuffPtr += 2U;
4351 huart->RxXferCount--;
4352
4353 if (huart->RxXferCount == 0U)
4354 {
4355 /* Disable the UART Parity Error Interrupt and RXNE interrupt*/
4356 ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
4357
4358 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
4359 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
4360
4361 /* Rx process is completed, restore huart->RxState to Ready */
4362 huart->RxState = HAL_UART_STATE_READY;
4363
4364 /* Clear RxISR function pointer */
4365 huart->RxISR = NULL;
4366
4367 /* Initialize type of RxEvent to Transfer Complete */
4368 huart->RxEventType = HAL_UART_RXEVENT_TC;
4369
4370 if (!(IS_LPUART_INSTANCE(huart->Instance)))
4371 {
4372 /* Check that USART RTOEN bit is set */
4373 if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
4374 {
4375 /* Enable the UART Receiver Timeout Interrupt */
4376 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
4377 }
4378 }
4379
4380 /* Check current reception Mode :
4381 If Reception till IDLE event has been selected : */
4382 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
4383 {
4384 /* Set reception type to Standard */
4385 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
4386
4387 /* Disable IDLE interrupt */
4388 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
4389
4390 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
4391 {
4392 /* Clear IDLE Flag */
4393 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
4394 }
4395
4396 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4397 /*Call registered Rx Event callback*/
4398 huart->RxEventCallback(huart, huart->RxXferSize);
4399 #else
4400 /*Call legacy weak Rx Event callback*/
4401 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
4402 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
4403 }
4404 else
4405 {
4406 /* Standard reception API called */
4407 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4408 /*Call registered Rx complete callback*/
4409 huart->RxCpltCallback(huart);
4410 #else
4411 /*Call legacy weak Rx complete callback*/
4412 HAL_UART_RxCpltCallback(huart);
4413 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4414 }
4415 }
4416 }
4417 else
4418 {
4419 /* Clear RXNE interrupt flag */
4420 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4421 }
4422 }
4423
4424 /**
4425 * @brief RX interrupt handler for 7 or 8 bits data word length and FIFO mode is enabled.
4426 * @note Function is called under interruption only, once
4427 * interruptions have been enabled by HAL_UART_Receive_IT()
4428 * @param huart UART handle.
4429 * @retval None
4430 */
UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef * huart)4431 static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart)
4432 {
4433 uint16_t uhMask = huart->Mask;
4434 uint16_t uhdata;
4435 uint16_t nb_rx_data;
4436 uint16_t rxdatacount;
4437 uint32_t isrflags = READ_REG(huart->Instance->ISR);
4438 uint32_t cr1its = READ_REG(huart->Instance->CR1);
4439 uint32_t cr3its = READ_REG(huart->Instance->CR3);
4440
4441 /* Check that a Rx process is ongoing */
4442 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
4443 {
4444 nb_rx_data = huart->NbRxDataToProcess;
4445 while ((nb_rx_data > 0U) && ((isrflags & USART_ISR_RXNE_RXFNE) != 0U))
4446 {
4447 uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
4448 *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
4449 huart->pRxBuffPtr++;
4450 huart->RxXferCount--;
4451 isrflags = READ_REG(huart->Instance->ISR);
4452
4453 /* If some non blocking errors occurred */
4454 if ((isrflags & (USART_ISR_PE | USART_ISR_FE | USART_ISR_NE)) != 0U)
4455 {
4456 /* UART parity error interrupt occurred -------------------------------------*/
4457 if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
4458 {
4459 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
4460
4461 huart->ErrorCode |= HAL_UART_ERROR_PE;
4462 }
4463
4464 /* UART frame error interrupt occurred --------------------------------------*/
4465 if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
4466 {
4467 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
4468
4469 huart->ErrorCode |= HAL_UART_ERROR_FE;
4470 }
4471
4472 /* UART noise error interrupt occurred --------------------------------------*/
4473 if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
4474 {
4475 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
4476
4477 huart->ErrorCode |= HAL_UART_ERROR_NE;
4478 }
4479
4480 /* Call UART Error Call back function if need be ----------------------------*/
4481 if (huart->ErrorCode != HAL_UART_ERROR_NONE)
4482 {
4483 /* Non Blocking error : transfer could go on.
4484 Error is notified to user through user error callback */
4485 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4486 /*Call registered error callback*/
4487 huart->ErrorCallback(huart);
4488 #else
4489 /*Call legacy weak error callback*/
4490 HAL_UART_ErrorCallback(huart);
4491 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4492 huart->ErrorCode = HAL_UART_ERROR_NONE;
4493 }
4494 }
4495
4496 if (huart->RxXferCount == 0U)
4497 {
4498 /* Disable the UART Parity Error Interrupt and RXFT interrupt*/
4499 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
4500
4501 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error)
4502 and RX FIFO Threshold interrupt */
4503 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
4504
4505 /* Rx process is completed, restore huart->RxState to Ready */
4506 huart->RxState = HAL_UART_STATE_READY;
4507
4508 /* Clear RxISR function pointer */
4509 huart->RxISR = NULL;
4510
4511 /* Initialize type of RxEvent to Transfer Complete */
4512 huart->RxEventType = HAL_UART_RXEVENT_TC;
4513
4514 if (!(IS_LPUART_INSTANCE(huart->Instance)))
4515 {
4516 /* Check that USART RTOEN bit is set */
4517 if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
4518 {
4519 /* Enable the UART Receiver Timeout Interrupt */
4520 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
4521 }
4522 }
4523
4524 /* Check current reception Mode :
4525 If Reception till IDLE event has been selected : */
4526 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
4527 {
4528 /* Set reception type to Standard */
4529 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
4530
4531 /* Disable IDLE interrupt */
4532 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
4533
4534 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
4535 {
4536 /* Clear IDLE Flag */
4537 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
4538 }
4539
4540 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4541 /*Call registered Rx Event callback*/
4542 huart->RxEventCallback(huart, huart->RxXferSize);
4543 #else
4544 /*Call legacy weak Rx Event callback*/
4545 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
4546 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
4547 }
4548 else
4549 {
4550 /* Standard reception API called */
4551 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4552 /*Call registered Rx complete callback*/
4553 huart->RxCpltCallback(huart);
4554 #else
4555 /*Call legacy weak Rx complete callback*/
4556 HAL_UART_RxCpltCallback(huart);
4557 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4558 }
4559 }
4560 }
4561
4562 /* When remaining number of bytes to receive is less than the RX FIFO
4563 threshold, next incoming frames are processed as if FIFO mode was
4564 disabled (i.e. one interrupt per received frame).
4565 */
4566 rxdatacount = huart->RxXferCount;
4567 if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess))
4568 {
4569 /* Disable the UART RXFT interrupt*/
4570 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
4571
4572 /* Update the RxISR function pointer */
4573 huart->RxISR = UART_RxISR_8BIT;
4574
4575 /* Enable the UART Data Register Not Empty interrupt */
4576 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
4577 }
4578 }
4579 else
4580 {
4581 /* Clear RXNE interrupt flag */
4582 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4583 }
4584 }
4585
4586 /**
4587 * @brief RX interrupt handler for 9 bits data word length and FIFO mode is enabled.
4588 * @note Function is called under interruption only, once
4589 * interruptions have been enabled by HAL_UART_Receive_IT()
4590 * @param huart UART handle.
4591 * @retval None
4592 */
UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef * huart)4593 static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart)
4594 {
4595 uint16_t *tmp;
4596 uint16_t uhMask = huart->Mask;
4597 uint16_t uhdata;
4598 uint16_t nb_rx_data;
4599 uint16_t rxdatacount;
4600 uint32_t isrflags = READ_REG(huart->Instance->ISR);
4601 uint32_t cr1its = READ_REG(huart->Instance->CR1);
4602 uint32_t cr3its = READ_REG(huart->Instance->CR3);
4603
4604 /* Check that a Rx process is ongoing */
4605 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
4606 {
4607 nb_rx_data = huart->NbRxDataToProcess;
4608 while ((nb_rx_data > 0U) && ((isrflags & USART_ISR_RXNE_RXFNE) != 0U))
4609 {
4610 uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
4611 tmp = (uint16_t *) huart->pRxBuffPtr ;
4612 *tmp = (uint16_t)(uhdata & uhMask);
4613 huart->pRxBuffPtr += 2U;
4614 huart->RxXferCount--;
4615 isrflags = READ_REG(huart->Instance->ISR);
4616
4617 /* If some non blocking errors occurred */
4618 if ((isrflags & (USART_ISR_PE | USART_ISR_FE | USART_ISR_NE)) != 0U)
4619 {
4620 /* UART parity error interrupt occurred -------------------------------------*/
4621 if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
4622 {
4623 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
4624
4625 huart->ErrorCode |= HAL_UART_ERROR_PE;
4626 }
4627
4628 /* UART frame error interrupt occurred --------------------------------------*/
4629 if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
4630 {
4631 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
4632
4633 huart->ErrorCode |= HAL_UART_ERROR_FE;
4634 }
4635
4636 /* UART noise error interrupt occurred --------------------------------------*/
4637 if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
4638 {
4639 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
4640
4641 huart->ErrorCode |= HAL_UART_ERROR_NE;
4642 }
4643
4644 /* Call UART Error Call back function if need be ----------------------------*/
4645 if (huart->ErrorCode != HAL_UART_ERROR_NONE)
4646 {
4647 /* Non Blocking error : transfer could go on.
4648 Error is notified to user through user error callback */
4649 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4650 /*Call registered error callback*/
4651 huart->ErrorCallback(huart);
4652 #else
4653 /*Call legacy weak error callback*/
4654 HAL_UART_ErrorCallback(huart);
4655 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4656 huart->ErrorCode = HAL_UART_ERROR_NONE;
4657 }
4658 }
4659
4660 if (huart->RxXferCount == 0U)
4661 {
4662 /* Disable the UART Parity Error Interrupt and RXFT interrupt*/
4663 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
4664
4665 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error)
4666 and RX FIFO Threshold interrupt */
4667 ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
4668
4669 /* Rx process is completed, restore huart->RxState to Ready */
4670 huart->RxState = HAL_UART_STATE_READY;
4671
4672 /* Clear RxISR function pointer */
4673 huart->RxISR = NULL;
4674
4675 /* Initialize type of RxEvent to Transfer Complete */
4676 huart->RxEventType = HAL_UART_RXEVENT_TC;
4677
4678 if (!(IS_LPUART_INSTANCE(huart->Instance)))
4679 {
4680 /* Check that USART RTOEN bit is set */
4681 if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
4682 {
4683 /* Enable the UART Receiver Timeout Interrupt */
4684 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
4685 }
4686 }
4687
4688 /* Check current reception Mode :
4689 If Reception till IDLE event has been selected : */
4690 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
4691 {
4692 /* Set reception type to Standard */
4693 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
4694
4695 /* Disable IDLE interrupt */
4696 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
4697
4698 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
4699 {
4700 /* Clear IDLE Flag */
4701 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
4702 }
4703
4704 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4705 /*Call registered Rx Event callback*/
4706 huart->RxEventCallback(huart, huart->RxXferSize);
4707 #else
4708 /*Call legacy weak Rx Event callback*/
4709 HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
4710 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
4711 }
4712 else
4713 {
4714 /* Standard reception API called */
4715 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4716 /*Call registered Rx complete callback*/
4717 huart->RxCpltCallback(huart);
4718 #else
4719 /*Call legacy weak Rx complete callback*/
4720 HAL_UART_RxCpltCallback(huart);
4721 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4722 }
4723 }
4724 }
4725
4726 /* When remaining number of bytes to receive is less than the RX FIFO
4727 threshold, next incoming frames are processed as if FIFO mode was
4728 disabled (i.e. one interrupt per received frame).
4729 */
4730 rxdatacount = huart->RxXferCount;
4731 if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess))
4732 {
4733 /* Disable the UART RXFT interrupt*/
4734 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
4735
4736 /* Update the RxISR function pointer */
4737 huart->RxISR = UART_RxISR_16BIT;
4738
4739 /* Enable the UART Data Register Not Empty interrupt */
4740 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
4741 }
4742 }
4743 else
4744 {
4745 /* Clear RXNE interrupt flag */
4746 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4747 }
4748 }
4749
4750 /**
4751 * @}
4752 */
4753
4754 #endif /* HAL_UART_MODULE_ENABLED */
4755 /**
4756 * @}
4757 */
4758
4759 /**
4760 * @}
4761 */
4762
4763