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