基于ARM含SD控制器的SD卡的SDIO模式驱动解析
goto SET_BUS;
}
4.2SD卡的读与写
读写就是正反向的问题,这里只分析读
步骤:1)读单block CMD17 多block CMD18
(写单block CMD24 多block CMD25)
2)发送CMD12,终止数据传输
程序如下:采用DMA模式
void Rd_Block(void)
{
int status;
rd_cnt=0;
rSDICON |= rSDICON|(1<<1); // FIFO reset
rSDICARG=0x0; // CMD17/18(addr参数)
RERDCMD:
pISR_DMA0=(unsigned)DMA_end; //DMA的相关配置
rINTMSK = ~(BIT_DMA0);
rDISRC0=(int)(SDIDAT); // SDIDAT
rDISRCC0=(1<<1)+(1<<0); // APB, fix
rDIDST0=(U32)(Rx_buffer); // Rx_buffer
rDIDSTC0=(0<<1)+(0<<0); // AHB, inc
rDCON0=(1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(2<<24)+(1<<23)+(1<<22)+(2<<20)+128*block;
//handshake, sync PCLK, TC int, single tx, single service, SDI, H/W request,
//auto-reload off, word, 128blk*num
rDMASKTRIG0=(0<<2)+(1<<1)+0;
//no-stop, DMA2 channel on, no-sw trigger
rSDIDCON=(1<<19)|(1<<17)|(Wide<<16)|(1<<15)|(2<<12)|(block<<0);
// Rx after rsp, blk, 4bit bus, dma enable, Rx start, blk num
if(block<2) // SINGLE_READ
{
rSDICCON=(0x1<<9)|(0x1<<8)|0x51;
// sht_resp, wait_resp, dat, start, CMD17
if(!Chk_CMDend(17, 1))
//-- Check end of CMD17
goto RERDCMD;
}
else // MULTI_READ
{
rSDICCON=(0x1<<9)|(0x1<<8)|0x52;
// sht_resp, wait_resp, dat, start, CMD18
if(!Chk_CMDend(18, 1))
//-- Check end of CMD18
goto RERDCMD;
}
while(!TR_end);
rINTMSK |= (BIT_DMA0);
TR_end=0;
rDMASKTRIG0=(1<<2); //DMA0 stop
break;
default:
break;
}
//-- Check end of DATA
if(!Chk_DATend())
;
rSDIDSTA=0x10; // Clear data Tx/Rx end
if(block>1)
{
RERCMD12:
//--Stop cmd(CMD12)
rSDICARG=0x0; //CMD12(stuff bit)
rSDICCON=(0x1<<9)|(0x1<<8)|0x4c;
//sht_resp, wait_resp, start, CMD12
//-- Check end of CMD12
if(!Chk_CMDend(12, 1))
goto RERCMD12;
}
}
4.3上面用到的响应判断函数
主要完成对反馈状态的分析。
函数如下:
int Chk_CMDend(int cmd, int be_resp) //指令反馈判断函数
{
int finish0;
if(!be_resp) // No response
{
finish0=rSDICSTA;
while((finish0&0x800)!=0x800) // 验证指令是不是发送
finish0=rSDICSTA;
rSDICSTA=finish0; // Clear cmd end state
return 1;
}
else // With response
{
finish0=rSDICSTA;
while( !( ((finish0&0x200)==0x200) | ((finish0&0x400)==0x400) ))
// 验证反馈响应完成
finish0=rSDICSTA;
if(cmd==1 | cmd==9 | cmd==41) // CRC no check
{
if( (finish0&0xf00) != 0xa00 ) // CRC是否错误
{
rSDICSTA=finish0; // Clear error state
if(((finish0&0x400)==0x400)) // 验证超时
return 0; }
rSDICSTA=finish0;
// Clear cmd & rsp end state
}
else // CRC check
{
if( (finish0&0x1f00) != 0xa00 ) // Check error
{
;
rSDICSTA=finish0; // Clear error state
if(((finish0&0x400)==0x400))
return 0; // Timeout error
}
rSDICSTA=finish0;
}
return 1;
}
}
int Chk_DATend(void)
{
int finish
- Linux嵌入式系统开发平台选型探讨(11-09)
- 基于ARM体系的嵌入式系统BSP的程序设计方案(04-11)
- 在Ubuntu上建立Arm Linux 开发环境(04-23)
- 达芬奇数字媒体片上系统的架构和Linux启动过程(06-02)
- SQLite嵌入式数据库系统的研究与实现(02-20)
- 革新2410D开发板试用手记(04-21)