📄 sdcard.c
字号:
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus = CmdResp1Error(SDIO_STOP_TRANSMISSION);
if (errorstatus != SD_OK)
{
return(errorstatus);
}
}
}
}
else if (DeviceMode == SD_INTERRUPT_MODE)
{
SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_TXFIFOHE | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR, ENABLE);
while ((TransferEnd == 0) && (TransferError == SD_OK))
{}
if (TransferError != SD_OK)
{
return(TransferError);
}
}
else if (DeviceMode == SD_DMA_MODE)
{
SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR, ENABLE);
SDIO_DMACmd(ENABLE);
DMA_TxConfiguration(writebuff, (NumberOfBlocks * BlockSize));
while (DMA_GetFlagStatus(DMA2_FLAG_TC4) == RESET)
{}
while ((TransferEnd == 0) && (TransferError == SD_OK))
{}
if (TransferError != SD_OK)
{
return(TransferError);
}
}
}
/* Clear all the static flags */
SDIO_ClearFlag(SDIO_STATIC_FLAGS);
/* Wait till the card is in programming state */
errorstatus = IsCardProgramming(&cardstate);
while ((errorstatus == SD_OK) && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING)))
{
errorstatus = IsCardProgramming(&cardstate);
}
return(errorstatus);
}
/**
* @brief Gets the cuurent data transfer state.
* @param None
* @retval : SDTransferState: Data Transfer state.
* This value can be:
* - SD_NO_TRANSFER: No data transfer is acting
* - SD_TRANSFER_IN_PROGRESS: Data transfer is acting
*/
SDTransferState SD_GetTransferState(void)
{
if (SDIO->STA & (SDIO_FLAG_TXACT | SDIO_FLAG_RXACT))
{
return(SD_TRANSFER_IN_PROGRESS);
}
else
{
return(SD_NO_TRANSFER);
}
}
/**
* @brief Aborts an ongoing data transfer.
* @param None
* @retval : SD_Error: SD Card Error code.
*/
SD_Error SD_StopTransfer(void)
{
SD_Error errorstatus = SD_OK;
/* Send CMD12 STOP_TRANSMISSION */
SDIO_CmdInitStructure.SDIO_Argument = 0x0;
SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_STOP_TRANSMISSION;
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus = CmdResp1Error(SDIO_STOP_TRANSMISSION);
return(errorstatus);
}
/**
* @brief Allows to erase memory area specified for the given card.
* @param startaddr: the start address.
* @param endaddr: the end address.
* @retval : SD_Error: SD Card Error code.
*/
SD_Error SD_Erase(uint32_t startaddr, uint32_t endaddr)
{
SD_Error errorstatus = SD_OK;
uint32_t delay = 0;
__IO uint32_t maxdelay = 0;
uint8_t cardstate = 0;
/* Check if the card coomnd class supports erase command */
if (((CSD_Tab[1] >> 20) & SD_CCCC_ERASE) == 0)
{
errorstatus = SD_REQUEST_NOT_APPLICABLE;
return(errorstatus);
}
maxdelay = 72000 / ((SDIO->CLKCR & 0xFF) + 2);
if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED)
{
errorstatus = SD_LOCK_UNLOCK_FAILED;
return(errorstatus);
}
if (CardType == SDIO_HIGH_CAPACITY_SD_CARD)
{
startaddr /= 512;
endaddr /= 512;
}
/* According to sd-card spec 1.0 ERASE_GROUP_START (CMD32) and erase_group_end(CMD33) */
if ((SDIO_STD_CAPACITY_SD_CARD_V1_1 == CardType) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == CardType) || (SDIO_HIGH_CAPACITY_SD_CARD == CardType))
{
/* Send CMD32 SD_ERASE_GRP_START with argument as addr */
SDIO_CmdInitStructure.SDIO_Argument = startaddr;
SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SD_ERASE_GRP_START;
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus = CmdResp1Error(SDIO_SD_ERASE_GRP_START);
if (errorstatus != SD_OK)
{
return(errorstatus);
}
/* Send CMD33 SD_ERASE_GRP_END with argument as addr */
SDIO_CmdInitStructure.SDIO_Argument = endaddr;
SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SD_ERASE_GRP_END;
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus = CmdResp1Error(SDIO_SD_ERASE_GRP_END);
if (errorstatus != SD_OK)
{
return(errorstatus);
}
}
/* Send CMD38 ERASE */
SDIO_CmdInitStructure.SDIO_Argument = 0;
SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_ERASE;
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus = CmdResp1Error(SDIO_ERASE);
if (errorstatus != SD_OK)
{
return(errorstatus);
}
for (delay = 0; delay < maxdelay; delay++)
{}
/* Wait till the card is in programming state */
errorstatus = IsCardProgramming(&cardstate);
while ((errorstatus == SD_OK) && ((SD_CARD_PROGRAMMING == cardstate) || (SD_CARD_RECEIVING == cardstate)))
{
errorstatus = IsCardProgramming(&cardstate);
}
return(errorstatus);
}
/**
* @brief Returns the current card's status.
* @param pcardstatus: pointer to the buffer that will contain the SD
* card status (Card Status register).
* @retval : SD_Error: SD Card Error code.
*/
SD_Error SD_SendStatus(uint32_t *pcardstatus)
{
SD_Error errorstatus = SD_OK;
if (pcardstatus == NULL)
{
errorstatus = SD_INVALID_PARAMETER;
return(errorstatus);
}
SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) RCA << 16;
SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SEND_STATUS;
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus = CmdResp1Error(SDIO_SEND_STATUS);
if (errorstatus != SD_OK)
{
return(errorstatus);
}
*pcardstatus = SDIO_GetResponse(SDIO_RESP1);
return(errorstatus);
}
/**
* @brief Returns the current SD card's status.
* @param psdstatus: pointer to the buffer that will contain the SD
* card status (SD Status register).
* @retval : SD_Error: SD Card Error code.
*/
SD_Error SD_SendSDStatus(uint32_t *psdstatus)
{
SD_Error errorstatus = SD_OK;
uint32_t count = 0;
if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED)
{
errorstatus = SD_LOCK_UNLOCK_FAILED;
return(errorstatus);
}
/* Set block size for card if it is not equal to current block size for card. */
SDIO_CmdInitStructure.SDIO_Argument = 64;
SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SET_BLOCKLEN;
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus = CmdResp1Error(SDIO_SET_BLOCKLEN);
if (errorstatus != SD_OK)
{
return(errorstatus);
}
/* CMD55 */
SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) RCA << 16;
SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_APP_CMD;
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus = CmdResp1Error(SDIO_APP_CMD);
if (errorstatus != SD_OK)
{
return(errorstatus);
}
SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
SDIO_DataInitStructure.SDIO_DataLength = 64;
SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DataBlockSize_64b;
SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToSDIO;
SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;
SDIO_DataConfig(&SDIO_DataInitStructure);
/* Send ACMD13 SD_APP_STAUS with argument as card's RCA.*/
SDIO_CmdInitStructure.SDIO_Argument = 0;
SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SD_APP_STAUS;
SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
SDIO_SendCommand(&SDIO_CmdInitStructure);
errorstatus = CmdResp1Error(SDIO_SD_APP_STAUS);
if (errorstatus != SD_OK)
{
return(errorstatus);
}
while (!(SDIO->STA &(SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR)))
{
if (SDIO_GetFlagStatus(SDIO_FLAG_RXFIFOHF) != RESET)
{
for (count = 0; count < 8; count++)
{
*(psdstatus + count) = SDIO_ReadData();
}
psdstatus += 8;
}
}
if (SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)
{
SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);
errorstatus = SD_DATA_TIMEOUT;
return(errorstatus);
}
else if (SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET)
{
SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);
errorstatus = SD_DATA_CRC_FAIL;
return(errorstatus);
}
else if (SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET)
{
SDIO_ClearFlag(SDIO_FLAG_RXOVERR);
errorstatus = SD_RX_OVERRUN;
return(errorstatus);
}
else if (SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)
{
SDIO_ClearFlag(SDIO_FLAG_STBITERR);
errorstatus = SD_START_BIT_ERR;
return(errorstatus);
}
while (SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET)
{
*psdstatus = SDIO_ReadData();
psdstatus++;
}
/* Clear all the static status flags*/
SDIO_ClearFlag(SDIO_STATIC_FLAGS);
psdstatus -= 16;
for (count = 0; count < 16; count++)
{
psdstatus[count] = ((psdstatus[count] & SD_0TO7BITS) << 24) |((psdstatus[count] & SD_8TO15BITS) << 8) |
((psdstatus[count] & SD_16TO23BITS) >> 8) |((psdstatus[count] & SD_24TO31BITS) >> 24);
}
return(errorstatus);
}
/**
* @brief Allows to process all the interrupts that are high.
* @param None
* @retval : SD_Error: SD Card Error code.
*/
SD_Error SD_ProcessIRQSrc(void)
{
uint32_t count = 0, restwords = 0;
if (DeviceMode == SD_INTERRUPT_MODE)
{
if (SDIO_GetITStatus(SDIO_IT_RXFIFOHF) != RESET)
{
for (count = 0; count < SD_HALFFIFO; count++)
{
*(DestBuffer + count) = SDIO_ReadData();
}
DestBuffer += SD_HALFFIFO;
NumberOfBytes += SD_HALFFIFOBYTES;
}
else if (SDIO_GetITStatus(SDIO_IT_TXFIFOHE) != RESET)
{
if ((TotalNumberOfBytes - NumberOfBytes) < SD_HALFFIFOBYTES)
{
restwords = ((TotalNumberOfBytes - NumberOfBytes) % 4 == 0) ?
((TotalNumberOfBytes - NumberOfBytes) / 4) :
((TotalNumberOfBytes - NumberOfBytes) / 4 + 1);
for (count = 0; count < restwords; count++, SrcBuffer++, NumberOfBytes += 4)
{
SDIO_WriteData(*SrcBuffer);
}
}
else
{
for (count = 0; count < SD_HALFFIFO; count++)
{
SDIO_WriteData(*(SrcBuffer + count));
}
SrcBuffer += SD_HALFFIFO;
NumberOfBytes += SD
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -