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