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