source: rtems/c/src/lib/libbsp/arm/stm32f7x/hal/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_usart.c @ c20847a5

5
Last change on this file since c20847a5 was c20847a5, checked in by Isaac Gutekunst <isaac.gutekunst@…>, on 09/16/15 at 13:16:02

Add STM32F7 HAL Files

These files originated as:

+ STC32CubeF7 V1.1.0 from http://www.st.com/web/en/catalog/tools/PF261909

  • Property mode set to 100644
File size: 55.3 KB
Line 
1/**
2  ******************************************************************************
3  * @file    stm32f7xx_hal_usart.c
4  * @author  MCD Application Team
5  * @version V1.0.1
6  * @date    25-June-2015
7  * @brief   USART HAL module driver.
8  *          This file provides firmware functions to manage the following
9  *          functionalities of the Universal Synchronous/Asynchronous Receiver Transmitter
10  *          Peripheral (USART).
11  *           + Initialization and de-initialization functions
12  *           + IO operation functions
13  *           + Peripheral Control functions
14  *
15  @verbatim
16  ===============================================================================
17                        ##### How to use this driver #####
18 ===============================================================================
19    [..]
20      The USART HAL driver can be used as follows:
21
22      (#) Declare a USART_HandleTypeDef handle structure.
23      (#) Initialize the USART low level resources by implement the HAL_USART_MspInit ()API:
24          (##) Enable the USARTx interface clock.
25          (##) USART pins configuration:
26            (+++) Enable the clock for the USART GPIOs.
27            (+++) Configure these USART pins as alternate function pull-up.
28          (##) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
29                HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
30            (+++) Configure the USARTx interrupt priority.
31            (+++) Enable the NVIC USART IRQ handle.
32            (+++) The specific USART interrupts (Transmission complete interrupt,
33                  RXNE interrupt and Error Interrupts) will be managed using the macros
34                  __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process.
35          (##) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA()
36               HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
37            (+++) Declare a DMA handle structure for the Tx/Rx stream.
38            (+++) Enable the DMAx interface clock.
39            (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
40            (+++) Configure the DMA Tx/Rx Stream.
41            (+++) Associate the initialized DMA handle to the USART DMA Tx/Rx handle.
42            (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx Stream.
43
44      (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
45          flow control and Mode(Receiver/Transmitter) in the husart Init structure.
46
47      (#) Initialize the USART registers by calling the HAL_USART_Init() API:
48          (++) These API's configures also the low level Hardware (GPIO, CLOCK, CORTEX...etc)
49               by calling the customed HAL_USART_MspInit(&husart) API.
50
51  @endverbatim
52  ******************************************************************************
53  * @attention
54  *
55  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
56  *
57  * Redistribution and use in source and binary forms, with or without modification,
58  * are permitted provided that the following conditions are met:
59  *   1. Redistributions of source code must retain the above copyright notice,
60  *      this list of conditions and the following disclaimer.
61  *   2. Redistributions in binary form must reproduce the above copyright notice,
62  *      this list of conditions and the following disclaimer in the documentation
63  *      and/or other materials provided with the distribution.
64  *   3. Neither the name of STMicroelectronics nor the names of its contributors
65  *      may be used to endorse or promote products derived from this software
66  *      without specific prior written permission.
67  *
68  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
69  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
70  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
71  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
72  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
73  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
74  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
75  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
76  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
77  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
78  *
79  ******************************************************************************
80  */
81
82/* Includes ------------------------------------------------------------------*/
83#include "stm32f7xx_hal.h"
84
85/** @addtogroup STM32F7xx_HAL_Driver
86  * @{
87  */
88
89/** @defgroup USART USART
90  * @brief HAL USART Synchronous module driver
91  * @{
92  */
93
94#ifdef HAL_USART_MODULE_ENABLED
95
96/* Private typedef -----------------------------------------------------------*/
97/* Private define ------------------------------------------------------------*/
98/** @addtogroup USART_Private_Constants
99  * @{
100  */
101#define DUMMY_DATA                             ((uint16_t) 0xFFFF)
102#define TEACK_REACK_TIMEOUT                    ((uint32_t) 1000)
103#define USART_TXDMA_TIMEOUTVALUE            22000
104#define USART_TIMEOUT_VALUE                 22000
105#define USART_CR1_FIELDS  ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
106                                     USART_CR1_TE | USART_CR1_RE  | USART_CR1_OVER8))
107#define USART_CR2_FIELDS       ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | \
108                            USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP))
109/**
110  * @}
111  */
112/* Private macro -------------------------------------------------------------*/
113/* Private variables ---------------------------------------------------------*/
114/* Private function prototypes -----------------------------------------------*/
115/* Private functions ---------------------------------------------------------*/
116/** @addtogroup USART_Private_Functions
117  * @{
118  */
119static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
120static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
121static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
122static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
123static void USART_DMAError(DMA_HandleTypeDef *hdma);
124static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
125static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart);
126static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart);
127static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart);
128static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart);
129static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart);
130static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart);
131/**
132  * @}
133  */
134
135/* Exported functions --------------------------------------------------------*/
136
137/** @defgroup USART_Exported_Functions USART Exported Functions
138  * @{
139  */
140
141/** @defgroup USART_Exported_Functions_Group1 USART Initialization and de-initialization functions
142  *  @brief    Initialization and Configuration functions
143  *
144@verbatim
145 ===============================================================================
146            ##### Initialization and Configuration functions #####
147 ===============================================================================
148    [..]
149    This subsection provides a set of functions allowing to initialize the USART
150    in asynchronous and in synchronous modes.
151      (+) For the asynchronous mode only these parameters can be configured:
152        (++) Baud Rate
153        (++) Word Length
154        (++) Stop Bit
155        (++) Parity: If the parity is enabled, then the MSB bit of the data written
156             in the data register is transmitted but is changed by the parity bit.
157             Depending on the frame length defined by the M1 and M0 bits (7-bit,
158             8-bit or 9-bit), the possible USART frame formats are as listed in the
159             following table:
160
161   (+++) +---------------------------------------------------------------+
162   (+++) | M1M0 bits |  PCE bit  |            USART frame                |
163   (+++) |-----------------------|---------------------------------------|
164   (+++) |     10    |     0     |    | SB | 7-bit data | STB |          |
165   (+++) |-----------|-----------|---------------------------------------|
166   (+++) |     10    |     1     |    | SB | 6-bit data | PB | STB |     |
167   (+++) +---------------------------------------------------------------+
168
169        (++) USART polarity
170        (++) USART phase
171        (++) USART LastBit
172        (++) Receiver/transmitter modes
173
174    [..]
175    The HAL_USART_Init() function follows the USART  synchronous configuration
176    procedure (details for the procedure are available in reference manual).
177
178@endverbatim
179  * @{
180  */
181
182/**
183  * @brief  Initializes the USART mode according to the specified
184  *         parameters in the USART_InitTypeDef and create the associated handle.
185  * @param husart: USART handle
186  * @retval HAL status
187  */
188HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
189{
190  /* Check the USART handle allocation */
191  if(husart == NULL)
192  {
193    return HAL_ERROR;
194  }
195
196  /* Check the parameters */
197  assert_param(IS_USART_INSTANCE(husart->Instance));
198
199  if(husart->State == HAL_USART_STATE_RESET)
200  {
201    /* Allocate lock resource and initialize it */
202    husart->Lock = HAL_UNLOCKED;
203    /* Init the low level hardware : GPIO, CLOCK */
204    HAL_USART_MspInit(husart);
205  }
206
207  husart->State = HAL_USART_STATE_BUSY;
208
209  /* Disable the Peripheral */
210  __HAL_USART_DISABLE(husart);
211
212  /* Set the Usart Communication parameters */
213  if (USART_SetConfig(husart) == HAL_ERROR)
214  {
215    return HAL_ERROR;
216  }
217
218  /* In Synchronous mode, the following bits must be kept cleared:
219  - LINEN bit in the USART_CR2 register
220  - HDSEL, SCEN and IREN bits in the USART_CR3 register.*/
221  husart->Instance->CR2 &= ~USART_CR2_LINEN;
222  husart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
223
224  /* Enable the Peripheral */
225  __HAL_USART_ENABLE(husart);
226
227  /* TEACK and/or REACK to check before moving husart->State to Ready */
228  return (USART_CheckIdleState(husart));
229}
230
231/**
232  * @brief DeInitializes the USART peripheral
233  * @param husart: USART handle
234  * @retval HAL status
235  */
236HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart)
237{
238   /* Check the USART handle allocation */
239  if(husart == NULL)
240  {
241    return HAL_ERROR;
242  }
243
244  /* Check the parameters */
245  assert_param(IS_USART_INSTANCE(husart->Instance));
246
247  husart->State = HAL_USART_STATE_BUSY;
248
249  husart->Instance->CR1 = 0x0;
250  husart->Instance->CR2 = 0x0;
251  husart->Instance->CR3 = 0x0;
252
253  /* DeInit the low level hardware */
254  HAL_USART_MspDeInit(husart);
255
256  husart->ErrorCode = HAL_USART_ERROR_NONE;
257  husart->State = HAL_USART_STATE_RESET;
258
259  /* Process Unlock */
260  __HAL_UNLOCK(husart);
261
262  return HAL_OK;
263}
264
265/**
266  * @brief USART MSP Init
267  * @param husart: USART handle
268  * @retval None
269  */
270 __weak void HAL_USART_MspInit(USART_HandleTypeDef *husart)
271{
272  /* NOTE : This function should not be modified, when the callback is needed,
273            the HAL_USART_MspInit can be implemented in the user file
274   */
275}
276
277/**
278  * @brief USART MSP DeInit
279  * @param husart: USART handle
280  * @retval None
281  */
282 __weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart)
283{
284  /* NOTE : This function should not be modified, when the callback is needed,
285            the HAL_USART_MspDeInit can be implemented in the user file
286   */
287}
288
289/**
290  * @}
291  */
292
293/** @defgroup USART_Exported_Functions_Group2 IO operation functions
294  *  @brief   USART Transmit and Receive functions
295  *
296@verbatim
297 ===============================================================================
298                      ##### IO operation functions #####
299 ===============================================================================
300    This subsection provides a set of functions allowing to manage the USART synchronous
301    data transfers.
302
303    [..] The USART supports master mode only: it cannot receive or send data related to an input
304         clock (SCLK is always an output).
305
306    (#) There are two mode of transfer:
307       (++) Blocking mode: The communication is performed in polling mode.
308            The HAL status of all data processing is returned by the same function
309            after finishing transfer.
310       (++) No-Blocking mode: The communication is performed using Interrupts
311           or DMA, These API's return the HAL status.
312           The end of the data processing will be indicated through the
313           dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
314           using DMA mode.
315           The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() user callbacks
316           will be executed respectively at the end of the transmit or Receive process
317           The HAL_USART_ErrorCallback()user callback will be executed when a communication error is detected
318
319    (#) Blocking mode API's are :
320        (++) HAL_USART_Transmit()in simplex mode
321        (++) HAL_USART_Receive() in full duplex receive only
322        (++) HAL_USART_TransmitReceive() in full duplex mode
323
324    (#) Non-Blocking mode API's with Interrupt are :
325        (++) HAL_USART_Transmit_IT()in simplex mode
326        (++) HAL_USART_Receive_IT() in full duplex receive only
327        (++) HAL_USART_TransmitReceive_IT()in full duplex mode
328        (++) HAL_USART_IRQHandler()
329
330    (#) No-Blocking mode functions with DMA are :
331        (++) HAL_USART_Transmit_DMA()in simplex mode
332        (++) HAL_USART_Receive_DMA() in full duplex receive only
333        (++) HAL_USART_TransmitReceive_DMA() in full duplex mode
334        (++) HAL_USART_DMAPause()
335        (++) HAL_USART_DMAResume()
336        (++) HAL_USART_DMAStop()
337
338    (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
339        (++) HAL_USART_TxCpltCallback()
340        (++) HAL_USART_RxCpltCallback()
341        (++) HAL_USART_TxHalfCpltCallback()
342        (++) HAL_USART_RxHalfCpltCallback()
343        (++) HAL_USART_ErrorCallback()
344        (++) HAL_USART_TxRxCpltCallback()
345
346@endverbatim
347  * @{
348  */
349
350/**
351  * @brief  Simplex Send an amount of data in blocking mode
352  * @param  husart: USART handle
353  * @param pTxData: pointer to data buffer
354  * @param Size: amount of data to be sent
355  * @param Timeout : Timeout duration
356  * @retval HAL status
357  */
358HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout)
359{
360  uint16_t* tmp;
361
362  if(husart->State == HAL_USART_STATE_READY)
363  {
364    if((pTxData == NULL) || (Size == 0))
365    {
366      return  HAL_ERROR;
367    }
368
369    /* Process Locked */
370    __HAL_LOCK(husart);
371
372    husart->ErrorCode = HAL_USART_ERROR_NONE;
373    husart->State = HAL_USART_STATE_BUSY_TX;
374
375    husart->TxXferSize = Size;
376    husart->TxXferCount = Size;
377
378    /* Check the remaining data to be sent */
379    while(husart->TxXferCount > 0)
380    {
381      husart->TxXferCount--;
382      if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK)
383        {
384          return HAL_TIMEOUT;
385        }
386      if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
387      {
388        tmp = (uint16_t*) pTxData;
389        husart->Instance->TDR = (*tmp & (uint16_t)0x01FF);
390        pTxData += 2;
391      }
392      else
393      {
394        husart->Instance->TDR = (*pTxData++ & (uint8_t)0xFF);
395      }
396    }
397
398    if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK)
399    {
400      return HAL_TIMEOUT;
401    }
402
403    husart->State = HAL_USART_STATE_READY;
404
405    /* Process Unlocked */
406    __HAL_UNLOCK(husart);
407
408    return HAL_OK;
409  }
410  else
411  {
412    return HAL_BUSY;
413  }
414}
415
416/**
417  * @brief Receive an amount of data in blocking mode
418  * @note To receive synchronous data, dummy data are simultaneously transmitted
419  * @param husart: USART handle
420  * @param pRxData: pointer to data buffer
421  * @param Size: amount of data to be received
422  * @param Timeout : Timeout duration
423  * @retval HAL status
424  */
425HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
426{
427  uint16_t* tmp;
428  uint16_t uhMask;
429
430  if(husart->State == HAL_USART_STATE_READY)
431  {
432    if((pRxData == NULL) || (Size == 0))
433    {
434      return  HAL_ERROR;
435    }
436    /* Process Locked */
437    __HAL_LOCK(husart);
438
439    husart->ErrorCode = HAL_USART_ERROR_NONE;
440    husart->State = HAL_USART_STATE_BUSY_RX;
441
442    husart->RxXferSize = Size;
443    husart->RxXferCount = Size;
444
445    /* Computation of USART mask to apply to RDR register */
446    __HAL_USART_MASK_COMPUTATION(husart);
447    uhMask = husart->Mask;
448
449    /* as long as data have to be received */
450    while(husart->RxXferCount > 0)
451    {
452      husart->RxXferCount--;
453
454      /* Wait until TC flag is set to send dummy byte in order to generate the
455      * clock for the slave to send data.
456       * Whatever the frame length (7, 8 or 9-bit long), the same dummy value
457       * can be written for all the cases. */
458      if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK)
459      {
460        return HAL_TIMEOUT;
461      }
462      husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x0FF);
463
464      /* Wait for RXNE Flag */
465      if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
466      {
467        return HAL_TIMEOUT;
468      }
469
470      if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
471      {
472        tmp = (uint16_t*) pRxData ;
473        *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
474        pRxData +=2;
475      }
476      else
477      {
478        *pRxData++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
479      }
480    }
481
482    husart->State = HAL_USART_STATE_READY;
483
484    /* Process Unlocked */
485    __HAL_UNLOCK(husart);
486
487    return HAL_OK;
488  }
489  else
490  {
491    return HAL_BUSY;
492  }
493}
494
495/**
496  * @brief Full-Duplex Send and Receive an amount of data in blocking mode
497  * @param husart: USART handle
498  * @param pTxData: pointer to TX data buffer
499  * @param pRxData: pointer to RX data buffer
500  * @param Size: amount of data to be sent (same amount to be received)
501  * @param Timeout : Timeout duration
502  * @retval HAL status
503  */
504HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
505{
506  uint16_t* tmp;
507  uint16_t uhMask;
508
509  if(husart->State == HAL_USART_STATE_READY)
510  {
511    if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
512    {
513      return  HAL_ERROR;
514    }
515    /* Process Locked */
516    __HAL_LOCK(husart);
517
518    husart->ErrorCode = HAL_USART_ERROR_NONE;
519    husart->State = HAL_USART_STATE_BUSY_RX;
520
521    husart->RxXferSize = Size;
522    husart->TxXferSize = Size;
523    husart->TxXferCount = Size;
524    husart->RxXferCount = Size;
525
526    /* Computation of USART mask to apply to RDR register */
527    __HAL_USART_MASK_COMPUTATION(husart);
528    uhMask = husart->Mask;
529
530    /* Check the remain data to be sent */
531    while(husart->TxXferCount > 0)
532    {
533      husart->TxXferCount--;
534      husart->RxXferCount--;
535
536      /* Wait until TC flag is set to send data */
537      if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK)
538      {
539        return HAL_TIMEOUT;
540      }
541      if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
542      {
543        tmp = (uint16_t*) pTxData;
544        husart->Instance->TDR = (*tmp & uhMask);
545        pTxData += 2;
546      }
547      else
548      {
549        husart->Instance->TDR = (*pTxData++ & (uint8_t)uhMask);
550      }
551
552      /* Wait for RXNE Flag */
553      if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
554      {
555        return HAL_TIMEOUT;
556      }
557
558      if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
559      {
560        tmp = (uint16_t*) pRxData ;
561        *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
562        pRxData +=2;
563      }
564      else
565      {
566        *pRxData++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
567      }
568    }
569
570    husart->State = HAL_USART_STATE_READY;
571
572    /* Process Unlocked */
573    __HAL_UNLOCK(husart);
574
575    return HAL_OK;
576  }
577  else
578  {
579    return HAL_BUSY;
580  }
581}
582
583/**
584  * @brief  Send an amount of data in interrupt mode
585  * @param  husart: USART handle
586  * @param pTxData: pointer to data buffer
587  * @param Size: amount of data to be sent
588  * @retval HAL status
589  */
590HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
591{
592  if(husart->State == HAL_USART_STATE_READY)
593  {
594    if((pTxData == NULL ) || (Size == 0))
595    {
596      return HAL_ERROR;
597    }
598
599    /* Process Locked */
600    __HAL_LOCK(husart);
601
602    husart->pTxBuffPtr = pTxData;
603    husart->TxXferSize = Size;
604    husart->TxXferCount = Size;
605
606    husart->ErrorCode = HAL_USART_ERROR_NONE;
607    husart->State = HAL_USART_STATE_BUSY_TX;
608
609    /* The USART Error Interrupts: (Frame error, noise error, overrun error)
610    are not managed by the USART Transmit Process to avoid the overrun interrupt
611    when the usart mode is configured for transmit and receive "USART_MODE_TX_RX"
612    to benefit for the frame error and noise interrupts the usart mode should be
613    configured only for transmit "USART_MODE_TX" */
614
615    /* Process Unlocked */
616    __HAL_UNLOCK(husart);
617
618    /* Enable the USART Transmit Data Register Empty Interrupt */
619    __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
620
621    return HAL_OK;
622  }
623  else
624  {
625    return HAL_BUSY;
626  }
627}
628
629/**
630  * @brief Receive an amount of data in blocking mode
631  *        To receive synchronous data, dummy data are simultaneously transmitted
632  * @param husart: USART handle
633  * @param pRxData: pointer to data buffer
634  * @param Size: amount of data to be received
635  * @retval HAL status
636  */
637HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
638{
639  if(husart->State == HAL_USART_STATE_READY)
640  {
641    if((pRxData == NULL ) || (Size == 0))
642    {
643      return HAL_ERROR;
644    }
645    /* Process Locked */
646    __HAL_LOCK(husart);
647
648    husart->pRxBuffPtr = pRxData;
649    husart->RxXferSize = Size;
650    husart->RxXferCount = Size;
651
652    __HAL_USART_MASK_COMPUTATION(husart);
653
654    husart->ErrorCode = HAL_USART_ERROR_NONE;
655    husart->State = HAL_USART_STATE_BUSY_RX;
656
657    /* Enable the USART Parity Error Interrupt */
658    __HAL_USART_ENABLE_IT(husart, USART_IT_PE);
659
660    /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
661    __HAL_USART_ENABLE_IT(husart, USART_IT_ERR);
662
663    /* Enable the USART Data Register not empty Interrupt */
664    __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE);
665
666    /* Process Unlocked */
667    __HAL_UNLOCK(husart);
668
669
670    /* Send dummy byte in order to generate the clock for the Slave to send the next data */
671    if(husart->Init.WordLength == USART_WORDLENGTH_9B)
672    {
673      husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x01FF);
674    }
675    else
676    {
677      husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x00FF);
678    }
679
680    return HAL_OK;
681  }
682  else
683  {
684    return HAL_BUSY;
685  }
686}
687
688/**
689  * @brief Full-Duplex Send and Receive an amount of data in interrupt mode
690  * @param husart: USART handle
691  * @param pTxData: pointer to TX data buffer
692  * @param pRxData: pointer to RX data buffer
693  * @param Size: amount of data to be sent (same amount to be received)
694  * @retval HAL status
695  */
696HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData,  uint16_t Size)
697{
698
699  if(husart->State == HAL_USART_STATE_READY)
700  {
701    if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
702    {
703      return HAL_ERROR;
704    }
705    /* Process Locked */
706    __HAL_LOCK(husart);
707
708    husart->pRxBuffPtr = pRxData;
709    husart->RxXferSize = Size;
710    husart->RxXferCount = Size;
711    husart->pTxBuffPtr = pTxData;
712    husart->TxXferSize = Size;
713    husart->TxXferCount = Size;
714
715    /* Computation of USART mask to apply to RDR register */
716    __HAL_USART_MASK_COMPUTATION(husart);
717
718    husart->ErrorCode = HAL_USART_ERROR_NONE;
719    husart->State = HAL_USART_STATE_BUSY_TX_RX;
720
721    /* Enable the USART Data Register not empty Interrupt */
722    __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE);
723
724    /* Enable the USART Parity Error Interrupt */
725    __HAL_USART_ENABLE_IT(husart, USART_IT_PE);
726
727    /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
728    __HAL_USART_ENABLE_IT(husart, USART_IT_ERR);
729
730    /* Process Unlocked */
731    __HAL_UNLOCK(husart);
732
733    /* Enable the USART Transmit Data Register Empty Interrupt */
734    __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
735
736    return HAL_OK;
737  }
738  else
739  {
740    return HAL_BUSY;
741  }
742
743}
744
745/**
746  * @brief Send an amount of data in DMA mode
747  * @param husart: USART handle
748  * @param pTxData: pointer to data buffer
749  * @param Size: amount of data to be sent
750  * @retval HAL status
751  */
752HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
753{
754  uint32_t *tmp;
755
756  if(husart->State == HAL_USART_STATE_READY)
757  {
758    if((pTxData == NULL ) || (Size == 0))
759    {
760      return HAL_ERROR;
761    }
762    /* Process Locked */
763    __HAL_LOCK(husart);
764
765    husart->pTxBuffPtr = pTxData;
766    husart->TxXferSize = Size;
767    husart->TxXferCount = Size;
768
769    husart->ErrorCode = HAL_USART_ERROR_NONE;
770    husart->State = HAL_USART_STATE_BUSY_TX;
771
772    /* Set the USART DMA transfer complete callback */
773    husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
774
775    /* Set the USART DMA Half transfer complete callback */
776    husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
777
778    /* Set the DMA error callback */
779    husart->hdmatx->XferErrorCallback = USART_DMAError;
780
781    /* Enable the USART transmit DMA channel */
782    tmp = (uint32_t*)&pTxData;
783    HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size);
784
785
786    /* Clear the TC flag in the SR register by writing 0 to it */
787    __HAL_USART_CLEAR_IT(husart, USART_FLAG_TC);
788
789    /* Enable the DMA transfer for transmit request by setting the DMAT bit
790       in the USART CR3 register */
791    husart->Instance->CR3 |= USART_CR3_DMAT;
792
793    /* Process Unlocked */
794    __HAL_UNLOCK(husart);
795
796    return HAL_OK;
797  }
798  else
799  {
800    return HAL_BUSY;
801  }
802}
803
804/**
805  * @brief Receive an amount of data in DMA mode
806  * @param husart: USART handle
807  * @param pRxData: pointer to data buffer
808  * @param Size: amount of data to be received
809  * @note   When the USART parity is enabled (PCE = 1), the received data contain
810  *         the parity bit (MSB position)
811  * @retval HAL status
812  * @note The USART DMA transmit stream must be configured in order to generate the clock for the slave.
813  */
814HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
815{
816  uint32_t *tmp;
817
818  if(husart->State == HAL_USART_STATE_READY)
819  {
820    if((pRxData == NULL ) || (Size == 0))
821    {
822      return HAL_ERROR;
823    }
824
825    /* Process Locked */
826    __HAL_LOCK(husart);
827
828    husart->pRxBuffPtr = pRxData;
829    husart->RxXferSize = Size;
830    husart->pTxBuffPtr = pRxData;
831    husart->TxXferSize = Size;
832
833    husart->ErrorCode = HAL_USART_ERROR_NONE;
834    husart->State = HAL_USART_STATE_BUSY_RX;
835
836    /* Set the USART DMA Rx transfer complete callback */
837    husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
838
839    /* Set the USART DMA Half transfer complete callback */
840    husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
841
842    /* Set the USART DMA Rx transfer error callback */
843    husart->hdmarx->XferErrorCallback = USART_DMAError;
844
845    /* Enable the USART receive DMA channel */
846    tmp = (uint32_t*)&pRxData;
847    HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t*)tmp, Size);
848
849    /* Enable the USART transmit DMA channel: the transmit stream is used in order
850       to generate in the non-blocking mode the clock to the slave device,
851       this mode isn't a simplex receive mode but a full-duplex receive mode */
852    tmp = (uint32_t*)&pRxData;
853    HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size);
854
855    /* Enable the DMA transfer for the receiver request by setting the DMAR bit
856       in the USART CR3 register */
857    husart->Instance->CR3 |= USART_CR3_DMAR;
858
859    /* Enable the DMA transfer for transmit request by setting the DMAT bit
860       in the USART CR3 register */
861    husart->Instance->CR3 |= USART_CR3_DMAT;
862
863    /* Process Unlocked */
864    __HAL_UNLOCK(husart);
865
866    return HAL_OK;
867  }
868  else
869  {
870    return HAL_BUSY;
871  }
872}
873
874/**
875  * @brief Full-Duplex Transmit Receive an amount of data in non blocking mode
876  * @param husart: USART handle
877  * @param pTxData: pointer to TX data buffer
878  * @param pRxData: pointer to RX data buffer
879  * @param Size: amount of data to be received/sent
880  * @note   When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
881  * @retval HAL status
882  */
883HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
884{
885  uint32_t *tmp;
886
887  if(husart->State == HAL_USART_STATE_READY)
888  {
889    if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
890    {
891      return HAL_ERROR;
892    }
893    /* Process Locked */
894    __HAL_LOCK(husart);
895
896    husart->pRxBuffPtr = pRxData;
897    husart->RxXferSize = Size;
898    husart->pTxBuffPtr = pTxData;
899    husart->TxXferSize = Size;
900
901    husart->ErrorCode = HAL_USART_ERROR_NONE;
902    husart->State = HAL_USART_STATE_BUSY_TX_RX;
903
904    /* Set the USART DMA Rx transfer complete callback */
905    husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
906
907    /* Set the USART DMA Half transfer complete callback */
908    husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
909
910    /* Set the USART DMA Tx transfer complete callback */
911    husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
912
913    /* Set the USART DMA Half transfer complete callback */
914    husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
915
916    /* Set the USART DMA Tx transfer error callback */
917    husart->hdmatx->XferErrorCallback = USART_DMAError;
918
919    /* Set the USART DMA Rx transfer error callback */
920    husart->hdmarx->XferErrorCallback = USART_DMAError;
921
922    /* Enable the USART receive DMA channel */
923    tmp = (uint32_t*)&pRxData;
924    HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t*)tmp, Size);
925
926    /* Enable the USART transmit DMA channel */
927    tmp = (uint32_t*)&pTxData;
928    HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size);
929
930    /* Clear the TC flag in the SR register by writing 0 to it */
931    __HAL_USART_CLEAR_IT(husart, USART_FLAG_TC);
932
933    /* Enable the DMA transfer for the receiver request by setting the DMAR bit
934       in the USART CR3 register */
935    husart->Instance->CR3 |= USART_CR3_DMAR;
936
937    /* Enable the DMA transfer for transmit request by setting the DMAT bit
938       in the USART CR3 register */
939    husart->Instance->CR3 |= USART_CR3_DMAT;
940
941    /* Process Unlocked */
942    __HAL_UNLOCK(husart);
943
944    return HAL_OK;
945  }
946  else
947  {
948    return HAL_BUSY;
949  }
950}
951
952/**
953  * @brief Pauses the DMA Transfer.
954  * @param husart: USART handle
955  * @retval None
956  */
957HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart)
958{
959  /* Process Locked */
960  __HAL_LOCK(husart);
961
962  if(husart->State == HAL_USART_STATE_BUSY_TX)
963  {
964    /* Disable the USART DMA Tx request */
965    husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT);
966  }
967  else if(husart->State == HAL_USART_STATE_BUSY_RX)
968  {
969    /* Disable the USART DMA Rx request */
970    husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR);
971  }
972  else if(husart->State == HAL_USART_STATE_BUSY_TX_RX)
973  {
974    /* Disable the USART DMA Tx request */
975    husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT);
976    /* Disable the USART DMA Rx request */
977    husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR);
978  }
979
980  /* Process Unlocked */
981  __HAL_UNLOCK(husart);
982
983  return HAL_OK;
984}
985
986/**
987  * @brief Resumes the DMA Transfer.
988  * @param husart: USART handle
989  * @retval None
990  */
991HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart)
992{
993  /* Process Locked */
994  __HAL_LOCK(husart);
995
996  if(husart->State == HAL_USART_STATE_BUSY_TX)
997  {
998    /* Enable the USART DMA Tx request */
999    husart->Instance->CR3 |= USART_CR3_DMAT;
1000  }
1001  else if(husart->State == HAL_USART_STATE_BUSY_RX)
1002  {
1003    /* Clear the Overrun flag before resuming the Rx transfer*/
1004    __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF);
1005
1006    /* Enable the USART DMA Rx request */
1007    husart->Instance->CR3 |= USART_CR3_DMAR;
1008  }
1009  else if(husart->State == HAL_USART_STATE_BUSY_TX_RX)
1010  {
1011    /* Clear the Overrun flag before resuming the Rx transfer*/
1012    __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF);
1013
1014    /* Enable the USART DMA Rx request  before the DMA Tx request */
1015    husart->Instance->CR3 |= USART_CR3_DMAR;
1016
1017    /* Enable the USART DMA Tx request */
1018    husart->Instance->CR3 |= USART_CR3_DMAT;
1019  }
1020
1021  /* Process Unlocked */
1022  __HAL_UNLOCK(husart);
1023
1024  return HAL_OK;
1025}
1026
1027/**
1028  * @brief Stops the DMA Transfer.
1029  * @param husart: USART handle
1030  * @retval None
1031  */
1032HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart)
1033{
1034  /* The Lock is not implemented on this API to allow the user application
1035     to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback() /
1036     HAL_USART_TxHalfCpltCallback / HAL_USART_RxHalfCpltCallback:
1037     indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
1038     interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
1039     the stream and the corresponding call back is executed. */
1040
1041  /* Disable the USART Tx/Rx DMA requests */
1042  husart->Instance->CR3 &= ~USART_CR3_DMAT;
1043  husart->Instance->CR3 &= ~USART_CR3_DMAR;
1044
1045  /* Abort the USART DMA tx Stream */
1046  if(husart->hdmatx != NULL)
1047  {
1048    HAL_DMA_Abort(husart->hdmatx);
1049  }
1050  /* Abort the USART DMA rx Stream */
1051  if(husart->hdmarx != NULL)
1052  {
1053    HAL_DMA_Abort(husart->hdmarx);
1054  }
1055
1056  husart->State = HAL_USART_STATE_READY;
1057
1058  return HAL_OK;
1059}
1060
1061/**
1062  * @brief  This function handles USART interrupt request.
1063  * @param  husart: USART handle
1064  * @retval None
1065  */
1066void HAL_USART_IRQHandler(USART_HandleTypeDef *husart)
1067{
1068
1069  /* USART parity error interrupt occurred ------------------------------------*/
1070  if((__HAL_USART_GET_IT(husart, USART_IT_PE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_PE) != RESET))
1071  {
1072    __HAL_USART_CLEAR_IT(husart, USART_CLEAR_PEF);
1073    husart->ErrorCode |= HAL_USART_ERROR_PE;
1074    /* Set the USART state ready to be able to start again the process */
1075    husart->State = HAL_USART_STATE_READY;
1076  }
1077
1078  /* USART frame error interrupt occurred -------------------------------------*/
1079  if((__HAL_USART_GET_IT(husart, USART_IT_FE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET))
1080  {
1081    __HAL_USART_CLEAR_IT(husart, USART_CLEAR_FEF);
1082    husart->ErrorCode |= HAL_USART_ERROR_FE;
1083    /* Set the USART state ready to be able to start again the process */
1084    husart->State = HAL_USART_STATE_READY;
1085  }
1086
1087  /* USART noise error interrupt occurred -------------------------------------*/
1088  if((__HAL_USART_GET_IT(husart, USART_IT_NE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET))
1089  {
1090    __HAL_USART_CLEAR_IT(husart, USART_CLEAR_NEF);
1091    husart->ErrorCode |= HAL_USART_ERROR_NE;
1092    /* Set the USART state ready to be able to start again the process */
1093    husart->State = HAL_USART_STATE_READY;
1094  }
1095
1096  /* USART Over-Run interrupt occurred ----------------------------------------*/
1097  if((__HAL_USART_GET_IT(husart, USART_IT_ORE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET))
1098  {
1099    __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF);
1100    husart->ErrorCode |= HAL_USART_ERROR_ORE;
1101    /* Set the USART state ready to be able to start again the process */
1102    husart->State = HAL_USART_STATE_READY;
1103  }
1104
1105   /* Call USART Error Call back function if need be --------------------------*/
1106  if(husart->ErrorCode != HAL_USART_ERROR_NONE)
1107  {
1108    HAL_USART_ErrorCallback(husart);
1109  }
1110
1111  /* USART in mode Receiver --------------------------------------------------*/
1112  if((__HAL_USART_GET_IT(husart, USART_IT_RXNE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_RXNE) != RESET))
1113  {
1114    if(husart->State == HAL_USART_STATE_BUSY_RX)
1115    {
1116      USART_Receive_IT(husart);
1117    }
1118    else
1119    {
1120      USART_TransmitReceive_IT(husart);
1121    }
1122  }
1123
1124  /* USART in mode Transmitter -----------------------------------------------*/
1125  if((__HAL_USART_GET_IT(husart, USART_IT_TXE) != RESET) &&(__HAL_USART_GET_IT_SOURCE(husart, USART_IT_TXE) != RESET))
1126  {
1127    if(husart->State == HAL_USART_STATE_BUSY_TX)
1128    {
1129      USART_Transmit_IT(husart);
1130    }
1131    else
1132    {
1133      USART_TransmitReceive_IT(husart);
1134    }
1135  }
1136
1137  /* USART in mode Transmitter (transmission end) -----------------------------*/
1138  if((__HAL_USART_GET_IT(husart, USART_IT_TC) != RESET) &&(__HAL_USART_GET_IT_SOURCE(husart, USART_IT_TC) != RESET))
1139  {
1140    USART_EndTransmit_IT(husart);
1141  }
1142
1143}
1144
1145/**
1146  * @brief Tx Transfer completed callbacks
1147  * @param husart: USART handle
1148  * @retval None
1149  */
1150__weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart)
1151{
1152  /* NOTE : This function should not be modified, when the callback is needed,
1153            the HAL_USART_TxCpltCallback can be implemented in the user file
1154   */
1155}
1156
1157/**
1158  * @brief  Tx Half Transfer completed callbacks.
1159  * @param  husart: USART handle
1160  * @retval None
1161  */
1162 __weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart)
1163{
1164  /* NOTE: This function should not be modified, when the callback is needed,
1165           the HAL_USART_TxHalfCpltCallback can be implemented in the user file
1166   */
1167}
1168
1169/**
1170  * @brief  Rx Transfer completed callbacks.
1171  * @param  husart: USART handle
1172  * @retval None
1173  */
1174__weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart)
1175{
1176  /* NOTE: This function should not be modified, when the callback is needed,
1177           the HAL_USART_RxCpltCallback can be implemented in the user file
1178   */
1179}
1180
1181/**
1182  * @brief Rx Half Transfer completed callbacks
1183  * @param husart: usart handle
1184  * @retval None
1185  */
1186__weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart)
1187{
1188  /* NOTE : This function should not be modified, when the callback is needed,
1189            the HAL_USART_RxHalfCpltCallback can be implemented in the user file
1190   */
1191}
1192
1193/**
1194  * @brief Tx/Rx Transfers completed callback for the non-blocking process
1195  * @param husart: USART handle
1196  * @retval None
1197  */
1198__weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart)
1199{
1200  /* NOTE : This function should not be modified, when the callback is needed,
1201            the HAL_USART_TxRxCpltCallback can be implemented in the user file
1202   */
1203}
1204
1205/**
1206  * @brief USART error callbacks
1207  * @param husart: USART handle
1208  * @retval None
1209  */
1210__weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart)
1211{
1212  /* NOTE : This function should not be modified, when the callback is needed,
1213            the HAL_USART_ErrorCallback can be implemented in the user file
1214   */
1215}
1216
1217/**
1218  * @}
1219  */
1220
1221/** @defgroup USART_Exported_Functions_Group3 Peripheral State and Errors functions
1222  *  @brief   USART State and Errors functions
1223  *
1224@verbatim
1225  ==============================================================================
1226                  ##### Peripheral State and Errors functions #####
1227  ==============================================================================
1228  [..]
1229    This subsection provides a set of functions allowing to return the State of
1230    USART communication
1231    process, return Peripheral Errors occurred during communication process
1232     (+) HAL_USART_GetState() API can be helpful to check in run-time the state
1233         of the USART peripheral.
1234     (+) HAL_USART_GetError() check in run-time errors that could be occurred during
1235         communication.
1236@endverbatim
1237  * @{
1238  */
1239
1240/**
1241  * @brief return the USART state
1242  * @param husart: USART handle
1243  * @retval HAL state
1244  */
1245HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart)
1246{
1247  return husart->State;
1248}
1249
1250/**
1251  * @brief  Return the USART error code
1252  * @param  husart : pointer to a USART_HandleTypeDef structure that contains
1253  *              the configuration information for the specified USART.
1254  * @retval USART Error Code
1255  */
1256uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart)
1257{
1258  return husart->ErrorCode;
1259}
1260
1261/**
1262  * @}
1263  */
1264
1265
1266/**
1267  * @brief  Simplex Send an amount of data in non-blocking mode.
1268  * @note   Function called under interruption only, once
1269  *         interruptions have been enabled by HAL_USART_Transmit_IT().
1270  * @param  husart: USART handle
1271  * @retval HAL status
1272  * @note   The USART errors are not managed to avoid the overrun error.
1273  */
1274static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart)
1275{
1276  uint16_t* tmp;
1277
1278  if(husart->State == HAL_USART_STATE_BUSY_TX)
1279  {
1280
1281    if(husart->TxXferCount == 0)
1282    {
1283      /* Disable the USART Transmit Complete Interrupt */
1284      __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
1285
1286      /* Enable the USART Transmit Complete Interrupt */
1287      __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
1288
1289      return HAL_OK;
1290    }
1291    else
1292    {
1293      if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1294      {
1295        tmp = (uint16_t*) husart->pTxBuffPtr;
1296        husart->Instance->TDR = (*tmp & (uint16_t)0x01FF);
1297        husart->pTxBuffPtr += 2;
1298      }
1299      else
1300      {
1301        husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0xFF);
1302      }
1303
1304      husart->TxXferCount--;
1305
1306      return HAL_OK;
1307    }
1308  }
1309  else
1310  {
1311    return HAL_BUSY;
1312  }
1313}
1314
1315/**
1316  * @brief  Wraps up transmission in non-blocking mode.
1317  * @param  husart: pointer to a USART_HandleTypeDef structure that contains
1318  *                the configuration information for the specified USART module.
1319  * @retval HAL status
1320  */
1321static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart)
1322{
1323  /* Disable the USART Transmit Complete Interrupt */
1324  __HAL_USART_DISABLE_IT(husart, USART_IT_TC);
1325
1326  /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1327  __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1328
1329  husart->State = HAL_USART_STATE_READY;
1330
1331  HAL_USART_TxCpltCallback(husart);
1332
1333  return HAL_OK;
1334}
1335
1336/**
1337  * @brief  Simplex Receive an amount of data in non-blocking mode.
1338  *         Function called under interruption only, once
1339  *         interruptions have been enabled by HAL_USART_Receive_IT()
1340  * @param  husart: USART handle
1341  * @retval HAL status
1342  */
1343static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart)
1344{
1345  uint16_t* tmp;
1346  uint16_t uhMask = husart->Mask;
1347
1348  if(husart->State == HAL_USART_STATE_BUSY_RX)
1349  {
1350
1351    if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1352    {
1353      tmp = (uint16_t*) husart->pRxBuffPtr;
1354      *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
1355      husart->pRxBuffPtr += 2;
1356    }
1357    else
1358    {
1359      *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
1360    }
1361      /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
1362      husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x00FF);
1363
1364    if(--husart->RxXferCount == 0)
1365    {
1366      __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
1367
1368      /* Disable the USART Parity Error Interrupt */
1369      __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
1370
1371      /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1372      __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1373
1374      husart->State = HAL_USART_STATE_READY;
1375
1376      HAL_USART_RxCpltCallback(husart);
1377
1378      return HAL_OK;
1379    }
1380
1381    return HAL_OK;
1382  }
1383  else
1384  {
1385    return HAL_BUSY;
1386  }
1387}
1388
1389/**
1390  * @brief  Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking).
1391  *         Function called under interruption only, once
1392  *         interruptions have been enabled by HAL_USART_TransmitReceive_IT()
1393  * @param  husart: USART handle
1394  * @retval HAL status
1395  */
1396static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart)
1397{
1398  uint16_t* tmp;
1399  uint16_t uhMask = husart->Mask;
1400
1401  if(husart->State == HAL_USART_STATE_BUSY_TX_RX)
1402  {
1403    if(husart->TxXferCount != 0x00)
1404    {
1405      if(__HAL_USART_GET_FLAG(husart, USART_FLAG_TXE) != RESET)
1406      {
1407        if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1408        {
1409          tmp = (uint16_t*) husart->pTxBuffPtr;
1410          husart->Instance->TDR = (uint16_t)(*tmp & uhMask);
1411          husart->pTxBuffPtr += 2;
1412        }
1413        else
1414        {
1415          husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)uhMask);
1416        }
1417        husart->TxXferCount--;
1418
1419        /* Check the latest data transmitted */
1420        if(husart->TxXferCount == 0)
1421        {
1422           __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
1423        }
1424      }
1425    }
1426
1427    if(husart->RxXferCount != 0x00)
1428    {
1429      if(__HAL_USART_GET_FLAG(husart, USART_FLAG_RXNE) != RESET)
1430      {
1431        if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1432        {
1433          tmp = (uint16_t*) husart->pRxBuffPtr;
1434          *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
1435          husart->pRxBuffPtr += 2;
1436        }
1437        else
1438        {
1439          *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
1440        }
1441        husart->RxXferCount--;
1442      }
1443    }
1444
1445    /* Check the latest data received */
1446    if(husart->RxXferCount == 0)
1447    {
1448      __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
1449
1450      /* Disable the USART Parity Error Interrupt */
1451      __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
1452
1453      /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1454      __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1455
1456      husart->State = HAL_USART_STATE_READY;
1457
1458      HAL_USART_TxRxCpltCallback(husart);
1459
1460      return HAL_OK;
1461    }
1462
1463    return HAL_OK;
1464  }
1465  else
1466  {
1467    return HAL_BUSY;
1468  }
1469}
1470
1471/**
1472  * @brief  This function handles USART Communication Timeout.
1473  * @param  husart: USART handle
1474  * @param  Flag: specifies the USART flag to check.
1475  * @param  Status: The new Flag status (SET or RESET).
1476  * @param  Timeout: Timeout duration
1477  * @retval HAL status
1478  */
1479static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
1480{
1481  uint32_t tickstart = HAL_GetTick();
1482
1483  /* Wait until flag is set */
1484  if(Status == RESET)
1485  {
1486    while(__HAL_USART_GET_FLAG(husart, Flag) == RESET)
1487    {
1488      /* Check for the Timeout */
1489      if(Timeout != HAL_MAX_DELAY)
1490      {
1491        if((Timeout == 0)||((HAL_GetTick()-tickstart) >=  Timeout))
1492        {
1493          /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1494          __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
1495          __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
1496          __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
1497          __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1498
1499          husart->State= HAL_USART_STATE_READY;
1500
1501          /* Process Unlocked */
1502          __HAL_UNLOCK(husart);
1503
1504          return HAL_TIMEOUT;
1505        }
1506      }
1507    }
1508  }
1509  else
1510  {
1511    while(__HAL_USART_GET_FLAG(husart, Flag) != RESET)
1512    {
1513      /* Check for the Timeout */
1514      if(Timeout != HAL_MAX_DELAY)
1515      {
1516        if((Timeout == 0)||((HAL_GetTick()-tickstart) >=  Timeout))
1517        {
1518          /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1519          __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
1520          __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
1521          __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
1522          __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1523
1524          husart->State= HAL_USART_STATE_READY;
1525
1526          /* Process Unlocked */
1527          __HAL_UNLOCK(husart);
1528
1529          return HAL_TIMEOUT;
1530        }
1531      }
1532    }
1533  }
1534  return HAL_OK;
1535}
1536
1537
1538/**
1539  * @brief DMA USART transmit process complete callback
1540  * @param  hdma: DMA handle
1541  * @retval None
1542  */
1543static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1544{
1545  USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1546
1547  /* DMA Normal mode */
1548  if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
1549  {
1550    husart->TxXferCount = 0;
1551
1552    if(husart->State == HAL_USART_STATE_BUSY_TX)
1553    {
1554      /* Disable the DMA transfer for transmit request by resetting the DMAT bit
1555         in the USART CR3 register */
1556      husart->Instance->CR3 &= ~(USART_CR3_DMAT);
1557
1558      /* Enable the USART Transmit Complete Interrupt */
1559      __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
1560    }
1561  }
1562  /* DMA Circular mode */
1563  else
1564  {
1565    if(husart->State == HAL_USART_STATE_BUSY_TX)
1566    {
1567    HAL_USART_TxCpltCallback(husart);
1568   }
1569 }
1570}
1571
1572
1573/**
1574  * @brief DMA USART transmit process half complete callback
1575  * @param hdma : DMA handle
1576  * @retval None
1577  */
1578static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1579{
1580  USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1581
1582  HAL_USART_TxHalfCpltCallback(husart);
1583}
1584
1585/**
1586  * @brief DMA USART receive process complete callback
1587  * @param  hdma: DMA handle
1588  * @retval None
1589  */
1590static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1591{
1592  USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1593
1594  /* DMA Normal mode */
1595  if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
1596  {
1597    husart->RxXferCount = 0;
1598
1599    /* Disable the DMA RX transfer for the receiver request by resetting the DMAR bit
1600    in USART CR3 register */
1601    husart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAR);
1602    /* similarly, disable the DMA TX transfer that was started to provide the
1603       clock to the slave device */
1604    husart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAT);
1605
1606      if(husart->State == HAL_USART_STATE_BUSY_RX)
1607      {
1608        HAL_USART_RxCpltCallback(husart);
1609      }
1610      /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
1611      else
1612      {
1613        HAL_USART_TxRxCpltCallback(husart);
1614      }
1615    husart->State= HAL_USART_STATE_READY;
1616  }
1617  /* DMA circular mode */
1618  else
1619  {
1620    if(husart->State == HAL_USART_STATE_BUSY_RX)
1621    {
1622      HAL_USART_RxCpltCallback(husart);
1623    }
1624    /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
1625    else
1626    {
1627      HAL_USART_TxRxCpltCallback(husart);
1628    }
1629  }
1630}
1631
1632/**
1633  * @brief DMA USART receive process half complete callback
1634  * @param hdma : DMA handle
1635  * @retval None
1636  */
1637static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1638{
1639  USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1640
1641  HAL_USART_RxHalfCpltCallback(husart);
1642}
1643
1644/**
1645  * @brief DMA USART communication error callback
1646  * @param  hdma: DMA handle
1647  * @retval None
1648  */
1649static void USART_DMAError(DMA_HandleTypeDef *hdma)
1650{
1651  USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1652
1653  husart->RxXferCount = 0;
1654  husart->TxXferCount = 0;
1655  husart->ErrorCode |= HAL_USART_ERROR_DMA;
1656  husart->State= HAL_USART_STATE_READY;
1657
1658  HAL_USART_ErrorCallback(husart);
1659}
1660
1661/**
1662  * @brief Configure the USART peripheral
1663  * @param husart: USART handle
1664  * @retval None
1665  */
1666static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart)
1667{
1668  uint32_t tmpreg      = 0x0;
1669  USART_ClockSourceTypeDef clocksource = USART_CLOCKSOURCE_UNDEFINED;
1670  HAL_StatusTypeDef ret                = HAL_OK;
1671  uint16_t brrtemp                     = 0x0000;
1672  uint16_t usartdiv                    = 0x0000;
1673
1674  /* Check the parameters */
1675  assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity));
1676  assert_param(IS_USART_PHASE(husart->Init.CLKPhase));
1677  assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit));
1678  assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate));
1679  assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength));
1680  assert_param(IS_USART_STOPBITS(husart->Init.StopBits));
1681  assert_param(IS_USART_PARITY(husart->Init.Parity));
1682  assert_param(IS_USART_MODE(husart->Init.Mode));
1683  assert_param(IS_USART_OVERSAMPLING(husart->Init.OverSampling));
1684
1685
1686  /*-------------------------- USART CR1 Configuration -----------------------*/
1687   /* Clear M, PCE, PS, TE and RE bits and configure
1688   *  the USART Word Length, Parity, Mode and OverSampling:
1689   *  set the M bits according to husart->Init.WordLength value
1690   *  set PCE and PS bits according to husart->Init.Parity value
1691   *  set TE and RE bits according to husart->Init.Mode value
1692   *  force OVER8 to 1 to allow to reach the maximum speed (Fclock/8) */
1693  tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8;
1694  MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
1695
1696  /*---------------------------- USART CR2 Configuration ---------------------*/
1697  /* Clear and configure the USART Clock, CPOL, CPHA, LBCL and STOP bits:
1698   * set CPOL bit according to husart->Init.CLKPolarity value
1699   * set CPHA bit according to husart->Init.CLKPhase value
1700   * set LBCL bit according to husart->Init.CLKLastBit value
1701   * set STOP[13:12] bits according to husart->Init.StopBits value */
1702  tmpreg = (uint32_t)(USART_CLOCK_ENABLE);
1703  tmpreg |= ((uint32_t)husart->Init.CLKPolarity | (uint32_t)husart->Init.CLKPhase);
1704  tmpreg |= ((uint32_t)husart->Init.CLKLastBit | (uint32_t)husart->Init.StopBits);
1705  MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg);
1706
1707  /*-------------------------- USART CR3 Configuration -----------------------*/
1708  /* no CR3 register configuration                                            */
1709
1710  /*-------------------------- USART BRR Configuration -----------------------*/
1711  /* BRR is filled-up according to OVER8 bit setting which is forced to 1     */
1712  USART_GETCLOCKSOURCE(husart, clocksource);
1713  switch (clocksource)
1714  {
1715    case USART_CLOCKSOURCE_PCLK1:
1716      usartdiv = (uint16_t)((2*HAL_RCC_GetPCLK1Freq()) / husart->Init.BaudRate);
1717      break;
1718    case USART_CLOCKSOURCE_PCLK2:
1719      usartdiv = (uint16_t)((2*HAL_RCC_GetPCLK2Freq()) / husart->Init.BaudRate);
1720      break;
1721    case USART_CLOCKSOURCE_HSI:
1722      usartdiv = (uint16_t)((2*HSI_VALUE) / husart->Init.BaudRate);
1723      break;
1724    case USART_CLOCKSOURCE_SYSCLK:
1725      usartdiv = (uint16_t)((2*HAL_RCC_GetSysClockFreq()) / husart->Init.BaudRate);
1726      break;
1727    case USART_CLOCKSOURCE_LSE:
1728      usartdiv = (uint16_t)((2*LSE_VALUE) / husart->Init.BaudRate);
1729      break;
1730    case USART_CLOCKSOURCE_UNDEFINED:
1731    default:
1732      ret = HAL_ERROR;
1733      break;
1734  }
1735
1736  brrtemp = usartdiv & 0xFFF0;
1737  brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000F) >> 1U);
1738  husart->Instance->BRR = brrtemp;
1739
1740  return ret;
1741}
1742
1743/**
1744  * @brief Check the USART Idle State
1745  * @param husart: USART handle
1746  * @retval HAL status
1747  */
1748static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart)
1749{
1750   /* Initialize the USART ErrorCode */
1751  husart->ErrorCode = HAL_USART_ERROR_NONE;
1752
1753  /* Check if the Transmitter is enabled */
1754  if((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
1755  {
1756    /* Wait until TEACK flag is set */
1757    if(USART_WaitOnFlagUntilTimeout(husart, USART_ISR_TEACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK)
1758    {
1759      husart->State= HAL_USART_STATE_TIMEOUT;
1760      return HAL_TIMEOUT;
1761    }
1762  }
1763  /* Check if the Receiver is enabled */
1764  if((husart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
1765  {
1766    /* Wait until REACK flag is set */
1767    if(USART_WaitOnFlagUntilTimeout(husart, USART_ISR_REACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK)
1768    {
1769      husart->State= HAL_USART_STATE_TIMEOUT;
1770      return HAL_TIMEOUT;
1771    }
1772  }
1773
1774  /* Initialize the USART state*/
1775  husart->State= HAL_USART_STATE_READY;
1776
1777  /* Process Unlocked */
1778  __HAL_UNLOCK(husart);
1779
1780  return HAL_OK;
1781}
1782
1783/**
1784  * @}
1785  */
1786
1787#endif /* HAL_USART_MODULE_ENABLED */
1788/**
1789  * @}
1790  */
1791
1792/**
1793  * @}
1794  */
1795
1796/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Note: See TracBrowser for help on using the repository browser.