/** * @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; } }
/** * @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); } }
/** * @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); }
/** * @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; } }