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