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