comparison Common/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_usart.c @ 128:c78bcbd5deda FlipDisplay

Added current STM32 standandard libraries in version independend folder structure
author Ideenmodellierer
date Sun, 17 Feb 2019 21:12:22 +0100
parents
children
comparison
equal deleted inserted replaced
127:1369f8660eaa 128:c78bcbd5deda
1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_usart.c
4 * @author MCD Application Team
5 * @brief USART HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Universal Synchronous Asynchronous Receiver Transmitter (USART) peripheral:
8 * + Initialization and de-initialization functions
9 * + IO operation functions
10 * + Peripheral Control functions
11 @verbatim
12 ==============================================================================
13 ##### How to use this driver #####
14 ==============================================================================
15 [..]
16 The USART HAL driver can be used as follows:
17
18 (#) Declare a USART_HandleTypeDef handle structure.
19 (#) Initialize the USART low level resources by implementing the HAL_USART_MspInit () API:
20 (##) Enable the USARTx interface clock.
21 (##) USART pins configuration:
22 (+++) Enable the clock for the USART GPIOs.
23 (+++) Configure these USART pins as alternate function pull-up.
24 (##) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
25 HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
26 (+++) Configure the USARTx interrupt priority.
27 (+++) Enable the NVIC USART IRQ handle.
28 (##) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA()
29 HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
30 (+++) Declare a DMA handle structure for the Tx/Rx stream.
31 (+++) Enable the DMAx interface clock.
32 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
33 (+++) Configure the DMA Tx/Rx Stream.
34 (+++) Associate the initialized DMA handle to the USART DMA Tx/Rx handle.
35 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx Stream.
36
37 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
38 flow control and Mode(Receiver/Transmitter) in the husart Init structure.
39
40 (#) Initialize the USART registers by calling the HAL_USART_Init() API:
41 (++) These APIs configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
42 by calling the customized HAL_USART_MspInit(&husart) API.
43
44 -@@- The specific USART interrupts (Transmission complete interrupt,
45 RXNE interrupt and Error Interrupts) will be managed using the macros
46 __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process.
47
48 (#) Three operation modes are available within this driver :
49
50 *** Polling mode IO operation ***
51 =================================
52 [..]
53 (+) Send an amount of data in blocking mode using HAL_USART_Transmit()
54 (+) Receive an amount of data in blocking mode using HAL_USART_Receive()
55
56 *** Interrupt mode IO operation ***
57 ===================================
58 [..]
59 (+) Send an amount of data in non blocking mode using HAL_USART_Transmit_IT()
60 (+) At transmission end of transfer HAL_USART_TxHalfCpltCallback is executed and user can
61 add his own code by customization of function pointer HAL_USART_TxCpltCallback
62 (+) Receive an amount of data in non blocking mode using HAL_USART_Receive_IT()
63 (+) At reception end of transfer HAL_USART_RxCpltCallback is executed and user can
64 add his own code by customization of function pointer HAL_USART_RxCpltCallback
65 (+) In case of transfer Error, HAL_USART_ErrorCallback() function is executed and user can
66 add his own code by customization of function pointer HAL_USART_ErrorCallback
67
68 *** DMA mode IO operation ***
69 ==============================
70 [..]
71 (+) Send an amount of data in non blocking mode (DMA) using HAL_USART_Transmit_DMA()
72 (+) At transmission end of half transfer HAL_USART_TxHalfCpltCallback is executed and user can
73 add his own code by customization of function pointer HAL_USART_TxHalfCpltCallback
74 (+) At transmission end of transfer HAL_USART_TxCpltCallback is executed and user can
75 add his own code by customization of function pointer HAL_USART_TxCpltCallback
76 (+) Receive an amount of data in non blocking mode (DMA) using HAL_USART_Receive_DMA()
77 (+) At reception end of half transfer HAL_USART_RxHalfCpltCallback is executed and user can
78 add his own code by customization of function pointer HAL_USART_RxHalfCpltCallback
79 (+) At reception end of transfer HAL_USART_RxCpltCallback is executed and user can
80 add his own code by customization of function pointer HAL_USART_RxCpltCallback
81 (+) In case of transfer Error, HAL_USART_ErrorCallback() function is executed and user can
82 add his own code by customization of function pointer HAL_USART_ErrorCallback
83 (+) Pause the DMA Transfer using HAL_USART_DMAPause()
84 (+) Resume the DMA Transfer using HAL_USART_DMAResume()
85 (+) Stop the DMA Transfer using HAL_USART_DMAStop()
86
87 *** USART HAL driver macros list ***
88 =============================================
89 [..]
90 Below the list of most used macros in USART HAL driver.
91
92 (+) __HAL_USART_ENABLE: Enable the USART peripheral
93 (+) __HAL_USART_DISABLE: Disable the USART peripheral
94 (+) __HAL_USART_GET_FLAG : Check whether the specified USART flag is set or not
95 (+) __HAL_USART_CLEAR_FLAG : Clear the specified USART pending flag
96 (+) __HAL_USART_ENABLE_IT: Enable the specified USART interrupt
97 (+) __HAL_USART_DISABLE_IT: Disable the specified USART interrupt
98
99 [..]
100 (@) You can refer to the USART HAL driver header file for more useful macros
101
102 @endverbatim
103 ******************************************************************************
104 * @attention
105 *
106 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
107 *
108 * Redistribution and use in source and binary forms, with or without modification,
109 * are permitted provided that the following conditions are met:
110 * 1. Redistributions of source code must retain the above copyright notice,
111 * this list of conditions and the following disclaimer.
112 * 2. Redistributions in binary form must reproduce the above copyright notice,
113 * this list of conditions and the following disclaimer in the documentation
114 * and/or other materials provided with the distribution.
115 * 3. Neither the name of STMicroelectronics nor the names of its contributors
116 * may be used to endorse or promote products derived from this software
117 * without specific prior written permission.
118 *
119 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
120 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
121 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
123 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
124 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
125 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
126 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
127 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
128 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129 *
130 ******************************************************************************
131 */
132
133 /* Includes ------------------------------------------------------------------*/
134 #include "stm32f4xx_hal.h"
135
136 /** @addtogroup STM32F4xx_HAL_Driver
137 * @{
138 */
139
140 /** @defgroup USART USART
141 * @brief HAL USART Synchronous module driver
142 * @{
143 */
144 #ifdef HAL_USART_MODULE_ENABLED
145 /* Private typedef -----------------------------------------------------------*/
146 /* Private define ------------------------------------------------------------*/
147 /** @addtogroup USART_Private_Constants
148 * @{
149 */
150 #define DUMMY_DATA 0xFFFFU
151 #define USART_TIMEOUT_VALUE 22000U
152 /**
153 * @}
154 */
155 /* Private macro -------------------------------------------------------------*/
156 /* Private variables ---------------------------------------------------------*/
157 /* Private function prototypes -----------------------------------------------*/
158 /* Private functions ---------------------------------------------------------*/
159 /** @addtogroup USART_Private_Functions
160 * @{
161 */
162 static void USART_EndTxTransfer(USART_HandleTypeDef *husart);
163 static void USART_EndRxTransfer(USART_HandleTypeDef *husart);
164 static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart);
165 static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart);
166 static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart);
167 static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart);
168 static void USART_SetConfig (USART_HandleTypeDef *husart);
169 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
170 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
171 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
172 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
173 static void USART_DMAError(DMA_HandleTypeDef *hdma);
174 static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
175 static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
176 static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
177
178 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout);
179 /**
180 * @}
181 */
182
183 /* Exported functions --------------------------------------------------------*/
184 /** @defgroup USART_Exported_Functions USART Exported Functions
185 * @{
186 */
187
188 /** @defgroup USART_Exported_Functions_Group1 USART Initialization and de-initialization functions
189 * @brief Initialization and Configuration functions
190 *
191 @verbatim
192 ==============================================================================
193 ##### Initialization and Configuration functions #####
194 ==============================================================================
195 [..]
196 This subsection provides a set of functions allowing to initialize the USART
197 in asynchronous and in synchronous modes.
198 (+) For the asynchronous mode only these parameters can be configured:
199 (++) Baud Rate
200 (++) Word Length
201 (++) Stop Bit
202 (++) Parity: If the parity is enabled, then the MSB bit of the data written
203 in the data register is transmitted but is changed by the parity bit.
204 Depending on the frame length defined by the M bit (8-bits or 9-bits),
205 please refer to Reference manual for possible USART frame formats.
206 (++) USART polarity
207 (++) USART phase
208 (++) USART LastBit
209 (++) Receiver/transmitter modes
210
211 [..]
212 The HAL_USART_Init() function follows the USART synchronous configuration
213 procedure (details for the procedure are available in reference manual (RM0329)).
214
215 @endverbatim
216 * @{
217 */
218
219 /**
220 * @brief Initializes the USART mode according to the specified
221 * parameters in the USART_InitTypeDef and create the associated handle.
222 * @param husart pointer to a USART_HandleTypeDef structure that contains
223 * the configuration information for the specified USART module.
224 * @retval HAL status
225 */
226 HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
227 {
228 /* Check the USART handle allocation */
229 if(husart == NULL)
230 {
231 return HAL_ERROR;
232 }
233
234 /* Check the parameters */
235 assert_param(IS_USART_INSTANCE(husart->Instance));
236
237 if(husart->State == HAL_USART_STATE_RESET)
238 {
239 /* Allocate lock resource and initialize it */
240 husart->Lock = HAL_UNLOCKED;
241 /* Init the low level hardware */
242 HAL_USART_MspInit(husart);
243 }
244
245 husart->State = HAL_USART_STATE_BUSY;
246
247 /* Set the USART Communication parameters */
248 USART_SetConfig(husart);
249
250 /* In USART mode, the following bits must be kept cleared:
251 - LINEN bit in the USART_CR2 register
252 - HDSEL, SCEN and IREN bits in the USART_CR3 register */
253 CLEAR_BIT(husart->Instance->CR2, USART_CR2_LINEN);
254 CLEAR_BIT(husart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
255
256 /* Enable the Peripheral */
257 __HAL_USART_ENABLE(husart);
258
259 /* Initialize the USART state */
260 husart->ErrorCode = HAL_USART_ERROR_NONE;
261 husart->State= HAL_USART_STATE_READY;
262
263 return HAL_OK;
264 }
265
266 /**
267 * @brief DeInitializes the USART peripheral.
268 * @param husart pointer to a USART_HandleTypeDef structure that contains
269 * the configuration information for the specified USART module.
270 * @retval HAL status
271 */
272 HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart)
273 {
274 /* Check the USART handle allocation */
275 if(husart == NULL)
276 {
277 return HAL_ERROR;
278 }
279
280 /* Check the parameters */
281 assert_param(IS_USART_INSTANCE(husart->Instance));
282
283 husart->State = HAL_USART_STATE_BUSY;
284
285 /* Disable the Peripheral */
286 __HAL_USART_DISABLE(husart);
287
288 /* DeInit the low level hardware */
289 HAL_USART_MspDeInit(husart);
290
291 husart->ErrorCode = HAL_USART_ERROR_NONE;
292 husart->State = HAL_USART_STATE_RESET;
293
294 /* Release Lock */
295 __HAL_UNLOCK(husart);
296
297 return HAL_OK;
298 }
299
300 /**
301 * @brief USART MSP Init.
302 * @param husart pointer to a USART_HandleTypeDef structure that contains
303 * the configuration information for the specified USART module.
304 * @retval None
305 */
306 __weak void HAL_USART_MspInit(USART_HandleTypeDef *husart)
307 {
308 /* Prevent unused argument(s) compilation warning */
309 UNUSED(husart);
310 /* NOTE: This function Should not be modified, when the callback is needed,
311 the HAL_USART_MspInit could be implemented in the user file
312 */
313 }
314
315 /**
316 * @brief USART MSP DeInit.
317 * @param husart pointer to a USART_HandleTypeDef structure that contains
318 * the configuration information for the specified USART module.
319 * @retval None
320 */
321 __weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart)
322 {
323 /* Prevent unused argument(s) compilation warning */
324 UNUSED(husart);
325 /* NOTE: This function Should not be modified, when the callback is needed,
326 the HAL_USART_MspDeInit could be implemented in the user file
327 */
328 }
329
330 /**
331 * @}
332 */
333
334 /** @defgroup USART_Exported_Functions_Group2 IO operation functions
335 * @brief USART Transmit and Receive functions
336 *
337 @verbatim
338 ==============================================================================
339 ##### IO operation functions #####
340 ==============================================================================
341 [..]
342 This subsection provides a set of functions allowing to manage the USART synchronous
343 data transfers.
344
345 [..]
346 The USART supports master mode only: it cannot receive or send data related to an input
347 clock (SCLK is always an output).
348
349 (#) There are two modes of transfer:
350 (++) Blocking mode: The communication is performed in polling mode.
351 The HAL status of all data processing is returned by the same function
352 after finishing transfer.
353 (++) No-Blocking mode: The communication is performed using Interrupts
354 or DMA, These API's return the HAL status.
355 The end of the data processing will be indicated through the
356 dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
357 using DMA mode.
358 The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback()
359 user callbacks
360 will be executed respectively at the end of the transmit or Receive process
361 The HAL_USART_ErrorCallback() user callback will be executed when a communication
362 error is detected
363
364 (#) Blocking mode APIs are :
365 (++) HAL_USART_Transmit() in simplex mode
366 (++) HAL_USART_Receive() in full duplex receive only
367 (++) HAL_USART_TransmitReceive() in full duplex mode
368
369 (#) Non Blocking mode APIs with Interrupt are :
370 (++) HAL_USART_Transmit_IT()in simplex mode
371 (++) HAL_USART_Receive_IT() in full duplex receive only
372 (++) HAL_USART_TransmitReceive_IT() in full duplex mode
373 (++) HAL_USART_IRQHandler()
374
375 (#) Non Blocking mode functions with DMA are :
376 (++) HAL_USART_Transmit_DMA()in simplex mode
377 (++) HAL_USART_Receive_DMA() in full duplex receive only
378 (++) HAL_USART_TransmitReceie_DMA() in full duplex mode
379 (++) HAL_USART_DMAPause()
380 (++) HAL_USART_DMAResume()
381 (++) HAL_USART_DMAStop()
382
383 (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
384 (++) HAL_USART_TxHalfCpltCallback()
385 (++) HAL_USART_TxCpltCallback()
386 (++) HAL_USART_RxHalfCpltCallback()
387 (++) HAL_USART_RxCpltCallback()
388 (++) HAL_USART_ErrorCallback()
389 (++) HAL_USART_TxRxCpltCallback()
390
391 @endverbatim
392 * @{
393 */
394
395 /**
396 * @brief Simplex Send an amount of data in blocking mode.
397 * @param husart pointer to a USART_HandleTypeDef structure that contains
398 * the configuration information for the specified USART module.
399 * @param pTxData Pointer to data buffer
400 * @param Size Amount of data to be sent
401 * @param Timeout Timeout duration
402 * @retval HAL status
403 */
404 HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout)
405 {
406 uint16_t* tmp;
407 uint32_t tickstart = 0U;
408
409 if(husart->State == HAL_USART_STATE_READY)
410 {
411 if((pTxData == NULL) || (Size == 0))
412 {
413 return HAL_ERROR;
414 }
415
416 /* Process Locked */
417 __HAL_LOCK(husart);
418
419 husart->ErrorCode = HAL_USART_ERROR_NONE;
420 husart->State = HAL_USART_STATE_BUSY_TX;
421
422 /* Init tickstart for timeout managment */
423 tickstart = HAL_GetTick();
424
425 husart->TxXferSize = Size;
426 husart->TxXferCount = Size;
427 while(husart->TxXferCount > 0U)
428 {
429 husart->TxXferCount--;
430 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
431 {
432 /* Wait for TC flag in order to write data in DR */
433 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
434 {
435 return HAL_TIMEOUT;
436 }
437 tmp = (uint16_t*) pTxData;
438 husart->Instance->DR = (*tmp & (uint16_t)0x01FF);
439 if(husart->Init.Parity == USART_PARITY_NONE)
440 {
441 pTxData += 2U;
442 }
443 else
444 {
445 pTxData += 1U;
446 }
447 }
448 else
449 {
450 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
451 {
452 return HAL_TIMEOUT;
453 }
454 husart->Instance->DR = (*pTxData++ & (uint8_t)0xFF);
455 }
456 }
457
458 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
459 {
460 return HAL_TIMEOUT;
461 }
462
463 husart->State = HAL_USART_STATE_READY;
464
465 /* Process Unlocked */
466 __HAL_UNLOCK(husart);
467
468 return HAL_OK;
469 }
470 else
471 {
472 return HAL_BUSY;
473 }
474 }
475
476 /**
477 * @brief Full-Duplex Receive an amount of data in blocking mode.
478 * @param husart pointer to a USART_HandleTypeDef structure that contains
479 * the configuration information for the specified USART module.
480 * @param pRxData Pointer to data buffer
481 * @param Size Amount of data to be received
482 * @param Timeout Timeout duration
483 * @retval HAL status
484 */
485 HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
486 {
487 uint16_t* tmp;
488 uint32_t tickstart = 0U;
489
490 if(husart->State == HAL_USART_STATE_READY)
491 {
492 if((pRxData == NULL) || (Size == 0))
493 {
494 return HAL_ERROR;
495 }
496 /* Process Locked */
497 __HAL_LOCK(husart);
498
499 husart->ErrorCode = HAL_USART_ERROR_NONE;
500 husart->State = HAL_USART_STATE_BUSY_RX;
501
502 /* Init tickstart for timeout managment */
503 tickstart = HAL_GetTick();
504
505 husart->RxXferSize = Size;
506 husart->RxXferCount = Size;
507 /* Check the remain data to be received */
508 while(husart->RxXferCount > 0U)
509 {
510 husart->RxXferCount--;
511 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
512 {
513 /* Wait until TXE flag is set to send dummy byte in order to generate the clock for the slave to send data */
514 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
515 {
516 return HAL_TIMEOUT;
517 }
518 /* Send dummy byte in order to generate clock */
519 husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x01FF);
520
521 /* Wait for RXNE Flag */
522 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
523 {
524 return HAL_TIMEOUT;
525 }
526 tmp = (uint16_t*) pRxData ;
527 if(husart->Init.Parity == USART_PARITY_NONE)
528 {
529 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
530 pRxData +=2U;
531 }
532 else
533 {
534 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
535 pRxData +=1U;
536 }
537 }
538 else
539 {
540 /* Wait until TXE flag is set to send dummy byte in order to generate the clock for the slave to send data */
541 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
542 {
543 return HAL_TIMEOUT;
544 }
545
546 /* Send Dummy Byte in order to generate clock */
547 husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x00FF);
548
549 /* Wait until RXNE flag is set to receive the byte */
550 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
551 {
552 return HAL_TIMEOUT;
553 }
554 if(husart->Init.Parity == USART_PARITY_NONE)
555 {
556 /* Receive data */
557 *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
558 }
559 else
560 {
561 /* Receive data */
562 *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
563 }
564
565 }
566 }
567
568 husart->State = HAL_USART_STATE_READY;
569
570 /* Process Unlocked */
571 __HAL_UNLOCK(husart);
572
573 return HAL_OK;
574 }
575 else
576 {
577 return HAL_BUSY;
578 }
579 }
580
581 /**
582 * @brief Full-Duplex Send receive an amount of data in full-duplex mode (blocking mode).
583 * @param husart pointer to a USART_HandleTypeDef structure that contains
584 * the configuration information for the specified USART module.
585 * @param pTxData Pointer to data transmitted buffer
586 * @param pRxData Pointer to data received buffer
587 * @param Size Amount of data to be sent
588 * @param Timeout Timeout duration
589 * @retval HAL status
590 */
591 HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
592 {
593 uint16_t* tmp;
594 uint32_t tickstart = 0U;
595
596 if(husart->State == HAL_USART_STATE_READY)
597 {
598 if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
599 {
600 return HAL_ERROR;
601 }
602 /* Process Locked */
603 __HAL_LOCK(husart);
604
605 husart->ErrorCode = HAL_USART_ERROR_NONE;
606 husart->State = HAL_USART_STATE_BUSY_RX;
607
608 /* Init tickstart for timeout managment */
609 tickstart = HAL_GetTick();
610
611 husart->RxXferSize = Size;
612 husart->TxXferSize = Size;
613 husart->TxXferCount = Size;
614 husart->RxXferCount = Size;
615
616 /* Check the remain data to be received */
617 while(husart->TxXferCount > 0U)
618 {
619 husart->TxXferCount--;
620 husart->RxXferCount--;
621 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
622 {
623 /* Wait for TC flag in order to write data in DR */
624 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
625 {
626 return HAL_TIMEOUT;
627 }
628 tmp = (uint16_t*) pTxData;
629 husart->Instance->DR = (*tmp & (uint16_t)0x01FF);
630 if(husart->Init.Parity == USART_PARITY_NONE)
631 {
632 pTxData += 2U;
633 }
634 else
635 {
636 pTxData += 1U;
637 }
638
639 /* Wait for RXNE Flag */
640 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
641 {
642 return HAL_TIMEOUT;
643 }
644 tmp = (uint16_t*) pRxData ;
645 if(husart->Init.Parity == USART_PARITY_NONE)
646 {
647 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
648 pRxData += 2U;
649 }
650 else
651 {
652 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
653 pRxData += 1U;
654 }
655 }
656 else
657 {
658 /* Wait for TC flag in order to write data in DR */
659 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
660 {
661 return HAL_TIMEOUT;
662 }
663 husart->Instance->DR = (*pTxData++ & (uint8_t)0x00FF);
664
665 /* Wait for RXNE Flag */
666 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
667 {
668 return HAL_TIMEOUT;
669 }
670 if(husart->Init.Parity == USART_PARITY_NONE)
671 {
672 /* Receive data */
673 *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
674 }
675 else
676 {
677 /* Receive data */
678 *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
679 }
680 }
681 }
682
683 husart->State = HAL_USART_STATE_READY;
684
685 /* Process Unlocked */
686 __HAL_UNLOCK(husart);
687
688 return HAL_OK;
689 }
690 else
691 {
692 return HAL_BUSY;
693 }
694 }
695
696 /**
697 * @brief Simplex Send an amount of data in non-blocking mode.
698 * @param husart pointer to a USART_HandleTypeDef structure that contains
699 * the configuration information for the specified USART module.
700 * @param pTxData Pointer to data buffer
701 * @param Size Amount of data to be sent
702 * @retval HAL status
703 * @note The USART errors are not managed to avoid the overrun error.
704 */
705 HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
706 {
707 if(husart->State == HAL_USART_STATE_READY)
708 {
709 if((pTxData == NULL) || (Size == 0))
710 {
711 return HAL_ERROR;
712 }
713
714 /* Process Locked */
715 __HAL_LOCK(husart);
716
717 husart->pTxBuffPtr = pTxData;
718 husart->TxXferSize = Size;
719 husart->TxXferCount = Size;
720
721 husart->ErrorCode = HAL_USART_ERROR_NONE;
722 husart->State = HAL_USART_STATE_BUSY_TX;
723
724 /* The USART Error Interrupts: (Frame error, Noise error, Overrun error)
725 are not managed by the USART transmit process to avoid the overrun interrupt
726 when the USART mode is configured for transmit and receive "USART_MODE_TX_RX"
727 to benefit for the frame error and noise interrupts the USART mode should be
728 configured only for transmit "USART_MODE_TX"
729 The __HAL_USART_ENABLE_IT(husart, USART_IT_ERR) can be used to enable the Frame error,
730 Noise error interrupt */
731
732 /* Process Unlocked */
733 __HAL_UNLOCK(husart);
734
735 /* Enable the USART Transmit Data Register Empty Interrupt */
736 SET_BIT(husart->Instance->CR1, USART_CR1_TXEIE);
737
738 return HAL_OK;
739 }
740 else
741 {
742 return HAL_BUSY;
743 }
744 }
745
746 /**
747 * @brief Simplex Receive an amount of data in non-blocking mode.
748 * @param husart pointer to a USART_HandleTypeDef structure that contains
749 * the configuration information for the specified USART module.
750 * @param pRxData Pointer to data buffer
751 * @param Size Amount of data to be received
752 * @retval HAL status
753 */
754 HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
755 {
756 if(husart->State == HAL_USART_STATE_READY)
757 {
758 if((pRxData == NULL) || (Size == 0))
759 {
760 return HAL_ERROR;
761 }
762 /* Process Locked */
763 __HAL_LOCK(husart);
764
765 husart->pRxBuffPtr = pRxData;
766 husart->RxXferSize = Size;
767 husart->RxXferCount = Size;
768
769 husart->ErrorCode = HAL_USART_ERROR_NONE;
770 husart->State = HAL_USART_STATE_BUSY_RX;
771
772 /* Process Unlocked */
773 __HAL_UNLOCK(husart);
774
775 /* Enable the USART Parity Error and Data Register not empty Interrupts */
776 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
777
778 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
779 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
780
781 /* Send dummy byte in order to generate the clock for the slave to send data */
782 husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x01FF);
783
784 return HAL_OK;
785 }
786 else
787 {
788 return HAL_BUSY;
789 }
790 }
791
792 /**
793 * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking).
794 * @param husart pointer to a USART_HandleTypeDef structure that contains
795 * the configuration information for the specified USART module.
796 * @param pTxData Pointer to data transmitted buffer
797 * @param pRxData Pointer to data received buffer
798 * @param Size Amount of data to be received
799 * @retval HAL status
800 */
801 HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
802 {
803 if(husart->State == HAL_USART_STATE_READY)
804 {
805 if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
806 {
807 return HAL_ERROR;
808 }
809 /* Process Locked */
810 __HAL_LOCK(husart);
811
812 husart->pRxBuffPtr = pRxData;
813 husart->RxXferSize = Size;
814 husart->RxXferCount = Size;
815 husart->pTxBuffPtr = pTxData;
816 husart->TxXferSize = Size;
817 husart->TxXferCount = Size;
818
819 husart->ErrorCode = HAL_USART_ERROR_NONE;
820 husart->State = HAL_USART_STATE_BUSY_TX_RX;
821
822 /* Process Unlocked */
823 __HAL_UNLOCK(husart);
824
825 /* Enable the USART Data Register not empty Interrupt */
826 SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE);
827
828 /* Enable the USART Parity Error Interrupt */
829 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
830
831 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
832 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
833
834 /* Enable the USART Transmit Data Register Empty Interrupt */
835 SET_BIT(husart->Instance->CR1, USART_CR1_TXEIE);
836
837 return HAL_OK;
838 }
839 else
840 {
841 return HAL_BUSY;
842 }
843 }
844
845 /**
846 * @brief Simplex Send an amount of data in non-blocking mode.
847 * @param husart pointer to a USART_HandleTypeDef structure that contains
848 * the configuration information for the specified USART module.
849 * @param pTxData Pointer to data buffer
850 * @param Size Amount of data to be sent
851 * @retval HAL status
852 */
853 HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
854 {
855 uint32_t *tmp;
856
857 if(husart->State == HAL_USART_STATE_READY)
858 {
859 if((pTxData == NULL) || (Size == 0))
860 {
861 return HAL_ERROR;
862 }
863 /* Process Locked */
864 __HAL_LOCK(husart);
865
866 husart->pTxBuffPtr = pTxData;
867 husart->TxXferSize = Size;
868 husart->TxXferCount = Size;
869
870 husart->ErrorCode = HAL_USART_ERROR_NONE;
871 husart->State = HAL_USART_STATE_BUSY_TX;
872
873 /* Set the USART DMA transfer complete callback */
874 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
875
876 /* Set the USART DMA Half transfer complete callback */
877 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
878
879 /* Set the DMA error callback */
880 husart->hdmatx->XferErrorCallback = USART_DMAError;
881
882 /* Set the DMA abort callback */
883 husart->hdmatx->XferAbortCallback = NULL;
884
885 /* Enable the USART transmit DMA Stream */
886 tmp = (uint32_t*)&pTxData;
887 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->DR, Size);
888
889 /* Clear the TC flag in the SR register by writing 0 to it */
890 __HAL_USART_CLEAR_FLAG(husart, USART_FLAG_TC);
891
892 /* Process Unlocked */
893 __HAL_UNLOCK(husart);
894
895 /* Enable the DMA transfer for transmit request by setting the DMAT bit
896 in the USART CR3 register */
897 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
898
899 return HAL_OK;
900 }
901 else
902 {
903 return HAL_BUSY;
904 }
905 }
906
907 /**
908 * @brief Full-Duplex Receive an amount of data in non-blocking mode.
909 * @param husart pointer to a USART_HandleTypeDef structure that contains
910 * the configuration information for the specified USART module.
911 * @param pRxData Pointer to data buffer
912 * @param Size Amount of data to be received
913 * @retval HAL status
914 * @note The USART DMA transmit stream must be configured in order to generate the clock for the slave.
915 * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
916 */
917 HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
918 {
919 uint32_t *tmp;
920
921 if(husart->State == HAL_USART_STATE_READY)
922 {
923 if((pRxData == NULL) || (Size == 0))
924 {
925 return HAL_ERROR;
926 }
927
928 /* Process Locked */
929 __HAL_LOCK(husart);
930
931 husart->pRxBuffPtr = pRxData;
932 husart->RxXferSize = Size;
933 husart->pTxBuffPtr = pRxData;
934 husart->TxXferSize = Size;
935
936 husart->ErrorCode = HAL_USART_ERROR_NONE;
937 husart->State = HAL_USART_STATE_BUSY_RX;
938
939 /* Set the USART DMA Rx transfer complete callback */
940 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
941
942 /* Set the USART DMA Half transfer complete callback */
943 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
944
945 /* Set the USART DMA Rx transfer error callback */
946 husart->hdmarx->XferErrorCallback = USART_DMAError;
947
948 /* Set the DMA abort callback */
949 husart->hdmarx->XferAbortCallback = NULL;
950
951 /* Set the USART Tx DMA transfer complete callback as NULL because the communication closing
952 is performed in DMA reception complete callback */
953 husart->hdmatx->XferHalfCpltCallback = NULL;
954 husart->hdmatx->XferCpltCallback = NULL;
955
956 /* Set the DMA error callback */
957 husart->hdmatx->XferErrorCallback = USART_DMAError;
958
959 /* Set the DMA AbortCpltCallback */
960 husart->hdmatx->XferAbortCallback = NULL;
961
962 /* Enable the USART receive DMA Stream */
963 tmp = (uint32_t*)&pRxData;
964 HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->DR, *(uint32_t*)tmp, Size);
965
966 /* Enable the USART transmit DMA Stream: the transmit stream is used in order
967 to generate in the non-blocking mode the clock to the slave device,
968 this mode isn't a simplex receive mode but a full-duplex receive one */
969 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->DR, Size);
970
971 /* Clear the Overrun flag just before enabling the DMA Rx request: mandatory for the second transfer */
972 __HAL_USART_CLEAR_OREFLAG(husart);
973
974 /* Process Unlocked */
975 __HAL_UNLOCK(husart);
976
977 /* Enable the USART Parity Error Interrupt */
978 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
979
980 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
981 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
982
983 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
984 in the USART CR3 register */
985 SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
986
987 /* Enable the DMA transfer for transmit request by setting the DMAT bit
988 in the USART CR3 register */
989 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
990
991 return HAL_OK;
992 }
993 else
994 {
995 return HAL_BUSY;
996 }
997 }
998
999 /**
1000 * @brief Full-Duplex Transmit Receive an amount of data in non-blocking mode.
1001 * @param husart pointer to a USART_HandleTypeDef structure that contains
1002 * the configuration information for the specified USART module.
1003 * @param pTxData Pointer to data transmitted buffer
1004 * @param pRxData Pointer to data received buffer
1005 * @param Size Amount of data to be received
1006 * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
1007 * @retval HAL status
1008 */
1009 HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
1010 {
1011 uint32_t *tmp;
1012
1013 if(husart->State == HAL_USART_STATE_READY)
1014 {
1015 if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
1016 {
1017 return HAL_ERROR;
1018 }
1019 /* Process Locked */
1020 __HAL_LOCK(husart);
1021
1022 husart->pRxBuffPtr = pRxData;
1023 husart->RxXferSize = Size;
1024 husart->pTxBuffPtr = pTxData;
1025 husart->TxXferSize = Size;
1026
1027 husart->ErrorCode = HAL_USART_ERROR_NONE;
1028 husart->State = HAL_USART_STATE_BUSY_TX_RX;
1029
1030 /* Set the USART DMA Rx transfer complete callback */
1031 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
1032
1033 /* Set the USART DMA Half transfer complete callback */
1034 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
1035
1036 /* Set the USART DMA Tx transfer complete callback */
1037 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
1038
1039 /* Set the USART DMA Half transfer complete callback */
1040 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
1041
1042 /* Set the USART DMA Tx transfer error callback */
1043 husart->hdmatx->XferErrorCallback = USART_DMAError;
1044
1045 /* Set the USART DMA Rx transfer error callback */
1046 husart->hdmarx->XferErrorCallback = USART_DMAError;
1047
1048 /* Set the DMA abort callback */
1049 husart->hdmarx->XferAbortCallback = NULL;
1050
1051 /* Enable the USART receive DMA Stream */
1052 tmp = (uint32_t*)&pRxData;
1053 HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->DR, *(uint32_t*)tmp, Size);
1054
1055 /* Enable the USART transmit DMA Stream */
1056 tmp = (uint32_t*)&pTxData;
1057 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->DR, Size);
1058
1059 /* Clear the TC flag in the SR register by writing 0 to it */
1060 __HAL_USART_CLEAR_FLAG(husart, USART_FLAG_TC);
1061
1062 /* Clear the Overrun flag: mandatory for the second transfer in circular mode */
1063 __HAL_USART_CLEAR_OREFLAG(husart);
1064
1065 /* Process Unlocked */
1066 __HAL_UNLOCK(husart);
1067
1068 /* Enable the USART Parity Error Interrupt */
1069 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1070
1071 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1072 SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
1073
1074 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1075 in the USART CR3 register */
1076 SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1077
1078 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1079 in the USART CR3 register */
1080 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1081
1082 return HAL_OK;
1083 }
1084 else
1085 {
1086 return HAL_BUSY;
1087 }
1088 }
1089
1090 /**
1091 * @brief Pauses the DMA Transfer.
1092 * @param husart pointer to a USART_HandleTypeDef structure that contains
1093 * the configuration information for the specified USART module.
1094 * @retval HAL status
1095 */
1096 HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart)
1097 {
1098 /* Process Locked */
1099 __HAL_LOCK(husart);
1100
1101 /* Disable the USART DMA Tx request */
1102 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1103
1104 /* Process Unlocked */
1105 __HAL_UNLOCK(husart);
1106
1107 return HAL_OK;
1108 }
1109
1110 /**
1111 * @brief Resumes the DMA Transfer.
1112 * @param husart pointer to a USART_HandleTypeDef structure that contains
1113 * the configuration information for the specified USART module.
1114 * @retval HAL status
1115 */
1116 HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart)
1117 {
1118 /* Process Locked */
1119 __HAL_LOCK(husart);
1120
1121 /* Enable the USART DMA Tx request */
1122 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1123
1124 /* Process Unlocked */
1125 __HAL_UNLOCK(husart);
1126
1127 return HAL_OK;
1128 }
1129
1130 /**
1131 * @brief Stops the DMA Transfer.
1132 * @param husart pointer to a USART_HandleTypeDef structure that contains
1133 * the configuration information for the specified USART module.
1134 * @retval HAL status
1135 */
1136 HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart)
1137 {
1138 uint32_t dmarequest = 0x00U;
1139 /* The Lock is not implemented on this API to allow the user application
1140 to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback():
1141 when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
1142 and the correspond call back is executed HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback()
1143 */
1144
1145 /* Stop USART DMA Tx request if ongoing */
1146 dmarequest = HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT);
1147 if((husart->State == HAL_USART_STATE_BUSY_TX) && dmarequest)
1148 {
1149 USART_EndTxTransfer(husart);
1150
1151 /* Abort the USART DMA Tx channel */
1152 if(husart->hdmatx != NULL)
1153 {
1154 HAL_DMA_Abort(husart->hdmatx);
1155 }
1156
1157 /* Disable the USART Tx DMA request */
1158 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1159 }
1160
1161 /* Stop USART DMA Rx request if ongoing */
1162 dmarequest = HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR);
1163 if((husart->State == HAL_USART_STATE_BUSY_RX) && dmarequest)
1164 {
1165 USART_EndRxTransfer(husart);
1166
1167 /* Abort the USART DMA Rx channel */
1168 if(husart->hdmarx != NULL)
1169 {
1170 HAL_DMA_Abort(husart->hdmarx);
1171 }
1172
1173 /* Disable the USART Rx DMA request */
1174 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1175 }
1176
1177 return HAL_OK;
1178 }
1179
1180 /**
1181 * @brief Abort ongoing transfer (blocking mode).
1182 * @param husart USART handle.
1183 * @note This procedure could be used for aborting any ongoing transfer (either Tx or Rx,
1184 * as described by TransferType parameter) started in Interrupt or DMA mode.
1185 * This procedure performs following operations :
1186 * - Disable PPP Interrupts (depending of transfer direction)
1187 * - Disable the DMA transfer in the peripheral register (if enabled)
1188 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1189 * - Set handle State to READY
1190 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1191 * @retval HAL status
1192 */
1193 HAL_StatusTypeDef HAL_USART_Abort(USART_HandleTypeDef *husart)
1194 {
1195 /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1196 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
1197 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
1198
1199 /* Disable the USART DMA Tx request if enabled */
1200 if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
1201 {
1202 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1203
1204 /* Abort the USART DMA Tx channel : use blocking DMA Abort API (no callback) */
1205 if(husart->hdmatx != NULL)
1206 {
1207 /* Set the USART DMA Abort callback to Null.
1208 No call back execution at end of DMA abort procedure */
1209 husart->hdmatx->XferAbortCallback = NULL;
1210
1211 HAL_DMA_Abort(husart->hdmatx);
1212 }
1213 }
1214
1215 /* Disable the USART DMA Rx request if enabled */
1216 if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
1217 {
1218 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1219
1220 /* Abort the USART DMA Rx channel : use blocking DMA Abort API (no callback) */
1221 if(husart->hdmarx != NULL)
1222 {
1223 /* Set the USART DMA Abort callback to Null.
1224 No call back execution at end of DMA abort procedure */
1225 husart->hdmarx->XferAbortCallback = NULL;
1226
1227 HAL_DMA_Abort(husart->hdmarx);
1228 }
1229 }
1230
1231 /* Reset Tx and Rx transfer counters */
1232 husart->TxXferCount = 0x00U;
1233 husart->RxXferCount = 0x00U;
1234
1235 /* Restore husart->State to Ready */
1236 husart->State = HAL_USART_STATE_READY;
1237
1238 /* Reset Handle ErrorCode to No Error */
1239 husart->ErrorCode = HAL_USART_ERROR_NONE;
1240
1241 return HAL_OK;
1242 }
1243
1244 /**
1245 * @brief Abort ongoing transfer (Interrupt mode).
1246 * @param husart USART handle.
1247 * @note This procedure could be used for aborting any ongoing transfer (either Tx or Rx,
1248 * as described by TransferType parameter) started in Interrupt or DMA mode.
1249 * This procedure performs following operations :
1250 * - Disable PPP Interrupts (depending of transfer direction)
1251 * - Disable the DMA transfer in the peripheral register (if enabled)
1252 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1253 * - Set handle State to READY
1254 * - At abort completion, call user abort complete callback
1255 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
1256 * considered as completed only when user abort complete callback is executed (not when exiting function).
1257 * @retval HAL status
1258 */
1259 HAL_StatusTypeDef HAL_USART_Abort_IT(USART_HandleTypeDef *husart)
1260 {
1261 uint32_t AbortCplt = 0x01U;
1262
1263 /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1264 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
1265 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
1266
1267 /* If DMA Tx and/or DMA Rx Handles are associated to USART Handle, DMA Abort complete callbacks should be initialised
1268 before any call to DMA Abort functions */
1269 /* DMA Tx Handle is valid */
1270 if(husart->hdmatx != NULL)
1271 {
1272 /* Set DMA Abort Complete callback if USART DMA Tx request if enabled.
1273 Otherwise, set it to NULL */
1274 if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
1275 {
1276 husart->hdmatx->XferAbortCallback = USART_DMATxAbortCallback;
1277 }
1278 else
1279 {
1280 husart->hdmatx->XferAbortCallback = NULL;
1281 }
1282 }
1283 /* DMA Rx Handle is valid */
1284 if(husart->hdmarx != NULL)
1285 {
1286 /* Set DMA Abort Complete callback if USART DMA Rx request if enabled.
1287 Otherwise, set it to NULL */
1288 if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
1289 {
1290 husart->hdmarx->XferAbortCallback = USART_DMARxAbortCallback;
1291 }
1292 else
1293 {
1294 husart->hdmarx->XferAbortCallback = NULL;
1295 }
1296 }
1297
1298 /* Disable the USART DMA Tx request if enabled */
1299 if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
1300 {
1301 /* Disable DMA Tx at USART level */
1302 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1303
1304 /* Abort the USART DMA Tx channel : use non blocking DMA Abort API (callback) */
1305 if(husart->hdmatx != NULL)
1306 {
1307 /* USART Tx DMA Abort callback has already been initialised :
1308 will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
1309
1310 /* Abort DMA TX */
1311 if(HAL_DMA_Abort_IT(husart->hdmatx) != HAL_OK)
1312 {
1313 husart->hdmatx->XferAbortCallback = NULL;
1314 }
1315 else
1316 {
1317 AbortCplt = 0x00U;
1318 }
1319 }
1320 }
1321
1322 /* Disable the USART DMA Rx request if enabled */
1323 if(HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
1324 {
1325 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1326
1327 /* Abort the USART DMA Rx channel : use non blocking DMA Abort API (callback) */
1328 if(husart->hdmarx != NULL)
1329 {
1330 /* USART Rx DMA Abort callback has already been initialised :
1331 will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
1332
1333 /* Abort DMA RX */
1334 if(HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
1335 {
1336 husart->hdmarx->XferAbortCallback = NULL;
1337 AbortCplt = 0x01U;
1338 }
1339 else
1340 {
1341 AbortCplt = 0x00U;
1342 }
1343 }
1344 }
1345
1346 /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
1347 if(AbortCplt == 0x01U)
1348 {
1349 /* Reset Tx and Rx transfer counters */
1350 husart->TxXferCount = 0x00U;
1351 husart->RxXferCount = 0x00U;
1352
1353 /* Reset errorCode */
1354 husart->ErrorCode = HAL_USART_ERROR_NONE;
1355
1356 /* Restore husart->State to Ready */
1357 husart->State = HAL_USART_STATE_READY;
1358
1359 /* As no DMA to be aborted, call directly user Abort complete callback */
1360 HAL_USART_AbortCpltCallback(husart);
1361 }
1362
1363 return HAL_OK;
1364 }
1365
1366 /**
1367 * @brief This function handles USART interrupt request.
1368 * @param husart pointer to a USART_HandleTypeDef structure that contains
1369 * the configuration information for the specified USART module.
1370 * @retval None
1371 */
1372 void HAL_USART_IRQHandler(USART_HandleTypeDef *husart)
1373 {
1374 uint32_t isrflags = READ_REG(husart->Instance->SR);
1375 uint32_t cr1its = READ_REG(husart->Instance->CR1);
1376 uint32_t cr3its = READ_REG(husart->Instance->CR3);
1377 uint32_t errorflags = 0x00U;
1378 uint32_t dmarequest = 0x00U;
1379
1380 /* If no error occurs */
1381 errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
1382 if(errorflags == RESET)
1383 {
1384 /* USART in mode Receiver -------------------------------------------------*/
1385 if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
1386 {
1387 if(husart->State == HAL_USART_STATE_BUSY_RX)
1388 {
1389 USART_Receive_IT(husart);
1390 }
1391 else
1392 {
1393 USART_TransmitReceive_IT(husart);
1394 }
1395 return;
1396 }
1397 }
1398 /* If some errors occur */
1399 if((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
1400 {
1401 /* USART parity error interrupt occurred ----------------------------------*/
1402 if(((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
1403 {
1404 husart->ErrorCode |= HAL_USART_ERROR_PE;
1405 }
1406
1407 /* USART noise error interrupt occurred --------------------------------*/
1408 if(((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
1409 {
1410 husart->ErrorCode |= HAL_USART_ERROR_NE;
1411 }
1412
1413 /* USART frame error interrupt occurred --------------------------------*/
1414 if(((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
1415 {
1416 husart->ErrorCode |= HAL_USART_ERROR_FE;
1417 }
1418
1419 /* USART Over-Run interrupt occurred -----------------------------------*/
1420 if(((isrflags & USART_SR_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
1421 {
1422 husart->ErrorCode |= HAL_USART_ERROR_ORE;
1423 }
1424
1425 if(husart->ErrorCode != HAL_USART_ERROR_NONE)
1426 {
1427 /* USART in mode Receiver -----------------------------------------------*/
1428 if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
1429 {
1430 if(husart->State == HAL_USART_STATE_BUSY_RX)
1431 {
1432 USART_Receive_IT(husart);
1433 }
1434 else
1435 {
1436 USART_TransmitReceive_IT(husart);
1437 }
1438 }
1439 /* If Overrun error occurs, or if any error occurs in DMA mode reception,
1440 consider error as blocking */
1441 dmarequest = HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR);
1442 if(((husart->ErrorCode & HAL_USART_ERROR_ORE) != RESET) || dmarequest)
1443 {
1444 /* Set the USART state ready to be able to start again the process,
1445 Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
1446 USART_EndRxTransfer(husart);
1447
1448 /* Disable the USART DMA Rx request if enabled */
1449 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
1450 {
1451 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1452
1453 /* Abort the USART DMA Rx channel */
1454 if(husart->hdmarx != NULL)
1455 {
1456 /* Set the USART DMA Abort callback :
1457 will lead to call HAL_USART_ErrorCallback() at end of DMA abort procedure */
1458 husart->hdmarx->XferAbortCallback = USART_DMAAbortOnError;
1459
1460 if(HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
1461 {
1462 /* Call Directly XferAbortCallback function in case of error */
1463 husart->hdmarx->XferAbortCallback(husart->hdmarx);
1464 }
1465 }
1466 else
1467 {
1468 /* Call user error callback */
1469 HAL_USART_ErrorCallback(husart);
1470 }
1471 }
1472 else
1473 {
1474 /* Call user error callback */
1475 HAL_USART_ErrorCallback(husart);
1476 }
1477 }
1478 else
1479 {
1480 /* Call user error callback */
1481 HAL_USART_ErrorCallback(husart);
1482 husart->ErrorCode = HAL_USART_ERROR_NONE;
1483 }
1484 }
1485 return;
1486 }
1487
1488 /* USART in mode Transmitter -----------------------------------------------*/
1489 if(((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
1490 {
1491 if(husart->State == HAL_USART_STATE_BUSY_TX)
1492 {
1493 USART_Transmit_IT(husart);
1494 }
1495 else
1496 {
1497 USART_TransmitReceive_IT(husart);
1498 }
1499 return;
1500 }
1501
1502 /* USART in mode Transmitter (transmission end) ----------------------------*/
1503 if(((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
1504 {
1505 USART_EndTransmit_IT(husart);
1506 return;
1507 }
1508 }
1509
1510 /**
1511 * @brief Tx Transfer completed callbacks.
1512 * @param husart pointer to a USART_HandleTypeDef structure that contains
1513 * the configuration information for the specified USART module.
1514 * @retval None
1515 */
1516 __weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart)
1517 {
1518 /* Prevent unused argument(s) compilation warning */
1519 UNUSED(husart);
1520 /* NOTE: This function Should not be modified, when the callback is needed,
1521 the HAL_USART_TxCpltCallback could be implemented in the user file
1522 */
1523 }
1524
1525 /**
1526 * @brief Tx Half Transfer completed callbacks.
1527 * @param husart pointer to a USART_HandleTypeDef structure that contains
1528 * the configuration information for the specified USART module.
1529 * @retval None
1530 */
1531 __weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart)
1532 {
1533 /* Prevent unused argument(s) compilation warning */
1534 UNUSED(husart);
1535 /* NOTE: This function Should not be modified, when the callback is needed,
1536 the HAL_USART_TxCpltCallback could be implemented in the user file
1537 */
1538 }
1539
1540 /**
1541 * @brief Rx Transfer completed callbacks.
1542 * @param husart pointer to a USART_HandleTypeDef structure that contains
1543 * the configuration information for the specified USART module.
1544 * @retval None
1545 */
1546 __weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart)
1547 {
1548 /* Prevent unused argument(s) compilation warning */
1549 UNUSED(husart);
1550 /* NOTE: This function Should not be modified, when the callback is needed,
1551 the HAL_USART_TxCpltCallback could be implemented in the user file
1552 */
1553 }
1554
1555 /**
1556 * @brief Rx Half Transfer completed callbacks.
1557 * @param husart pointer to a USART_HandleTypeDef structure that contains
1558 * the configuration information for the specified USART module.
1559 * @retval None
1560 */
1561 __weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart)
1562 {
1563 /* Prevent unused argument(s) compilation warning */
1564 UNUSED(husart);
1565 /* NOTE: This function Should not be modified, when the callback is needed,
1566 the HAL_USART_TxCpltCallback could be implemented in the user file
1567 */
1568 }
1569
1570 /**
1571 * @brief Tx/Rx Transfers completed callback for the non-blocking process.
1572 * @param husart pointer to a USART_HandleTypeDef structure that contains
1573 * the configuration information for the specified USART module.
1574 * @retval None
1575 */
1576 __weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart)
1577 {
1578 /* Prevent unused argument(s) compilation warning */
1579 UNUSED(husart);
1580 /* NOTE: This function Should not be modified, when the callback is needed,
1581 the HAL_USART_TxCpltCallback could be implemented in the user file
1582 */
1583 }
1584
1585 /**
1586 * @brief USART error callbacks.
1587 * @param husart pointer to a USART_HandleTypeDef structure that contains
1588 * the configuration information for the specified USART module.
1589 * @retval None
1590 */
1591 __weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart)
1592 {
1593 /* Prevent unused argument(s) compilation warning */
1594 UNUSED(husart);
1595 /* NOTE: This function Should not be modified, when the callback is needed,
1596 the HAL_USART_ErrorCallback could be implemented in the user file
1597 */
1598 }
1599
1600 /**
1601 * @brief USART Abort Complete callback.
1602 * @param husart USART handle.
1603 * @retval None
1604 */
1605 __weak void HAL_USART_AbortCpltCallback (USART_HandleTypeDef *husart)
1606 {
1607 /* Prevent unused argument(s) compilation warning */
1608 UNUSED(husart);
1609
1610 /* NOTE : This function should not be modified, when the callback is needed,
1611 the HAL_USART_AbortCpltCallback can be implemented in the user file.
1612 */
1613 }
1614
1615 /**
1616 * @}
1617 */
1618
1619 /** @defgroup USART_Exported_Functions_Group3 Peripheral State and Errors functions
1620 * @brief USART State and Errors functions
1621 *
1622 @verbatim
1623 ==============================================================================
1624 ##### Peripheral State and Errors functions #####
1625 ==============================================================================
1626 [..]
1627 This subsection provides a set of functions allowing to return the State of
1628 USART communication
1629 process, return Peripheral Errors occurred during communication process
1630 (+) HAL_USART_GetState() API can be helpful to check in run-time the state
1631 of the USART peripheral.
1632 (+) HAL_USART_GetError() check in run-time errors that could be occurred during
1633 communication.
1634 @endverbatim
1635 * @{
1636 */
1637
1638 /**
1639 * @brief Returns the USART state.
1640 * @param husart pointer to a USART_HandleTypeDef structure that contains
1641 * the configuration information for the specified USART module.
1642 * @retval HAL state
1643 */
1644 HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart)
1645 {
1646 return husart->State;
1647 }
1648
1649 /**
1650 * @brief Return the USART error code
1651 * @param husart pointer to a USART_HandleTypeDef structure that contains
1652 * the configuration information for the specified USART.
1653 * @retval USART Error Code
1654 */
1655 uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart)
1656 {
1657 return husart->ErrorCode;
1658 }
1659
1660 /**
1661 * @}
1662 */
1663
1664 /**
1665 * @brief DMA USART transmit process complete callback.
1666 * @param hdma DMA handle
1667 * @retval None
1668 */
1669 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1670 {
1671 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1672 /* DMA Normal mode */
1673 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
1674 {
1675 husart->TxXferCount = 0U;
1676 if(husart->State == HAL_USART_STATE_BUSY_TX)
1677 {
1678 /* Disable the DMA transfer for transmit request by resetting the DMAT bit
1679 in the USART CR3 register */
1680 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1681
1682 /* Enable the USART Transmit Complete Interrupt */
1683 SET_BIT(husart->Instance->CR1, USART_CR1_TCIE);
1684 }
1685 }
1686 /* DMA Circular mode */
1687 else
1688 {
1689 if(husart->State == HAL_USART_STATE_BUSY_TX)
1690 {
1691 HAL_USART_TxCpltCallback(husart);
1692 }
1693 }
1694 }
1695
1696 /**
1697 * @brief DMA USART transmit process half complete callback
1698 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1699 * the configuration information for the specified DMA module.
1700 * @retval None
1701 */
1702 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1703 {
1704 USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1705
1706 HAL_USART_TxHalfCpltCallback(husart);
1707 }
1708
1709 /**
1710 * @brief DMA USART receive process complete callback.
1711 * @param hdma DMA handle
1712 * @retval None
1713 */
1714 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1715 {
1716 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1717 /* DMA Normal mode */
1718 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
1719 {
1720 husart->RxXferCount = 0x00U;
1721
1722 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1723 CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1724 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
1725
1726 /* Disable the DMA transfer for the Transmit/receiver request by clearing the DMAT/DMAR bit
1727 in the USART CR3 register */
1728 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
1729 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
1730
1731 husart->State= HAL_USART_STATE_READY;
1732
1733 /* The USART state is HAL_USART_STATE_BUSY_RX */
1734 if(husart->State == HAL_USART_STATE_BUSY_RX)
1735 {
1736 HAL_USART_RxCpltCallback(husart);
1737 }
1738 /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
1739 else
1740 {
1741 HAL_USART_TxRxCpltCallback(husart);
1742 }
1743 }
1744 /* DMA circular mode */
1745 else
1746 {
1747 if(husart->State == HAL_USART_STATE_BUSY_RX)
1748 {
1749 HAL_USART_RxCpltCallback(husart);
1750 }
1751 /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
1752 else
1753 {
1754 HAL_USART_TxRxCpltCallback(husart);
1755 }
1756 }
1757 }
1758
1759 /**
1760 * @brief DMA USART receive process half complete callback
1761 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1762 * the configuration information for the specified DMA module.
1763 * @retval None
1764 */
1765 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1766 {
1767 USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1768
1769 HAL_USART_RxHalfCpltCallback(husart);
1770 }
1771
1772 /**
1773 * @brief DMA USART communication error callback.
1774 * @param hdma DMA handle
1775 * @retval None
1776 */
1777 static void USART_DMAError(DMA_HandleTypeDef *hdma)
1778 {
1779 uint32_t dmarequest = 0x00U;
1780 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1781 husart->RxXferCount = 0x00U;
1782 husart->TxXferCount = 0x00U;
1783
1784 /* Stop USART DMA Tx request if ongoing */
1785 dmarequest = HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT);
1786 if((husart->State == HAL_USART_STATE_BUSY_TX) && dmarequest)
1787 {
1788 USART_EndTxTransfer(husart);
1789 }
1790
1791 /* Stop USART DMA Rx request if ongoing */
1792 dmarequest = HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR);
1793 if((husart->State == HAL_USART_STATE_BUSY_RX) && dmarequest)
1794 {
1795 USART_EndRxTransfer(husart);
1796 }
1797
1798 husart->ErrorCode |= HAL_USART_ERROR_DMA;
1799 husart->State= HAL_USART_STATE_READY;
1800
1801 HAL_USART_ErrorCallback(husart);
1802 }
1803
1804 /**
1805 * @brief This function handles USART Communication Timeout.
1806 * @param husart pointer to a USART_HandleTypeDef structure that contains
1807 * the configuration information for the specified USART module.
1808 * @param Flag specifies the USART flag to check.
1809 * @param Status The new Flag status (SET or RESET).
1810 * @param Tickstart Tick start value.
1811 * @param Timeout Timeout duration.
1812 * @retval HAL status
1813 */
1814 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
1815 {
1816 /* Wait until flag is set */
1817 while((__HAL_USART_GET_FLAG(husart, Flag) ? SET : RESET) == Status)
1818 {
1819 /* Check for the Timeout */
1820 if(Timeout != HAL_MAX_DELAY)
1821 {
1822 if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout))
1823 {
1824 /* Disable the USART Transmit Complete Interrupt */
1825 CLEAR_BIT(husart->Instance->CR1, USART_CR1_TXEIE);
1826
1827 /* Disable the USART RXNE Interrupt */
1828 CLEAR_BIT(husart->Instance->CR1, USART_CR1_RXNEIE);
1829
1830 /* Disable the USART Parity Error Interrupt */
1831 CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
1832
1833 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1834 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
1835
1836 husart->State= HAL_USART_STATE_READY;
1837
1838 /* Process Unlocked */
1839 __HAL_UNLOCK(husart);
1840
1841 return HAL_TIMEOUT;
1842 }
1843 }
1844 }
1845 return HAL_OK;
1846 }
1847
1848 /**
1849 * @brief End ongoing Tx transfer on USART peripheral (following error detection or Transmit completion).
1850 * @param husart USART handle.
1851 * @retval None
1852 */
1853 static void USART_EndTxTransfer(USART_HandleTypeDef *husart)
1854 {
1855 /* Disable TXEIE and TCIE interrupts */
1856 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
1857
1858 /* At end of Tx process, restore husart->State to Ready */
1859 husart->State = HAL_USART_STATE_READY;
1860 }
1861
1862 /**
1863 * @brief End ongoing Rx transfer on USART peripheral (following error detection or Reception completion).
1864 * @param husart USART handle.
1865 * @retval None
1866 */
1867 static void USART_EndRxTransfer(USART_HandleTypeDef *husart)
1868 {
1869 /* Disable RXNE, PE and ERR interrupts */
1870 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
1871 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
1872
1873 /* At end of Rx process, restore husart->State to Ready */
1874 husart->State = HAL_USART_STATE_READY;
1875 }
1876
1877 /**
1878 * @brief DMA USART communication abort callback, when initiated by HAL services on Error
1879 * (To be called at end of DMA Abort procedure following error occurrence).
1880 * @param hdma DMA handle.
1881 * @retval None
1882 */
1883 static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
1884 {
1885 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1886 husart->RxXferCount = 0x00U;
1887 husart->TxXferCount = 0x00U;
1888
1889 HAL_USART_ErrorCallback(husart);
1890 }
1891
1892 /**
1893 * @brief DMA USART Tx communication abort callback, when initiated by user
1894 * (To be called at end of DMA Tx Abort procedure following user abort request).
1895 * @note When this callback is executed, User Abort complete call back is called only if no
1896 * Abort still ongoing for Rx DMA Handle.
1897 * @param hdma DMA handle.
1898 * @retval None
1899 */
1900 static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
1901 {
1902 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1903
1904 husart->hdmatx->XferAbortCallback = NULL;
1905
1906 /* Check if an Abort process is still ongoing */
1907 if(husart->hdmarx != NULL)
1908 {
1909 if(husart->hdmarx->XferAbortCallback != NULL)
1910 {
1911 return;
1912 }
1913 }
1914
1915 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
1916 husart->TxXferCount = 0x00U;
1917 husart->RxXferCount = 0x00U;
1918
1919 /* Reset errorCode */
1920 husart->ErrorCode = HAL_USART_ERROR_NONE;
1921
1922 /* Restore husart->State to Ready */
1923 husart->State = HAL_USART_STATE_READY;
1924
1925 /* Call user Abort complete callback */
1926 HAL_USART_AbortCpltCallback(husart);
1927 }
1928
1929 /**
1930 * @brief DMA USART Rx communication abort callback, when initiated by user
1931 * (To be called at end of DMA Rx Abort procedure following user abort request).
1932 * @note When this callback is executed, User Abort complete call back is called only if no
1933 * Abort still ongoing for Tx DMA Handle.
1934 * @param hdma DMA handle.
1935 * @retval None
1936 */
1937 static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
1938 {
1939 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1940
1941 husart->hdmarx->XferAbortCallback = NULL;
1942
1943 /* Check if an Abort process is still ongoing */
1944 if(husart->hdmatx != NULL)
1945 {
1946 if(husart->hdmatx->XferAbortCallback != NULL)
1947 {
1948 return;
1949 }
1950 }
1951
1952 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
1953 husart->TxXferCount = 0x00U;
1954 husart->RxXferCount = 0x00U;
1955
1956 /* Reset errorCode */
1957 husart->ErrorCode = HAL_USART_ERROR_NONE;
1958
1959 /* Restore husart->State to Ready */
1960 husart->State = HAL_USART_STATE_READY;
1961
1962 /* Call user Abort complete callback */
1963 HAL_USART_AbortCpltCallback(husart);
1964 }
1965
1966 /**
1967 * @brief Simplex Send an amount of data in non-blocking mode.
1968 * @param husart pointer to a USART_HandleTypeDef structure that contains
1969 * the configuration information for the specified USART module.
1970 * @retval HAL status
1971 * @note The USART errors are not managed to avoid the overrun error.
1972 */
1973 static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart)
1974 {
1975 uint16_t* tmp;
1976
1977 if(husart->State == HAL_USART_STATE_BUSY_TX)
1978 {
1979 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
1980 {
1981 tmp = (uint16_t*) husart->pTxBuffPtr;
1982 husart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
1983 if(husart->Init.Parity == USART_PARITY_NONE)
1984 {
1985 husart->pTxBuffPtr += 2U;
1986 }
1987 else
1988 {
1989 husart->pTxBuffPtr += 1U;
1990 }
1991 }
1992 else
1993 {
1994 husart->Instance->DR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0x00FF);
1995 }
1996
1997 if(--husart->TxXferCount == 0U)
1998 {
1999 /* Disable the USART Transmit data register empty Interrupt */
2000 CLEAR_BIT(husart->Instance->CR1, USART_CR1_TXEIE);
2001
2002 /* Enable the USART Transmit Complete Interrupt */
2003 SET_BIT(husart->Instance->CR1, USART_CR1_TCIE);
2004 }
2005 return HAL_OK;
2006 }
2007 else
2008 {
2009 return HAL_BUSY;
2010 }
2011 }
2012
2013 /**
2014 * @brief Wraps up transmission in non blocking mode.
2015 * @param husart pointer to a USART_HandleTypeDef structure that contains
2016 * the configuration information for the specified USART module.
2017 * @retval HAL status
2018 */
2019 static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart)
2020 {
2021 /* Disable the USART Transmit Complete Interrupt */
2022 CLEAR_BIT(husart->Instance->CR1, USART_CR1_TCIE);
2023
2024 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
2025 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
2026
2027 husart->State = HAL_USART_STATE_READY;
2028
2029 HAL_USART_TxCpltCallback(husart);
2030
2031 return HAL_OK;
2032 }
2033
2034 /**
2035 * @brief Simplex Receive an amount of data in non-blocking mode.
2036 * @param husart pointer to a USART_HandleTypeDef structure that contains
2037 * the configuration information for the specified USART module.
2038 * @retval HAL status
2039 */
2040 static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart)
2041 {
2042 uint16_t* tmp;
2043 if(husart->State == HAL_USART_STATE_BUSY_RX)
2044 {
2045 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
2046 {
2047 tmp = (uint16_t*) husart->pRxBuffPtr;
2048 if(husart->Init.Parity == USART_PARITY_NONE)
2049 {
2050 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
2051 husart->pRxBuffPtr += 2U;
2052 }
2053 else
2054 {
2055 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
2056 husart->pRxBuffPtr += 1U;
2057 }
2058 if(--husart->RxXferCount != 0x00U)
2059 {
2060 /* Send dummy byte in order to generate the clock for the slave to send the next data */
2061 husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x01FF);
2062 }
2063 }
2064 else
2065 {
2066 if(husart->Init.Parity == USART_PARITY_NONE)
2067 {
2068 *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
2069 }
2070 else
2071 {
2072 *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
2073 }
2074
2075 if(--husart->RxXferCount != 0x00U)
2076 {
2077 /* Send dummy byte in order to generate the clock for the slave to send the next data */
2078 husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x00FF);
2079 }
2080 }
2081
2082 if(husart->RxXferCount == 0U)
2083 {
2084 /* Disable the USART RXNE Interrupt */
2085 CLEAR_BIT(husart->Instance->CR1, USART_CR1_RXNEIE);
2086
2087 /* Disable the USART Parity Error Interrupt */
2088 CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
2089
2090 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
2091 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
2092
2093 husart->State = HAL_USART_STATE_READY;
2094 HAL_USART_RxCpltCallback(husart);
2095
2096 return HAL_OK;
2097 }
2098 return HAL_OK;
2099 }
2100 else
2101 {
2102 return HAL_BUSY;
2103 }
2104 }
2105
2106 /**
2107 * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking).
2108 * @param husart pointer to a USART_HandleTypeDef structure that contains
2109 * the configuration information for the specified USART module.
2110 * @retval HAL status
2111 */
2112 static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart)
2113 {
2114 uint16_t* tmp;
2115
2116 if(husart->State == HAL_USART_STATE_BUSY_TX_RX)
2117 {
2118 if(husart->TxXferCount != 0x00U)
2119 {
2120 if(__HAL_USART_GET_FLAG(husart, USART_FLAG_TXE) != RESET)
2121 {
2122 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
2123 {
2124 tmp = (uint16_t*) husart->pTxBuffPtr;
2125 husart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
2126 if(husart->Init.Parity == USART_PARITY_NONE)
2127 {
2128 husart->pTxBuffPtr += 2U;
2129 }
2130 else
2131 {
2132 husart->pTxBuffPtr += 1U;
2133 }
2134 }
2135 else
2136 {
2137 husart->Instance->DR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0x00FF);
2138 }
2139 husart->TxXferCount--;
2140
2141 /* Check the latest data transmitted */
2142 if(husart->TxXferCount == 0U)
2143 {
2144 CLEAR_BIT(husart->Instance->CR1, USART_CR1_TXEIE);
2145 }
2146 }
2147 }
2148
2149 if(husart->RxXferCount != 0x00U)
2150 {
2151 if(__HAL_USART_GET_FLAG(husart, USART_FLAG_RXNE) != RESET)
2152 {
2153 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
2154 {
2155 tmp = (uint16_t*) husart->pRxBuffPtr;
2156 if(husart->Init.Parity == USART_PARITY_NONE)
2157 {
2158 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
2159 husart->pRxBuffPtr += 2U;
2160 }
2161 else
2162 {
2163 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
2164 husart->pRxBuffPtr += 1U;
2165 }
2166 }
2167 else
2168 {
2169 if(husart->Init.Parity == USART_PARITY_NONE)
2170 {
2171 *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
2172 }
2173 else
2174 {
2175 *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
2176 }
2177 }
2178 husart->RxXferCount--;
2179 }
2180 }
2181
2182 /* Check the latest data received */
2183 if(husart->RxXferCount == 0U)
2184 {
2185 /* Disable the USART RXNE Interrupt */
2186 CLEAR_BIT(husart->Instance->CR1, USART_CR1_RXNEIE);
2187
2188 /* Disable the USART Parity Error Interrupt */
2189 CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
2190
2191 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
2192 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
2193
2194 husart->State = HAL_USART_STATE_READY;
2195
2196 HAL_USART_TxRxCpltCallback(husart);
2197
2198 return HAL_OK;
2199 }
2200
2201 return HAL_OK;
2202 }
2203 else
2204 {
2205 return HAL_BUSY;
2206 }
2207 }
2208
2209 /**
2210 * @brief Configures the USART pferipheral.
2211 * @param husart pointer to a USART_HandleTypeDef structure that contains
2212 * the configuration information for the specified USART module.
2213 * @retval None
2214 */
2215 static void USART_SetConfig(USART_HandleTypeDef *husart)
2216 {
2217 uint32_t tmpreg = 0x00U;
2218
2219 /* Check the parameters */
2220 assert_param(IS_USART_INSTANCE(husart->Instance));
2221 assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity));
2222 assert_param(IS_USART_PHASE(husart->Init.CLKPhase));
2223 assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit));
2224 assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate));
2225 assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength));
2226 assert_param(IS_USART_STOPBITS(husart->Init.StopBits));
2227 assert_param(IS_USART_PARITY(husart->Init.Parity));
2228 assert_param(IS_USART_MODE(husart->Init.Mode));
2229
2230 /* The LBCL, CPOL and CPHA bits have to be selected when both the transmitter and the
2231 receiver are disabled (TE=RE=0) to ensure that the clock pulses function correctly. */
2232 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
2233
2234 /*---------------------------- USART CR2 Configuration ---------------------*/
2235 tmpreg = husart->Instance->CR2;
2236 /* Clear CLKEN, CPOL, CPHA and LBCL bits */
2237 tmpreg &= (uint32_t)~((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP));
2238 /* Configure the USART Clock, CPOL, CPHA and LastBit -----------------------*/
2239 /* Set CPOL bit according to husart->Init.CLKPolarity value */
2240 /* Set CPHA bit according to husart->Init.CLKPhase value */
2241 /* Set LBCL bit according to husart->Init.CLKLastBit value */
2242 /* Set Stop Bits: Set STOP[13:12] bits according to husart->Init.StopBits value */
2243 tmpreg |= (uint32_t)(USART_CLOCK_ENABLE| husart->Init.CLKPolarity |
2244 husart->Init.CLKPhase| husart->Init.CLKLastBit | husart->Init.StopBits);
2245 /* Write to USART CR2 */
2246 WRITE_REG(husart->Instance->CR2, (uint32_t)tmpreg);
2247
2248 /*-------------------------- USART CR1 Configuration -----------------------*/
2249 tmpreg = husart->Instance->CR1;
2250
2251 /* Clear M, PCE, PS, TE, RE and OVER8 bits */
2252 tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | \
2253 USART_CR1_RE | USART_CR1_OVER8));
2254
2255 /* Configure the USART Word Length, Parity and mode:
2256 Set the M bits according to husart->Init.WordLength value
2257 Set PCE and PS bits according to husart->Init.Parity value
2258 Set TE and RE bits according to husart->Init.Mode value
2259 Force OVER8 bit to 1 in order to reach the max USART frequencies */
2260 tmpreg |= (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8;
2261
2262 /* Write to USART CR1 */
2263 WRITE_REG(husart->Instance->CR1, (uint32_t)tmpreg);
2264
2265 /*-------------------------- USART CR3 Configuration -----------------------*/
2266 /* Clear CTSE and RTSE bits */
2267 CLEAR_BIT(husart->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE));
2268
2269 /*-------------------------- USART BRR Configuration -----------------------*/
2270 #if defined(USART6)
2271 if((husart->Instance == USART1) || (husart->Instance == USART6))
2272 {
2273 husart->Instance->BRR = USART_BRR(HAL_RCC_GetPCLK2Freq(), husart->Init.BaudRate);
2274 }
2275 #else
2276 if(husart->Instance == USART1)
2277 {
2278 husart->Instance->BRR = USART_BRR(HAL_RCC_GetPCLK2Freq(), husart->Init.BaudRate);
2279 }
2280 #endif /* USART6 */
2281 else
2282 {
2283 husart->Instance->BRR = USART_BRR(HAL_RCC_GetPCLK1Freq(), husart->Init.BaudRate);
2284 }
2285 }
2286
2287 /**
2288 * @}
2289 */
2290
2291 #endif /* HAL_USART_MODULE_ENABLED */
2292 /**
2293 * @}
2294 */
2295
2296 /**
2297 * @}
2298 */
2299
2300 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/