2 ******************************************************************************
3 * @file stm32h7xx_hal_usart.c
4 * @author MCD Application Team
5 * @brief USART HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Universal Synchronous/Asynchronous Receiver Transmitter
9 * + Initialization and de-initialization functions
10 * + IO operation functions
11 * + Peripheral Control functions
12 * + Peripheral State and Error functions
15 ===============================================================================
16 ##### How to use this driver #####
17 ===============================================================================
19 The USART HAL driver can be used as follows:
21 (#) Declare a USART_HandleTypeDef handle structure (eg. USART_HandleTypeDef husart).
22 (#) Initialize the USART low level resources by implementing the HAL_USART_MspInit() API:
23 (++) Enable the USARTx interface clock.
24 (++) USART pins configuration:
25 (+++) Enable the clock for the USART GPIOs.
26 (+++) Configure these USART pins as alternate function pull-up.
27 (++) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
28 HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
29 (+++) Configure the USARTx interrupt priority.
30 (+++) Enable the NVIC USART IRQ handle.
31 (++) USART interrupts handling:
32 -@@- The specific USART interrupts (Transmission complete interrupt,
33 RXNE interrupt and Error Interrupts) will be managed using the macros
34 __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process.
35 (++) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA()
36 HAL_USART_Receive_DMA() and HAL_USART_TransmitReceive_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 USART DMA Tx/Rx handle.
42 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
44 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, and Mode
45 (Receiver/Transmitter) in the husart handle Init structure.
47 (#) Initialize the USART registers by calling the HAL_USART_Init() API:
48 (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
49 by calling the customized HAL_USART_MspInit(&husart) API.
52 (@) To configure and enable/disable the USART to wake up the MCU from stop mode, resort to UART API's
53 HAL_UARTEx_StopModeWakeUpSourceConfig(), HAL_UARTEx_EnableStopMode() and
54 HAL_UARTEx_DisableStopMode() in casting the USART handle to UART type UART_HandleTypeDef.
56 ##### Callback registration #####
57 ==================================
60 The compilation define USE_HAL_USART_REGISTER_CALLBACKS when set to 1
61 allows the user to configure dynamically the driver callbacks.
64 Use Function @ref HAL_USART_RegisterCallback() to register a user callback.
65 Function @ref HAL_USART_RegisterCallback() allows to register following callbacks:
66 (+) TxHalfCpltCallback : Tx Half Complete Callback.
67 (+) TxCpltCallback : Tx Complete Callback.
68 (+) RxHalfCpltCallback : Rx Half Complete Callback.
69 (+) RxCpltCallback : Rx Complete Callback.
70 (+) TxRxCpltCallback : Tx Rx Complete Callback.
71 (+) ErrorCallback : Error Callback.
72 (+) AbortCpltCallback : Abort Complete Callback.
73 (+) RxFifoFullCallback : Rx Fifo Full Callback.
74 (+) TxFifoEmptyCallback : Tx Fifo Empty Callback.
75 (+) MspInitCallback : USART MspInit.
76 (+) MspDeInitCallback : USART MspDeInit.
77 This function takes as parameters the HAL peripheral handle, the Callback ID
78 and a pointer to the user callback function.
81 Use function @ref HAL_USART_UnRegisterCallback() to reset a callback to the default
82 weak (surcharged) function.
83 @ref HAL_USART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
85 This function allows to reset following callbacks:
86 (+) TxHalfCpltCallback : Tx Half Complete Callback.
87 (+) TxCpltCallback : Tx Complete Callback.
88 (+) RxHalfCpltCallback : Rx Half Complete Callback.
89 (+) RxCpltCallback : Rx Complete Callback.
90 (+) TxRxCpltCallback : Tx Rx Complete Callback.
91 (+) ErrorCallback : Error Callback.
92 (+) AbortCpltCallback : Abort Complete Callback.
93 (+) RxFifoFullCallback : Rx Fifo Full Callback.
94 (+) TxFifoEmptyCallback : Tx Fifo Empty Callback.
95 (+) MspInitCallback : USART MspInit.
96 (+) MspDeInitCallback : USART MspDeInit.
99 By default, after the @ref HAL_USART_Init() and when the state is HAL_USART_STATE_RESET
100 all callbacks are set to the corresponding weak (surcharged) functions:
101 examples @ref HAL_USART_TxCpltCallback(), @ref HAL_USART_RxHalfCpltCallback().
102 Exception done for MspInit and MspDeInit functions that are respectively
103 reset to the legacy weak (surcharged) functions in the @ref HAL_USART_Init()
104 and @ref HAL_USART_DeInit() only when these callbacks are null (not registered beforehand).
105 If not, MspInit or MspDeInit are not null, the @ref HAL_USART_Init() and @ref HAL_USART_DeInit()
106 keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
109 Callbacks can be registered/unregistered in HAL_USART_STATE_READY state only.
110 Exception done MspInit/MspDeInit that can be registered/unregistered
111 in HAL_USART_STATE_READY or HAL_USART_STATE_RESET state, thus registered (user)
112 MspInit/DeInit callbacks can be used during the Init/DeInit.
113 In that case first register the MspInit/MspDeInit user callbacks
114 using @ref HAL_USART_RegisterCallback() before calling @ref HAL_USART_DeInit()
115 or @ref HAL_USART_Init() function.
118 When The compilation define USE_HAL_USART_REGISTER_CALLBACKS is set to 0 or
119 not defined, the callback registration feature is not available
120 and weak (surcharged) callbacks are used.
124 ******************************************************************************
127 * <h2><center>© Copyright (c) 2017 STMicroelectronics.
128 * All rights reserved.</center></h2>
130 * This software component is licensed by ST under BSD 3-Clause license,
131 * the "License"; You may not use this file except in compliance with the
132 * License. You may obtain a copy of the License at:
133 * opensource.org/licenses/BSD-3-Clause
135 ******************************************************************************
138 /* Includes ------------------------------------------------------------------*/
139 #include "stm32h7xx_hal.h"
141 /** @addtogroup STM32H7xx_HAL_Driver
145 /** @defgroup USART USART
146 * @brief HAL USART Synchronous module driver
150 #ifdef HAL_USART_MODULE_ENABLED
152 /* Private typedef -----------------------------------------------------------*/
153 /* Private define ------------------------------------------------------------*/
154 /** @defgroup USART_Private_Constants USART Private Constants
157 #define USART_DUMMY_DATA ((uint16_t) 0xFFFF) /*!< USART transmitted dummy data */
158 #define USART_TEACK_REACK_TIMEOUT 1000U /*!< USART TX or RX enable acknowledge time-out value */
159 #define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
160 USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8 | \
161 USART_CR1_FIFOEN )) /*!< USART CR1 fields of parameters set by USART_SetConfig API */
163 #define USART_CR2_FIELDS ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | \
164 USART_CR2_LBCL | USART_CR2_STOP | USART_CR2_SLVEN | \
165 USART_CR2_DIS_NSS)) /*!< USART CR2 fields of parameters set by USART_SetConfig API */
167 #define USART_CR3_FIELDS ((uint32_t)(USART_CR3_TXFTCFG | USART_CR3_RXFTCFG )) /*!< USART or USART CR3 fields of parameters set by USART_SetConfig API */
169 #define USART_BRR_MIN 0x10U /* USART BRR minimum authorized value */
170 #define USART_BRR_MAX 0xFFFFU /* USART BRR maximum authorized value */
175 /* Private macros ------------------------------------------------------------*/
176 /* Private variables ---------------------------------------------------------*/
177 /* Private function prototypes -----------------------------------------------*/
178 /** @addtogroup USART_Private_Functions
181 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
182 void USART_InitCallbacksToDefault(USART_HandleTypeDef
*husart
);
183 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
184 static void USART_EndTransfer(USART_HandleTypeDef
*husart
);
185 static void USART_DMATransmitCplt(DMA_HandleTypeDef
*hdma
);
186 static void USART_DMAReceiveCplt(DMA_HandleTypeDef
*hdma
);
187 static void USART_DMATxHalfCplt(DMA_HandleTypeDef
*hdma
);
188 static void USART_DMARxHalfCplt(DMA_HandleTypeDef
*hdma
);
189 static void USART_DMAError(DMA_HandleTypeDef
*hdma
);
190 static void USART_DMAAbortOnError(DMA_HandleTypeDef
*hdma
);
191 static void USART_DMATxAbortCallback(DMA_HandleTypeDef
*hdma
);
192 static void USART_DMARxAbortCallback(DMA_HandleTypeDef
*hdma
);
193 static HAL_StatusTypeDef
USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef
*husart
, uint32_t Flag
, FlagStatus Status
,
194 uint32_t Tickstart
, uint32_t Timeout
);
195 static HAL_StatusTypeDef
USART_SetConfig(USART_HandleTypeDef
*husart
);
196 static HAL_StatusTypeDef
USART_CheckIdleState(USART_HandleTypeDef
*husart
);
197 static void USART_TxISR_8BIT(USART_HandleTypeDef
*husart
);
198 static void USART_TxISR_16BIT(USART_HandleTypeDef
*husart
);
199 static void USART_TxISR_8BIT_FIFOEN(USART_HandleTypeDef
*husart
);
200 static void USART_TxISR_16BIT_FIFOEN(USART_HandleTypeDef
*husart
);
201 static void USART_EndTransmit_IT(USART_HandleTypeDef
*husart
);
202 static void USART_RxISR_8BIT(USART_HandleTypeDef
*husart
);
203 static void USART_RxISR_16BIT(USART_HandleTypeDef
*husart
);
204 static void USART_RxISR_8BIT_FIFOEN(USART_HandleTypeDef
*husart
);
205 static void USART_RxISR_16BIT_FIFOEN(USART_HandleTypeDef
*husart
);
212 /* Exported functions --------------------------------------------------------*/
214 /** @defgroup USART_Exported_Functions USART Exported Functions
218 /** @defgroup USART_Exported_Functions_Group1 Initialization and de-initialization functions
219 * @brief Initialization and Configuration functions
222 ===============================================================================
223 ##### Initialization and Configuration functions #####
224 ===============================================================================
226 This subsection provides a set of functions allowing to initialize the USART
227 in asynchronous and in synchronous modes.
228 (+) For the asynchronous mode only these parameters can be configured:
232 (++) Parity: If the parity is enabled, then the MSB bit of the data written
233 in the data register is transmitted but is changed by the parity bit.
237 (++) Receiver/transmitter modes
240 The HAL_USART_Init() function follows the USART synchronous configuration
241 procedure (details for the procedure are available in reference manual).
245 Depending on the frame length defined by the M1 and M0 bits (7-bit,
246 8-bit or 9-bit), the possible USART formats are listed in the
249 Table 1. USART frame format.
250 +-----------------------------------------------------------------------+
251 | M1 bit | M0 bit | PCE bit | USART frame |
252 |---------|---------|-----------|---------------------------------------|
253 | 0 | 0 | 0 | | SB | 8 bit data | STB | |
254 |---------|---------|-----------|---------------------------------------|
255 | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | |
256 |---------|---------|-----------|---------------------------------------|
257 | 0 | 1 | 0 | | SB | 9 bit data | STB | |
258 |---------|---------|-----------|---------------------------------------|
259 | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | |
260 |---------|---------|-----------|---------------------------------------|
261 | 1 | 0 | 0 | | SB | 7 bit data | STB | |
262 |---------|---------|-----------|---------------------------------------|
263 | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | |
264 +-----------------------------------------------------------------------+
270 * @brief Initialize the USART mode according to the specified
271 * parameters in the USART_InitTypeDef and initialize the associated handle.
272 * @param husart USART handle.
275 HAL_StatusTypeDef
HAL_USART_Init(USART_HandleTypeDef
*husart
)
277 /* Check the USART handle allocation */
283 /* Check the parameters */
284 assert_param(IS_USART_INSTANCE(husart
->Instance
));
286 if (husart
->State
== HAL_USART_STATE_RESET
)
288 /* Allocate lock resource and initialize it */
289 husart
->Lock
= HAL_UNLOCKED
;
291 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
292 USART_InitCallbacksToDefault(husart
);
294 if (husart
->MspInitCallback
== NULL
)
296 husart
->MspInitCallback
= HAL_USART_MspInit
;
299 /* Init the low level hardware */
300 husart
->MspInitCallback(husart
);
302 /* Init the low level hardware : GPIO, CLOCK */
303 HAL_USART_MspInit(husart
);
304 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
307 husart
->State
= HAL_USART_STATE_BUSY
;
309 /* Disable the Peripheral */
310 __HAL_USART_DISABLE(husart
);
312 /* Set the Usart Communication parameters */
313 if (USART_SetConfig(husart
) == HAL_ERROR
)
318 /* In Synchronous mode, the following bits must be kept cleared:
319 - LINEN bit in the USART_CR2 register
320 - HDSEL, SCEN and IREN bits in the USART_CR3 register.
322 husart
->Instance
->CR2
&= ~USART_CR2_LINEN
;
323 husart
->Instance
->CR3
&= ~(USART_CR3_SCEN
| USART_CR3_HDSEL
| USART_CR3_IREN
);
325 /* Enable the Peripheral */
326 __HAL_USART_ENABLE(husart
);
328 /* TEACK and/or REACK to check before moving husart->State to Ready */
329 return (USART_CheckIdleState(husart
));
333 * @brief DeInitialize the USART peripheral.
334 * @param husart USART handle.
337 HAL_StatusTypeDef
HAL_USART_DeInit(USART_HandleTypeDef
*husart
)
339 /* Check the USART handle allocation */
345 /* Check the parameters */
346 assert_param(IS_USART_INSTANCE(husart
->Instance
));
348 husart
->State
= HAL_USART_STATE_BUSY
;
350 husart
->Instance
->CR1
= 0x0U
;
351 husart
->Instance
->CR2
= 0x0U
;
352 husart
->Instance
->CR3
= 0x0U
;
354 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
355 if (husart
->MspDeInitCallback
== NULL
)
357 husart
->MspDeInitCallback
= HAL_USART_MspDeInit
;
359 /* DeInit the low level hardware */
360 husart
->MspDeInitCallback(husart
);
362 /* DeInit the low level hardware */
363 HAL_USART_MspDeInit(husart
);
364 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
366 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
367 husart
->State
= HAL_USART_STATE_RESET
;
370 __HAL_UNLOCK(husart
);
376 * @brief Initialize the USART MSP.
377 * @param husart USART handle.
380 __weak
void HAL_USART_MspInit(USART_HandleTypeDef
*husart
)
382 /* Prevent unused argument(s) compilation warning */
385 /* NOTE : This function should not be modified, when the callback is needed,
386 the HAL_USART_MspInit can be implemented in the user file
391 * @brief DeInitialize the USART MSP.
392 * @param husart USART handle.
395 __weak
void HAL_USART_MspDeInit(USART_HandleTypeDef
*husart
)
397 /* Prevent unused argument(s) compilation warning */
400 /* NOTE : This function should not be modified, when the callback is needed,
401 the HAL_USART_MspDeInit can be implemented in the user file
405 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
407 * @brief Register a User USART Callback
408 * To be used instead of the weak predefined callback
409 * @param husart usart handle
410 * @param CallbackID ID of the callback to be registered
411 * This parameter can be one of the following values:
412 * @arg @ref HAL_USART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
413 * @arg @ref HAL_USART_TX_COMPLETE_CB_ID Tx Complete Callback ID
414 * @arg @ref HAL_USART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
415 * @arg @ref HAL_USART_RX_COMPLETE_CB_ID Rx Complete Callback ID
416 * @arg @ref HAL_USART_TX_RX_COMPLETE_CB_ID Rx Complete Callback ID
417 * @arg @ref HAL_USART_ERROR_CB_ID Error Callback ID
418 * @arg @ref HAL_USART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
419 * @arg @ref HAL_USART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
420 * @arg @ref HAL_USART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
421 * @arg @ref HAL_USART_MSPINIT_CB_ID MspInit Callback ID
422 * @arg @ref HAL_USART_MSPDEINIT_CB_ID MspDeInit Callback ID
423 * @param pCallback pointer to the Callback function
426 HAL_StatusTypeDef
HAL_USART_RegisterCallback(USART_HandleTypeDef
*husart
, HAL_USART_CallbackIDTypeDef CallbackID
,
427 pUSART_CallbackTypeDef pCallback
)
429 HAL_StatusTypeDef status
= HAL_OK
;
431 if (pCallback
== NULL
)
433 /* Update the error code */
434 husart
->ErrorCode
|= HAL_USART_ERROR_INVALID_CALLBACK
;
441 if (husart
->State
== HAL_USART_STATE_READY
)
445 case HAL_USART_TX_HALFCOMPLETE_CB_ID
:
446 husart
->TxHalfCpltCallback
= pCallback
;
449 case HAL_USART_TX_COMPLETE_CB_ID
:
450 husart
->TxCpltCallback
= pCallback
;
453 case HAL_USART_RX_HALFCOMPLETE_CB_ID
:
454 husart
->RxHalfCpltCallback
= pCallback
;
457 case HAL_USART_RX_COMPLETE_CB_ID
:
458 husart
->RxCpltCallback
= pCallback
;
461 case HAL_USART_TX_RX_COMPLETE_CB_ID
:
462 husart
->TxRxCpltCallback
= pCallback
;
465 case HAL_USART_ERROR_CB_ID
:
466 husart
->ErrorCallback
= pCallback
;
469 case HAL_USART_ABORT_COMPLETE_CB_ID
:
470 husart
->AbortCpltCallback
= pCallback
;
473 case HAL_USART_RX_FIFO_FULL_CB_ID
:
474 husart
->RxFifoFullCallback
= pCallback
;
477 case HAL_USART_TX_FIFO_EMPTY_CB_ID
:
478 husart
->TxFifoEmptyCallback
= pCallback
;
481 case HAL_USART_MSPINIT_CB_ID
:
482 husart
->MspInitCallback
= pCallback
;
485 case HAL_USART_MSPDEINIT_CB_ID
:
486 husart
->MspDeInitCallback
= pCallback
;
490 /* Update the error code */
491 husart
->ErrorCode
|= HAL_USART_ERROR_INVALID_CALLBACK
;
493 /* Return error status */
498 else if (husart
->State
== HAL_USART_STATE_RESET
)
502 case HAL_USART_MSPINIT_CB_ID
:
503 husart
->MspInitCallback
= pCallback
;
506 case HAL_USART_MSPDEINIT_CB_ID
:
507 husart
->MspDeInitCallback
= pCallback
;
511 /* Update the error code */
512 husart
->ErrorCode
|= HAL_USART_ERROR_INVALID_CALLBACK
;
514 /* Return error status */
521 /* Update the error code */
522 husart
->ErrorCode
|= HAL_USART_ERROR_INVALID_CALLBACK
;
524 /* Return error status */
529 __HAL_UNLOCK(husart
);
535 * @brief Unregister an UART Callback
536 * UART callaback is redirected to the weak predefined callback
537 * @param husart uart handle
538 * @param CallbackID ID of the callback to be unregistered
539 * This parameter can be one of the following values:
540 * @arg @ref HAL_USART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
541 * @arg @ref HAL_USART_TX_COMPLETE_CB_ID Tx Complete Callback ID
542 * @arg @ref HAL_USART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
543 * @arg @ref HAL_USART_RX_COMPLETE_CB_ID Rx Complete Callback ID
544 * @arg @ref HAL_USART_TX_RX_COMPLETE_CB_ID Rx Complete Callback ID
545 * @arg @ref HAL_USART_ERROR_CB_ID Error Callback ID
546 * @arg @ref HAL_USART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
547 * @arg @ref HAL_USART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
548 * @arg @ref HAL_USART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
549 * @arg @ref HAL_USART_MSPINIT_CB_ID MspInit Callback ID
550 * @arg @ref HAL_USART_MSPDEINIT_CB_ID MspDeInit Callback ID
553 HAL_StatusTypeDef
HAL_USART_UnRegisterCallback(USART_HandleTypeDef
*husart
, HAL_USART_CallbackIDTypeDef CallbackID
)
555 HAL_StatusTypeDef status
= HAL_OK
;
560 if (HAL_USART_STATE_READY
== husart
->State
)
564 case HAL_USART_TX_HALFCOMPLETE_CB_ID
:
565 husart
->TxHalfCpltCallback
= HAL_USART_TxHalfCpltCallback
; /* Legacy weak TxHalfCpltCallback */
568 case HAL_USART_TX_COMPLETE_CB_ID
:
569 husart
->TxCpltCallback
= HAL_USART_TxCpltCallback
; /* Legacy weak TxCpltCallback */
572 case HAL_USART_RX_HALFCOMPLETE_CB_ID
:
573 husart
->RxHalfCpltCallback
= HAL_USART_RxHalfCpltCallback
; /* Legacy weak RxHalfCpltCallback */
576 case HAL_USART_RX_COMPLETE_CB_ID
:
577 husart
->RxCpltCallback
= HAL_USART_RxCpltCallback
; /* Legacy weak RxCpltCallback */
580 case HAL_USART_TX_RX_COMPLETE_CB_ID
:
581 husart
->TxRxCpltCallback
= HAL_USART_TxRxCpltCallback
; /* Legacy weak TxRxCpltCallback */
584 case HAL_USART_ERROR_CB_ID
:
585 husart
->ErrorCallback
= HAL_USART_ErrorCallback
; /* Legacy weak ErrorCallback */
588 case HAL_USART_ABORT_COMPLETE_CB_ID
:
589 husart
->AbortCpltCallback
= HAL_USART_AbortCpltCallback
; /* Legacy weak AbortCpltCallback */
592 case HAL_USART_RX_FIFO_FULL_CB_ID
:
593 husart
->RxFifoFullCallback
= HAL_USARTEx_RxFifoFullCallback
; /* Legacy weak RxFifoFullCallback */
596 case HAL_USART_TX_FIFO_EMPTY_CB_ID
:
597 husart
->TxFifoEmptyCallback
= HAL_USARTEx_TxFifoEmptyCallback
; /* Legacy weak TxFifoEmptyCallback */
600 case HAL_USART_MSPINIT_CB_ID
:
601 husart
->MspInitCallback
= HAL_USART_MspInit
; /* Legacy weak MspInitCallback */
604 case HAL_USART_MSPDEINIT_CB_ID
:
605 husart
->MspDeInitCallback
= HAL_USART_MspDeInit
; /* Legacy weak MspDeInitCallback */
609 /* Update the error code */
610 husart
->ErrorCode
|= HAL_USART_ERROR_INVALID_CALLBACK
;
612 /* Return error status */
617 else if (HAL_USART_STATE_RESET
== husart
->State
)
621 case HAL_USART_MSPINIT_CB_ID
:
622 husart
->MspInitCallback
= HAL_USART_MspInit
;
625 case HAL_USART_MSPDEINIT_CB_ID
:
626 husart
->MspDeInitCallback
= HAL_USART_MspDeInit
;
630 /* Update the error code */
631 husart
->ErrorCode
|= HAL_USART_ERROR_INVALID_CALLBACK
;
633 /* Return error status */
640 /* Update the error code */
641 husart
->ErrorCode
|= HAL_USART_ERROR_INVALID_CALLBACK
;
643 /* Return error status */
648 __HAL_UNLOCK(husart
);
652 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
659 /** @defgroup USART_Exported_Functions_Group2 IO operation functions
660 * @brief USART Transmit and Receive functions
663 ===============================================================================
664 ##### IO operation functions #####
665 ===============================================================================
666 [..] This subsection provides a set of functions allowing to manage the USART synchronous
669 [..] The USART supports master mode only: it cannot receive or send data related to an input
670 clock (SCLK is always an output).
674 (#) There are two modes of transfer:
675 (++) Blocking mode: The communication is performed in polling mode.
676 The HAL status of all data processing is returned by the same function
677 after finishing transfer.
678 (++) No-Blocking mode: The communication is performed using Interrupts
679 or DMA, These API's return the HAL status.
680 The end of the data processing will be indicated through the
681 dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
683 The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() user callbacks
684 will be executed respectively at the end of the transmit or Receive process
685 The HAL_USART_ErrorCallback()user callback will be executed when a communication error is detected
687 (#) Blocking mode API's are :
688 (++) HAL_USART_Transmit() in simplex mode
689 (++) HAL_USART_Receive() in full duplex receive only
690 (++) HAL_USART_TransmitReceive() in full duplex mode
692 (#) Non-Blocking mode API's with Interrupt are :
693 (++) HAL_USART_Transmit_IT() in simplex mode
694 (++) HAL_USART_Receive_IT() in full duplex receive only
695 (++) HAL_USART_TransmitReceive_IT() in full duplex mode
696 (++) HAL_USART_IRQHandler()
698 (#) No-Blocking mode API's with DMA are :
699 (++) HAL_USART_Transmit_DMA() in simplex mode
700 (++) HAL_USART_Receive_DMA() in full duplex receive only
701 (++) HAL_USART_TransmitReceive_DMA() in full duplex mode
702 (++) HAL_USART_DMAPause()
703 (++) HAL_USART_DMAResume()
704 (++) HAL_USART_DMAStop()
706 (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
707 (++) HAL_USART_TxCpltCallback()
708 (++) HAL_USART_RxCpltCallback()
709 (++) HAL_USART_TxHalfCpltCallback()
710 (++) HAL_USART_RxHalfCpltCallback()
711 (++) HAL_USART_ErrorCallback()
712 (++) HAL_USART_TxRxCpltCallback()
714 (#) Non-Blocking mode transfers could be aborted using Abort API's :
715 (++) HAL_USART_Abort()
716 (++) HAL_USART_Abort_IT()
718 (#) For Abort services based on interrupts (HAL_USART_Abort_IT), a Abort Complete Callbacks is provided:
719 (++) HAL_USART_AbortCpltCallback()
721 (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
722 Errors are handled as follows :
723 (++) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
724 to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception .
725 Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type,
726 and HAL_USART_ErrorCallback() user callback is executed. Transfer is kept ongoing on USART side.
727 If user wants to abort it, Abort services should be called by user.
728 (++) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
729 This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
730 Error code is set to allow user to identify error type, and HAL_USART_ErrorCallback() user callback is executed.
737 * @brief Simplex send an amount of data in blocking mode.
738 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
739 * the sent data is handled as a set of u16. In this case, Size must indicate the number
740 * of u16 provided through pTxData.
741 * @param husart USART handle.
742 * @param pTxData Pointer to data buffer (u8 or u16 data elements).
743 * @param Size Amount of data elements (u8 or u16) to be sent.
744 * @param Timeout Timeout duration.
747 HAL_StatusTypeDef
HAL_USART_Transmit(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint16_t Size
, uint32_t Timeout
)
749 uint8_t *ptxdata8bits
;
750 uint16_t *ptxdata16bits
;
753 if (husart
->State
== HAL_USART_STATE_READY
)
755 if ((pTxData
== NULL
) || (Size
== 0U))
763 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
764 husart
->State
= HAL_USART_STATE_BUSY_TX
;
766 /* Init tickstart for timeout managment*/
767 tickstart
= HAL_GetTick();
769 husart
->TxXferSize
= Size
;
770 husart
->TxXferCount
= Size
;
772 /* In case of 9bits/No Parity transfer, pTxData needs to be handled as a uint16_t pointer */
773 if ((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
776 ptxdata16bits
= (uint16_t *) pTxData
;
780 ptxdata8bits
= pTxData
;
781 ptxdata16bits
= NULL
;
784 /* Check the remaining data to be sent */
785 while (husart
->TxXferCount
> 0U)
787 if (USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TXE
, RESET
, tickstart
, Timeout
) != HAL_OK
)
791 if (ptxdata8bits
== NULL
)
793 husart
->Instance
->TDR
= (uint16_t)(*ptxdata16bits
& 0x01FFU
);
798 husart
->Instance
->TDR
= (uint8_t)(*ptxdata8bits
& 0xFFU
);
802 husart
->TxXferCount
--;
805 if (USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TC
, RESET
, tickstart
, Timeout
) != HAL_OK
)
810 /* Clear Transmission Complete Flag */
811 __HAL_USART_CLEAR_FLAG(husart
, USART_CLEAR_TCF
);
813 /* Clear overrun flag and discard the received data */
814 __HAL_USART_CLEAR_OREFLAG(husart
);
815 __HAL_USART_SEND_REQ(husart
, USART_RXDATA_FLUSH_REQUEST
);
816 __HAL_USART_SEND_REQ(husart
, USART_TXDATA_FLUSH_REQUEST
);
818 /* At end of Tx process, restore husart->State to Ready */
819 husart
->State
= HAL_USART_STATE_READY
;
821 /* Process Unlocked */
822 __HAL_UNLOCK(husart
);
833 * @brief Receive an amount of data in blocking mode.
834 * @note To receive synchronous data, dummy data are simultaneously transmitted.
835 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
836 * the received data is handled as a set of u16. In this case, Size must indicate the number
837 * of u16 available through pRxData.
838 * @param husart USART handle.
839 * @param pRxData Pointer to data buffer (u8 or u16 data elements).
840 * @param Size Amount of data elements (u8 or u16) to be received.
841 * @param Timeout Timeout duration.
844 HAL_StatusTypeDef
HAL_USART_Receive(USART_HandleTypeDef
*husart
, uint8_t *pRxData
, uint16_t Size
, uint32_t Timeout
)
846 uint8_t *prxdata8bits
;
847 uint16_t *prxdata16bits
;
851 if (husart
->State
== HAL_USART_STATE_READY
)
853 if ((pRxData
== NULL
) || (Size
== 0U))
861 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
862 husart
->State
= HAL_USART_STATE_BUSY_RX
;
864 /* Init tickstart for timeout managment*/
865 tickstart
= HAL_GetTick();
867 husart
->RxXferSize
= Size
;
868 husart
->RxXferCount
= Size
;
870 /* Computation of USART mask to apply to RDR register */
871 USART_MASK_COMPUTATION(husart
);
872 uhMask
= husart
->Mask
;
874 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
875 if ((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
878 prxdata16bits
= (uint16_t *) pRxData
;
882 prxdata8bits
= pRxData
;
883 prxdata16bits
= NULL
;
886 /* as long as data have to be received */
887 while (husart
->RxXferCount
> 0U)
889 if (husart
->SlaveMode
== USART_SLAVEMODE_DISABLE
)
891 /* Wait until TXE flag is set to send dummy byte in order to generate the
892 * clock for the slave to send data.
893 * Whatever the frame length (7, 8 or 9-bit long), the same dummy value
894 * can be written for all the cases. */
895 if (USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TXE
, RESET
, tickstart
, Timeout
) != HAL_OK
)
899 husart
->Instance
->TDR
= (USART_DUMMY_DATA
& (uint16_t)0x0FF);
902 /* Wait for RXNE Flag */
903 if (USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_RXNE
, RESET
, tickstart
, Timeout
) != HAL_OK
)
908 if (prxdata8bits
== NULL
)
910 *prxdata16bits
= (uint16_t)(husart
->Instance
->RDR
& uhMask
);
915 *prxdata8bits
= (uint8_t)(husart
->Instance
->RDR
& (uint8_t)(uhMask
& 0xFFU
));
919 husart
->RxXferCount
--;
923 /* Clear SPI slave underrun flag and discard transmit data */
924 if (husart
->SlaveMode
== USART_SLAVEMODE_ENABLE
)
926 __HAL_USART_CLEAR_UDRFLAG(husart
);
927 __HAL_USART_SEND_REQ(husart
, USART_TXDATA_FLUSH_REQUEST
);
930 /* At end of Rx process, restore husart->State to Ready */
931 husart
->State
= HAL_USART_STATE_READY
;
933 /* Process Unlocked */
934 __HAL_UNLOCK(husart
);
945 * @brief Full-Duplex Send and Receive an amount of data in blocking mode.
946 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
947 * the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
948 * of u16 available through pTxData and through pRxData.
949 * @param husart USART handle.
950 * @param pTxData pointer to TX data buffer (u8 or u16 data elements).
951 * @param pRxData pointer to RX data buffer (u8 or u16 data elements).
952 * @param Size amount of data elements (u8 or u16) to be sent (same amount to be received).
953 * @param Timeout Timeout duration.
956 HAL_StatusTypeDef
HAL_USART_TransmitReceive(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint8_t *pRxData
,
957 uint16_t Size
, uint32_t Timeout
)
959 uint8_t *prxdata8bits
;
960 uint16_t *prxdata16bits
;
961 uint8_t *ptxdata8bits
;
962 uint16_t *ptxdata16bits
;
964 uint16_t rxdatacount
;
967 if (husart
->State
== HAL_USART_STATE_READY
)
969 if ((pTxData
== NULL
) || (pRxData
== NULL
) || (Size
== 0U))
977 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
978 husart
->State
= HAL_USART_STATE_BUSY_RX
;
980 /* Init tickstart for timeout managment*/
981 tickstart
= HAL_GetTick();
983 husart
->RxXferSize
= Size
;
984 husart
->TxXferSize
= Size
;
985 husart
->TxXferCount
= Size
;
986 husart
->RxXferCount
= Size
;
988 /* Computation of USART mask to apply to RDR register */
989 USART_MASK_COMPUTATION(husart
);
990 uhMask
= husart
->Mask
;
992 /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
993 if ((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
997 ptxdata16bits
= (uint16_t *) pTxData
;
998 prxdata16bits
= (uint16_t *) pRxData
;
1002 prxdata8bits
= pRxData
;
1003 ptxdata8bits
= pTxData
;
1004 ptxdata16bits
= NULL
;
1005 prxdata16bits
= NULL
;
1008 if ((husart
->TxXferCount
== 0x01U
) || (husart
->SlaveMode
== USART_SLAVEMODE_ENABLE
))
1010 /* Wait until TXE flag is set to send data */
1011 if (USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TXE
, RESET
, tickstart
, Timeout
) != HAL_OK
)
1015 if (ptxdata8bits
== NULL
)
1017 husart
->Instance
->TDR
= (uint16_t)(*ptxdata16bits
& uhMask
);
1022 husart
->Instance
->TDR
= (uint8_t)(*ptxdata8bits
& (uint8_t)(uhMask
& 0xFFU
));
1026 husart
->TxXferCount
--;
1029 /* Check the remain data to be sent */
1030 /* rxdatacount is a temporary variable for MISRAC2012-Rule-13.5 */
1031 rxdatacount
= husart
->RxXferCount
;
1032 while ((husart
->TxXferCount
> 0U) || (rxdatacount
> 0U))
1034 if (husart
->TxXferCount
> 0U)
1036 /* Wait until TXE flag is set to send data */
1037 if (USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_TXE
, RESET
, tickstart
, Timeout
) != HAL_OK
)
1041 if (ptxdata8bits
== NULL
)
1043 husart
->Instance
->TDR
= (uint16_t)(*ptxdata16bits
& uhMask
);
1048 husart
->Instance
->TDR
= (uint8_t)(*ptxdata8bits
& (uint8_t)(uhMask
& 0xFFU
));
1052 husart
->TxXferCount
--;
1055 if (husart
->RxXferCount
> 0U)
1057 /* Wait for RXNE Flag */
1058 if (USART_WaitOnFlagUntilTimeout(husart
, USART_FLAG_RXNE
, RESET
, tickstart
, Timeout
) != HAL_OK
)
1063 if (prxdata8bits
== NULL
)
1065 *prxdata16bits
= (uint16_t)(husart
->Instance
->RDR
& uhMask
);
1070 *prxdata8bits
= (uint8_t)(husart
->Instance
->RDR
& (uint8_t)(uhMask
& 0xFFU
));
1074 husart
->RxXferCount
--;
1076 rxdatacount
= husart
->RxXferCount
;
1079 /* At end of TxRx process, restore husart->State to Ready */
1080 husart
->State
= HAL_USART_STATE_READY
;
1082 /* Process Unlocked */
1083 __HAL_UNLOCK(husart
);
1094 * @brief Send an amount of data in interrupt mode.
1095 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1096 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1097 * of u16 provided through pTxData.
1098 * @param husart USART handle.
1099 * @param pTxData pointer to data buffer (u8 or u16 data elements).
1100 * @param Size amount of data elements (u8 or u16) to be sent.
1101 * @retval HAL status
1103 HAL_StatusTypeDef
HAL_USART_Transmit_IT(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint16_t Size
)
1105 if (husart
->State
== HAL_USART_STATE_READY
)
1107 if ((pTxData
== NULL
) || (Size
== 0U))
1112 /* Process Locked */
1115 husart
->pTxBuffPtr
= pTxData
;
1116 husart
->TxXferSize
= Size
;
1117 husart
->TxXferCount
= Size
;
1118 husart
->TxISR
= NULL
;
1120 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
1121 husart
->State
= HAL_USART_STATE_BUSY_TX
;
1123 /* The USART Error Interrupts: (Frame error, noise error, overrun error)
1124 are not managed by the USART Transmit Process to avoid the overrun interrupt
1125 when the usart mode is configured for transmit and receive "USART_MODE_TX_RX"
1126 to benefit for the frame error and noise interrupts the usart mode should be
1127 configured only for transmit "USART_MODE_TX" */
1129 /* Configure Tx interrupt processing */
1130 if (husart
->FifoMode
== USART_FIFOMODE_ENABLE
)
1132 /* Set the Tx ISR function pointer according to the data word length */
1133 if ((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
1135 husart
->TxISR
= USART_TxISR_16BIT_FIFOEN
;
1139 husart
->TxISR
= USART_TxISR_8BIT_FIFOEN
;
1142 /* Process Unlocked */
1143 __HAL_UNLOCK(husart
);
1145 /* Enable the TX FIFO threshold interrupt */
1146 __HAL_USART_ENABLE_IT(husart
, USART_IT_TXFT
);
1150 /* Set the Tx ISR function pointer according to the data word length */
1151 if ((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
1153 husart
->TxISR
= USART_TxISR_16BIT
;
1157 husart
->TxISR
= USART_TxISR_8BIT
;
1160 /* Process Unlocked */
1161 __HAL_UNLOCK(husart
);
1163 /* Enable the USART Transmit Data Register Empty Interrupt */
1164 __HAL_USART_ENABLE_IT(husart
, USART_IT_TXE
);
1176 * @brief Receive an amount of data in interrupt mode.
1177 * @note To receive synchronous data, dummy data are simultaneously transmitted.
1178 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1179 * the received data is handled as a set of u16. In this case, Size must indicate the number
1180 * of u16 available through pRxData.
1181 * @param husart USART handle.
1182 * @param pRxData pointer to data buffer (u8 or u16 data elements).
1183 * @param Size amount of data elements (u8 or u16) to be received.
1184 * @retval HAL status
1186 HAL_StatusTypeDef
HAL_USART_Receive_IT(USART_HandleTypeDef
*husart
, uint8_t *pRxData
, uint16_t Size
)
1188 uint16_t nb_dummy_data
;
1190 if (husart
->State
== HAL_USART_STATE_READY
)
1192 if ((pRxData
== NULL
) || (Size
== 0U))
1197 /* Process Locked */
1200 husart
->pRxBuffPtr
= pRxData
;
1201 husart
->RxXferSize
= Size
;
1202 husart
->RxXferCount
= Size
;
1203 husart
->RxISR
= NULL
;
1205 USART_MASK_COMPUTATION(husart
);
1207 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
1208 husart
->State
= HAL_USART_STATE_BUSY_RX
;
1210 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1211 SET_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1213 /* Configure Rx interrupt processing */
1214 if ((husart
->FifoMode
== USART_FIFOMODE_ENABLE
) && (Size
>= husart
->NbRxDataToProcess
))
1216 /* Set the Rx ISR function pointer according to the data word length */
1217 if ((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
1219 husart
->RxISR
= USART_RxISR_16BIT_FIFOEN
;
1223 husart
->RxISR
= USART_RxISR_8BIT_FIFOEN
;
1226 /* Process Unlocked */
1227 __HAL_UNLOCK(husart
);
1229 /* Enable the USART Parity Error interrupt and RX FIFO Threshold interrupt */
1230 SET_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
1231 SET_BIT(husart
->Instance
->CR3
, USART_CR3_RXFTIE
);
1235 /* Set the Rx ISR function pointer according to the data word length */
1236 if ((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
1238 husart
->RxISR
= USART_RxISR_16BIT
;
1242 husart
->RxISR
= USART_RxISR_8BIT
;
1245 /* Process Unlocked */
1246 __HAL_UNLOCK(husart
);
1248 /* Enable the USART Parity Error and Data Register not empty Interrupts */
1249 SET_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
| USART_CR1_RXNEIE_RXFNEIE
);
1252 if (husart
->SlaveMode
== USART_SLAVEMODE_DISABLE
)
1254 /* Send dummy data in order to generate the clock for the Slave to send the next data.
1255 When FIFO mode is disabled only one data must be transferred.
1256 When FIFO mode is enabled data must be transmitted until the RX FIFO reaches its threshold.
1258 if ((husart
->FifoMode
== USART_FIFOMODE_ENABLE
) && (Size
>= husart
->NbRxDataToProcess
))
1260 for (nb_dummy_data
= husart
->NbRxDataToProcess
; nb_dummy_data
> 0U ; nb_dummy_data
--)
1262 husart
->Instance
->TDR
= (USART_DUMMY_DATA
& (uint16_t)0x00FF);
1267 husart
->Instance
->TDR
= (USART_DUMMY_DATA
& (uint16_t)0x00FF);
1280 * @brief Full-Duplex Send and Receive an amount of data in interrupt mode.
1281 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1282 * the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
1283 * of u16 available through pTxData and through pRxData.
1284 * @param husart USART handle.
1285 * @param pTxData pointer to TX data buffer (u8 or u16 data elements).
1286 * @param pRxData pointer to RX data buffer (u8 or u16 data elements).
1287 * @param Size amount of data elements (u8 or u16) to be sent (same amount to be received).
1288 * @retval HAL status
1290 HAL_StatusTypeDef
HAL_USART_TransmitReceive_IT(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint8_t *pRxData
,
1294 if (husart
->State
== HAL_USART_STATE_READY
)
1296 if ((pTxData
== NULL
) || (pRxData
== NULL
) || (Size
== 0U))
1301 /* Process Locked */
1304 husart
->pRxBuffPtr
= pRxData
;
1305 husart
->RxXferSize
= Size
;
1306 husart
->RxXferCount
= Size
;
1307 husart
->pTxBuffPtr
= pTxData
;
1308 husart
->TxXferSize
= Size
;
1309 husart
->TxXferCount
= Size
;
1311 /* Computation of USART mask to apply to RDR register */
1312 USART_MASK_COMPUTATION(husart
);
1314 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
1315 husart
->State
= HAL_USART_STATE_BUSY_TX_RX
;
1317 /* Configure TxRx interrupt processing */
1318 if ((husart
->FifoMode
== USART_FIFOMODE_ENABLE
) && (Size
>= husart
->NbRxDataToProcess
))
1320 /* Set the Rx ISR function pointer according to the data word length */
1321 if ((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
1323 husart
->TxISR
= USART_TxISR_16BIT_FIFOEN
;
1324 husart
->RxISR
= USART_RxISR_16BIT_FIFOEN
;
1328 husart
->TxISR
= USART_TxISR_8BIT_FIFOEN
;
1329 husart
->RxISR
= USART_RxISR_8BIT_FIFOEN
;
1332 /* Process Locked */
1333 __HAL_UNLOCK(husart
);
1335 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1336 SET_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1338 /* Enable the USART Parity Error interrupt */
1339 SET_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
1341 /* Enable the TX and RX FIFO Threshold interrupts */
1342 SET_BIT(husart
->Instance
->CR3
, (USART_CR3_TXFTIE
| USART_CR3_RXFTIE
));
1346 if ((husart
->Init
.WordLength
== USART_WORDLENGTH_9B
) && (husart
->Init
.Parity
== USART_PARITY_NONE
))
1348 husart
->TxISR
= USART_TxISR_16BIT
;
1349 husart
->RxISR
= USART_RxISR_16BIT
;
1353 husart
->TxISR
= USART_TxISR_8BIT
;
1354 husart
->RxISR
= USART_RxISR_8BIT
;
1357 /* Process Locked */
1358 __HAL_UNLOCK(husart
);
1360 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1361 SET_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1363 /* Enable the USART Parity Error and USART Data Register not empty Interrupts */
1364 SET_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
| USART_CR1_RXNEIE_RXFNEIE
);
1366 /* Enable the USART Transmit Data Register Empty Interrupt */
1367 SET_BIT(husart
->Instance
->CR1
, USART_CR1_TXEIE_TXFNFIE
);
1379 * @brief Send an amount of data in DMA mode.
1380 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1381 * the sent data is handled as a set of u16. In this case, Size must indicate the number
1382 * of u16 provided through pTxData.
1383 * @param husart USART handle.
1384 * @param pTxData pointer to data buffer (u8 or u16 data elements).
1385 * @param Size amount of data elements (u8 or u16) to be sent.
1386 * @retval HAL status
1388 HAL_StatusTypeDef
HAL_USART_Transmit_DMA(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint16_t Size
)
1390 HAL_StatusTypeDef status
= HAL_OK
;
1393 if (husart
->State
== HAL_USART_STATE_READY
)
1395 if ((pTxData
== NULL
) || (Size
== 0U))
1400 /* Process Locked */
1403 husart
->pTxBuffPtr
= pTxData
;
1404 husart
->TxXferSize
= Size
;
1405 husart
->TxXferCount
= Size
;
1407 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
1408 husart
->State
= HAL_USART_STATE_BUSY_TX
;
1410 if (husart
->hdmatx
!= NULL
)
1412 /* Set the USART DMA transfer complete callback */
1413 husart
->hdmatx
->XferCpltCallback
= USART_DMATransmitCplt
;
1415 /* Set the USART DMA Half transfer complete callback */
1416 husart
->hdmatx
->XferHalfCpltCallback
= USART_DMATxHalfCplt
;
1418 /* Set the DMA error callback */
1419 husart
->hdmatx
->XferErrorCallback
= USART_DMAError
;
1421 /* Enable the USART transmit DMA channel */
1422 tmp
= (uint32_t *)&pTxData
;
1423 status
= HAL_DMA_Start_IT(husart
->hdmatx
, *(uint32_t *)tmp
, (uint32_t)&husart
->Instance
->TDR
, Size
);
1426 if (status
== HAL_OK
)
1428 /* Clear the TC flag in the ICR register */
1429 __HAL_USART_CLEAR_FLAG(husart
, USART_CLEAR_TCF
);
1431 /* Process Unlocked */
1432 __HAL_UNLOCK(husart
);
1434 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1435 in the USART CR3 register */
1436 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1442 /* Set error code to DMA */
1443 husart
->ErrorCode
= HAL_USART_ERROR_DMA
;
1445 /* Process Unlocked */
1446 __HAL_UNLOCK(husart
);
1448 /* Restore husart->State to ready */
1449 husart
->State
= HAL_USART_STATE_READY
;
1461 * @brief Receive an amount of data in DMA mode.
1462 * @note When the USART parity is enabled (PCE = 1), the received data contain
1463 * the parity bit (MSB position).
1464 * @note The USART DMA transmit channel must be configured in order to generate the clock for the slave.
1465 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1466 * the received data is handled as a set of u16. In this case, Size must indicate the number
1467 * of u16 available through pRxData.
1468 * @param husart USART handle.
1469 * @param pRxData pointer to data buffer (u8 or u16 data elements).
1470 * @param Size amount of data elements (u8 or u16) to be received.
1471 * @retval HAL status
1473 HAL_StatusTypeDef
HAL_USART_Receive_DMA(USART_HandleTypeDef
*husart
, uint8_t *pRxData
, uint16_t Size
)
1475 HAL_StatusTypeDef status
= HAL_OK
;
1476 uint32_t *tmp
= (uint32_t *)&pRxData
;
1478 /* Check that a Rx process is not already ongoing */
1479 if (husart
->State
== HAL_USART_STATE_READY
)
1481 if ((pRxData
== NULL
) || (Size
== 0U))
1486 /* Process Locked */
1489 husart
->pRxBuffPtr
= pRxData
;
1490 husart
->RxXferSize
= Size
;
1491 husart
->pTxBuffPtr
= pRxData
;
1492 husart
->TxXferSize
= Size
;
1494 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
1495 husart
->State
= HAL_USART_STATE_BUSY_RX
;
1497 if (husart
->hdmarx
!= NULL
)
1499 /* Set the USART DMA Rx transfer complete callback */
1500 husart
->hdmarx
->XferCpltCallback
= USART_DMAReceiveCplt
;
1502 /* Set the USART DMA Half transfer complete callback */
1503 husart
->hdmarx
->XferHalfCpltCallback
= USART_DMARxHalfCplt
;
1505 /* Set the USART DMA Rx transfer error callback */
1506 husart
->hdmarx
->XferErrorCallback
= USART_DMAError
;
1508 /* Enable the USART receive DMA channel */
1509 status
= HAL_DMA_Start_IT(husart
->hdmarx
, (uint32_t)&husart
->Instance
->RDR
, *(uint32_t *)tmp
, Size
);
1512 if ((status
== HAL_OK
) &&
1513 (husart
->SlaveMode
== USART_SLAVEMODE_DISABLE
))
1515 /* Enable the USART transmit DMA channel: the transmit channel is used in order
1516 to generate in the non-blocking mode the clock to the slave device,
1517 this mode isn't a simplex receive mode but a full-duplex receive mode */
1519 /* Set the USART DMA Tx Complete and Error callback to Null */
1520 if (husart
->hdmatx
!= NULL
)
1522 husart
->hdmatx
->XferErrorCallback
= NULL
;
1523 husart
->hdmatx
->XferHalfCpltCallback
= NULL
;
1524 husart
->hdmatx
->XferCpltCallback
= NULL
;
1525 status
= HAL_DMA_Start_IT(husart
->hdmatx
, *(uint32_t *)tmp
, (uint32_t)&husart
->Instance
->TDR
, Size
);
1529 if (status
== HAL_OK
)
1531 /* Process Unlocked */
1532 __HAL_UNLOCK(husart
);
1534 /* Enable the USART Parity Error Interrupt */
1535 SET_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
1537 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1538 SET_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1540 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1541 in the USART CR3 register */
1542 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1544 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1545 in the USART CR3 register */
1546 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1552 if (husart
->hdmarx
!= NULL
)
1554 status
= HAL_DMA_Abort(husart
->hdmarx
);
1557 /* No need to check on error code */
1560 /* Set error code to DMA */
1561 husart
->ErrorCode
= HAL_USART_ERROR_DMA
;
1563 /* Process Unlocked */
1564 __HAL_UNLOCK(husart
);
1566 /* Restore husart->State to ready */
1567 husart
->State
= HAL_USART_STATE_READY
;
1579 * @brief Full-Duplex Transmit Receive an amount of data in non-blocking mode.
1580 * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
1581 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
1582 * the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
1583 * of u16 available through pTxData and through pRxData.
1584 * @param husart USART handle.
1585 * @param pTxData pointer to TX data buffer (u8 or u16 data elements).
1586 * @param pRxData pointer to RX data buffer (u8 or u16 data elements).
1587 * @param Size amount of data elements (u8 or u16) to be received/sent.
1588 * @retval HAL status
1590 HAL_StatusTypeDef
HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef
*husart
, uint8_t *pTxData
, uint8_t *pRxData
,
1593 HAL_StatusTypeDef status
;
1596 if (husart
->State
== HAL_USART_STATE_READY
)
1598 if ((pTxData
== NULL
) || (pRxData
== NULL
) || (Size
== 0U))
1603 /* Process Locked */
1606 husart
->pRxBuffPtr
= pRxData
;
1607 husart
->RxXferSize
= Size
;
1608 husart
->pTxBuffPtr
= pTxData
;
1609 husart
->TxXferSize
= Size
;
1611 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
1612 husart
->State
= HAL_USART_STATE_BUSY_TX_RX
;
1614 if ((husart
->hdmarx
!= NULL
) && (husart
->hdmatx
!= NULL
))
1616 /* Set the USART DMA Rx transfer complete callback */
1617 husart
->hdmarx
->XferCpltCallback
= USART_DMAReceiveCplt
;
1619 /* Set the USART DMA Half transfer complete callback */
1620 husart
->hdmarx
->XferHalfCpltCallback
= USART_DMARxHalfCplt
;
1622 /* Set the USART DMA Tx transfer complete callback */
1623 husart
->hdmatx
->XferCpltCallback
= USART_DMATransmitCplt
;
1625 /* Set the USART DMA Half transfer complete callback */
1626 husart
->hdmatx
->XferHalfCpltCallback
= USART_DMATxHalfCplt
;
1628 /* Set the USART DMA Tx transfer error callback */
1629 husart
->hdmatx
->XferErrorCallback
= USART_DMAError
;
1631 /* Set the USART DMA Rx transfer error callback */
1632 husart
->hdmarx
->XferErrorCallback
= USART_DMAError
;
1634 /* Enable the USART receive DMA channel */
1635 tmp
= (uint32_t *)&pRxData
;
1636 status
= HAL_DMA_Start_IT(husart
->hdmarx
, (uint32_t)&husart
->Instance
->RDR
, *(uint32_t *)tmp
, Size
);
1638 /* Enable the USART transmit DMA channel */
1639 if (status
== HAL_OK
)
1641 tmp
= (uint32_t *)&pTxData
;
1642 status
= HAL_DMA_Start_IT(husart
->hdmatx
, *(uint32_t *)tmp
, (uint32_t)&husart
->Instance
->TDR
, Size
);
1650 if (status
== HAL_OK
)
1652 /* Process Unlocked */
1653 __HAL_UNLOCK(husart
);
1655 /* Enable the USART Parity Error Interrupt */
1656 SET_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
1658 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1659 SET_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1661 /* Clear the TC flag in the ICR register */
1662 __HAL_USART_CLEAR_FLAG(husart
, USART_CLEAR_TCF
);
1664 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1665 in the USART CR3 register */
1666 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1668 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1669 in the USART CR3 register */
1670 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1676 if (husart
->hdmarx
!= NULL
)
1678 status
= HAL_DMA_Abort(husart
->hdmarx
);
1681 /* No need to check on error code */
1684 /* Set error code to DMA */
1685 husart
->ErrorCode
= HAL_USART_ERROR_DMA
;
1687 /* Process Unlocked */
1688 __HAL_UNLOCK(husart
);
1690 /* Restore husart->State to ready */
1691 husart
->State
= HAL_USART_STATE_READY
;
1703 * @brief Pause the DMA Transfer.
1704 * @param husart USART handle.
1705 * @retval HAL status
1707 HAL_StatusTypeDef
HAL_USART_DMAPause(USART_HandleTypeDef
*husart
)
1709 const HAL_USART_StateTypeDef state
= husart
->State
;
1711 /* Process Locked */
1714 if ((HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAT
)) &&
1715 (state
== HAL_USART_STATE_BUSY_TX
))
1717 /* Disable the USART DMA Tx request */
1718 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1720 else if ((state
== HAL_USART_STATE_BUSY_RX
) ||
1721 (state
== HAL_USART_STATE_BUSY_TX_RX
))
1723 if (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAT
))
1725 /* Disable the USART DMA Tx request */
1726 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1728 if (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAR
))
1730 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
1731 CLEAR_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
1732 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1734 /* Disable the USART DMA Rx request */
1735 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1743 /* Process Unlocked */
1744 __HAL_UNLOCK(husart
);
1750 * @brief Resume the DMA Transfer.
1751 * @param husart USART handle.
1752 * @retval HAL status
1754 HAL_StatusTypeDef
HAL_USART_DMAResume(USART_HandleTypeDef
*husart
)
1756 const HAL_USART_StateTypeDef state
= husart
->State
;
1758 /* Process Locked */
1761 if (state
== HAL_USART_STATE_BUSY_TX
)
1763 /* Enable the USART DMA Tx request */
1764 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1766 else if ((state
== HAL_USART_STATE_BUSY_RX
) ||
1767 (state
== HAL_USART_STATE_BUSY_TX_RX
))
1769 /* Clear the Overrun flag before resuming the Rx transfer*/
1770 __HAL_USART_CLEAR_FLAG(husart
, USART_CLEAR_OREF
);
1772 /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */
1773 SET_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
1774 SET_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
1776 /* Enable the USART DMA Rx request before the DMA Tx request */
1777 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1779 /* Enable the USART DMA Tx request */
1780 SET_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1787 /* Process Unlocked */
1788 __HAL_UNLOCK(husart
);
1794 * @brief Stop the DMA Transfer.
1795 * @param husart USART handle.
1796 * @retval HAL status
1798 HAL_StatusTypeDef
HAL_USART_DMAStop(USART_HandleTypeDef
*husart
)
1800 /* The Lock is not implemented on this API to allow the user application
1801 to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback() /
1802 HAL_USART_TxHalfCpltCallback / HAL_USART_RxHalfCpltCallback:
1803 indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
1804 interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
1805 the stream and the corresponding call back is executed. */
1807 /* Disable the USART Tx/Rx DMA requests */
1808 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1809 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1811 /* Abort the USART DMA tx channel */
1812 if (husart
->hdmatx
!= NULL
)
1814 if (HAL_DMA_Abort(husart
->hdmatx
) != HAL_OK
)
1816 if (HAL_DMA_GetError(husart
->hdmatx
) == HAL_DMA_ERROR_TIMEOUT
)
1818 /* Set error code to DMA */
1819 husart
->ErrorCode
= HAL_USART_ERROR_DMA
;
1825 /* Abort the USART DMA rx channel */
1826 if (husart
->hdmarx
!= NULL
)
1828 if (HAL_DMA_Abort(husart
->hdmarx
) != HAL_OK
)
1830 if (HAL_DMA_GetError(husart
->hdmarx
) == HAL_DMA_ERROR_TIMEOUT
)
1832 /* Set error code to DMA */
1833 husart
->ErrorCode
= HAL_USART_ERROR_DMA
;
1840 USART_EndTransfer(husart
);
1841 husart
->State
= HAL_USART_STATE_READY
;
1847 * @brief Abort ongoing transfers (blocking mode).
1848 * @param husart USART handle.
1849 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1850 * This procedure performs following operations :
1851 * - Disable USART Interrupts (Tx and Rx)
1852 * - Disable the DMA transfer in the peripheral register (if enabled)
1853 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1854 * - Set handle State to READY
1855 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1856 * @retval HAL status
1858 HAL_StatusTypeDef
HAL_USART_Abort(USART_HandleTypeDef
*husart
)
1860 /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */
1861 CLEAR_BIT(husart
->Instance
->CR1
, (USART_CR1_RXNEIE_RXFNEIE
| USART_CR1_PEIE
| USART_CR1_TXEIE_TXFNFIE
|
1863 CLEAR_BIT(husart
->Instance
->CR3
, (USART_CR3_EIE
| USART_CR3_RXFTIE
| USART_CR3_TXFTIE
));
1865 /* Disable the USART DMA Tx request if enabled */
1866 if (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAT
))
1868 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
1870 /* Abort the USART DMA Tx channel : use blocking DMA Abort API (no callback) */
1871 if (husart
->hdmatx
!= NULL
)
1873 /* Set the USART DMA Abort callback to Null.
1874 No call back execution at end of DMA abort procedure */
1875 husart
->hdmatx
->XferAbortCallback
= NULL
;
1877 if (HAL_DMA_Abort(husart
->hdmatx
) != HAL_OK
)
1879 if (HAL_DMA_GetError(husart
->hdmatx
) == HAL_DMA_ERROR_TIMEOUT
)
1881 /* Set error code to DMA */
1882 husart
->ErrorCode
= HAL_USART_ERROR_DMA
;
1890 /* Disable the USART DMA Rx request if enabled */
1891 if (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAR
))
1893 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
1895 /* Abort the USART DMA Rx channel : use blocking DMA Abort API (no callback) */
1896 if (husart
->hdmarx
!= NULL
)
1898 /* Set the USART DMA Abort callback to Null.
1899 No call back execution at end of DMA abort procedure */
1900 husart
->hdmarx
->XferAbortCallback
= NULL
;
1902 if (HAL_DMA_Abort(husart
->hdmarx
) != HAL_OK
)
1904 if (HAL_DMA_GetError(husart
->hdmarx
) == HAL_DMA_ERROR_TIMEOUT
)
1906 /* Set error code to DMA */
1907 husart
->ErrorCode
= HAL_USART_ERROR_DMA
;
1915 /* Reset Tx and Rx transfer counters */
1916 husart
->TxXferCount
= 0U;
1917 husart
->RxXferCount
= 0U;
1919 /* Clear the Error flags in the ICR register */
1920 __HAL_USART_CLEAR_FLAG(husart
, USART_CLEAR_OREF
| USART_CLEAR_NEF
| USART_CLEAR_PEF
| USART_CLEAR_FEF
);
1922 /* Flush the whole TX FIFO (if needed) */
1923 if (husart
->FifoMode
== USART_FIFOMODE_ENABLE
)
1925 __HAL_USART_SEND_REQ(husart
, USART_TXDATA_FLUSH_REQUEST
);
1928 /* Discard the received data */
1929 __HAL_USART_SEND_REQ(husart
, USART_RXDATA_FLUSH_REQUEST
);
1931 /* Restore husart->State to Ready */
1932 husart
->State
= HAL_USART_STATE_READY
;
1934 /* Reset Handle ErrorCode to No Error */
1935 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
1941 * @brief Abort ongoing transfers (Interrupt mode).
1942 * @param husart USART handle.
1943 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1944 * This procedure performs following operations :
1945 * - Disable USART Interrupts (Tx and Rx)
1946 * - Disable the DMA transfer in the peripheral register (if enabled)
1947 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1948 * - Set handle State to READY
1949 * - At abort completion, call user abort complete callback
1950 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
1951 * considered as completed only when user abort complete callback is executed (not when exiting function).
1952 * @retval HAL status
1954 HAL_StatusTypeDef
HAL_USART_Abort_IT(USART_HandleTypeDef
*husart
)
1956 uint32_t abortcplt
= 1U;
1958 /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */
1959 CLEAR_BIT(husart
->Instance
->CR1
, (USART_CR1_RXNEIE_RXFNEIE
| USART_CR1_PEIE
| USART_CR1_TXEIE_TXFNFIE
|
1961 CLEAR_BIT(husart
->Instance
->CR3
, (USART_CR3_EIE
| USART_CR3_RXFTIE
| USART_CR3_TXFTIE
));
1963 /* If DMA Tx and/or DMA Rx Handles are associated to USART Handle, DMA Abort complete callbacks should be initialised
1964 before any call to DMA Abort functions */
1965 /* DMA Tx Handle is valid */
1966 if (husart
->hdmatx
!= NULL
)
1968 /* Set DMA Abort Complete callback if USART DMA Tx request if enabled.
1969 Otherwise, set it to NULL */
1970 if (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAT
))
1972 husart
->hdmatx
->XferAbortCallback
= USART_DMATxAbortCallback
;
1976 husart
->hdmatx
->XferAbortCallback
= NULL
;
1979 /* DMA Rx Handle is valid */
1980 if (husart
->hdmarx
!= NULL
)
1982 /* Set DMA Abort Complete callback if USART DMA Rx request if enabled.
1983 Otherwise, set it to NULL */
1984 if (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAR
))
1986 husart
->hdmarx
->XferAbortCallback
= USART_DMARxAbortCallback
;
1990 husart
->hdmarx
->XferAbortCallback
= NULL
;
1994 /* Disable the USART DMA Tx request if enabled */
1995 if (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAT
))
1997 /* Disable DMA Tx at USART level */
1998 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
2000 /* Abort the USART DMA Tx channel : use non blocking DMA Abort API (callback) */
2001 if (husart
->hdmatx
!= NULL
)
2003 /* USART Tx DMA Abort callback has already been initialised :
2004 will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
2007 if (HAL_DMA_Abort_IT(husart
->hdmatx
) != HAL_OK
)
2009 husart
->hdmatx
->XferAbortCallback
= NULL
;
2018 /* Disable the USART DMA Rx request if enabled */
2019 if (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAR
))
2021 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
2023 /* Abort the USART DMA Rx channel : use non blocking DMA Abort API (callback) */
2024 if (husart
->hdmarx
!= NULL
)
2026 /* USART Rx DMA Abort callback has already been initialised :
2027 will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
2030 if (HAL_DMA_Abort_IT(husart
->hdmarx
) != HAL_OK
)
2032 husart
->hdmarx
->XferAbortCallback
= NULL
;
2042 /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
2043 if (abortcplt
== 1U)
2045 /* Reset Tx and Rx transfer counters */
2046 husart
->TxXferCount
= 0U;
2047 husart
->RxXferCount
= 0U;
2049 /* Reset errorCode */
2050 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
2052 /* Clear the Error flags in the ICR register */
2053 __HAL_USART_CLEAR_FLAG(husart
, USART_CLEAR_OREF
| USART_CLEAR_NEF
| USART_CLEAR_PEF
| USART_CLEAR_FEF
);
2055 /* Flush the whole TX FIFO (if needed) */
2056 if (husart
->FifoMode
== USART_FIFOMODE_ENABLE
)
2058 __HAL_USART_SEND_REQ(husart
, USART_TXDATA_FLUSH_REQUEST
);
2061 /* Discard the received data */
2062 __HAL_USART_SEND_REQ(husart
, USART_RXDATA_FLUSH_REQUEST
);
2064 /* Restore husart->State to Ready */
2065 husart
->State
= HAL_USART_STATE_READY
;
2067 /* As no DMA to be aborted, call directly user Abort complete callback */
2068 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2069 /* Call registered Abort Complete Callback */
2070 husart
->AbortCpltCallback(husart
);
2072 /* Call legacy weak Abort Complete Callback */
2073 HAL_USART_AbortCpltCallback(husart
);
2074 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2081 * @brief Handle USART interrupt request.
2082 * @param husart USART handle.
2085 void HAL_USART_IRQHandler(USART_HandleTypeDef
*husart
)
2087 uint32_t isrflags
= READ_REG(husart
->Instance
->ISR
);
2088 uint32_t cr1its
= READ_REG(husart
->Instance
->CR1
);
2089 uint32_t cr3its
= READ_REG(husart
->Instance
->CR3
);
2091 uint32_t errorflags
;
2094 /* If no error occurs */
2095 errorflags
= (isrflags
& (uint32_t)(USART_ISR_PE
| USART_ISR_FE
| USART_ISR_ORE
| USART_ISR_NE
| USART_ISR_RTOF
| USART_ISR_UDR
));
2096 if (errorflags
== 0U)
2098 /* USART in mode Receiver ---------------------------------------------------*/
2099 if (((isrflags
& USART_ISR_RXNE_RXFNE
) != 0U)
2100 && (((cr1its
& USART_CR1_RXNEIE_RXFNEIE
) != 0U)
2101 || ((cr3its
& USART_CR3_RXFTIE
) != 0U)))
2103 if (husart
->RxISR
!= NULL
)
2105 husart
->RxISR(husart
);
2111 /* If some errors occur */
2112 if ((errorflags
!= 0U)
2113 && (((cr3its
& (USART_CR3_RXFTIE
| USART_CR3_EIE
)) != 0U)
2114 || ((cr1its
& (USART_CR1_RXNEIE_RXFNEIE
| USART_CR1_PEIE
)) != 0U)))
2116 /* USART parity error interrupt occurred -------------------------------------*/
2117 if (((isrflags
& USART_ISR_PE
) != 0U) && ((cr1its
& USART_CR1_PEIE
) != 0U))
2119 __HAL_USART_CLEAR_IT(husart
, USART_CLEAR_PEF
);
2121 husart
->ErrorCode
|= HAL_USART_ERROR_PE
;
2124 /* USART frame error interrupt occurred --------------------------------------*/
2125 if (((isrflags
& USART_ISR_FE
) != 0U) && ((cr3its
& USART_CR3_EIE
) != 0U))
2127 __HAL_USART_CLEAR_IT(husart
, USART_CLEAR_FEF
);
2129 husart
->ErrorCode
|= HAL_USART_ERROR_FE
;
2132 /* USART noise error interrupt occurred --------------------------------------*/
2133 if (((isrflags
& USART_ISR_NE
) != 0U) && ((cr3its
& USART_CR3_EIE
) != 0U))
2135 __HAL_USART_CLEAR_IT(husart
, USART_CLEAR_NEF
);
2137 husart
->ErrorCode
|= HAL_USART_ERROR_NE
;
2140 /* USART Over-Run interrupt occurred -----------------------------------------*/
2141 if (((isrflags
& USART_ISR_ORE
) != 0U)
2142 && (((cr1its
& USART_CR1_RXNEIE_RXFNEIE
) != 0U) ||
2143 ((cr3its
& (USART_CR3_RXFTIE
| USART_CR3_EIE
)) != 0U)))
2145 __HAL_USART_CLEAR_IT(husart
, USART_CLEAR_OREF
);
2147 husart
->ErrorCode
|= HAL_USART_ERROR_ORE
;
2150 /* USART Receiver Timeout interrupt occurred ---------------------------------*/
2151 if (((isrflags
& USART_ISR_RTOF
) != 0U) && ((cr1its
& USART_CR1_RTOIE
) != 0U))
2153 __HAL_USART_CLEAR_IT(husart
, USART_CLEAR_RTOF
);
2155 husart
->ErrorCode
|= HAL_USART_ERROR_RTO
;
2158 /* USART SPI slave underrun error interrupt occurred -------------------------*/
2159 if (((isrflags
& USART_ISR_UDR
) != 0U) && ((cr3its
& USART_CR3_EIE
) != 0U))
2161 /* Ignore SPI slave underrun errors when reception is going on */
2162 if (husart
->State
== HAL_USART_STATE_BUSY_RX
)
2164 __HAL_USART_CLEAR_UDRFLAG(husart
);
2169 __HAL_USART_CLEAR_UDRFLAG(husart
);
2170 husart
->ErrorCode
|= HAL_USART_ERROR_UDR
;
2174 /* Call USART Error Call back function if need be --------------------------*/
2175 if (husart
->ErrorCode
!= HAL_USART_ERROR_NONE
)
2177 /* USART in mode Receiver ---------------------------------------------------*/
2178 if (((isrflags
& USART_ISR_RXNE_RXFNE
) != 0U)
2179 && (((cr1its
& USART_CR1_RXNEIE_RXFNEIE
) != 0U)
2180 || ((cr3its
& USART_CR3_RXFTIE
) != 0U)))
2182 if (husart
->RxISR
!= NULL
)
2184 husart
->RxISR(husart
);
2188 /* If Overrun error occurs, or if any error occurs in DMA mode reception,
2189 consider error as blocking */
2190 errorcode
= husart
->ErrorCode
& HAL_USART_ERROR_ORE
;
2191 if ((HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAR
)) ||
2194 /* Blocking error : transfer is aborted
2195 Set the USART state ready to be able to start again the process,
2196 Disable Interrupts, and disable DMA requests, if ongoing */
2197 USART_EndTransfer(husart
);
2199 /* Disable the USART DMA Rx request if enabled */
2200 if (HAL_IS_BIT_SET(husart
->Instance
->CR3
, USART_CR3_DMAR
))
2202 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
| USART_CR3_DMAR
);
2204 /* Abort the USART DMA Tx channel */
2205 if (husart
->hdmatx
!= NULL
)
2207 /* Set the USART Tx DMA Abort callback to NULL : no callback
2208 executed at end of DMA abort procedure */
2209 husart
->hdmatx
->XferAbortCallback
= NULL
;
2212 (void)HAL_DMA_Abort_IT(husart
->hdmatx
);
2215 /* Abort the USART DMA Rx channel */
2216 if (husart
->hdmarx
!= NULL
)
2218 /* Set the USART Rx DMA Abort callback :
2219 will lead to call HAL_USART_ErrorCallback() at end of DMA abort procedure */
2220 husart
->hdmarx
->XferAbortCallback
= USART_DMAAbortOnError
;
2223 if (HAL_DMA_Abort_IT(husart
->hdmarx
) != HAL_OK
)
2225 /* Call Directly husart->hdmarx->XferAbortCallback function in case of error */
2226 husart
->hdmarx
->XferAbortCallback(husart
->hdmarx
);
2231 /* Call user error callback */
2232 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2233 /* Call registered Error Callback */
2234 husart
->ErrorCallback(husart
);
2236 /* Call legacy weak Error Callback */
2237 HAL_USART_ErrorCallback(husart
);
2238 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2243 /* Call user error callback */
2244 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2245 /* Call registered Error Callback */
2246 husart
->ErrorCallback(husart
);
2248 /* Call legacy weak Error Callback */
2249 HAL_USART_ErrorCallback(husart
);
2250 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2255 /* Non Blocking error : transfer could go on.
2256 Error is notified to user through user error callback */
2257 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2258 /* Call registered Error Callback */
2259 husart
->ErrorCallback(husart
);
2261 /* Call legacy weak Error Callback */
2262 HAL_USART_ErrorCallback(husart
);
2263 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2264 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
2269 } /* End if some error occurs */
2272 /* USART in mode Transmitter ------------------------------------------------*/
2273 if (((isrflags
& USART_ISR_TXE_TXFNF
) != 0U)
2274 && (((cr1its
& USART_CR1_TXEIE_TXFNFIE
) != 0U)
2275 || ((cr3its
& USART_CR3_TXFTIE
) != 0U)))
2277 if (husart
->TxISR
!= NULL
)
2279 husart
->TxISR(husart
);
2284 /* USART in mode Transmitter (transmission end) -----------------------------*/
2285 if (((isrflags
& USART_ISR_TC
) != 0U) && ((cr1its
& USART_CR1_TCIE
) != 0U))
2287 USART_EndTransmit_IT(husart
);
2291 /* USART TX Fifo Empty occurred ----------------------------------------------*/
2292 if (((isrflags
& USART_ISR_TXFE
) != 0U) && ((cr1its
& USART_CR1_TXFEIE
) != 0U))
2294 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2295 /* Call registered Tx Fifo Empty Callback */
2296 husart
->TxFifoEmptyCallback(husart
);
2298 /* Call legacy weak Tx Fifo Empty Callback */
2299 HAL_USARTEx_TxFifoEmptyCallback(husart
);
2300 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2304 /* USART RX Fifo Full occurred ----------------------------------------------*/
2305 if (((isrflags
& USART_ISR_RXFF
) != 0U) && ((cr1its
& USART_CR1_RXFFIE
) != 0U))
2307 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2308 /* Call registered Rx Fifo Full Callback */
2309 husart
->RxFifoFullCallback(husart
);
2311 /* Call legacy weak Rx Fifo Full Callback */
2312 HAL_USARTEx_RxFifoFullCallback(husart
);
2313 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2319 * @brief Tx Transfer completed callback.
2320 * @param husart USART handle.
2323 __weak
void HAL_USART_TxCpltCallback(USART_HandleTypeDef
*husart
)
2325 /* Prevent unused argument(s) compilation warning */
2328 /* NOTE : This function should not be modified, when the callback is needed,
2329 the HAL_USART_TxCpltCallback can be implemented in the user file.
2334 * @brief Tx Half Transfer completed callback.
2335 * @param husart USART handle.
2338 __weak
void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef
*husart
)
2340 /* Prevent unused argument(s) compilation warning */
2343 /* NOTE: This function should not be modified, when the callback is needed,
2344 the HAL_USART_TxHalfCpltCallback can be implemented in the user file.
2349 * @brief Rx Transfer completed callback.
2350 * @param husart USART handle.
2353 __weak
void HAL_USART_RxCpltCallback(USART_HandleTypeDef
*husart
)
2355 /* Prevent unused argument(s) compilation warning */
2358 /* NOTE: This function should not be modified, when the callback is needed,
2359 the HAL_USART_RxCpltCallback can be implemented in the user file.
2364 * @brief Rx Half Transfer completed callback.
2365 * @param husart USART handle.
2368 __weak
void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef
*husart
)
2370 /* Prevent unused argument(s) compilation warning */
2373 /* NOTE : This function should not be modified, when the callback is needed,
2374 the HAL_USART_RxHalfCpltCallback can be implemented in the user file
2379 * @brief Tx/Rx Transfers completed callback for the non-blocking process.
2380 * @param husart USART handle.
2383 __weak
void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef
*husart
)
2385 /* Prevent unused argument(s) compilation warning */
2388 /* NOTE : This function should not be modified, when the callback is needed,
2389 the HAL_USART_TxRxCpltCallback can be implemented in the user file
2394 * @brief USART error callback.
2395 * @param husart USART handle.
2398 __weak
void HAL_USART_ErrorCallback(USART_HandleTypeDef
*husart
)
2400 /* Prevent unused argument(s) compilation warning */
2403 /* NOTE : This function should not be modified, when the callback is needed,
2404 the HAL_USART_ErrorCallback can be implemented in the user file.
2409 * @brief USART Abort Complete callback.
2410 * @param husart USART handle.
2413 __weak
void HAL_USART_AbortCpltCallback(USART_HandleTypeDef
*husart
)
2415 /* Prevent unused argument(s) compilation warning */
2418 /* NOTE : This function should not be modified, when the callback is needed,
2419 the HAL_USART_AbortCpltCallback can be implemented in the user file.
2427 /** @defgroup USART_Exported_Functions_Group4 Peripheral State and Error functions
2428 * @brief USART Peripheral State and Error functions
2431 ==============================================================================
2432 ##### Peripheral State and Error functions #####
2433 ==============================================================================
2435 This subsection provides functions allowing to :
2436 (+) Return the USART handle state
2437 (+) Return the USART handle error code
2445 * @brief Return the USART handle state.
2446 * @param husart pointer to a USART_HandleTypeDef structure that contains
2447 * the configuration information for the specified USART.
2448 * @retval USART handle state
2450 HAL_USART_StateTypeDef
HAL_USART_GetState(USART_HandleTypeDef
*husart
)
2452 return husart
->State
;
2456 * @brief Return the USART error code.
2457 * @param husart pointer to a USART_HandleTypeDef structure that contains
2458 * the configuration information for the specified USART.
2459 * @retval USART handle Error Code
2461 uint32_t HAL_USART_GetError(USART_HandleTypeDef
*husart
)
2463 return husart
->ErrorCode
;
2474 /** @defgroup USART_Private_Functions USART Private Functions
2479 * @brief Initialize the callbacks to their default values.
2480 * @param husart USART handle.
2483 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2484 void USART_InitCallbacksToDefault(USART_HandleTypeDef
*husart
)
2486 /* Init the USART Callback settings */
2487 husart
->TxHalfCpltCallback
= HAL_USART_TxHalfCpltCallback
; /* Legacy weak TxHalfCpltCallback */
2488 husart
->TxCpltCallback
= HAL_USART_TxCpltCallback
; /* Legacy weak TxCpltCallback */
2489 husart
->RxHalfCpltCallback
= HAL_USART_RxHalfCpltCallback
; /* Legacy weak RxHalfCpltCallback */
2490 husart
->RxCpltCallback
= HAL_USART_RxCpltCallback
; /* Legacy weak RxCpltCallback */
2491 husart
->TxRxCpltCallback
= HAL_USART_TxRxCpltCallback
; /* Legacy weak TxRxCpltCallback */
2492 husart
->ErrorCallback
= HAL_USART_ErrorCallback
; /* Legacy weak ErrorCallback */
2493 husart
->AbortCpltCallback
= HAL_USART_AbortCpltCallback
; /* Legacy weak AbortCpltCallback */
2494 husart
->RxFifoFullCallback
= HAL_USARTEx_RxFifoFullCallback
; /* Legacy weak RxFifoFullCallback */
2495 husart
->TxFifoEmptyCallback
= HAL_USARTEx_TxFifoEmptyCallback
; /* Legacy weak TxFifoEmptyCallback */
2497 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2500 * @brief End ongoing transfer on USART peripheral (following error detection or Transfer completion).
2501 * @param husart USART handle.
2504 static void USART_EndTransfer(USART_HandleTypeDef
*husart
)
2506 /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */
2507 CLEAR_BIT(husart
->Instance
->CR1
, (USART_CR1_RXNEIE_RXFNEIE
| USART_CR1_PEIE
| USART_CR1_TXEIE_TXFNFIE
|
2509 CLEAR_BIT(husart
->Instance
->CR3
, (USART_CR3_EIE
| USART_CR3_RXFTIE
| USART_CR3_TXFTIE
));
2511 /* At end of process, restore husart->State to Ready */
2512 husart
->State
= HAL_USART_STATE_READY
;
2516 * @brief DMA USART transmit process complete callback.
2517 * @param hdma DMA handle.
2520 static void USART_DMATransmitCplt(DMA_HandleTypeDef
*hdma
)
2522 USART_HandleTypeDef
*husart
= (USART_HandleTypeDef
*)(hdma
->Parent
);
2524 /* DMA Normal mode */
2525 if (hdma
->Init
.Mode
!= DMA_CIRCULAR
)
2527 husart
->TxXferCount
= 0U;
2529 if (husart
->State
== HAL_USART_STATE_BUSY_TX
)
2531 /* Disable the DMA transfer for transmit request by resetting the DMAT bit
2532 in the USART CR3 register */
2533 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
2535 /* Enable the USART Transmit Complete Interrupt */
2536 __HAL_USART_ENABLE_IT(husart
, USART_IT_TC
);
2539 /* DMA Circular mode */
2542 if (husart
->State
== HAL_USART_STATE_BUSY_TX
)
2544 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2545 /* Call registered Tx Complete Callback */
2546 husart
->TxCpltCallback(husart
);
2548 /* Call legacy weak Tx Complete Callback */
2549 HAL_USART_TxCpltCallback(husart
);
2550 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2556 * @brief DMA USART transmit process half complete callback.
2557 * @param hdma DMA handle.
2560 static void USART_DMATxHalfCplt(DMA_HandleTypeDef
*hdma
)
2562 USART_HandleTypeDef
*husart
= (USART_HandleTypeDef
*)(hdma
->Parent
);
2564 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2565 /* Call registered Tx Half Complete Callback */
2566 husart
->TxHalfCpltCallback(husart
);
2568 /* Call legacy weak Tx Half Complete Callback */
2569 HAL_USART_TxHalfCpltCallback(husart
);
2570 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2574 * @brief DMA USART receive process complete callback.
2575 * @param hdma DMA handle.
2578 static void USART_DMAReceiveCplt(DMA_HandleTypeDef
*hdma
)
2580 USART_HandleTypeDef
*husart
= (USART_HandleTypeDef
*)(hdma
->Parent
);
2582 /* DMA Normal mode */
2583 if (hdma
->Init
.Mode
!= DMA_CIRCULAR
)
2585 husart
->RxXferCount
= 0U;
2587 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
2588 CLEAR_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
2589 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
2591 /* Disable the DMA RX transfer for the receiver request by resetting the DMAR bit
2592 in USART CR3 register */
2593 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAR
);
2594 /* similarly, disable the DMA TX transfer that was started to provide the
2595 clock to the slave device */
2596 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_DMAT
);
2598 if (husart
->State
== HAL_USART_STATE_BUSY_RX
)
2600 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2601 /* Call registered Rx Complete Callback */
2602 husart
->RxCpltCallback(husart
);
2604 /* Call legacy weak Rx Complete Callback */
2605 HAL_USART_RxCpltCallback(husart
);
2606 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2608 /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
2611 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2612 /* Call registered Tx Rx Complete Callback */
2613 husart
->TxRxCpltCallback(husart
);
2615 /* Call legacy weak Tx Rx Complete Callback */
2616 HAL_USART_TxRxCpltCallback(husart
);
2617 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2619 husart
->State
= HAL_USART_STATE_READY
;
2621 /* DMA circular mode */
2624 if (husart
->State
== HAL_USART_STATE_BUSY_RX
)
2626 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2627 /* Call registered Rx Complete Callback */
2628 husart
->RxCpltCallback(husart
);
2630 /* Call legacy weak Rx Complete Callback */
2631 HAL_USART_RxCpltCallback(husart
);
2632 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2634 /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
2637 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2638 /* Call registered Tx Rx Complete Callback */
2639 husart
->TxRxCpltCallback(husart
);
2641 /* Call legacy weak Tx Rx Complete Callback */
2642 HAL_USART_TxRxCpltCallback(husart
);
2643 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2649 * @brief DMA USART receive process half complete callback.
2650 * @param hdma DMA handle.
2653 static void USART_DMARxHalfCplt(DMA_HandleTypeDef
*hdma
)
2655 USART_HandleTypeDef
*husart
= (USART_HandleTypeDef
*)(hdma
->Parent
);
2657 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2658 /* Call registered Rx Half Complete Callback */
2659 husart
->RxHalfCpltCallback(husart
);
2661 /* Call legacy weak Rx Half Complete Callback */
2662 HAL_USART_RxHalfCpltCallback(husart
);
2663 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2667 * @brief DMA USART communication error callback.
2668 * @param hdma DMA handle.
2671 static void USART_DMAError(DMA_HandleTypeDef
*hdma
)
2673 USART_HandleTypeDef
*husart
= (USART_HandleTypeDef
*)(hdma
->Parent
);
2675 husart
->RxXferCount
= 0U;
2676 husart
->TxXferCount
= 0U;
2677 USART_EndTransfer(husart
);
2679 husart
->ErrorCode
|= HAL_USART_ERROR_DMA
;
2680 husart
->State
= HAL_USART_STATE_READY
;
2682 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2683 /* Call registered Error Callback */
2684 husart
->ErrorCallback(husart
);
2686 /* Call legacy weak Error Callback */
2687 HAL_USART_ErrorCallback(husart
);
2688 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2692 * @brief DMA USART communication abort callback, when initiated by HAL services on Error
2693 * (To be called at end of DMA Abort procedure following error occurrence).
2694 * @param hdma DMA handle.
2697 static void USART_DMAAbortOnError(DMA_HandleTypeDef
*hdma
)
2699 USART_HandleTypeDef
*husart
= (USART_HandleTypeDef
*)(hdma
->Parent
);
2700 husart
->RxXferCount
= 0U;
2701 husart
->TxXferCount
= 0U;
2703 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2704 /* Call registered Error Callback */
2705 husart
->ErrorCallback(husart
);
2707 /* Call legacy weak Error Callback */
2708 HAL_USART_ErrorCallback(husart
);
2709 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2713 * @brief DMA USART Tx communication abort callback, when initiated by user
2714 * (To be called at end of DMA Tx Abort procedure following user abort request).
2715 * @note When this callback is executed, User Abort complete call back is called only if no
2716 * Abort still ongoing for Rx DMA Handle.
2717 * @param hdma DMA handle.
2720 static void USART_DMATxAbortCallback(DMA_HandleTypeDef
*hdma
)
2722 USART_HandleTypeDef
*husart
= (USART_HandleTypeDef
*)(hdma
->Parent
);
2724 husart
->hdmatx
->XferAbortCallback
= NULL
;
2726 /* Check if an Abort process is still ongoing */
2727 if (husart
->hdmarx
!= NULL
)
2729 if (husart
->hdmarx
->XferAbortCallback
!= NULL
)
2735 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2736 husart
->TxXferCount
= 0U;
2737 husart
->RxXferCount
= 0U;
2739 /* Reset errorCode */
2740 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
2742 /* Clear the Error flags in the ICR register */
2743 __HAL_USART_CLEAR_FLAG(husart
, USART_CLEAR_OREF
| USART_CLEAR_NEF
| USART_CLEAR_PEF
| USART_CLEAR_FEF
);
2745 /* Restore husart->State to Ready */
2746 husart
->State
= HAL_USART_STATE_READY
;
2748 /* Call user Abort complete callback */
2749 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2750 /* Call registered Abort Complete Callback */
2751 husart
->AbortCpltCallback(husart
);
2753 /* Call legacy weak Abort Complete Callback */
2754 HAL_USART_AbortCpltCallback(husart
);
2755 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2761 * @brief DMA USART Rx communication abort callback, when initiated by user
2762 * (To be called at end of DMA Rx Abort procedure following user abort request).
2763 * @note When this callback is executed, User Abort complete call back is called only if no
2764 * Abort still ongoing for Tx DMA Handle.
2765 * @param hdma DMA handle.
2768 static void USART_DMARxAbortCallback(DMA_HandleTypeDef
*hdma
)
2770 USART_HandleTypeDef
*husart
= (USART_HandleTypeDef
*)(hdma
->Parent
);
2772 husart
->hdmarx
->XferAbortCallback
= NULL
;
2774 /* Check if an Abort process is still ongoing */
2775 if (husart
->hdmatx
!= NULL
)
2777 if (husart
->hdmatx
->XferAbortCallback
!= NULL
)
2783 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2784 husart
->TxXferCount
= 0U;
2785 husart
->RxXferCount
= 0U;
2787 /* Reset errorCode */
2788 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
2790 /* Clear the Error flags in the ICR register */
2791 __HAL_USART_CLEAR_FLAG(husart
, USART_CLEAR_OREF
| USART_CLEAR_NEF
| USART_CLEAR_PEF
| USART_CLEAR_FEF
);
2793 /* Restore husart->State to Ready */
2794 husart
->State
= HAL_USART_STATE_READY
;
2796 /* Call user Abort complete callback */
2797 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
2798 /* Call registered Abort Complete Callback */
2799 husart
->AbortCpltCallback(husart
);
2801 /* Call legacy weak Abort Complete Callback */
2802 HAL_USART_AbortCpltCallback(husart
);
2803 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
2808 * @brief Handle USART Communication Timeout.
2809 * @param husart USART handle.
2810 * @param Flag Specifies the USART flag to check.
2811 * @param Status the Flag status (SET or RESET).
2812 * @param Tickstart Tick start value
2813 * @param Timeout timeout duration.
2814 * @retval HAL status
2816 static HAL_StatusTypeDef
USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef
*husart
, uint32_t Flag
, FlagStatus Status
,
2817 uint32_t Tickstart
, uint32_t Timeout
)
2819 /* Wait until flag is set */
2820 while ((__HAL_USART_GET_FLAG(husart
, Flag
) ? SET
: RESET
) == Status
)
2822 /* Check for the Timeout */
2823 if (Timeout
!= HAL_MAX_DELAY
)
2825 if (((HAL_GetTick() - Tickstart
) > Timeout
) || (Timeout
== 0U))
2827 husart
->State
= HAL_USART_STATE_READY
;
2829 /* Process Unlocked */
2830 __HAL_UNLOCK(husart
);
2840 * @brief Configure the USART peripheral.
2841 * @param husart USART handle.
2842 * @retval HAL status
2844 static HAL_StatusTypeDef
USART_SetConfig(USART_HandleTypeDef
*husart
)
2847 USART_ClockSourceTypeDef clocksource
;
2848 HAL_StatusTypeDef ret
= HAL_OK
;
2850 uint32_t usartdiv
= 0x00000000;
2851 PLL2_ClocksTypeDef pll2_clocks
;
2852 PLL3_ClocksTypeDef pll3_clocks
;
2855 /* Check the parameters */
2856 assert_param(IS_USART_POLARITY(husart
->Init
.CLKPolarity
));
2857 assert_param(IS_USART_PHASE(husart
->Init
.CLKPhase
));
2858 assert_param(IS_USART_LASTBIT(husart
->Init
.CLKLastBit
));
2859 assert_param(IS_USART_BAUDRATE(husart
->Init
.BaudRate
));
2860 assert_param(IS_USART_WORD_LENGTH(husart
->Init
.WordLength
));
2861 assert_param(IS_USART_STOPBITS(husart
->Init
.StopBits
));
2862 assert_param(IS_USART_PARITY(husart
->Init
.Parity
));
2863 assert_param(IS_USART_MODE(husart
->Init
.Mode
));
2864 assert_param(IS_USART_PRESCALER(husart
->Init
.ClockPrescaler
));
2866 /*-------------------------- USART CR1 Configuration -----------------------*/
2867 /* Clear M, PCE, PS, TE and RE bits and configure
2868 * the USART Word Length, Parity and Mode:
2869 * set the M bits according to husart->Init.WordLength value
2870 * set PCE and PS bits according to husart->Init.Parity value
2871 * set TE and RE bits according to husart->Init.Mode value
2872 * force OVER8 to 1 to allow to reach the maximum speed (Fclock/8) */
2873 tmpreg
= (uint32_t)husart
->Init
.WordLength
| husart
->Init
.Parity
| husart
->Init
.Mode
| USART_CR1_OVER8
;
2874 MODIFY_REG(husart
->Instance
->CR1
, USART_CR1_FIELDS
, tmpreg
);
2876 /*---------------------------- USART CR2 Configuration ---------------------*/
2877 /* Clear and configure the USART Clock, CPOL, CPHA, LBCL STOP and SLVEN bits:
2878 * set CPOL bit according to husart->Init.CLKPolarity value
2879 * set CPHA bit according to husart->Init.CLKPhase value
2880 * set LBCL bit according to husart->Init.CLKLastBit value (used in SPI master mode only)
2881 * set STOP[13:12] bits according to husart->Init.StopBits value */
2882 tmpreg
= (uint32_t)(USART_CLOCK_ENABLE
);
2883 tmpreg
|= (uint32_t)husart
->Init
.CLKLastBit
;
2884 tmpreg
|= ((uint32_t)husart
->Init
.CLKPolarity
| (uint32_t)husart
->Init
.CLKPhase
);
2885 tmpreg
|= (uint32_t)husart
->Init
.StopBits
;
2886 MODIFY_REG(husart
->Instance
->CR2
, USART_CR2_FIELDS
, tmpreg
);
2888 /*-------------------------- USART PRESC Configuration -----------------------*/
2890 * - USART Clock Prescaler : set PRESCALER according to husart->Init.ClockPrescaler value */
2891 MODIFY_REG(husart
->Instance
->PRESC
, USART_PRESC_PRESCALER
, husart
->Init
.ClockPrescaler
);
2893 /*-------------------------- USART BRR Configuration -----------------------*/
2894 /* BRR is filled-up according to OVER8 bit setting which is forced to 1 */
2895 USART_GETCLOCKSOURCE(husart
, clocksource
);
2897 switch (clocksource
)
2899 case USART_CLOCKSOURCE_D2PCLK1
:
2900 pclk
= HAL_RCC_GetPCLK1Freq();
2901 usartdiv
= (uint32_t)(USART_DIV_SAMPLING8(pclk
, husart
->Init
.BaudRate
, husart
->Init
.ClockPrescaler
));
2903 case USART_CLOCKSOURCE_D2PCLK2
:
2904 pclk
= HAL_RCC_GetPCLK2Freq();
2905 usartdiv
= (uint32_t)(USART_DIV_SAMPLING8(pclk
, husart
->Init
.BaudRate
, husart
->Init
.ClockPrescaler
));
2907 case USART_CLOCKSOURCE_PLL2
:
2908 HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks
);
2909 usartdiv
= (uint32_t)(USART_DIV_SAMPLING8(pll2_clocks
.PLL2_Q_Frequency
, husart
->Init
.BaudRate
, husart
->Init
.ClockPrescaler
));
2911 case USART_CLOCKSOURCE_PLL3
:
2912 HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks
);
2913 usartdiv
= (uint32_t)(USART_DIV_SAMPLING8(pll3_clocks
.PLL3_Q_Frequency
, husart
->Init
.BaudRate
, husart
->Init
.ClockPrescaler
));
2915 case USART_CLOCKSOURCE_HSI
:
2916 if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV
) != 0U)
2918 usartdiv
= (uint32_t)(USART_DIV_SAMPLING8((HSI_VALUE
>> (__HAL_RCC_GET_HSI_DIVIDER() >> 3U)), husart
->Init
.BaudRate
, husart
->Init
.ClockPrescaler
));
2922 usartdiv
= (uint32_t)(USART_DIV_SAMPLING8(HSI_VALUE
, husart
->Init
.BaudRate
, husart
->Init
.ClockPrescaler
));
2925 case USART_CLOCKSOURCE_CSI
:
2926 usartdiv
= (uint32_t)(USART_DIV_SAMPLING8(CSI_VALUE
, husart
->Init
.BaudRate
, husart
->Init
.ClockPrescaler
));
2928 case USART_CLOCKSOURCE_LSE
:
2929 usartdiv
= (uint32_t)(USART_DIV_SAMPLING8(LSE_VALUE
, husart
->Init
.BaudRate
, husart
->Init
.ClockPrescaler
));
2936 /* USARTDIV must be greater than or equal to 0d16 and smaller than or equal to ffff */
2937 if ((usartdiv
>= USART_BRR_MIN
) && (usartdiv
<= USART_BRR_MAX
))
2939 brrtemp
= (uint16_t)(usartdiv
& 0xFFF0U
);
2940 brrtemp
|= (uint16_t)((usartdiv
& (uint16_t)0x000FU
) >> 1U);
2941 husart
->Instance
->BRR
= brrtemp
;
2948 /* Initialize the number of data to process during RX/TX ISR execution */
2949 husart
->NbTxDataToProcess
= 1U;
2950 husart
->NbRxDataToProcess
= 1U;
2952 /* Clear ISR function pointers */
2953 husart
->RxISR
= NULL
;
2954 husart
->TxISR
= NULL
;
2960 * @brief Check the USART Idle State.
2961 * @param husart USART handle.
2962 * @retval HAL status
2964 static HAL_StatusTypeDef
USART_CheckIdleState(USART_HandleTypeDef
*husart
)
2968 /* Initialize the USART ErrorCode */
2969 husart
->ErrorCode
= HAL_USART_ERROR_NONE
;
2971 /* Init tickstart for timeout managment*/
2972 tickstart
= HAL_GetTick();
2974 /* Check if the Transmitter is enabled */
2975 if ((husart
->Instance
->CR1
& USART_CR1_TE
) == USART_CR1_TE
)
2977 /* Wait until TEACK flag is set */
2978 if (USART_WaitOnFlagUntilTimeout(husart
, USART_ISR_TEACK
, RESET
, tickstart
, USART_TEACK_REACK_TIMEOUT
) != HAL_OK
)
2980 /* Timeout occurred */
2984 /* Check if the Receiver is enabled */
2985 if ((husart
->Instance
->CR1
& USART_CR1_RE
) == USART_CR1_RE
)
2987 /* Wait until REACK flag is set */
2988 if (USART_WaitOnFlagUntilTimeout(husart
, USART_ISR_REACK
, RESET
, tickstart
, USART_TEACK_REACK_TIMEOUT
) != HAL_OK
)
2990 /* Timeout occurred */
2995 /* Initialize the USART state*/
2996 husart
->State
= HAL_USART_STATE_READY
;
2998 /* Process Unlocked */
2999 __HAL_UNLOCK(husart
);
3005 * @brief Simplex send an amount of data in non-blocking mode.
3006 * @note Function called under interruption only, once
3007 * interruptions have been enabled by HAL_USART_Transmit_IT().
3008 * @note The USART errors are not managed to avoid the overrun error.
3009 * @note ISR function executed when FIFO mode is disabled and when the
3010 * data word length is less than 9 bits long.
3011 * @param husart USART handle.
3014 static void USART_TxISR_8BIT(USART_HandleTypeDef
*husart
)
3016 const HAL_USART_StateTypeDef state
= husart
->State
;
3018 /* Check that a Tx process is ongoing */
3019 if ((state
== HAL_USART_STATE_BUSY_TX
) ||
3020 (state
== HAL_USART_STATE_BUSY_TX_RX
))
3022 if (husart
->TxXferCount
== 0U)
3024 /* Disable the USART Transmit data register empty interrupt */
3025 __HAL_USART_DISABLE_IT(husart
, USART_IT_TXE
);
3027 /* Enable the USART Transmit Complete Interrupt */
3028 __HAL_USART_ENABLE_IT(husart
, USART_IT_TC
);
3032 husart
->Instance
->TDR
= (uint8_t)(*husart
->pTxBuffPtr
& (uint8_t)0xFF);
3033 husart
->pTxBuffPtr
++;
3034 husart
->TxXferCount
--;
3040 * @brief Simplex send an amount of data in non-blocking mode.
3041 * @note Function called under interruption only, once
3042 * interruptions have been enabled by HAL_USART_Transmit_IT().
3043 * @note The USART errors are not managed to avoid the overrun error.
3044 * @note ISR function executed when FIFO mode is disabled and when the
3045 * data word length is 9 bits long.
3046 * @param husart USART handle.
3049 static void USART_TxISR_16BIT(USART_HandleTypeDef
*husart
)
3051 const HAL_USART_StateTypeDef state
= husart
->State
;
3054 if ((state
== HAL_USART_STATE_BUSY_TX
) ||
3055 (state
== HAL_USART_STATE_BUSY_TX_RX
))
3057 if (husart
->TxXferCount
== 0U)
3059 /* Disable the USART Transmit data register empty interrupt */
3060 __HAL_USART_DISABLE_IT(husart
, USART_IT_TXE
);
3062 /* Enable the USART Transmit Complete Interrupt */
3063 __HAL_USART_ENABLE_IT(husart
, USART_IT_TC
);
3067 tmp
= (uint16_t *) husart
->pTxBuffPtr
;
3068 husart
->Instance
->TDR
= (uint16_t)(*tmp
& 0x01FFU
);
3069 husart
->pTxBuffPtr
+= 2U;
3070 husart
->TxXferCount
--;
3076 * @brief Simplex send an amount of data in non-blocking mode.
3077 * @note Function called under interruption only, once
3078 * interruptions have been enabled by HAL_USART_Transmit_IT().
3079 * @note The USART errors are not managed to avoid the overrun error.
3080 * @note ISR function executed when FIFO mode is enabled and when the
3081 * data word length is less than 9 bits long.
3082 * @param husart USART handle.
3085 static void USART_TxISR_8BIT_FIFOEN(USART_HandleTypeDef
*husart
)
3087 const HAL_USART_StateTypeDef state
= husart
->State
;
3088 uint16_t nb_tx_data
;
3090 /* Check that a Tx process is ongoing */
3091 if ((state
== HAL_USART_STATE_BUSY_TX
) ||
3092 (state
== HAL_USART_STATE_BUSY_TX_RX
))
3094 for (nb_tx_data
= husart
->NbTxDataToProcess
; nb_tx_data
> 0U ; nb_tx_data
--)
3096 if (husart
->TxXferCount
== 0U)
3098 /* Disable the TX FIFO threshold interrupt */
3099 __HAL_USART_DISABLE_IT(husart
, USART_IT_TXFT
);
3101 /* Enable the USART Transmit Complete Interrupt */
3102 __HAL_USART_ENABLE_IT(husart
, USART_IT_TC
);
3104 break; /* force exit loop */
3106 else if (__HAL_USART_GET_FLAG(husart
, USART_FLAG_TXFNF
) == SET
)
3108 husart
->Instance
->TDR
= (uint8_t)(*husart
->pTxBuffPtr
& (uint8_t)0xFF);
3109 husart
->pTxBuffPtr
++;
3110 husart
->TxXferCount
--;
3121 * @brief Simplex send an amount of data in non-blocking mode.
3122 * @note Function called under interruption only, once
3123 * interruptions have been enabled by HAL_USART_Transmit_IT().
3124 * @note The USART errors are not managed to avoid the overrun error.
3125 * @note ISR function executed when FIFO mode is enabled and when the
3126 * data word length is 9 bits long.
3127 * @param husart USART handle.
3130 static void USART_TxISR_16BIT_FIFOEN(USART_HandleTypeDef
*husart
)
3132 const HAL_USART_StateTypeDef state
= husart
->State
;
3134 uint16_t nb_tx_data
;
3136 /* Check that a Tx process is ongoing */
3137 if ((state
== HAL_USART_STATE_BUSY_TX
) ||
3138 (state
== HAL_USART_STATE_BUSY_TX_RX
))
3140 for (nb_tx_data
= husart
->NbTxDataToProcess
; nb_tx_data
> 0U ; nb_tx_data
--)
3142 if (husart
->TxXferCount
== 0U)
3144 /* Disable the TX FIFO threshold interrupt */
3145 __HAL_USART_DISABLE_IT(husart
, USART_IT_TXFT
);
3147 /* Enable the USART Transmit Complete Interrupt */
3148 __HAL_USART_ENABLE_IT(husart
, USART_IT_TC
);
3150 break; /* force exit loop */
3152 else if (__HAL_USART_GET_FLAG(husart
, USART_FLAG_TXFNF
) == SET
)
3154 tmp
= (uint16_t *) husart
->pTxBuffPtr
;
3155 husart
->Instance
->TDR
= (uint16_t)(*tmp
& 0x01FFU
);
3156 husart
->pTxBuffPtr
+= 2U;
3157 husart
->TxXferCount
--;
3168 * @brief Wraps up transmission in non-blocking mode.
3169 * @param husart Pointer to a USART_HandleTypeDef structure that contains
3170 * the configuration information for the specified USART module.
3173 static void USART_EndTransmit_IT(USART_HandleTypeDef
*husart
)
3175 /* Disable the USART Transmit Complete Interrupt */
3176 __HAL_USART_DISABLE_IT(husart
, USART_IT_TC
);
3178 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3179 __HAL_USART_DISABLE_IT(husart
, USART_IT_ERR
);
3181 /* Clear TxISR function pointer */
3182 husart
->TxISR
= NULL
;
3184 if (husart
->State
== HAL_USART_STATE_BUSY_TX
)
3186 /* Clear overrun flag and discard the received data */
3187 __HAL_USART_CLEAR_OREFLAG(husart
);
3188 __HAL_USART_SEND_REQ(husart
, USART_RXDATA_FLUSH_REQUEST
);
3190 /* Tx process is completed, restore husart->State to Ready */
3191 husart
->State
= HAL_USART_STATE_READY
;
3193 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3194 /* Call registered Tx Complete Callback */
3195 husart
->TxCpltCallback(husart
);
3197 /* Call legacy weak Tx Complete Callback */
3198 HAL_USART_TxCpltCallback(husart
);
3199 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3201 else if (husart
->RxXferCount
== 0U)
3203 /* TxRx process is completed, restore husart->State to Ready */
3204 husart
->State
= HAL_USART_STATE_READY
;
3206 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3207 /* Call registered Tx Rx Complete Callback */
3208 husart
->TxRxCpltCallback(husart
);
3210 /* Call legacy weak Tx Rx Complete Callback */
3211 HAL_USART_TxRxCpltCallback(husart
);
3212 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3222 * @brief Simplex receive an amount of data in non-blocking mode.
3223 * @note Function called under interruption only, once
3224 * interruptions have been enabled by HAL_USART_Receive_IT().
3225 * @note ISR function executed when FIFO mode is disabled and when the
3226 * data word length is less than 9 bits long.
3227 * @param husart USART handle
3230 static void USART_RxISR_8BIT(USART_HandleTypeDef
*husart
)
3232 const HAL_USART_StateTypeDef state
= husart
->State
;
3233 uint16_t txdatacount
;
3234 uint16_t uhMask
= husart
->Mask
;
3237 if ((state
== HAL_USART_STATE_BUSY_RX
) ||
3238 (state
== HAL_USART_STATE_BUSY_TX_RX
))
3240 *husart
->pRxBuffPtr
= (uint8_t)(husart
->Instance
->RDR
& (uint8_t)uhMask
);
3241 husart
->pRxBuffPtr
++;
3242 husart
->RxXferCount
--;
3244 if (husart
->RxXferCount
== 0U)
3246 /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
3247 CLEAR_BIT(husart
->Instance
->CR1
, (USART_CR1_RXNEIE_RXFNEIE
| USART_CR1_PEIE
));
3249 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3250 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
3252 /* Clear RxISR function pointer */
3253 husart
->RxISR
= NULL
;
3255 /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3256 txftie
= READ_BIT(husart
->Instance
->CR3
, USART_CR3_TXFTIE
);
3257 txdatacount
= husart
->TxXferCount
;
3259 if (state
== HAL_USART_STATE_BUSY_RX
)
3261 /* Clear SPI slave underrun flag and discard transmit data */
3262 if (husart
->SlaveMode
== USART_SLAVEMODE_ENABLE
)
3264 __HAL_USART_CLEAR_UDRFLAG(husart
);
3265 __HAL_USART_SEND_REQ(husart
, USART_TXDATA_FLUSH_REQUEST
);
3268 /* Rx process is completed, restore husart->State to Ready */
3269 husart
->State
= HAL_USART_STATE_READY
;
3271 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3272 /* Call registered Rx Complete Callback */
3273 husart
->RxCpltCallback(husart
);
3275 /* Call legacy weak Rx Complete Callback */
3276 HAL_USART_RxCpltCallback(husart
);
3277 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3279 else if ((READ_BIT(husart
->Instance
->CR1
, USART_CR1_TCIE
) != USART_CR1_TCIE
) &&
3280 (txftie
!= USART_CR3_TXFTIE
) &&
3281 (txdatacount
== 0U))
3283 /* TxRx process is completed, restore husart->State to Ready */
3284 husart
->State
= HAL_USART_STATE_READY
;
3286 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3287 /* Call registered Tx Rx Complete Callback */
3288 husart
->TxRxCpltCallback(husart
);
3290 /* Call legacy weak Tx Rx Complete Callback */
3291 HAL_USART_TxRxCpltCallback(husart
);
3292 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3299 else if ((state
== HAL_USART_STATE_BUSY_RX
) &&
3300 (husart
->SlaveMode
== USART_SLAVEMODE_DISABLE
))
3302 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3303 husart
->Instance
->TDR
= (USART_DUMMY_DATA
& (uint16_t)0x00FF);
3313 * @brief Simplex receive an amount of data in non-blocking mode.
3314 * @note Function called under interruption only, once
3315 * interruptions have been enabled by HAL_USART_Receive_IT().
3316 * @note ISR function executed when FIFO mode is disabled and when the
3317 * data word length is 9 bits long.
3318 * @param husart USART handle
3321 static void USART_RxISR_16BIT(USART_HandleTypeDef
*husart
)
3323 const HAL_USART_StateTypeDef state
= husart
->State
;
3324 uint16_t txdatacount
;
3326 uint16_t uhMask
= husart
->Mask
;
3329 if ((state
== HAL_USART_STATE_BUSY_RX
) ||
3330 (state
== HAL_USART_STATE_BUSY_TX_RX
))
3332 tmp
= (uint16_t *) husart
->pRxBuffPtr
;
3333 *tmp
= (uint16_t)(husart
->Instance
->RDR
& uhMask
);
3334 husart
->pRxBuffPtr
+= 2U;
3335 husart
->RxXferCount
--;
3337 if (husart
->RxXferCount
== 0U)
3339 /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
3340 CLEAR_BIT(husart
->Instance
->CR1
, (USART_CR1_RXNEIE_RXFNEIE
| USART_CR1_PEIE
));
3342 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
3343 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_EIE
);
3345 /* Clear RxISR function pointer */
3346 husart
->RxISR
= NULL
;
3348 /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3349 txftie
= READ_BIT(husart
->Instance
->CR3
, USART_CR3_TXFTIE
);
3350 txdatacount
= husart
->TxXferCount
;
3352 if (state
== HAL_USART_STATE_BUSY_RX
)
3354 /* Clear SPI slave underrun flag and discard transmit data */
3355 if (husart
->SlaveMode
== USART_SLAVEMODE_ENABLE
)
3357 __HAL_USART_CLEAR_UDRFLAG(husart
);
3358 __HAL_USART_SEND_REQ(husart
, USART_TXDATA_FLUSH_REQUEST
);
3361 /* Rx process is completed, restore husart->State to Ready */
3362 husart
->State
= HAL_USART_STATE_READY
;
3364 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3365 /* Call registered Rx Complete Callback */
3366 husart
->RxCpltCallback(husart
);
3368 /* Call legacy weak Rx Complete Callback */
3369 HAL_USART_RxCpltCallback(husart
);
3370 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3372 else if ((READ_BIT(husart
->Instance
->CR1
, USART_CR1_TCIE
) != USART_CR1_TCIE
) &&
3373 (txftie
!= USART_CR3_TXFTIE
) &&
3374 (txdatacount
== 0U))
3376 /* TxRx process is completed, restore husart->State to Ready */
3377 husart
->State
= HAL_USART_STATE_READY
;
3379 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3380 /* Call registered Tx Rx Complete Callback */
3381 husart
->TxRxCpltCallback(husart
);
3383 /* Call legacy weak Tx Rx Complete Callback */
3384 HAL_USART_TxRxCpltCallback(husart
);
3385 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3392 else if ((state
== HAL_USART_STATE_BUSY_RX
) &&
3393 (husart
->SlaveMode
== USART_SLAVEMODE_DISABLE
))
3395 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3396 husart
->Instance
->TDR
= (USART_DUMMY_DATA
& (uint16_t)0x00FF);
3406 * @brief Simplex receive an amount of data in non-blocking mode.
3407 * @note Function called under interruption only, once
3408 * interruptions have been enabled by HAL_USART_Receive_IT().
3409 * @note ISR function executed when FIFO mode is enabled and when the
3410 * data word length is less than 9 bits long.
3411 * @param husart USART handle
3414 static void USART_RxISR_8BIT_FIFOEN(USART_HandleTypeDef
*husart
)
3416 HAL_USART_StateTypeDef state
= husart
->State
;
3417 uint16_t txdatacount
;
3418 uint16_t rxdatacount
;
3419 uint16_t uhMask
= husart
->Mask
;
3420 uint16_t nb_rx_data
;
3423 /* Check that a Rx process is ongoing */
3424 if ((state
== HAL_USART_STATE_BUSY_RX
) ||
3425 (state
== HAL_USART_STATE_BUSY_TX_RX
))
3427 for (nb_rx_data
= husart
->NbRxDataToProcess
; nb_rx_data
> 0U ; nb_rx_data
--)
3429 if (__HAL_USART_GET_FLAG(husart
, USART_FLAG_RXFNE
) == SET
)
3431 *husart
->pRxBuffPtr
= (uint8_t)(husart
->Instance
->RDR
& (uint8_t)(uhMask
& 0xFFU
));
3432 husart
->pRxBuffPtr
++;
3433 husart
->RxXferCount
--;
3435 if (husart
->RxXferCount
== 0U)
3437 /* Disable the USART Parity Error Interrupt */
3438 CLEAR_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
3440 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */
3441 CLEAR_BIT(husart
->Instance
->CR3
, (USART_CR3_EIE
| USART_CR3_RXFTIE
));
3443 /* Clear RxISR function pointer */
3444 husart
->RxISR
= NULL
;
3446 /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3447 txftie
= READ_BIT(husart
->Instance
->CR3
, USART_CR3_TXFTIE
);
3448 txdatacount
= husart
->TxXferCount
;
3450 if (state
== HAL_USART_STATE_BUSY_RX
)
3452 /* Clear SPI slave underrun flag and discard transmit data */
3453 if (husart
->SlaveMode
== USART_SLAVEMODE_ENABLE
)
3455 __HAL_USART_CLEAR_UDRFLAG(husart
);
3456 __HAL_USART_SEND_REQ(husart
, USART_TXDATA_FLUSH_REQUEST
);
3459 /* Rx process is completed, restore husart->State to Ready */
3460 husart
->State
= HAL_USART_STATE_READY
;
3461 state
= HAL_USART_STATE_READY
;
3463 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3464 /* Call registered Rx Complete Callback */
3465 husart
->RxCpltCallback(husart
);
3467 /* Call legacy weak Rx Complete Callback */
3468 HAL_USART_RxCpltCallback(husart
);
3469 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3471 else if ((READ_BIT(husart
->Instance
->CR1
, USART_CR1_TCIE
) != USART_CR1_TCIE
) &&
3472 (txftie
!= USART_CR3_TXFTIE
) &&
3473 (txdatacount
== 0U))
3475 /* TxRx process is completed, restore husart->State to Ready */
3476 husart
->State
= HAL_USART_STATE_READY
;
3477 state
= HAL_USART_STATE_READY
;
3479 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3480 /* Call registered Tx Rx Complete Callback */
3481 husart
->TxRxCpltCallback(husart
);
3483 /* Call legacy weak Tx Rx Complete Callback */
3484 HAL_USART_TxRxCpltCallback(husart
);
3485 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3492 else if ((state
== HAL_USART_STATE_BUSY_RX
) &&
3493 (husart
->SlaveMode
== USART_SLAVEMODE_DISABLE
))
3495 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3496 husart
->Instance
->TDR
= (USART_DUMMY_DATA
& (uint16_t)0x00FF);
3505 /* When remaining number of bytes to receive is less than the RX FIFO
3506 threshold, next incoming frames are processed as if FIFO mode was
3507 disabled (i.e. one interrupt per received frame).
3509 rxdatacount
= husart
->RxXferCount
;
3510 if (((rxdatacount
!= 0U)) && (rxdatacount
< husart
->NbRxDataToProcess
))
3512 /* Disable the USART RXFT interrupt*/
3513 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_RXFTIE
);
3515 /* Update the RxISR function pointer */
3516 husart
->RxISR
= USART_RxISR_8BIT
;
3518 /* Enable the USART Data Register Not Empty interrupt */
3519 SET_BIT(husart
->Instance
->CR1
, USART_CR1_RXNEIE_RXFNEIE
);
3521 if ((husart
->TxXferCount
== 0U) &&
3522 (state
== HAL_USART_STATE_BUSY_TX_RX
) &&
3523 (husart
->SlaveMode
== USART_SLAVEMODE_DISABLE
))
3525 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3526 husart
->Instance
->TDR
= (USART_DUMMY_DATA
& (uint16_t)0x00FF);
3532 /* Clear RXNE interrupt flag */
3533 __HAL_USART_SEND_REQ(husart
, USART_RXDATA_FLUSH_REQUEST
);
3538 * @brief Simplex receive an amount of data in non-blocking mode.
3539 * @note Function called under interruption only, once
3540 * interruptions have been enabled by HAL_USART_Receive_IT().
3541 * @note ISR function executed when FIFO mode is enabled and when the
3542 * data word length is 9 bits long.
3543 * @param husart USART handle
3546 static void USART_RxISR_16BIT_FIFOEN(USART_HandleTypeDef
*husart
)
3548 HAL_USART_StateTypeDef state
= husart
->State
;
3549 uint16_t txdatacount
;
3550 uint16_t rxdatacount
;
3552 uint16_t uhMask
= husart
->Mask
;
3553 uint16_t nb_rx_data
;
3556 /* Check that a Tx process is ongoing */
3557 if ((state
== HAL_USART_STATE_BUSY_RX
) ||
3558 (state
== HAL_USART_STATE_BUSY_TX_RX
))
3560 for (nb_rx_data
= husart
->NbRxDataToProcess
; nb_rx_data
> 0U ; nb_rx_data
--)
3562 if (__HAL_USART_GET_FLAG(husart
, USART_FLAG_RXFNE
) == SET
)
3564 tmp
= (uint16_t *) husart
->pRxBuffPtr
;
3565 *tmp
= (uint16_t)(husart
->Instance
->RDR
& uhMask
);
3566 husart
->pRxBuffPtr
+= 2U;
3567 husart
->RxXferCount
--;
3569 if (husart
->RxXferCount
== 0U)
3571 /* Disable the USART Parity Error Interrupt */
3572 CLEAR_BIT(husart
->Instance
->CR1
, USART_CR1_PEIE
);
3574 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */
3575 CLEAR_BIT(husart
->Instance
->CR3
, (USART_CR3_EIE
| USART_CR3_RXFTIE
));
3577 /* Clear RxISR function pointer */
3578 husart
->RxISR
= NULL
;
3580 /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
3581 txftie
= READ_BIT(husart
->Instance
->CR3
, USART_CR3_TXFTIE
);
3582 txdatacount
= husart
->TxXferCount
;
3584 if (state
== HAL_USART_STATE_BUSY_RX
)
3586 /* Clear SPI slave underrun flag and discard transmit data */
3587 if (husart
->SlaveMode
== USART_SLAVEMODE_ENABLE
)
3589 __HAL_USART_CLEAR_UDRFLAG(husart
);
3590 __HAL_USART_SEND_REQ(husart
, USART_TXDATA_FLUSH_REQUEST
);
3593 /* Rx process is completed, restore husart->State to Ready */
3594 husart
->State
= HAL_USART_STATE_READY
;
3595 state
= HAL_USART_STATE_READY
;
3597 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3598 /* Call registered Rx Complete Callback */
3599 husart
->RxCpltCallback(husart
);
3601 /* Call legacy weak Rx Complete Callback */
3602 HAL_USART_RxCpltCallback(husart
);
3603 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3605 else if ((READ_BIT(husart
->Instance
->CR1
, USART_CR1_TCIE
) != USART_CR1_TCIE
) &&
3606 (txftie
!= USART_CR3_TXFTIE
) &&
3607 (txdatacount
== 0U))
3609 /* TxRx process is completed, restore husart->State to Ready */
3610 husart
->State
= HAL_USART_STATE_READY
;
3611 state
= HAL_USART_STATE_READY
;
3613 #if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
3614 /* Call registered Tx Rx Complete Callback */
3615 husart
->TxRxCpltCallback(husart
);
3617 /* Call legacy weak Tx Rx Complete Callback */
3618 HAL_USART_TxRxCpltCallback(husart
);
3619 #endif /* USE_HAL_USART_REGISTER_CALLBACKS */
3626 else if ((state
== HAL_USART_STATE_BUSY_RX
) &&
3627 (husart
->SlaveMode
== USART_SLAVEMODE_DISABLE
))
3629 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3630 husart
->Instance
->TDR
= (USART_DUMMY_DATA
& (uint16_t)0x00FF);
3639 /* When remaining number of bytes to receive is less than the RX FIFO
3640 threshold, next incoming frames are processed as if FIFO mode was
3641 disabled (i.e. one interrupt per received frame).
3643 rxdatacount
= husart
->RxXferCount
;
3644 if (((rxdatacount
!= 0U)) && (rxdatacount
< husart
->NbRxDataToProcess
))
3646 /* Disable the USART RXFT interrupt*/
3647 CLEAR_BIT(husart
->Instance
->CR3
, USART_CR3_RXFTIE
);
3649 /* Update the RxISR function pointer */
3650 husart
->RxISR
= USART_RxISR_16BIT
;
3652 /* Enable the USART Data Register Not Empty interrupt */
3653 SET_BIT(husart
->Instance
->CR1
, USART_CR1_RXNEIE_RXFNEIE
);
3655 if ((husart
->TxXferCount
== 0U) &&
3656 (state
== HAL_USART_STATE_BUSY_TX_RX
) &&
3657 (husart
->SlaveMode
== USART_SLAVEMODE_DISABLE
))
3659 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
3660 husart
->Instance
->TDR
= (USART_DUMMY_DATA
& (uint16_t)0x00FF);
3666 /* Clear RXNE interrupt flag */
3667 __HAL_USART_SEND_REQ(husart
, USART_RXDATA_FLUSH_REQUEST
);
3675 #endif /* HAL_USART_MODULE_ENABLED */
3684 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/