sd_error read_block(uint32_t addr,uint32_t len,uint8_t *data)
{
uint8_t temp;
SDIO_DataInitTypeDef SDIO_DATA;
u32 count=0;
uint32_t timeout;
uint32_t *tempbuff=(u32*)data;
SDIO_DATA.SDIO_DataBlockSize=SDIO_DataBlockSize_1b;
SDIO_DATA.SDIO_DataLength=0;
SDIO_DATA.SDIO_DataTimeOut=0xFFFFFFFF;
SDIO_DATA.SDIO_DPSM=SDIO_DPSM_Enable;
SDIO_DATA.SDIO_TransferDir=SDIO_TransferDir_ToCard;
SDIO_DATA.SDIO_TransferMode=SDIO_TransferMode_Block;
if(flag_bit_transfer=!1)
{
sd_send_commder(7,(uint32_t)(rca<<16),SDIO_Response_Short);
temp=cmdresponse7();
if(temp!=sd_ok) return temp;
flag_bit_transfer=1;
}
SDIO_DataConfig(&SDIO_DATA);
sd_send_commder(16,0x00000200,SDIO_Response_Short);
temp=cmdresponse7();
if(temp!=sd_ok) return temp;
SDIO_DATA.SDIO_DataBlockSize=SDIO_DataBlockSize_512b;
SDIO_DATA.SDIO_DataLength=len;
SDIO_DATA.SDIO_DataTimeOut=0xFFFFFFFF;
SDIO_DATA.SDIO_DPSM=SDIO_DPSM_Enable;
SDIO_DATA.SDIO_TransferDir=SDIO_TransferDir_ToSDIO;
SDIO_DATA.SDIO_TransferMode=SDIO_TransferMode_Block;
SDIO_DataConfig(&SDIO_DATA);
sd_send_commder(17,(uint32_t)addr,SDIO_Response_Short);
temp=cmdresponse7();
if(temp!=sd_ok) return temp;
SDIO->ICR|=(1<<5);
while(!(SDIO->STA&((1<<5)|(1<<1)|(1<<3)|(1<<10)|(1<<9))))//无上溢/CRC/超时/完成(标志)/起始位错误
{
if(SDIO_GetFlagStatus(SDIO_FLAG_RXFIFOHF) != RESET) //接收区半满,表示至少存了8个字
{
for(count=0;count<8;count++) //循环读取数据
{
*(tempbuff+count)=SDIO->FIFO;
}
tempbuff+=8;
timeout=0X7FFFFF; //读数据溢出时间
}else //处理超时
{
if(timeout==0)return sd_timeout;
timeout--;
}
}
if(SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET) //数据超时错误
{
SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT); //清错误标志
return sd_timeout;
}else if(SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET) //数据块CRC错误
{
SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL); //清错误标志
return sd_dcrcerror;
}else if(SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET) //接收fifo上溢错误
{
SDIO_ClearFlag(SDIO_FLAG_RXOVERR); //清错误标志
return sd_rxoverr;
}else if(SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET) //接收起始位错误
{
SDIO_ClearFlag(SDIO_FLAG_STBITERR);//清错误标志
return sd_stbiterr;
}
while(SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET) //FIFO里面,还存在可用数据
{
*tempbuff=SDIO->FIFO; //循环读取数据
tempbuff++;
}
SDIO_ClearFlag(0x000005FF);//清除所有标记
return sd_ok;
}
其中接收部分是模仿正点原子的。
坑:
1、千万不要在读取sd卡的时候调试,坑死了,一调试就是fifo上溢错误,***我调了4个小时,最后想着要不先运行一下(破罐子破摔),结果读出数据了。我那个绝望啊
2、关于数据路径接收机的配置,还有一种思路是直接调用内部的函数
SDIO_StartSDIOReadWait();
SDIO_SetSDIOReadWaitMode()
我也已经验证,可以顺利读到数据(其实是使用数据路径状态机的读等待功能)只需要在发送完读命令后打开状态机即可。
终于可以睡个好觉了!
sd卡第 0扇区的数据,激动!!
sd_init return value=64
sd card size is =15601664
sd card set 4 bit bus width =64
sd card read block result =64
sd card The first 440 data =47
sd card The first 441 data =45
sd card The first 442 data =12
sd card The first 443 data =47
sd card The first 448 data =1
sd card The first 449 data =1
sd card The first 450 data =c
sd card The first 451 data =3f
sd card The first 452 data =e0
sd card The first 453 data =80
sd card The first 460 data =dc
sd card The first 461 data =1
sd card The first 510 data =55
sd card The first 511 data =aa