/**
  * @brief Initializes the SmartCard mode according to the specified
  *         parameters in the SMARTCARD_InitTypeDef and create the associated handle .
  * @param  hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains
  *                the configuration information for SMARTCARD module.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsc)
{
  /* Check the SMARTCARD handle allocation */
  if(hsc == NULL)
  {
    return HAL_ERROR;
  }

  /* Check the parameters */
  assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance));
  assert_param(IS_SMARTCARD_NACK_STATE(hsc->Init.NACKState));

  if(hsc->gState == HAL_SMARTCARD_STATE_RESET)
  {  
    /* Allocate lock resource and initialize it */
    hsc->Lock = HAL_UNLOCKED;
    /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
    HAL_SMARTCARD_MspInit(hsc);
  }
  
  hsc->gState = HAL_SMARTCARD_STATE_BUSY;

  /* Set the Prescaler */
  MODIFY_REG(hsc->Instance->GTPR, USART_GTPR_PSC, hsc->Init.Prescaler);

  /* Set the Guard Time */
  MODIFY_REG(hsc->Instance->GTPR, USART_GTPR_GT, ((hsc->Init.GuardTime)<<8));

  /* Set the Smartcard Communication parameters */
  SMARTCARD_SetConfig(hsc);

  /* In SmartCard mode, the following bits must be kept cleared: 
  - LINEN bit in the USART_CR2 register
  - HDSEL and IREN bits in the USART_CR3 register.*/
  hsc->Instance->CR2 &= ~USART_CR2_LINEN;
  hsc->Instance->CR3 &= ~(USART_CR3_IREN | USART_CR3_HDSEL);

  /* Enable the SMARTCARD Parity Error Interrupt */
  __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_PE);

  /* Enable the SMARTCARD Framing Error Interrupt */
  __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_ERR);

  /* Enable the Peripheral */
  __HAL_SMARTCARD_ENABLE(hsc);

  /* Configure the Smartcard NACK state */
  MODIFY_REG(hsc->Instance->CR3, USART_CR3_NACK, hsc->Init.NACKState);

  /* Enable the SC mode by setting the SCEN bit in the CR3 register */
  hsc->Instance->CR3 |= (USART_CR3_SCEN);

  /* Initialize the SMARTCARD state*/
  hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
  hsc->gState= HAL_SMARTCARD_STATE_READY;
  hsc->RxState= HAL_SMARTCARD_STATE_READY;

  return HAL_OK;
}
/**
  * @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.
  * @param pData: pointer to data buffer
  * @param Size: amount of data to be sent
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
{
  uint32_t tmp1 = 0;
  
  tmp1 = hsc->State;
  if((tmp1 == HAL_SMARTCARD_STATE_READY) || (tmp1 == HAL_SMARTCARD_STATE_BUSY_RX))
  {
    if((pData == NULL) || (Size == 0)) 
    {
      return HAL_ERROR;
    }

    /* Process Locked */
    __HAL_LOCK(hsc);

    hsc->pTxBuffPtr = pData;
    hsc->TxXferSize = Size;
    hsc->TxXferCount = Size;

    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;
    }

    /* Process Unlocked */
    __HAL_UNLOCK(hsc);
    
    /* Enable the SMARTCARD Parity Error Interrupt */
    __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_PE);

    /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
    __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_ERR);

    /* Enable the SMARTCARD Transmit data register empty Interrupt */
    __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_TXE);

    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))
  {
    tmp = (uint16_t*) hsc->pTxBuffPtr;
    hsc->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
    hsc->pTxBuffPtr += 1;    
    
    if(--hsc->TxXferCount == 0)
    {
      /* Disable the SMARTCARD Transmit data register empty Interrupt */
      __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_TXE);
      
      /* Enable the SMARTCARD Transmit Complete Interrupt */    
      __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_TC);
    }
    
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}
示例#4
0
文件: main.c 项目: dazuo78/TBall
/**
  * @brief SMARTCARD error callbacks
  * @param hsc: usart handle
  * @retval None
  */
void HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef *hsc)
{
  if(HAL_SMARTCARD_GetError(hsc) & HAL_SMARTCARD_ERROR_FE)
  {
    __HAL_SMARTCARD_FLUSH_DRREGISTER(hsc);
    /* Resend the byte that failed to be received (by the Smartcard) correctly */
    SC_ParityErrorHandler();
  }
  
  if(HAL_SMARTCARD_GetError(hsc) & HAL_SMARTCARD_ERROR_PE)
  {
    /* Enable SC_USART RXNE Interrupt (until receiving the corrupted byte) */
    __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_RXNE);
    /* Flush the SC_USART DR register */
    __HAL_SMARTCARD_FLUSH_DRREGISTER(hsc);
  }  
  if(HAL_SMARTCARD_GetError(hsc) & HAL_SMARTCARD_ERROR_NE)
  {
    __HAL_SMARTCARD_FLUSH_DRREGISTER(hsc);
  }
  
  if(HAL_SMARTCARD_GetError(hsc) & HAL_SMARTCARD_ERROR_ORE)
  {
    __HAL_SMARTCARD_FLUSH_DRREGISTER(hsc);
  } 
}
示例#5
0
/**
  * @brief  Send an amount of data in non-blocking mode.
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
  *                the configuration information for the specified SMARTCARD module.
  *         Function called under interruption only, once
  *         interruptions have been enabled by HAL_SMARTCARD_Transmit_IT()
  * @retval HAL status
  */
static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc)
{
  uint32_t tmp_state = 0;

  tmp_state = hsc->State;
  if((tmp_state == HAL_SMARTCARD_STATE_BUSY_TX) || (tmp_state == HAL_SMARTCARD_STATE_BUSY_TX_RX))
  {
    WRITE_REG(hsc->Instance->DR, (*hsc->pTxBuffPtr++ & (uint8_t)0xFF));

    if(--hsc->TxXferCount == 0)
    {
      /* Disable the SMARTCARD Transmit Data Register Empty Interrupt */
      __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_TXE);

      /* Enable the SMARTCARD Transmit Complete Interrupt */
      __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_TC);
    }

    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;
  
  /* Check that a Tx process is ongoing */
  if(hsc->gState == HAL_SMARTCARD_STATE_BUSY_TX) 
  {
    tmp = (uint16_t*) hsc->pTxBuffPtr;
    hsc->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FFU);
    hsc->pTxBuffPtr += 1U;    
    
    if(--hsc->TxXferCount == 0U)
    {
      /* Disable the SMARTCARD Transmit data register empty Interrupt */
      __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_TXE);
      
      /* Enable the SMARTCARD Transmit Complete Interrupt */
      __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_TC);
    }
    
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}
/**
  * @brief Receive an amount of data in interrupt mode 
  * @param hsc: SMARTCARD handle
  * @param pData: pointer to data buffer
  * @param Size: amount of data to be received
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
{
  if((hsc->State == HAL_SMARTCARD_STATE_READY) || (hsc->State == HAL_SMARTCARD_STATE_BUSY_TX))
  {
    if((pData == NULL) || (Size == 0)) 
    {
      return HAL_ERROR;
    }

    /* Process Locked */
    __HAL_LOCK(hsc);

    hsc->pRxBuffPtr = pData;
    hsc->RxXferSize = Size;
    hsc->RxXferCount = Size;

    hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
    /* Check if a 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;
    }
    
    /* Enable the SMARTCARD Parity Error Interrupt */
    __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_PE);

    /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
    __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_ERR);

    /* Process Unlocked */
    __HAL_UNLOCK(hsc);

    /* Enable the SMARTCARD Data Register not empty Interrupt */
    __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_RXNE);

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}
/**
  * @brief Send an amount of data in interrupt mode 
  * @param hsc: SMARTCARD handle
  * @param pData: pointer to data buffer
  * @param Size: amount of data to be sent
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
{
  if((hsc->State == HAL_SMARTCARD_STATE_READY) || (hsc->State == HAL_SMARTCARD_STATE_BUSY_RX))
  {
    if((pData == NULL) || (Size == 0U)) 
    {
      return HAL_ERROR;
    }
    
    /* Process Locked */
    __HAL_LOCK(hsc);
    
    hsc->pTxBuffPtr = pData;
    hsc->TxXferSize = Size;
    hsc->TxXferCount = Size;
    
    hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
    /* Check if a 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;
    }

    /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
    __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_ERR);
    
    /* Process Unlocked */
    __HAL_UNLOCK(hsc);    
    
    /* Enable the SMARTCARD Transmit Complete Interrupt */
    __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_TC);
    
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}
/**
  * @brief DMA SMARTCARD transmit process complete callback 
  * @param hdma: DMA handle
  * @retval None
  */
static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma)     
{
  SMARTCARD_HandleTypeDef* hsmartcard = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  hsmartcard->TxXferCount = 0;

  /* Disable the DMA transfer for transmit request by resetting the DMAT bit
  in the SMARTCARD associated USART CR3 register */
  hsmartcard->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_DMAT);

  /* Enable the SMARTCARD Transmit Complete Interrupt */
  __HAL_SMARTCARD_ENABLE_IT(hsmartcard, SMARTCARD_IT_TC);
}
示例#10
0
/**
  * @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);

  /* Enable the SMARTCARD Transmit Complete Interrupt */
  __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_TC);
}
/**
  * @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.
  * @param pData: pointer to data buffer
  * @param Size: amount of data to be sent
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
{
  /* Check that a Tx process is not already ongoing */
  if(hsc->gState == HAL_SMARTCARD_STATE_READY) 
  {
    if((pData == NULL) || (Size == 0U)) 
    {
      return HAL_ERROR;
    }

    /* Process Locked */
    __HAL_LOCK(hsc);

    hsc->pTxBuffPtr = pData;
    hsc->TxXferSize = Size;
    hsc->TxXferCount = Size;

    hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
    hsc->gState = HAL_SMARTCARD_STATE_BUSY_TX;
    
    /* Process Unlocked */
    __HAL_UNLOCK(hsc);
    
    /* Enable the SMARTCARD Parity Error Interrupt */
    __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_PE);

    /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
    __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_ERR);

    /* Enable the SMARTCARD Transmit data register empty Interrupt */
    __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_TXE);

    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 the specified SMARTCARD module.
  *         Function called under interruption only, once
  *         interruptions have been enabled by HAL_SMARTCARD_Transmit_IT()      
  * @retval HAL status
  */
static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc)
{
  uint16_t* tmp = 0;
  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;
      WRITE_REG(hsc->Instance->DR, (uint16_t)(*tmp & (uint16_t)0x01FF));
      if(hsc->Init.Parity == SMARTCARD_PARITY_NONE)
      {
        hsc->pTxBuffPtr += 2;
      }
      else
      {
        hsc->pTxBuffPtr += 1;
      }
    } 
    else
    {
      WRITE_REG(hsc->Instance->DR, (uint8_t)(*hsc->pTxBuffPtr++ & (uint8_t)0x00FF));
    }
    
    if(--hsc->TxXferCount == 0)
    {
      /* Disable the SMARTCARD Transmit Data Register Empty Interrupt */
      __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_TXE);

      /* Enable the SMARTCARD Transmit Complete Interrupt */    
      __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_TC);
    }
    
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}