1 /**
2   ******************************************************************************
3   * @file    stm32l1xx_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 (UART) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + IO operation functions
10   *           + Peripheral Control functions
11   *           + Peripheral State and Errors functions
12   @verbatim
13   ==============================================================================
14                         ##### How to use this driver #####
15   ==============================================================================
16   [..]
17     The UART HAL driver can be used as follows:
18 
19     (#) Declare a UART_HandleTypeDef handle structure.
20 
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 the 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         (##) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
31              and HAL_UART_Receive_DMA() APIs):
32             (+++) Declare a DMA handle structure for the Tx/Rx channel.
33             (+++) Enable the DMAx interface clock.
34             (+++) Configure the declared DMA handle structure with the required
35                   Tx/Rx parameters.
36             (+++) Configure the DMA Tx/Rx channel.
37             (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle.
38             (+++) Configure the priority and enable the NVIC for the transfer complete
39                   interrupt on the DMA Tx/Rx channel.
40             (+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle
41                   (used for last byte sending completion detection in DMA non circular mode)
42 
43     (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
44         flow control and Mode(Receiver/Transmitter) in the huart Init structure.
45 
46     (#) For the UART asynchronous mode, initialize the UART registers by calling
47         the HAL_UART_Init() API.
48 
49     (#) For the UART Half duplex mode, initialize the UART registers by calling
50         the HAL_HalfDuplex_Init() API.
51 
52     (#) For the LIN mode, initialize the UART registers by calling the HAL_LIN_Init() API.
53 
54     (#) For the Multi-Processor mode, initialize the UART registers by calling
55         the HAL_MultiProcessor_Init() API.
56 
57      [..]
58        (@) The specific UART interrupts (Transmission complete interrupt,
59             RXNE interrupt and Error Interrupts) will be managed using the macros
60             __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the transmit
61             and receive process.
62 
63      [..]
64        (@) These APIs (HAL_UART_Init() and HAL_HalfDuplex_Init()) configure also the
65             low level Hardware GPIO, CLOCK, CORTEX...etc) by calling the customed
66             HAL_UART_MspInit() API.
67 
68      [..]
69         Three operation modes are available within this driver :
70 
71      *** Polling mode IO operation ***
72      =================================
73      [..]
74        (+) Send an amount of data in blocking mode using HAL_UART_Transmit()
75        (+) Receive an amount of data in blocking mode using HAL_UART_Receive()
76 
77      *** Interrupt mode IO operation ***
78      ===================================
79      [..]
80        (+) Send an amount of data in non blocking mode using HAL_UART_Transmit_IT()
81        (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
82             add his own code by customization of function pointer HAL_UART_TxCpltCallback
83        (+) Receive an amount of data in non blocking mode using HAL_UART_Receive_IT()
84        (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
85             add his own code by customization of function pointer HAL_UART_RxCpltCallback
86        (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
87             add his own code by customization of function pointer HAL_UART_ErrorCallback
88 
89      *** DMA mode IO operation ***
90      ==============================
91      [..]
92        (+) Send an amount of data in non blocking mode (DMA) using HAL_UART_Transmit_DMA()
93        (+) At transmission end of half transfer HAL_UART_TxHalfCpltCallback is executed and user can
94             add his own code by customization of function pointer HAL_UART_TxHalfCpltCallback
95        (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
96             add his own code by customization of function pointer HAL_UART_TxCpltCallback
97        (+) Receive an amount of data in non blocking mode (DMA) using HAL_UART_Receive_DMA()
98        (+) At reception end of half transfer HAL_UART_RxHalfCpltCallback is executed and user can
99             add his own code by customization of function pointer HAL_UART_RxHalfCpltCallback
100        (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
101             add his own code by customization of function pointer HAL_UART_RxCpltCallback
102        (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
103             add his own code by customization of function pointer HAL_UART_ErrorCallback
104        (+) Pause the DMA Transfer using HAL_UART_DMAPause()
105        (+) Resume the DMA Transfer using HAL_UART_DMAResume()
106        (+) Stop the DMA Transfer using HAL_UART_DMAStop()
107 
108      *** UART HAL driver macros list ***
109      =============================================
110      [..]
111        Below the list of most used macros in UART HAL driver.
112 
113       (+) __HAL_UART_ENABLE: Enable the UART peripheral
114       (+) __HAL_UART_DISABLE: Disable the UART peripheral
115       (+) __HAL_UART_GET_FLAG : Check whether the specified UART flag is set or not
116       (+) __HAL_UART_CLEAR_FLAG : Clear the specified UART pending flag
117       (+) __HAL_UART_ENABLE_IT: Enable the specified UART interrupt
118       (+) __HAL_UART_DISABLE_IT: Disable the specified UART interrupt
119       (+) __HAL_UART_GET_IT_SOURCE: Check whether the specified UART interrupt has occurred or not
120 
121      [..]
122        (@) You can refer to the UART HAL driver header file for more useful macros
123 
124   @endverbatim
125   ******************************************************************************
126   * @attention
127   *
128   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
129   *
130   * Redistribution and use in source and binary forms, with or without modification,
131   * are permitted provided that the following conditions are met:
132   *   1. Redistributions of source code must retain the above copyright notice,
133   *      this list of conditions and the following disclaimer.
134   *   2. Redistributions in binary form must reproduce the above copyright notice,
135   *      this list of conditions and the following disclaimer in the documentation
136   *      and/or other materials provided with the distribution.
137   *   3. Neither the name of STMicroelectronics nor the names of its contributors
138   *      may be used to endorse or promote products derived from this software
139   *      without specific prior written permission.
140   *
141   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
142   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
143   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
145   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
146   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
147   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
148   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
149   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
150   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
151   *
152   ******************************************************************************
153   */
154 
155 /* Includes ------------------------------------------------------------------*/
156 #include "stm32l1xx_hal.h"
157 
158 /** @addtogroup STM32L1xx_HAL_Driver
159   * @{
160   */
161 
162 /** @defgroup UART UART
163   * @brief HAL UART module driver
164   * @{
165   */
166 #ifdef HAL_UART_MODULE_ENABLED
167 
168 /* Private typedef -----------------------------------------------------------*/
169 /* Private define ------------------------------------------------------------*/
170 /* Private macros ------------------------------------------------------------*/
171 /* Private variables ---------------------------------------------------------*/
172 /* Private function prototypes -----------------------------------------------*/
173 /** @addtogroup UART_Private_Functions   UART Private Functions
174   * @{
175   */
176 static void UART_SetConfig (UART_HandleTypeDef *huart);
177 static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart);
178 static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart);
179 static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart);
180 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
181 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
182 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
183 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
184 static void UART_DMAError(DMA_HandleTypeDef *hdma);
185 static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
186 /**
187   * @}
188   */
189 
190 /* Exported functions ---------------------------------------------------------*/
191 
192 /** @defgroup UART_Exported_Functions UART Exported Functions
193   * @{
194   */
195 
196 /** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
197   *  @brief    Initialization and Configuration functions
198   *
199 @verbatim
200 ===============================================================================
201             ##### Initialization and Configuration functions #####
202  ===============================================================================
203     [..]
204     This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
205     in asynchronous mode.
206       (+) For the asynchronous mode only these parameters can be configured:
207         (++) Baud Rate
208         (++) Word Length
209         (++) Stop Bit
210         (++) Parity
211         (++) Hardware flow control
212         (++) Receiver/transmitter modes
213         (++) Over Sampling Methode
214     [..]
215     The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init() and HAL_MultiProcessor_Init() APIs
216     follow respectively the UART asynchronous, UART Half duplex, LIN and Multi-Processor
217     configuration procedures (details for the procedures are available in reference manual (RM0038)).
218 
219 @endverbatim
220   * @{
221   */
222 
223 /*
224   Additionnal remark: If the parity is enabled, then the MSB bit of the data written
225                       in the data register is transmitted but is changed by the parity bit.
226                       Depending on the frame length defined by the M bit (8-bits or 9-bits),
227                       the possible UART frame formats are as listed in the following table:
228     +-------------------------------------------------------------+
229     |   M bit |  PCE bit  |            UART frame                 |
230     |---------------------|---------------------------------------|
231     |    0    |    0      |    | SB | 8 bit data | STB |          |
232     |---------|-----------|---------------------------------------|
233     |    0    |    1      |    | SB | 7 bit data | PB | STB |     |
234     |---------|-----------|---------------------------------------|
235     |    1    |    0      |    | SB | 9 bit data | STB |          |
236     |---------|-----------|---------------------------------------|
237     |    1    |    1      |    | SB | 8 bit data | PB | STB |     |
238     +-------------------------------------------------------------+
239 */
240 
241 /**
242   * @brief  Initializes the UART mode according to the specified parameters in
243   *         the UART_InitTypeDef and create the associated handle.
244   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
245   *                the configuration information for the specified UART module.
246   * @retval HAL status
247   */
HAL_UART_Init(UART_HandleTypeDef * huart)248 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
249 {
250   /* Check the UART handle allocation */
251   if(huart == NULL)
252   {
253     return HAL_ERROR;
254   }
255 
256   /* Check the parameters */
257   if(huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
258   {
259     /* The hardware flow control is available only for USART1, USART2, USART3 */
260     assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
261     assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
262   }
263   else
264   {
265     assert_param(IS_UART_INSTANCE(huart->Instance));
266   }
267   assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
268   assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
269 
270   if(huart->State == HAL_UART_STATE_RESET)
271   {
272     /* Allocate lock resource and initialize it */
273     huart->Lock = HAL_UNLOCKED;
274 
275     /* Init the low level hardware */
276     HAL_UART_MspInit(huart);
277   }
278 
279   huart->State = HAL_UART_STATE_BUSY;
280 
281   /* Disable the peripheral */
282   __HAL_UART_DISABLE(huart);
283 
284   /* Set the UART Communication parameters */
285   UART_SetConfig(huart);
286 
287   /* In asynchronous mode, the following bits must be kept cleared:
288      - LINEN and CLKEN bits in the USART_CR2 register,
289      - SCEN, HDSEL and IREN  bits in the USART_CR3 register.*/
290   CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
291   CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
292 
293   /* Enable the peripheral */
294   __HAL_UART_ENABLE(huart);
295 
296   /* Initialize the UART state */
297   huart->ErrorCode = HAL_UART_ERROR_NONE;
298   huart->State= HAL_UART_STATE_READY;
299 
300   return HAL_OK;
301 }
302 
303 /**
304   * @brief  Initializes the half-duplex mode according to the specified
305   *         parameters in the UART_InitTypeDef and create the associated handle.
306   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
307   *                the configuration information for the specified UART module.
308   * @retval HAL status
309   */
HAL_HalfDuplex_Init(UART_HandleTypeDef * huart)310 HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart)
311 {
312   /* Check the UART handle allocation */
313   if(huart == NULL)
314   {
315     return HAL_ERROR;
316   }
317 
318   /* Check UART instance */
319   assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance));
320   assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
321   assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
322 
323   if(huart->State == HAL_UART_STATE_RESET)
324   {
325     /* Allocate lock resource and initialize it */
326     huart->Lock = HAL_UNLOCKED;
327 
328     /* Init the low level hardware */
329     HAL_UART_MspInit(huart);
330   }
331 
332   huart->State = HAL_UART_STATE_BUSY;
333 
334   /* Disable the peripheral */
335   __HAL_UART_DISABLE(huart);
336 
337   /* Set the UART Communication parameters */
338   UART_SetConfig(huart);
339 
340   /* In half-duplex mode, the following bits must be kept cleared:
341      - LINEN and CLKEN bits in the USART_CR2 register,
342      - SCEN and IREN bits in the USART_CR3 register.*/
343   CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
344   CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN));
345 
346   /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
347   SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
348 
349   /* Enable the peripheral */
350   __HAL_UART_ENABLE(huart);
351 
352   /* Initialize the UART state*/
353   huart->ErrorCode = HAL_UART_ERROR_NONE;
354   huart->State= HAL_UART_STATE_READY;
355 
356   return HAL_OK;
357 }
358 
359 /**
360   * @brief  Initializes the LIN mode according to the specified
361   *         parameters in the UART_InitTypeDef and create the associated handle.
362   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
363   *                the configuration information for the specified UART module.
364   * @param  BreakDetectLength: Specifies the LIN break detection length.
365   *         This parameter can be one of the following values:
366   *            @arg UART_LINBREAKDETECTLENGTH_10B: 10-bit break detection
367   *            @arg UART_LINBREAKDETECTLENGTH_11B: 11-bit break detection
368   * @retval HAL status
369   */
HAL_LIN_Init(UART_HandleTypeDef * huart,uint32_t BreakDetectLength)370 HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength)
371 {
372   /* Check the UART handle allocation */
373   if(huart == NULL)
374   {
375     return HAL_ERROR;
376   }
377 
378   /* Check the LIN UART instance */
379   assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
380   /* Check the Break detection length parameter */
381   assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength));
382   assert_param(IS_UART_LIN_WORD_LENGTH(huart->Init.WordLength));
383   assert_param(IS_UART_LIN_OVERSAMPLING(huart->Init.OverSampling));
384 
385   if(huart->State == HAL_UART_STATE_RESET)
386   {
387     /* Allocate lock resource and initialize it */
388     huart->Lock = HAL_UNLOCKED;
389 
390     /* Init the low level hardware */
391     HAL_UART_MspInit(huart);
392   }
393 
394   huart->State = HAL_UART_STATE_BUSY;
395 
396   /* Disable the peripheral */
397   __HAL_UART_DISABLE(huart);
398 
399   /* Set the UART Communication parameters */
400   UART_SetConfig(huart);
401 
402   /* In LIN mode, the following bits must be kept cleared:
403      - CLKEN bits in the USART_CR2 register,
404      - SCEN and IREN bits in the USART_CR3 register.*/
405   CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN);
406   CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN));
407 
408   /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
409   SET_BIT(huart->Instance->CR2, USART_CR2_LINEN);
410 
411   /* Set the USART LIN Break detection length. */
412   MODIFY_REG(huart->Instance->CR2, USART_CR2_LBDL, BreakDetectLength);
413 
414   /* Enable the peripheral */
415   __HAL_UART_ENABLE(huart);
416 
417   /* Initialize the UART state*/
418   huart->ErrorCode = HAL_UART_ERROR_NONE;
419   huart->State= HAL_UART_STATE_READY;
420 
421   return HAL_OK;
422 }
423 
424 /**
425   * @brief  Initializes the Multi-Processor mode according to the specified
426   *         parameters in the UART_InitTypeDef and create the associated handle.
427   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
428   *                the configuration information for the specified UART module.
429   * @param  Address: UART node address
430   * @param  WakeUpMethod: specifies the UART wakeup method.
431   *         This parameter can be one of the following values:
432   *            @arg UART_WAKEUPMETHOD_IDLELINE: Wakeup by an idle line detection
433   *            @arg UART_WAKEUPMETHOD_ADDRESSMARK: Wakeup by an address mark
434   * @retval HAL status
435   */
HAL_MultiProcessor_Init(UART_HandleTypeDef * huart,uint8_t Address,uint32_t WakeUpMethod)436 HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod)
437 {
438   /* Check the UART handle allocation */
439   if(huart == NULL)
440   {
441     return HAL_ERROR;
442   }
443 
444   /* Check UART instance capabilities */
445   assert_param(IS_UART_MULTIPROCESSOR_INSTANCE(huart->Instance));
446 
447   /* Check the Address & wake up method parameters */
448   assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod));
449   assert_param(IS_UART_ADDRESS(Address));
450   assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
451   assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
452 
453   if(huart->State == HAL_UART_STATE_RESET)
454   {
455     /* Allocate lock resource and initialize it */
456     huart->Lock = HAL_UNLOCKED;
457 
458     /* Init the low level hardware */
459     HAL_UART_MspInit(huart);
460   }
461 
462   huart->State = HAL_UART_STATE_BUSY;
463 
464   /* Disable the peripheral */
465   __HAL_UART_DISABLE(huart);
466 
467   /* Set the UART Communication parameters */
468   UART_SetConfig(huart);
469 
470   /* In Multi-Processor mode, the following bits must be kept cleared:
471      - LINEN and CLKEN bits in the USART_CR2 register,
472      - SCEN, HDSEL and IREN  bits in the USART_CR3 register */
473   CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
474   CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
475 
476   /* Set the USART address node */
477   MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, Address);
478 
479   /* Set the wake up method by setting the WAKE bit in the CR1 register */
480   MODIFY_REG(huart->Instance->CR1, USART_CR1_WAKE, WakeUpMethod);
481 
482   /* Enable the peripheral */
483   __HAL_UART_ENABLE(huart);
484 
485   /* Initialize the UART state */
486   huart->ErrorCode = HAL_UART_ERROR_NONE;
487   huart->State= HAL_UART_STATE_READY;
488 
489   return HAL_OK;
490 }
491 
492 /**
493   * @brief  DeInitializes the UART peripheral.
494   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
495   *                the configuration information for the specified UART module.
496   * @retval HAL status
497   */
HAL_UART_DeInit(UART_HandleTypeDef * huart)498 HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
499 {
500   /* Check the UART handle allocation */
501   if(huart == NULL)
502   {
503     return HAL_ERROR;
504   }
505 
506   /* Check the parameters */
507   assert_param(IS_UART_INSTANCE(huart->Instance));
508 
509   huart->State = HAL_UART_STATE_BUSY;
510 
511   /* Disable the Peripheral */
512   __HAL_UART_DISABLE(huart);
513 
514   huart->Instance->CR1 = 0x0;
515   huart->Instance->CR2 = 0x0;
516   huart->Instance->CR3 = 0x0;
517 
518   /* DeInit the low level hardware */
519   HAL_UART_MspDeInit(huart);
520 
521   huart->ErrorCode = HAL_UART_ERROR_NONE;
522   huart->State = HAL_UART_STATE_RESET;
523 
524   /* Process Unlock */
525   __HAL_UNLOCK(huart);
526 
527   return HAL_OK;
528 }
529 
530 /**
531   * @brief  UART MSP Init.
532   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
533   *                the configuration information for the specified UART module.
534   * @retval None
535   */
HAL_UART_MspInit(UART_HandleTypeDef * huart)536  __weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
537 {
538   /* Prevent unused argument(s) compilation warning */
539   UNUSED(huart);
540 
541   /* NOTE: This function should not be modified, when the callback is needed,
542            the HAL_UART_MspInit can be implemented in the user file
543    */
544 }
545 
546 /**
547   * @brief  UART MSP DeInit.
548   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
549   *                the configuration information for the specified UART module.
550   * @retval None
551   */
HAL_UART_MspDeInit(UART_HandleTypeDef * huart)552  __weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
553 {
554   /* Prevent unused argument(s) compilation warning */
555   UNUSED(huart);
556 
557   /* NOTE: This function should not be modified, when the callback is needed,
558            the HAL_UART_MspDeInit can be implemented in the user file
559    */
560 }
561 
562 /**
563   * @}
564   */
565 
566 /** @defgroup UART_Exported_Functions_Group2 IO operation functions
567   *  @brief UART Transmit and Receive functions
568   *
569 @verbatim
570   ==============================================================================
571                       ##### IO operation functions #####
572   ==============================================================================
573   [..]
574     This subsection provides a set of functions allowing to manage the UART asynchronous
575     and Half duplex data transfers.
576 
577     (#) There are two modes of transfer:
578        (++) Blocking mode: The communication is performed in polling mode.
579             The HAL status of all data processing is returned by the same function
580             after finishing transfer.
581        (++) Non blocking mode: The communication is performed using Interrupts
582             or DMA, these APIs return the HAL status.
583             The end of the data processing will be indicated through the
584             dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
585             using DMA mode.
586             The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
587             will be executed respectively at the end of the transmit or receive process.
588             The HAL_UART_ErrorCallback() user callback will be executed when
589             a communication error is detected.
590 
591     (#) Blocking mode APIs are:
592         (++) HAL_UART_Transmit()
593         (++) HAL_UART_Receive()
594 
595     (#) Non Blocking mode APIs with Interrupt are:
596         (++) HAL_UART_Transmit_IT()
597         (++) HAL_UART_Receive_IT()
598         (++) HAL_UART_IRQHandler()
599 
600     (#) Non Blocking mode functions with DMA are:
601         (++) HAL_UART_Transmit_DMA()
602         (++) HAL_UART_Receive_DMA()
603         (++) HAL_UART_DMAPause()
604         (++) HAL_UART_DMAResume()
605         (++) HAL_UART_DMAStop()
606 
607     (#) A set of Transfer Complete Callbacks are provided in non blocking mode:
608         (++) HAL_UART_TxHalfCpltCallback()
609         (++) HAL_UART_TxCpltCallback()
610         (++) HAL_UART_RxHalfCpltCallback()
611         (++) HAL_UART_RxCpltCallback()
612         (++) HAL_UART_ErrorCallback()
613 
614     [..]
615       (@) In the Half duplex communication, it is forbidden to run the transmit
616           and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX
617           can't be useful.
618 
619 @endverbatim
620   * @{
621   */
622 
623 /**
624   * @brief  Sends an amount of data in blocking mode.
625   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
626   *                the configuration information for the specified UART module.
627   * @param  pData: Pointer to data buffer
628   * @param  Size: Amount of data to be sent
629   * @param  Timeout: Timeout duration
630   * @retval HAL status
631   */
HAL_UART_Transmit(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size,uint32_t Timeout)632 HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
633 {
634   uint16_t* tmp;
635   uint32_t tmp_state = 0;
636 
637   tmp_state = huart->State;
638   if((tmp_state == HAL_UART_STATE_READY) || (tmp_state == HAL_UART_STATE_BUSY_RX))
639   {
640     if((pData == NULL) || (Size == 0))
641     {
642       return  HAL_ERROR;
643     }
644 
645     /* Process Locked */
646     __HAL_LOCK(huart);
647 
648     huart->ErrorCode = HAL_UART_ERROR_NONE;
649     /* Check if a non-blocking receive process is ongoing or not */
650     if(huart->State == HAL_UART_STATE_BUSY_RX)
651     {
652       huart->State = HAL_UART_STATE_BUSY_TX_RX;
653     }
654     else
655     {
656       huart->State = HAL_UART_STATE_BUSY_TX;
657     }
658 
659     huart->TxXferSize = Size;
660     huart->TxXferCount = Size;
661     while(huart->TxXferCount > 0)
662     {
663       huart->TxXferCount--;
664       if(huart->Init.WordLength == UART_WORDLENGTH_9B)
665       {
666         if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, Timeout) != HAL_OK)
667         {
668           return HAL_TIMEOUT;
669         }
670         tmp = (uint16_t*) pData;
671         huart->Instance->DR = (*tmp & (uint16_t)0x01FF);
672         if(huart->Init.Parity == UART_PARITY_NONE)
673         {
674           pData +=2;
675         }
676         else
677         {
678           pData +=1;
679         }
680       }
681       else
682       {
683         if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, Timeout) != HAL_OK)
684         {
685           return HAL_TIMEOUT;
686         }
687         huart->Instance->DR = (*pData++ & (uint8_t)0xFF);
688       }
689     }
690 
691     if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, Timeout) != HAL_OK)
692     {
693       return HAL_TIMEOUT;
694     }
695 
696     /* Check if a non-blocking receive process is ongoing or not */
697     if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
698     {
699       huart->State = HAL_UART_STATE_BUSY_RX;
700     }
701     else
702     {
703       huart->State = HAL_UART_STATE_READY;
704     }
705 
706     /* Process Unlocked */
707     __HAL_UNLOCK(huart);
708 
709     return HAL_OK;
710   }
711   else
712   {
713     return HAL_BUSY;
714   }
715 }
716 
717 /**
718   * @brief  Receives an amount of data in blocking mode.
719   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
720   *                the configuration information for the specified UART module.
721   * @param  pData: Pointer to data buffer
722   * @param  Size: Amount of data to be received
723   * @param  Timeout: Timeout duration
724   * @retval HAL status
725   */
HAL_UART_Receive(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size,uint32_t Timeout)726 HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
727 {
728   uint16_t* tmp;
729   uint32_t  tmp_state = 0;
730 
731   tmp_state = huart->State;
732   if((tmp_state == HAL_UART_STATE_READY) || (tmp_state == HAL_UART_STATE_BUSY_TX))
733   {
734     if((pData == NULL ) || (Size == 0))
735     {
736       return  HAL_ERROR;
737     }
738 
739     /* Process Locked */
740     __HAL_LOCK(huart);
741 
742     huart->ErrorCode = HAL_UART_ERROR_NONE;
743     /* Check if a non-blocking transmit process is ongoing or not */
744     if(huart->State == HAL_UART_STATE_BUSY_TX)
745     {
746       huart->State = HAL_UART_STATE_BUSY_TX_RX;
747     }
748     else
749     {
750       huart->State = HAL_UART_STATE_BUSY_RX;
751     }
752 
753     huart->RxXferSize = Size;
754     huart->RxXferCount = Size;
755 
756     /* Check the remain data to be received */
757     while(huart->RxXferCount > 0)
758     {
759       huart->RxXferCount--;
760       if(huart->Init.WordLength == UART_WORDLENGTH_9B)
761       {
762         if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
763         {
764           return HAL_TIMEOUT;
765         }
766         tmp = (uint16_t*) pData ;
767         if(huart->Init.Parity == UART_PARITY_NONE)
768         {
769           *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
770           pData +=2;
771         }
772         else
773         {
774           *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
775           pData +=1;
776         }
777 
778       }
779       else
780       {
781         if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
782         {
783           return HAL_TIMEOUT;
784         }
785         if(huart->Init.Parity == UART_PARITY_NONE)
786         {
787           *pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
788         }
789         else
790         {
791           *pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
792         }
793 
794       }
795     }
796 
797     /* Check if a non-blocking transmit process is ongoing or not */
798     if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
799     {
800       huart->State = HAL_UART_STATE_BUSY_TX;
801     }
802     else
803     {
804       huart->State = 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  Sends an amount of data in non blocking mode.
819   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
820   *                the configuration information for the specified UART module.
821   * @param  pData: Pointer to data buffer
822   * @param  Size: Amount of data to be sent
823   * @retval HAL status
824   */
HAL_UART_Transmit_IT(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)825 HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
826 {
827   uint32_t tmp_state = 0;
828 
829   tmp_state = huart->State;
830   if((tmp_state == HAL_UART_STATE_READY) || (tmp_state == HAL_UART_STATE_BUSY_RX))
831   {
832     if((pData == NULL ) || (Size == 0))
833     {
834       return HAL_ERROR;
835     }
836 
837     /* Process Locked */
838     __HAL_LOCK(huart);
839 
840     huart->pTxBuffPtr = pData;
841     huart->TxXferSize = Size;
842     huart->TxXferCount = Size;
843 
844     huart->ErrorCode = HAL_UART_ERROR_NONE;
845     /* Check if a receive process is ongoing or not */
846     if(huart->State == HAL_UART_STATE_BUSY_RX)
847     {
848       huart->State = HAL_UART_STATE_BUSY_TX_RX;
849     }
850     else
851     {
852       huart->State = HAL_UART_STATE_BUSY_TX;
853     }
854 
855     /* Process Unlocked */
856     __HAL_UNLOCK(huart);
857 
858     /* Enable the UART Transmit data register empty Interrupt */
859     __HAL_UART_ENABLE_IT(huart, UART_IT_TXE);
860 
861     return HAL_OK;
862   }
863   else
864   {
865     return HAL_BUSY;
866   }
867 }
868 
869 /**
870   * @brief  Receives an amount of data in non blocking mode
871   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
872   *                the configuration information for the specified UART module.
873   * @param  pData: Pointer to data buffer
874   * @param  Size: Amount of data to be received
875   * @retval HAL status
876   */
HAL_UART_Receive_IT(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)877 HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
878 {
879   uint32_t tmp_state = 0;
880 
881   tmp_state = huart->State;
882   if((tmp_state == HAL_UART_STATE_READY) || (tmp_state == HAL_UART_STATE_BUSY_TX))
883   {
884     if((pData == NULL ) || (Size == 0))
885     {
886       return HAL_ERROR;
887     }
888 
889     /* Process Locked */
890     __HAL_LOCK(huart);
891 
892     huart->pRxBuffPtr = pData;
893     huart->RxXferSize = Size;
894     huart->RxXferCount = Size;
895 
896     huart->ErrorCode = HAL_UART_ERROR_NONE;
897     /* Check if a transmit process is ongoing or not */
898     if(huart->State == HAL_UART_STATE_BUSY_TX)
899     {
900       huart->State = HAL_UART_STATE_BUSY_TX_RX;
901     }
902     else
903     {
904       huart->State = HAL_UART_STATE_BUSY_RX;
905     }
906 
907     /* Process Unlocked */
908     __HAL_UNLOCK(huart);
909 
910     /* Enable the UART Parity Error Interrupt */
911     __HAL_UART_ENABLE_IT(huart, UART_IT_PE);
912 
913     /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
914     __HAL_UART_ENABLE_IT(huart, UART_IT_ERR);
915 
916     /* Enable the UART Data Register not empty Interrupt */
917     __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
918 
919     return HAL_OK;
920   }
921   else
922   {
923     return HAL_BUSY;
924   }
925 }
926 
927 /**
928   * @brief  Sends an amount of data in non blocking mode.
929   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
930   *                the configuration information for the specified UART module.
931   * @param  pData: Pointer to data buffer
932   * @param  Size: Amount of data to be sent
933   * @retval HAL status
934   */
HAL_UART_Transmit_DMA(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)935 HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
936 {
937   uint32_t *tmp;
938   uint32_t tmp_state = 0;
939 
940   tmp_state = huart->State;
941   if((tmp_state == HAL_UART_STATE_READY) || (tmp_state == HAL_UART_STATE_BUSY_RX))
942   {
943     if((pData == NULL ) || (Size == 0))
944     {
945       return HAL_ERROR;
946     }
947 
948     /* Process Locked */
949     __HAL_LOCK(huart);
950 
951     huart->pTxBuffPtr = pData;
952     huart->TxXferSize = Size;
953     huart->TxXferCount = Size;
954 
955     huart->ErrorCode = HAL_UART_ERROR_NONE;
956     /* Check if a receive process is ongoing or not */
957     if(huart->State == HAL_UART_STATE_BUSY_RX)
958     {
959       huart->State = HAL_UART_STATE_BUSY_TX_RX;
960     }
961     else
962     {
963       huart->State = HAL_UART_STATE_BUSY_TX;
964     }
965 
966     /* Set the UART DMA transfer complete callback */
967     huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
968 
969     /* Set the UART DMA Half transfer complete callback */
970     huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
971 
972     /* Set the DMA error callback */
973     huart->hdmatx->XferErrorCallback = UART_DMAError;
974 
975     /* Enable the UART transmit DMA channel */
976     tmp = (uint32_t*)&pData;
977     HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->DR, Size);
978 
979     /* Clear the TC flag in the SR register by writing 0 to it */
980     __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
981 
982     /* Enable the DMA transfer for transmit request by setting the DMAT bit
983        in the UART CR3 register */
984     SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
985 
986     /* Process Unlocked */
987     __HAL_UNLOCK(huart);
988 
989     return HAL_OK;
990   }
991   else
992   {
993     return HAL_BUSY;
994   }
995 }
996 
997 /**
998   * @brief  Receives an amount of data in non blocking mode.
999   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1000   *                the configuration information for the specified UART module.
1001   * @param  pData: Pointer to data buffer
1002   * @param  Size: Amount of data to be received
1003   * @note   When the UART parity is enabled (PCE = 1), the received data contain
1004   *         the parity bit (MSB position)
1005   * @retval HAL status
1006   */
HAL_UART_Receive_DMA(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)1007 HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1008 {
1009   uint32_t *tmp;
1010   uint32_t tmp_state = 0;
1011 
1012   tmp_state = huart->State;
1013   if((tmp_state == HAL_UART_STATE_READY) || (tmp_state == HAL_UART_STATE_BUSY_TX))
1014   {
1015     if((pData == NULL ) || (Size == 0))
1016     {
1017       return HAL_ERROR;
1018     }
1019 
1020     /* Process Locked */
1021     __HAL_LOCK(huart);
1022 
1023     huart->pRxBuffPtr = pData;
1024     huart->RxXferSize = Size;
1025 
1026     huart->ErrorCode = HAL_UART_ERROR_NONE;
1027     /* Check if a transmit process is ongoing or not */
1028     if(huart->State == HAL_UART_STATE_BUSY_TX)
1029     {
1030       huart->State = HAL_UART_STATE_BUSY_TX_RX;
1031     }
1032     else
1033     {
1034       huart->State = HAL_UART_STATE_BUSY_RX;
1035     }
1036 
1037     /* Set the UART DMA transfer complete callback */
1038     huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
1039 
1040     /* Set the UART DMA Half transfer complete callback */
1041     huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
1042 
1043     /* Set the DMA error callback */
1044     huart->hdmarx->XferErrorCallback = UART_DMAError;
1045 
1046     /* Enable the DMA channel */
1047     tmp = (uint32_t*)&pData;
1048     HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->DR, *(uint32_t*)tmp, Size);
1049 
1050     /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1051        in the UART CR3 register */
1052     SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1053 
1054     /* Process Unlocked */
1055     __HAL_UNLOCK(huart);
1056 
1057     return HAL_OK;
1058   }
1059   else
1060   {
1061     return HAL_BUSY;
1062   }
1063 }
1064 
1065 /**
1066   * @brief Pauses the DMA Transfer.
1067   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1068   *                the configuration information for the specified UART module.
1069   * @retval HAL status
1070   */
HAL_UART_DMAPause(UART_HandleTypeDef * huart)1071 HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
1072 {
1073   /* Process Locked */
1074   __HAL_LOCK(huart);
1075 
1076   if(huart->State == HAL_UART_STATE_BUSY_TX)
1077   {
1078     /* Disable the UART DMA Tx request */
1079     CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1080   }
1081   else if(huart->State == HAL_UART_STATE_BUSY_RX)
1082   {
1083     /* Disable the UART DMA Rx request */
1084     CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1085   }
1086   else if (huart->State == HAL_UART_STATE_BUSY_TX_RX)
1087   {
1088     /* Disable the UART DMA Tx & Rx requests */
1089     CLEAR_BIT(huart->Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
1090   }
1091   else
1092   {
1093     /* Process Unlocked */
1094     __HAL_UNLOCK(huart);
1095 
1096     return HAL_ERROR;
1097   }
1098 
1099   /* Process Unlocked */
1100   __HAL_UNLOCK(huart);
1101 
1102   return HAL_OK;
1103 }
1104 
1105 /**
1106   * @brief Resumes the DMA Transfer.
1107   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1108   *                the configuration information for the specified UART module.
1109   * @retval HAL status
1110   */
HAL_UART_DMAResume(UART_HandleTypeDef * huart)1111 HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
1112 {
1113   /* Process Locked */
1114   __HAL_LOCK(huart);
1115 
1116   if(huart->State == HAL_UART_STATE_BUSY_TX)
1117   {
1118     /* Enable the UART DMA Tx request */
1119     SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1120   }
1121   else if(huart->State == HAL_UART_STATE_BUSY_RX)
1122   {
1123     /* Clear the Overrun flag before resumming the Rx transfer*/
1124     __HAL_UART_CLEAR_OREFLAG(huart);
1125     /* Enable the UART DMA Rx request */
1126     SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1127   }
1128   else if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
1129   {
1130     /* Clear the Overrun flag before resumming the Rx transfer*/
1131     __HAL_UART_CLEAR_OREFLAG(huart);
1132     /* Enable the UART DMA Tx & Rx request */
1133     SET_BIT(huart->Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
1134   }
1135   else
1136   {
1137     /* Process Unlocked */
1138     __HAL_UNLOCK(huart);
1139 
1140     return HAL_ERROR;
1141   }
1142 
1143   /* Process Unlocked */
1144   __HAL_UNLOCK(huart);
1145 
1146   return HAL_OK;
1147 }
1148 
1149 /**
1150   * @brief Stops the DMA Transfer.
1151   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1152   *                the configuration information for the specified UART module.
1153   * @retval HAL status
1154   */
HAL_UART_DMAStop(UART_HandleTypeDef * huart)1155 HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
1156 {
1157   /* The Lock is not implemented on this API to allow the user application
1158      to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback():
1159      when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
1160      and the correspond call back is executed HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback()
1161      */
1162 
1163   /* Disable the UART Tx/Rx DMA requests */
1164   CLEAR_BIT(huart->Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
1165 
1166   /* Abort the UART DMA tx channel */
1167   if(huart->hdmatx != NULL)
1168   {
1169     HAL_DMA_Abort(huart->hdmatx);
1170   }
1171   /* Abort the UART DMA rx channel */
1172   if(huart->hdmarx != NULL)
1173   {
1174     HAL_DMA_Abort(huart->hdmarx);
1175   }
1176 
1177   huart->State = HAL_UART_STATE_READY;
1178 
1179   return HAL_OK;
1180 }
1181 
1182 /**
1183   * @brief  This function handles UART interrupt request.
1184   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1185   *                the configuration information for the specified UART module.
1186   * @retval None
1187   */
HAL_UART_IRQHandler(UART_HandleTypeDef * huart)1188 void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
1189 {
1190   uint32_t tmp_flag = 0, tmp_it_source = 0;
1191 
1192   tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_PE);
1193   tmp_it_source = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_PE);
1194   /* UART parity error interrupt occurred ------------------------------------*/
1195   if((tmp_flag != RESET) && (tmp_it_source != RESET))
1196   {
1197     huart->ErrorCode |= HAL_UART_ERROR_PE;
1198   }
1199 
1200   tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_FE);
1201   tmp_it_source = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
1202   /* UART frame error interrupt occurred -------------------------------------*/
1203   if((tmp_flag != RESET) && (tmp_it_source != RESET))
1204   {
1205     huart->ErrorCode |= HAL_UART_ERROR_FE;
1206   }
1207 
1208   tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_NE);
1209   /* UART noise error interrupt occurred -------------------------------------*/
1210   if((tmp_flag != RESET) && (tmp_it_source != RESET))
1211   {
1212     huart->ErrorCode |= HAL_UART_ERROR_NE;
1213   }
1214 
1215   tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_ORE);
1216   /* UART Over-Run interrupt occurred ----------------------------------------*/
1217   if((tmp_flag != RESET) && (tmp_it_source != RESET))
1218   {
1219     huart->ErrorCode |= HAL_UART_ERROR_ORE;
1220   }
1221 
1222   tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE);
1223   tmp_it_source = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE);
1224   /* UART in mode Receiver ---------------------------------------------------*/
1225   if((tmp_flag != RESET) && (tmp_it_source != RESET))
1226   {
1227     UART_Receive_IT(huart);
1228   }
1229 
1230   tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_TXE);
1231   tmp_it_source = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_TXE);
1232   /* UART in mode Transmitter ------------------------------------------------*/
1233   if((tmp_flag != RESET) && (tmp_it_source != RESET))
1234   {
1235     UART_Transmit_IT(huart);
1236   }
1237 
1238   tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_TC);
1239   tmp_it_source = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC);
1240   /* UART in mode Transmitter end --------------------------------------------*/
1241   if((tmp_flag != RESET) && (tmp_it_source != RESET))
1242   {
1243     UART_EndTransmit_IT(huart);
1244   }
1245 
1246   if(huart->ErrorCode != HAL_UART_ERROR_NONE)
1247   {
1248     /* Clear all the error flag at once */
1249     __HAL_UART_CLEAR_PEFLAG(huart);
1250 
1251     /* Set the UART state ready to be able to start again the process */
1252     huart->State = HAL_UART_STATE_READY;
1253 
1254     HAL_UART_ErrorCallback(huart);
1255   }
1256 }
1257 
1258 /**
1259   * @brief  Tx Transfer completed callbacks.
1260   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1261   *                the configuration information for the specified UART module.
1262   * @retval None
1263   */
HAL_UART_TxCpltCallback(UART_HandleTypeDef * huart)1264  __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
1265 {
1266   /* Prevent unused argument(s) compilation warning */
1267   UNUSED(huart);
1268 
1269   /* NOTE: This function should not be modified, when the callback is needed,
1270            the HAL_UART_TxCpltCallback can be implemented in the user file
1271    */
1272 }
1273 
1274 /**
1275   * @brief  Tx Half Transfer completed callbacks.
1276   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1277   *                the configuration information for the specified UART module.
1278   * @retval None
1279   */
HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef * huart)1280  __weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
1281 {
1282   /* Prevent unused argument(s) compilation warning */
1283   UNUSED(huart);
1284 
1285   /* NOTE: This function should not be modified, when the callback is needed,
1286            the HAL_UART_TxHalfCpltCallback can be implemented in the user file
1287    */
1288 }
1289 
1290 /**
1291   * @brief  Rx Transfer completed callbacks.
1292   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1293   *                the configuration information for the specified UART module.
1294   * @retval None
1295   */
HAL_UART_RxCpltCallback(UART_HandleTypeDef * huart)1296 __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
1297 {
1298   /* Prevent unused argument(s) compilation warning */
1299   UNUSED(huart);
1300 
1301   /* NOTE: This function should not be modified, when the callback is needed,
1302            the HAL_UART_RxCpltCallback can be implemented in the user file
1303    */
1304 }
1305 
1306 /**
1307   * @brief  Rx Half Transfer completed callbacks.
1308   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1309   *                the configuration information for the specified UART module.
1310   * @retval None
1311   */
HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef * huart)1312 __weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
1313 {
1314   /* Prevent unused argument(s) compilation warning */
1315   UNUSED(huart);
1316 
1317   /* NOTE: This function should not be modified, when the callback is needed,
1318            the HAL_UART_RxHalfCpltCallback can be implemented in the user file
1319    */
1320 }
1321 
1322 /**
1323   * @brief  UART error callbacks.
1324   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1325   *                the configuration information for the specified UART module.
1326   * @retval None
1327   */
HAL_UART_ErrorCallback(UART_HandleTypeDef * huart)1328  __weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
1329 {
1330   /* Prevent unused argument(s) compilation warning */
1331   UNUSED(huart);
1332 
1333   /* NOTE: This function should not be modified, when the callback is needed,
1334            the HAL_UART_ErrorCallback can be implemented in the user file
1335    */
1336 }
1337 
1338 /**
1339   * @}
1340   */
1341 
1342 /** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions
1343   *  @brief   UART control functions
1344   *
1345 @verbatim
1346   ==============================================================================
1347                       ##### Peripheral Control functions #####
1348   ==============================================================================
1349   [..]
1350     This subsection provides a set of functions allowing to control the UART:
1351     (+) HAL_LIN_SendBreak() API can be helpful to transmit the break character.
1352     (+) HAL_MultiProcessor_EnterMuteMode() API can be helpful to enter the UART in mute mode.
1353     (+) HAL_MultiProcessor_ExitMuteMode() API can be helpful to exit the UART mute mode by software.
1354     (+) HAL_HalfDuplex_EnableTransmitter() API to enable the UART transmitter and disables the UART receiver in Half Duplex mode
1355     (+) HAL_HalfDuplex_EnableReceiver() API to enable the UART receiver and disables the UART transmitter in Half Duplex mode
1356 
1357 @endverbatim
1358   * @{
1359   */
1360 
1361 /**
1362   * @brief  Transmits break characters.
1363   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1364   *                the configuration information for the specified UART module.
1365   * @retval HAL status
1366   */
HAL_LIN_SendBreak(UART_HandleTypeDef * huart)1367 HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
1368 {
1369   /* Check the parameters */
1370   assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
1371 
1372   /* Process Locked */
1373   __HAL_LOCK(huart);
1374 
1375   huart->State = HAL_UART_STATE_BUSY;
1376 
1377   /* Send break characters */
1378   SET_BIT(huart->Instance->CR1, USART_CR1_SBK);
1379 
1380   huart->State = HAL_UART_STATE_READY;
1381 
1382   /* Process Unlocked */
1383   __HAL_UNLOCK(huart);
1384 
1385   return HAL_OK;
1386 }
1387 
1388 /**
1389   * @brief  Enters the UART in mute mode.
1390   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1391   *                the configuration information for the specified UART module.
1392   * @retval HAL status
1393   */
HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef * huart)1394 HAL_StatusTypeDef HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart)
1395 {
1396   /* Check the parameters */
1397   assert_param(IS_UART_INSTANCE(huart->Instance));
1398 
1399   /* Process Locked */
1400   __HAL_LOCK(huart);
1401 
1402   huart->State = HAL_UART_STATE_BUSY;
1403 
1404   /* Enable the USART mute mode  by setting the RWU bit in the CR1 register */
1405   SET_BIT(huart->Instance->CR1, USART_CR1_RWU);
1406 
1407   huart->State = HAL_UART_STATE_READY;
1408 
1409   /* Process Unlocked */
1410   __HAL_UNLOCK(huart);
1411 
1412   return HAL_OK;
1413 }
1414 
1415 /**
1416   * @brief  Exits the UART mute mode: wake up software.
1417   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1418   *                the configuration information for the specified UART module.
1419   * @retval HAL status
1420   */
HAL_MultiProcessor_ExitMuteMode(UART_HandleTypeDef * huart)1421 HAL_StatusTypeDef HAL_MultiProcessor_ExitMuteMode(UART_HandleTypeDef *huart)
1422 {
1423   /* Check the parameters */
1424   assert_param(IS_UART_INSTANCE(huart->Instance));
1425 
1426   /* Process Locked */
1427   __HAL_LOCK(huart);
1428 
1429   huart->State = HAL_UART_STATE_BUSY;
1430 
1431   /* Disable the USART mute mode by clearing the RWU bit in the CR1 register */
1432   CLEAR_BIT(huart->Instance->CR1, USART_CR1_RWU);
1433 
1434   huart->State = HAL_UART_STATE_READY;
1435 
1436   /* Process Unlocked */
1437   __HAL_UNLOCK(huart);
1438 
1439   return HAL_OK;
1440 }
1441 
1442 /**
1443   * @brief  Enables the UART transmitter and disables the UART receiver.
1444   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1445   *                the configuration information for the specified UART module.
1446   * @retval HAL status
1447   */
HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef * huart)1448 HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
1449 {
1450   /* Process Locked */
1451   __HAL_LOCK(huart);
1452 
1453   huart->State = HAL_UART_STATE_BUSY;
1454 
1455   /*-------------------------- USART CR1 Configuration -----------------------*/
1456   /* Clear TE and RE bits */
1457   /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
1458   MODIFY_REG(huart->Instance->CR1, (uint32_t)(USART_CR1_TE | USART_CR1_RE), USART_CR1_TE);
1459 
1460   huart->State = HAL_UART_STATE_READY;
1461 
1462   /* Process Unlocked */
1463   __HAL_UNLOCK(huart);
1464 
1465   return HAL_OK;
1466 }
1467 
1468 /**
1469   * @brief  Enables the UART receiver and disables the UART transmitter.
1470   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1471   *                the configuration information for the specified UART module.
1472   * @retval HAL status
1473   */
HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef * huart)1474 HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart)
1475 {
1476   /* Process Locked */
1477   __HAL_LOCK(huart);
1478 
1479   huart->State = HAL_UART_STATE_BUSY;
1480 
1481   /*-------------------------- USART CR1 Configuration -----------------------*/
1482   /* Clear TE and RE bits */
1483   /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
1484   MODIFY_REG(huart->Instance->CR1, (uint32_t)(USART_CR1_TE | USART_CR1_RE), USART_CR1_RE);
1485 
1486   huart->State = HAL_UART_STATE_READY;
1487 
1488   /* Process Unlocked */
1489   __HAL_UNLOCK(huart);
1490 
1491   return HAL_OK;
1492 }
1493 
1494 /**
1495   * @}
1496   */
1497 
1498 /** @defgroup UART_Exported_Functions_Group4 Peripheral State and Errors functions
1499   *  @brief   UART State and Errors functions
1500   *
1501 @verbatim
1502   ==============================================================================
1503                  ##### Peripheral State and Errors functions #####
1504   ==============================================================================
1505  [..]
1506    This subsection provides a set of functions allowing to return the State of
1507    UART communication process, return Peripheral Errors occurred during communication
1508    process
1509    (+) HAL_UART_GetState() API can be helpful to check in run-time the state of the UART peripheral.
1510    (+) HAL_UART_GetError() check in run-time errors that could be occurred during communication.
1511 
1512 @endverbatim
1513   * @{
1514   */
1515 
1516 /**
1517   * @brief  Returns the UART state.
1518   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1519   *                the configuration information for the specified UART module.
1520   * @retval HAL state
1521   */
HAL_UART_GetState(UART_HandleTypeDef * huart)1522 HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart)
1523 {
1524   return huart->State;
1525 }
1526 
1527 /**
1528 * @brief  Return the UART error code
1529 * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1530   *              the configuration information for the specified UART.
1531 * @retval UART Error Code
1532 */
HAL_UART_GetError(UART_HandleTypeDef * huart)1533 uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart)
1534 {
1535   return huart->ErrorCode;
1536 }
1537 
1538 /**
1539   * @}
1540   */
1541 
1542 /**
1543   * @}
1544   */
1545 
1546 /** @defgroup UART_Private_Functions   UART Private Functions
1547   *  @brief   UART Private functions
1548   * @{
1549   */
1550 /**
1551   * @brief  DMA UART transmit process complete callback.
1552   * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
1553   *               the configuration information for the specified DMA module.
1554   * @retval None
1555   */
UART_DMATransmitCplt(DMA_HandleTypeDef * hdma)1556 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1557 {
1558   UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1559   /* DMA Normal mode*/
1560   if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
1561   {
1562     huart->TxXferCount = 0;
1563 
1564     /* Disable the DMA transfer for transmit request by setting the DMAT bit
1565        in the UART CR3 register */
1566     CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1567 
1568     /* Enable the UART Transmit Complete Interrupt */
1569     __HAL_UART_ENABLE_IT(huart, UART_IT_TC);
1570   }
1571   /* DMA Circular mode */
1572   else
1573   {
1574     HAL_UART_TxCpltCallback(huart);
1575   }
1576 }
1577 
1578 /**
1579   * @brief DMA UART transmit process half complete callback
1580   * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
1581   *               the configuration information for the specified DMA module.
1582   * @retval None
1583   */
UART_DMATxHalfCplt(DMA_HandleTypeDef * hdma)1584 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1585 {
1586   UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1587 
1588   HAL_UART_TxHalfCpltCallback(huart);
1589 }
1590 
1591 /**
1592   * @brief  DMA UART receive process complete callback.
1593   * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
1594   *               the configuration information for the specified DMA module.
1595   * @retval None
1596   */
UART_DMAReceiveCplt(DMA_HandleTypeDef * hdma)1597 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1598 {
1599   UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1600   /* DMA Normal mode*/
1601   if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
1602   {
1603     huart->RxXferCount = 0;
1604 
1605     /* Disable the DMA transfer for the receiver request by setting the DMAR bit
1606        in the UART CR3 register */
1607     CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1608 
1609     /* Check if a transmit process is ongoing or not */
1610     if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
1611     {
1612       huart->State = HAL_UART_STATE_BUSY_TX;
1613     }
1614     else
1615     {
1616       huart->State = HAL_UART_STATE_READY;
1617     }
1618   }
1619   HAL_UART_RxCpltCallback(huart);
1620 }
1621 
1622 /**
1623   * @brief DMA UART receive process half complete callback
1624   * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
1625   *               the configuration information for the specified DMA module.
1626   * @retval None
1627   */
UART_DMARxHalfCplt(DMA_HandleTypeDef * hdma)1628 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1629 {
1630   UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1631 
1632   HAL_UART_RxHalfCpltCallback(huart);
1633 }
1634 
1635 /**
1636   * @brief  DMA UART communication error callback.
1637   * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
1638   *               the configuration information for the specified DMA module.
1639   * @retval None
1640   */
UART_DMAError(DMA_HandleTypeDef * hdma)1641 static void UART_DMAError(DMA_HandleTypeDef *hdma)
1642 {
1643   UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1644   huart->RxXferCount = 0;
1645   huart->TxXferCount = 0;
1646   huart->State= HAL_UART_STATE_READY;
1647   huart->ErrorCode |= HAL_UART_ERROR_DMA;
1648   HAL_UART_ErrorCallback(huart);
1649 }
1650 
1651 /**
1652   * @brief  This function handles UART Communication Timeout.
1653   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1654   *                the configuration information for the specified UART module.
1655   * @param  Flag: specifies the UART flag to check.
1656   * @param  Status: The new Flag status (SET or RESET).
1657   * @param  Timeout: Timeout duration
1658   * @retval HAL status
1659   */
UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef * huart,uint32_t Flag,FlagStatus Status,uint32_t Timeout)1660 static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
1661 {
1662   uint32_t tickstart = 0;
1663 
1664   /* Get tick */
1665   tickstart = HAL_GetTick();
1666 
1667   /* Wait until flag is set */
1668   if(Status == RESET)
1669   {
1670     while(__HAL_UART_GET_FLAG(huart, Flag) == RESET)
1671     {
1672       /* Check for the Timeout */
1673       if(Timeout != HAL_MAX_DELAY)
1674       {
1675         if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1676         {
1677           /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1678           __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
1679           __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
1680           __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
1681           __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
1682 
1683           huart->State= HAL_UART_STATE_READY;
1684 
1685           /* Process Unlocked */
1686           __HAL_UNLOCK(huart);
1687 
1688           return HAL_TIMEOUT;
1689         }
1690       }
1691     }
1692   }
1693   else
1694   {
1695     while(__HAL_UART_GET_FLAG(huart, Flag) != RESET)
1696     {
1697       /* Check for the Timeout */
1698       if(Timeout != HAL_MAX_DELAY)
1699       {
1700         if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1701         {
1702           /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1703           __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
1704           __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
1705           __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
1706           __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
1707 
1708           huart->State= HAL_UART_STATE_READY;
1709 
1710           /* Process Unlocked */
1711           __HAL_UNLOCK(huart);
1712 
1713           return HAL_TIMEOUT;
1714         }
1715       }
1716     }
1717   }
1718   return HAL_OK;
1719 }
1720 
1721 /**
1722   * @brief  Sends an amount of data in non blocking mode.
1723   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1724   *                the configuration information for the specified UART module.
1725   * @retval HAL status
1726   */
UART_Transmit_IT(UART_HandleTypeDef * huart)1727 static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart)
1728 {
1729   uint16_t* tmp;
1730   uint32_t tmp_state = 0;
1731 
1732   tmp_state = huart->State;
1733   if((tmp_state == HAL_UART_STATE_BUSY_TX) || (tmp_state == HAL_UART_STATE_BUSY_TX_RX))
1734   {
1735     if(huart->Init.WordLength == UART_WORDLENGTH_9B)
1736     {
1737       tmp = (uint16_t*) huart->pTxBuffPtr;
1738       huart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
1739       if(huart->Init.Parity == UART_PARITY_NONE)
1740       {
1741         huart->pTxBuffPtr += 2;
1742       }
1743       else
1744       {
1745         huart->pTxBuffPtr += 1;
1746       }
1747     }
1748     else
1749     {
1750       huart->Instance->DR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0x00FF);
1751     }
1752 
1753     if(--huart->TxXferCount == 0)
1754     {
1755       /* Disable the UART Transmit Complete Interrupt */
1756       __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
1757 
1758       /* Enable the UART Transmit Complete Interrupt */
1759       __HAL_UART_ENABLE_IT(huart, UART_IT_TC);
1760     }
1761     return HAL_OK;
1762   }
1763   else
1764   {
1765     return HAL_BUSY;
1766   }
1767 }
1768 
1769 
1770 /**
1771   * @brief  Wraps up transmission in non blocking mode.
1772   * @param  huart: pointer to a UART_HandleTypeDef structure that contains
1773   *                the configuration information for the specified UART module.
1774   * @retval HAL status
1775   */
UART_EndTransmit_IT(UART_HandleTypeDef * huart)1776 static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart)
1777 {
1778   /* Disable the UART Transmit Complete Interrupt */
1779   __HAL_UART_DISABLE_IT(huart, UART_IT_TC);
1780 
1781   /* Check if a receive process is ongoing or not */
1782   if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
1783   {
1784     huart->State = HAL_UART_STATE_BUSY_RX;
1785   }
1786   else
1787   {
1788     huart->State = HAL_UART_STATE_READY;
1789   }
1790 
1791   HAL_UART_TxCpltCallback(huart);
1792 
1793   return HAL_OK;
1794 }
1795 
1796 /**
1797   * @brief  Receives an amount of data in non blocking mode
1798   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1799   *                the configuration information for the specified UART module.
1800   * @retval HAL status
1801   */
UART_Receive_IT(UART_HandleTypeDef * huart)1802 static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
1803 {
1804   uint16_t* tmp;
1805   uint32_t tmp_state = 0;
1806 
1807   tmp_state = huart->State;
1808   if((tmp_state == HAL_UART_STATE_BUSY_RX) || (tmp_state == HAL_UART_STATE_BUSY_TX_RX))
1809   {
1810     if(huart->Init.WordLength == UART_WORDLENGTH_9B)
1811     {
1812       tmp = (uint16_t*) huart->pRxBuffPtr;
1813       if(huart->Init.Parity == UART_PARITY_NONE)
1814       {
1815         *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
1816         huart->pRxBuffPtr += 2;
1817       }
1818       else
1819       {
1820         *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
1821         huart->pRxBuffPtr += 1;
1822       }
1823     }
1824     else
1825     {
1826       if(huart->Init.Parity == UART_PARITY_NONE)
1827       {
1828         *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
1829       }
1830       else
1831       {
1832         *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
1833       }
1834     }
1835 
1836     if(--huart->RxXferCount == 0)
1837     {
1838       __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
1839 
1840       /* Check if a transmit process is ongoing or not */
1841       if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
1842       {
1843         huart->State = HAL_UART_STATE_BUSY_TX;
1844       }
1845       else
1846       {
1847         /* Disable the UART Parity Error Interrupt */
1848         __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
1849 
1850         /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
1851         __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
1852 
1853         huart->State = HAL_UART_STATE_READY;
1854       }
1855       HAL_UART_RxCpltCallback(huart);
1856 
1857       return HAL_OK;
1858     }
1859     return HAL_OK;
1860   }
1861   else
1862   {
1863     return HAL_BUSY;
1864   }
1865 }
1866 
1867 /**
1868   * @brief  Configures the UART peripheral.
1869   * @param  huart: Pointer to a UART_HandleTypeDef structure that contains
1870   *                the configuration information for the specified UART module.
1871   * @retval None
1872   */
UART_SetConfig(UART_HandleTypeDef * huart)1873 static void UART_SetConfig(UART_HandleTypeDef *huart)
1874 {
1875   uint32_t tmpreg = 0x00;
1876 
1877   /* Check the parameters */
1878   assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
1879   assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
1880   assert_param(IS_UART_PARITY(huart->Init.Parity));
1881   assert_param(IS_UART_MODE(huart->Init.Mode));
1882 
1883   /*------- UART-associated USART registers setting : CR2 Configuration ------*/
1884   /* Configure the UART Stop Bits: Set STOP[13:12] bits according
1885    * to huart->Init.StopBits value */
1886   MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
1887 
1888   /*------- UART-associated USART registers setting : CR1 Configuration ------*/
1889   /* Configure the UART Word Length, Parity and mode:
1890      Set the M bits according to huart->Init.WordLength value
1891      Set PCE and PS bits according to huart->Init.Parity value
1892      Set TE and RE bits according to huart->Init.Mode value
1893      Set OVER8 bit according to huart->Init.OverSampling value */
1894   tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling;
1895   MODIFY_REG(huart->Instance->CR1,
1896              (uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8),
1897              tmpreg);
1898 
1899   /*------- UART-associated USART registers setting : CR3 Configuration ------*/
1900   /* Configure the UART HFC: Set CTSE and RTSE bits according to huart->Init.HwFlowCtl value */
1901   MODIFY_REG(huart->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE), huart->Init.HwFlowCtl);
1902 
1903   /* Check the Over Sampling */
1904   if(huart->Init.OverSampling == UART_OVERSAMPLING_8)
1905   {
1906     /*------- UART-associated USART registers setting : BRR Configuration ------*/
1907     if((huart->Instance == USART1))
1908     {
1909       huart->Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate);
1910     }
1911     else
1912     {
1913       huart->Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate);
1914     }
1915   }
1916   else
1917   {
1918     /*------- UART-associated USART registers setting : BRR Configuration ------*/
1919     if((huart->Instance == USART1))
1920     {
1921       huart->Instance->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate);
1922     }
1923     else
1924     {
1925       huart->Instance->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate);
1926     }
1927   }
1928 }
1929 /**
1930   * @}
1931   */
1932 
1933 #endif /* HAL_UART_MODULE_ENABLED */
1934 /**
1935   * @}
1936   */
1937 
1938 /**
1939   * @}
1940   */
1941 
1942 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1943