1 /**
2 ******************************************************************************
3 * @file stm32f4xx_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 stream.
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 stream.
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 stream.
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 "stm32f4xx_hal.h"
259
260 /** @addtogroup STM32F4xx_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 manual
341 (RM0430 for STM32F4X3xx MCUs and RM0402 for STM32F412xx MCUs
342 RM0383 for STM32F411xC/E MCUs and RM0401 for STM32F410xx MCUs
343 RM0090 for STM32F4X5xx/STM32F4X7xx/STM32F429xx/STM32F439xx MCUs
344 RM0390 for STM32F446xx MCUs and RM0386 for STM32F469xx/STM32F479xx MCUs)).
345
346 @endverbatim
347 * @{
348 */
349
350 /**
351 * @brief Initializes the UART mode according to the specified parameters in
352 * the UART_InitTypeDef and create the associated handle.
353 * @param huart Pointer to a UART_HandleTypeDef structure that contains
354 * the configuration information for the specified UART module.
355 * @retval HAL status
356 */
HAL_UART_Init(UART_HandleTypeDef * huart)357 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
358 {
359 /* Check the UART handle allocation */
360 if (huart == NULL)
361 {
362 return HAL_ERROR;
363 }
364
365 /* Check the parameters */
366 if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
367 {
368 /* The hardware flow control is available only for USART1, USART2, USART3 and USART6.
369 Except for STM32F446xx devices, that is available for USART1, USART2, USART3, USART6, UART4 and UART5.
370 */
371 assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
372 assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
373 }
374 else
375 {
376 assert_param(IS_UART_INSTANCE(huart->Instance));
377 }
378 assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
379 assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
380
381 if (huart->gState == HAL_UART_STATE_RESET)
382 {
383 /* Allocate lock resource and initialize it */
384 huart->Lock = HAL_UNLOCKED;
385
386 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
387 UART_InitCallbacksToDefault(huart);
388
389 if (huart->MspInitCallback == NULL)
390 {
391 huart->MspInitCallback = HAL_UART_MspInit;
392 }
393
394 /* Init the low level hardware */
395 huart->MspInitCallback(huart);
396 #else
397 /* Init the low level hardware : GPIO, CLOCK */
398 HAL_UART_MspInit(huart);
399 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
400 }
401
402 huart->gState = HAL_UART_STATE_BUSY;
403
404 /* Disable the peripheral */
405 __HAL_UART_DISABLE(huart);
406
407 /* Set the UART Communication parameters */
408 UART_SetConfig(huart);
409
410 /* In asynchronous mode, the following bits must be kept cleared:
411 - LINEN and CLKEN bits in the USART_CR2 register,
412 - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
413 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
414 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
415
416 /* Enable the peripheral */
417 __HAL_UART_ENABLE(huart);
418
419 /* Initialize the UART state */
420 huart->ErrorCode = HAL_UART_ERROR_NONE;
421 huart->gState = HAL_UART_STATE_READY;
422 huart->RxState = HAL_UART_STATE_READY;
423 huart->RxEventType = HAL_UART_RXEVENT_TC;
424
425 return HAL_OK;
426 }
427
428 /**
429 * @brief Initializes the half-duplex mode according to the specified
430 * parameters in the UART_InitTypeDef and create the associated handle.
431 * @param huart Pointer to a UART_HandleTypeDef structure that contains
432 * the configuration information for the specified UART module.
433 * @retval HAL status
434 */
HAL_HalfDuplex_Init(UART_HandleTypeDef * huart)435 HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart)
436 {
437 /* Check the UART handle allocation */
438 if (huart == NULL)
439 {
440 return HAL_ERROR;
441 }
442
443 /* Check the parameters */
444 assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance));
445 assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
446 assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
447
448 if (huart->gState == HAL_UART_STATE_RESET)
449 {
450 /* Allocate lock resource and initialize it */
451 huart->Lock = HAL_UNLOCKED;
452
453 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
454 UART_InitCallbacksToDefault(huart);
455
456 if (huart->MspInitCallback == NULL)
457 {
458 huart->MspInitCallback = HAL_UART_MspInit;
459 }
460
461 /* Init the low level hardware */
462 huart->MspInitCallback(huart);
463 #else
464 /* Init the low level hardware : GPIO, CLOCK */
465 HAL_UART_MspInit(huart);
466 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
467 }
468
469 huart->gState = HAL_UART_STATE_BUSY;
470
471 /* Disable the peripheral */
472 __HAL_UART_DISABLE(huart);
473
474 /* Set the UART Communication parameters */
475 UART_SetConfig(huart);
476
477 /* In half-duplex mode, the following bits must be kept cleared:
478 - LINEN and CLKEN bits in the USART_CR2 register,
479 - SCEN and IREN bits in the USART_CR3 register.*/
480 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
481 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN));
482
483 /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
484 SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
485
486 /* Enable the peripheral */
487 __HAL_UART_ENABLE(huart);
488
489 /* Initialize the UART state*/
490 huart->ErrorCode = HAL_UART_ERROR_NONE;
491 huart->gState = HAL_UART_STATE_READY;
492 huart->RxState = HAL_UART_STATE_READY;
493 huart->RxEventType = HAL_UART_RXEVENT_TC;
494
495 return HAL_OK;
496 }
497
498 /**
499 * @brief Initializes the LIN mode according to the specified
500 * parameters in the UART_InitTypeDef and create the associated handle.
501 * @param huart Pointer to a UART_HandleTypeDef structure that contains
502 * the configuration information for the specified UART module.
503 * @param BreakDetectLength Specifies the LIN break detection length.
504 * This parameter can be one of the following values:
505 * @arg UART_LINBREAKDETECTLENGTH_10B: 10-bit break detection
506 * @arg UART_LINBREAKDETECTLENGTH_11B: 11-bit break detection
507 * @retval HAL status
508 */
HAL_LIN_Init(UART_HandleTypeDef * huart,uint32_t BreakDetectLength)509 HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength)
510 {
511 /* Check the UART handle allocation */
512 if (huart == NULL)
513 {
514 return HAL_ERROR;
515 }
516
517 /* Check the LIN UART instance */
518 assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
519
520 /* Check the Break detection length parameter */
521 assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength));
522 assert_param(IS_UART_LIN_WORD_LENGTH(huart->Init.WordLength));
523 assert_param(IS_UART_LIN_OVERSAMPLING(huart->Init.OverSampling));
524
525 if (huart->gState == HAL_UART_STATE_RESET)
526 {
527 /* Allocate lock resource and initialize it */
528 huart->Lock = HAL_UNLOCKED;
529
530 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
531 UART_InitCallbacksToDefault(huart);
532
533 if (huart->MspInitCallback == NULL)
534 {
535 huart->MspInitCallback = HAL_UART_MspInit;
536 }
537
538 /* Init the low level hardware */
539 huart->MspInitCallback(huart);
540 #else
541 /* Init the low level hardware : GPIO, CLOCK */
542 HAL_UART_MspInit(huart);
543 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
544 }
545
546 huart->gState = HAL_UART_STATE_BUSY;
547
548 /* Disable the peripheral */
549 __HAL_UART_DISABLE(huart);
550
551 /* Set the UART Communication parameters */
552 UART_SetConfig(huart);
553
554 /* In LIN mode, the following bits must be kept cleared:
555 - CLKEN bits in the USART_CR2 register,
556 - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
557 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_CLKEN));
558 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN));
559
560 /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
561 SET_BIT(huart->Instance->CR2, USART_CR2_LINEN);
562
563 /* Set the USART LIN Break detection length. */
564 CLEAR_BIT(huart->Instance->CR2, USART_CR2_LBDL);
565 SET_BIT(huart->Instance->CR2, BreakDetectLength);
566
567 /* Enable the peripheral */
568 __HAL_UART_ENABLE(huart);
569
570 /* Initialize the UART state*/
571 huart->ErrorCode = HAL_UART_ERROR_NONE;
572 huart->gState = HAL_UART_STATE_READY;
573 huart->RxState = HAL_UART_STATE_READY;
574 huart->RxEventType = HAL_UART_RXEVENT_TC;
575
576 return HAL_OK;
577 }
578
579 /**
580 * @brief Initializes the Multi-Processor mode according to the specified
581 * parameters in the UART_InitTypeDef and create the associated handle.
582 * @param huart Pointer to a UART_HandleTypeDef structure that contains
583 * the configuration information for the specified UART module.
584 * @param Address USART address
585 * @param WakeUpMethod specifies the USART wake-up method.
586 * This parameter can be one of the following values:
587 * @arg UART_WAKEUPMETHOD_IDLELINE: Wake-up by an idle line detection
588 * @arg UART_WAKEUPMETHOD_ADDRESSMARK: Wake-up by an address mark
589 * @retval HAL status
590 */
HAL_MultiProcessor_Init(UART_HandleTypeDef * huart,uint8_t Address,uint32_t WakeUpMethod)591 HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod)
592 {
593 /* Check the UART handle allocation */
594 if (huart == NULL)
595 {
596 return HAL_ERROR;
597 }
598
599 /* Check the parameters */
600 assert_param(IS_UART_INSTANCE(huart->Instance));
601
602 /* Check the Address & wake up method parameters */
603 assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod));
604 assert_param(IS_UART_ADDRESS(Address));
605 assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
606 assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
607
608 if (huart->gState == HAL_UART_STATE_RESET)
609 {
610 /* Allocate lock resource and initialize it */
611 huart->Lock = HAL_UNLOCKED;
612
613 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
614 UART_InitCallbacksToDefault(huart);
615
616 if (huart->MspInitCallback == NULL)
617 {
618 huart->MspInitCallback = HAL_UART_MspInit;
619 }
620
621 /* Init the low level hardware */
622 huart->MspInitCallback(huart);
623 #else
624 /* Init the low level hardware : GPIO, CLOCK */
625 HAL_UART_MspInit(huart);
626 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
627 }
628
629 huart->gState = HAL_UART_STATE_BUSY;
630
631 /* Disable the peripheral */
632 __HAL_UART_DISABLE(huart);
633
634 /* Set the UART Communication parameters */
635 UART_SetConfig(huart);
636
637 /* In Multi-Processor mode, the following bits must be kept cleared:
638 - LINEN and CLKEN bits in the USART_CR2 register,
639 - SCEN, HDSEL and IREN bits in the USART_CR3 register */
640 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
641 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
642
643 /* Set the USART address node */
644 CLEAR_BIT(huart->Instance->CR2, USART_CR2_ADD);
645 SET_BIT(huart->Instance->CR2, Address);
646
647 /* Set the wake up method by setting the WAKE bit in the CR1 register */
648 CLEAR_BIT(huart->Instance->CR1, USART_CR1_WAKE);
649 SET_BIT(huart->Instance->CR1, WakeUpMethod);
650
651 /* Enable the peripheral */
652 __HAL_UART_ENABLE(huart);
653
654 /* Initialize the UART state */
655 huart->ErrorCode = HAL_UART_ERROR_NONE;
656 huart->gState = HAL_UART_STATE_READY;
657 huart->RxState = HAL_UART_STATE_READY;
658 huart->RxEventType = HAL_UART_RXEVENT_TC;
659
660 return HAL_OK;
661 }
662
663 /**
664 * @brief DeInitializes the UART peripheral.
665 * @param huart Pointer to a UART_HandleTypeDef structure that contains
666 * the configuration information for the specified UART module.
667 * @retval HAL status
668 */
HAL_UART_DeInit(UART_HandleTypeDef * huart)669 HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
670 {
671 /* Check the UART handle allocation */
672 if (huart == NULL)
673 {
674 return HAL_ERROR;
675 }
676
677 /* Check the parameters */
678 assert_param(IS_UART_INSTANCE(huart->Instance));
679
680 huart->gState = HAL_UART_STATE_BUSY;
681
682 /* Disable the Peripheral */
683 __HAL_UART_DISABLE(huart);
684
685 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
686 if (huart->MspDeInitCallback == NULL)
687 {
688 huart->MspDeInitCallback = HAL_UART_MspDeInit;
689 }
690 /* DeInit the low level hardware */
691 huart->MspDeInitCallback(huart);
692 #else
693 /* DeInit the low level hardware */
694 HAL_UART_MspDeInit(huart);
695 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
696
697 huart->ErrorCode = HAL_UART_ERROR_NONE;
698 huart->gState = HAL_UART_STATE_RESET;
699 huart->RxState = HAL_UART_STATE_RESET;
700 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
701 huart->RxEventType = HAL_UART_RXEVENT_TC;
702
703 /* Process Unlock */
704 __HAL_UNLOCK(huart);
705
706 return HAL_OK;
707 }
708
709 /**
710 * @brief UART MSP Init.
711 * @param huart Pointer to a UART_HandleTypeDef structure that contains
712 * the configuration information for the specified UART module.
713 * @retval None
714 */
HAL_UART_MspInit(UART_HandleTypeDef * huart)715 __weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
716 {
717 /* Prevent unused argument(s) compilation warning */
718 UNUSED(huart);
719 /* NOTE: This function should not be modified, when the callback is needed,
720 the HAL_UART_MspInit could be implemented in the user file
721 */
722 }
723
724 /**
725 * @brief UART MSP DeInit.
726 * @param huart Pointer to a UART_HandleTypeDef structure that contains
727 * the configuration information for the specified UART module.
728 * @retval None
729 */
HAL_UART_MspDeInit(UART_HandleTypeDef * huart)730 __weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
731 {
732 /* Prevent unused argument(s) compilation warning */
733 UNUSED(huart);
734 /* NOTE: This function should not be modified, when the callback is needed,
735 the HAL_UART_MspDeInit could be implemented in the user file
736 */
737 }
738
739 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
740 /**
741 * @brief Register a User UART Callback
742 * To be used instead of the weak predefined callback
743 * @note The HAL_UART_RegisterCallback() may be called before HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init(),
744 * HAL_MultiProcessor_Init() to register callbacks for HAL_UART_MSPINIT_CB_ID and HAL_UART_MSPDEINIT_CB_ID
745 * @param huart uart handle
746 * @param CallbackID ID of the callback to be registered
747 * This parameter can be one of the following values:
748 * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
749 * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
750 * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
751 * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
752 * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
753 * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
754 * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
755 * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
756 * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
757 * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
758 * @param pCallback pointer to the Callback function
759 * @retval HAL status
760 */
HAL_UART_RegisterCallback(UART_HandleTypeDef * huart,HAL_UART_CallbackIDTypeDef CallbackID,pUART_CallbackTypeDef pCallback)761 HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID,
762 pUART_CallbackTypeDef pCallback)
763 {
764 HAL_StatusTypeDef status = HAL_OK;
765
766 if (pCallback == NULL)
767 {
768 /* Update the error code */
769 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
770
771 return HAL_ERROR;
772 }
773
774 if (huart->gState == HAL_UART_STATE_READY)
775 {
776 switch (CallbackID)
777 {
778 case HAL_UART_TX_HALFCOMPLETE_CB_ID :
779 huart->TxHalfCpltCallback = pCallback;
780 break;
781
782 case HAL_UART_TX_COMPLETE_CB_ID :
783 huart->TxCpltCallback = pCallback;
784 break;
785
786 case HAL_UART_RX_HALFCOMPLETE_CB_ID :
787 huart->RxHalfCpltCallback = pCallback;
788 break;
789
790 case HAL_UART_RX_COMPLETE_CB_ID :
791 huart->RxCpltCallback = pCallback;
792 break;
793
794 case HAL_UART_ERROR_CB_ID :
795 huart->ErrorCallback = pCallback;
796 break;
797
798 case HAL_UART_ABORT_COMPLETE_CB_ID :
799 huart->AbortCpltCallback = pCallback;
800 break;
801
802 case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
803 huart->AbortTransmitCpltCallback = pCallback;
804 break;
805
806 case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
807 huart->AbortReceiveCpltCallback = pCallback;
808 break;
809
810 case HAL_UART_MSPINIT_CB_ID :
811 huart->MspInitCallback = pCallback;
812 break;
813
814 case HAL_UART_MSPDEINIT_CB_ID :
815 huart->MspDeInitCallback = pCallback;
816 break;
817
818 default :
819 /* Update the error code */
820 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
821
822 /* Return error status */
823 status = HAL_ERROR;
824 break;
825 }
826 }
827 else if (huart->gState == HAL_UART_STATE_RESET)
828 {
829 switch (CallbackID)
830 {
831 case HAL_UART_MSPINIT_CB_ID :
832 huart->MspInitCallback = pCallback;
833 break;
834
835 case HAL_UART_MSPDEINIT_CB_ID :
836 huart->MspDeInitCallback = pCallback;
837 break;
838
839 default :
840 /* Update the error code */
841 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
842
843 /* Return error status */
844 status = HAL_ERROR;
845 break;
846 }
847 }
848 else
849 {
850 /* Update the error code */
851 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
852
853 /* Return error status */
854 status = HAL_ERROR;
855 }
856
857 return status;
858 }
859
860 /**
861 * @brief Unregister an UART Callback
862 * UART callaback is redirected to the weak predefined callback
863 * @note The HAL_UART_UnRegisterCallback() may be called before HAL_UART_Init(), HAL_HalfDuplex_Init(),
864 * HAL_LIN_Init(), HAL_MultiProcessor_Init() to un-register callbacks for HAL_UART_MSPINIT_CB_ID
865 * and HAL_UART_MSPDEINIT_CB_ID
866 * @param huart uart handle
867 * @param CallbackID ID of the callback to be unregistered
868 * This parameter can be one of the following values:
869 * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
870 * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
871 * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
872 * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
873 * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
874 * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
875 * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
876 * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
877 * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
878 * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
879 * @retval HAL status
880 */
HAL_UART_UnRegisterCallback(UART_HandleTypeDef * huart,HAL_UART_CallbackIDTypeDef CallbackID)881 HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID)
882 {
883 HAL_StatusTypeDef status = HAL_OK;
884
885 if (HAL_UART_STATE_READY == huart->gState)
886 {
887 switch (CallbackID)
888 {
889 case HAL_UART_TX_HALFCOMPLETE_CB_ID :
890 huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
891 break;
892
893 case HAL_UART_TX_COMPLETE_CB_ID :
894 huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */
895 break;
896
897 case HAL_UART_RX_HALFCOMPLETE_CB_ID :
898 huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
899 break;
900
901 case HAL_UART_RX_COMPLETE_CB_ID :
902 huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */
903 break;
904
905 case HAL_UART_ERROR_CB_ID :
906 huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */
907 break;
908
909 case HAL_UART_ABORT_COMPLETE_CB_ID :
910 huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
911 break;
912
913 case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
914 huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
915 break;
916
917 case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
918 huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
919 break;
920
921 case HAL_UART_MSPINIT_CB_ID :
922 huart->MspInitCallback = HAL_UART_MspInit; /* Legacy weak MspInitCallback */
923 break;
924
925 case HAL_UART_MSPDEINIT_CB_ID :
926 huart->MspDeInitCallback = HAL_UART_MspDeInit; /* Legacy weak MspDeInitCallback */
927 break;
928
929 default :
930 /* Update the error code */
931 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
932
933 /* Return error status */
934 status = HAL_ERROR;
935 break;
936 }
937 }
938 else if (HAL_UART_STATE_RESET == huart->gState)
939 {
940 switch (CallbackID)
941 {
942 case HAL_UART_MSPINIT_CB_ID :
943 huart->MspInitCallback = HAL_UART_MspInit;
944 break;
945
946 case HAL_UART_MSPDEINIT_CB_ID :
947 huart->MspDeInitCallback = HAL_UART_MspDeInit;
948 break;
949
950 default :
951 /* Update the error code */
952 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
953
954 /* Return error status */
955 status = HAL_ERROR;
956 break;
957 }
958 }
959 else
960 {
961 /* Update the error code */
962 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
963
964 /* Return error status */
965 status = HAL_ERROR;
966 }
967
968 return status;
969 }
970
971 /**
972 * @brief Register a User UART Rx Event Callback
973 * To be used instead of the weak predefined callback
974 * @param huart Uart handle
975 * @param pCallback Pointer to the Rx Event Callback function
976 * @retval HAL status
977 */
HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef * huart,pUART_RxEventCallbackTypeDef pCallback)978 HAL_StatusTypeDef HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef *huart, pUART_RxEventCallbackTypeDef pCallback)
979 {
980 HAL_StatusTypeDef status = HAL_OK;
981
982 if (pCallback == NULL)
983 {
984 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
985
986 return HAL_ERROR;
987 }
988
989 /* Process locked */
990 __HAL_LOCK(huart);
991
992 if (huart->gState == HAL_UART_STATE_READY)
993 {
994 huart->RxEventCallback = pCallback;
995 }
996 else
997 {
998 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
999
1000 status = HAL_ERROR;
1001 }
1002
1003 /* Release Lock */
1004 __HAL_UNLOCK(huart);
1005
1006 return status;
1007 }
1008
1009 /**
1010 * @brief UnRegister the UART Rx Event Callback
1011 * UART Rx Event Callback is redirected to the weak HAL_UARTEx_RxEventCallback() predefined callback
1012 * @param huart Uart handle
1013 * @retval HAL status
1014 */
HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef * huart)1015 HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart)
1016 {
1017 HAL_StatusTypeDef status = HAL_OK;
1018
1019 /* Process locked */
1020 __HAL_LOCK(huart);
1021
1022 if (huart->gState == HAL_UART_STATE_READY)
1023 {
1024 huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak UART Rx Event Callback */
1025 }
1026 else
1027 {
1028 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
1029
1030 status = HAL_ERROR;
1031 }
1032
1033 /* Release Lock */
1034 __HAL_UNLOCK(huart);
1035 return status;
1036 }
1037 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
1038
1039 /**
1040 * @}
1041 */
1042
1043 /** @defgroup UART_Exported_Functions_Group2 IO operation functions
1044 * @brief UART Transmit and Receive functions
1045 *
1046 @verbatim
1047 ===============================================================================
1048 ##### IO operation functions #####
1049 ===============================================================================
1050 This subsection provides a set of functions allowing to manage the UART asynchronous
1051 and Half duplex data transfers.
1052
1053 (#) There are two modes of transfer:
1054 (+) Blocking mode: The communication is performed in polling mode.
1055 The HAL status of all data processing is returned by the same function
1056 after finishing transfer.
1057 (+) Non-Blocking mode: The communication is performed using Interrupts
1058 or DMA, these API's return the HAL status.
1059 The end of the data processing will be indicated through the
1060 dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
1061 using DMA mode.
1062 The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
1063 will be executed respectively at the end of the transmit or receive process
1064 The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected.
1065
1066 (#) Blocking mode API's are :
1067 (+) HAL_UART_Transmit()
1068 (+) HAL_UART_Receive()
1069
1070 (#) Non-Blocking mode API's with Interrupt are :
1071 (+) HAL_UART_Transmit_IT()
1072 (+) HAL_UART_Receive_IT()
1073 (+) HAL_UART_IRQHandler()
1074
1075 (#) Non-Blocking mode API's with DMA are :
1076 (+) HAL_UART_Transmit_DMA()
1077 (+) HAL_UART_Receive_DMA()
1078 (+) HAL_UART_DMAPause()
1079 (+) HAL_UART_DMAResume()
1080 (+) HAL_UART_DMAStop()
1081
1082 (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
1083 (+) HAL_UART_TxHalfCpltCallback()
1084 (+) HAL_UART_TxCpltCallback()
1085 (+) HAL_UART_RxHalfCpltCallback()
1086 (+) HAL_UART_RxCpltCallback()
1087 (+) HAL_UART_ErrorCallback()
1088
1089 (#) Non-Blocking mode transfers could be aborted using Abort API's :
1090 (+) HAL_UART_Abort()
1091 (+) HAL_UART_AbortTransmit()
1092 (+) HAL_UART_AbortReceive()
1093 (+) HAL_UART_Abort_IT()
1094 (+) HAL_UART_AbortTransmit_IT()
1095 (+) HAL_UART_AbortReceive_IT()
1096
1097 (#) For Abort services based on interrupts (HAL_UART_Abortxxx_IT), a set of Abort Complete Callbacks are provided:
1098 (+) HAL_UART_AbortCpltCallback()
1099 (+) HAL_UART_AbortTransmitCpltCallback()
1100 (+) HAL_UART_AbortReceiveCpltCallback()
1101
1102 (#) A Rx Event Reception Callback (Rx event notification) is available for Non_Blocking modes of enhanced reception services:
1103 (+) HAL_UARTEx_RxEventCallback()
1104
1105 (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
1106 Errors are handled as follows :
1107 (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
1108 to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception .
1109 Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type,
1110 and HAL_UART_ErrorCallback() user callback is executed. Transfer is kept ongoing on UART side.
1111 If user wants to abort it, Abort services should be called by user.
1112 (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
1113 This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
1114 Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback() user callback is executed.
1115
1116 -@- In the Half duplex communication, it is forbidden to run the transmit
1117 and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful.
1118
1119 @endverbatim
1120 * @{
1121 */
1122
1123 /**
1124 * @brief Sends an amount of data in blocking mode.
1125 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1126 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1127 * of u16 provided through pData.
1128 * @param huart Pointer to a UART_HandleTypeDef structure that contains
1129 * the configuration information for the specified UART module.
1130 * @param pData Pointer to data buffer (u8 or u16 data elements).
1131 * @param Size Amount of data elements (u8 or u16) to be sent
1132 * @param Timeout Timeout duration
1133 * @retval HAL status
1134 */
HAL_UART_Transmit(UART_HandleTypeDef * huart,const uint8_t * pData,uint16_t Size,uint32_t Timeout)1135 HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
1136 {
1137 const uint8_t *pdata8bits;
1138 const uint16_t *pdata16bits;
1139 uint32_t tickstart = 0U;
1140
1141 /* Check that a Tx process is not already ongoing */
1142 if (huart->gState == HAL_UART_STATE_READY)
1143 {
1144 if ((pData == NULL) || (Size == 0U))
1145 {
1146 return HAL_ERROR;
1147 }
1148
1149 huart->ErrorCode = HAL_UART_ERROR_NONE;
1150 huart->gState = HAL_UART_STATE_BUSY_TX;
1151
1152 /* Init tickstart for timeout management */
1153 tickstart = HAL_GetTick();
1154
1155 huart->TxXferSize = Size;
1156 huart->TxXferCount = Size;
1157
1158 /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
1159 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1160 {
1161 pdata8bits = NULL;
1162 pdata16bits = (const uint16_t *) pData;
1163 }
1164 else
1165 {
1166 pdata8bits = pData;
1167 pdata16bits = NULL;
1168 }
1169
1170 while (huart->TxXferCount > 0U)
1171 {
1172 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
1173 {
1174 huart->gState = HAL_UART_STATE_READY;
1175
1176 return HAL_TIMEOUT;
1177 }
1178 if (pdata8bits == NULL)
1179 {
1180 huart->Instance->DR = (uint16_t)(*pdata16bits & 0x01FFU);
1181 pdata16bits++;
1182 }
1183 else
1184 {
1185 huart->Instance->DR = (uint8_t)(*pdata8bits & 0xFFU);
1186 pdata8bits++;
1187 }
1188 huart->TxXferCount--;
1189 }
1190
1191 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
1192 {
1193 huart->gState = HAL_UART_STATE_READY;
1194
1195 return HAL_TIMEOUT;
1196 }
1197
1198 /* At end of Tx process, restore huart->gState to Ready */
1199 huart->gState = HAL_UART_STATE_READY;
1200
1201 return HAL_OK;
1202 }
1203 else
1204 {
1205 return HAL_BUSY;
1206 }
1207 }
1208
1209 /**
1210 * @brief Receives an amount of data in blocking mode.
1211 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1212 * the received data is handled as a set of u16. In this case, Size must indicate the number
1213 * of u16 available through pData.
1214 * @param huart Pointer to a UART_HandleTypeDef structure that contains
1215 * the configuration information for the specified UART module.
1216 * @param pData Pointer to data buffer (u8 or u16 data elements).
1217 * @param Size Amount of data elements (u8 or u16) to be received.
1218 * @param Timeout Timeout duration
1219 * @retval HAL status
1220 */
HAL_UART_Receive(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size,uint32_t Timeout)1221 HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
1222 {
1223 uint8_t *pdata8bits;
1224 uint16_t *pdata16bits;
1225 uint32_t tickstart = 0U;
1226
1227 /* Check that a Rx process is not already ongoing */
1228 if (huart->RxState == HAL_UART_STATE_READY)
1229 {
1230 if ((pData == NULL) || (Size == 0U))
1231 {
1232 return HAL_ERROR;
1233 }
1234
1235 huart->ErrorCode = HAL_UART_ERROR_NONE;
1236 huart->RxState = HAL_UART_STATE_BUSY_RX;
1237 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
1238
1239 /* Init tickstart for timeout management */
1240 tickstart = HAL_GetTick();
1241
1242 huart->RxXferSize = Size;
1243 huart->RxXferCount = Size;
1244
1245 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
1246 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1247 {
1248 pdata8bits = NULL;
1249 pdata16bits = (uint16_t *) pData;
1250 }
1251 else
1252 {
1253 pdata8bits = pData;
1254 pdata16bits = NULL;
1255 }
1256
1257 /* Check the remain data to be received */
1258 while (huart->RxXferCount > 0U)
1259 {
1260 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
1261 {
1262 huart->RxState = HAL_UART_STATE_READY;
1263
1264 return HAL_TIMEOUT;
1265 }
1266 if (pdata8bits == NULL)
1267 {
1268 *pdata16bits = (uint16_t)(huart->Instance->DR & 0x01FF);
1269 pdata16bits++;
1270 }
1271 else
1272 {
1273 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE)))
1274 {
1275 *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
1276 }
1277 else
1278 {
1279 *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
1280 }
1281 pdata8bits++;
1282 }
1283 huart->RxXferCount--;
1284 }
1285
1286 /* At end of Rx process, restore huart->RxState to Ready */
1287 huart->RxState = HAL_UART_STATE_READY;
1288
1289 return HAL_OK;
1290 }
1291 else
1292 {
1293 return HAL_BUSY;
1294 }
1295 }
1296
1297 /**
1298 * @brief Sends an amount of data in non blocking mode.
1299 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1300 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1301 * of u16 provided through pData.
1302 * @param huart Pointer to a UART_HandleTypeDef structure that contains
1303 * the configuration information for the specified UART module.
1304 * @param pData Pointer to data buffer (u8 or u16 data elements).
1305 * @param Size Amount of data elements (u8 or u16) to be sent
1306 * @retval HAL status
1307 */
HAL_UART_Transmit_IT(UART_HandleTypeDef * huart,const uint8_t * pData,uint16_t Size)1308 HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
1309 {
1310 /* Check that a Tx process is not already ongoing */
1311 if (huart->gState == HAL_UART_STATE_READY)
1312 {
1313 if ((pData == NULL) || (Size == 0U))
1314 {
1315 return HAL_ERROR;
1316 }
1317
1318 huart->pTxBuffPtr = pData;
1319 huart->TxXferSize = Size;
1320 huart->TxXferCount = Size;
1321
1322 huart->ErrorCode = HAL_UART_ERROR_NONE;
1323 huart->gState = HAL_UART_STATE_BUSY_TX;
1324
1325 /* Enable the UART Transmit data register empty Interrupt */
1326 __HAL_UART_ENABLE_IT(huart, UART_IT_TXE);
1327
1328 return HAL_OK;
1329 }
1330 else
1331 {
1332 return HAL_BUSY;
1333 }
1334 }
1335
1336 /**
1337 * @brief Receives an amount of data in non blocking mode.
1338 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1339 * the received data is handled as a set of u16. In this case, Size must indicate the number
1340 * of u16 available through pData.
1341 * @param huart Pointer to a UART_HandleTypeDef structure that contains
1342 * the configuration information for the specified UART module.
1343 * @param pData Pointer to data buffer (u8 or u16 data elements).
1344 * @param Size Amount of data elements (u8 or u16) to be received.
1345 * @retval HAL status
1346 */
HAL_UART_Receive_IT(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)1347 HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1348 {
1349 /* Check that a Rx process is not already ongoing */
1350 if (huart->RxState == HAL_UART_STATE_READY)
1351 {
1352 if ((pData == NULL) || (Size == 0U))
1353 {
1354 return HAL_ERROR;
1355 }
1356
1357 /* Set Reception type to Standard reception */
1358 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
1359
1360 return (UART_Start_Receive_IT(huart, pData, Size));
1361 }
1362 else
1363 {
1364 return HAL_BUSY;
1365 }
1366 }
1367
1368 /**
1369 * @brief Sends an amount of data in DMA mode.
1370 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1371 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1372 * of u16 provided through pData.
1373 * @param huart Pointer to a UART_HandleTypeDef structure that contains
1374 * the configuration information for the specified UART module.
1375 * @param pData Pointer to data buffer (u8 or u16 data elements).
1376 * @param Size Amount of data elements (u8 or u16) to be sent
1377 * @retval HAL status
1378 */
HAL_UART_Transmit_DMA(UART_HandleTypeDef * huart,const uint8_t * pData,uint16_t Size)1379 HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
1380 {
1381 const uint32_t *tmp;
1382
1383 /* Check that a Tx process is not already ongoing */
1384 if (huart->gState == HAL_UART_STATE_READY)
1385 {
1386 if ((pData == NULL) || (Size == 0U))
1387 {
1388 return HAL_ERROR;
1389 }
1390
1391 huart->pTxBuffPtr = pData;
1392 huart->TxXferSize = Size;
1393 huart->TxXferCount = Size;
1394
1395 huart->ErrorCode = HAL_UART_ERROR_NONE;
1396 huart->gState = HAL_UART_STATE_BUSY_TX;
1397
1398 /* Set the UART DMA transfer complete callback */
1399 huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
1400
1401 /* Set the UART DMA Half transfer complete callback */
1402 huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
1403
1404 /* Set the DMA error callback */
1405 huart->hdmatx->XferErrorCallback = UART_DMAError;
1406
1407 /* Set the DMA abort callback */
1408 huart->hdmatx->XferAbortCallback = NULL;
1409
1410 /* Enable the UART transmit DMA stream */
1411 tmp = (const uint32_t *)&pData;
1412 HAL_DMA_Start_IT(huart->hdmatx, *(const uint32_t *)tmp, (uint32_t)&huart->Instance->DR, Size);
1413
1414 /* Clear the TC flag in the SR register by writing 0 to it */
1415 __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
1416
1417 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1418 in the UART CR3 register */
1419 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1420
1421 return HAL_OK;
1422 }
1423 else
1424 {
1425 return HAL_BUSY;
1426 }
1427 }
1428
1429 /**
1430 * @brief Receives an amount of data in DMA mode.
1431 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1432 * the received data is handled as a set of u16. In this case, Size must indicate the number
1433 * of u16 available through pData.
1434 * @param huart Pointer to a UART_HandleTypeDef structure that contains
1435 * the configuration information for the specified UART module.
1436 * @param pData Pointer to data buffer (u8 or u16 data elements).
1437 * @param Size Amount of data elements (u8 or u16) to be received.
1438 * @note When the UART parity is enabled (PCE = 1) the received data contains the parity bit.
1439 * @retval HAL status
1440 */
HAL_UART_Receive_DMA(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)1441 HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1442 {
1443 /* Check that a Rx process is not already ongoing */
1444 if (huart->RxState == HAL_UART_STATE_READY)
1445 {
1446 if ((pData == NULL) || (Size == 0U))
1447 {
1448 return HAL_ERROR;
1449 }
1450
1451 /* Set Reception type to Standard reception */
1452 huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
1453
1454 return (UART_Start_Receive_DMA(huart, pData, Size));
1455 }
1456 else
1457 {
1458 return HAL_BUSY;
1459 }
1460 }
1461
1462 /**
1463 * @brief Pauses the DMA Transfer.
1464 * @param huart Pointer to a UART_HandleTypeDef structure that contains
1465 * the configuration information for the specified UART module.
1466 * @retval HAL status
1467 */
HAL_UART_DMAPause(UART_HandleTypeDef * huart)1468 HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
1469 {
1470 uint32_t dmarequest = 0x00U;
1471
1472 dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
1473 if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
1474 {
1475 /* Disable the UART DMA Tx request */
1476 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1477 }
1478
1479 dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
1480 if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
1481 {
1482 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1483 ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1484 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
1485
1486 /* Disable the UART DMA Rx request */
1487 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1488 }
1489
1490 return HAL_OK;
1491 }
1492
1493 /**
1494 * @brief Resumes the DMA Transfer.
1495 * @param huart Pointer to a UART_HandleTypeDef structure that contains
1496 * the configuration information for the specified UART module.
1497 * @retval HAL status
1498 */
HAL_UART_DMAResume(UART_HandleTypeDef * huart)1499 HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
1500 {
1501
1502 if (huart->gState == HAL_UART_STATE_BUSY_TX)
1503 {
1504 /* Enable the UART DMA Tx request */
1505 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1506 }
1507
1508 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
1509 {
1510 /* Clear the Overrun flag before resuming the Rx transfer*/
1511 __HAL_UART_CLEAR_OREFLAG(huart);
1512
1513 /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */
1514 if (huart->Init.Parity != UART_PARITY_NONE)
1515 {
1516 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1517 }
1518 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
1519
1520 /* Enable the UART DMA Rx request */
1521 ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1522 }
1523
1524 return HAL_OK;
1525 }
1526
1527 /**
1528 * @brief Stops the DMA Transfer.
1529 * @param huart Pointer to a UART_HandleTypeDef structure that contains
1530 * the configuration information for the specified UART module.
1531 * @retval HAL status
1532 */
HAL_UART_DMAStop(UART_HandleTypeDef * huart)1533 HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
1534 {
1535 uint32_t dmarequest = 0x00U;
1536 /* The Lock is not implemented on this API to allow the user application
1537 to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback():
1538 when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
1539 and the correspond call back is executed HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback()
1540 */
1541
1542 /* Stop UART DMA Tx request if ongoing */
1543 dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
1544 if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
1545 {
1546 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1547
1548 /* Abort the UART DMA Tx stream */
1549 if (huart->hdmatx != NULL)
1550 {
1551 HAL_DMA_Abort(huart->hdmatx);
1552 }
1553 UART_EndTxTransfer(huart);
1554 }
1555
1556 /* Stop UART DMA Rx request if ongoing */
1557 dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
1558 if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
1559 {
1560 ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1561
1562 /* Abort the UART DMA Rx stream */
1563 if (huart->hdmarx != NULL)
1564 {
1565 HAL_DMA_Abort(huart->hdmarx);
1566 }
1567 UART_EndRxTransfer(huart);
1568 }
1569
1570 return HAL_OK;
1571 }
1572
1573 /**
1574 * @brief Receive an amount of data in blocking mode till either the expected number of data is received or an IDLE event occurs.
1575 * @note HAL_OK is returned if reception is completed (expected number of data has been received)
1576 * or if reception is stopped after IDLE event (less than the expected number of data has been received)
1577 * In this case, RxLen output parameter indicates number of data available in reception buffer.
1578 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01),
1579 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
1580 * of uint16_t available through pData.
1581 * @param huart UART handle.
1582 * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
1583 * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
1584 * @param RxLen Number of data elements finally received (could be lower than Size, in case reception ends on IDLE event)
1585 * @param Timeout Timeout duration expressed in ms (covers the whole reception sequence).
1586 * @retval HAL status
1587 */
HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size,uint16_t * RxLen,uint32_t Timeout)1588 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen,
1589 uint32_t Timeout)
1590 {
1591 uint8_t *pdata8bits;
1592 uint16_t *pdata16bits;
1593 uint32_t tickstart;
1594
1595 /* Check that a Rx process is not already ongoing */
1596 if (huart->RxState == HAL_UART_STATE_READY)
1597 {
1598 if ((pData == NULL) || (Size == 0U))
1599 {
1600 return HAL_ERROR;
1601 }
1602
1603 huart->ErrorCode = HAL_UART_ERROR_NONE;
1604 huart->RxState = HAL_UART_STATE_BUSY_RX;
1605 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
1606 huart->RxEventType = HAL_UART_RXEVENT_TC;
1607
1608 /* Init tickstart for timeout management */
1609 tickstart = HAL_GetTick();
1610
1611 huart->RxXferSize = Size;
1612 huart->RxXferCount = Size;
1613
1614 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
1615 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1616 {
1617 pdata8bits = NULL;
1618 pdata16bits = (uint16_t *) pData;
1619 }
1620 else
1621 {
1622 pdata8bits = pData;
1623 pdata16bits = NULL;
1624 }
1625
1626 /* Initialize output number of received elements */
1627 *RxLen = 0U;
1628
1629 /* as long as data have to be received */
1630 while (huart->RxXferCount > 0U)
1631 {
1632 /* Check if IDLE flag is set */
1633 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
1634 {
1635 /* Clear IDLE flag in ISR */
1636 __HAL_UART_CLEAR_IDLEFLAG(huart);
1637
1638 /* If Set, but no data ever received, clear flag without exiting loop */
1639 /* If Set, and data has already been received, this means Idle Event is valid : End reception */
1640 if (*RxLen > 0U)
1641 {
1642 huart->RxEventType = HAL_UART_RXEVENT_IDLE;
1643 huart->RxState = HAL_UART_STATE_READY;
1644
1645 return HAL_OK;
1646 }
1647 }
1648
1649 /* Check if RXNE flag is set */
1650 if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE))
1651 {
1652 if (pdata8bits == NULL)
1653 {
1654 *pdata16bits = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
1655 pdata16bits++;
1656 }
1657 else
1658 {
1659 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE)))
1660 {
1661 *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
1662 }
1663 else
1664 {
1665 *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
1666 }
1667
1668 pdata8bits++;
1669 }
1670 /* Increment number of received elements */
1671 *RxLen += 1U;
1672 huart->RxXferCount--;
1673 }
1674
1675 /* Check for the Timeout */
1676 if (Timeout != HAL_MAX_DELAY)
1677 {
1678 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1679 {
1680 huart->RxState = HAL_UART_STATE_READY;
1681
1682 return HAL_TIMEOUT;
1683 }
1684 }
1685 }
1686
1687 /* Set number of received elements in output parameter : RxLen */
1688 *RxLen = huart->RxXferSize - huart->RxXferCount;
1689 /* At end of Rx process, restore huart->RxState to Ready */
1690 huart->RxState = HAL_UART_STATE_READY;
1691
1692 return HAL_OK;
1693 }
1694 else
1695 {
1696 return HAL_BUSY;
1697 }
1698 }
1699
1700 /**
1701 * @brief Receive an amount of data in interrupt mode till either the expected number of data is received or an IDLE event occurs.
1702 * @note Reception is initiated by this function call. Further progress of reception is achieved thanks
1703 * to UART interrupts raised by RXNE and IDLE events. Callback is called at end of reception indicating
1704 * number of received data elements.
1705 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01),
1706 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
1707 * of uint16_t available through pData.
1708 * @param huart UART handle.
1709 * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
1710 * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
1711 * @retval HAL status
1712 */
HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)1713 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1714 {
1715 HAL_StatusTypeDef status;
1716
1717 /* Check that a Rx process is not already ongoing */
1718 if (huart->RxState == HAL_UART_STATE_READY)
1719 {
1720 if ((pData == NULL) || (Size == 0U))
1721 {
1722 return HAL_ERROR;
1723 }
1724
1725 /* Set Reception type to reception till IDLE Event*/
1726 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
1727 huart->RxEventType = HAL_UART_RXEVENT_TC;
1728
1729 status = UART_Start_Receive_IT(huart, pData, Size);
1730
1731 /* Check Rx process has been successfully started */
1732 if (status == HAL_OK)
1733 {
1734 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
1735 {
1736 __HAL_UART_CLEAR_IDLEFLAG(huart);
1737 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
1738 }
1739 else
1740 {
1741 /* In case of errors already pending when reception is started,
1742 Interrupts may have already been raised and lead to reception abortion.
1743 (Overrun error for instance).
1744 In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
1745 status = HAL_ERROR;
1746 }
1747 }
1748
1749 return status;
1750 }
1751 else
1752 {
1753 return HAL_BUSY;
1754 }
1755 }
1756
1757 /**
1758 * @brief Receive an amount of data in DMA mode till either the expected number of data is received or an IDLE event occurs.
1759 * @note Reception is initiated by this function call. Further progress of reception is achieved thanks
1760 * to DMA services, transferring automatically received data elements in user reception buffer and
1761 * calling registered callbacks at half/end of reception. UART IDLE events are also used to consider
1762 * reception phase as ended. In all cases, callback execution will indicate number of received data elements.
1763 * @note When the UART parity is enabled (PCE = 1), the received data contain
1764 * the parity bit (MSB position).
1765 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01),
1766 * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
1767 * of uint16_t available through pData.
1768 * @param huart UART handle.
1769 * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
1770 * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
1771 * @retval HAL status
1772 */
HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)1773 HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1774 {
1775 HAL_StatusTypeDef status;
1776
1777 /* Check that a Rx process is not already ongoing */
1778 if (huart->RxState == HAL_UART_STATE_READY)
1779 {
1780 if ((pData == NULL) || (Size == 0U))
1781 {
1782 return HAL_ERROR;
1783 }
1784
1785 /* Set Reception type to reception till IDLE Event*/
1786 huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
1787 huart->RxEventType = HAL_UART_RXEVENT_TC;
1788
1789 status = UART_Start_Receive_DMA(huart, pData, Size);
1790
1791 /* Check Rx process has been successfully started */
1792 if (status == HAL_OK)
1793 {
1794 if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
1795 {
1796 __HAL_UART_CLEAR_IDLEFLAG(huart);
1797 ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
1798 }
1799 else
1800 {
1801 /* In case of errors already pending when reception is started,
1802 Interrupts may have already been raised and lead to reception abortion.
1803 (Overrun error for instance).
1804 In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
1805 status = HAL_ERROR;
1806 }
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 stream: 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 stream: 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 stream : 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 stream : 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 stream : 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 stream : 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 stream : 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 stream : 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 stream */
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->CR & DMA_SxCR_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->CR & DMA_SxCR_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 tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling;
3719 MODIFY_REG(huart->Instance->CR1,
3720 (uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8),
3721 tmpreg);
3722
3723 /*-------------------------- USART CR3 Configuration -----------------------*/
3724 /* Configure the UART HFC: Set CTSE and RTSE bits according to huart->Init.HwFlowCtl value */
3725 MODIFY_REG(huart->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE), huart->Init.HwFlowCtl);
3726
3727
3728 #if defined(USART6) && defined(UART9) && defined(UART10)
3729 if ((huart->Instance == USART1) || (huart->Instance == USART6) || (huart->Instance == UART9) || (huart->Instance == UART10))
3730 {
3731 pclk = HAL_RCC_GetPCLK2Freq();
3732 }
3733 #elif defined(USART6)
3734 if ((huart->Instance == USART1) || (huart->Instance == USART6))
3735 {
3736 pclk = HAL_RCC_GetPCLK2Freq();
3737 }
3738 #else
3739 if (huart->Instance == USART1)
3740 {
3741 pclk = HAL_RCC_GetPCLK2Freq();
3742 }
3743 #endif /* USART6 */
3744 else
3745 {
3746 pclk = HAL_RCC_GetPCLK1Freq();
3747 }
3748 /*-------------------------- USART BRR Configuration ---------------------*/
3749 if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
3750 {
3751 huart->Instance->BRR = UART_BRR_SAMPLING8(pclk, huart->Init.BaudRate);
3752 }
3753 else
3754 {
3755 huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, huart->Init.BaudRate);
3756 }
3757 }
3758
3759 /**
3760 * @}
3761 */
3762
3763 #endif /* HAL_UART_MODULE_ENABLED */
3764 /**
3765 * @}
3766 */
3767
3768 /**
3769 * @}
3770 */
3771
3772