source: S-port/trunk/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_usart.c

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