SD卡驱动,4bit模式,读Card Registers有问题,SCR,CID and CSD
搜索了 不少文章,没找到合适的建议,问题还没解决。主要问题在于 SD_init().中读取特定寄存器的问题--Card Registers, ----OCR, CID ,CSD, RCA DSR,SCR. 有谁熟悉这块,帮忙看一下问题所在...
参考手册为:
1。SD Specification Part A2 SD Host Controller Standard Simplified Specification Version 1.00 April 3, 2006
2。SD Specifications Part 1 PHYSICAL LAYER Simplified Specification Version 1.10 April 3, 2006
Code:
void sdio_wait(int max)
{
int i;
for (i=0; i<max; i++)
asm("nop");
}
/*
Sd_cmd(SD_CMD_APP_CMD_55, 1, 1, 0x02, 0x00000000); //R1
发送命令函数 注明参数:
SD_CMD_APP_CMD_55: CMD55, 对应返回R1 ,对应设置后3项为:1 , 1 , 0x2
1: Index Check Enable
1: RC Check Enable
2: 返回的信息长度,1:136bit 2:48bit
0x00000000: CMD命令对应的输入参数
此处有一疑问:返回有R1 R2 R3 R4 R5 R6 R1b R5b,但是读返回值都应该是在如下的附表1 中,response0--response7中啊,那个R1 R2 R3 有什么区别么?*/
void sdio_init(void)
{
/* Set the frequency divisor to 8 <<8 | Enable internal clock. */
reg[SOFT_RST] = (0x04<<8)| 0x01;
/* After the internal clock is stable: Software reset | Data timeout counter <<16| | Enable SD clock. */
while(0 == (reg[SOFT_RST]&0x00000002))
sdio_wait(8);
reg[SOFT_RST] = (0x07<<24)| (0x00<<16)| reg[SOFT_RST]| 0x04; //内部时钟稳定后,使能SD时钟
sdio_wait(128);
/* Status and signals enable */
reg[INTR_STATUS_EN] = 0x01ff01f7;
reg[INTR_SIGNAL_EN] = 0x01ff01f7;
/*Enable interrupt at block gap| Set bus voltage 3.3| Normal Speed| Data width 4 bit| LED off*/
reg[WAKEUP_CONTROL] = (0x08<<16)| (0x07<<9)| (0x00<<2)| (0x01<<1)| 0x00;
sdio_wait(8);
/*SD bus power on <<8 */
reg[WAKEUP_CONTROL] |= (0x01<<8); //后给SD bus上电
sdio_wait(128);
/* CMD0: Set SD card enter idle state */
Sd_cmd(SD_CMD_GO_IDLE_STATE, 0, 0, 0x00, 0x00000000); //使SD card 进入idle状态
sdio_wait(1024);
/*Check the SD card, if no device, power down the bus, disable the internal clock, and return.*/
/*
if(no device) //???????????????????????? //这块有问题,通过哪个寄存器来检测,SD卡是否插入
{
Power_down_SD();
return;
}
*/
/*Check the SD card state ,write enable or protected.*/
if(0 == (reg[PRESENT_STATE]&0x80000)) //如果有卡,此时if成立的话,此卡已经把写保护的开关打开,能读不能写入
{
//the card can be read, but can't write ,read only, and can't modify the access time. else read and write enable.
}
/* ACMD41: read OCR register to R3, Response Length :48 */
//此处发送ACMD41命令 读取Card Registers 中的OCR值,返回为0x80ff8000,表明电压范围是2.7--3.6V,此处读取没有错误,放在reg[RESPONSE_1]中。
do
{
Sd_cmd(SD_CMD_APP_CMD, 1, 1, 0x02, 0x00000000); //R1
Sd_cmd(SD_ACMD_SD_SEND_OP_COND, 0, 0, 0x02, 0x00ff8000); //R3
sdio_wait(128);
}while(!(reg[RESPONSE_1]&0x80000000)); //bit 31 --> 1, the power up finished, 0:busy
/*Test OCR here.... VDD voltage 2.7-3.6v */
if(-1 == Ocr_check(reg[RESPONSE_1]))
{
Power_down_SD(); //OCR error
return;
}
/* CMD2: Get CID 128bit*/ //读取CID ,感觉数据不对,跟CID的各值意义对不上号
Sd_cmd(SD_CMD_ALL_SEND_CID, 0, 1, 0x01, 0x00000000); //R2
/* CMD3: Get new RCA 16bit*/ //此处读取RCA ,返回结果0x12340000,0x1234是新的RCA 16bit,
Sd_cmd(SD_CMD_SEND_REL_ADDR, 1, 1, 0x02, 0x00000000); //R6 RCA = reg[RESPONSE_1]&0xFFFF0000;
printf("RCA = 0x%x\n", RCA);
/* CMD9: Get CSD 128bit*/ //读取CSD,为 CSD = 0x4f0032 5f59a3cb ffffff8f 8a400000 data=55aabb41 ,肯定错了
Sd_cmd(SD_CMD_SEND_CSD, 0, 1, 0x01, RCA); //R2
printf("CSD = 0x%x %x %x %x data=%x\n", reg[RESPONSE_1], reg[RESPONSE_2], reg[RESPONSE_3], reg[RESPONSE_4], reg[DATA_PORT]);
/* CMD7: Select the card*/
Sd_cmd(SD_CMD_SELECT_CARD, 1, 1, 0x03, RCA); //R1b
/* CMD13: get the addressed card status register */ //???????????????
Sd_cmd(SD_CMD_SEND_STATUS, 1, 1, 0x02, RCA); //R1
/* CMD16: Set the block length, 0x200 = 512*/ //???????????????? 应该根据读出来的CSD 值,来设定block的大小,现在直接设定了512。
Sd_cmd(SD_CMD_SET_BLOCKLEN, 1, 1, 0x02, 0x200); //R1
/*ACMD51: get the SCR, (51:adtc, DAT), 64bit */
//此处读取,SCR,打印出的值分别是:SCR2 = 0x920 5f59a3cb ffffff8f 8a400000 data=a2ef6aab, 对不上SCR的值,这个重要,要根据这个card的DAT Bus widths supported参数设定 DAT Bus 的widths,现在因为读不出来,就直接设定的width为4bit。????????? printf("SCR1 = 0x%x %x %x %x data=%x\n", reg[RESPONSE_1], reg[RESPONSE_2], reg[RESPONSE_3], reg[RESPONSE_4], reg[DATA_PORT]);
Sd_cmd(SD_CMD_APP_CMD, 1, 1, 0x02, RCA); //R1
Sd_cmd(SD_ACMD_SEND_SCR, 1, 1, 0x02, 0x00000000); //R1
printf("SCR2 = 0x%x %x %x %x data=%x\n", reg[RESPONSE_1], reg[RESPONSE_2], reg[RESPONSE_3], reg[RESPONSE_4], reg[DATA_PORT]);
/*ACMD6: set bus width 4bit */
Sd_cmd(SD_CMD_APP_CMD, 1, 1, 0x02, RCA); //R1
Sd_cmd(SD_ACMD_SET_BUS_WIDTH, 1, 1, 0x02, 0x00000002); //R1 //???????????????? should according to the SCR
sdio_wait(128);
return;
}
以上红色部分,为有问题部分,请帮忙分析一下。reg[RESPONSE_1], reg[RESPONSE_2], reg[RESPONSE_3], reg[RESPONSE_4], reg[DATA_PORT]); 分别对应以下Register Map offset为:0x10 0x14 0x18 0x1c(response) , 0x20(data)的数据。
附表1:SD Host Control Register Map
Offset 15-08 bit 07-00 bit Offset 15-08 bit 07-00 bit
002h System Address (High)000h System Address (Low)
006h Block Count 004h Block Size
00Ah Argument1 008h Argument0
00Eh Command 00Ch Transfer Mode
012h Response1 010h Response0
016h Response3 014h Response2
01Ah Response5 018h Response4
01Eh Response7 01Ch Response6
022h Buffer Data Port1 020h Buffer Data Port0
026h Present State 024h Present State
02Ah Wakeup Control Block Gap Control 028h Power Control Host Control
02Eh Software Reset Timeout Control 02Ch Clock Control
032h Error Interrupt Status 030h Normal Interrupt Status
036h Error Interrupt Status Enable 034h Normal Interrupt Status Enable
03Ah Error Interrupt Signal Enable 038h Normal Interrupt Signal Enable
03Eh --- 03Ch Auto CMD12 Error Status
042h Capabilities 040h Capabilities
046h Capabilities (Reserved) 044h Capabilities (Reserved)
04Ah Maximum Current Capabilities 048h Maximum Current Capabilities
04Eh Maximum Current Capabilities (Reserved) 04Ch Maximum Current Capabilities (Reserved)