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