comparison l476rg/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c @ 0:32a3b1785697

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