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