/**
  * @brief Check the SMARTCARD Idle State
  * @param hsc: SMARTCARD handle
  * @retval HAL status
  */
static HAL_StatusTypeDef SMARTCARD_CheckIdleState(SMARTCARD_HandleTypeDef *hsc)
{
  
  /* Initialize the SMARTCARD ErrorCode */
  hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;

  /* Check if the Transmitter is enabled */
  if((hsc->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
  {
    /* Wait until TEACK flag is set */
    if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, USART_ISR_TEACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK)  
    { 
      return HAL_TIMEOUT;
    } 
  }
  /* Check if the Receiver is enabled */
  if((hsc->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
  {
    /* Wait until REACK flag is set */
    if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, USART_ISR_REACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK)  
    { 
      return HAL_TIMEOUT;
    }
  }
  
  /* Process Unlocked */
  __HAL_UNLOCK(hsc);
        
  /* Initialize the SMARTCARD state*/
  hsc->State= HAL_SMARTCARD_STATE_READY;
  
  return HAL_OK;
}
/**
  * @brief Send an amount of data in blocking mode 
  * @param hsc: SMARTCARD handle
  * @param pData: pointer to data buffer
  * @param Size: amount of data to be sent
  * @param Timeout : Timeout duration
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
  if((hsc->State == HAL_SMARTCARD_STATE_READY) || (hsc->State == HAL_SMARTCARD_STATE_BUSY_RX))
  {
    if((pData == NULL) || (Size == 0)) 
    {
      return  HAL_ERROR;
    }
    
    /* Process Locked */
    __HAL_LOCK(hsc);
    hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;    
    /* Check if a non-blocking receive process is ongoing or not */
    if(hsc->State == HAL_SMARTCARD_STATE_BUSY_RX) 
    {
      hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX;
    }
    else
    {
      hsc->State = HAL_SMARTCARD_STATE_BUSY_TX;
    }
    
    hsc->TxXferSize = Size;
    hsc->TxXferCount = Size;
    while(hsc->TxXferCount > 0)
    {
      hsc->TxXferCount--;      
      if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TXE, RESET, Timeout) != HAL_OK)  
      { 
        return HAL_TIMEOUT;
      }
      hsc->Instance->TDR = (*pData++ & (uint8_t)0xFF);     
    }
    if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TC, RESET, Timeout) != HAL_OK)  
    { 
      return HAL_TIMEOUT;
    }
    /* Check if a non-blocking receive Process is ongoing or not */
    if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) 
    {
      hsc->State = HAL_SMARTCARD_STATE_BUSY_RX;
    }
    else
    {
      hsc->State = HAL_SMARTCARD_STATE_READY;
    }
    
    /* Process Unlocked */
    __HAL_UNLOCK(hsc);
    
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;   
  }
}
/**
  * @brief Send an amount of data in blocking mode 
  * @param  hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
  *                the configuration information for SMARTCARD module.
  * @param pData: pointer to data buffer
  * @param Size: amount of data to be sent
  * @param Timeout: Timeout duration 
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
  uint16_t* tmp;
  uint32_t tickstart = 0U;
  
  if(hsc->gState == HAL_SMARTCARD_STATE_READY) 
  {
    if((pData == NULL) || (Size == 0U)) 
    {
      return  HAL_ERROR;
    }

    /* Process Locked */
    __HAL_LOCK(hsc);

    hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
    hsc->gState = HAL_SMARTCARD_STATE_BUSY_TX;
       
    /* Init tickstart for timeout managment */ 
    tickstart = HAL_GetTick();
    
    hsc->TxXferSize = Size;
    hsc->TxXferCount = Size;
    while(hsc->TxXferCount > 0U)
    {
      hsc->TxXferCount--;
      if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
      {
        return HAL_TIMEOUT;
      }
      tmp = (uint16_t*) pData;
      hsc->Instance->DR = (*tmp & (uint16_t)0x01FFU);
      pData +=1U;
    }
    
    if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
    {
      return HAL_TIMEOUT;
    }

	/* At end of Tx process, restore hsc->gState to Ready */
    hsc->gState = HAL_SMARTCARD_STATE_READY;
    
    /* Process Unlocked */
    __HAL_UNLOCK(hsc);

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}
/**
  * @brief  DMA SMARTCARD transmit process complete callback. 
  * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
  *               the configuration information for the specified DMA module.
  * @retval None
  */
static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{
  SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;

  hsc->TxXferCount = 0;

  /* Disable the DMA transfer for transmit request by setting the DMAT bit
     in the SMARTCARD CR3 register */
  CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT);

  /* Wait for SMARTCARD TC Flag */
  if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TC, RESET, SMARTCARD_TIMEOUT_VALUE) != HAL_OK)
  {
    /* Timeout occurred */ 
    hsc->State = HAL_SMARTCARD_STATE_TIMEOUT;
    HAL_SMARTCARD_ErrorCallback(hsc);
  }
  else
  {
    /* No Timeout */
    /* Check if a non-blocking receive process is ongoing or not */
    if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) 
    {
      hsc->State = HAL_SMARTCARD_STATE_BUSY_RX;
    }
    else
    {
      hsc->State = HAL_SMARTCARD_STATE_READY;
    }
    HAL_SMARTCARD_TxCpltCallback(hsc);
  }
}
Example #5
0
/**
  * @brief  Receive an amount of data in blocking mode.
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
  *                the configuration information for the specified SMARTCARD module.
  * @param  pData: Pointer to data buffer
  * @param  Size: Amount of data to be received
  * @param  Timeout: Specify timeout value
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
  uint32_t tmp_state = 0;

  tmp_state = hsc->State;
  if((tmp_state == HAL_SMARTCARD_STATE_READY) || (tmp_state == HAL_SMARTCARD_STATE_BUSY_TX))
  {
    if((pData == NULL) || (Size == 0))
    {
      return  HAL_ERROR;
    }

    /* Process Locked */
    __HAL_LOCK(hsc);

    hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;

    /* Check if a non-blocking transmit process is ongoing or not */
    if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX)
    {
      hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX;
    }
    else
    {
      hsc->State = HAL_SMARTCARD_STATE_BUSY_RX;
    }

    hsc->RxXferSize = Size;
    hsc->RxXferCount = Size;
    /* Check the remain data to be received */
    while(hsc->RxXferCount > 0)
    {
      if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_RXNE, RESET, Timeout) != HAL_OK)
      {
        return HAL_TIMEOUT;
      }
      *pData++ = (uint8_t)(hsc->Instance->DR & (uint8_t)0x00FF);
      hsc->RxXferCount--;
    }

    /* Check if a non-blocking transmit process is ongoing or not */
    if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX)
    {
      hsc->State = HAL_SMARTCARD_STATE_BUSY_TX;
    }
    else
    {
      hsc->State = HAL_SMARTCARD_STATE_READY;
    }

    /* Process Unlocked */
    __HAL_UNLOCK(hsc);

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}
/**
  * @brief Receive an amount of data in blocking mode 
  * @param hsc: SMARTCARD handle
  * @param pData: pointer to data buffer
  * @param Size: amount of data to be received
  * @param Timeout: Timeout duration
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
  uint32_t tickstart = 0U;
  
  if(hsc->RxState == HAL_SMARTCARD_STATE_READY)
  {
    if((pData == NULL) || (Size == 0U)) 
    {
      return  HAL_ERROR;
    }

    /* Process Locked */
    __HAL_LOCK(hsc);
    
    hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
    hsc->RxState = HAL_SMARTCARD_STATE_BUSY_RX;
    
    /* Init tickstart for timeout managment*/
    tickstart = HAL_GetTick();

    hsc->RxXferSize = Size;
    hsc->RxXferCount = Size;
    /* Check the remain data to be received */
    while(hsc->RxXferCount > 0U)
    {
      hsc->RxXferCount--;
      if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)  
      {
        return HAL_TIMEOUT;
      }
      *pData++ = (uint8_t)(hsc->Instance->RDR & (uint8_t)0x00FFU);
    }

    /* At end of Rx process, restore hsc->RxState to Ready */
    hsc->RxState = HAL_SMARTCARD_STATE_READY;

    /* Process Unlocked */
    __HAL_UNLOCK(hsc);

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}
/**
  * @brief  Sends an amount of data in blocking mode.
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
  *                the configuration information for the specified SMARTCARD module.
  * @param  pData: Pointer to data buffer
  * @param  Size: Amount of data to be sent
  * @param  Timeout: Specify timeout value  
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
  uint16_t* tmp = 0;
  uint32_t tmp1 = 0;
  
  tmp1 = hsc->State;
  if((tmp1 == HAL_SMARTCARD_STATE_READY) || (tmp1 == HAL_SMARTCARD_STATE_BUSY_RX))
  {
    if((pData == HAL_NULL) || (Size == 0)) 
    {
      return  HAL_ERROR;
    }

    /* Process Locked */
    __HAL_LOCK(hsc);

    hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
    /* Check if a non-blocking receive process is ongoing or not */
    if(hsc->State == HAL_SMARTCARD_STATE_BUSY_RX) 
    {
      hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX;
    }
    else
    {
      hsc->State = HAL_SMARTCARD_STATE_BUSY_TX;
    }
    
    hsc->TxXferSize = Size;
    hsc->TxXferCount = Size;
    while(hsc->TxXferCount > 0)
    {
      if(hsc->Init.WordLength == SMARTCARD_WORDLENGTH_9B)
      {
        if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TXE, RESET, Timeout) != HAL_OK)
        {
          return HAL_TIMEOUT;
        }
        tmp = (uint16_t*) pData;
        WRITE_REG(hsc->Instance->DR, (*tmp & (uint16_t)0x01FF));
        if(hsc->Init.Parity == SMARTCARD_PARITY_NONE)
        {
          pData +=2;
        }
        else
        {
          pData +=1;
        }
      }
      else
      {
        if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TXE, RESET, Timeout) != HAL_OK)
        {
          return HAL_TIMEOUT;
        }
        WRITE_REG(hsc->Instance->DR, (*pData++ & (uint8_t)0xFF));
      }
      hsc->TxXferCount--;
    }

    if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TC, RESET, Timeout) != HAL_OK)
    {
      return HAL_TIMEOUT;
    }

    /* Check if a non-blocking receive process is ongoing or not */
    if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) 
    {
      hsc->State = HAL_SMARTCARD_STATE_BUSY_RX;
    }
    else
    {
      hsc->State = HAL_SMARTCARD_STATE_READY;
    }
    /* Process Unlocked */
    __HAL_UNLOCK(hsc);

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}
/**
  * @brief Send an amount of data in non blocking mode 
  * @param  hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
  *                the configuration information for SMARTCARD module.
  * @retval HAL status
  */
static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc)
{
  uint16_t* tmp;
  uint32_t tmp1 = 0;
  
  tmp1 = hsc->State;
  if((tmp1 == HAL_SMARTCARD_STATE_BUSY_TX) || (tmp1 == HAL_SMARTCARD_STATE_BUSY_TX_RX))
  {
    if(hsc->Init.WordLength == SMARTCARD_WORDLENGTH_9B)
    {
      tmp = (uint16_t*) hsc->pTxBuffPtr;
      hsc->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
      if(hsc->Init.Parity == SMARTCARD_PARITY_NONE)
      {
        hsc->pTxBuffPtr += 2;
      }
      else
      {
        hsc->pTxBuffPtr += 1;
      }
    } 
    else
    {
      hsc->Instance->DR = (uint8_t)(*hsc->pTxBuffPtr++ & (uint8_t)0x00FF);
    }
    
    if(--hsc->TxXferCount == 0)
    {
      /* Disable the SMARTCARD Transmit data register empty Interrupt */
      __SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_TXE);
      
      /* Disable the SMARTCARD Parity Error Interrupt */
      __SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_PE);
      
      /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
      __SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_ERR);
      
      if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TC, RESET, SMARTCARD_TIMEOUT_VALUE) != HAL_OK)
      {
        return HAL_TIMEOUT;
      }
            
      /* Check if a non-blocking receive process is ongoing or not */
      if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) 
      {
        hsc->State = HAL_SMARTCARD_STATE_BUSY_RX;
      }
      else
      {
        hsc->State = HAL_SMARTCARD_STATE_READY;
      }

      HAL_SMARTCARD_TxCpltCallback(hsc);
      
      return HAL_OK;
    }
    
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;   
  }
}