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