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