1 /**
2 ******************************************************************************
3 * @file stm32l4xx_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, RX/TX FIFOs related interrupts and Error Interrupts)
33 are managed using the macros __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT()
34 inside the transmit and receive processes.
35 (++) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
36 and HAL_UART_Receive_DMA() APIs):
37 (+++) Declare a DMA handle structure for the Tx/Rx channel.
38 (+++) Enable the DMAx interface clock.
39 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
40 (+++) Configure the DMA Tx/Rx channel.
41 (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle.
42 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
43
44 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Prescaler value , Hardware
45 flow control and Mode (Receiver/Transmitter) in the huart handle Init structure.
46
47 (#) If required, program UART advanced features (TX/RX pins swap, auto Baud rate detection,...)
48 in the huart handle AdvancedInit structure.
49
50 (#) For the UART asynchronous mode, initialize the UART registers by calling
51 the HAL_UART_Init() API.
52
53 (#) For the UART Half duplex mode, initialize the UART registers by calling
54 the HAL_HalfDuplex_Init() API.
55
56 (#) For the UART LIN (Local Interconnection Network) mode, initialize the UART registers
57 by calling the HAL_LIN_Init() API.
58
59 (#) For the UART Multiprocessor mode, initialize the UART registers
60 by calling the HAL_MultiProcessor_Init() API.
61
62 (#) For the UART RS485 Driver Enabled mode, initialize the UART registers
63 by calling the HAL_RS485Ex_Init() API.
64
65 [..]
66 (@) These API's (HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init(), HAL_MultiProcessor_Init(),
67 also configure the low level Hardware GPIO, CLOCK, CORTEX...etc) by
68 calling the customized HAL_UART_MspInit() API.
69
70 ##### Callback registration #####
71 ==================================
72
73 [..]
74 The compilation define USE_HAL_UART_REGISTER_CALLBACKS when set to 1
75 allows the user to configure dynamically the driver callbacks.
76
77 [..]
78 Use Function @ref HAL_UART_RegisterCallback() to register a user callback.
79 Function @ref HAL_UART_RegisterCallback() allows to register following callbacks:
80 (+) TxHalfCpltCallback : Tx Half Complete Callback.
81 (+) TxCpltCallback : Tx Complete Callback.
82 (+) RxHalfCpltCallback : Rx Half Complete Callback.
83 (+) RxCpltCallback : Rx Complete Callback.
84 (+) ErrorCallback : Error Callback.
85 (+) AbortCpltCallback : Abort Complete Callback.
86 (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
87 (+) AbortReceiveCpltCallback : Abort Receive Complete Callback.
88 (+) WakeupCallback : Wakeup Callback.
89 (+) RxFifoFullCallback : Rx Fifo Full Callback.
90 (+) TxFifoEmptyCallback : Tx Fifo Empty Callback.
91 (+) MspInitCallback : UART MspInit.
92 (+) MspDeInitCallback : UART MspDeInit.
93 This function takes as parameters the HAL peripheral handle, the Callback ID
94 and a pointer to the user callback function.
95
96 [..]
97 Use function @ref HAL_UART_UnRegisterCallback() to reset a callback to the default
98 weak (surcharged) function.
99 @ref HAL_UART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
100 and the Callback ID.
101 This function allows to reset following callbacks:
102 (+) TxHalfCpltCallback : Tx Half Complete Callback.
103 (+) TxCpltCallback : Tx Complete Callback.
104 (+) RxHalfCpltCallback : Rx Half Complete Callback.
105 (+) RxCpltCallback : Rx Complete Callback.
106 (+) ErrorCallback : Error Callback.
107 (+) AbortCpltCallback : Abort Complete Callback.
108 (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
109 (+) AbortReceiveCpltCallback : Abort Receive Complete Callback.
110 (+) WakeupCallback : Wakeup Callback.
111 (+) RxFifoFullCallback : Rx Fifo Full Callback.
112 (+) TxFifoEmptyCallback : Tx Fifo Empty Callback.
113 (+) MspInitCallback : UART MspInit.
114 (+) MspDeInitCallback : UART MspDeInit.
115
116 [..]
117 By default, after the @ref HAL_UART_Init() and when the state is HAL_UART_STATE_RESET
118 all callbacks are set to the corresponding weak (surcharged) functions:
119 examples @ref HAL_UART_TxCpltCallback(), @ref HAL_UART_RxHalfCpltCallback().
120 Exception done for MspInit and MspDeInit functions that are respectively
121 reset to the legacy weak (surcharged) functions in the @ref HAL_UART_Init()
122 and @ref HAL_UART_DeInit() only when these callbacks are null (not registered beforehand).
123 If not, MspInit or MspDeInit are not null, the @ref HAL_UART_Init() and @ref HAL_UART_DeInit()
124 keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
125
126 [..]
127 Callbacks can be registered/unregistered in HAL_UART_STATE_READY state only.
128 Exception done MspInit/MspDeInit that can be registered/unregistered
129 in HAL_UART_STATE_READY or HAL_UART_STATE_RESET state, thus registered (user)
130 MspInit/DeInit callbacks can be used during the Init/DeInit.
131 In that case first register the MspInit/MspDeInit user callbacks
132 using @ref HAL_UART_RegisterCallback() before calling @ref HAL_UART_DeInit()
133 or @ref HAL_UART_Init() function.
134
135 [..]
136 When The compilation define USE_HAL_UART_REGISTER_CALLBACKS is set to 0 or
137 not defined, the callback registration feature is not available
138 and weak (surcharged) callbacks are used.
139
140
141 @endverbatim
142 ******************************************************************************
143 * @attention
144 *
145 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
146 *
147 * Redistribution and use in source and binary forms, with or without modification,
148 * are permitted provided that the following conditions are met:
149 * 1. Redistributions of source code must retain the above copyright notice,
150 * this list of conditions and the following disclaimer.
151 * 2. Redistributions in binary form must reproduce the above copyright notice,
152 * this list of conditions and the following disclaimer in the documentation
153 * and/or other materials provided with the distribution.
154 * 3. Neither the name of STMicroelectronics nor the names of its contributors
155 * may be used to endorse or promote products derived from this software
156 * without specific prior written permission.
157 *
158 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
159 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
160 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
161 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
162 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
163 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
164 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
165 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
166 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
167 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
168 *
169 ******************************************************************************
170 */
171
172 /* Includes ------------------------------------------------------------------*/
173 #include "stm32l4xx_hal.h"
174
175 /** @addtogroup STM32L4xx_HAL_Driver
176 * @{
177 */
178
179 /** @defgroup UART UART
180 * @brief HAL UART module driver
181 * @{
182 */
183
184 #ifdef HAL_UART_MODULE_ENABLED
185
186 /* Private typedef -----------------------------------------------------------*/
187 /* Private define ------------------------------------------------------------*/
188 /** @defgroup UART_Private_Constants UART Private Constants
189 * @{
190 */
191 #if defined(USART_CR1_FIFOEN)
192 #define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
193 USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8| \
194 USART_CR1_FIFOEN )) /*!< UART or USART CR1 fields of parameters set by UART_SetConfig API */
195 #else
196 #define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
197 USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8 )) /*!< UART or USART CR1 fields of parameters set by UART_SetConfig API */
198 #endif
199
200 #if defined(USART_CR1_FIFOEN)
201 #define USART_CR3_FIELDS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT| \
202 USART_CR3_TXFTCFG | USART_CR3_RXFTCFG )) /*!< UART or USART CR3 fields of parameters set by UART_SetConfig API */
203 #else
204 #define USART_CR3_FIELDS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT)) /*!< UART or USART CR3 fields of parameters set by UART_SetConfig API */
205 #endif
206
207 #define LPUART_BRR_MIN 0x00000300U /* LPUART BRR minimum authorized value */
208 #define LPUART_BRR_MAX 0x000FFFFFU /* LPUART BRR maximum authorized value */
209
210 #define UART_BRR_MIN 0x10U /* UART BRR minimum authorized value */
211 #define UART_BRR_MAX 0x0000FFFFU /* UART BRR maximum authorized value */
212
213 /**
214 * @}
215 */
216
217 /* Private macros ------------------------------------------------------------*/
218 /* Private variables ---------------------------------------------------------*/
219 /* Private function prototypes -----------------------------------------------*/
220 /** @addtogroup UART_Private_Functions
221 * @{
222 */
223 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
224 void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart);
225 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
226 static void UART_EndTxTransfer(UART_HandleTypeDef *huart);
227 static void UART_EndRxTransfer(UART_HandleTypeDef *huart);
228 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
229 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
230 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
231 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
232 static void UART_DMAError(DMA_HandleTypeDef *hdma);
233 static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
234 static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
235 static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
236 static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
237 static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
238 static void UART_TxISR_8BIT(UART_HandleTypeDef *huart);
239 static void UART_TxISR_16BIT(UART_HandleTypeDef *huart);
240 #if defined(USART_CR1_FIFOEN)
241 static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart);
242 static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart);
243 #endif
244 static void UART_EndTransmit_IT(UART_HandleTypeDef *huart);
245 static void UART_RxISR_8BIT(UART_HandleTypeDef *huart);
246 static void UART_RxISR_16BIT(UART_HandleTypeDef *huart);
247 #if defined(USART_CR1_FIFOEN)
248 static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart);
249 static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart);
250 #endif
251 /**
252 * @}
253 */
254
255 /* Exported functions --------------------------------------------------------*/
256
257 /** @defgroup UART_Exported_Functions UART Exported Functions
258 * @{
259 */
260
261 /** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
262 * @brief Initialization and Configuration functions
263 *
264 @verbatim
265 ===============================================================================
266 ##### Initialization and Configuration functions #####
267 ===============================================================================
268 [..]
269 This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
270 in asynchronous mode.
271 (+) For the asynchronous mode the parameters below can be configured:
272 (++) Baud Rate
273 (++) Word Length
274 (++) Stop Bit
275 (++) Parity: If the parity is enabled, then the MSB bit of the data written
276 in the data register is transmitted but is changed by the parity bit.
277 (++) Hardware flow control
278 (++) Receiver/transmitter modes
279 (++) Over Sampling Method
280 (++) One-Bit Sampling Method
281 (+) For the asynchronous mode, the following advanced features can be configured as well:
282 (++) TX and/or RX pin level inversion
283 (++) data logical level inversion
284 (++) RX and TX pins swap
285 (++) RX overrun detection disabling
286 (++) DMA disabling on RX error
287 (++) MSB first on communication line
288 (++) auto Baud rate detection
289 [..]
290 The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init()and HAL_MultiProcessor_Init()API
291 follow respectively the UART asynchronous, UART Half duplex, UART LIN mode
292 and UART multiprocessor mode configuration procedures (details for the procedures
293 are available in reference manual).
294
295 @endverbatim
296
297 Depending on the frame length defined by the M1 and M0 bits (7-bit,
298 8-bit or 9-bit), the possible UART formats are listed in the
299 following table.
300
301 Table 1. UART frame format.
302 +-----------------------------------------------------------------------+
303 | M1 bit | M0 bit | PCE bit | UART frame |
304 |---------|---------|-----------|---------------------------------------|
305 | 0 | 0 | 0 | | SB | 8 bit data | STB | |
306 |---------|---------|-----------|---------------------------------------|
307 | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | |
308 |---------|---------|-----------|---------------------------------------|
309 | 0 | 1 | 0 | | SB | 9 bit data | STB | |
310 |---------|---------|-----------|---------------------------------------|
311 | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | |
312 |---------|---------|-----------|---------------------------------------|
313 | 1 | 0 | 0 | | SB | 7 bit data | STB | |
314 |---------|---------|-----------|---------------------------------------|
315 | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | |
316 +-----------------------------------------------------------------------+
317
318 * @{
319 */
320
321 /**
322 * @brief Initialize the UART mode according to the specified
323 * parameters in the UART_InitTypeDef and initialize the associated handle.
324 * @param huart UART handle.
325 * @retval HAL status
326 */
HAL_UART_Init(UART_HandleTypeDef * huart)327 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
328 {
329 /* Check the UART handle allocation */
330 if (huart == NULL)
331 {
332 return HAL_ERROR;
333 }
334
335 if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
336 {
337 /* Check the parameters */
338 assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
339 }
340 else
341 {
342 /* Check the parameters */
343 assert_param((IS_UART_INSTANCE(huart->Instance)) || (IS_LPUART_INSTANCE(huart->Instance)));
344 }
345
346 if (huart->gState == HAL_UART_STATE_RESET)
347 {
348 /* Allocate lock resource and initialize it */
349 huart->Lock = HAL_UNLOCKED;
350
351 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
352 UART_InitCallbacksToDefault(huart);
353
354 if (huart->MspInitCallback == NULL)
355 {
356 huart->MspInitCallback = HAL_UART_MspInit;
357 }
358
359 /* Init the low level hardware */
360 huart->MspInitCallback(huart);
361 #else
362 /* Init the low level hardware : GPIO, CLOCK */
363 HAL_UART_MspInit(huart);
364 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
365 }
366
367 huart->gState = HAL_UART_STATE_BUSY;
368
369 /* Disable the Peripheral */
370 __HAL_UART_DISABLE(huart);
371
372 /* Set the UART Communication parameters */
373 if (UART_SetConfig(huart) == HAL_ERROR)
374 {
375 return HAL_ERROR;
376 }
377
378 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
379 {
380 UART_AdvFeatureConfig(huart);
381 }
382
383 /* In asynchronous mode, the following bits must be kept cleared:
384 - LINEN and CLKEN bits in the USART_CR2 register,
385 - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
386 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
387 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
388
389 /* Enable the Peripheral */
390 __HAL_UART_ENABLE(huart);
391
392 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
393 return (UART_CheckIdleState(huart));
394 }
395
396 /**
397 * @brief Initialize the half-duplex mode according to the specified
398 * parameters in the UART_InitTypeDef and creates the associated handle.
399 * @param huart UART handle.
400 * @retval HAL status
401 */
HAL_HalfDuplex_Init(UART_HandleTypeDef * huart)402 HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart)
403 {
404 /* Check the UART handle allocation */
405 if (huart == NULL)
406 {
407 return HAL_ERROR;
408 }
409
410 /* Check UART instance */
411 assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance));
412
413 if (huart->gState == HAL_UART_STATE_RESET)
414 {
415 /* Allocate lock resource and initialize it */
416 huart->Lock = HAL_UNLOCKED;
417
418 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
419 UART_InitCallbacksToDefault(huart);
420
421 if (huart->MspInitCallback == NULL)
422 {
423 huart->MspInitCallback = HAL_UART_MspInit;
424 }
425
426 /* Init the low level hardware */
427 huart->MspInitCallback(huart);
428 #else
429 /* Init the low level hardware : GPIO, CLOCK */
430 HAL_UART_MspInit(huart);
431 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
432 }
433
434 huart->gState = HAL_UART_STATE_BUSY;
435
436 /* Disable the Peripheral */
437 __HAL_UART_DISABLE(huart);
438
439 /* Set the UART Communication parameters */
440 if (UART_SetConfig(huart) == HAL_ERROR)
441 {
442 return HAL_ERROR;
443 }
444
445 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
446 {
447 UART_AdvFeatureConfig(huart);
448 }
449
450 /* In half-duplex mode, the following bits must be kept cleared:
451 - LINEN and CLKEN bits in the USART_CR2 register,
452 - SCEN and IREN bits in the USART_CR3 register.*/
453 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
454 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN));
455
456 /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
457 SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
458
459 /* Enable the Peripheral */
460 __HAL_UART_ENABLE(huart);
461
462 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
463 return (UART_CheckIdleState(huart));
464 }
465
466
467 /**
468 * @brief Initialize the LIN mode according to the specified
469 * parameters in the UART_InitTypeDef and creates the associated handle .
470 * @param huart UART handle.
471 * @param BreakDetectLength Specifies the LIN break detection length.
472 * This parameter can be one of the following values:
473 * @arg @ref UART_LINBREAKDETECTLENGTH_10B 10-bit break detection
474 * @arg @ref UART_LINBREAKDETECTLENGTH_11B 11-bit break detection
475 * @retval HAL status
476 */
HAL_LIN_Init(UART_HandleTypeDef * huart,uint32_t BreakDetectLength)477 HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength)
478 {
479 /* Check the UART handle allocation */
480 if (huart == NULL)
481 {
482 return HAL_ERROR;
483 }
484
485 /* Check the LIN UART instance */
486 assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
487 /* Check the Break detection length parameter */
488 assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength));
489
490 /* LIN mode limited to 16-bit oversampling only */
491 if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
492 {
493 return HAL_ERROR;
494 }
495 /* LIN mode limited to 8-bit data length */
496 if (huart->Init.WordLength != UART_WORDLENGTH_8B)
497 {
498 return HAL_ERROR;
499 }
500
501 if (huart->gState == HAL_UART_STATE_RESET)
502 {
503 /* Allocate lock resource and initialize it */
504 huart->Lock = HAL_UNLOCKED;
505
506 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
507 UART_InitCallbacksToDefault(huart);
508
509 if (huart->MspInitCallback == NULL)
510 {
511 huart->MspInitCallback = HAL_UART_MspInit;
512 }
513
514 /* Init the low level hardware */
515 huart->MspInitCallback(huart);
516 #else
517 /* Init the low level hardware : GPIO, CLOCK */
518 HAL_UART_MspInit(huart);
519 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
520 }
521
522 huart->gState = HAL_UART_STATE_BUSY;
523
524 /* Disable the Peripheral */
525 __HAL_UART_DISABLE(huart);
526
527 /* Set the UART Communication parameters */
528 if (UART_SetConfig(huart) == HAL_ERROR)
529 {
530 return HAL_ERROR;
531 }
532
533 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
534 {
535 UART_AdvFeatureConfig(huart);
536 }
537
538 /* In LIN mode, the following bits must be kept cleared:
539 - LINEN and CLKEN bits in the USART_CR2 register,
540 - SCEN and IREN bits in the USART_CR3 register.*/
541 CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN);
542 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN));
543
544 /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
545 SET_BIT(huart->Instance->CR2, USART_CR2_LINEN);
546
547 /* Set the USART LIN Break detection length. */
548 MODIFY_REG(huart->Instance->CR2, USART_CR2_LBDL, BreakDetectLength);
549
550 /* Enable the Peripheral */
551 __HAL_UART_ENABLE(huart);
552
553 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
554 return (UART_CheckIdleState(huart));
555 }
556
557
558 /**
559 * @brief Initialize the multiprocessor mode according to the specified
560 * parameters in the UART_InitTypeDef and initialize the associated handle.
561 * @param huart UART handle.
562 * @param Address UART node address (4-, 6-, 7- or 8-bit long).
563 * @param WakeUpMethod Specifies the UART wakeup method.
564 * This parameter can be one of the following values:
565 * @arg @ref UART_WAKEUPMETHOD_IDLELINE WakeUp by an idle line detection
566 * @arg @ref UART_WAKEUPMETHOD_ADDRESSMARK WakeUp by an address mark
567 * @note If the user resorts to idle line detection wake up, the Address parameter
568 * is useless and ignored by the initialization function.
569 * @note If the user resorts to address mark wake up, the address length detection
570 * is configured by default to 4 bits only. For the UART to be able to
571 * manage 6-, 7- or 8-bit long addresses detection, the API
572 * HAL_MultiProcessorEx_AddressLength_Set() must be called after
573 * HAL_MultiProcessor_Init().
574 * @retval HAL status
575 */
HAL_MultiProcessor_Init(UART_HandleTypeDef * huart,uint8_t Address,uint32_t WakeUpMethod)576 HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod)
577 {
578 /* Check the UART handle allocation */
579 if (huart == NULL)
580 {
581 return HAL_ERROR;
582 }
583
584 /* Check the wake up method parameter */
585 assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod));
586
587 if (huart->gState == HAL_UART_STATE_RESET)
588 {
589 /* Allocate lock resource and initialize it */
590 huart->Lock = HAL_UNLOCKED;
591
592 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
593 UART_InitCallbacksToDefault(huart);
594
595 if (huart->MspInitCallback == NULL)
596 {
597 huart->MspInitCallback = HAL_UART_MspInit;
598 }
599
600 /* Init the low level hardware */
601 huart->MspInitCallback(huart);
602 #else
603 /* Init the low level hardware : GPIO, CLOCK */
604 HAL_UART_MspInit(huart);
605 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
606 }
607
608 huart->gState = HAL_UART_STATE_BUSY;
609
610 /* Disable the Peripheral */
611 __HAL_UART_DISABLE(huart);
612
613 /* Set the UART Communication parameters */
614 if (UART_SetConfig(huart) == HAL_ERROR)
615 {
616 return HAL_ERROR;
617 }
618
619 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
620 {
621 UART_AdvFeatureConfig(huart);
622 }
623
624 /* In multiprocessor mode, the following bits must be kept cleared:
625 - LINEN and CLKEN bits in the USART_CR2 register,
626 - SCEN, HDSEL and IREN bits in the USART_CR3 register. */
627 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
628 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
629
630 if (WakeUpMethod == UART_WAKEUPMETHOD_ADDRESSMARK)
631 {
632 /* If address mark wake up method is chosen, set the USART address node */
633 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)Address << UART_CR2_ADDRESS_LSB_POS));
634 }
635
636 /* Set the wake up method by setting the WAKE bit in the CR1 register */
637 MODIFY_REG(huart->Instance->CR1, USART_CR1_WAKE, WakeUpMethod);
638
639 /* Enable the Peripheral */
640 __HAL_UART_ENABLE(huart);
641
642 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
643 return (UART_CheckIdleState(huart));
644 }
645
646
647 /**
648 * @brief DeInitialize the UART peripheral.
649 * @param huart UART handle.
650 * @retval HAL status
651 */
HAL_UART_DeInit(UART_HandleTypeDef * huart)652 HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
653 {
654 /* Check the UART handle allocation */
655 if (huart == NULL)
656 {
657 return HAL_ERROR;
658 }
659
660 /* Check the parameters */
661 assert_param((IS_UART_INSTANCE(huart->Instance)) || (IS_LPUART_INSTANCE(huart->Instance)));
662
663 huart->gState = HAL_UART_STATE_BUSY;
664
665 /* Disable the Peripheral */
666 __HAL_UART_DISABLE(huart);
667
668 huart->Instance->CR1 = 0x0U;
669 huart->Instance->CR2 = 0x0U;
670 huart->Instance->CR3 = 0x0U;
671
672 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
673 if (huart->MspDeInitCallback == NULL)
674 {
675 huart->MspDeInitCallback = HAL_UART_MspDeInit;
676 }
677 /* DeInit the low level hardware */
678 huart->MspDeInitCallback(huart);
679 #else
680 /* DeInit the low level hardware */
681 HAL_UART_MspDeInit(huart);
682 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
683
684 huart->ErrorCode = HAL_UART_ERROR_NONE;
685 huart->gState = HAL_UART_STATE_RESET;
686 huart->RxState = HAL_UART_STATE_RESET;
687
688 /* Process Unlock */
689 __HAL_UNLOCK(huart);
690
691 return HAL_OK;
692 }
693
694 /**
695 * @brief Initialize the UART MSP.
696 * @param huart UART handle.
697 * @retval None
698 */
HAL_UART_MspInit(UART_HandleTypeDef * huart)699 __weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
700 {
701 /* Prevent unused argument(s) compilation warning */
702 UNUSED(huart);
703
704 /* NOTE : This function should not be modified, when the callback is needed,
705 the HAL_UART_MspInit can be implemented in the user file
706 */
707 }
708
709 /**
710 * @brief DeInitialize the UART MSP.
711 * @param huart UART handle.
712 * @retval None
713 */
HAL_UART_MspDeInit(UART_HandleTypeDef * huart)714 __weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
715 {
716 /* Prevent unused argument(s) compilation warning */
717 UNUSED(huart);
718
719 /* NOTE : This function should not be modified, when the callback is needed,
720 the HAL_UART_MspDeInit can be implemented in the user file
721 */
722 }
723
724 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
725 /**
726 * @brief Register a User UART Callback
727 * To be used instead of the weak predefined callback
728 * @param huart uart handle
729 * @param CallbackID ID of the callback to be registered
730 * This parameter can be one of the following values:
731 * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
732 * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
733 * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
734 * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
735 * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
736 * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
737 * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
738 * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
739 * @arg @ref HAL_UART_WAKEUP_CB_ID Wakeup Callback ID
740 * @arg @ref HAL_UART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
741 * @arg @ref HAL_UART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
742 * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
743 * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
744 * @param pCallback pointer to the Callback function
745 * @retval HAL status
746 */
HAL_UART_RegisterCallback(UART_HandleTypeDef * huart,HAL_UART_CallbackIDTypeDef CallbackID,pUART_CallbackTypeDef pCallback)747 HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID, pUART_CallbackTypeDef pCallback)
748 {
749 HAL_StatusTypeDef status = HAL_OK;
750
751 if (pCallback == NULL)
752 {
753 /* Update the error code */
754 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
755
756 return HAL_ERROR;
757 }
758 /* Process locked */
759 __HAL_LOCK(huart);
760
761 if (huart->gState == HAL_UART_STATE_READY)
762 {
763 switch (CallbackID)
764 {
765 case HAL_UART_TX_HALFCOMPLETE_CB_ID :
766 huart->TxHalfCpltCallback = pCallback;
767 break;
768
769 case HAL_UART_TX_COMPLETE_CB_ID :
770 huart->TxCpltCallback = pCallback;
771 break;
772
773 case HAL_UART_RX_HALFCOMPLETE_CB_ID :
774 huart->RxHalfCpltCallback = pCallback;
775 break;
776
777 case HAL_UART_RX_COMPLETE_CB_ID :
778 huart->RxCpltCallback = pCallback;
779 break;
780
781 case HAL_UART_ERROR_CB_ID :
782 huart->ErrorCallback = pCallback;
783 break;
784
785 case HAL_UART_ABORT_COMPLETE_CB_ID :
786 huart->AbortCpltCallback = pCallback;
787 break;
788
789 case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
790 huart->AbortTransmitCpltCallback = pCallback;
791 break;
792
793 case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
794 huart->AbortReceiveCpltCallback = pCallback;
795 break;
796
797 case HAL_UART_WAKEUP_CB_ID :
798 huart->WakeupCallback = pCallback;
799 break;
800
801 #if defined(USART_CR1_FIFOEN)
802 case HAL_UART_RX_FIFO_FULL_CB_ID :
803 huart->RxFifoFullCallback = pCallback;
804 break;
805
806 case HAL_UART_TX_FIFO_EMPTY_CB_ID :
807 huart->TxFifoEmptyCallback = pCallback;
808 break;
809 #endif
810
811 case HAL_UART_MSPINIT_CB_ID :
812 huart->MspInitCallback = pCallback;
813 break;
814
815 case HAL_UART_MSPDEINIT_CB_ID :
816 huart->MspDeInitCallback = pCallback;
817 break;
818
819 default :
820 /* Update the error code */
821 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
822
823 /* Return error status */
824 status = HAL_ERROR;
825 break;
826 }
827 }
828 else if (huart->gState == HAL_UART_STATE_RESET)
829 {
830 switch (CallbackID)
831 {
832 case HAL_UART_MSPINIT_CB_ID :
833 huart->MspInitCallback = pCallback;
834 break;
835
836 case HAL_UART_MSPDEINIT_CB_ID :
837 huart->MspDeInitCallback = pCallback;
838 break;
839
840 default :
841 /* Update the error code */
842 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
843
844 /* Return error status */
845 status = HAL_ERROR;
846 break;
847 }
848 }
849 else
850 {
851 /* Update the error code */
852 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
853
854 /* Return error status */
855 status = HAL_ERROR;
856 }
857
858 /* Release Lock */
859 __HAL_UNLOCK(huart);
860
861 return status;
862 }
863
864 /**
865 * @brief Unregister an UART Callback
866 * UART callaback is redirected to the weak predefined callback
867 * @param huart uart handle
868 * @param CallbackID ID of the callback to be unregistered
869 * This parameter can be one of the following values:
870 * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
871 * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
872 * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
873 * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
874 * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
875 * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
876 * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
877 * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
878 * @arg @ref HAL_UART_WAKEUP_CB_ID Wakeup Callback ID
879 * @arg @ref HAL_UART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
880 * @arg @ref HAL_UART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
881 * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
882 * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
883 * @retval HAL status
884 */
HAL_UART_UnRegisterCallback(UART_HandleTypeDef * huart,HAL_UART_CallbackIDTypeDef CallbackID)885 HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID)
886 {
887 HAL_StatusTypeDef status = HAL_OK;
888
889 /* Process locked */
890 __HAL_LOCK(huart);
891
892 if (HAL_UART_STATE_READY == huart->gState)
893 {
894 switch (CallbackID)
895 {
896 case HAL_UART_TX_HALFCOMPLETE_CB_ID :
897 huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
898 break;
899
900 case HAL_UART_TX_COMPLETE_CB_ID :
901 huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */
902 break;
903
904 case HAL_UART_RX_HALFCOMPLETE_CB_ID :
905 huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
906 break;
907
908 case HAL_UART_RX_COMPLETE_CB_ID :
909 huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */
910 break;
911
912 case HAL_UART_ERROR_CB_ID :
913 huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */
914 break;
915
916 case HAL_UART_ABORT_COMPLETE_CB_ID :
917 huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
918 break;
919
920 case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
921 huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
922 break;
923
924 case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
925 huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
926 break;
927
928 case HAL_UART_WAKEUP_CB_ID :
929 huart->WakeupCallback = HAL_UARTEx_WakeupCallback; /* Legacy weak WakeupCallback */
930 break;
931
932 #if defined(USART_CR1_FIFOEN)
933 case HAL_UART_RX_FIFO_FULL_CB_ID :
934 huart->RxFifoFullCallback = HAL_UARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */
935 break;
936
937 case HAL_UART_TX_FIFO_EMPTY_CB_ID :
938 huart->TxFifoEmptyCallback = HAL_UARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */
939 break;
940 #endif
941
942 case HAL_UART_MSPINIT_CB_ID :
943 huart->MspInitCallback = HAL_UART_MspInit; /* Legacy weak MspInitCallback */
944 break;
945
946 case HAL_UART_MSPDEINIT_CB_ID :
947 huart->MspDeInitCallback = HAL_UART_MspDeInit; /* Legacy weak MspDeInitCallback */
948 break;
949
950 default :
951 /* Update the error code */
952 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
953
954 /* Return error status */
955 status = HAL_ERROR;
956 break;
957 }
958 }
959 else if (HAL_UART_STATE_RESET == huart->gState)
960 {
961 switch (CallbackID)
962 {
963 case HAL_UART_MSPINIT_CB_ID :
964 huart->MspInitCallback = HAL_UART_MspInit;
965 break;
966
967 case HAL_UART_MSPDEINIT_CB_ID :
968 huart->MspDeInitCallback = HAL_UART_MspDeInit;
969 break;
970
971 default :
972 /* Update the error code */
973 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
974
975 /* Return error status */
976 status = HAL_ERROR;
977 break;
978 }
979 }
980 else
981 {
982 /* Update the error code */
983 huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
984
985 /* Return error status */
986 status = HAL_ERROR;
987 }
988
989 /* Release Lock */
990 __HAL_UNLOCK(huart);
991
992 return status;
993 }
994 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
995
996 /**
997 * @}
998 */
999
1000 /** @defgroup UART_Exported_Functions_Group2 IO operation functions
1001 * @brief UART Transmit/Receive functions
1002 *
1003 @verbatim
1004 ===============================================================================
1005 ##### IO operation functions #####
1006 ===============================================================================
1007 This subsection provides a set of functions allowing to manage the UART asynchronous
1008 and Half duplex data transfers.
1009
1010 (#) There are two mode of transfer:
1011 (+) Blocking mode: The communication is performed in polling mode.
1012 The HAL status of all data processing is returned by the same function
1013 after finishing transfer.
1014 (+) Non-Blocking mode: The communication is performed using Interrupts
1015 or DMA, These API's return the HAL status.
1016 The end of the data processing will be indicated through the
1017 dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
1018 using DMA mode.
1019 The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
1020 will be executed respectively at the end of the transmit or Receive process
1021 The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected
1022
1023 (#) Blocking mode API's are :
1024 (+) HAL_UART_Transmit()
1025 (+) HAL_UART_Receive()
1026
1027 (#) Non-Blocking mode API's with Interrupt are :
1028 (+) HAL_UART_Transmit_IT()
1029 (+) HAL_UART_Receive_IT()
1030 (+) HAL_UART_IRQHandler()
1031
1032 (#) Non-Blocking mode API's with DMA are :
1033 (+) HAL_UART_Transmit_DMA()
1034 (+) HAL_UART_Receive_DMA()
1035 (+) HAL_UART_DMAPause()
1036 (+) HAL_UART_DMAResume()
1037 (+) HAL_UART_DMAStop()
1038
1039 (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
1040 (+) HAL_UART_TxHalfCpltCallback()
1041 (+) HAL_UART_TxCpltCallback()
1042 (+) HAL_UART_RxHalfCpltCallback()
1043 (+) HAL_UART_RxCpltCallback()
1044 (+) HAL_UART_ErrorCallback()
1045
1046 (#) Non-Blocking mode transfers could be aborted using Abort API's :
1047 (+) HAL_UART_Abort()
1048 (+) HAL_UART_AbortTransmit()
1049 (+) HAL_UART_AbortReceive()
1050 (+) HAL_UART_Abort_IT()
1051 (+) HAL_UART_AbortTransmit_IT()
1052 (+) HAL_UART_AbortReceive_IT()
1053
1054 (#) For Abort services based on interrupts (HAL_UART_Abortxxx_IT), a set of Abort Complete Callbacks are provided:
1055 (+) HAL_UART_AbortCpltCallback()
1056 (+) HAL_UART_AbortTransmitCpltCallback()
1057 (+) HAL_UART_AbortReceiveCpltCallback()
1058
1059 (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
1060 Errors are handled as follows :
1061 (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
1062 to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception .
1063 Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type,
1064 and HAL_UART_ErrorCallback() user callback is executed. Transfer is kept ongoing on UART side.
1065 If user wants to abort it, Abort services should be called by user.
1066 (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
1067 This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
1068 Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback() user callback is executed.
1069
1070 -@- In the Half duplex communication, it is forbidden to run the transmit
1071 and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful.
1072
1073 @endverbatim
1074 * @{
1075 */
1076
1077 /**
1078 * @brief Send an amount of data in blocking mode.
1079 * @note When FIFO mode is enabled, writing a data in the TDR register adds one
1080 * data to the TXFIFO. Write operations to the TDR register are performed
1081 * when TXFNF flag is set. From hardware perspective, TXFNF flag and
1082 * TXE are mapped on the same bit-field.
1083 * @param huart UART handle.
1084 * @param pData Pointer to data buffer.
1085 * @param Size Amount of data to be sent.
1086 * @param Timeout Timeout duration.
1087 * @retval HAL status
1088 */
HAL_UART_Transmit(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size,uint32_t Timeout)1089 HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
1090 {
1091 uint16_t *tmp;
1092 uint32_t tickstart = 0U;
1093
1094 /* Check that a Tx process is not already ongoing */
1095 if (huart->gState == HAL_UART_STATE_READY)
1096 {
1097 if ((pData == NULL) || (Size == 0U))
1098 {
1099 return HAL_ERROR;
1100 }
1101
1102 /* Process Locked */
1103 __HAL_LOCK(huart);
1104
1105 huart->ErrorCode = HAL_UART_ERROR_NONE;
1106 huart->gState = HAL_UART_STATE_BUSY_TX;
1107
1108 /* Init tickstart for timeout managment*/
1109 tickstart = HAL_GetTick();
1110
1111 huart->TxXferSize = Size;
1112 huart->TxXferCount = Size;
1113
1114 while (huart->TxXferCount > 0U)
1115 {
1116 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
1117 {
1118 return HAL_TIMEOUT;
1119 }
1120 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1121 {
1122 tmp = (uint16_t *) pData;
1123 huart->Instance->TDR = (*tmp & (uint16_t)0x01FFU);
1124 pData += 2U;
1125 }
1126 else
1127 {
1128 huart->Instance->TDR = (*pData++ & (uint8_t)0xFFU);
1129 }
1130 huart->TxXferCount--;
1131 }
1132
1133 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
1134 {
1135 return HAL_TIMEOUT;
1136 }
1137
1138 /* At end of Tx process, restore huart->gState to Ready */
1139 huart->gState = HAL_UART_STATE_READY;
1140
1141 /* Process Unlocked */
1142 __HAL_UNLOCK(huart);
1143
1144 return HAL_OK;
1145 }
1146 else
1147 {
1148 return HAL_BUSY;
1149 }
1150 }
1151
1152 /**
1153 * @brief Receive an amount of data in blocking mode.
1154 * @note When FIFO mode is enabled, the RXFNE flag is set as long as the RXFIFO
1155 * is not empty. Read operations from the RDR register are performed when
1156 * RXFNE flag is set. From hardware perspective, RXFNE flag and
1157 * RXNE are mapped on the same bit-field.
1158 * @param huart UART handle.
1159 * @param pData Pointer to data buffer.
1160 * @param Size Amount of data to be received.
1161 * @param Timeout Timeout duration.
1162 * @retval HAL status
1163 */
HAL_UART_Receive(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size,uint32_t Timeout)1164 HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
1165 {
1166 uint16_t *tmp;
1167 uint16_t uhMask;
1168 uint32_t tickstart = 0;
1169
1170 /* Check that a Rx process is not already ongoing */
1171 if (huart->RxState == HAL_UART_STATE_READY)
1172 {
1173 if ((pData == NULL) || (Size == 0U))
1174 {
1175 return HAL_ERROR;
1176 }
1177
1178 /* Process Locked */
1179 __HAL_LOCK(huart);
1180
1181 huart->ErrorCode = HAL_UART_ERROR_NONE;
1182 huart->RxState = HAL_UART_STATE_BUSY_RX;
1183
1184 /* Init tickstart for timeout managment*/
1185 tickstart = HAL_GetTick();
1186
1187 huart->RxXferSize = Size;
1188 huart->RxXferCount = Size;
1189
1190 /* Computation of UART mask to apply to RDR register */
1191 UART_MASK_COMPUTATION(huart);
1192 uhMask = huart->Mask;
1193
1194 /* as long as data have to be received */
1195 while (huart->RxXferCount > 0U)
1196 {
1197 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
1198 {
1199 return HAL_TIMEOUT;
1200 }
1201 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1202 {
1203 tmp = (uint16_t *) pData ;
1204 *tmp = (uint16_t)(huart->Instance->RDR & uhMask);
1205 pData += 2U;
1206 }
1207 else
1208 {
1209 *pData++ = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
1210 }
1211 huart->RxXferCount--;
1212 }
1213
1214 /* At end of Rx process, restore huart->RxState to Ready */
1215 huart->RxState = HAL_UART_STATE_READY;
1216
1217 /* Process Unlocked */
1218 __HAL_UNLOCK(huart);
1219
1220 return HAL_OK;
1221 }
1222 else
1223 {
1224 return HAL_BUSY;
1225 }
1226 }
1227
1228 /**
1229 * @brief Send an amount of data in interrupt mode.
1230 * @param huart UART handle.
1231 * @param pData Pointer to data buffer.
1232 * @param Size Amount of data to be sent.
1233 * @retval HAL status
1234 */
HAL_UART_Transmit_IT(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)1235 HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1236 {
1237 /* Check that a Tx process is not already ongoing */
1238 if (huart->gState == HAL_UART_STATE_READY)
1239 {
1240 if ((pData == NULL) || (Size == 0U))
1241 {
1242 return HAL_ERROR;
1243 }
1244
1245 /* Process Locked */
1246 __HAL_LOCK(huart);
1247
1248 huart->pTxBuffPtr = pData;
1249 huart->TxXferSize = Size;
1250 huart->TxXferCount = Size;
1251 huart->TxISR = NULL;
1252
1253 huart->ErrorCode = HAL_UART_ERROR_NONE;
1254 huart->gState = HAL_UART_STATE_BUSY_TX;
1255
1256 #if defined(USART_CR1_FIFOEN)
1257 /* Configure Tx interrupt processing */
1258 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1259 {
1260 /* Set the Tx ISR function pointer according to the data word length */
1261 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1262 {
1263 huart->TxISR = UART_TxISR_16BIT_FIFOEN;
1264 }
1265 else
1266 {
1267 huart->TxISR = UART_TxISR_8BIT_FIFOEN;
1268 }
1269
1270 /* Process Unlocked */
1271 __HAL_UNLOCK(huart);
1272
1273 /* Enable the TX FIFO threshold interrupt */
1274 SET_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
1275 }
1276 else
1277 #endif
1278 {
1279 /* Set the Tx ISR function pointer according to the data word length */
1280 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1281 {
1282 huart->TxISR = UART_TxISR_16BIT;
1283 }
1284 else
1285 {
1286 huart->TxISR = UART_TxISR_8BIT;
1287 }
1288
1289 /* Process Unlocked */
1290 __HAL_UNLOCK(huart);
1291
1292 /* Enable the Transmit Data Register Empty interrupt */
1293 #if defined(USART_CR1_FIFOEN)
1294 SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
1295 #else
1296 SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE);
1297 #endif
1298 }
1299
1300 return HAL_OK;
1301 }
1302 else
1303 {
1304 return HAL_BUSY;
1305 }
1306 }
1307
1308 /**
1309 * @brief Receive an amount of data in interrupt mode.
1310 * @param huart UART handle.
1311 * @param pData Pointer to data buffer.
1312 * @param Size Amount of data to be received.
1313 * @retval HAL status
1314 */
HAL_UART_Receive_IT(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)1315 HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1316 {
1317 /* Check that a Rx process is not already ongoing */
1318 if (huart->RxState == HAL_UART_STATE_READY)
1319 {
1320 if ((pData == NULL) || (Size == 0U))
1321 {
1322 return HAL_ERROR;
1323 }
1324
1325 /* Process Locked */
1326 __HAL_LOCK(huart);
1327
1328 huart->pRxBuffPtr = pData;
1329 huart->RxXferSize = Size;
1330 huart->RxXferCount = Size;
1331 huart->RxISR = NULL;
1332
1333 /* Computation of UART mask to apply to RDR register */
1334 UART_MASK_COMPUTATION(huart);
1335
1336 huart->ErrorCode = HAL_UART_ERROR_NONE;
1337 huart->RxState = HAL_UART_STATE_BUSY_RX;
1338
1339 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
1340 SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
1341
1342 #if defined(USART_CR1_FIFOEN)
1343 /* Configure Rx interrupt processing*/
1344 if ((huart->FifoMode == UART_FIFOMODE_ENABLE) && (Size >= huart->NbRxDataToProcess))
1345 {
1346 /* Set the Rx ISR function pointer according to the data word length */
1347 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1348 {
1349 huart->RxISR = UART_RxISR_16BIT_FIFOEN;
1350 }
1351 else
1352 {
1353 huart->RxISR = UART_RxISR_8BIT_FIFOEN;
1354 }
1355
1356 /* Process Unlocked */
1357 __HAL_UNLOCK(huart);
1358
1359 /* Enable the UART Parity Error interrupt and RX FIFO Threshold interrupt */
1360 SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1361 SET_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
1362 }
1363 else
1364 #endif
1365 {
1366 /* Set the Rx ISR function pointer according to the data word length */
1367 if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
1368 {
1369 huart->RxISR = UART_RxISR_16BIT;
1370 }
1371 else
1372 {
1373 huart->RxISR = UART_RxISR_8BIT;
1374 }
1375
1376 /* Process Unlocked */
1377 __HAL_UNLOCK(huart);
1378
1379 /* Enable the UART Parity Error interrupt and Data Register Not Empty interrupt */
1380 #if defined(USART_CR1_FIFOEN)
1381 SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
1382 #else
1383 SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
1384 #endif
1385 }
1386
1387 return HAL_OK;
1388 }
1389 else
1390 {
1391 return HAL_BUSY;
1392 }
1393 }
1394
1395 /**
1396 * @brief Send an amount of data in DMA mode.
1397 * @param huart UART handle.
1398 * @param pData Pointer to data buffer.
1399 * @param Size Amount of data to be sent.
1400 * @retval HAL status
1401 */
HAL_UART_Transmit_DMA(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)1402 HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1403 {
1404 /* Check that a Tx process is not already ongoing */
1405 if (huart->gState == HAL_UART_STATE_READY)
1406 {
1407 if ((pData == NULL) || (Size == 0U))
1408 {
1409 return HAL_ERROR;
1410 }
1411
1412 /* Process Locked */
1413 __HAL_LOCK(huart);
1414
1415 huart->pTxBuffPtr = pData;
1416 huart->TxXferSize = Size;
1417 huart->TxXferCount = Size;
1418
1419 huart->ErrorCode = HAL_UART_ERROR_NONE;
1420 huart->gState = HAL_UART_STATE_BUSY_TX;
1421
1422 /* Set the UART DMA transfer complete callback */
1423 huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
1424
1425 /* Set the UART DMA Half transfer complete callback */
1426 huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
1427
1428 /* Set the DMA error callback */
1429 huart->hdmatx->XferErrorCallback = UART_DMAError;
1430
1431 /* Set the DMA abort callback */
1432 huart->hdmatx->XferAbortCallback = NULL;
1433
1434 /* Enable the UART transmit DMA channel */
1435 HAL_DMA_Start_IT(huart->hdmatx, (uint32_t)huart->pTxBuffPtr, (uint32_t)&huart->Instance->TDR, Size);
1436
1437 /* Clear the TC flag in the ICR register */
1438 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF);
1439
1440 /* Process Unlocked */
1441 __HAL_UNLOCK(huart);
1442
1443 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1444 in the UART CR3 register */
1445 SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1446
1447 return HAL_OK;
1448 }
1449 else
1450 {
1451 return HAL_BUSY;
1452 }
1453 }
1454
1455 /**
1456 * @brief Receive an amount of data in DMA mode.
1457 * @note When the UART parity is enabled (PCE = 1), the received data contain
1458 * the parity bit (MSB position).
1459 * @param huart UART handle.
1460 * @param pData Pointer to data buffer.
1461 * @param Size Amount of data to be received.
1462 * @retval HAL status
1463 */
HAL_UART_Receive_DMA(UART_HandleTypeDef * huart,uint8_t * pData,uint16_t Size)1464 HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
1465 {
1466 /* Check that a Rx process is not already ongoing */
1467 if (huart->RxState == HAL_UART_STATE_READY)
1468 {
1469 if ((pData == NULL) || (Size == 0U))
1470 {
1471 return HAL_ERROR;
1472 }
1473
1474 /* Process Locked */
1475 __HAL_LOCK(huart);
1476
1477 huart->pRxBuffPtr = pData;
1478 huart->RxXferSize = Size;
1479
1480 huart->ErrorCode = HAL_UART_ERROR_NONE;
1481 huart->RxState = HAL_UART_STATE_BUSY_RX;
1482
1483 /* Set the UART DMA transfer complete callback */
1484 huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
1485
1486 /* Set the UART DMA Half transfer complete callback */
1487 huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
1488
1489 /* Set the DMA error callback */
1490 huart->hdmarx->XferErrorCallback = UART_DMAError;
1491
1492 /* Set the DMA abort callback */
1493 huart->hdmarx->XferAbortCallback = NULL;
1494
1495 /* Enable the DMA channel */
1496 HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, (uint32_t)huart->pRxBuffPtr, Size);
1497
1498 /* Process Unlocked */
1499 __HAL_UNLOCK(huart);
1500
1501 /* Enable the UART Parity Error Interrupt */
1502 SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1503
1504 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
1505 SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
1506
1507 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1508 in the UART CR3 register */
1509 SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1510
1511 return HAL_OK;
1512 }
1513 else
1514 {
1515 return HAL_BUSY;
1516 }
1517 }
1518
1519 /**
1520 * @brief Pause the DMA Transfer.
1521 * @param huart UART handle.
1522 * @retval HAL status
1523 */
HAL_UART_DMAPause(UART_HandleTypeDef * huart)1524 HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
1525 {
1526 /* Process Locked */
1527 __HAL_LOCK(huart);
1528
1529 if ((huart->gState == HAL_UART_STATE_BUSY_TX) &&
1530 (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)))
1531 {
1532 /* Disable the UART DMA Tx request */
1533 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1534 }
1535 if ((huart->RxState == HAL_UART_STATE_BUSY_RX) &&
1536 (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)))
1537 {
1538 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
1539 CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1540 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
1541
1542 /* Disable the UART DMA Rx request */
1543 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1544 }
1545
1546 /* Process Unlocked */
1547 __HAL_UNLOCK(huart);
1548
1549 return HAL_OK;
1550 }
1551
1552 /**
1553 * @brief Resume the DMA Transfer.
1554 * @param huart UART handle.
1555 * @retval HAL status
1556 */
HAL_UART_DMAResume(UART_HandleTypeDef * huart)1557 HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
1558 {
1559 /* Process Locked */
1560 __HAL_LOCK(huart);
1561
1562 if (huart->gState == HAL_UART_STATE_BUSY_TX)
1563 {
1564 /* Enable the UART DMA Tx request */
1565 SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1566 }
1567 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
1568 {
1569 /* Clear the Overrun flag before resuming the Rx transfer */
1570 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
1571
1572 /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */
1573 SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
1574 SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
1575
1576 /* Enable the UART DMA Rx request */
1577 SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1578 }
1579
1580 /* Process Unlocked */
1581 __HAL_UNLOCK(huart);
1582
1583 return HAL_OK;
1584 }
1585
1586 /**
1587 * @brief Stop the DMA Transfer.
1588 * @param huart UART handle.
1589 * @retval HAL status
1590 */
HAL_UART_DMAStop(UART_HandleTypeDef * huart)1591 HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
1592 {
1593 /* The Lock is not implemented on this API to allow the user application
1594 to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() /
1595 HAL_UART_TxHalfCpltCallback / HAL_UART_RxHalfCpltCallback:
1596 indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
1597 interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
1598 the stream and the corresponding call back is executed. */
1599
1600 /* Stop UART DMA Tx request if ongoing */
1601 if ((huart->gState == HAL_UART_STATE_BUSY_TX) &&
1602 (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)))
1603 {
1604 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1605
1606 /* Abort the UART DMA Tx channel */
1607 if (huart->hdmatx != NULL)
1608 {
1609 HAL_DMA_Abort(huart->hdmatx);
1610 }
1611
1612 UART_EndTxTransfer(huart);
1613 }
1614
1615 /* Stop UART DMA Rx request if ongoing */
1616 if ((huart->RxState == HAL_UART_STATE_BUSY_RX) &&
1617 (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)))
1618 {
1619 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1620
1621 /* Abort the UART DMA Rx channel */
1622 if (huart->hdmarx != NULL)
1623 {
1624 HAL_DMA_Abort(huart->hdmarx);
1625 }
1626
1627 UART_EndRxTransfer(huart);
1628 }
1629
1630 return HAL_OK;
1631 }
1632
1633 /**
1634 * @brief Abort ongoing transfers (blocking mode).
1635 * @param huart UART handle.
1636 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1637 * This procedure performs following operations :
1638 * - Disable UART Interrupts (Tx and Rx)
1639 * - Disable the DMA transfer in the peripheral register (if enabled)
1640 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1641 * - Set handle State to READY
1642 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1643 * @retval HAL status
1644 */
HAL_UART_Abort(UART_HandleTypeDef * huart)1645 HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart)
1646 {
1647 #if defined(USART_CR1_FIFOEN)
1648 /* Disable TXE, TC, RXNE, PE, RXFT, TXFT and ERR (Frame error, noise error, overrun error) interrupts */
1649 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
1650 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE);
1651 #else
1652 /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1653 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
1654 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
1655 #endif
1656
1657 /* Disable the UART DMA Tx request if enabled */
1658 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1659 {
1660 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1661
1662 /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
1663 if (huart->hdmatx != NULL)
1664 {
1665 /* Set the UART DMA Abort callback to Null.
1666 No call back execution at end of DMA abort procedure */
1667 huart->hdmatx->XferAbortCallback = NULL;
1668
1669 HAL_DMA_Abort(huart->hdmatx);
1670 }
1671 }
1672
1673 /* Disable the UART DMA Rx request if enabled */
1674 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1675 {
1676 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1677
1678 /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
1679 if (huart->hdmarx != NULL)
1680 {
1681 /* Set the UART DMA Abort callback to Null.
1682 No call back execution at end of DMA abort procedure */
1683 huart->hdmarx->XferAbortCallback = NULL;
1684
1685 HAL_DMA_Abort(huart->hdmarx);
1686 }
1687 }
1688
1689 /* Reset Tx and Rx transfer counters */
1690 huart->TxXferCount = 0U;
1691 huart->RxXferCount = 0U;
1692
1693 /* Clear the Error flags in the ICR register */
1694 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
1695
1696 #if defined(USART_CR1_FIFOEN)
1697 /* Flush the whole TX FIFO (if needed) */
1698 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1699 {
1700 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
1701 }
1702 #endif
1703
1704 /* Discard the received data */
1705 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
1706
1707 /* Restore huart->gState and huart->RxState to Ready */
1708 huart->gState = HAL_UART_STATE_READY;
1709 huart->RxState = HAL_UART_STATE_READY;
1710
1711 /* Reset Handle ErrorCode to No Error */
1712 huart->ErrorCode = HAL_UART_ERROR_NONE;
1713
1714 return HAL_OK;
1715 }
1716
1717 /**
1718 * @brief Abort ongoing Transmit transfer (blocking mode).
1719 * @param huart UART handle.
1720 * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
1721 * This procedure performs following operations :
1722 * - Disable UART Interrupts (Tx)
1723 * - Disable the DMA transfer in the peripheral register (if enabled)
1724 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1725 * - Set handle State to READY
1726 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1727 * @retval HAL status
1728 */
HAL_UART_AbortTransmit(UART_HandleTypeDef * huart)1729 HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart)
1730 {
1731 #if defined(USART_CR1_FIFOEN)
1732 /* Disable TCIE, TXEIE and TXFTIE interrupts */
1733 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE));
1734 CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
1735 #else
1736 /* Disable TXEIE and TCIE interrupts */
1737 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
1738 #endif
1739
1740 /* Disable the UART DMA Tx request if enabled */
1741 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1742 {
1743 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1744
1745 /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
1746 if (huart->hdmatx != NULL)
1747 {
1748 /* Set the UART DMA Abort callback to Null.
1749 No call back execution at end of DMA abort procedure */
1750 huart->hdmatx->XferAbortCallback = NULL;
1751
1752 HAL_DMA_Abort(huart->hdmatx);
1753 }
1754 }
1755
1756 /* Reset Tx transfer counter */
1757 huart->TxXferCount = 0U;
1758
1759 #if defined(USART_CR1_FIFOEN)
1760 /* Flush the whole TX FIFO (if needed) */
1761 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1762 {
1763 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
1764 }
1765 #endif
1766
1767 /* Restore huart->gState to Ready */
1768 huart->gState = HAL_UART_STATE_READY;
1769
1770 return HAL_OK;
1771 }
1772
1773 /**
1774 * @brief Abort ongoing Receive transfer (blocking mode).
1775 * @param huart UART handle.
1776 * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
1777 * This procedure performs following operations :
1778 * - Disable UART Interrupts (Rx)
1779 * - Disable the DMA transfer in the peripheral register (if enabled)
1780 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1781 * - Set handle State to READY
1782 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1783 * @retval HAL status
1784 */
HAL_UART_AbortReceive(UART_HandleTypeDef * huart)1785 HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart)
1786 {
1787 #if defined(USART_CR1_FIFOEN)
1788 /* Disable PEIE, EIE, RXNEIE and RXFTIE interrupts */
1789 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE));
1790 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE);
1791 #else
1792 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1793 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
1794 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
1795 #endif
1796
1797 /* Disable the UART DMA Rx request if enabled */
1798 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1799 {
1800 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1801
1802 /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
1803 if (huart->hdmarx != NULL)
1804 {
1805 /* Set the UART DMA Abort callback to Null.
1806 No call back execution at end of DMA abort procedure */
1807 huart->hdmarx->XferAbortCallback = NULL;
1808
1809 HAL_DMA_Abort(huart->hdmarx);
1810 }
1811 }
1812
1813 /* Reset Rx transfer counter */
1814 huart->RxXferCount = 0U;
1815
1816 /* Clear the Error flags in the ICR register */
1817 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
1818
1819 /* Discard the received data */
1820 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
1821
1822 /* Restore huart->RxState to Ready */
1823 huart->RxState = HAL_UART_STATE_READY;
1824
1825 return HAL_OK;
1826 }
1827
1828 /**
1829 * @brief Abort ongoing transfers (Interrupt mode).
1830 * @param huart UART handle.
1831 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1832 * This procedure performs following operations :
1833 * - Disable UART Interrupts (Tx and Rx)
1834 * - Disable the DMA transfer in the peripheral register (if enabled)
1835 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1836 * - Set handle State to READY
1837 * - At abort completion, call user abort complete callback
1838 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
1839 * considered as completed only when user abort complete callback is executed (not when exiting function).
1840 * @retval HAL status
1841 */
HAL_UART_Abort_IT(UART_HandleTypeDef * huart)1842 HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart)
1843 {
1844 uint32_t abortcplt = 1U;
1845
1846 /* Disable interrupts */
1847 #if defined(USART_CR1_FIFOEN)
1848 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_TCIE | USART_CR1_RXNEIE_RXFNEIE | USART_CR1_TXEIE_TXFNFIE));
1849 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
1850 #else
1851 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
1852 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
1853 #endif
1854
1855 /* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised
1856 before any call to DMA Abort functions */
1857 /* DMA Tx Handle is valid */
1858 if (huart->hdmatx != NULL)
1859 {
1860 /* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
1861 Otherwise, set it to NULL */
1862 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1863 {
1864 huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback;
1865 }
1866 else
1867 {
1868 huart->hdmatx->XferAbortCallback = NULL;
1869 }
1870 }
1871 /* DMA Rx Handle is valid */
1872 if (huart->hdmarx != NULL)
1873 {
1874 /* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
1875 Otherwise, set it to NULL */
1876 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1877 {
1878 huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback;
1879 }
1880 else
1881 {
1882 huart->hdmarx->XferAbortCallback = NULL;
1883 }
1884 }
1885
1886 /* Disable the UART DMA Tx request if enabled */
1887 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
1888 {
1889 /* Disable DMA Tx at UART level */
1890 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
1891
1892 /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
1893 if (huart->hdmatx != NULL)
1894 {
1895 /* UART Tx DMA Abort callback has already been initialised :
1896 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
1897
1898 /* Abort DMA TX */
1899 if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
1900 {
1901 huart->hdmatx->XferAbortCallback = NULL;
1902 }
1903 else
1904 {
1905 abortcplt = 0U;
1906 }
1907 }
1908 }
1909
1910 /* Disable the UART DMA Rx request if enabled */
1911 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
1912 {
1913 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
1914
1915 /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
1916 if (huart->hdmarx != NULL)
1917 {
1918 /* UART Rx DMA Abort callback has already been initialised :
1919 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
1920
1921 /* Abort DMA RX */
1922 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
1923 {
1924 huart->hdmarx->XferAbortCallback = NULL;
1925 abortcplt = 1U;
1926 }
1927 else
1928 {
1929 abortcplt = 0U;
1930 }
1931 }
1932 }
1933
1934 /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
1935 if (abortcplt == 1U)
1936 {
1937 /* Reset Tx and Rx transfer counters */
1938 huart->TxXferCount = 0U;
1939 huart->RxXferCount = 0U;
1940
1941 /* Clear ISR function pointers */
1942 huart->RxISR = NULL;
1943 huart->TxISR = NULL;
1944
1945 /* Reset errorCode */
1946 huart->ErrorCode = HAL_UART_ERROR_NONE;
1947
1948 /* Clear the Error flags in the ICR register */
1949 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
1950
1951 #if defined(USART_CR1_FIFOEN)
1952 /* Flush the whole TX FIFO (if needed) */
1953 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
1954 {
1955 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
1956 }
1957 #endif
1958
1959 /* Discard the received data */
1960 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
1961
1962 /* Restore huart->gState and huart->RxState to Ready */
1963 huart->gState = HAL_UART_STATE_READY;
1964 huart->RxState = HAL_UART_STATE_READY;
1965
1966 /* As no DMA to be aborted, call directly user Abort complete callback */
1967 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
1968 /* Call registered Abort complete callback */
1969 huart->AbortCpltCallback(huart);
1970 #else
1971 /* Call legacy weak Abort complete callback */
1972 HAL_UART_AbortCpltCallback(huart);
1973 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
1974 }
1975
1976 return HAL_OK;
1977 }
1978
1979 /**
1980 * @brief Abort ongoing Transmit transfer (Interrupt mode).
1981 * @param huart UART handle.
1982 * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
1983 * This procedure performs following operations :
1984 * - Disable UART Interrupts (Tx)
1985 * - Disable the DMA transfer in the peripheral register (if enabled)
1986 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1987 * - Set handle State to READY
1988 * - At abort completion, call user abort complete callback
1989 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
1990 * considered as completed only when user abort complete callback is executed (not when exiting function).
1991 * @retval HAL status
1992 */
HAL_UART_AbortTransmit_IT(UART_HandleTypeDef * huart)1993 HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart)
1994 {
1995 /* Disable interrupts */
1996 #if defined(USART_CR1_FIFOEN)
1997 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE));
1998 CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
1999 #else
2000 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
2001 #endif
2002
2003 /* Disable the UART DMA Tx request if enabled */
2004 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
2005 {
2006 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
2007
2008 /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
2009 if (huart->hdmatx != NULL)
2010 {
2011 /* Set the UART DMA Abort callback :
2012 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2013 huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback;
2014
2015 /* Abort DMA TX */
2016 if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
2017 {
2018 /* Call Directly huart->hdmatx->XferAbortCallback function in case of error */
2019 huart->hdmatx->XferAbortCallback(huart->hdmatx);
2020 }
2021 }
2022 else
2023 {
2024 /* Reset Tx transfer counter */
2025 huart->TxXferCount = 0U;
2026
2027 /* Clear TxISR function pointers */
2028 huart->TxISR = NULL;
2029
2030 /* Restore huart->gState to Ready */
2031 huart->gState = HAL_UART_STATE_READY;
2032
2033 /* As no DMA to be aborted, call directly user Abort complete callback */
2034 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2035 /* Call registered Abort Transmit Complete Callback */
2036 huart->AbortTransmitCpltCallback(huart);
2037 #else
2038 /* Call legacy weak Abort Transmit Complete Callback */
2039 HAL_UART_AbortTransmitCpltCallback(huart);
2040 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2041 }
2042 }
2043 else
2044 {
2045 /* Reset Tx transfer counter */
2046 huart->TxXferCount = 0U;
2047
2048 /* Clear TxISR function pointers */
2049 huart->TxISR = NULL;
2050
2051 #if defined(USART_CR1_FIFOEN)
2052 /* Flush the whole TX FIFO (if needed) */
2053 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
2054 {
2055 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
2056 }
2057 #endif
2058
2059 /* Restore huart->gState to Ready */
2060 huart->gState = HAL_UART_STATE_READY;
2061
2062 /* As no DMA to be aborted, call directly user Abort complete callback */
2063 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2064 /* Call registered Abort Transmit Complete Callback */
2065 huart->AbortTransmitCpltCallback(huart);
2066 #else
2067 /* Call legacy weak Abort Transmit Complete Callback */
2068 HAL_UART_AbortTransmitCpltCallback(huart);
2069 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2070 }
2071
2072 return HAL_OK;
2073 }
2074
2075 /**
2076 * @brief Abort ongoing Receive transfer (Interrupt mode).
2077 * @param huart UART handle.
2078 * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
2079 * This procedure performs following operations :
2080 * - Disable UART Interrupts (Rx)
2081 * - Disable the DMA transfer in the peripheral register (if enabled)
2082 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
2083 * - Set handle State to READY
2084 * - At abort completion, call user abort complete callback
2085 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
2086 * considered as completed only when user abort complete callback is executed (not when exiting function).
2087 * @retval HAL status
2088 */
HAL_UART_AbortReceive_IT(UART_HandleTypeDef * huart)2089 HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart)
2090 {
2091 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
2092 #if defined(USART_CR1_FIFOEN)
2093 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE));
2094 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
2095 #else
2096 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
2097 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
2098 #endif
2099
2100 /* Disable the UART DMA Rx request if enabled */
2101 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2102 {
2103 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2104
2105 /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
2106 if (huart->hdmarx != NULL)
2107 {
2108 /* Set the UART DMA Abort callback :
2109 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
2110 huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback;
2111
2112 /* Abort DMA RX */
2113 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
2114 {
2115 /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
2116 huart->hdmarx->XferAbortCallback(huart->hdmarx);
2117 }
2118 }
2119 else
2120 {
2121 /* Reset Rx transfer counter */
2122 huart->RxXferCount = 0U;
2123
2124 /* Clear RxISR function pointer */
2125 huart->pRxBuffPtr = NULL;
2126
2127 /* Clear the Error flags in the ICR register */
2128 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
2129
2130 /* Discard the received data */
2131 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
2132
2133 /* Restore huart->RxState to Ready */
2134 huart->RxState = HAL_UART_STATE_READY;
2135
2136 /* As no DMA to be aborted, call directly user Abort complete callback */
2137 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2138 /* Call registered Abort Receive Complete Callback */
2139 huart->AbortReceiveCpltCallback(huart);
2140 #else
2141 /* Call legacy weak Abort Receive Complete Callback */
2142 HAL_UART_AbortReceiveCpltCallback(huart);
2143 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2144 }
2145 }
2146 else
2147 {
2148 /* Reset Rx transfer counter */
2149 huart->RxXferCount = 0U;
2150
2151 /* Clear RxISR function pointer */
2152 huart->pRxBuffPtr = NULL;
2153
2154 /* Clear the Error flags in the ICR register */
2155 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
2156
2157 /* Restore huart->RxState to Ready */
2158 huart->RxState = HAL_UART_STATE_READY;
2159
2160 /* As no DMA to be aborted, call directly user Abort complete callback */
2161 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2162 /* Call registered Abort Receive Complete Callback */
2163 huart->AbortReceiveCpltCallback(huart);
2164 #else
2165 /* Call legacy weak Abort Receive Complete Callback */
2166 HAL_UART_AbortReceiveCpltCallback(huart);
2167 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2168 }
2169
2170 return HAL_OK;
2171 }
2172
2173 /**
2174 * @brief Handle UART interrupt request.
2175 * @param huart UART handle.
2176 * @retval None
2177 */
HAL_UART_IRQHandler(UART_HandleTypeDef * huart)2178 void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
2179 {
2180 uint32_t isrflags = READ_REG(huart->Instance->ISR);
2181 uint32_t cr1its = READ_REG(huart->Instance->CR1);
2182 uint32_t cr3its = READ_REG(huart->Instance->CR3);
2183 uint32_t errorflags;
2184
2185 /* If no error occurs */
2186 errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE));
2187 if (errorflags == RESET)
2188 {
2189 /* UART in mode Receiver ---------------------------------------------------*/
2190 #if defined(USART_CR1_FIFOEN)
2191 if (((isrflags & USART_ISR_RXNE_RXFNE) != RESET)
2192 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != RESET)
2193 || ((cr3its & USART_CR3_RXFTIE) != RESET)))
2194 #else
2195 if (((isrflags & USART_ISR_RXNE) != RESET)
2196 && ((cr1its & USART_CR1_RXNEIE) != RESET))
2197 #endif
2198 {
2199 if (huart->RxISR != NULL)
2200 {
2201 huart->RxISR(huart);
2202 }
2203 return;
2204 }
2205 }
2206
2207 /* If some errors occur */
2208 #if defined(USART_CR1_FIFOEN)
2209 if ((errorflags != RESET)
2210 && ((((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != RESET)
2211 || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)) != RESET))))
2212 #else
2213 if ((errorflags != RESET)
2214 && (((cr3its & USART_CR3_EIE) != RESET)
2215 || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
2216 #endif
2217 {
2218 /* UART parity error interrupt occurred -------------------------------------*/
2219 if (((isrflags & USART_ISR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
2220 {
2221 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
2222
2223 huart->ErrorCode |= HAL_UART_ERROR_PE;
2224 }
2225
2226 /* UART frame error interrupt occurred --------------------------------------*/
2227 if (((isrflags & USART_ISR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
2228 {
2229 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
2230
2231 huart->ErrorCode |= HAL_UART_ERROR_FE;
2232 }
2233
2234 /* UART noise error interrupt occurred --------------------------------------*/
2235 if (((isrflags & USART_ISR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
2236 {
2237 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
2238
2239 huart->ErrorCode |= HAL_UART_ERROR_NE;
2240 }
2241
2242 /* UART Over-Run interrupt occurred -----------------------------------------*/
2243 #if defined(USART_CR1_FIFOEN)
2244 if (((isrflags & USART_ISR_ORE) != RESET)
2245 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != RESET) ||
2246 ((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != RESET)))
2247 #else
2248 if (((isrflags & USART_ISR_ORE) != RESET)
2249 && (((cr1its & USART_CR1_RXNEIE) != RESET) ||
2250 ((cr3its & USART_CR3_EIE) != RESET)))
2251 #endif
2252 {
2253 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
2254
2255 huart->ErrorCode |= HAL_UART_ERROR_ORE;
2256 }
2257
2258 /* Call UART Error Call back function if need be --------------------------*/
2259 if (huart->ErrorCode != HAL_UART_ERROR_NONE)
2260 {
2261 /* UART in mode Receiver ---------------------------------------------------*/
2262 #if defined(USART_CR1_FIFOEN)
2263 if (((isrflags & USART_ISR_RXNE_RXFNE) != RESET)
2264 && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != RESET)
2265 || ((cr3its & USART_CR3_RXFTIE) != RESET)))
2266 #else
2267 if (((isrflags & USART_ISR_RXNE) != RESET)
2268 && ((cr1its & USART_CR1_RXNEIE) != RESET))
2269 #endif
2270 {
2271 if (huart->RxISR != NULL)
2272 {
2273 huart->RxISR(huart);
2274 }
2275 }
2276
2277 /* If Overrun error occurs, or if any error occurs in DMA mode reception,
2278 consider error as blocking */
2279 if (((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) ||
2280 (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)))
2281 {
2282 /* Blocking error : transfer is aborted
2283 Set the UART state ready to be able to start again the process,
2284 Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
2285 UART_EndRxTransfer(huart);
2286
2287 /* Disable the UART DMA Rx request if enabled */
2288 if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
2289 {
2290 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
2291
2292 /* Abort the UART DMA Rx channel */
2293 if (huart->hdmarx != NULL)
2294 {
2295 /* Set the UART DMA Abort callback :
2296 will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */
2297 huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;
2298
2299 /* Abort DMA RX */
2300 if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
2301 {
2302 /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
2303 huart->hdmarx->XferAbortCallback(huart->hdmarx);
2304 }
2305 }
2306 else
2307 {
2308 /* Call user error callback */
2309 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2310 /*Call registered error callback*/
2311 huart->ErrorCallback(huart);
2312 #else
2313 /*Call legacy weak error callback*/
2314 HAL_UART_ErrorCallback(huart);
2315 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2316
2317 }
2318 }
2319 else
2320 {
2321 /* Call user error callback */
2322 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2323 /*Call registered error callback*/
2324 huart->ErrorCallback(huart);
2325 #else
2326 /*Call legacy weak error callback*/
2327 HAL_UART_ErrorCallback(huart);
2328 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2329 }
2330 }
2331 else
2332 {
2333 /* Non Blocking error : transfer could go on.
2334 Error is notified to user through user error callback */
2335 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2336 /*Call registered error callback*/
2337 huart->ErrorCallback(huart);
2338 #else
2339 /*Call legacy weak error callback*/
2340 HAL_UART_ErrorCallback(huart);
2341 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2342 huart->ErrorCode = HAL_UART_ERROR_NONE;
2343 }
2344 }
2345 return;
2346
2347 } /* End if some error occurs */
2348
2349 /* UART wakeup from Stop mode interrupt occurred ---------------------------*/
2350 if (((isrflags & USART_ISR_WUF) != RESET) && ((cr3its & USART_CR3_WUFIE) != RESET))
2351 {
2352 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_WUF);
2353
2354 /* UART Rx state is not reset as a reception process might be ongoing.
2355 If UART handle state fields need to be reset to READY, this could be done in Wakeup callback */
2356
2357 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2358 /* Call registered Wakeup Callback */
2359 huart->WakeupCallback(huart);
2360 #else
2361 /* Call legacy weak Wakeup Callback */
2362 HAL_UARTEx_WakeupCallback(huart);
2363 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2364 return;
2365 }
2366
2367 /* UART in mode Transmitter ------------------------------------------------*/
2368 #if defined(USART_CR1_FIFOEN)
2369 if (((isrflags & USART_ISR_TXE_TXFNF) != RESET)
2370 && (((cr1its & USART_CR1_TXEIE_TXFNFIE) != RESET)
2371 || ((cr3its & USART_CR3_TXFTIE) != RESET)))
2372 #else
2373 if (((isrflags & USART_ISR_TXE) != RESET)
2374 && ((cr1its & USART_CR1_TXEIE) != RESET))
2375 #endif
2376 {
2377 if (huart->TxISR != NULL)
2378 {
2379 huart->TxISR(huart);
2380 }
2381 return;
2382 }
2383
2384 /* UART in mode Transmitter (transmission end) -----------------------------*/
2385 if (((isrflags & USART_ISR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
2386 {
2387 UART_EndTransmit_IT(huart);
2388 return;
2389 }
2390
2391 #if defined(USART_CR1_FIFOEN)
2392 /* UART TX Fifo Empty occurred ----------------------------------------------*/
2393 if (((isrflags & USART_ISR_TXFE) != RESET) && ((cr1its & USART_CR1_TXFEIE) != RESET))
2394 {
2395 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2396 /* Call registered Tx Fifo Empty Callback */
2397 huart->TxFifoEmptyCallback(huart);
2398 #else
2399 /* Call legacy weak Tx Fifo Empty Callback */
2400 HAL_UARTEx_TxFifoEmptyCallback(huart);
2401 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2402 return;
2403 }
2404
2405 /* UART RX Fifo Full occurred ----------------------------------------------*/
2406 if (((isrflags & USART_ISR_RXFF) != RESET) && ((cr1its & USART_CR1_RXFFIE) != RESET))
2407 {
2408 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
2409 /* Call registered Rx Fifo Full Callback */
2410 huart->RxFifoFullCallback(huart);
2411 #else
2412 /* Call legacy weak Rx Fifo Full Callback */
2413 HAL_UARTEx_RxFifoFullCallback(huart);
2414 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2415 return;
2416 }
2417 #endif
2418 }
2419
2420 /**
2421 * @brief Tx Transfer completed callback.
2422 * @param huart UART handle.
2423 * @retval None
2424 */
HAL_UART_TxCpltCallback(UART_HandleTypeDef * huart)2425 __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
2426 {
2427 /* Prevent unused argument(s) compilation warning */
2428 UNUSED(huart);
2429
2430 /* NOTE : This function should not be modified, when the callback is needed,
2431 the HAL_UART_TxCpltCallback can be implemented in the user file.
2432 */
2433 }
2434
2435 /**
2436 * @brief Tx Half Transfer completed callback.
2437 * @param huart UART handle.
2438 * @retval None
2439 */
HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef * huart)2440 __weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
2441 {
2442 /* Prevent unused argument(s) compilation warning */
2443 UNUSED(huart);
2444
2445 /* NOTE: This function should not be modified, when the callback is needed,
2446 the HAL_UART_TxHalfCpltCallback can be implemented in the user file.
2447 */
2448 }
2449
2450 /**
2451 * @brief Rx Transfer completed callback.
2452 * @param huart UART handle.
2453 * @retval None
2454 */
HAL_UART_RxCpltCallback(UART_HandleTypeDef * huart)2455 __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
2456 {
2457 /* Prevent unused argument(s) compilation warning */
2458 UNUSED(huart);
2459
2460 /* NOTE : This function should not be modified, when the callback is needed,
2461 the HAL_UART_RxCpltCallback can be implemented in the user file.
2462 */
2463 }
2464
2465 /**
2466 * @brief Rx Half Transfer completed callback.
2467 * @param huart UART handle.
2468 * @retval None
2469 */
HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef * huart)2470 __weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
2471 {
2472 /* Prevent unused argument(s) compilation warning */
2473 UNUSED(huart);
2474
2475 /* NOTE: This function should not be modified, when the callback is needed,
2476 the HAL_UART_RxHalfCpltCallback can be implemented in the user file.
2477 */
2478 }
2479
2480 /**
2481 * @brief UART error callback.
2482 * @param huart UART handle.
2483 * @retval None
2484 */
HAL_UART_ErrorCallback(UART_HandleTypeDef * huart)2485 __weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
2486 {
2487 /* Prevent unused argument(s) compilation warning */
2488 UNUSED(huart);
2489
2490 /* NOTE : This function should not be modified, when the callback is needed,
2491 the HAL_UART_ErrorCallback can be implemented in the user file.
2492 */
2493 }
2494
2495 /**
2496 * @brief UART Abort Complete callback.
2497 * @param huart UART handle.
2498 * @retval None
2499 */
HAL_UART_AbortCpltCallback(UART_HandleTypeDef * huart)2500 __weak void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart)
2501 {
2502 /* Prevent unused argument(s) compilation warning */
2503 UNUSED(huart);
2504
2505 /* NOTE : This function should not be modified, when the callback is needed,
2506 the HAL_UART_AbortCpltCallback can be implemented in the user file.
2507 */
2508 }
2509
2510 /**
2511 * @brief UART Abort Complete callback.
2512 * @param huart UART handle.
2513 * @retval None
2514 */
HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef * huart)2515 __weak void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart)
2516 {
2517 /* Prevent unused argument(s) compilation warning */
2518 UNUSED(huart);
2519
2520 /* NOTE : This function should not be modified, when the callback is needed,
2521 the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file.
2522 */
2523 }
2524
2525 /**
2526 * @brief UART Abort Receive Complete callback.
2527 * @param huart UART handle.
2528 * @retval None
2529 */
HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef * huart)2530 __weak void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart)
2531 {
2532 /* Prevent unused argument(s) compilation warning */
2533 UNUSED(huart);
2534
2535 /* NOTE : This function should not be modified, when the callback is needed,
2536 the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file.
2537 */
2538 }
2539
2540 /**
2541 * @}
2542 */
2543
2544 /** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions
2545 * @brief UART control functions
2546 *
2547 @verbatim
2548 ===============================================================================
2549 ##### Peripheral Control functions #####
2550 ===============================================================================
2551 [..]
2552 This subsection provides a set of functions allowing to control the UART.
2553 (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode
2554 (+) HAL_MultiProcessor_DisableMuteMode() API disables mute mode
2555 (+) HAL_MultiProcessor_EnterMuteMode() API enters mute mode
2556 (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode
2557 (+) UART_SetConfig() API configures the UART peripheral
2558 (+) UART_AdvFeatureConfig() API optionally configures the UART advanced features
2559 (+) UART_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization
2560 (+) UART_Wakeup_AddressConfig() API configures the wake-up from stop mode parameters
2561 (+) HAL_HalfDuplex_EnableTransmitter() API disables receiver and enables transmitter
2562 (+) HAL_HalfDuplex_EnableReceiver() API disables transmitter and enables receiver
2563 (+) HAL_LIN_SendBreak() API transmits the break characters
2564 @endverbatim
2565 * @{
2566 */
2567
2568 /**
2569 * @brief Enable UART in mute mode (does not mean UART enters mute mode;
2570 * to enter mute mode, HAL_MultiProcessor_EnterMuteMode() API must be called).
2571 * @param huart UART handle.
2572 * @retval HAL status
2573 */
HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef * huart)2574 HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart)
2575 {
2576 /* Process Locked */
2577 __HAL_LOCK(huart);
2578
2579 huart->gState = HAL_UART_STATE_BUSY;
2580
2581 /* Enable USART mute mode by setting the MME bit in the CR1 register */
2582 SET_BIT(huart->Instance->CR1, USART_CR1_MME);
2583
2584 huart->gState = HAL_UART_STATE_READY;
2585
2586 return (UART_CheckIdleState(huart));
2587 }
2588
2589 /**
2590 * @brief Disable UART mute mode (does not mean the UART actually exits mute mode
2591 * as it may not have been in mute mode at this very moment).
2592 * @param huart UART handle.
2593 * @retval HAL status
2594 */
HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef * huart)2595 HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart)
2596 {
2597 /* Process Locked */
2598 __HAL_LOCK(huart);
2599
2600 huart->gState = HAL_UART_STATE_BUSY;
2601
2602 /* Disable USART mute mode by clearing the MME bit in the CR1 register */
2603 CLEAR_BIT(huart->Instance->CR1, USART_CR1_MME);
2604
2605 huart->gState = HAL_UART_STATE_READY;
2606
2607 return (UART_CheckIdleState(huart));
2608 }
2609
2610 /**
2611 * @brief Enter UART mute mode (means UART actually enters mute mode).
2612 * @note To exit from mute mode, HAL_MultiProcessor_DisableMuteMode() API must be called.
2613 * @param huart UART handle.
2614 * @retval None
2615 */
HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef * huart)2616 void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart)
2617 {
2618 __HAL_UART_SEND_REQ(huart, UART_MUTE_MODE_REQUEST);
2619 }
2620
2621 /**
2622 * @brief Enable the UART transmitter and disable the UART receiver.
2623 * @param huart UART handle.
2624 * @retval HAL status
2625 */
HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef * huart)2626 HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
2627 {
2628 /* Process Locked */
2629 __HAL_LOCK(huart);
2630 huart->gState = HAL_UART_STATE_BUSY;
2631
2632 /* Clear TE and RE bits */
2633 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
2634
2635 /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
2636 SET_BIT(huart->Instance->CR1, USART_CR1_TE);
2637
2638 huart->gState = HAL_UART_STATE_READY;
2639
2640 /* Process Unlocked */
2641 __HAL_UNLOCK(huart);
2642
2643 return HAL_OK;
2644 }
2645
2646 /**
2647 * @brief Enable the UART receiver and disable the UART transmitter.
2648 * @param huart UART handle.
2649 * @retval HAL status.
2650 */
HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef * huart)2651 HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart)
2652 {
2653 /* Process Locked */
2654 __HAL_LOCK(huart);
2655 huart->gState = HAL_UART_STATE_BUSY;
2656
2657 /* Clear TE and RE bits */
2658 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
2659
2660 /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
2661 SET_BIT(huart->Instance->CR1, USART_CR1_RE);
2662
2663 huart->gState = HAL_UART_STATE_READY;
2664
2665 /* Process Unlocked */
2666 __HAL_UNLOCK(huart);
2667
2668 return HAL_OK;
2669 }
2670
2671
2672 /**
2673 * @brief Transmit break characters.
2674 * @param huart UART handle.
2675 * @retval HAL status
2676 */
HAL_LIN_SendBreak(UART_HandleTypeDef * huart)2677 HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
2678 {
2679 /* Check the parameters */
2680 assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
2681
2682 /* Process Locked */
2683 __HAL_LOCK(huart);
2684
2685 huart->gState = HAL_UART_STATE_BUSY;
2686
2687 /* Send break characters */
2688 SET_BIT(huart->Instance->RQR, UART_SENDBREAK_REQUEST);
2689
2690 huart->gState = HAL_UART_STATE_READY;
2691
2692 /* Process Unlocked */
2693 __HAL_UNLOCK(huart);
2694
2695 return HAL_OK;
2696 }
2697
2698 /**
2699 * @}
2700 */
2701
2702 /** @defgroup UART_Exported_Functions_Group4 Peripheral State and Error functions
2703 * @brief UART Peripheral State functions
2704 *
2705 @verbatim
2706 ==============================================================================
2707 ##### Peripheral State and Error functions #####
2708 ==============================================================================
2709 [..]
2710 This subsection provides functions allowing to :
2711 (+) Return the UART handle state.
2712 (+) Return the UART handle error code
2713
2714 @endverbatim
2715 * @{
2716 */
2717
2718 /**
2719 * @brief Return the UART handle state.
2720 * @param huart Pointer to a UART_HandleTypeDef structure that contains
2721 * the configuration information for the specified UART.
2722 * @retval HAL state
2723 */
HAL_UART_GetState(UART_HandleTypeDef * huart)2724 HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart)
2725 {
2726 uint32_t temp1 = 0x00U, temp2 = 0x00U;
2727 temp1 = huart->gState;
2728 temp2 = huart->RxState;
2729
2730 return (HAL_UART_StateTypeDef)(temp1 | temp2);
2731 }
2732
2733 /**
2734 * @brief Return the UART handle error code.
2735 * @param huart Pointer to a UART_HandleTypeDef structure that contains
2736 * the configuration information for the specified UART.
2737 * @retval UART Error Code
2738 */
HAL_UART_GetError(UART_HandleTypeDef * huart)2739 uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart)
2740 {
2741 return huart->ErrorCode;
2742 }
2743 /**
2744 * @}
2745 */
2746
2747 /**
2748 * @}
2749 */
2750
2751 /** @defgroup UART_Private_Functions UART Private Functions
2752 * @{
2753 */
2754
2755 /**
2756 * @brief Initialize the callbacks to their default values.
2757 * @param huart UART handle.
2758 * @retval none
2759 */
2760 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
UART_InitCallbacksToDefault(UART_HandleTypeDef * huart)2761 void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart)
2762 {
2763 /* Init the UART Callback settings */
2764 huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
2765 huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */
2766 huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
2767 huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */
2768 huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */
2769 huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
2770 huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
2771 huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
2772 huart->WakeupCallback = HAL_UARTEx_WakeupCallback; /* Legacy weak WakeupCallback */
2773 #if defined(USART_CR1_FIFOEN)
2774 huart->RxFifoFullCallback = HAL_UARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */
2775 huart->TxFifoEmptyCallback = HAL_UARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */
2776 #endif
2777
2778 }
2779 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
2780
2781 /**
2782 * @brief Configure the UART peripheral.
2783 * @param huart UART handle.
2784 * @retval HAL status
2785 */
UART_SetConfig(UART_HandleTypeDef * huart)2786 HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart)
2787 {
2788 uint32_t tmpreg = 0x00000000U;
2789 UART_ClockSourceTypeDef clocksource = UART_CLOCKSOURCE_UNDEFINED;
2790 uint16_t brrtemp = 0x0000U;
2791 uint32_t usartdiv = 0x00000000U;
2792 HAL_StatusTypeDef ret = HAL_OK;
2793 uint32_t lpuart_ker_ck_pres = 0x00000000U;
2794
2795 /* Check the parameters */
2796 assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
2797 assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
2798 if (UART_INSTANCE_LOWPOWER(huart))
2799 {
2800 assert_param(IS_LPUART_STOPBITS(huart->Init.StopBits));
2801 }
2802 else
2803 {
2804 assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
2805 assert_param(IS_UART_ONE_BIT_SAMPLE(huart->Init.OneBitSampling));
2806 }
2807
2808 assert_param(IS_UART_PARITY(huart->Init.Parity));
2809 assert_param(IS_UART_MODE(huart->Init.Mode));
2810 assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
2811 assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
2812 #if defined(USART_PRESC_PRESCALER)
2813 assert_param(IS_UART_PRESCALER(huart->Init.ClockPrescaler));
2814 #endif
2815
2816 /*-------------------------- USART CR1 Configuration -----------------------*/
2817 /* Clear M, PCE, PS, TE, RE and OVER8 bits and configure
2818 * the UART Word Length, Parity, Mode and oversampling:
2819 * set the M bits according to huart->Init.WordLength value
2820 * set PCE and PS bits according to huart->Init.Parity value
2821 * set TE and RE bits according to huart->Init.Mode value
2822 * set OVER8 bit according to huart->Init.OverSampling value */
2823 tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling ;
2824 #if defined(USART_CR1_FIFOEN)
2825 tmpreg |= (uint32_t)huart->FifoMode;
2826 #endif
2827 MODIFY_REG(huart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
2828
2829 /*-------------------------- USART CR2 Configuration -----------------------*/
2830 /* Configure the UART Stop Bits: Set STOP[13:12] bits according
2831 * to huart->Init.StopBits value */
2832 MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
2833
2834 /*-------------------------- USART CR3 Configuration -----------------------*/
2835 /* Configure
2836 * - UART HardWare Flow Control: set CTSE and RTSE bits according
2837 * to huart->Init.HwFlowCtl value
2838 * - one-bit sampling method versus three samples' majority rule according
2839 * to huart->Init.OneBitSampling (not applicable to LPUART) */
2840 tmpreg = (uint32_t)huart->Init.HwFlowCtl;
2841
2842 if (!(UART_INSTANCE_LOWPOWER(huart)))
2843 {
2844 tmpreg |= huart->Init.OneBitSampling;
2845 }
2846 MODIFY_REG(huart->Instance->CR3, USART_CR3_FIELDS, tmpreg);
2847
2848 #if defined(USART_PRESC_PRESCALER)
2849 /*-------------------------- USART PRESC Configuration -----------------------*/
2850 /* Configure
2851 * - UART Clock Prescaler : set PRESCALER according to huart->Init.ClockPrescaler value */
2852 MODIFY_REG(huart->Instance->PRESC, USART_PRESC_PRESCALER, huart->Init.ClockPrescaler);
2853 #endif
2854
2855 /*-------------------------- USART BRR Configuration -----------------------*/
2856 UART_GETCLOCKSOURCE(huart, clocksource);
2857
2858 /* Check LPUART instance */
2859 if (UART_INSTANCE_LOWPOWER(huart))
2860 {
2861 /* Retrieve frequency clock */
2862 switch (clocksource)
2863 {
2864 case UART_CLOCKSOURCE_PCLK1:
2865 #if defined(USART_PRESC_PRESCALER)
2866 lpuart_ker_ck_pres = (HAL_RCC_GetPCLK1Freq() / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler));
2867 #else
2868 lpuart_ker_ck_pres = HAL_RCC_GetPCLK1Freq();
2869 #endif
2870 break;
2871 case UART_CLOCKSOURCE_HSI:
2872 #if defined(USART_PRESC_PRESCALER)
2873 lpuart_ker_ck_pres = ((uint32_t)HSI_VALUE / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler));
2874 #else
2875 lpuart_ker_ck_pres = (uint32_t)HSI_VALUE;
2876 #endif
2877 break;
2878 case UART_CLOCKSOURCE_SYSCLK:
2879 #if defined(USART_PRESC_PRESCALER)
2880 lpuart_ker_ck_pres = (HAL_RCC_GetSysClockFreq() / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler));
2881 #else
2882 lpuart_ker_ck_pres = HAL_RCC_GetSysClockFreq();
2883 #endif
2884 break;
2885 case UART_CLOCKSOURCE_LSE:
2886 #if defined(USART_PRESC_PRESCALER)
2887 lpuart_ker_ck_pres = ((uint32_t)LSE_VALUE / UART_GET_DIV_FACTOR(huart->Init.ClockPrescaler));
2888 #else
2889 lpuart_ker_ck_pres = (uint32_t)LSE_VALUE;
2890 #endif
2891 break;
2892 case UART_CLOCKSOURCE_UNDEFINED:
2893 default:
2894 ret = HAL_ERROR;
2895 break;
2896 }
2897
2898 /* if proper clock source reported */
2899 if (lpuart_ker_ck_pres != 0U)
2900 {
2901 /* ensure that Frequency clock is in the range [3 * baudrate, 4096 * baudrate] */
2902 if ((lpuart_ker_ck_pres < (3 * huart->Init.BaudRate)) ||
2903 (lpuart_ker_ck_pres > (4096 * huart->Init.BaudRate)))
2904 {
2905 ret = HAL_ERROR;
2906 }
2907 else
2908 {
2909 switch (clocksource)
2910 {
2911 case UART_CLOCKSOURCE_PCLK1:
2912 #if defined(USART_PRESC_PRESCALER)
2913 usartdiv = (uint32_t)(UART_DIV_LPUART(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate, huart->Init.ClockPrescaler));
2914 #else
2915 usartdiv = (uint32_t)(UART_DIV_LPUART(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate));
2916 #endif
2917 break;
2918 case UART_CLOCKSOURCE_HSI:
2919 #if defined(USART_PRESC_PRESCALER)
2920 usartdiv = (uint32_t)(UART_DIV_LPUART(HSI_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
2921 #else
2922 usartdiv = (uint32_t)(UART_DIV_LPUART(HSI_VALUE, huart->Init.BaudRate));
2923 #endif
2924 break;
2925 case UART_CLOCKSOURCE_SYSCLK:
2926 #if defined(USART_PRESC_PRESCALER)
2927 usartdiv = (uint32_t)(UART_DIV_LPUART(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate, huart->Init.ClockPrescaler));
2928 #else
2929 usartdiv = (uint32_t)(UART_DIV_LPUART(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate));
2930 #endif
2931 break;
2932 case UART_CLOCKSOURCE_LSE:
2933 #if defined(USART_PRESC_PRESCALER)
2934 usartdiv = (uint32_t)(UART_DIV_LPUART(LSE_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
2935 #else
2936 usartdiv = (uint32_t)(UART_DIV_LPUART(LSE_VALUE, huart->Init.BaudRate));
2937 #endif
2938 break;
2939 case UART_CLOCKSOURCE_UNDEFINED:
2940 default:
2941 ret = HAL_ERROR;
2942 break;
2943 }
2944
2945 /* It is forbidden to write values lower than 0x300 in the LPUART_BRR register */
2946 if ((usartdiv >= LPUART_BRR_MIN) && (usartdiv <= LPUART_BRR_MAX))
2947 {
2948 huart->Instance->BRR = usartdiv;
2949 }
2950 else
2951 {
2952 ret = HAL_ERROR;
2953 }
2954 } /* if ( (tmpreg < (3 * huart->Init.BaudRate) ) || (tmpreg > (4096 * huart->Init.BaudRate) )) */
2955 } /* if (tmpreg != 0) */
2956 }
2957 /* Check UART Over Sampling to set Baud Rate Register */
2958 else if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
2959 {
2960 switch (clocksource)
2961 {
2962 case UART_CLOCKSOURCE_PCLK1:
2963 #if defined(USART_PRESC_PRESCALER)
2964 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate, huart->Init.ClockPrescaler));
2965 #else
2966 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate));
2967 #endif
2968 break;
2969 case UART_CLOCKSOURCE_PCLK2:
2970 #if defined(USART_PRESC_PRESCALER)
2971 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate, huart->Init.ClockPrescaler));
2972 #else
2973 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate));
2974 #endif
2975 break;
2976 case UART_CLOCKSOURCE_HSI:
2977 #if defined(USART_PRESC_PRESCALER)
2978 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HSI_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
2979 #else
2980 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HSI_VALUE, huart->Init.BaudRate));
2981 #endif
2982 break;
2983 case UART_CLOCKSOURCE_SYSCLK:
2984 #if defined(USART_PRESC_PRESCALER)
2985 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate, huart->Init.ClockPrescaler));
2986 #else
2987 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate));
2988 #endif
2989 break;
2990 case UART_CLOCKSOURCE_LSE:
2991 #if defined(USART_PRESC_PRESCALER)
2992 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(LSE_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
2993 #else
2994 usartdiv = (uint16_t)(UART_DIV_SAMPLING8(LSE_VALUE, huart->Init.BaudRate));
2995 #endif
2996 break;
2997 case UART_CLOCKSOURCE_UNDEFINED:
2998 default:
2999 ret = HAL_ERROR;
3000 break;
3001 }
3002
3003 /* USARTDIV must be greater than or equal to 0d16 */
3004 if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
3005 {
3006 brrtemp = usartdiv & 0xFFF0U;
3007 brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U);
3008 huart->Instance->BRR = brrtemp;
3009 }
3010 else
3011 {
3012 ret = HAL_ERROR;
3013 }
3014 }
3015 else
3016 {
3017 switch (clocksource)
3018 {
3019 case UART_CLOCKSOURCE_PCLK1:
3020 #if defined(USART_PRESC_PRESCALER)
3021 usartdiv = (uint16_t)(UART_DIV_SAMPLING16(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate, huart->Init.ClockPrescaler));
3022 #else
3023 usartdiv = (uint16_t)(UART_DIV_SAMPLING16(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate));
3024 #endif
3025 break;
3026 case UART_CLOCKSOURCE_PCLK2:
3027 #if defined(USART_PRESC_PRESCALER)
3028 usartdiv = (uint16_t)(UART_DIV_SAMPLING16(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate, huart->Init.ClockPrescaler));
3029 #else
3030 usartdiv = (uint16_t)(UART_DIV_SAMPLING16(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate));
3031 #endif
3032 break;
3033 case UART_CLOCKSOURCE_HSI:
3034 #if defined(USART_PRESC_PRESCALER)
3035 usartdiv = (uint16_t)(UART_DIV_SAMPLING16(HSI_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3036 #else
3037 usartdiv = (uint16_t)(UART_DIV_SAMPLING16(HSI_VALUE, huart->Init.BaudRate));
3038 #endif
3039 break;
3040 case UART_CLOCKSOURCE_SYSCLK:
3041 #if defined(USART_PRESC_PRESCALER)
3042 usartdiv = (uint16_t)(UART_DIV_SAMPLING16(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate, huart->Init.ClockPrescaler));
3043 #else
3044 usartdiv = (uint16_t)(UART_DIV_SAMPLING16(HAL_RCC_GetSysClockFreq(), huart->Init.BaudRate));
3045 #endif
3046 break;
3047 case UART_CLOCKSOURCE_LSE:
3048 #if defined(USART_PRESC_PRESCALER)
3049 usartdiv = (uint16_t)(UART_DIV_SAMPLING16(LSE_VALUE, huart->Init.BaudRate, huart->Init.ClockPrescaler));
3050 #else
3051 usartdiv = (uint16_t)(UART_DIV_SAMPLING16(LSE_VALUE, huart->Init.BaudRate));
3052 #endif
3053 break;
3054 case UART_CLOCKSOURCE_UNDEFINED:
3055 default:
3056 ret = HAL_ERROR;
3057 break;
3058 }
3059
3060 /* USARTDIV must be greater than or equal to 0d16 */
3061 if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
3062 {
3063 huart->Instance->BRR = usartdiv;
3064 }
3065 else
3066 {
3067 ret = HAL_ERROR;
3068 }
3069 }
3070
3071 #if defined(USART_CR1_FIFOEN)
3072 /* Initialize the number of data to process during RX/TX ISR execution */
3073 huart->NbTxDataToProcess = 1;
3074 huart->NbRxDataToProcess = 1;
3075 #endif
3076
3077 /* Clear ISR function pointers */
3078 huart->RxISR = NULL;
3079 huart->TxISR = NULL;
3080
3081 return ret;
3082 }
3083
3084 /**
3085 * @brief Configure the UART peripheral advanced features.
3086 * @param huart UART handle.
3087 * @retval None
3088 */
UART_AdvFeatureConfig(UART_HandleTypeDef * huart)3089 void UART_AdvFeatureConfig(UART_HandleTypeDef *huart)
3090 {
3091 /* Check whether the set of advanced features to configure is properly set */
3092 assert_param(IS_UART_ADVFEATURE_INIT(huart->AdvancedInit.AdvFeatureInit));
3093
3094 /* if required, configure TX pin active level inversion */
3095 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_TXINVERT_INIT))
3096 {
3097 assert_param(IS_UART_ADVFEATURE_TXINV(huart->AdvancedInit.TxPinLevelInvert));
3098 MODIFY_REG(huart->Instance->CR2, USART_CR2_TXINV, huart->AdvancedInit.TxPinLevelInvert);
3099 }
3100
3101 /* if required, configure RX pin active level inversion */
3102 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXINVERT_INIT))
3103 {
3104 assert_param(IS_UART_ADVFEATURE_RXINV(huart->AdvancedInit.RxPinLevelInvert));
3105 MODIFY_REG(huart->Instance->CR2, USART_CR2_RXINV, huart->AdvancedInit.RxPinLevelInvert);
3106 }
3107
3108 /* if required, configure data inversion */
3109 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DATAINVERT_INIT))
3110 {
3111 assert_param(IS_UART_ADVFEATURE_DATAINV(huart->AdvancedInit.DataInvert));
3112 MODIFY_REG(huart->Instance->CR2, USART_CR2_DATAINV, huart->AdvancedInit.DataInvert);
3113 }
3114
3115 /* if required, configure RX/TX pins swap */
3116 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_SWAP_INIT))
3117 {
3118 assert_param(IS_UART_ADVFEATURE_SWAP(huart->AdvancedInit.Swap));
3119 MODIFY_REG(huart->Instance->CR2, USART_CR2_SWAP, huart->AdvancedInit.Swap);
3120 }
3121
3122 /* if required, configure RX overrun detection disabling */
3123 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXOVERRUNDISABLE_INIT))
3124 {
3125 assert_param(IS_UART_OVERRUN(huart->AdvancedInit.OverrunDisable));
3126 MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, huart->AdvancedInit.OverrunDisable);
3127 }
3128
3129 /* if required, configure DMA disabling on reception error */
3130 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DMADISABLEONERROR_INIT))
3131 {
3132 assert_param(IS_UART_ADVFEATURE_DMAONRXERROR(huart->AdvancedInit.DMADisableonRxError));
3133 MODIFY_REG(huart->Instance->CR3, USART_CR3_DDRE, huart->AdvancedInit.DMADisableonRxError);
3134 }
3135
3136 /* if required, configure auto Baud rate detection scheme */
3137 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT))
3138 {
3139 assert_param(IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(huart->Instance));
3140 assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable));
3141 MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable);
3142 /* set auto Baudrate detection parameters if detection is enabled */
3143 if (huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)
3144 {
3145 assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode));
3146 MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode);
3147 }
3148 }
3149
3150 /* if required, configure MSB first on communication line */
3151 if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_MSBFIRST_INIT))
3152 {
3153 assert_param(IS_UART_ADVFEATURE_MSBFIRST(huart->AdvancedInit.MSBFirst));
3154 MODIFY_REG(huart->Instance->CR2, USART_CR2_MSBFIRST, huart->AdvancedInit.MSBFirst);
3155 }
3156 }
3157
3158 /**
3159 * @brief Check the UART Idle State.
3160 * @param huart UART handle.
3161 * @retval HAL status
3162 */
UART_CheckIdleState(UART_HandleTypeDef * huart)3163 HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart)
3164 {
3165 uint32_t tickstart = 0U;
3166
3167 /* Initialize the UART ErrorCode */
3168 huart->ErrorCode = HAL_UART_ERROR_NONE;
3169
3170 /* Init tickstart for timeout managment*/
3171 tickstart = HAL_GetTick();
3172
3173 /* Check if the Transmitter is enabled */
3174 if ((huart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
3175 {
3176 /* Wait until TEACK flag is set */
3177 if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
3178 {
3179 /* Timeout occurred */
3180 return HAL_TIMEOUT;
3181 }
3182 }
3183 /* Check if the Receiver is enabled */
3184 if ((huart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
3185 {
3186 /* Wait until REACK flag is set */
3187 if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
3188 {
3189 /* Timeout occurred */
3190 return HAL_TIMEOUT;
3191 }
3192 }
3193
3194 /* Initialize the UART State */
3195 huart->gState = HAL_UART_STATE_READY;
3196 huart->RxState = HAL_UART_STATE_READY;
3197
3198 /* Process Unlocked */
3199 __HAL_UNLOCK(huart);
3200
3201 return HAL_OK;
3202 }
3203
3204 /**
3205 * @brief Handle UART Communication Timeout.
3206 * @param huart UART handle.
3207 * @param Flag Specifies the UART flag to check
3208 * @param Status Flag status (SET or RESET)
3209 * @param Tickstart Tick start value
3210 * @param Timeout Timeout duration
3211 * @retval HAL status
3212 */
UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef * huart,uint32_t Flag,FlagStatus Status,uint32_t Tickstart,uint32_t Timeout)3213 HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
3214 {
3215 /* Wait until flag is set */
3216 while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status)
3217 {
3218 /* Check for the Timeout */
3219 if (Timeout != HAL_MAX_DELAY)
3220 {
3221 if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
3222 {
3223 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
3224 #if defined(USART_CR1_FIFOEN)
3225 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE));
3226 #else
3227 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
3228 #endif
3229 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3230
3231 huart->gState = HAL_UART_STATE_READY;
3232 huart->RxState = HAL_UART_STATE_READY;
3233
3234 /* Process Unlocked */
3235 __HAL_UNLOCK(huart);
3236
3237 return HAL_TIMEOUT;
3238 }
3239 }
3240 }
3241 return HAL_OK;
3242 }
3243
3244
3245 /**
3246 * @brief End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion).
3247 * @param huart UART handle.
3248 * @retval None
3249 */
UART_EndTxTransfer(UART_HandleTypeDef * huart)3250 static void UART_EndTxTransfer(UART_HandleTypeDef *huart)
3251 {
3252 #if defined(USART_CR1_FIFOEN)
3253 /* Disable TXEIE, TCIE, TXFT interrupts */
3254 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
3255 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_TXFTIE));
3256 #else
3257 /* Disable TXEIE and TCIE interrupts */
3258 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
3259 #endif
3260
3261 /* At end of Tx process, restore huart->gState to Ready */
3262 huart->gState = HAL_UART_STATE_READY;
3263 }
3264
3265
3266 /**
3267 * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
3268 * @param huart UART handle.
3269 * @retval None
3270 */
UART_EndRxTransfer(UART_HandleTypeDef * huart)3271 static void UART_EndRxTransfer(UART_HandleTypeDef *huart)
3272 {
3273 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
3274 #if defined(USART_CR1_FIFOEN)
3275 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3276 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
3277 #else
3278 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
3279 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3280 #endif
3281
3282 /* At end of Rx process, restore huart->RxState to Ready */
3283 huart->RxState = HAL_UART_STATE_READY;
3284
3285 /* Reset RxIsr function pointer */
3286 huart->RxISR = NULL;
3287 }
3288
3289
3290 /**
3291 * @brief DMA UART transmit process complete callback.
3292 * @param hdma DMA handle.
3293 * @retval None
3294 */
UART_DMATransmitCplt(DMA_HandleTypeDef * hdma)3295 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
3296 {
3297 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3298
3299 /* DMA Normal mode */
3300 if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
3301 {
3302 huart->TxXferCount = 0U;
3303
3304 /* Disable the DMA transfer for transmit request by resetting the DMAT bit
3305 in the UART CR3 register */
3306 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
3307
3308 /* Enable the UART Transmit Complete Interrupt */
3309 SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3310 }
3311 /* DMA Circular mode */
3312 else
3313 {
3314 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3315 /*Call registered Tx complete callback*/
3316 huart->TxCpltCallback(huart);
3317 #else
3318 /*Call legacy weak Tx complete callback*/
3319 HAL_UART_TxCpltCallback(huart);
3320 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3321 }
3322 }
3323
3324 /**
3325 * @brief DMA UART transmit process half complete callback.
3326 * @param hdma DMA handle.
3327 * @retval None
3328 */
UART_DMATxHalfCplt(DMA_HandleTypeDef * hdma)3329 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
3330 {
3331 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3332
3333 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3334 /*Call registered Tx Half complete callback*/
3335 huart->TxHalfCpltCallback(huart);
3336 #else
3337 /*Call legacy weak Tx Half complete callback*/
3338 HAL_UART_TxHalfCpltCallback(huart);
3339 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3340 }
3341
3342 /**
3343 * @brief DMA UART receive process complete callback.
3344 * @param hdma DMA handle.
3345 * @retval None
3346 */
UART_DMAReceiveCplt(DMA_HandleTypeDef * hdma)3347 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
3348 {
3349 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3350
3351 /* DMA Normal mode */
3352 if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
3353 {
3354 huart->RxXferCount = 0U;
3355
3356 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
3357 CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
3358 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3359
3360 /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
3361 in the UART CR3 register */
3362 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
3363
3364 /* At end of Rx process, restore huart->RxState to Ready */
3365 huart->RxState = HAL_UART_STATE_READY;
3366 }
3367
3368 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3369 /*Call registered Rx complete callback*/
3370 huart->RxCpltCallback(huart);
3371 #else
3372 /*Call legacy weak Rx complete callback*/
3373 HAL_UART_RxCpltCallback(huart);
3374 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3375 }
3376
3377 /**
3378 * @brief DMA UART receive process half complete callback.
3379 * @param hdma DMA handle.
3380 * @retval None
3381 */
UART_DMARxHalfCplt(DMA_HandleTypeDef * hdma)3382 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
3383 {
3384 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3385
3386 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3387 /*Call registered Rx Half complete callback*/
3388 huart->RxHalfCpltCallback(huart);
3389 #else
3390 /*Call legacy weak Rx Half complete callback*/
3391 HAL_UART_RxHalfCpltCallback(huart);
3392 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3393 }
3394
3395 /**
3396 * @brief DMA UART communication error callback.
3397 * @param hdma DMA handle.
3398 * @retval None
3399 */
UART_DMAError(DMA_HandleTypeDef * hdma)3400 static void UART_DMAError(DMA_HandleTypeDef *hdma)
3401 {
3402 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3403
3404 /* Stop UART DMA Tx request if ongoing */
3405 if ((huart->gState == HAL_UART_STATE_BUSY_TX)
3406 && (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)))
3407 {
3408 huart->TxXferCount = 0U;
3409 UART_EndTxTransfer(huart);
3410 }
3411
3412 /* Stop UART DMA Rx request if ongoing */
3413 if ((huart->RxState == HAL_UART_STATE_BUSY_RX)
3414 && (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)))
3415 {
3416 huart->RxXferCount = 0U;
3417 UART_EndRxTransfer(huart);
3418 }
3419
3420 huart->ErrorCode |= HAL_UART_ERROR_DMA;
3421
3422 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3423 /*Call registered error callback*/
3424 huart->ErrorCallback(huart);
3425 #else
3426 /*Call legacy weak error callback*/
3427 HAL_UART_ErrorCallback(huart);
3428 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3429 }
3430
3431 /**
3432 * @brief DMA UART communication abort callback, when initiated by HAL services on Error
3433 * (To be called at end of DMA Abort procedure following error occurrence).
3434 * @param hdma DMA handle.
3435 * @retval None
3436 */
UART_DMAAbortOnError(DMA_HandleTypeDef * hdma)3437 static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
3438 {
3439 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3440 huart->RxXferCount = 0U;
3441 huart->TxXferCount = 0U;
3442
3443 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3444 /*Call registered error callback*/
3445 huart->ErrorCallback(huart);
3446 #else
3447 /*Call legacy weak error callback*/
3448 HAL_UART_ErrorCallback(huart);
3449 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3450 }
3451
3452 /**
3453 * @brief DMA UART Tx communication abort callback, when initiated by user
3454 * (To be called at end of DMA Tx Abort procedure following user abort request).
3455 * @note When this callback is executed, User Abort complete call back is called only if no
3456 * Abort still ongoing for Rx DMA Handle.
3457 * @param hdma DMA handle.
3458 * @retval None
3459 */
UART_DMATxAbortCallback(DMA_HandleTypeDef * hdma)3460 static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
3461 {
3462 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3463
3464 huart->hdmatx->XferAbortCallback = NULL;
3465
3466 /* Check if an Abort process is still ongoing */
3467 if (huart->hdmarx != NULL)
3468 {
3469 if (huart->hdmarx->XferAbortCallback != NULL)
3470 {
3471 return;
3472 }
3473 }
3474
3475 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
3476 huart->TxXferCount = 0U;
3477 huart->RxXferCount = 0U;
3478
3479 /* Reset errorCode */
3480 huart->ErrorCode = HAL_UART_ERROR_NONE;
3481
3482 /* Clear the Error flags in the ICR register */
3483 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3484
3485 #if defined(USART_CR1_FIFOEN)
3486 /* Flush the whole TX FIFO (if needed) */
3487 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
3488 {
3489 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
3490 }
3491 #endif
3492
3493 /* Restore huart->gState and huart->RxState to Ready */
3494 huart->gState = HAL_UART_STATE_READY;
3495 huart->RxState = HAL_UART_STATE_READY;
3496
3497 /* Call user Abort complete callback */
3498 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3499 /* Call registered Abort complete callback */
3500 huart->AbortCpltCallback(huart);
3501 #else
3502 /* Call legacy weak Abort complete callback */
3503 HAL_UART_AbortCpltCallback(huart);
3504 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3505 }
3506
3507
3508 /**
3509 * @brief DMA UART Rx communication abort callback, when initiated by user
3510 * (To be called at end of DMA Rx Abort procedure following user abort request).
3511 * @note When this callback is executed, User Abort complete call back is called only if no
3512 * Abort still ongoing for Tx DMA Handle.
3513 * @param hdma DMA handle.
3514 * @retval None
3515 */
UART_DMARxAbortCallback(DMA_HandleTypeDef * hdma)3516 static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
3517 {
3518 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3519
3520 huart->hdmarx->XferAbortCallback = NULL;
3521
3522 /* Check if an Abort process is still ongoing */
3523 if (huart->hdmatx != NULL)
3524 {
3525 if (huart->hdmatx->XferAbortCallback != NULL)
3526 {
3527 return;
3528 }
3529 }
3530
3531 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
3532 huart->TxXferCount = 0U;
3533 huart->RxXferCount = 0U;
3534
3535 /* Reset errorCode */
3536 huart->ErrorCode = HAL_UART_ERROR_NONE;
3537
3538 /* Clear the Error flags in the ICR register */
3539 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3540
3541 /* Discard the received data */
3542 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3543
3544 /* Restore huart->gState and huart->RxState to Ready */
3545 huart->gState = HAL_UART_STATE_READY;
3546 huart->RxState = HAL_UART_STATE_READY;
3547
3548 /* Call user Abort complete callback */
3549 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3550 /* Call registered Abort complete callback */
3551 huart->AbortCpltCallback(huart);
3552 #else
3553 /* Call legacy weak Abort complete callback */
3554 HAL_UART_AbortCpltCallback(huart);
3555 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3556 }
3557
3558
3559 /**
3560 * @brief DMA UART Tx communication abort callback, when initiated by user by a call to
3561 * HAL_UART_AbortTransmit_IT API (Abort only Tx transfer)
3562 * (This callback is executed at end of DMA Tx Abort procedure following user abort request,
3563 * and leads to user Tx Abort Complete callback execution).
3564 * @param hdma DMA handle.
3565 * @retval None
3566 */
UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef * hdma)3567 static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
3568 {
3569 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
3570
3571 huart->TxXferCount = 0U;
3572
3573 #if defined(USART_CR1_FIFOEN)
3574 /* Flush the whole TX FIFO (if needed) */
3575 if (huart->FifoMode == UART_FIFOMODE_ENABLE)
3576 {
3577 __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
3578 }
3579 #endif
3580
3581 /* Restore huart->gState to Ready */
3582 huart->gState = HAL_UART_STATE_READY;
3583
3584 /* Call user Abort complete callback */
3585 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3586 /* Call registered Abort Transmit Complete Callback */
3587 huart->AbortTransmitCpltCallback(huart);
3588 #else
3589 /* Call legacy weak Abort Transmit Complete Callback */
3590 HAL_UART_AbortTransmitCpltCallback(huart);
3591 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3592 }
3593
3594 /**
3595 * @brief DMA UART Rx communication abort callback, when initiated by user by a call to
3596 * HAL_UART_AbortReceive_IT API (Abort only Rx transfer)
3597 * (This callback is executed at end of DMA Rx Abort procedure following user abort request,
3598 * and leads to user Rx Abort Complete callback execution).
3599 * @param hdma DMA handle.
3600 * @retval None
3601 */
UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef * hdma)3602 static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
3603 {
3604 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3605
3606 huart->RxXferCount = 0U;
3607
3608 /* Clear the Error flags in the ICR register */
3609 __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
3610
3611 /* Discard the received data */
3612 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3613
3614 /* Restore huart->RxState to Ready */
3615 huart->RxState = HAL_UART_STATE_READY;
3616
3617 /* Call user Abort complete callback */
3618 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3619 /* Call registered Abort Receive Complete Callback */
3620 huart->AbortReceiveCpltCallback(huart);
3621 #else
3622 /* Call legacy weak Abort Receive Complete Callback */
3623 HAL_UART_AbortReceiveCpltCallback(huart);
3624 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3625 }
3626
3627 /**
3628 * @brief TX interrrupt handler for 7 or 8 bits data word length .
3629 * @note Function is called under interruption only, once
3630 * interruptions have been enabled by HAL_UART_Transmit_IT().
3631 * @param huart UART handle.
3632 * @retval None
3633 */
UART_TxISR_8BIT(UART_HandleTypeDef * huart)3634 static void UART_TxISR_8BIT(UART_HandleTypeDef *huart)
3635 {
3636 /* Check that a Tx process is ongoing */
3637 if (huart->gState == HAL_UART_STATE_BUSY_TX)
3638 {
3639 if (huart->TxXferCount == 0)
3640 {
3641 /* Disable the UART Transmit Data Register Empty Interrupt */
3642 #if defined(USART_CR1_FIFOEN)
3643 CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
3644 #else
3645 CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE);
3646 #endif
3647
3648 /* Enable the UART Transmit Complete Interrupt */
3649 SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3650 }
3651 else
3652 {
3653 huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0xFF);
3654 huart->TxXferCount--;
3655 }
3656 }
3657 }
3658
3659 /**
3660 * @brief TX interrrupt handler for 9 bits data word length.
3661 * @note Function is called under interruption only, once
3662 * interruptions have been enabled by HAL_UART_Transmit_IT().
3663 * @param huart UART handle.
3664 * @retval None
3665 */
UART_TxISR_16BIT(UART_HandleTypeDef * huart)3666 static void UART_TxISR_16BIT(UART_HandleTypeDef *huart)
3667 {
3668 uint16_t *tmp;
3669
3670 /* Check that a Tx process is ongoing */
3671 if (huart->gState == HAL_UART_STATE_BUSY_TX)
3672 {
3673 if (huart->TxXferCount == 0)
3674 {
3675 /* Disable the UART Transmit Data Register Empty Interrupt */
3676 #if defined(USART_CR1_FIFOEN)
3677 CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
3678 #else
3679 CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE);
3680 #endif
3681
3682 /* Enable the UART Transmit Complete Interrupt */
3683 SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3684 }
3685 else
3686 {
3687 tmp = (uint16_t *) huart->pTxBuffPtr;
3688 huart->Instance->TDR = (*tmp & (uint16_t)0x01FF);
3689 huart->pTxBuffPtr += 2;
3690 huart->TxXferCount--;
3691 }
3692 }
3693 }
3694
3695 #if defined(USART_CR1_FIFOEN)
3696 /**
3697 * @brief TX interrrupt handler for 7 or 8 bits data word length and FIFO mode is enabled.
3698 * @note Function is called under interruption only, once
3699 * interruptions have been enabled by HAL_UART_Transmit_IT().
3700 * @param huart UART handle.
3701 * @retval None
3702 */
UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef * huart)3703 static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart)
3704 {
3705 uint8_t nb_tx_data;
3706
3707 /* Check that a Tx process is ongoing */
3708 if (huart->gState == HAL_UART_STATE_BUSY_TX)
3709 {
3710 for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0 ; nb_tx_data--)
3711 {
3712 if (huart->TxXferCount == 0U)
3713 {
3714 /* Disable the TX FIFO threshold interrupt */
3715 CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
3716
3717 /* Enable the UART Transmit Complete Interrupt */
3718 SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3719
3720 break; /* force exit loop */
3721 }
3722 else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != RESET)
3723 {
3724 huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0xFF);
3725 huart->TxXferCount--;
3726 }
3727 }
3728 }
3729 }
3730
3731 /**
3732 * @brief TX interrrupt handler for 9 bits data word length and FIFO mode is enabled.
3733 * @note Function is called under interruption only, once
3734 * interruptions have been enabled by HAL_UART_Transmit_IT().
3735 * @param huart UART handle.
3736 * @retval None
3737 */
UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef * huart)3738 static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart)
3739 {
3740 uint16_t *tmp;
3741 uint8_t nb_tx_data;
3742
3743 /* Check that a Tx process is ongoing */
3744 if (huart->gState == HAL_UART_STATE_BUSY_TX)
3745 {
3746 for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0 ; nb_tx_data--)
3747 {
3748 if (huart->TxXferCount == 0U)
3749 {
3750 /* Disable the TX FIFO threshold interrupt */
3751 CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
3752
3753 /* Enable the UART Transmit Complete Interrupt */
3754 SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3755
3756 break; /* force exit loop */
3757 }
3758 else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != RESET)
3759 {
3760 tmp = (uint16_t *) huart->pTxBuffPtr;
3761 huart->Instance->TDR = (*tmp & (uint16_t)0x01FFU);
3762 huart->pTxBuffPtr += 2U;
3763 huart->TxXferCount--;
3764 }
3765 }
3766 }
3767 }
3768 #endif
3769
3770 /**
3771 * @brief Wrap up transmission in non-blocking mode.
3772 * @param huart pointer to a UART_HandleTypeDef structure that contains
3773 * the configuration information for the specified UART module.
3774 * @retval None
3775 */
UART_EndTransmit_IT(UART_HandleTypeDef * huart)3776 static void UART_EndTransmit_IT(UART_HandleTypeDef *huart)
3777 {
3778 /* Disable the UART Transmit Complete Interrupt */
3779 CLEAR_BIT(huart->Instance->CR1, USART_CR1_TCIE);
3780
3781 /* Tx process is ended, restore huart->gState to Ready */
3782 huart->gState = HAL_UART_STATE_READY;
3783
3784 /* Cleat TxISR function pointer */
3785 huart->TxISR = NULL;
3786
3787 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3788 /*Call registered Tx complete callback*/
3789 huart->TxCpltCallback(huart);
3790 #else
3791 /*Call legacy weak Tx complete callback*/
3792 HAL_UART_TxCpltCallback(huart);
3793 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3794 }
3795
3796 /**
3797 * @brief RX interrrupt handler for 7 or 8 bits data word length .
3798 * @param huart UART handle.
3799 * @retval None
3800 */
UART_RxISR_8BIT(UART_HandleTypeDef * huart)3801 static void UART_RxISR_8BIT(UART_HandleTypeDef *huart)
3802 {
3803 uint16_t uhMask = huart->Mask;
3804 uint16_t uhdata;
3805
3806 /* Check that a Rx process is ongoing */
3807 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
3808 {
3809 uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
3810 *huart->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)uhMask);
3811
3812 if (--huart->RxXferCount == 0)
3813 {
3814 /* Disable the UART Parity Error Interrupt and RXNE interrupts */
3815 #if defined(USART_CR1_FIFOEN)
3816 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3817 #else
3818 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
3819 #endif
3820
3821 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
3822 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3823
3824 /* Rx process is completed, restore huart->RxState to Ready */
3825 huart->RxState = HAL_UART_STATE_READY;
3826
3827 /* Clear RxISR function pointer */
3828 huart->RxISR = NULL;
3829
3830 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3831 /*Call registered Rx complete callback*/
3832 huart->RxCpltCallback(huart);
3833 #else
3834 /*Call legacy weak Rx complete callback*/
3835 HAL_UART_RxCpltCallback(huart);
3836 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3837 }
3838 }
3839 else
3840 {
3841 /* Clear RXNE interrupt flag */
3842 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3843 }
3844 }
3845
3846 /**
3847 * @brief RX interrrupt handler for 9 bits data word length .
3848 * @note Function is called under interruption only, once
3849 * interruptions have been enabled by HAL_UART_Receive_IT()
3850 * @param huart UART handle.
3851 * @retval None
3852 */
UART_RxISR_16BIT(UART_HandleTypeDef * huart)3853 static void UART_RxISR_16BIT(UART_HandleTypeDef *huart)
3854 {
3855 uint16_t *tmp;
3856 uint16_t uhMask = huart->Mask;
3857 uint16_t uhdata;
3858
3859 /* Check that a Rx process is ongoing */
3860 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
3861 {
3862 uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
3863 tmp = (uint16_t *) huart->pRxBuffPtr ;
3864 *tmp = (uint16_t)(uhdata & uhMask);
3865 huart->pRxBuffPtr += 2;
3866
3867 if (--huart->RxXferCount == 0)
3868 {
3869 /* Disable the UART Parity Error Interrupt and RXNE interrupt*/
3870 #if defined(USART_CR1_FIFOEN)
3871 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
3872 #else
3873 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
3874 #endif
3875
3876 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
3877 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
3878
3879 /* Rx process is completed, restore huart->RxState to Ready */
3880 huart->RxState = HAL_UART_STATE_READY;
3881
3882 /* Clear RxISR function pointer */
3883 huart->RxISR = NULL;
3884
3885 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3886 /*Call registered Rx complete callback*/
3887 huart->RxCpltCallback(huart);
3888 #else
3889 /*Call legacy weak Rx complete callback*/
3890 HAL_UART_RxCpltCallback(huart);
3891 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3892 }
3893 }
3894 else
3895 {
3896 /* Clear RXNE interrupt flag */
3897 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3898 }
3899 }
3900
3901 #if defined(USART_CR1_FIFOEN)
3902 /**
3903 * @brief RX interrrupt handler for 7 or 8 bits data word length and FIFO mode is enabled.
3904 * @note Function is called under interruption only, once
3905 * interruptions have been enabled by HAL_UART_Receive_IT()
3906 * @param huart UART handle.
3907 * @retval None
3908 */
UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef * huart)3909 static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart)
3910 {
3911 uint16_t uhMask = huart->Mask;
3912 uint16_t uhdata;
3913 uint8_t nb_rx_data;
3914
3915 /* Check that a Rx process is ongoing */
3916 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
3917 {
3918 for (nb_rx_data = huart->NbRxDataToProcess ; nb_rx_data > 0 ; nb_rx_data--)
3919 {
3920 uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
3921 *huart->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)uhMask);
3922 huart->RxXferCount--;
3923
3924 if (huart->RxXferCount == 0U)
3925 {
3926 /* Disable the UART Parity Error Interrupt and RXFT interrupt*/
3927 CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
3928
3929 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */
3930 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
3931
3932 /* Rx process is completed, restore huart->RxState to Ready */
3933 huart->RxState = HAL_UART_STATE_READY;
3934
3935 /* Clear RxISR function pointer */
3936 huart->RxISR = NULL;
3937
3938 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
3939 /*Call registered Rx complete callback*/
3940 huart->RxCpltCallback(huart);
3941 #else
3942 /*Call legacy weak Rx complete callback*/
3943 HAL_UART_RxCpltCallback(huart);
3944 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
3945 }
3946 }
3947
3948 /* When remaining number of bytes to receive is less than the RX FIFO
3949 threshold, next incoming frames are processed as if FIFO mode was
3950 disabled (i.e. one interrupt per received frame).
3951 */
3952 if (((huart->RxXferCount != 0U)) && (huart->RxXferCount < huart->NbRxDataToProcess))
3953 {
3954 /* Disable the UART RXFT interrupt*/
3955 CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
3956
3957 /* Update the RxISR function pointer */
3958 huart->RxISR = UART_RxISR_8BIT;
3959
3960 /* Enable the UART Data Register Not Empty interrupt */
3961 SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
3962 }
3963 }
3964 else
3965 {
3966 /* Clear RXNE interrupt flag */
3967 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
3968 }
3969 }
3970
3971 /**
3972 * @brief RX interrrupt handler for 9 bits data word length and FIFO mode is enabled.
3973 * @note Function is called under interruption only, once
3974 * interruptions have been enabled by HAL_UART_Receive_IT()
3975 * @param huart UART handle.
3976 * @retval None
3977 */
UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef * huart)3978 static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart)
3979 {
3980 uint16_t *tmp;
3981 uint16_t uhMask = huart->Mask;
3982 uint16_t uhdata;
3983 uint8_t nb_rx_data;
3984
3985 /* Check that a Rx process is ongoing */
3986 if (huart->RxState == HAL_UART_STATE_BUSY_RX)
3987 {
3988 for (nb_rx_data = huart->NbRxDataToProcess ; nb_rx_data > 0 ; nb_rx_data--)
3989 {
3990 uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
3991 tmp = (uint16_t *) huart->pRxBuffPtr ;
3992 *tmp = (uint16_t)(uhdata & uhMask);
3993 huart->pRxBuffPtr += 2;
3994 huart->RxXferCount--;
3995
3996 if (huart->RxXferCount == 0U)
3997 {
3998 /* Disable the UART Parity Error Interrupt and RXFT interrupt*/
3999 CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
4000
4001 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */
4002 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
4003
4004 /* Rx process is completed, restore huart->RxState to Ready */
4005 huart->RxState = HAL_UART_STATE_READY;
4006
4007 /* Clear RxISR function pointer */
4008 huart->RxISR = NULL;
4009
4010 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
4011 /*Call registered Rx complete callback*/
4012 huart->RxCpltCallback(huart);
4013 #else
4014 /*Call legacy weak Rx complete callback*/
4015 HAL_UART_RxCpltCallback(huart);
4016 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4017 }
4018 }
4019
4020 /* When remaining number of bytes to receive is less than the RX FIFO
4021 threshold, next incoming frames are processed as if FIFO mode was
4022 disabled (i.e. one interrupt per received frame).
4023 */
4024 if (((huart->RxXferCount != 0U)) && (huart->RxXferCount < huart->NbRxDataToProcess))
4025 {
4026 /* Disable the UART RXFT interrupt*/
4027 CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
4028
4029 /* Update the RxISR function pointer */
4030 huart->RxISR = UART_RxISR_16BIT;
4031
4032 /* Enable the UART Data Register Not Empty interrupt */
4033 SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
4034 }
4035 }
4036 else
4037 {
4038 /* Clear RXNE interrupt flag */
4039 __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
4040 }
4041 }
4042 #endif
4043
4044 /**
4045 * @}
4046 */
4047
4048 #endif /* HAL_UART_MODULE_ENABLED */
4049 /**
4050 * @}
4051 */
4052
4053 /**
4054 * @}
4055 */
4056
4057 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
4058