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>© 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