TUKS MCU Introductory course / TUKS-COURSE-2-LED
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32l4xx_hal_usart.c Source File

stm32l4xx_hal_usart.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_hal_usart.c
00004   * @author  MCD Application Team
00005   * @version V1.5.1
00006   * @date    31-May-2016
00007   * @brief   USART HAL module driver.
00008   *          This file provides firmware functions to manage the following
00009   *          functionalities of the Universal Synchronous/Asynchronous Receiver Transmitter
00010   *          Peripheral (USART).
00011   *           + Initialization and de-initialization functions
00012   *           + IO operation functions
00013   *           + Peripheral Control functions
00014   *           + Peripheral State and Error functions
00015   *
00016   @verbatim
00017  ===============================================================================
00018                         ##### How to use this driver #####
00019  ===============================================================================
00020     [..]
00021       The USART HAL driver can be used as follows:
00022 
00023       (#) Declare a USART_HandleTypeDef handle structure (eg. USART_HandleTypeDef husart).
00024       (#) Initialize the USART low level resources by implementing the HAL_USART_MspInit() API:
00025           (++) Enable the USARTx interface clock.
00026           (++) USART pins configuration:
00027             (+++) Enable the clock for the USART GPIOs.
00028             (+++) Configure these USART pins as alternate function pull-up.
00029           (++) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
00030                 HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
00031             (+++) Configure the USARTx interrupt priority.
00032             (+++) Enable the NVIC USART IRQ handle.
00033             (++) USART interrupts handling:
00034               -@@-   The specific USART interrupts (Transmission complete interrupt,
00035                   RXNE interrupt and Error Interrupts) will be managed using the macros
00036                   __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process.
00037           (++) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA()
00038                HAL_USART_Receive_DMA() and HAL_USART_TransmitReceive_DMA() APIs):
00039             (+++) Declare a DMA handle structure for the Tx/Rx channel.
00040             (+++) Enable the DMAx interface clock.
00041             (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
00042             (+++) Configure the DMA Tx/Rx channel.
00043             (+++) Associate the initialized DMA handle to the USART DMA Tx/Rx handle.
00044             (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
00045 
00046       (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
00047           flow control and Mode (Receiver/Transmitter) in the husart handle Init structure.
00048 
00049       (#) Initialize the USART registers by calling the HAL_USART_Init() API:
00050           (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
00051                by calling the customized HAL_USART_MspInit(&husart) API.
00052 
00053     [..]
00054      (@) To configure and enable/disable the USART to wake up the MCU from stop mode, resort to UART API's
00055         HAL_UARTEx_StopModeWakeUpSourceConfig(), HAL_UARTEx_EnableStopMode() and                 
00056         HAL_UARTEx_DisableStopMode() in casting the USART handle to UART type UART_HandleTypeDef.                
00057 
00058   @endverbatim
00059   ******************************************************************************
00060   * @attention
00061   *
00062   * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
00063   *
00064   * Redistribution and use in source and binary forms, with or without modification,
00065   * are permitted provided that the following conditions are met:
00066   *   1. Redistributions of source code must retain the above copyright notice,
00067   *      this list of conditions and the following disclaimer.
00068   *   2. Redistributions in binary form must reproduce the above copyright notice,
00069   *      this list of conditions and the following disclaimer in the documentation
00070   *      and/or other materials provided with the distribution.
00071   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00072   *      may be used to endorse or promote products derived from this software
00073   *      without specific prior written permission.
00074   *
00075   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00076   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00077   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00078   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00079   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00080   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00081   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00082   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00083   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00084   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00085   *
00086   ******************************************************************************
00087   */
00088 
00089 /* Includes ------------------------------------------------------------------*/
00090 #include "stm32l4xx_hal.h"
00091 
00092 /** @addtogroup STM32L4xx_HAL_Driver
00093   * @{
00094   */
00095 
00096 /** @defgroup USART USART
00097   * @brief HAL USART Synchronous module driver
00098   * @{
00099   */
00100 
00101 #ifdef HAL_USART_MODULE_ENABLED
00102 
00103 /* Private typedef -----------------------------------------------------------*/
00104 /* Private define ------------------------------------------------------------*/
00105 /** @defgroup USART_Private_Constants USART Private Constants
00106   * @{
00107   */
00108 #define USART_DUMMY_DATA          ((uint16_t) 0xFFFF)           /*!< USART transmitted dummy data                     */
00109 #define USART_TEACK_REACK_TIMEOUT ((uint32_t) 1000)             /*!< USART TX or RX enable acknowledge time-out value */
00110 #define USART_CR1_FIELDS          ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
00111                                               USART_CR1_TE | USART_CR1_RE  | USART_CR1_OVER8))    /*!< USART CR1 fields of parameters set by USART_SetConfig API */
00112 #define USART_CR2_FIELDS          ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | \
00113                                               USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP)) /*!< USART CR2 fields of parameters set by USART_SetConfig API */
00114 /**
00115   * @}
00116   */
00117 
00118 /* Private macros ------------------------------------------------------------*/
00119 /* Private variables ---------------------------------------------------------*/
00120 /* Private function prototypes -----------------------------------------------*/
00121 /** @addtogroup USART_Private_Functions
00122   * @{
00123   */
00124 static void USART_EndTransfer(USART_HandleTypeDef *husart);
00125 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
00126 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
00127 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
00128 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
00129 static void USART_DMAError(DMA_HandleTypeDef *hdma);
00130 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout);
00131 static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart);
00132 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart);
00133 static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
00134 static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart);
00135 static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart);
00136 static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart);
00137 static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart);
00138 /**
00139   * @}
00140   */
00141 
00142 /* Exported functions --------------------------------------------------------*/
00143 
00144 /** @defgroup USART_Exported_Functions USART Exported Functions
00145   * @{
00146   */
00147 
00148 /** @defgroup USART_Exported_Functions_Group1 Initialization and de-initialization functions
00149   *  @brief    Initialization and Configuration functions
00150   *
00151 @verbatim
00152  ===============================================================================
00153             ##### Initialization and Configuration functions #####
00154  ===============================================================================
00155     [..]
00156     This subsection provides a set of functions allowing to initialize the USART
00157     in asynchronous and in synchronous modes.
00158       (+) For the asynchronous mode only these parameters can be configured:
00159         (++) Baud Rate
00160         (++) Word Length
00161         (++) Stop Bit
00162         (++) Parity: If the parity is enabled, then the MSB bit of the data written
00163              in the data register is transmitted but is changed by the parity bit.
00164         (++) USART polarity
00165         (++) USART phase
00166         (++) USART LastBit
00167         (++) Receiver/transmitter modes
00168 
00169     [..]
00170     The HAL_USART_Init() function follows the USART  synchronous configuration
00171     procedure (details for the procedure are available in reference manual).
00172 
00173 @endverbatim
00174 
00175   Depending on the frame length defined by the M1 and M0 bits (7-bit, 
00176   8-bit or 9-bit), the possible USART formats are listed in the 
00177   following table.
00178   
00179     Table 1. USART frame format.
00180     +-----------------------------------------------------------------------+
00181     |  M1 bit |  M0 bit |  PCE bit  |            USART frame                |
00182     |---------|---------|-----------|---------------------------------------|
00183     |    0    |    0    |    0      |    | SB |    8 bit data   | STB |     |
00184     |---------|---------|-----------|---------------------------------------|
00185     |    0    |    0    |    1      |    | SB | 7 bit data | PB | STB |     |
00186     |---------|---------|-----------|---------------------------------------|
00187     |    0    |    1    |    0      |    | SB |    9 bit data   | STB |     |
00188     |---------|---------|-----------|---------------------------------------|
00189     |    0    |    1    |    1      |    | SB | 8 bit data | PB | STB |     |
00190     |---------|---------|-----------|---------------------------------------|
00191     |    1    |    0    |    0      |    | SB |    7 bit data   | STB |     |
00192     |---------|---------|-----------|---------------------------------------|
00193     |    1    |    0    |    1      |    | SB | 6 bit data | PB | STB |     |
00194     +-----------------------------------------------------------------------+
00195 
00196   * @{
00197   */
00198 
00199 /**
00200   * @brief  Initializes the USART mode according to the specified
00201   *         parameters in the USART_InitTypeDef and initialize the associated handle.
00202   * @param husart: USART handle.
00203   * @retval HAL status
00204   */
00205 HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
00206 {
00207   /* Check the USART handle allocation */
00208   if(husart == NULL)
00209   {
00210     return HAL_ERROR;
00211   }
00212 
00213   /* Check the parameters */
00214   assert_param(IS_USART_INSTANCE(husart->Instance));
00215 
00216   if(husart->State == HAL_USART_STATE_RESET)
00217   {
00218     /* Allocate lock resource and initialize it */
00219     husart->Lock = HAL_UNLOCKED;
00220 
00221     /* Init the low level hardware : GPIO, CLOCK */
00222     HAL_USART_MspInit(husart);
00223   }
00224 
00225   husart->State = HAL_USART_STATE_BUSY;
00226 
00227   /* Disable the Peripheral */
00228   __HAL_USART_DISABLE(husart);
00229 
00230   /* Set the Usart Communication parameters */
00231   if (USART_SetConfig(husart) == HAL_ERROR)
00232   {
00233     return HAL_ERROR;
00234   }
00235 
00236   /* In Synchronous mode, the following bits must be kept cleared:
00237   - LINEN bit in the USART_CR2 register
00238   - HDSEL, SCEN and IREN bits in the USART_CR3 register.*/
00239   husart->Instance->CR2 &= ~USART_CR2_LINEN;
00240   husart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
00241 
00242   /* Enable the Peripheral */
00243   __HAL_USART_ENABLE(husart);
00244 
00245   /* TEACK and/or REACK to check before moving husart->State to Ready */
00246   return (USART_CheckIdleState(husart));
00247 }
00248 
00249 /**
00250   * @brief DeInitialize the USART peripheral.
00251   * @param husart: USART handle.
00252   * @retval HAL status
00253   */
00254 HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart)
00255 {
00256    /* Check the USART handle allocation */
00257   if(husart == NULL)
00258   {
00259     return HAL_ERROR;
00260   }
00261 
00262   /* Check the parameters */
00263   assert_param(IS_USART_INSTANCE(husart->Instance));
00264 
00265   husart->State = HAL_USART_STATE_BUSY;
00266 
00267   husart->Instance->CR1 = 0x0;
00268   husart->Instance->CR2 = 0x0;
00269   husart->Instance->CR3 = 0x0;
00270 
00271   /* DeInit the low level hardware */
00272   HAL_USART_MspDeInit(husart);
00273 
00274   husart->ErrorCode = HAL_USART_ERROR_NONE;
00275   husart->State = HAL_USART_STATE_RESET;
00276 
00277   /* Process Unlock */
00278   __HAL_UNLOCK(husart);
00279 
00280   return HAL_OK;
00281 }
00282 
00283 /**
00284   * @brief Initialize the USART MSP.
00285   * @param husart: USART handle.
00286   * @retval None
00287   */
00288 __weak void HAL_USART_MspInit(USART_HandleTypeDef *husart)
00289 {
00290   /* Prevent unused argument(s) compilation warning */
00291   UNUSED(husart);
00292 
00293   /* NOTE : This function should not be modified, when the callback is needed,
00294             the HAL_USART_MspInit can be implemented in the user file
00295    */
00296 }
00297 
00298 /**
00299   * @brief DeInitialize the USART MSP.
00300   * @param husart: USART handle.
00301   * @retval None
00302   */
00303 __weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart)
00304 {
00305   /* Prevent unused argument(s) compilation warning */
00306   UNUSED(husart);
00307 
00308   /* NOTE : This function should not be modified, when the callback is needed,
00309             the HAL_USART_MspDeInit can be implemented in the user file
00310    */
00311 }
00312 
00313 /**
00314   * @}
00315   */
00316 
00317 /** @defgroup USART_Exported_Functions_Group2 IO operation functions
00318   *  @brief   USART Transmit and Receive functions
00319   *
00320 @verbatim
00321  ===============================================================================
00322                       ##### IO operation functions #####
00323  ===============================================================================
00324     [..] This subsection provides a set of functions allowing to manage the USART synchronous
00325     data transfers.
00326 
00327     [..] The USART supports master mode only: it cannot receive or send data related to an input
00328          clock (SCLK is always an output).
00329 
00330     (#) There are two modes of transfer:
00331        (++) Blocking mode: The communication is performed in polling mode.
00332             The HAL status of all data processing is returned by the same function
00333             after finishing transfer.
00334        (++) No-Blocking mode: The communication is performed using Interrupts
00335            or DMA, These API's return the HAL status.
00336            The end of the data processing will be indicated through the
00337            dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
00338            using DMA mode.
00339            The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() user callbacks
00340            will be executed respectively at the end of the transmit or Receive process
00341            The HAL_USART_ErrorCallback()user callback will be executed when a communication error is detected
00342 
00343     (#) Blocking mode API's are :
00344         (++) HAL_USART_Transmit()in simplex mode
00345         (++) HAL_USART_Receive() in full duplex receive only
00346         (++) HAL_USART_TransmitReceive() in full duplex mode
00347 
00348     (#) Non-Blocking mode API's with Interrupt are :
00349         (++) HAL_USART_Transmit_IT()in simplex mode
00350         (++) HAL_USART_Receive_IT() in full duplex receive only
00351         (++) HAL_USART_TransmitReceive_IT()in full duplex mode
00352         (++) HAL_USART_IRQHandler()
00353 
00354     (#) No-Blocking mode API's  with DMA are :
00355         (++) HAL_USART_Transmit_DMA()in simplex mode
00356         (++) HAL_USART_Receive_DMA() in full duplex receive only
00357         (++) HAL_USART_TransmitReceive_DMA() in full duplex mode
00358         (++) HAL_USART_DMAPause()
00359         (++) HAL_USART_DMAResume()
00360         (++) HAL_USART_DMAStop()
00361 
00362     (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
00363         (++) HAL_USART_TxCpltCallback()
00364         (++) HAL_USART_RxCpltCallback()
00365         (++) HAL_USART_TxHalfCpltCallback()
00366         (++) HAL_USART_RxHalfCpltCallback()
00367         (++) HAL_USART_ErrorCallback()
00368         (++) HAL_USART_TxRxCpltCallback()
00369 
00370     (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
00371         Errors are handled as follows :
00372        (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is 
00373            to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception .
00374            Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type,
00375            and HAL_USART_ErrorCallback() user callback is executed. Transfer is kept ongoing on USART side.
00376        (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
00377            This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
00378            Error code is set to allow user to identify error type, and HAL_USART_ErrorCallback() user callback is executed.
00379 
00380 @endverbatim
00381   * @{
00382   */
00383 
00384 /**
00385   * @brief  Simplex send an amount of data in blocking mode.
00386   * @param  husart USART handle.
00387   * @param  pTxData Pointer to data buffer.
00388   * @param  Size Amount of data to be sent.
00389   * @param  Timeout Timeout duration.
00390   * @retval HAL status
00391   */
00392 HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout)
00393 {
00394   uint16_t* tmp;
00395   uint32_t tickstart = 0;
00396 
00397   if(husart->State == HAL_USART_STATE_READY)
00398   {
00399     if((pTxData == NULL) || (Size == 0))
00400     {
00401       return  HAL_ERROR;
00402     }
00403 
00404     /* Process Locked */
00405     __HAL_LOCK(husart);
00406 
00407     husart->ErrorCode = HAL_USART_ERROR_NONE;
00408     husart->State = HAL_USART_STATE_BUSY_TX;
00409 
00410     /* Init tickstart for timeout managment*/
00411     tickstart = HAL_GetTick();
00412 
00413     husart->TxXferSize = Size;
00414     husart->TxXferCount = Size;
00415 
00416     /* Check the remaining data to be sent */
00417     while(husart->TxXferCount > 0)
00418     {
00419       husart->TxXferCount--;
00420       if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
00421       {
00422         return HAL_TIMEOUT;
00423       }
00424       if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
00425       {
00426         tmp = (uint16_t*) pTxData;
00427         husart->Instance->TDR = (*tmp & (uint16_t)0x01FF);
00428         pTxData += 2;
00429       }
00430       else
00431       {
00432         husart->Instance->TDR = (*pTxData++ & (uint8_t)0xFF);
00433       }
00434     }
00435 
00436     if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
00437     {
00438       return HAL_TIMEOUT;
00439     }
00440 
00441     /* At end of Tx process, restore husart->State to Ready */
00442     husart->State = HAL_USART_STATE_READY;
00443 
00444     /* Process Unlocked */
00445     __HAL_UNLOCK(husart);
00446 
00447     return HAL_OK;
00448   }
00449   else
00450   {
00451     return HAL_BUSY;
00452   }
00453 }
00454 
00455 /**
00456   * @brief Receive an amount of data in blocking mode.
00457   * @note  To receive synchronous data, dummy data are simultaneously transmitted.
00458   * @param husart USART handle.
00459   * @param pRxData Pointer to data buffer.
00460   * @param Size Amount of data to be received.
00461   * @param Timeout Timeout duration.
00462   * @retval HAL status
00463   */
00464 HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
00465 {
00466   uint16_t* tmp;
00467   uint16_t uhMask;
00468   uint32_t tickstart = 0;
00469 
00470   if(husart->State == HAL_USART_STATE_READY)
00471   {
00472     if((pRxData == NULL) || (Size == 0))
00473     {
00474       return  HAL_ERROR;
00475     }
00476 
00477     /* Process Locked */
00478     __HAL_LOCK(husart);
00479 
00480     husart->ErrorCode = HAL_USART_ERROR_NONE;
00481     husart->State = HAL_USART_STATE_BUSY_RX;
00482 
00483     /* Init tickstart for timeout managment*/
00484     tickstart = HAL_GetTick();
00485 
00486     husart->RxXferSize = Size;
00487     husart->RxXferCount = Size;
00488 
00489     /* Computation of USART mask to apply to RDR register */
00490     USART_MASK_COMPUTATION(husart);
00491     uhMask = husart->Mask;
00492 
00493     /* as long as data have to be received */
00494     while(husart->RxXferCount > 0)
00495     {
00496       husart->RxXferCount--;
00497 
00498       /* Wait until TC flag is set to send dummy byte in order to generate the
00499       * clock for the slave to send data.
00500        * Whatever the frame length (7, 8 or 9-bit long), the same dummy value
00501        * can be written for all the cases. */
00502       if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
00503       {
00504         return HAL_TIMEOUT;
00505       }
00506       husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x0FF);
00507 
00508       /* Wait for RXNE Flag */
00509       if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
00510       {
00511         return HAL_TIMEOUT;
00512       }
00513 
00514       if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
00515       {
00516         tmp = (uint16_t*) pRxData ;
00517         *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
00518         pRxData +=2;
00519       }
00520       else
00521       {
00522         *pRxData++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
00523       }
00524     }
00525 
00526     /* At end of Rx process, restore husart->State to Ready */
00527     husart->State = HAL_USART_STATE_READY;
00528 
00529     /* Process Unlocked */
00530     __HAL_UNLOCK(husart);
00531 
00532     return HAL_OK;
00533   }
00534   else
00535   {
00536     return HAL_BUSY;
00537   }
00538 }
00539 
00540 /**
00541   * @brief  Full-Duplex Send and Receive an amount of data in blocking mode.
00542   * @param  husart USART handle.
00543   * @param  pTxData pointer to TX data buffer.
00544   * @param  pRxData pointer to RX data buffer.
00545   * @param  Size amount of data to be sent (same amount to be received).
00546   * @param  Timeout Timeout duration.
00547   * @retval HAL status
00548   */
00549 HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
00550 {
00551   uint16_t* tmp;
00552   uint16_t uhMask;
00553   uint32_t tickstart = 0;
00554 
00555   if(husart->State == HAL_USART_STATE_READY)
00556   {
00557     if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
00558     {
00559       return  HAL_ERROR;
00560     }
00561     /* Process Locked */
00562     __HAL_LOCK(husart);
00563 
00564     husart->ErrorCode = HAL_USART_ERROR_NONE;
00565     husart->State = HAL_USART_STATE_BUSY_RX;
00566 
00567     /* Init tickstart for timeout managment*/
00568     tickstart = HAL_GetTick();
00569 
00570     husart->RxXferSize = Size;
00571     husart->TxXferSize = Size;
00572     husart->TxXferCount = Size;
00573     husart->RxXferCount = Size;
00574 
00575     /* Computation of USART mask to apply to RDR register */
00576     USART_MASK_COMPUTATION(husart);
00577     uhMask = husart->Mask;
00578 
00579     /* Check the remain data to be sent */
00580     while(husart->TxXferCount > 0)
00581     {
00582       husart->TxXferCount--;
00583       husart->RxXferCount--;
00584 
00585       /* Wait until TC flag is set to send data */
00586       if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
00587       {
00588         return HAL_TIMEOUT;
00589       }
00590       if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
00591       {
00592         tmp = (uint16_t*) pTxData;
00593         husart->Instance->TDR = (*tmp & uhMask);
00594         pTxData += 2;
00595       }
00596       else
00597       {
00598         husart->Instance->TDR = (*pTxData++ & (uint8_t)uhMask);
00599       }
00600 
00601       /* Wait for RXNE Flag */
00602       if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
00603       {
00604         return HAL_TIMEOUT;
00605       }
00606 
00607       if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
00608       {
00609         tmp = (uint16_t*) pRxData ;
00610         *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
00611         pRxData +=2;
00612       }
00613       else
00614       {
00615         *pRxData++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
00616       }
00617     }
00618 
00619     /* At end of TxRx process, restore husart->State to Ready */
00620     husart->State = HAL_USART_STATE_READY;
00621 
00622     /* Process Unlocked */
00623     __HAL_UNLOCK(husart);
00624 
00625     return HAL_OK;
00626   }
00627   else
00628   {
00629     return HAL_BUSY;
00630   }
00631 }
00632 
00633 /**
00634   * @brief  Send an amount of data in interrupt mode.
00635   * @param  husart USART handle.
00636   * @param  pTxData pointer to data buffer.
00637   * @param  Size amount of data to be sent.
00638   * @retval HAL status
00639   */
00640 HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
00641 {
00642   if(husart->State == HAL_USART_STATE_READY)
00643   {
00644     if((pTxData == NULL ) || (Size == 0))
00645     {
00646       return HAL_ERROR;
00647     }
00648 
00649     /* Process Locked */
00650     __HAL_LOCK(husart);
00651 
00652     husart->pTxBuffPtr = pTxData;
00653     husart->TxXferSize = Size;
00654     husart->TxXferCount = Size;
00655 
00656     husart->ErrorCode = HAL_USART_ERROR_NONE;
00657     husart->State = HAL_USART_STATE_BUSY_TX;
00658 
00659     /* The USART Error Interrupts: (Frame error, noise error, overrun error)
00660     are not managed by the USART Transmit Process to avoid the overrun interrupt
00661     when the usart mode is configured for transmit and receive "USART_MODE_TX_RX"
00662     to benefit for the frame error and noise interrupts the usart mode should be
00663     configured only for transmit "USART_MODE_TX" */
00664 
00665     /* Process Unlocked */
00666     __HAL_UNLOCK(husart);
00667 
00668     /* Enable the USART Transmit Data Register Empty Interrupt */
00669     __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
00670 
00671     return HAL_OK;
00672   }
00673   else
00674   {
00675     return HAL_BUSY;
00676   }
00677 }
00678 
00679 /**
00680   * @brief  Receive an amount of data in blocking mode.
00681   * @note   To receive synchronous data, dummy data are simultaneously transmitted.
00682   * @param  husart USART handle.
00683   * @param  pRxData pointer to data buffer.
00684   * @param  Size amount of data to be received.
00685   * @retval HAL status
00686   */
00687 HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
00688 {
00689   if(husart->State == HAL_USART_STATE_READY)
00690   {
00691     if((pRxData == NULL ) || (Size == 0))
00692     {
00693       return HAL_ERROR;
00694     }
00695 
00696     /* Process Locked */
00697     __HAL_LOCK(husart);
00698 
00699     husart->pRxBuffPtr = pRxData;
00700     husart->RxXferSize = Size;
00701     husart->RxXferCount = Size;
00702 
00703     USART_MASK_COMPUTATION(husart);
00704 
00705     husart->ErrorCode = HAL_USART_ERROR_NONE;
00706     husart->State = HAL_USART_STATE_BUSY_RX;
00707 
00708     /* Process Unlocked */
00709     __HAL_UNLOCK(husart);
00710 
00711     /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
00712     SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
00713 
00714     /* Enable the USART Parity Error and USART Data Register not empty Interrupts */
00715     SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
00716 
00717     /* Send dummy byte in order to generate the clock for the Slave to send the next data */
00718     if(husart->Init.WordLength == USART_WORDLENGTH_9B)
00719     {
00720       husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x01FF);
00721     }
00722     else
00723     {
00724       husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
00725     }
00726 
00727     return HAL_OK;
00728   }
00729   else
00730   {
00731     return HAL_BUSY;
00732   }
00733 }
00734 
00735 /**
00736   * @brief  Full-Duplex Send and Receive an amount of data in interrupt mode.
00737   * @param  husart USART handle.
00738   * @param  pTxData pointer to TX data buffer.
00739   * @param  pRxData pointer to RX data buffer.                         
00740   * @param  Size amount of data to be sent (same amount to be received).
00741   * @retval HAL status
00742   */
00743 HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData,  uint16_t Size)
00744 {
00745 
00746   if(husart->State == HAL_USART_STATE_READY)
00747   {
00748     if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
00749     {
00750       return HAL_ERROR;
00751     }
00752     /* Process Locked */
00753     __HAL_LOCK(husart);
00754 
00755     husart->pRxBuffPtr = pRxData;
00756     husart->RxXferSize = Size;
00757     husart->RxXferCount = Size;
00758     husart->pTxBuffPtr = pTxData;
00759     husart->TxXferSize = Size;
00760     husart->TxXferCount = Size;
00761 
00762     /* Computation of USART mask to apply to RDR register */
00763     USART_MASK_COMPUTATION(husart);
00764 
00765     husart->ErrorCode = HAL_USART_ERROR_NONE;
00766     husart->State = HAL_USART_STATE_BUSY_TX_RX;
00767 
00768     /* Process Unlocked */
00769     __HAL_UNLOCK(husart);
00770 
00771     /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
00772     SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
00773 
00774     /* Enable the USART Parity Error and USART Data Register not empty Interrupts */
00775     SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
00776 
00777     /* Enable the USART Transmit Data Register Empty Interrupt */
00778     SET_BIT(husart->Instance->CR1, USART_CR1_TXEIE);
00779 
00780     return HAL_OK;
00781   }
00782   else
00783   {
00784     return HAL_BUSY;
00785   }
00786 }
00787 
00788 /**
00789   * @brief  Send an amount of data in DMA mode.
00790   * @param  husart USART handle.
00791   * @param  pTxData pointer to data buffer.
00792   * @param  Size amount of data to be sent.
00793   * @retval HAL status
00794   */
00795 HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
00796 {
00797   uint32_t *tmp;
00798 
00799   if(husart->State == HAL_USART_STATE_READY)
00800   {
00801     if((pTxData == NULL ) || (Size == 0))
00802     {
00803       return HAL_ERROR;
00804     }
00805     /* Process Locked */
00806     __HAL_LOCK(husart);
00807 
00808     husart->pTxBuffPtr = pTxData;
00809     husart->TxXferSize = Size;
00810     husart->TxXferCount = Size;
00811 
00812     husart->ErrorCode = HAL_USART_ERROR_NONE;
00813     husart->State = HAL_USART_STATE_BUSY_TX;
00814 
00815     /* Set the USART DMA transfer complete callback */
00816     husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
00817 
00818     /* Set the USART DMA Half transfer complete callback */
00819     husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
00820 
00821     /* Set the DMA error callback */
00822     husart->hdmatx->XferErrorCallback = USART_DMAError;
00823 
00824     /* Enable the USART transmit DMA channel */
00825     tmp = (uint32_t*)&pTxData;
00826     HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size);
00827 
00828     /* Clear the TC flag in the ICR register */
00829     __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
00830 
00831     /* Process Unlocked */
00832     __HAL_UNLOCK(husart);
00833 
00834     /* Enable the DMA transfer for transmit request by setting the DMAT bit
00835        in the USART CR3 register */
00836     SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
00837 
00838     return HAL_OK;
00839   }
00840   else
00841   {
00842     return HAL_BUSY;
00843   }
00844 }
00845 
00846 /**
00847   * @brief  Receive an amount of data in DMA mode.
00848   * @param  husart USART handle.
00849   * @param  pRxData pointer to data buffer.
00850   * @param  Size amount of data to be received.
00851   * @note   When the USART parity is enabled (PCE = 1), the received data contain
00852   *         the parity bit (MSB position).
00853   * @note   The USART DMA transmit channel must be configured in order to generate the clock for the slave.  
00854   * @retval HAL status
00855   */
00856 HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
00857 {
00858   uint32_t *tmp;
00859 
00860   /* Check that a Rx process is not already ongoing */
00861   if(husart->State == HAL_USART_STATE_READY)
00862   {
00863     if((pRxData == NULL ) || (Size == 0))
00864     {
00865       return HAL_ERROR;
00866     }
00867 
00868     /* Process Locked */
00869     __HAL_LOCK(husart);
00870 
00871     husart->pRxBuffPtr = pRxData;
00872     husart->RxXferSize = Size;
00873     husart->pTxBuffPtr = pRxData;
00874     husart->TxXferSize = Size;
00875 
00876     husart->ErrorCode = HAL_USART_ERROR_NONE;
00877     husart->State = HAL_USART_STATE_BUSY_RX;
00878 
00879     /* Set the USART DMA Rx transfer complete callback */
00880     husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
00881 
00882     /* Set the USART DMA Half transfer complete callback */
00883     husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
00884 
00885     /* Set the USART DMA Rx transfer error callback */
00886     husart->hdmarx->XferErrorCallback = USART_DMAError;
00887 
00888     /* Enable the USART receive DMA channel */
00889     tmp = (uint32_t*)&pRxData;
00890     HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t*)tmp, Size);
00891 
00892     /* Enable the USART transmit DMA channel: the transmit channel is used in order
00893        to generate in the non-blocking mode the clock to the slave device,
00894        this mode isn't a simplex receive mode but a full-duplex receive mode */
00895     tmp = (uint32_t*)&pRxData;
00896     /* Set the USART DMA Tx Complete and Error callback to Null */
00897     husart->hdmatx->XferErrorCallback = NULL;
00898     husart->hdmatx->XferHalfCpltCallback = NULL;
00899     husart->hdmatx->XferCpltCallback = NULL;
00900     HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size);
00901 
00902     /* Process Unlocked */
00903     __HAL_UNLOCK(husart);
00904 
00905     /* Enable the USART Parity Error Interrupt */
00906     SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
00907 
00908     /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
00909     SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
00910 
00911     /* Enable the DMA transfer for the receiver request by setting the DMAR bit
00912        in the USART CR3 register */
00913     SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
00914 
00915     /* Enable the DMA transfer for transmit request by setting the DMAT bit
00916        in the USART CR3 register */
00917     SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
00918 
00919     return HAL_OK;
00920   }
00921   else
00922   {
00923     return HAL_BUSY;
00924   }
00925 }
00926 
00927 /**
00928   * @brief  Full-Duplex Transmit Receive an amount of data in non-blocking mode.
00929   * @param  husart USART handle.
00930   * @param  pTxData pointer to TX data buffer.
00931   * @param  pRxData pointer to RX data buffer.
00932   * @param  Size amount of data to be received/sent.
00933   * @note   When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
00934   * @retval HAL status
00935   */
00936 HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
00937 {
00938   uint32_t *tmp;
00939 
00940   if(husart->State == HAL_USART_STATE_READY)
00941   {
00942     if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
00943     {
00944       return HAL_ERROR;
00945     }
00946     /* Process Locked */
00947     __HAL_LOCK(husart);
00948 
00949     husart->pRxBuffPtr = pRxData;
00950     husart->RxXferSize = Size;
00951     husart->pTxBuffPtr = pTxData;
00952     husart->TxXferSize = Size;
00953 
00954     husart->ErrorCode = HAL_USART_ERROR_NONE;
00955     husart->State = HAL_USART_STATE_BUSY_TX_RX;
00956 
00957     /* Set the USART DMA Rx transfer complete callback */
00958     husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
00959 
00960     /* Set the USART DMA Half transfer complete callback */
00961     husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
00962 
00963     /* Set the USART DMA Tx transfer complete callback */
00964     husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
00965 
00966     /* Set the USART DMA Half transfer complete callback */
00967     husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
00968 
00969     /* Set the USART DMA Tx transfer error callback */
00970     husart->hdmatx->XferErrorCallback = USART_DMAError;
00971 
00972     /* Set the USART DMA Rx transfer error callback */
00973     husart->hdmarx->XferErrorCallback = USART_DMAError;
00974 
00975     /* Enable the USART receive DMA channel */
00976     tmp = (uint32_t*)&pRxData;
00977     HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t*)tmp, Size);
00978 
00979     /* Enable the USART transmit DMA channel */
00980     tmp = (uint32_t*)&pTxData;
00981     HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size);
00982 
00983     /* Process Unlocked */
00984     __HAL_UNLOCK(husart);
00985 
00986     /* Enable the USART Parity Error Interrupt */
00987     SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
00988 
00989     /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
00990     SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
00991 
00992     /* Clear the TC flag in the ICR register */
00993     __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
00994 
00995     /* Enable the DMA transfer for the receiver request by setting the DMAR bit
00996        in the USART CR3 register */
00997     SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
00998 
00999     /* Enable the DMA transfer for transmit request by setting the DMAT bit
01000        in the USART CR3 register */
01001     SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
01002 
01003     return HAL_OK;
01004   }
01005   else
01006   {
01007     return HAL_BUSY;
01008   }
01009 }
01010 
01011 /**
01012   * @brief  Pause the DMA Transfer.
01013   * @param  husart USART handle.
01014   * @retval HAL status
01015   */
01016 HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart)
01017 {
01018   /* Process Locked */
01019   __HAL_LOCK(husart);
01020 
01021   if( (husart->State == HAL_USART_STATE_BUSY_TX) &&
01022       (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)))
01023   {
01024     /* Disable the USART DMA Tx request */
01025     CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
01026   }
01027   else if( (husart->State == HAL_USART_STATE_BUSY_RX) ||
01028            (husart->State == HAL_USART_STATE_BUSY_TX_RX) )
01029   {
01030     if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
01031     {
01032       /* Disable the USART DMA Tx request */
01033       CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
01034     }
01035     if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
01036     {
01037       /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
01038       CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
01039       CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
01040 
01041       /* Disable the USART DMA Rx request */
01042       CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
01043     }
01044   }
01045 
01046   /* Process Unlocked */
01047   __HAL_UNLOCK(husart);
01048 
01049   return HAL_OK;
01050 }
01051 
01052 /**
01053   * @brief  Resume the DMA Transfer.
01054   * @param  husart USART handle.
01055   * @retval HAL status
01056   */
01057 HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart)
01058 {
01059   /* Process Locked */
01060   __HAL_LOCK(husart);
01061 
01062   if(husart->State == HAL_USART_STATE_BUSY_TX)
01063   {
01064     /* Enable the USART DMA Tx request */
01065     SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
01066   }
01067   else if( (husart->State == HAL_USART_STATE_BUSY_RX) ||
01068            (husart->State == HAL_USART_STATE_BUSY_TX_RX) )
01069   {
01070     /* Clear the Overrun flag before resuming the Rx transfer*/
01071     __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF);
01072 
01073     /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */
01074     SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
01075     SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
01076 
01077     /* Enable the USART DMA Rx request  before the DMA Tx request */
01078     SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
01079 
01080     /* Enable the USART DMA Tx request */
01081     SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
01082   }
01083 
01084   /* Process Unlocked */
01085   __HAL_UNLOCK(husart);
01086 
01087   return HAL_OK;
01088 }
01089 
01090 /**
01091   * @brief  Stop the DMA Transfer.
01092   * @param  husart USART handle.
01093   * @retval HAL status
01094   */
01095 HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart)
01096 {
01097   /* The Lock is not implemented on this API to allow the user application
01098      to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback() /
01099      HAL_USART_TxHalfCpltCallback / HAL_USART_RxHalfCpltCallback: 
01100      indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete  
01101      interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of 
01102      the stream and the corresponding call back is executed. */
01103 
01104   /* Disable the USART Tx/Rx DMA requests */
01105   CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
01106   CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
01107 
01108   /* Abort the USART DMA tx channel */
01109   if(husart->hdmatx != NULL)
01110   {
01111     HAL_DMA_Abort(husart->hdmatx);
01112   }
01113   /* Abort the USART DMA rx channel */
01114   if(husart->hdmarx != NULL)
01115   {
01116     HAL_DMA_Abort(husart->hdmarx);
01117   }
01118 
01119   USART_EndTransfer(husart);
01120   husart->State = HAL_USART_STATE_READY;
01121 
01122   return HAL_OK;
01123 }
01124 
01125 /**
01126   * @brief  Handle USART interrupt request.
01127   * @param  husart USART handle.
01128   * @retval None
01129   */
01130 void HAL_USART_IRQHandler(USART_HandleTypeDef *husart)
01131 {
01132   uint32_t isrflags   = READ_REG(husart->Instance->ISR);
01133   uint32_t cr1its     = READ_REG(husart->Instance->CR1);
01134   uint32_t cr3its;
01135   uint32_t errorflags;
01136 
01137   /* If no error occurs */
01138   errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE));
01139   if (errorflags == RESET)
01140   {
01141     /* USART in mode Receiver ---------------------------------------------------*/
01142     if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
01143     {
01144       if(husart->State == HAL_USART_STATE_BUSY_RX)
01145       {
01146         USART_Receive_IT(husart);
01147       }
01148       else
01149       {
01150         USART_TransmitReceive_IT(husart);
01151       }
01152       return;
01153     }
01154   }
01155 
01156   /* If some errors occur */
01157   cr3its = READ_REG(husart->Instance->CR3);
01158   if((errorflags != RESET) && ((cr3its & (USART_CR3_EIE | USART_CR1_PEIE)) != RESET))
01159   {
01160     /* USART parity error interrupt occurred -------------------------------------*/
01161     if(((isrflags & USART_ISR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
01162     {
01163       __HAL_USART_CLEAR_IT(husart, USART_CLEAR_PEF);
01164 
01165       husart->ErrorCode |= HAL_USART_ERROR_PE;
01166     }
01167 
01168     /* USART frame error interrupt occurred --------------------------------------*/
01169     if(((isrflags & USART_ISR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
01170     {
01171       __HAL_USART_CLEAR_IT(husart, USART_CLEAR_FEF);
01172 
01173       husart->ErrorCode |= HAL_USART_ERROR_FE;
01174     }
01175 
01176     /* USART noise error interrupt occurred --------------------------------------*/
01177     if(((isrflags & USART_ISR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
01178     {
01179       __HAL_USART_CLEAR_IT(husart, USART_CLEAR_NEF);
01180 
01181       husart->ErrorCode |= HAL_USART_ERROR_NE;
01182     }
01183 
01184     /* USART Over-Run interrupt occurred -----------------------------------------*/
01185     if(((isrflags & USART_ISR_ORE) != RESET) &&
01186        (((cr1its & USART_CR1_RXNEIE) != RESET) || ((cr3its & USART_CR3_EIE) != RESET)))
01187     {
01188       __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF);
01189 
01190       husart->ErrorCode |= HAL_USART_ERROR_ORE;
01191     }
01192 
01193     /* Call USART Error Call back function if need be --------------------------*/
01194     if(husart->ErrorCode != HAL_USART_ERROR_NONE)
01195     {
01196       /* USART in mode Receiver ---------------------------------------------------*/
01197       if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
01198       {
01199         if(husart->State == HAL_USART_STATE_BUSY_RX)
01200         {
01201           USART_Receive_IT(husart);
01202         }
01203         else
01204         {
01205           USART_TransmitReceive_IT(husart);
01206         }
01207       }
01208 
01209       /* If Overrun error occurs, or if any error occurs in DMA mode reception,
01210          consider error as blocking */
01211       if (((husart->ErrorCode & HAL_USART_ERROR_ORE) != RESET) ||
01212           (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)))
01213       {  
01214         /* Blocking error : transfer is aborted
01215            Set the USART state ready to be able to start again the process,
01216            Disable Interrupts, and disable DMA requests, if ongoing */
01217         USART_EndTransfer(husart);
01218 
01219         /* Disable the USART DMA Rx request if enabled */
01220         if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
01221         {
01222           CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR | USART_CR3_DMAR);
01223 
01224           /* Abort the USART DMA Tx channel */
01225           if(husart->hdmatx != NULL)
01226           {
01227             /* Set the USART Tx DMA Abort callback to NULL : no callback
01228                executed at end of DMA abort procedure */
01229             husart->hdmatx->XferAbortCallback = NULL;
01230             
01231             /* Abort DMA TX */
01232             HAL_DMA_Abort_IT(husart->hdmatx);
01233           }
01234 
01235           /* Abort the USART DMA Rx channel */
01236           if(husart->hdmarx != NULL)
01237           {
01238             /* Set the USART Rx DMA Abort callback : 
01239                will lead to call HAL_USART_ErrorCallback() at end of DMA abort procedure */
01240             husart->hdmarx->XferAbortCallback = USART_DMAAbortOnError;
01241 
01242             /* Abort DMA RX */
01243             if(HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
01244             {
01245               /* Call Directly husart->hdmarx->XferAbortCallback function in case of error */
01246               husart->hdmarx->XferAbortCallback(husart->hdmarx);
01247             }
01248           }
01249           else
01250           {
01251             /* Call user error callback */
01252             HAL_USART_ErrorCallback(husart);
01253           }
01254         }
01255         else
01256         {
01257           /* Call user error callback */
01258           HAL_USART_ErrorCallback(husart);
01259         }
01260       }
01261       else
01262       {
01263         /* Non Blocking error : transfer could go on. 
01264            Error is notified to user through user error callback */
01265         HAL_USART_ErrorCallback(husart);
01266         husart->ErrorCode = HAL_USART_ERROR_NONE;
01267       }
01268     }
01269     return;
01270 
01271   } /* End if some error occurs */
01272 
01273 
01274   /* USART in mode Transmitter ------------------------------------------------*/
01275   if(((isrflags & USART_ISR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
01276   {
01277     if(husart->State == HAL_USART_STATE_BUSY_TX)
01278     {
01279       USART_Transmit_IT(husart);
01280     }
01281     else
01282     {
01283       USART_TransmitReceive_IT(husart);
01284     }
01285     return;
01286   }
01287 
01288   /* USART in mode Transmitter (transmission end) -----------------------------*/
01289   if(((isrflags & USART_ISR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
01290   {
01291     USART_EndTransmit_IT(husart);
01292     return;
01293   }
01294 
01295 }
01296 
01297 /**
01298   * @brief Tx Transfer completed callback.
01299   * @param husart: USART handle.
01300   * @retval None
01301   */
01302 __weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart)
01303 {
01304   /* Prevent unused argument(s) compilation warning */
01305   UNUSED(husart);
01306 
01307   /* NOTE : This function should not be modified, when the callback is needed,
01308             the HAL_USART_TxCpltCallback can be implemented in the user file.
01309    */
01310 }
01311 
01312 /**
01313   * @brief  Tx Half Transfer completed callback.
01314   * @param husart: USART handle.
01315   * @retval None
01316   */
01317 __weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart)
01318 {
01319   /* Prevent unused argument(s) compilation warning */
01320   UNUSED(husart);
01321 
01322   /* NOTE: This function should not be modified, when the callback is needed,
01323            the HAL_USART_TxHalfCpltCallback can be implemented in the user file.
01324    */
01325 }
01326 
01327 /**
01328   * @brief  Rx Transfer completed callback.
01329   * @param husart: USART handle.
01330   * @retval None
01331   */
01332 __weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart)
01333 {
01334   /* Prevent unused argument(s) compilation warning */
01335   UNUSED(husart);
01336 
01337   /* NOTE: This function should not be modified, when the callback is needed,
01338            the HAL_USART_RxCpltCallback can be implemented in the user file.
01339    */
01340 }
01341 
01342 /**
01343   * @brief Rx Half Transfer completed callback.
01344   * @param husart: USART handle.
01345   * @retval None
01346   */
01347 __weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart)
01348 {
01349   /* Prevent unused argument(s) compilation warning */
01350   UNUSED(husart);
01351 
01352   /* NOTE : This function should not be modified, when the callback is needed,
01353             the HAL_USART_RxHalfCpltCallback can be implemented in the user file
01354    */
01355 }
01356 
01357 /**
01358   * @brief Tx/Rx Transfers completed callback for the non-blocking process.
01359   * @param husart: USART handle.
01360   * @retval None
01361   */
01362 __weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart)
01363 {
01364   /* Prevent unused argument(s) compilation warning */
01365   UNUSED(husart);
01366 
01367   /* NOTE : This function should not be modified, when the callback is needed,
01368             the HAL_USART_TxRxCpltCallback can be implemented in the user file
01369    */
01370 }
01371 
01372 /**
01373   * @brief USART error callback.
01374   * @param husart: USART handle.
01375   * @retval None
01376   */
01377 __weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart)
01378 {
01379   /* Prevent unused argument(s) compilation warning */
01380   UNUSED(husart);
01381 
01382   /* NOTE : This function should not be modified, when the callback is needed,
01383             the HAL_USART_ErrorCallback can be implemented in the user file.
01384    */
01385 }
01386 
01387 /**
01388   * @}
01389   */
01390 
01391 /** @defgroup USART_Exported_Functions_Group4 Peripheral State and Error functions
01392  *  @brief   USART Peripheral State and Error functions
01393  *
01394 @verbatim
01395   ==============================================================================
01396             ##### Peripheral State and Error functions #####
01397   ==============================================================================
01398     [..]
01399     This subsection provides functions allowing to :
01400       (+) Return the USART handle state
01401       (+) Return the USART handle error code
01402 
01403 @endverbatim
01404   * @{
01405   */
01406 
01407 
01408 /**
01409   * @brief Return the USART handle state.
01410   * @param husart : pointer to a USART_HandleTypeDef structure that contains
01411   *              the configuration information for the specified USART.
01412   * @retval USART handle state
01413   */
01414 HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart)
01415 {
01416   return husart->State;
01417 }
01418 
01419 /**
01420   * @brief Return the USART error code.
01421   * @param husart : pointer to a USART_HandleTypeDef structure that contains
01422   *              the configuration information for the specified USART.
01423   * @retval USART handle Error Code
01424   */
01425 uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart)
01426 {
01427   return husart->ErrorCode;
01428 }
01429 
01430 /**
01431   * @}
01432   */
01433 
01434 /**
01435   * @}
01436   */
01437 
01438 /** @defgroup USART_Private_Functions USART Private Functions
01439  * @{
01440  */
01441 
01442 /**
01443   * @brief  End ongoing transfer on USART peripheral (following error detection or Transfer completion).
01444   * @param  husart USART handle.
01445   * @retval None
01446   */
01447 static void USART_EndTransfer(USART_HandleTypeDef *husart)
01448 {
01449   /* Disable TXEIE and TCIE interrupts */
01450   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
01451   CLEAR_BIT(husart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE | USART_CR1_RXNEIE | USART_CR1_PEIE));
01452   CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
01453 
01454   /* At end of process, restore husart->State to Ready */
01455   husart->State = HAL_USART_STATE_READY;
01456 }
01457 
01458 /**
01459   * @brief  DMA USART transmit process complete callback.
01460   * @param  hdma DMA handle.
01461   * @retval None
01462   */
01463 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
01464 {
01465   USART_HandleTypeDef* husart = (USART_HandleTypeDef*)(hdma->Parent);
01466 
01467   /* DMA Normal mode */
01468   if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
01469   {
01470     husart->TxXferCount = 0;
01471 
01472     if(husart->State == HAL_USART_STATE_BUSY_TX)
01473     {
01474       /* Disable the DMA transfer for transmit request by resetting the DMAT bit
01475          in the USART CR3 register */
01476       CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
01477 
01478       /* Enable the USART Transmit Complete Interrupt */
01479       __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
01480     }
01481   }
01482   /* DMA Circular mode */
01483   else
01484   {
01485     if(husart->State == HAL_USART_STATE_BUSY_TX)
01486     {
01487     HAL_USART_TxCpltCallback(husart);
01488    }
01489  }
01490 }
01491 
01492 /**
01493   * @brief  DMA USART transmit process half complete callback.
01494   * @param  hdma DMA handle.
01495   * @retval None
01496   */
01497 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
01498 {
01499   USART_HandleTypeDef* husart = (USART_HandleTypeDef*)(hdma->Parent);
01500 
01501   HAL_USART_TxHalfCpltCallback(husart);
01502 }
01503 
01504 /**
01505   * @brief  DMA USART receive process complete callback.
01506   * @param  hdma DMA handle.
01507   * @retval None
01508   */
01509 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
01510 {
01511   USART_HandleTypeDef* husart = (USART_HandleTypeDef*)(hdma->Parent);
01512 
01513   /* DMA Normal mode */
01514   if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
01515   {
01516     husart->RxXferCount = 0;
01517 
01518     /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
01519     CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
01520     CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
01521 
01522     /* Disable the DMA RX transfer for the receiver request by resetting the DMAR bit
01523        in USART CR3 register */
01524     CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
01525     /* similarly, disable the DMA TX transfer that was started to provide the
01526        clock to the slave device */
01527     CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
01528 
01529     if(husart->State == HAL_USART_STATE_BUSY_RX)
01530     {
01531       HAL_USART_RxCpltCallback(husart);
01532     }
01533     /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
01534     else
01535     {
01536       HAL_USART_TxRxCpltCallback(husart);
01537     }
01538     husart->State= HAL_USART_STATE_READY;
01539   }
01540   /* DMA circular mode */
01541   else
01542   {
01543     if(husart->State == HAL_USART_STATE_BUSY_RX)
01544     {
01545       HAL_USART_RxCpltCallback(husart);
01546     }
01547     /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
01548     else
01549     {
01550       HAL_USART_TxRxCpltCallback(husart);
01551     }
01552   }    
01553 
01554 }
01555 
01556 /**
01557   * @brief  DMA USART receive process half complete callback.
01558   * @param  hdma DMA handle.
01559   * @retval None
01560   */
01561 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
01562 {
01563   USART_HandleTypeDef* husart = (USART_HandleTypeDef*)(hdma->Parent);
01564 
01565   HAL_USART_RxHalfCpltCallback(husart);
01566 }
01567 
01568 /**
01569   * @brief DMA USART communication error callback.
01570   * @param  hdma: DMA handle.
01571   * @retval None
01572   */
01573 static void USART_DMAError(DMA_HandleTypeDef *hdma)
01574 {
01575   USART_HandleTypeDef* husart = (USART_HandleTypeDef*)(hdma->Parent);
01576 
01577   husart->RxXferCount = 0;
01578   husart->TxXferCount = 0;
01579   USART_EndTransfer(husart);
01580 
01581   husart->ErrorCode |= HAL_USART_ERROR_DMA;
01582   husart->State= HAL_USART_STATE_READY;
01583 
01584   HAL_USART_ErrorCallback(husart);
01585 }
01586 
01587 /**
01588   * @brief  DMA USART communication abort callback, when initiated by HAL services on Error
01589   *         (To be called at end of DMA Abort procedure following error occurrence).
01590   * @param  hdma DMA handle.
01591   * @retval None
01592   */
01593 static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
01594 {
01595   USART_HandleTypeDef* husart = (USART_HandleTypeDef*)(hdma->Parent);
01596   husart->RxXferCount = 0;
01597   husart->TxXferCount = 0;
01598 
01599   HAL_USART_ErrorCallback(husart);
01600 }
01601 
01602 /**
01603   * @brief  Handle USART Communication Timeout.
01604   * @param  husart USART handle.
01605   * @param  Flag Specifies the USART flag to check.
01606   * @param  Status the Flag status (SET or RESET).
01607   * @param  Tickstart Tick start value
01608   * @param  Timeout timeout duration.
01609   * @retval HAL status
01610   */
01611 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
01612 {
01613   /* Wait until flag is set */
01614   while((__HAL_USART_GET_FLAG(husart, Flag) ? SET : RESET) == Status)
01615   {
01616     /* Check for the Timeout */
01617     if(Timeout != HAL_MAX_DELAY)
01618     {
01619       if((Timeout == 0) || ((HAL_GetTick()-Tickstart) > Timeout))
01620       {
01621         /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
01622         CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
01623         CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
01624 
01625         husart->State= HAL_USART_STATE_READY;
01626 
01627         /* Process Unlocked */
01628         __HAL_UNLOCK(husart);
01629 
01630         return HAL_TIMEOUT;
01631       }
01632     }
01633   }
01634   return HAL_OK;
01635 }
01636 
01637 /**
01638   * @brief Configure the USART peripheral.
01639   * @param husart: USART handle.
01640   * @retval HAL status
01641   */
01642 static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart)
01643 {
01644   uint32_t tmpreg                      = 0x0;
01645   USART_ClockSourceTypeDef clocksource = USART_CLOCKSOURCE_UNDEFINED;
01646   HAL_StatusTypeDef ret                = HAL_OK;
01647   uint16_t brrtemp                     = 0x0000;
01648   uint16_t usartdiv                    = 0x0000;  
01649 
01650   /* Check the parameters */
01651   assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity));
01652   assert_param(IS_USART_PHASE(husart->Init.CLKPhase));
01653   assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit));
01654   assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate));
01655   assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength));
01656   assert_param(IS_USART_STOPBITS(husart->Init.StopBits));
01657   assert_param(IS_USART_PARITY(husart->Init.Parity));
01658   assert_param(IS_USART_MODE(husart->Init.Mode));
01659 
01660 
01661   /*-------------------------- USART CR1 Configuration -----------------------*/
01662    /* Clear M, PCE, PS, TE and RE bits and configure
01663    *  the USART Word Length, Parity and Mode:
01664    *  set the M bits according to husart->Init.WordLength value
01665    *  set PCE and PS bits according to husart->Init.Parity value
01666    *  set TE and RE bits according to husart->Init.Mode value 
01667    *  force OVER8 to 1 to allow to reach the maximum speed (Fclock/8)  */
01668   tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8;
01669   MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
01670 
01671   /*---------------------------- USART CR2 Configuration ---------------------*/
01672   /* Clear and configure the USART Clock, CPOL, CPHA, LBCL and STOP bits:
01673    * set CPOL bit according to husart->Init.CLKPolarity value
01674    * set CPHA bit according to husart->Init.CLKPhase value
01675    * set LBCL bit according to husart->Init.CLKLastBit value
01676    * set STOP[13:12] bits according to husart->Init.StopBits value */
01677   tmpreg = (uint32_t)(USART_CLOCK_ENABLE);
01678   tmpreg |= ((uint32_t)husart->Init.CLKPolarity | (uint32_t)husart->Init.CLKPhase);
01679   tmpreg |= ((uint32_t)husart->Init.CLKLastBit | (uint32_t)husart->Init.StopBits);
01680   MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg);
01681 
01682   /*-------------------------- USART CR3 Configuration -----------------------*/
01683   /* no CR3 register configuration                                            */
01684 
01685   /*-------------------------- USART BRR Configuration -----------------------*/
01686   /* BRR is filled-up according to OVER8 bit setting which is forced to 1     */ 
01687   USART_GETCLOCKSOURCE(husart, clocksource);
01688   switch (clocksource)
01689   {
01690     case USART_CLOCKSOURCE_PCLK1:
01691       usartdiv = (uint16_t)(((2*HAL_RCC_GetPCLK1Freq()) + (husart->Init.BaudRate/2)) / husart->Init.BaudRate);
01692       break;
01693     case USART_CLOCKSOURCE_PCLK2:
01694       usartdiv = (uint16_t)(((2*HAL_RCC_GetPCLK2Freq()) + (husart->Init.BaudRate/2)) / husart->Init.BaudRate);
01695       break;
01696     case USART_CLOCKSOURCE_HSI:
01697       usartdiv = (uint16_t)(((2*HSI_VALUE) + (husart->Init.BaudRate/2)) / husart->Init.BaudRate);
01698       break;
01699     case USART_CLOCKSOURCE_SYSCLK:
01700       usartdiv = (uint16_t)(((2*HAL_RCC_GetSysClockFreq()) + (husart->Init.BaudRate/2)) / husart->Init.BaudRate);
01701       break;
01702     case USART_CLOCKSOURCE_LSE:
01703       usartdiv = (uint16_t)(((2*LSE_VALUE) + (husart->Init.BaudRate/2)) / husart->Init.BaudRate);
01704       break;
01705     case USART_CLOCKSOURCE_UNDEFINED:
01706     default:
01707       ret = HAL_ERROR;
01708       break;
01709   }
01710   
01711   brrtemp = usartdiv & 0xFFF0;
01712   brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000F) >> 1U);
01713   husart->Instance->BRR = brrtemp;
01714 
01715   return ret;
01716 }
01717 
01718 /**
01719   * @brief Check the USART Idle State.
01720   * @param husart: USART handle.
01721   * @retval HAL status
01722   */
01723 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart)
01724 {
01725   uint32_t tickstart = 0;
01726 
01727   /* Initialize the USART ErrorCode */
01728   husart->ErrorCode = HAL_USART_ERROR_NONE;
01729 
01730   /* Init tickstart for timeout managment*/
01731   tickstart = HAL_GetTick();
01732 
01733   /* Check if the Transmitter is enabled */
01734   if((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
01735   {
01736     /* Wait until TEACK flag is set */
01737     if(USART_WaitOnFlagUntilTimeout(husart, USART_ISR_TEACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK)
01738     {
01739       /* Timeout occurred */
01740       return HAL_TIMEOUT;
01741     }
01742   }
01743   /* Check if the Receiver is enabled */
01744   if((husart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
01745   {
01746     /* Wait until REACK flag is set */
01747     if(USART_WaitOnFlagUntilTimeout(husart, USART_ISR_REACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK)
01748     {
01749       /* Timeout occurred */
01750       return HAL_TIMEOUT;
01751     }
01752   }
01753 
01754   /* Initialize the USART state*/
01755   husart->State= HAL_USART_STATE_READY;
01756 
01757   /* Process Unlocked */
01758   __HAL_UNLOCK(husart);
01759 
01760   return HAL_OK;
01761 }
01762 
01763 /**
01764   * @brief  Simplex send an amount of data in non-blocking mode.
01765   * @note   Function called under interruption only, once
01766   *         interruptions have been enabled by HAL_USART_Transmit_IT().
01767   * @note   The USART errors are not managed to avoid the overrun error.
01768   * @param  husart USART handle.
01769   * @retval HAL status
01770   */
01771 static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart)
01772 {
01773   uint16_t* tmp;
01774 
01775   /* Check that a Tx process is ongoing */
01776   if(husart->State == HAL_USART_STATE_BUSY_TX)
01777   {
01778 
01779     if(husart->TxXferCount == 0)
01780     {
01781       /* Disable the USART Transmit data register empty interrupt */
01782       __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
01783 
01784       /* Enable the USART Transmit Complete Interrupt */
01785       __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
01786 
01787       return HAL_OK;
01788     }
01789     else
01790     {
01791       if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
01792       {
01793         tmp = (uint16_t*) husart->pTxBuffPtr;
01794         husart->Instance->TDR = (*tmp & (uint16_t)0x01FF);
01795         husart->pTxBuffPtr += 2;
01796       }
01797       else
01798       {
01799         husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0xFF);
01800       }
01801 
01802       husart->TxXferCount--;
01803 
01804       return HAL_OK;
01805     }
01806   }
01807   else
01808   {
01809     return HAL_BUSY;
01810   }
01811 }
01812 
01813 
01814 /**
01815   * @brief  Wraps up transmission in non-blocking mode.
01816   * @param  husart Pointer to a USART_HandleTypeDef structure that contains
01817   *                the configuration information for the specified USART module.
01818   * @retval HAL status
01819   */
01820 static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart)
01821 {
01822   /* Disable the USART Transmit Complete Interrupt */
01823   __HAL_USART_DISABLE_IT(husart, USART_IT_TC);
01824 
01825   /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
01826   __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
01827 
01828   /* Tx process is ended, restore husart->State to Ready */
01829   husart->State = HAL_USART_STATE_READY;
01830 
01831   HAL_USART_TxCpltCallback(husart);
01832 
01833   return HAL_OK;
01834 }
01835 
01836 
01837 /**
01838   * @brief  Simplex receive an amount of data in non-blocking mode.
01839   * @note   Function called under interruption only, once
01840   *         interruptions have been enabled by HAL_USART_Receive_IT().
01841   * @param  husart USART handle
01842   * @retval HAL status
01843   */
01844 static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart)
01845 {
01846   uint16_t* tmp;
01847   uint16_t uhMask = husart->Mask;
01848 
01849   if(husart->State == HAL_USART_STATE_BUSY_RX)
01850   {
01851 
01852     if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
01853     {
01854       tmp = (uint16_t*) husart->pRxBuffPtr;
01855       *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
01856       husart->pRxBuffPtr += 2;
01857     }
01858     else
01859     {
01860       *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
01861     }
01862     /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
01863     husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
01864 
01865     if(--husart->RxXferCount == 0)
01866     {
01867       /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
01868       CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
01869 
01870       /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
01871       CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
01872 
01873       /* Rx process is completed, restore husart->State to Ready */
01874       husart->State = HAL_USART_STATE_READY;
01875 
01876       HAL_USART_RxCpltCallback(husart);
01877 
01878       return HAL_OK;
01879     }
01880 
01881     return HAL_OK;
01882   }
01883   else
01884   {
01885     return HAL_BUSY;
01886   }
01887 }
01888 
01889 /**
01890   * @brief  Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking).
01891   * @note   Function called under interruption only, once
01892   *         interruptions have been enabled by HAL_USART_TransmitReceive_IT().
01893   * @param husart: USART handle.
01894   * @retval HAL status
01895   */
01896 static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart)
01897 {
01898   uint16_t* tmp;
01899   uint16_t uhMask = husart->Mask;
01900 
01901   if(husart->State == HAL_USART_STATE_BUSY_TX_RX)
01902   {
01903 
01904     if(husart->TxXferCount != 0x00)
01905     {
01906       if(__HAL_USART_GET_FLAG(husart, USART_FLAG_TXE) != RESET)
01907       {
01908         if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
01909         {
01910           tmp = (uint16_t*) husart->pTxBuffPtr;
01911           husart->Instance->TDR = (uint16_t)(*tmp & uhMask);
01912           husart->pTxBuffPtr += 2;
01913         }
01914         else
01915         {
01916           husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)uhMask);
01917         }
01918         husart->TxXferCount--;
01919 
01920         /* Check the latest data transmitted */
01921         if(husart->TxXferCount == 0)
01922         {
01923            __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
01924         }
01925       }
01926     }
01927 
01928     if(husart->RxXferCount != 0x00)
01929     {
01930       if(__HAL_USART_GET_FLAG(husart, USART_FLAG_RXNE) != RESET)
01931       {
01932         if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
01933         {
01934           tmp = (uint16_t*) husart->pRxBuffPtr;
01935           *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
01936           husart->pRxBuffPtr += 2;
01937         }
01938         else
01939         {
01940           *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
01941         }
01942         husart->RxXferCount--;
01943       }
01944     }
01945 
01946     /* Check the latest data received */
01947     if(husart->RxXferCount == 0)
01948     {
01949       /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
01950       CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
01951 
01952       /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
01953       CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
01954 
01955       /* Rx process is completed, restore husart->State to Ready */
01956       husart->State = HAL_USART_STATE_READY;
01957 
01958       HAL_USART_TxRxCpltCallback(husart);
01959 
01960       return HAL_OK;
01961     }
01962 
01963     return HAL_OK;
01964   }
01965   else
01966   {
01967     return HAL_BUSY;
01968   }
01969 }
01970 
01971 /**
01972   * @}
01973   */
01974 
01975 #endif /* HAL_USART_MODULE_ENABLED */
01976 /**
01977   * @}
01978   */
01979 
01980 /**
01981   * @}
01982   */
01983 
01984 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/