📄 spi_sd.c
字号:
tmp=sdcard_command2(CMD55);
if(tmp !=1)
continue;
tmp=sdcard_command1(ACMD41);
if(timeout++>1000)
{
return 2;
}
}
return 0;
}
/*
* sdcard multiple block read routine.
* @param addr: data address
* @param buf : data buf
* @param block_num: data block num
* @param off: data offset address
* @return value:
* 0-- sdcard read ok 1-- CMD18 send failture
* 2-- read ready state error 3-- read ready timeout error
* 4-- wait read ready ok flag tineout error 5-- CMD18 send failture
* 6-- wait sdcard free timeout error 10-- sdcard dma mode transfer failture
*
*/
#ifdef CONFIG_SSP_DMA
unsigned int sdcard_read(unsigned int addr,unsigned int off,unsigned int block_num)
#else
unsigned int sdcard_read(unsigned int addr,unsigned char *buf,unsigned int block_num)
#endif
{
unsigned char CMD18[] = {0x52,0x00,0x00,0x00,0x00,0xFF};
unsigned char CMD12[] = {0x4c,0x00,0x00,0x00,0x00,0xFF};
unsigned int i=0,num=0,timeout=0;
unsigned char temp=0;
#ifdef CONFIG_SSP_DMA
DECLARE_WAITQUEUE(wait, current);
#endif
CMD18[1] = ((addr & 0xFF000000) >> 24);
CMD18[2] = ((addr & 0x00FF0000) >> 16);
CMD18[3] = ((addr & 0x0000FF00) >> 8);
sdcard_disable();
for (i=0;i<64;i++)
{
sdcard_read_byte();
}
temp=sdcard_command2(CMD18);
if (temp!=0)
return 1;
for(num=0;num<block_num;num++)
{
timeout=0;
do{
temp=sdcard_read_byte();
if(temp == 15)
return(2);
if(timeout++ > timeout_read)
return(3);
}while (temp != 0xff);
timeout=0;
do{
temp=sdcard_read_byte();
if(timeout++ > timeout_read)
return(4);
}while(temp != 0xfe);
#ifdef CONFIG_SSP_DMA
sd_add_wait(&wait);
if(hi_ssp_dmac_transfer((dmac_ssp_s.ssprxchbufaddress + off+512*num),dmac_ssp_temp_s.txbufaddress,0x200) !=0)
return 10;
schedule();
sd_rm_wait(&wait);
#else
for(i=0;i<512;i++)
{
*(buf+i+512*num) = sdcard_read_byte();
}
#endif
sdcard_read_byte();
sdcard_read_byte();
}
timeout=0;
do{
temp=sdcard_command2(CMD12);
if(timeout++ >10000)
{
return (5);
}
}while(temp!=0);
timeout=0;
do{
temp=sdcard_read_byte();
if(timeout++ > 10000)
{
return(6);
}
}while (temp != 0xff);
sdcard_disable();
for(i=0;i<64;i++)
{
sdcard_read_byte();
}
return 0;
}
/*
* sdcard multiple block write routine.
* @param addr: data address
* @param buf : data buf
* @param block_num: data block num
* @param off: data offset address
* @return value:
* 0-- sdcard write ok 1-- CMD25 send failture
* 2-- wait ack error 3-- wait sdcard free timeout error
* 4-- wait sdcard write stop free timeout error
* 10-- sdcard dma mode transfer failture
*
*/
#ifdef CONFIG_SSP_DMA
unsigned int sdcard_write(unsigned int addr,unsigned int off,unsigned int block_num)
#else
unsigned int sdcard_write(unsigned int addr,unsigned char *buf,unsigned int block_num)
#endif
{
unsigned char CMD25[] = {0x59,0x00,0x00,0x00,0x00,0x95};
unsigned int i=0,num=0,timeout=0;
unsigned char temp;
#ifdef CONFIG_SSP_DMA
DECLARE_WAITQUEUE(wait, current);
#endif
CMD25[1] = ((addr & 0xFF000000) >> 24);
CMD25[2] = ((addr & 0x00FF0000) >> 16);
CMD25[3] = ((addr & 0x0000FF00) >> 8);
sdcard_disable();
for (i=0;i<64;i++)
{
sdcard_read_byte();
}
temp = sdcard_command2(CMD25);
if (temp!=0)
return 1;
for(num=0;num<block_num;num++)
{
sdcard_write_byte(0xFC);
#ifdef CONFIG_SSP_DMA
sd_add_wait(&wait);
if(hi_ssp_dmac_transfer(dmac_ssp_temp_s.rxbufaddress,(dmac_ssp_s.ssptxchbufaddress + off+512*num),0x200) !=0)
return 10;
schedule();
sd_rm_wait(&wait);
#else
for (i = 0; i < 512; i++)
{
sdcard_write_byte(*(buf+i+512*num));
}
#endif
timeout=0;
do{
temp=sdcard_read_byte();
if(timeout++ >timeout_write)
{
return 2;
}
}while (temp != 0xe5);
timeout=0;
do{
temp=sdcard_read_byte();
if(timeout++ >timeout_write)
{
return 3;
}
}while(temp!=0xff);
}
sdcard_write_byte(0xFD);
timeout=0;
do{
temp=sdcard_read_byte();
if(timeout++ >1000)
{
return(4);
}
}while(temp!=0xff);
sdcard_disable();
for (i = 0; i < 64; ++i)
{
sdcard_write_byte(0xFF);
}
return 0;
}
/*
* read sdcard cid routine.
*
* @return value:
* 0-- success; 1-- cmd10 send failture.
* 2-- wait read ready ok flag tineout error
*
*/
unsigned int sdcard_cid_read(void)
{
unsigned int temp=0xff,i,timeout=0;
unsigned char CMD10[]={0x4a,0x00,0x00,0x00,0x00,0x95};
unsigned char cid[16];
unsigned char mid;
unsigned short oid;
unsigned char pnm[5];
unsigned char prv;
unsigned int psn;
unsigned short mdt;
sdcard_disable();
for(i=0;i<0xf;i++)
{
while (hi_ssp_busystate_check());
hi_ssp_writedata(0xff);
}
while (hi_ssp_busystate_check());
hi_ssp_writedata(0xff);
sdcard_enable();
for(i=0;i<6;i++)
{
while (hi_ssp_busystate_check());
hi_ssp_writedata(CMD10[i]);
}
while (temp != 0x0)
{
while (hi_ssp_busystate_check());
hi_ssp_writedata(0xff);
while (hi_ssp_busystate_check());
temp = hi_ssp_readdata();
if (timeout++ > 100)
{
sdcard_disable();
return (1);
}
}
while (temp != 0xfe)
{
while (hi_ssp_busystate_check());
hi_ssp_writedata(0xff);
while (hi_ssp_busystate_check());
temp = hi_ssp_readdata();
if (timeout++ > 100)
{
sdcard_disable();
return (2);
}
}
for(i=0;i<16;i++)
cid[i]=sdcard_read_byte();
sdcard_write_byte(0xFF);
sdcard_write_byte(0xFF);
for(i=0;i<16;i++)
{
sdcard_read_byte();
}
sdcard_disable();
mid=cid[0];
oid=cid[1]*256+cid[2];
pnm[0]=cid[3+0];pnm[1]=cid[3+1];pnm[2]=cid[3+2];pnm[3]=cid[3+3];pnm[4]=cid[3+4];
prv=cid[8];
psn=cid[9]*256*256*256+cid[10]*256*256+cid[11]*256+cid[12];
mdt=cid[13]*256+cid[14];mdt&=0x0fff;
printk(" %c%c%c%c%c ",pnm[0],pnm[1],pnm[2],pnm[3],pnm[4]);
return(0);
}
/*
* read sdcard csd routine.
*
* @return value:
* 0-- sdcard capacity get error size-- get sdcard capacity (Byte)
*
*/
unsigned int sdcard_csd_read(void)
{
unsigned int temp=0xff,i;
unsigned char CMD9[]={0x49,0x00,0x00,0x00,0x00,0x95};
unsigned char csd[32];
unsigned int c_size;
unsigned int c_size_mult;
unsigned int mult;
unsigned int read_bl_len;
unsigned int blocknr = 0;
unsigned int block_len = 0;
unsigned int size = 0;
unsigned int timeout=0;
unsigned int taac=0,nsac=0,tmp;
unsigned int read_timeout_100ms,write_timeout_250ms;
unsigned char time_u, time_v, fator;
struct clk *clk_temp;
unsigned long ahb_clk,spi_clock;
sdcard_disable();
for(i=0;i<0xf;i++)
{
while (hi_ssp_busystate_check());
hi_ssp_writedata(0xff);
}
while (hi_ssp_busystate_check());
hi_ssp_writedata(0xff);
sdcard_enable();
for(i=0;i<6;i++)
{
while (hi_ssp_busystate_check());
hi_ssp_writedata((CMD9[i]));
}
while (temp != 0x0)
{
while (hi_ssp_busystate_check());
hi_ssp_writedata(0xff);
while (hi_ssp_busystate_check());
temp = hi_ssp_readdata();
if (timeout++ > 100)
{
sdcard_disable();
return (0);
}
}
while (temp != 0xfe)
{
while (hi_ssp_busystate_check());
hi_ssp_writedata(0xff);
while (hi_ssp_busystate_check());
temp = hi_ssp_readdata();
if (timeout++ > 100)
{
sdcard_disable();
return (0);
}
}
for(i=0;i<16;i++)
csd[i]=sdcard_read_byte();
sdcard_write_byte(0xFF);
sdcard_write_byte(0xFF);
for(i=0;i<16;i++)
{
sdcard_read_byte();
}
sdcard_disable();
c_size = csd[8] + csd[7] * 256 + (csd[6] & 0x03) * 256 * 256;
c_size >>= 6;
c_size_mult = csd[10] + (csd[9] & 0x03) * 256;
c_size_mult >>= 7;
read_bl_len = csd[5] & 0x0f;
mult = 1;
mult <<= c_size_mult + 2;
blocknr = (c_size + 1) * mult;
block_len = 1;
block_len <<= read_bl_len;
size = block_len * blocknr;
taac = csd[1];
nsac = csd[2];
time_u = csd[1] & 0x07;
time_v = (csd[1] & 0x78) >> 3;
fator = (csd[12] & 0x1c) >> 3;
if(time_v == 0)
{
printk("time_v = 0\n");
return 0;
}
if(fator >= 6)
{
printk("fator >= 6\n");
return 0;
}
clk_temp = clk_get(NULL,"AHBCLK");
ahb_clk = clk_get_rate(clk_temp);
#ifdef CONFIG_SSP_DMA
spi_clock = ahb_clk/10;
#else
spi_clock = ahb_clk/6;
#endif
if(spi_clock > 25000000)
{
printk("spi clock is more than 25MHZ!\n");
return 0;
}
tmp = spi_clock * time_value[time_v] / 10 / time_unit[time_u];
tmp = tmp + csd[2] * 100;
timeout_read = tmp;
timeout_write = tmp * r2w_fator[fator];
timeout_read = timeout_read * 100/8;
timeout_write = timeout_write * 100/8;
read_timeout_100ms = 100 * (spi_clock/1000) / 8;
write_timeout_250ms = 250 * (spi_clock/1000) / 8;
if(timeout_read < read_timeout_100ms)
timeout_read = read_timeout_100ms;
if(timeout_write < write_timeout_250ms)
timeout_write = write_timeout_250ms;
return(size);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -