最近在调试一个spi的sdcard,发现在初始化时,ACMD41一直返回0x01;想请教下大家有没有好的建议排查;
1 查看了sdcard spi模式的初始化流程,觉得也是对的;
上电,cs拉高,发送spi 80个clk,cs拉低,发送CMD0,返回0x01;
发送(CMD8,0x1AA),返回R1=0x01;读取ocr,也是可以读到ocr 0x01和0xAA,
可是发送CMD55 R1=0x01,ACMD41 R1=0x1,而且一直是0x01
这个地方表示sd卡一直都没有进入初始化完成状态;
2 主电源断点,power off重新上电后,ACMD41又可以正常返回0x00;
3 再次关闭主电源,重新上电后,ACMD41再次不能正常返回0x00;
如此,交替ok;比较异常;
个人还是比较怀疑我的spi sdcard上电流程上哪里出了问题,
还请大神帮忙诊断;
附上初始化的一小段代码;
DSTATUS spisd_disk_initialize (
BYTE drv /* Physical drive nmuber (0) */
)
{
BYTE n, cmd, ty, ocr[4];
uint16_t retry = 0;
BYTE ret = 0;
if (drv)
return STA_NOINIT; /* Supports only single drive */
if (Stat & STA_NODISK)
return Stat; /* No card in the socket */
MMC_SPI_Config();
MMC_POWERON(); /* Force socket power on */
delay_ms(500);
SPI_LowSpeed();
MMC_DESELECT();
/* Wait for enter Idle state in timeout of 5000 msec */
/* retry 10 times*/
retry = 50;
do
{
for (n = 10; n; n--) SPI_ReadWrite_Byte(0xFF); /* 80 dummy clocks */
}
while((Send_Command(CMD0,0) != 1) && retry--);
ty = 0;
retry = 0xfffe; /* Initialization timeout of 2000 msec */
if (Send_Command(CMD8, 0x1AA) == 1) /* 检查是否支持SDC Ver2 */
{
for (n = 0; n < 4; n++)
{
ocr[n] = SPI_ReadWrite_Byte(0xff); /* Get trailing return value of R7 resp */
}
printf("ocr2=0x%x ocr3=0x%x \r\n",ocr[2],ocr[3]);
if (ocr[2] == 0x01 && ocr[3] == 0xAA)
{
/* The card can work at vdd range of 2.7-3.6V */
/* Wait for leaving idle state (ACMD41 with HCS bit) */
do
{
ret = Send_Command(ACMD41,0x40000000);
printf("ACMD41 ret=%d\r\n",ret);
}
while ((--retry) && ret);
printf("retry %d \r\n",retry);
if ((retry) && Send_Command(CMD58,0) == 0)
{
/* Check CCS bit in the OCR */
for (n = 0; n < 4; n++)
ocr[n] = SPI_ReadWrite_Byte(0xff);
/* When CCS bit is set R/W in block address insted of byte address */
ty = (ocr[0] & 0x40) ? 12 : 4;
}
}
}
else
{
/* SDSC or MMC */
if (Send_Command(ACMD41, 0) <= 1) /* initialize successful will response 0x00 */
{
ty = 2; cmd = ACMD41; /* SDv1 */
}
else
{
ty = 1; cmd = CMD1; /* MMC */
}
while ((--retry) && Send_Command(cmd, 0)); /* Wait for leaving idle state */
if (!retry || Send_Command(CMD16, 512) != 0) /* Set R/W block length to 512 */
ty = 0;
}
CardType = ty;
SPI_HighSpeed();
SPI_Release();
if (ty)
{ /* Initialization succeded */
Stat &= ~STA_NOINIT;
printf("ty %d stat %d\r\n",ty,Stat);
}
else
{ /* Initialization failed */
printf("ty %d stat %d\r\n",ty,Stat);
MMC_POWEROFF();
}
return Stat;
}
|