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