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