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