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