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