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