📄 sd_drv.c
字号:
U32 vol,blocknr,block_len;
U32 c_size,mult;
c_size = (g_stCSD.c_size_hi<<2)+g_stCSD.c_size_lo;
mult = 2 <<(g_stCSD.c_size_mul+1);
blocknr = (c_size+1)*mult;
block_len = 2<<(g_stCSD.read_bl_len-1);
vol = blocknr*block_len/1024/1024;
aos_printf(MPE_SYS," SD-CARD Ok. Volume is %d M Bytes.",vol);
/*
aos_printf(MPE_DRV," read_bl_len is 0x%x .",g_stCSD.read_bl_len);
aos_printf(MPE_DRV," write_bl_len is 0x%x .",g_stCSD.write_bl_len);
aos_printf(MPE_DRV," c_size is 0x%x .",(g_stCSD.c_size_hi<<2)+g_stCSD.c_size_lo);
aos_printf(MPE_DRV," c_size_mul 0x%x .",g_stCSD.c_size_mul);
aos_printf(MPE_DRV," taac 0x%x .",g_stCSD.taac);
aos_printf(MPE_DRV," nsac 0x%x .",g_stCSD.nsac);
aos_printf(MPE_DRV, " SD-card Misalign Read=%d Write=%d",
g_stCSD.write_bl_misalign,g_stCSD.read_bl_misalign);
*/
g_SDVolume=vol; //便于sh显示用
return vol;
}
/******************************************************************************
函数: sd_read_cid_config
描述:
读SD卡的CID
输入:
输出:
返回:
成功返回AOS_SUCC,失败返回AOS_FAIL
******************************************************************************/
U32 sd_read_cid_config()
{
U8 *pBuf;
U8 status;
U32 i,result;
spi_enable_cs();
result = AOS_SUCC;
status = sd_write_command(CMD10_READ_CID); //response R1
if(status != 0)
{
AOS_ASSERT(0);
result = AOS_FAIL;
goto done;
}
//start block 0xFE + 16 bytes user datas + 16 bit CRC
i=0;
do
{
status = spi_read();
i++;
if( i > 3000 )
{
AOS_ASSERT(0);
result = AOS_FAIL;
goto done;
}
} while(status != 0xFE);
// Read off all the bytes in the block
pBuf =(U8*)&g_stCID;
for(i = 0; i < 16; ++i)
{
*pBuf = spi_read();
pBuf++;
}
status = spi_read();
//aos_printf(0," CID CRC byte is 0x%x",status);
status = spi_read();
//aos_printf(0," CID CRC byte is 0x%x",status);
done:
//发一个0xFF表示结束操作
status=0xFF;
spi_write(&status,1);
spi_disable_cs();
return result;
}
/******************************************************************************
函数: sd_read_csd_config
描述:
读SD卡的CSD
输入:
输出:
返回:
成功返回AOS_SUCC,失败返回AOS_FAIL
******************************************************************************/
U32 sd_read_csd_config()
{
U8 *pBuf;
U8 status;
//U8 crc_hi=0xFF,crc_lo=0xFF;
//U16 crc_value=0xFFFF;
U32 i,result;
U32 AgainCnt=0;
clear_watch_dog();
spi_enable_cs();
//需要计算卡的容量,有时需要多读几次卡才能得到CSD
again:
result = AOS_SUCC;
pBuf =(U8*)&g_stCSD;
for (i=0;i<5000;i++)
{
status = sd_write_command(CMD9_READ_CSD); //response R1
if(status == 0)
break;
}
if(status != 0)
{
AOS_ASSERT(0);
result = AOS_FAIL;
goto done;
}
//start block 0xFE + 16 bytes user datas + 16 bit CRC
i=0;
do
{
status = spi_read();
i++;
if( i > 800 )
{
AOS_ASSERT(0);
result = AOS_FAIL;
AgainCnt++;
goto done;
}
} while(status != 0xFE);
// Read off all the bytes in the block
for(i = 0; i < 16; i++)
{
*pBuf = spi_read();
pBuf++;
}
status = spi_read();
status = spi_read();
/* //对比硬件计算的CRC 与软件计算的CRC
crc_hi = spi_read();
crc_lo = spi_read();
crc_value=((crc_hi<<8)|crc_lo);
aos_printf(MPE_DRV," CSD CRC byte(hardwre) is 0x%x",crc_value);
crc_value=aos_CalCRC ( pBuf, 16);
aos_printf(MPE_DRV," CSD CRC(software)byte is 0x%x",crc_value);
*/
done:
if( (result == AOS_FAIL)&& (AgainCnt< 2) )
{
goto again;
}
//发一个0xFF表示结束操作
status=0xFF;
spi_write(&status,1);
spi_disable_cs();
return result;
}
/******************************************************************************
函数:sd_erase_block
描述:
擦除SD卡的一部分,在SD模式下,先擦除再写速度有提高
输入:
U32 addr0 起始地址
U32 addr1 结束地址
输出:
返回:
成功返回AOS_SUCC,失败返回AOS_FAIL
******************************************************************************/
U32 sd_erase_block(U32 addr0, U32 addr1)
{
U8 status;
U8 cmd;
U16 status_r2;
U32 i,result;
result = AOS_SUCC;
aos_printf(MPE_DRV,"sd erase block from addr0=0x%x to addr1=0x%x",
addr0, addr1);
CMD32_ERASE_START_BLOCK[1] = ((addr0 & 0xFF000000) >> 24);
CMD32_ERASE_START_BLOCK[2] = ((addr0 & 0x00FF0000) >> 16);
CMD32_ERASE_START_BLOCK[3] = ((addr0 & 0x0000FF00) >> 8);
CMD32_ERASE_START_BLOCK[4] = ((addr0 & 0x000000FF));
CMD33_ERASE_END_BLOCK[1] = ((addr1 & 0xFF000000) >> 24);
CMD33_ERASE_END_BLOCK[2] = ((addr1 & 0x00FF0000) >> 16);
CMD33_ERASE_END_BLOCK[3] = ((addr1 & 0x0000FF00) >> 8);
CMD33_ERASE_END_BLOCK[4] = ((addr1 & 0x000000FF));
spi_enable_cs();
status = sd_write_command(CMD32_ERASE_START_BLOCK);
if(status != 0)
{
// ABORT: invalid response for read single block command
//aos_printf(MPE_DRV," sd erase start cmd status=0x%x",status);
AOS_ASSERT(0);
result = AOS_FAIL;
goto done;
}
status = sd_write_command(CMD33_ERASE_END_BLOCK);
if(status != 0)
{
// ABORT: invalid response for read single block command
//aos_printf(MPE_SYS," sd erase end cmd status=0x%x",status);
AOS_ASSERT(0);
result = AOS_FAIL;
goto done;
}
status = sd_write_command(CMD38_ERASE_BLOCK);
if(status != 0)
{
// ABORT: invalid response for read single block command
//aos_printf(MPE_DRV," sd erase cmd status=0x%x",status);
AOS_ASSERT(0);
result = AOS_FAIL;
goto done;
}
status = sd_wait_for_r1();
SD_CHECK_BUSY(500);
// send status R2 response
for( i=0; i< 500; i++ )
{
status_r2 = sd_write_cmd_r2(CMD13_SEND_STATUS_BLOCK);
if(status_r2 == 0)
{
result = AOS_SUCC;
break;
}
// ABORT: invalid response for read single block command
//aos_printf(MPE_DRV," sd erase status=0x%x",status_r2);
result = AOS_FAIL;
}
done:
cmd=0xFF;
spi_write(&cmd,1);
spi_disable_cs();
return result;
}
/******************************************************************************
函数: sd_mem_read
描述:
从SD的相应源地址读数据到SDRAM目的地址
输入:
U32 addr 将要读出数据的SD源地址
U32 buf_addr SDRAM目的地址
U32 size 数据大小(字节数)
输出:
返回:
如果成功,返回AOS_SUCC , 否则AOS_FAIL
******************************************************************************/
U32 sd_mem_read(U32 addr,U32 buf_addr,U32 size)
{
U32 sd_addr,len=0;
U32 blockaddr0,blockaddr1,off;
U8 *pDst=NULL,*pSrc=NULL;
U8 szBuf[BLOCK_SIZE+4];
//卡不存在就返回
if( !sdcard_pos )
{
AOS_ASSERT(0);
return AOS_FAIL;
}
sd_addr = addr - SDCARD_BASE_ADDR;
// 512字节对齐
blockaddr0= sd_addr-(sd_addr%BLOCK_SIZE);
blockaddr1= (sd_addr+size)-((sd_addr+size)%BLOCK_SIZE);
for( off=blockaddr0; off<= blockaddr1; off=off+BLOCK_SIZE )
{
if( off == blockaddr0 )
{
// the first block
pDst = (U8*)buf_addr;
pSrc = szBuf+ (sd_addr%BLOCK_SIZE);
len = BLOCK_SIZE-(sd_addr%BLOCK_SIZE);
if( len > size )
len = size;
}
else if( off == blockaddr1 )
{
// the last block
len = (sd_addr+size)%BLOCK_SIZE;
}
//should add delay
if( AOS_SUCC != sd_read_block(off,szBuf) )
{
AOS_ASSERT(0);
return AOS_FAIL;
}
aos_memcpy( pDst,pSrc, len);
pDst += len;
pSrc = szBuf;
len = BLOCK_SIZE;
}
return AOS_SUCC;
}
/******************************************************************************
函数: sd_read_block
描述:
从SD的相应地址读数据到指针处
输入:
U32 addr 将要读出数据的SD地址
输出: U8 *buf 数据保存所在指针
返回:
如果成功,返回AOS_SUCC , 否则AOS_FAIL
******************************************************************************/
U32 sd_read_block(U32 addr, U8 *buf)
{
U8 status=1;
U8 *pCh;
//U8 crc_hi=0xFF,crc_lo=0xFF;
//U16 crc_value=0xFFFF;
U32 i,result;
U32 AgainCnt=0;
if( addr%BLOCK_SIZE != 0 )
{
AOS_ASSERT(0);
return AOS_FAIL;
}
clear_watch_dog();
again:
aos_printf(MPE_DRV,"sd read a block addr=0x%x buf=0x%x",addr, buf);
result = AOS_SUCC;
//read block length is 512 bytes
CMD17_READ_SINGLE_BLOCK[1] = ((addr & 0xFF000000) >> 24);
CMD17_READ_SINGLE_BLOCK[2] = ((addr & 0x00FF0000) >> 16);
CMD17_READ_SINGLE_BLOCK[3] = ((addr & 0x0000FF00) >> 8);
CMD17_READ_SINGLE_BLOCK[4] = ((addr & 0x000000FF));
spi_enable_cs();
// Send the read command
for( i=0; i< 200; i++ )
{
status = sd_write_command(CMD17_READ_SINGLE_BLOCK);
if( status == 0 )
//aos_printf(MPE_DRV,"cmd17 response is %d,and current i is %d",status,i);
break;
}
if( i ==200 )
{
// ABORT: invalid response for read single block command
AOS_ASSERT(0);
//aos_printf(MPE_DRV,"cmd17 error status is = %d",status);
result = AOS_FAIL;
goto done;
}
//不同卡TAAC不同,有可能Nac达到ms,这里有一个goto ,again重写机制,不会出错
/*
if (((g_stCSD.taac)&0x07)==7)
hw_delay(8000);
else */
hw_delay(100);
// BLOCK 0xFE 2-513 CRC16 (515Bytes)
// Now wait for the "Start Block" token (0xFE)
// (see SanDisk SD Card Product Manual v1.9 section 5.2.4. Data Tokens)
i=0;
do
{
status = spi_read();
i++;
if( i ==1000)
{
AOS_ASSERT(0);
AgainCnt++;
result = AOS_FAIL;
goto done;
}
}
while(status!=0xFE);
// aos_printf(MPE_DRV,"read start block( 1111110) is %d ,times is %d",status,i);
// Read off all the bytes in the block
pCh = buf;
for(i = 0; i < BLOCK_SIZE; i++)
{
*pCh = spi_read();
pCh++;
}
// Read CRC bytes
status = spi_read();
status = spi_read();
//比较硬件计算的CRC值和软件计算的CRC值
/*
crc_hi = spi_read();
crc_lo = spi_read();
crc_value=((crc_hi<<8)|crc_lo);
aos_printf(MPE_DRV," read block CRC byte(hardwre) is 0x%x",crc_value);
crc_value=aos_CalCRC ( pCh, BLOCK_SIZE);
aos_printf(MPE_DRV," read CRC(software)byte is 0x%x",crc_value);
*/
hw_delay(10);
// Following a read transaction, the SD Card needs 8 clocks after the end
// bit of the last data block to finish up its work.
// (from SanDisk SD Card Product Manual v1.9 section 5.1.8)
done:
if( (result == AOS_FAIL)&& (AgainCnt< 3) )
{
goto again;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -