📄 sdcard.c
字号:
/* Send CMD25 WRITE_MULT_BLOCK with argument data address */
SDIO_CmdInitStructure.SDIO_Argument = (u32)addr;
SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_WRITE_MULT_BLOCK;
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_WRITE_MULT_BLOCK);
if (SD_OK != errorstatus)
{
return(errorstatus);
}
TotalNumberOfBytes = NumberOfBlocks * BlockSize;
StopCondition = 1;
SrcBuffer = writebuff;
SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
SDIO_DataInitStructure.SDIO_DataLength = NumberOfBlocks * BlockSize;
SDIO_DataInitStructure.SDIO_DataBlockSize = (u32) power << 4;
SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToCard;
SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;
SDIO_DataConfig(&SDIO_DataInitStructure);
if (DeviceMode == SD_POLLING_MODE)
{
while (!(SDIO->STA & (SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DATAEND | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_STBITERR)))
{
if (SDIO_GetFlagStatus(SDIO_FLAG_TXFIFOHE) != RESET)
{
if (!((TotalNumberOfBytes - bytestransferred) < SD_HALFFIFOBYTES))
{
for (count = 0; count < SD_HALFFIFO; count++)
{
SDIO_WriteData(*(tempbuff + count));
}
tempbuff += SD_HALFFIFO;
bytestransferred += SD_HALFFIFOBYTES;
}
else
{
restwords = ((TotalNumberOfBytes - bytestransferred) % 4 == 0) ? ((TotalNumberOfBytes - bytestransferred) / 4) :
((TotalNumberOfBytes - bytestransferred) / 4 + 1);
for (count = 0; count < restwords; count++, tempbuff++, bytestransferred += 4)
{
SDIO_WriteData(*tempbuff);
}
}
}
}
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_TXUNDERR) != RESET)
{
SDIO_ClearFlag(SDIO_FLAG_TXUNDERR);
errorstatus = SD_TX_UNDERRUN;
return(errorstatus);
}
else if (SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)
{
SDIO_ClearFlag(SDIO_FLAG_STBITERR);
errorstatus = SD_START_BIT_ERR;
return(errorstatus);
}
if (SDIO_GetFlagStatus(SDIO_FLAG_DATAEND) != RESET)
{
if ((SDIO_STD_CAPACITY_SD_CARD_V1_1 == CardType) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == CardType) || (SDIO_HIGH_CAPACITY_SD_CARD == CardType))
{
/* 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);
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);
}
/*******************************************************************************
* Function Name : SD_GetTransferState
* Description : Gets the cuurent data transfer state.
* Input : None
* Output : None
* Return : 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);
}
}
/*******************************************************************************
* Function Name : SD_StopTransfer
* Description : Aborts an ongoing data transfer.
* Input : None
* Output : None
* Return : 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);
}
/*******************************************************************************
* Function Name : SD_Erase
* Description : Allows to erase memory area specified for the given card.
* Input : - startaddr: the start address.
* - endaddr: the end address.
* Output : None
* Return : SD_Error: SD Card Error code.
*******************************************************************************/
SD_Error SD_Erase(u32 startaddr, u32 endaddr)
{
SD_Error errorstatus = SD_OK;
u32 delay = 0;
vu32 maxdelay = 0;
u8 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);
}
/*******************************************************************************
* Function Name : SD_SendStatus
* Description : Returns the current card's status.
* Input : pcardstatus: pointer to the buffer that will contain the SD
* card status (Card Status register).
* Output : None
* Return : SD_Error: SD Card Error code.
*******************************************************************************/
SD_Error SD_SendStatus(u32 *pcardstatus)
{
SD_Error errorstatus = SD_OK;
if (pcardstatus == NULL)
{
errorstatus = SD_INVALID_PARAMETER;
return(errorstatus);
}
SDIO_CmdInitStructure.SDIO_Argument = (u32) 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);
}
/*******************************************************************************
* Function Name : SD_SendSDStatus
* Description : Returns the current SD card's status.
* Input : psdstatus: pointer to the buffer that will contain the SD
* card status (SD Status register).
* Output : None
* Return : SD_Error: SD Card Error code.
*******************************************************************************/
SD_Error SD_SendSDStatus(u32 *psdstatus)
{
SD_Error errorstatus = SD_OK;
u32 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 = (u32) 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.SD
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -