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