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