📄 sdcard.c
字号:
CSD_Tab[0] = SDIO_GetResponse(SDIO_RESP1);
CSD_Tab[1] = SDIO_GetResponse(SDIO_RESP2);
CSD_Tab[2] = SDIO_GetResponse(SDIO_RESP3);
CSD_Tab[3] = SDIO_GetResponse(SDIO_RESP4);
}
errorstatus = SD_OK; /* All cards get intialized */
return(errorstatus);
}
/*******************************************************************************
* 函数名 : SD_GetCardInfo
* 功能描述: 获取卡信息.
* 输入 : cardinfo
* 输出 :无
* Return : SD_Error: SD卡错误代码.
*******************************************************************************/
SD_Error SD_GetCardInfo(SD_CardInfo *cardinfo)
{
SD_Error errorstatus = SD_OK;
u8 tmp = 0;
cardinfo->CardType = (u8)CardType;
cardinfo->RCA = (u16)RCA;
/* Byte 0 */
tmp = (u8)((CSD_Tab[0] & 0xFF000000) >> 24);
cardinfo->SD_csd.CSDStruct = (tmp & 0xC0) >> 6;
cardinfo->SD_csd.SysSpecVersion = (tmp & 0x3C) >> 2;
cardinfo->SD_csd.Reserved1 = tmp & 0x03;
/* Byte 1 */
tmp = (u8)((CSD_Tab[0] & 0x00FF0000) >> 16);
cardinfo->SD_csd.TAAC = tmp;
/* Byte 2 */
tmp = (u8)((CSD_Tab[0] & 0x0000FF00) >> 8);
cardinfo->SD_csd.NSAC = tmp;
/* Byte 3 */
tmp = (u8)(CSD_Tab[0] & 0x000000FF);
cardinfo->SD_csd.MaxBusClkFrec = tmp;
/* Byte 4 */
tmp = (u8)((CSD_Tab[1] & 0xFF000000) >> 24);
cardinfo->SD_csd.CardComdClasses = tmp << 4;
/* Byte 5 */
tmp = (u8)((CSD_Tab[1] & 0x00FF0000) >> 16);
cardinfo->SD_csd.CardComdClasses |= (tmp & 0xF0) >> 4;
cardinfo->SD_csd.RdBlockLen = tmp & 0x0F;
/* Byte 6 */
tmp = (u8)((CSD_Tab[1] & 0x0000FF00) >> 8);
cardinfo->SD_csd.PartBlockRead = (tmp & 0x80) >> 7;
cardinfo->SD_csd.WrBlockMisalign = (tmp & 0x40) >> 6;
cardinfo->SD_csd.RdBlockMisalign = (tmp & 0x20) >> 5;
cardinfo->SD_csd.DSRImpl = (tmp & 0x10) >> 4;
cardinfo->SD_csd.Reserved2 = 0; /* Reserved */
cardinfo->SD_csd.DeviceSize = (tmp & 0x03) << 10;
/* Byte 7 */
tmp = (u8)(CSD_Tab[1] & 0x000000FF);
cardinfo->SD_csd.DeviceSize |= (tmp) << 2;
/* Byte 8 */
tmp = (u8)((CSD_Tab[2] & 0xFF000000) >> 24);
cardinfo->SD_csd.DeviceSize |= (tmp & 0xC0) >> 6;
cardinfo->SD_csd.MaxRdCurrentVDDMin = (tmp & 0x38) >> 3;
cardinfo->SD_csd.MaxRdCurrentVDDMax = (tmp & 0x07);
/* Byte 9 */
tmp = (u8)((CSD_Tab[2] & 0x00FF0000) >> 16);
cardinfo->SD_csd.MaxWrCurrentVDDMin = (tmp & 0xE0) >> 5;
cardinfo->SD_csd.MaxWrCurrentVDDMax = (tmp & 0x1C) >> 2;
cardinfo->SD_csd.DeviceSizeMul = (tmp & 0x03) << 1;
/* Byte 10 */
tmp = (u8)((CSD_Tab[2] & 0x0000FF00) >> 8);
cardinfo->SD_csd.DeviceSizeMul |= (tmp & 0x80) >> 7;
cardinfo->SD_csd.EraseGrSize = (tmp & 0x40) >> 6;
cardinfo->SD_csd.EraseGrMul = (tmp & 0x3F) << 1;
/* Byte 11 */
tmp = (u8)(CSD_Tab[2] & 0x000000FF);
cardinfo->SD_csd.EraseGrMul |= (tmp & 0x80) >> 7;
cardinfo->SD_csd.WrProtectGrSize = (tmp & 0x7F);
/* Byte 12 */
tmp = (u8)((CSD_Tab[3] & 0xFF000000) >> 24);
cardinfo->SD_csd.WrProtectGrEnable = (tmp & 0x80) >> 7;
cardinfo->SD_csd.ManDeflECC = (tmp & 0x60) >> 5;
cardinfo->SD_csd.WrSpeedFact = (tmp & 0x1C) >> 2;
cardinfo->SD_csd.MaxWrBlockLen = (tmp & 0x03) << 2;
/* Byte 13 */
tmp = (u8)((CSD_Tab[3] & 0x00FF0000) >> 16);
cardinfo->SD_csd.MaxWrBlockLen |= (tmp & 0xC0) >> 6;
cardinfo->SD_csd.WriteBlockPaPartial = (tmp & 0x20) >> 5;
cardinfo->SD_csd.Reserved3 = 0;
cardinfo->SD_csd.ContentProtectAppli = (tmp & 0x01);
/* Byte 14 */
tmp = (u8)((CSD_Tab[3] & 0x0000FF00) >> 8);
cardinfo->SD_csd.FileFormatGrouop = (tmp & 0x80) >> 7;
cardinfo->SD_csd.CopyFlag = (tmp & 0x40) >> 6;
cardinfo->SD_csd.PermWrProtect = (tmp & 0x20) >> 5;
cardinfo->SD_csd.TempWrProtect = (tmp & 0x10) >> 4;
cardinfo->SD_csd.FileFormat = (tmp & 0x0C) >> 2;
cardinfo->SD_csd.ECC = (tmp & 0x03);
/* Byte 15 */
tmp = (u8)(CSD_Tab[3] & 0x000000FF);
cardinfo->SD_csd.CSD_CRC = (tmp & 0xFE) >> 1;
cardinfo->SD_csd.Reserved4 = 1;
/* Byte 0 */
tmp = (u8)((CID_Tab[0] & 0xFF000000) >> 24);
cardinfo->SD_cid.ManufacturerID = tmp;
/* Byte 1 */
tmp = (u8)((CID_Tab[0] & 0x00FF0000) >> 16);
cardinfo->SD_cid.OEM_AppliID = tmp << 8;
/* Byte 2 */
tmp = (u8)((CID_Tab[0] & 0x000000FF00) >> 8);
cardinfo->SD_cid.OEM_AppliID |= tmp;
/* Byte 3 */
tmp = (u8)(CID_Tab[0] & 0x000000FF);
cardinfo->SD_cid.ProdName1 = tmp << 24;
/* Byte 4 */
tmp = (u8)((CID_Tab[1] & 0xFF000000) >> 24);
cardinfo->SD_cid.ProdName1 |= tmp << 16;
/* Byte 5 */
tmp = (u8)((CID_Tab[1] & 0x00FF0000) >> 16);
cardinfo->SD_cid.ProdName1 |= tmp << 8;
/* Byte 6 */
tmp = (u8)((CID_Tab[1] & 0x0000FF00) >> 8);
cardinfo->SD_cid.ProdName1 |= tmp;
/* Byte 7 */
tmp = (u8)(CID_Tab[1] & 0x000000FF);
cardinfo->SD_cid.ProdName2 = tmp;
/* Byte 8 */
tmp = (u8)((CID_Tab[2] & 0xFF000000) >> 24);
cardinfo->SD_cid.ProdRev = tmp;
/* Byte 9 */
tmp = (u8)((CID_Tab[2] & 0x00FF0000) >> 16);
cardinfo->SD_cid.ProdSN = tmp << 24;
/* Byte 10 */
tmp = (u8)((CID_Tab[2] & 0x0000FF00) >> 8);
cardinfo->SD_cid.ProdSN |= tmp << 16;
/* Byte 11 */
tmp = (u8)(CID_Tab[2] & 0x000000FF);
cardinfo->SD_cid.ProdSN |= tmp << 8;
/* Byte 12 */
tmp = (u8)((CID_Tab[3] & 0xFF000000) >> 24);
cardinfo->SD_cid.ProdSN |= tmp;
/* Byte 13 */
tmp = (u8)((CID_Tab[3] & 0x00FF0000) >> 16);
cardinfo->SD_cid.Reserved1 |= (tmp & 0xF0) >> 4;
cardinfo->SD_cid.ManufactDate = (tmp & 0x0F) << 8;
/* Byte 14 */
tmp = (u8)((CID_Tab[3] & 0x0000FF00) >> 8);
cardinfo->SD_cid.ManufactDate |= tmp;
/* Byte 15 */
tmp = (u8)(CID_Tab[3] & 0x000000FF);
cardinfo->SD_cid.CID_CRC = (tmp & 0xFE) >> 1;
cardinfo->SD_cid.Reserved2 = 1;
return(errorstatus);
}
/*******************************************************************************
* 函数名 : SD_EnableWideBusOperation
* 功能描述 : 使能SD卡数据传输模式(SD_8/4/1位模式)
* 输入 : 位宽度模式
* - SDIO_BusWide_8b: 8位数据传输 (仅MMC卡)
* - SDIO_BusWide_4b: 4位数据传输
* - SDIO_BusWide_1b: 1位数据传输
* 输出 : 无
* 返回 : SD_Error: SD卡错误代码
*******************************************************************************/
SD_Error SD_EnableWideBusOperation(u32 WideMode)
{
SD_Error errorstatus = SD_OK;
/* MMC不支持此操作 */
if (SDIO_MULTIMEDIA_CARD == CardType)
{
errorstatus = SD_UNSUPPORTED_FEATURE;
return(errorstatus);
}
else if ((SDIO_SECURE_DIGITAL_CARD == CardType) || (SDIO_HIGH_CAPACITY_SD_CARD == CardType))
{
if (SDIO_BusWide_8b == WideMode)
{
errorstatus = SD_UNSUPPORTED_FEATURE;
return(errorstatus);
}
else if (SDIO_BusWide_4b == WideMode)
{
errorstatus = SDEnWideBus(ENABLE);
if (SD_OK == errorstatus)
{
/* 配置SDIO外设 */
SDIO_InitStructure.SDIO_ClockDiv = SDIO_TRANSFER_CLK_DIV;
SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising;
SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable;
SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable;
SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_4b;
SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;/*硬件流控*/
SDIO_Init(&SDIO_InitStructure);
}
}
else
{
errorstatus = SDEnWideBus(DISABLE);
if (SD_OK == errorstatus)
{
/* 配置SDIO外设 */
SDIO_InitStructure.SDIO_ClockDiv = SDIO_TRANSFER_CLK_DIV;
SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising;
SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable;
SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable;
SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b;
SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;
SDIO_Init(&SDIO_InitStructure);
}
}
}
return(errorstatus);
}
/*******************************************************************************
* 函数名 : SD_SetDeviceMode
* 功能描述 : Sets device mode whether to operate in Polling, Interrupt or
* DMA mode.
* 输入 : Mode: Specifies the Data Transfer mode.
* This parameter can be one of the following values:
* - SD_DMA_MODE: Data transfer using DMA.
* - SD_INTERRUPT_MODE: Data transfer using interrupts.
* - SD_POLLING_MODE: Data transfer using flags.
* 输出 : None
* 返回 : SD_Error: SD Card Error code.
*******************************************************************************/
SD_Error SD_SetDeviceMode(u32 Mode)
{
SD_Error errorstatus = SD_OK;
if ((Mode == SD_DMA_MODE) || (Mode == SD_INTERRUPT_MODE) || (Mode == SD_POLLING_MODE))
{
DeviceMode = Mode;
}
else
{
errorstatus = SD_INVALID_PARAMETER;
}
return(errorstatus);
}
/*******************************************************************************
* 函数名 : SD_SelectDeselect
* 功能描述 : Selects od Deselects the corresponding card.
* 输入 : addr: Address of the Card to be selected.
* 输出 : None
* 返回 : SD_Error: SD Card Error code.
*******************************************************************************/
SD_Error SD_SelectDeselect(u32 addr)
{
SD_Error errorstatus = SD_OK;
/* Send CMD7 SDIO_SEL_DESEL_CARD */
SDIO_CmdInitStructure.SDIO_Argument = addr;
SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SEL_DESEL_CARD;
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_SEL_DESEL_CARD);
return(errorstatus);
}
/*******************************************************************************
* 函数名 : SD_ReadBlock
* 功能描述 : 读块.
* 输入 : - addr: 指定数据地址.
* - readbuff: 缓存指针
* - blocksize: 数据块大小.
* 输出 : 无
* 返回 : SD_Error: 错误代码.
*******************************************************************************/
SD_Error SD_ReadBlock(u32 addr, u32 *readbuff, u16 BlockSize)
{
SD_Error errorstatus = SD_OK;
u32 count = 0, *tempbuff = readbuff;
u8 power = 0;
if (NULL == readbuff)
{
errorstatus = SD_INVALID_PARAMETER;
return(errorstatus);
}
TransferError = SD_OK;
TransferEnd = 0;
TotalNumberOfBytes = 0;
/* 清除DPSM配置 */
SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
SDIO_DataInitStructure.SDIO_DataLength = 0;
SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DataBlockSize_1b;
SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToCard;
SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Disable;
SDIO_DataConfig(&SDIO_DataInitStructure);
SDIO_DMACmd(DISABLE);
if (SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED)
{
errorstatus = SD_LOCK_UNLOCK_FAILED;
return(errorstatus);
}
if ((BlockSize > 0) && (BlockSize <= 2048) && ((BlockSize & (BlockSize - 1)) == 0))
{
power = convert_from_bytes_to_power_of_two(BlockSize);
/*设定块大小*/
SDIO_CmdInitStructure.SDIO_Argument = (u32) BlockSize;
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 (SD_OK != errorstatus)
{
return(errorstatus);
}
}
else
{
errorstatus = SD_INVALID_PARAMETER;
return(errorstatus);
}
SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
SDIO_DataInitStructure.SDIO_DataLength = BlockSize;
SDIO_DataInitStructure.SDIO_DataBlockSize = (u32) power << 4;
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);
TotalNumberOfBytes = BlockSize;
StopCondition = 0;
DestBuffer = readbuff;
/* 发送命令CMD17 READ_SINGLE_BLOCK */
SDIO_CmdInitStructure.SDIO_Argument = (u32)addr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -