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   */