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