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