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