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