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