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