📄 sd_card.h
字号:
#ifndef _SD_CARD_H_
#define _SD_CARD_H_
#include "config.h"
//-------------------------------------------------------------------------
// SD Card Set I/O Direction
#define SD_CMD_IN IOWR(SD_CMD_BASE, 1, 0)
#define SD_CMD_OUT IOWR(SD_CMD_BASE, 1, 1)
#define SD_DAT_IN IOWR(SD_DAT_BASE, 1, 0)
#define SD_DAT_OUT IOWR(SD_DAT_BASE, 1, 1)
// SD Card Output High/Low
#define SD_CMD_LOW IOWR(SD_CMD_BASE, 0, 0)
#define SD_CMD_HIGH IOWR(SD_CMD_BASE, 0, 1)
#define SD_DAT_LOW IOWR(SD_DAT_BASE, 0, 0)
#define SD_DAT_HIGH IOWR(SD_DAT_BASE, 0, 1)
#define SD_CLK_LOW IOWR(SD_CLK_BASE, 0, 0)
#define SD_CLK_HIGH IOWR(SD_CLK_BASE, 0, 1)
// SD Card Input Read
#define SD_TEST_CMD IORD(SD_CMD_BASE, 0)
#define SD_TEST_DAT IORD(SD_DAT_BASE, 0)
//-------------------------------------------------------------------------
#define BYTE unsigned char
#define UINT16 unsigned int
#define UINT32 unsigned long
//-------------------------------------------------------------------------
void Ncr(void);
void Ncc(void);
BYTE response_R(BYTE);
BYTE send_cmd(BYTE *);
BYTE SD_read_lba(BYTE *,UINT32,UINT32);
BYTE SD_card_init(void);
uint16 SDCammand(uint8 Cammand, void *Parameter);
uint32 GetVolumeFirstSect(uint8 Device);
//-------------------------------------------------------------------------
BYTE read_status;
BYTE response_buffer[20];
BYTE RCA[2];
BYTE cmd_buffer[5];
const BYTE cmd0[5] = {0x40,0x00,0x00,0x00,0x00};
const BYTE cmd55[5] = {0x77,0x00,0x00,0x00,0x00};
const BYTE cmd2[5] = {0x42,0x00,0x00,0x00,0x00};
const BYTE cmd3[5] = {0x43,0x00,0x00,0x00,0x00};
const BYTE cmd7[5] = {0x47,0x00,0x00,0x00,0x00};
const BYTE cmd9[5] = {0x49,0x00,0x00,0x00,0x00};
const BYTE cmd16[5] = {0x50,0x00,0x00,0x02,0x00};
const BYTE cmd17[5] = {0x51,0x00,0x00,0x00,0x00};
const BYTE cmd24[5] = {0x58,0x00,0x00,0x00,0x00};
const BYTE acmd6[5] = {0x46,0x00,0x00,0x00,0x02};
const BYTE acmd41[5] = {0x69,0x0f,0xf0,0x00,0x00};
const BYTE acmd51[5] = {0x73,0x00,0x00,0x00,0x00};
//-------------------------------------------------------------------------
void Ncr(void)
{
SD_CMD_IN;
SD_CLK_LOW;
SD_CLK_HIGH;
SD_CLK_LOW;
SD_CLK_HIGH;
}
//-------------------------------------------------------------------------
void Ncc(void)
{
int i;
for(i=0;i<8;i++)
{
SD_CLK_LOW;
SD_CLK_HIGH;
}
}
//-------------------------------------------------------------------------
BYTE SD_Initialize(void)
{
BYTE x,y;
SD_CMD_OUT;
SD_DAT_IN;
SD_CLK_HIGH;
SD_CMD_HIGH;
SD_DAT_LOW;
read_status=0;
for(x=0;x<40;x++)
Ncr();
for(x=0;x<5;x++)
cmd_buffer[x]=cmd0[x];
y = send_cmd(cmd_buffer);
do
{
for(x=0;x<40;x++);
Ncc();
for(x=0;x<5;x++)
cmd_buffer[x]=cmd55[x];
y = send_cmd(cmd_buffer);
Ncr();
if(response_R(1)>1) //response too long or crc error
return 1;
Ncc();
for(x=0;x<5;x++)
cmd_buffer[x]=acmd41[x];
y = send_cmd(cmd_buffer);
Ncr();
} while(response_R(3)==1);
Ncc();
for(x=0;x<5;x++)
cmd_buffer[x]=cmd2[x];
y = send_cmd(cmd_buffer);
Ncr();
if(response_R(2)>1)
return 1;
Ncc();
for(x=0;x<5;x++)
cmd_buffer[x]=cmd3[x];
y = send_cmd(cmd_buffer);
Ncr();
if(response_R(6)>1)
return 1;
RCA[0]=response_buffer[1];
RCA[1]=response_buffer[2];
Ncc();
for(x=0;x<5;x++)
cmd_buffer[x]=cmd9[x];
cmd_buffer[1] = RCA[0];
cmd_buffer[2] = RCA[1];
y = send_cmd(cmd_buffer);
Ncr();
if(response_R(2)>1)
return 1;
Ncc();
for(x=0;x<5;x++)
cmd_buffer[x]=cmd7[x];
cmd_buffer[1] = RCA[0];
cmd_buffer[2] = RCA[1];
y = send_cmd(cmd_buffer);
Ncr();
if(response_R(1)>1)
return 1;
Ncc();
for(x=0;x<5;x++)
cmd_buffer[x]=cmd16[x];
y = send_cmd(cmd_buffer);
Ncr();
if(response_R(1)>1)
return 1;
read_status =1; //sd card ready
return 0;
}
//-------------------------------------------------------------------------
BYTE SD_ReadBlock(BYTE *buff,UINT32 lba,UINT32 seccnt)
{
BYTE c=0;
UINT32 i,j;
lba+=99;
lba<<=9;
SD_DAT_IN;
for(j=0;j<seccnt;j++)
{
{
Ncc();
cmd_buffer[0] = cmd17[0];
cmd_buffer[1] = (INT8U)(lba >> 24);
cmd_buffer[2] = (INT8U)(lba >> 16);
cmd_buffer[3] = (INT8U)(lba >> 8);
cmd_buffer[4] = (INT8U)(lba );
send_cmd(cmd_buffer);
Ncr();
}
while(1)
{
SD_CLK_LOW;
SD_CLK_HIGH;
if(!(SD_TEST_DAT))
break;
}
for(i=0;i<512;i++)
{
BYTE j;
for(j=0;j<8;j++)
{
SD_CLK_LOW;
SD_CLK_HIGH;
c <<= 1;
if(SD_TEST_DAT)
c |= 0x01;
}
*buff=c;
buff++;
}
for(i=0; i<16; i++)
{
SD_CLK_LOW;
SD_CLK_HIGH;
}
}
read_status = 1; //SD data next in
return 0;
}
/*BYTE SD_WriteBlock(BYTE *buff,UINT32 lba,UINT32 seccnt)
{
BYTE c=0;
UINT32 i,j;
lba+=99;
lba<<=9;
//SD_DAT_IN;
for(j=0;j<seccnt;j++)
{
{
Ncc();
cmd_buffer[0] = cmd24[0];
cmd_buffer[1] = (INT8U)(lba >> 24);
cmd_buffer[2] = (INT8U)(lba >> 16);
cmd_buffer[3] = (INT8U)(lba >> 8);
cmd_buffer[4] = (INT8U)(lba );
send_cmd(cmd_buffer);
Ncr();
if(response_R(1)>1)
return 1;
// Ncr();
}
/* while(1)
{
SD_CLK_LOW;
SD_CLK_HIGH;
if(!(SD_TEST_DAT))
break;
}*/
/* SD_DAT_OUT;
for(i=0;i<512;i++)
{
BYTE j;
*buff=c;
for(j=0;j<8;j++)
{
SD_CLK_LOW;
SD_CLK_HIGH;
if(c&0x01)
SD_DAT_HIGH;
else
SD_DAT_LOW;
c >>= 1;
//if(SD_TEST_DAT)
//c |= 0x01;
}
buff++;
}
for(i=0; i<16; i++)
{
SD_CLK_LOW;
SD_CLK_HIGH;
}
}
}*/
//-------------------------------------------------------------------------
BYTE response_R(BYTE s)
{
BYTE a=0,b=0,c=0,r=0,crc=0;
BYTE i,j=6,k;
while(1)
{
SD_CLK_LOW;
SD_CLK_HIGH;
if(!(SD_TEST_CMD))
break;
if(crc++ >100)
return 2;
}
crc =0;
if(s == 2)
j = 17;
for(k=0; k<j; k++)
{
c = 0;
if(k > 0) //for crc culcar
b = response_buffer[k-1];
for(i=0; i<8; i++)
{
SD_CLK_LOW;
if(a > 0)
c <<= 1;
else
i++;
a++;
SD_CLK_HIGH;
if(SD_TEST_CMD)
c |= 0x01;
if(k > 0)
{
crc <<= 1;
if((crc ^ b) & 0x80)
crc ^= 0x09;
b <<= 1;
crc &= 0x7f;
}
}
if(s==3)
{
if( k==1 &&(!(c&0x80)))
r=1;
}
response_buffer[k] = c;
}
if(s==1 || s==6)
{
if(c != ((crc<<1)+1))
r=2;
}
return r;
}
//-------------------------------------------------------------------------
BYTE send_cmd(BYTE *in)
{
int i,j;
BYTE b,crc=0;
SD_CMD_OUT;
for(i=0; i < 5; i++)
{
b = in[i];
// while(1)
// {
for(j=0; j<8; j++)
{
SD_CLK_LOW;
if(b&0x80)
SD_CMD_HIGH;
else
SD_CMD_LOW; //否则置0
crc <<= 1;
SD_CLK_HIGH;//送时钟,需注意,从host端向card发送cmd或者data,总是要在时钟的下降沿发出,因为card在上升沿采样。
if((crc ^ b) & 0x80)//左移异或产生CRC码
crc ^= 0x09;
b<<=1;
}
// }
crc &= 0x7f;
}
crc =((crc<<1)|0x01);
b = crc;
for(j=0; j<8; j++)
{
SD_CLK_LOW;
if(crc&0x80)
SD_CMD_HIGH;
else
SD_CMD_LOW;
SD_CLK_HIGH;
crc<<=1;
}
return b;
}
uint32 GetVolumeFirstSect(uint8 Device)/*获得卷首扇区数据*/
{
uint8 buffer[512];
uint32 RelaStaSect;
SD_ReadBlock(buffer, 0, 1); /* 读SD卡的0块 */
if((buffer[510]==0x55)&&(buffer[511]==0xAA))
{
if(((buffer[0]==0xEB)&&(buffer[2]==0x90))||(buffer[0] == 0xE9))
{
RelaStaSect = 0;
}
else
{
RelaStaSect = buffer[454]+
buffer[455]*0x100 +
buffer[456]*0x10000 +
buffer[457]*0x1000000;
}
}
return RelaStaSect;
}
uint16 SDCammand(uint8 Cammand, void *Parameter) /*使用您自己的函数名称 */
{
uint16 rt;
Disk_RW_Parameter * Dp;
uint8 ret;
Disk_Info *DiskInfo;
Dp = (Disk_RW_Parameter *)Parameter;
switch (Cammand)
{
case DISK_INIT:
rt = DISK_INIT_NOT_OK;
ret = SD_Initialize();
if (ret == 0)
{
DiskInfo = GetEmptyDiskInfoAddr();
if (DiskInfo != NULL)
{
DiskInfo->DiakCommand = SDCammand;
DiskInfo->RsvdForLow = GetVolumeFirstSect(0);/*获取卷首扇区*/
rt = 1;
}
}
break;
// case DISK_CLOSE:
// rt =0;
// break;
case DISK_READ_SECTOR:
if (SD_ReadBlock( Dp->Buf, Dp->SectorIndex + Dp->RsvdForLow, 1)==0)
{
rt = DISK_READ_OK;
}
else
rt = DISK_READ_NOT_OK;
break;
//case DISK_WRITE_SECTOR:
// if (SD_ReadBlock( Dp->Buf, Dp->SectorIndex + Dp->RsvdForLow, 1)==0)
// {
// rt = DISK_WRITE_OK;
// }
// else
// rt = DISK_WRITE_NOT_OK;
// break;
default:
rt = BAD_DISK_COMMAND;
break;
}
return rt;
}
#endif //_SD_CARD_H_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -