📄 sd.c
字号:
说 明:
调 用:必须先调用SDCIF_CMD55()
全局变量:ErrVal, OCR
入口参数:无
出口参数:无
返 回 值:无
************************************************/
Bool SDCIF_ACMD41( void )
{
Bool status = OK;
ARG31_24 = SDVar.OCR[ 3 ]; //argument = OCR
ARG23_16 = SDVar.OCR[ 2 ];
ARG15_08 = SDVar.OCR[ 1 ];
ARG07_00 = SDVar.OCR[ 0 ];
CMDCON = WAITRSP;
CMDINDEX = SD_SEND_OP_COND;
while( !( STATUS07_00 & CMDSEND ));
while( !( STATUS07_00 & RSPRXVP ))
{
if( STATUS07_00 & RSPTIMEOUT )
{
//STATUS07_00 = 0xFF;
//return KO;
status = KO;
break;
}
}
STATUS07_00 = 0xFF;
//return OK;
return status;
}
/************************************************
函 数 名: SDCIF_ACMD51()
功 能:Reads the SD Configuration Register (SCR)(64 bits)
说 明:数据存放地址由SDH_DMA_CS决定
调 用:必须先调用SDCIF_CMD55()
全局变量:ErrVal
入口参数:无
出口参数:无
返 回 值:无
************************************************/
Bool SDCIF_ACMD51( void )
{
Bool status = OK;
//argument dont't care
//ARG31_24 = SDVar.OCR[ 3 ];
//ARG23_16 = SDVar.OCR[ 2 ];
//ARG15_08 = SDVar.OCR[ 1 ];
//ARG07_00 = SDVar.OCR[ 0 ];
BLKLEN11_08 = 0x00; //SET_BLOCKLEN
BLKLEN07_00 = 64 / 8;
CMDCON = WAITRSP | DATA_WITH;
CMDINDEX = SEND_SCR;
while( !( STATUS07_00 & CMDSEND ));
while( !( STATUS07_00 & RSPRXVP ))
{
if(( STATUS07_00 & RSPTIMEOUT )
||( STATUS07_00 & CRC7ERROR ))
{
//SDVar.ErrVal = 1;
//STATUS07_00 = 0xFF;
//return;
status = KO;
break;
}
}
while( !( STATUS07_00 & XFEREND ))
{
if(( STATUS07_00 & DTIMEOUT )
||( STATUS07_00 & CRC16ERROR ))
{
//SDVar.ErrVal = 1;
//STATUS07_00 = 0xFF;
//return;
}
}
STATUS07_00 = 0xFF;
}
/************************************************
函 数 名: Read_CardCapacity()
功 能:
说 明:
调 用:
全局变量:
入口参数:无
出口参数:无
返 回 值:无
************************************************/
void Read_CardCapacity( void )
{
idata U16 C_SIZE, MULT,Block_Len, tmpword;
idata U8 C_SIZE_MULT;
SDVar.LResp[ 0 ] = RESP127_120;
SDVar.LResp[ 1 ] = RESP119_112;
SDVar.LResp[ 2 ] = RREP111_104;
SDVar.LResp[ 3 ] = RREP103_096;
SDVar.LResp[ 4 ] = RREP095_088;
SDVar.LResp[ 5 ] = RREP087_080;
SDVar.LResp[ 6 ] = RREP079_072;
SDVar.LResp[ 7 ] = RREP071_064;
SDVar.LResp[ 8 ] = RREP063_056;
SDVar.LResp[ 9 ] = RREP055_048;
SDVar.LResp[ 10 ] = RREP047_040;
SDVar.LResp[ 11 ] = RREP039_032;
SDVar.LResp[ 12 ] = RREP031_024;
SDVar.LResp[ 13 ] = RREP023_016;
SDVar.LResp[ 14 ] = RREP015_008;
SDVar.LResp[ 15 ] = RREP007_000;
if(( SDVar.LResp[ 0 ]& 0xC0 ) == 0x40 )
{
//CSD Version 2
varAl.TmpLong = 0;
SDVar.CardCapacity = 0;
varAl.TmpLong = SDVar.LResp[ 7 ]& 0x3F;
varAl.TmpLong <<= 16;
SDVar.CardCapacity = varAl.TmpLong;
varAl.TmpLong = 0;
varAl.TmpLong = SDVar.LResp[ 8 ];
varAl.TmpLong <<= 8;
SDVar.CardCapacity |= varAl.TmpLong;
varAl.TmpLong = SDVar.LResp[ 9 ];
SDVar.CardCapacity |= varAl.TmpLong;
varAl.TmpLong = SDVar.CardCapacity ;
SDVar.CardCapacity = ( varAl.TmpLong + 1 )* 512; //KBytes
//SDVar.CardCapacity <<= 1; // 2*512(512 is sector byte by PC host),so we just *2 here
}
else
{
//CSD Version 1
varAl.TmpByte = SDVar.LResp[ 6 ];
varAl.TmpByte &= 0x0F;
Block_Len = pow( 2, varAl.TmpByte ); // Block_Len
tmpword = 0x00;
varAl.TmpByte = SDVar.LResp[ 7 ] & 0x03; //Bit[73:72]
tmpword = varAl.TmpByte; //Bit[71:64]
tmpword <<= 10;
varAl.TmpWord = 0;
varAl.TmpByte = SDVar.LResp[ 8 ];
varAl.TmpWord = varAl.TmpByte;
tmpword |= varAl.TmpWord << 2;
varAl.TmpByte = SDVar.LResp[ 9 ]& 0xC0;
tmpword |= varAl.TmpByte >> 6;
C_SIZE = tmpword;
varAl.TmpByte = SDVar.LResp[ 10 ]& 0x03;
C_SIZE_MULT = 0;
C_SIZE_MULT |= varAl.TmpByte << 1;
varAl.TmpByte = SDVar.LResp[ 11 ]& 0x80;
C_SIZE_MULT |= varAl.TmpByte >> 7;
MULT= pow( 2, C_SIZE_MULT + 2 );
varAl.TmpLong = ( U32 )( C_SIZE + 1 )* MULT; //BlockNR
SDVar.CardCapacity = ( U32 )varAl.TmpLong * Block_Len;
}
}
/************************************************
函 数 名: ChkCurrentState()
功 能:检查SD卡状态
说 明:
调 用:
全局变量:CardStatus
入口参数:无
出口参数:无
返 回 值:无
************************************************/
/*void ChkCurrentState(void)
{
SDVar.CardStatus[1] = RREP103_096;
SDVar.CardStatus[1] &= 0x1E;
//
SDVar.CardStatus[1] >>= 1;
//
}
/************************************************
函 数 名: SDHostRead512B_LBA
功 能:从逻辑块地址开始读取512字节
说 明:数据存放地址由SDH_DMA_CS决定
调 用:
全局变量:ErrVal, SD_lba(FlashAddr[3:0])
入口参数:无
出口参数:无
返 回 值:1 -> success, 0 -> failure
************************************************/
bit SDHostRead512B_LBA(U32 logic_address, U8 dma_section)
{
SDH_DMA_CS = dma_section;
SD_lba = logic_address << 9;
if(SDCIF_CMD17())
return OK;
else
return KO;
}
/************************************************
函 数 名: DMA_load_sector()
功 能:从逻辑块地址开始读取512字节
说 明:数据存放地址由SDH_DMA_CS决定
调 用:
全局变量:ErrVal, SD_lba(FlashAddr[3:0])
入口参数:无
出口参数:无
返 回 值:1 -> success, 0 -> failure
************************************************/
#pragma disable
/*bit*/U8 DMA_load_sector(U32 sector, U8 dma_cs)
{
/* U8 data i = 5;
do
{
SDCIF_CMD12();
SDH_DMA_CS = dma_cs;
SD_lba = sector << 9;
if(SDCIF_CMD17())
return OK;
}
while(--i);
(*(void(*)())0)();
return KO;*/
U8 data i = 5;
do
{
SDCIF_CMD12();
if(SDHostRead512B_LBA(sector, dma_cs))
{
if(SDHostRead512B_LBA(sector, dma_cs))
return OK;
}
SYSDelay();
SYSDelay();
}
while(--i);
return KO;
}
/************************************************
函 数 名: SDHostWrite512B_LBA()
功 能:从逻辑块地址开始写入512字节
说 明:数据存放地址由SDH_DMA_CS决定
调 用:
全局变量:ErrVal, SD_lba(FlashAddr[3:0])
入口参数:无
出口参数:无
返 回 值:0 -> success, 1 -> failure
************************************************/
bit DMA_write_sector(U32 sector, U8 dma_cs)
{
//SDCIF_CMD12();
SDH_DMA_CS = dma_cs;
SD_lba = sector << 9;
if(!SDCIF_CMD24())
{
if(!SDCIF_CMD24())
{
return KO;
}
}
return OK;
}
/************************************************
函 数 名: SD_SysInit()
功 能:SD host和SD memory系统初始化
说 明:
调 用:
全局变量:
入口参数:无
出口参数:无
返 回 值:无
************************************************/
void SD_SysInit(void)
{
/* SDCIF_Init();
if(!GetSDMemoryOCR())//added MMC CMD1
{
#if TX_DEBUG
SendChar(0xAB);
#endif
SDIFCON0 = 0x00;
//SYSDelay();
//(*(void(*)())0)();
LedFlash(50);
}
SDMemoryCardInit();*/
U8 i = 5;
do
{
SDCIF_Init();
if(!GetSDMemoryOCR())//added MMC CMD1
{
SDIFCON0 = 0x00;
SYSDelay();
}
else
break;
}
while(--i);
if(!i)
{
#if TX_DEBUG
SendChar(0xAB);
#endif
LedFlash(50);
}
SDMemoryCardInit();
}
/*F**************************************************************************
* NAME: sd_format
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
* Address of the format parameter structure in code
*----------------------------------------------------------------------------
* PURPOSE:
* This function is called by the fat_format function and returns a pointer
* to a table containing the format parameters.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* The following values are maximum. The number of cylinder is calculated
* with the real LBAs of the card.
* SD FORMAT PARAMETERS
* CAPACITY LBAs CYL HDs S/T CLUSTs S/C S/F FAT HID
* 4MB 8032 251 2 16 198 16 2 12 27
* 8MB 16224 507 2 16 1010 16 3 12 25
* 16MB 32448 507 2 32 1011 32 3 12 57
* 32MB 64896 507 4 32 2025 32 6 12 51
* 64MB 129792 507 8 32 4053 32 12 12 39
* 128MB 259584 1014 8 32 8106 32 32 16 95
* 256MB 519168 1014 16 32 16216 32 64 16 95
*
* MMC FORMAT PARAMETERS
* CAPACITY LBAs CYL HDs S/T CLUSTs S/C S/F FAT HID
* 4MB 8192 128 2 32 975 8 3 12 32
* 8MB 16384 256 2 32 1950 8 6 12 32
* 16MB 32768 512 2 32 3908 8 12 12 32
* 28MB 57344 448 4 32 13652 4 54 16 32
* 32MB 65536 512 4 32 15632 4 62 16 32
* 64MB 131072 512 8 32 31282 4 123 16 32
* 128MB 262144 1024 8 32 62581 4 245 16 32
* 256MB 524288 1024 16 32 62720 8 245 16 32
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
#if 0
s_format * sd_format (void)
{
s_format pdata *tab;
tab = (s_format pdata *)gl_buffer;
if (sd_flag == SD)
{
code s_format sd_tab_format[]=
{
/* nb_cylinder, nb_head, nb_sector, nb_hidden, nb_sector_per_cluster */
{ (Uint16)0, (Byte)2, (Byte)16, (Byte)27, (Byte)16 }, /* 4MB */
{ (Uint16)0, (Byte)2, (Byte)16, (Byte)25, (Byte)16 }, /* 8MB */
{ (Uint16)0, (Byte)2, (Byte)32, (Byte)57, (Byte)32 }, /* 16MB */
{ (Uint16)0, (Byte)4, (Byte)32, (Byte)51, (Byte)32 }, /* 32MB */
{ (Uint16)0, (Byte)8, (Byte)32, (Byte)39, (Byte)32 }, /* 64MB */
{ (Uint16)0, (Byte)8, (Byte)32, (Byte)95, (Byte)32 }, /* 128MB */
{ (Uint16)0, (Byte)16, (Byte)32, (Byte)95, (Byte)32 }, /* 256MB */
};
/* -- SD Type Selection -- */
if (Sd_disk_size() <= SD_SIZE_4MB)
{
*tab = sd_tab_format[SD_4MB];
/* calculation of cylinder number */
(*tab).nb_cylinder = (Sd_disk_size() + 1) /
(sd_tab_format[SD_4MB].nb_head *
sd_tab_format[SD_4MB].nb_sector);
return tab;
}
if (Sd_disk_size() <= SD_SIZE_8MB)
{
*tab = sd_tab_format[SD_8MB];
/* calculation of cylinder number */
(*tab).nb_cylinder = (Sd_disk_size() + 1) /
(sd_tab_format[SD_8MB].nb_head *
sd_tab_format[SD_8MB].nb_sector);
return tab;
}
if (Sd_disk_size() <= SD_SIZE_16MB)
{
*tab = sd_tab_format[SD_16MB];
/* calculation of cylinder number */
(*tab).nb_cylinder = (Sd_disk_size() + 1) /
(sd_tab_format[SD_16MB].nb_head *
sd_tab_format[SD_16MB].nb_sector);
return tab;
}
if (Sd_disk_size() <= SD_SIZE_32MB)
{
*tab = sd_tab_format[SD_32MB];
/* calculation of cylinder number */
(*tab).nb_cylinder = (Sd_disk_size() + 1) /
(sd_tab_format[SD_32MB].nb_head *
sd_tab_format[SD_32MB].nb_sector);
return tab;
}
if (Sd_disk_size() <= SD_SIZE_64MB)
{
*tab = sd_tab_format[SD_64MB];
/* calculation of cylinder number */
(*tab).nb_cylinder = (Sd_disk_size() + 1) /
(sd_tab_format[SD_64MB].nb_head *
sd_tab_format[SD_64MB].nb_sector);
return tab;
}
if (Sd_disk_size() <= SD_SIZE_128MB)
{
*tab = sd_tab_format[SD_128MB];
/* calculation of cylinder number */
(*tab).nb_cylinder = (Sd_disk_size() + 1) /
(sd_tab_format[SD_128MB].nb_head *
sd_tab_format[SD_128MB].nb_sector);
return tab;
}
else
{
*tab = sd_tab_format[SD_256MB];
/* calculation of cylinder number */
(*tab).nb_cylinder = (Sd_disk_size() + 1) /
(sd_tab_format[SD_256MB].nb_head *
sd_tab_format[SD_256MB].nb_sector);
return tab;
}
}
else
{
code s_format sd_tab_format[]=
{
/* nb_cylinder, nb_head, nb_sector, nb_hidden, nb_sector_per_cluster */
{ (Uint16)0, (Byte)2, (Byte)32, (Byte)32, (Byte)8 }, /* 4MB */
{ (Uint16)0, (Byte)2, (Byte)32, (Byte)32, (Byte)8 }, /* 8MB */
{ (Uint16)0, (Byte)2, (Byte)32, (Byte)32, (Byte)8 }, /* 16MB */
{ (Uint16)0, (Byte)4, (Byte)32, (Byte)32, (Byte)4 }, /* 28MB */
{ (Uint16)0, (Byte)4, (Byte)32, (Byte)32, (Byte)4 }, /* 32MB */
{ (Uint16)0, (Byte)8, (Byte)32, (Byte)32, (Byte)4 }, /* 64MB */
{ (Uint16)0, (Byte)8, (Byte)32, (Byte)32, (Byte)4 }, /* 128MB */
{ (Uint16)0, (Byte)16, (Byte)32, (Byte)32, (Byte)8 }, /* 256MB */
};
/* -- MMC Type Selection -- */
if (Sd_disk_size() <= MMC_SIZE_4MB)
{
*tab = sd_tab_format[MMC_4MB];
/* calculation of cylinder number */
(*tab).nb_cylinder = (Sd_disk_size() + 1) /
(sd_tab_format[MMC_4MB].nb_head *
sd_tab_format[MMC_4MB].nb_sector);
return tab;
}
if (Sd_disk_size() <= MMC_SIZE_8MB)
{
*tab = sd_tab_format[MMC_8MB];
/* calculation of cylinder number */
(*tab).nb_cylinder = (Sd_disk_size() + 1) /
(sd_tab_format[MMC_8MB].nb_head *
sd_tab_format[MMC_8MB].nb_sector);
return tab;
}
if (Sd_disk_size() <= MMC_SIZE_16MB)
{
*tab = sd_tab_format[MMC_16MB];
/* calculation of cylinder number */
(*tab).nb_cylinder = (Sd_disk_size() + 1) /
(sd_tab_format[MMC_16MB].nb_head *
sd_tab_format[MMC_16MB].nb_sector);
return tab;
}
if (Sd_disk_size() <= MMC_SIZE_28MB)
{
*tab = sd_tab_format[MMC_28MB];
/* calculation of cylinder number */
(*tab).nb_cylinder = (Sd_disk_size() + 1) /
(sd_tab_format[MMC_28MB].nb_head *
sd_tab_format[MMC_28MB].nb_sector);
return tab;
}
if (Sd_disk_size() <= MMC_SIZE_32MB)
{
*tab = sd_tab_format[MMC_32MB];
/* calculation of cylinder number */
(*tab).nb_cylinder = (Sd_disk_size() + 1) /
(sd_tab_format[MMC_32MB].nb_head *
sd_tab_format[MMC_32MB].nb_sector);
return tab;
}
if (Sd_disk_size() <= MMC_SIZE_64MB)
{
*tab = sd_tab_format[MMC_64MB];
/* calculation of cylinder number */
(*tab).nb_cylinder = (Sd_disk_size() + 1) /
(sd_tab_format[MMC_64MB].nb_head *
sd_tab_format[MMC_64MB].nb_sector);
return tab;
}
if (Sd_disk_size() <= MMC_SIZE_128MB)
{
*tab = sd_tab_format[MMC_128MB];
/* calculation of cylinder number */
(*tab).nb_cylinder = (Sd_disk_size() + 1) /
(sd_tab_format[MMC_128MB].nb_head *
sd_tab_format[MMC_128MB].nb_sector);
return tab;
}
else
{
*tab = sd_tab_format[MMC_256MB];
/* calculation of cylinder number */
(*tab).nb_cylinder = (Sd_disk_size() + 1) /
(sd_tab_format[MMC_256MB].nb_head *
sd_tab_format[MMC_256MB].nb_sector);
return tab;
}
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -