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