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