Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32f1xx_hal_usart.c Source File

stm32f1xx_hal_usart.c

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