📄 sd.c
字号:
#include "dp8051.h"
#include "config.h"
#include "absacc.h"
#include "constant.h"
#include "variable.h"
#include "function.h"
#include "sdhost.h"
#include "sssmp3_regs.h"
#include "fat.h"
#include "mp3_appl.h"
//***********************************************
#if 0
idata Uint32 sd_mem_size; /* memory disk size in pages */
#define Sd_disk_size() (( Uint32 )( sd_mem_size ))
#endif
extern Bool gfSysUSBMP3Mode;
/************************************************
函 数 名: SYSDelay()
功 能:系统延时
说 明:
调 用:
全局变量:i
入口参数:无
出口参数:无
返 回 值:无
************************************************/
void SYSDelay(void)
{
for( varAl.i = 0; varAl.i < 0x1FFF; varAl.i++ );
}
/************************************************
函 数 名: SDCIF_Init()
功 能:SD Host初始化
说 明:
调 用:
全局变量:
入口参数:无
出口参数:无
返 回 值:无
************************************************/
void SDCIF_Init( void )
{
// for SD_Host initial, 100KHz~400KHz
// Either VBUS in or not
if( gfSysUSBMP3Mode )
{
// in USB mode
SDH_CLOCK = 0x4C;
}
else
{
// in MP3 mode
//SDH_CLOCK = 0x0F; // CLK down to 380(375)KHz for MMC card,
SDH_CLOCK = 0x1F; // CLK down to 380(375)KHz for MMC card,
} // but In USB V_Bus mode will be 375*2.5=937KHz
//SDH_CLOCK = 0x0F;//32分频
//SDH_DMA_CS = 0x05;//SRAM5
// select SD DMA Buffer
//SDH_DMA_CS = 0x00; // select buffer 0 at 0x9000
SDH_DMA_CS = 0x01; // select buffer 0 at 0x9000
varAl.USB_DMA_CS = 0;
SDIFCON0 = CLK_EN; //clock enable
BLKCNT11_08 = 0;
BLKCNT07_00 = 0;
BLKLEN11_08 = 0x02;
BLKLEN07_00 = 0x00;
DATACON = 0x00;
// pls note that new FPGA has added one byte timer count
DTIMER15_08 = 0xFF;
DTIMER07_00 = 0xFF;
}
/************************************************
函 数 名: GetSDMemoryOCR()
功 能:获得SD卡Operating Conditions Register
说 明:SDCIF_IF: 0 -> SD Memory,1 -> SDIO,2 --> MMC
调 用:
全局变量:RCA, OCR, SDCIF_IF
入口参数:无
出口参数:无
返 回 值:OK or KO
************************************************/
Bool GetSDMemoryOCR( void )
{
Bool flag = 0;
Bool SDv20CCS = 0;
SDCIF_CMD0();
SDCIF_CMD08();
SDVar.RCA[ 1 ] = 0;
SDVar.RCA[ 0 ] = 0;
SDVar.OCR[ 3 ] = 0;
if( SDVar.Info.CardVer2 )
SDVar.OCR[ 3 ] |= 0x40; // SD 2.0 --> CMD8 resp
SDVar.OCR[ 2 ] = 0;
SDVar.OCR[ 1 ] = 0;
SDVar.OCR[ 0 ] = 0;
do
{
// --------- CMD55---------- RCA = 0x0000
if( !SDCIF_CMD55())
{
flag = 1;
break;
}
// --------- ACMD41---------- OCR = 0x0000 -> High
if( !SDCIF_ACMD41())
{
flag = 1;
break;
}
if( SDVar.Info.CardVer2 )
{
// SD 2.0 --> CMD8 resp
SDVar.OCR[ 3 ] = 0x40;
if( RESP119_112 & BIT6 )
SDv20CCS = 1;
}
else
{
SDVar.OCR[ 3 ] = RESP119_112 & 0x7F;
}
SDVar.OCR[ 2 ] = RREP111_104;
SDVar.OCR[ 1 ] = RREP103_096;
SDVar.OCR[ 0 ] = RREP095_088;
}
while( !( RESP119_112 & 0x80 )); // wait Bit31 is ready
SDVar.Info.SDCIF_IF = 0; //0 -> SD Memory
if( SDv20CCS == 0 )
SDVar.Info.CardVer2 = 0 ; // SDv20 card but in low-capacity card
//MMC
if( !flag )
return OK;
SDIFCON0 = 0x00; // CLK Dis-able ,Mason@20060309
for( varAl.i = 0; varAl.i < 0x7000; varAl.i++ ); // delay
// gfSysUSBMP3Mode
if( gfSysUSBMP3Mode )
{
// in USB mode
SDH_CLOCK = 0x59;
}
else
{
SDH_CLOCK = 0x27;
}
//SDH_CLOCK = 0x3B;
SDIFCON0 = CLK_EN; // CLK enable & 1-bit Bus mode
SDCIF_CMD0();
SDVar.OCR[ 3 ] = 0;
SDVar.OCR[ 2 ] = 0;
SDVar.OCR[ 1 ] = 0;
SDVar.OCR[ 0 ] = 0;
// Finding MMC card by CMD1
do
{
if( !SDCIF_CMD1())
return KO;
SDVar.OCR[ 3 ] = RESP119_112 & 0x7F;
SDVar.OCR[ 2 ] = RREP111_104;
SDVar.OCR[ 1 ] = RREP103_096;
SDVar.OCR[ 0 ] = RREP095_088;
}
while( !( RESP119_112 & 0x80 )); // wait Bit31 is ready
SDVar.Info.SDCIF_IF = 2; //2 --> MMC
return OK;
}
/************************************************
函 数 名: SDMemoryCardInit()
功 能:SD卡初始化
说 明:
调 用:
全局变量:BusBits
入口参数:无
出口参数:无
返 回 值:无
************************************************/
void SDMemoryCardInit( void )
{
idata unsigned char CMD6_SW;
if( !SDCIF_CMD2()
&& ( SDVar.SDCIF_IF == 2 )) // for MMC card, init twice if its failed in 1st time
{
SDH_CLOCK = 0x40;
//SDH_CLOCK = 0x19; // 230K seems all OK
SYSDelay();
GetSDMemoryOCR();
if( !SDCIF_CMD2())
{
SDH_CLOCK = 0x50; // 46K for MMC one last time
SYSDelay();
GetSDMemoryOCR();
SDCIF_CMD2();
}
}
SDCIF_CMD3();
SDCIF_CMD09();
if( gfSysUSBMP3Mode )
{
// Read Card capacity only in USB mode
Read_CardCapacity(); // Mason@0116
}
// CMD7 to enter Transfer Mode
SDCIF_SDIOCMD7(); // SD & SDIO use a same CMD7
//* change to 4 bits mode for SD Card only
if( !SDVar.Info.SDCIF_IF )
{
SDCIF_CMD55();
SDVar.BusBits = 0x02; //2 -> 4-bit bus
SDCIF_ACMD06(); //set bus wide
/*if(SDVar.ErrVal)
{
//while(P1_6);
SDIFCON0 = 0x00;
SYSDelay();
(*(void(*)())0)();
}*/
}
// need to add MMC in High-speed mode
if( gfSysUSBMP3Mode )
{
// Detect Speed mode in USB mode
for( varAl.i = 0; varAl.i < 64; varAl.i++ )
XBYTE[ 0x9000 + varAl.i ] = 0;
ChkCurrentState();
if( SDVar.Info.SDCIF_IF == 0 )
{
CMD6_SW = 0;
if( SDCIF_CMD6( SWITCH_FUNCTION_CHECK ))
{
_nop_();
_nop_();
_nop_();
_nop_();
for( varAl.i = 0; varAl.i < 0x1ff; varAl.i++ ); // a delay --> must
if(( XBYTE[ 0x9000 + 13 ]& 0x03 ) == 0x03 )
{
if( SDCIF_CMD6( SWITCH_FUNCTION_SET ))
CMD6_SW = 1;
else
CMD6_SW = 0;
}
}
}
_nop_();
_nop_();
_nop_();
_nop_();
if(( SDVar.Info.CardVer2 )||( CMD6_SW == 1 ))
SDH_CLOCK = 0x00; // CLK up to 30MHz for High-Speed mode
else
SDH_CLOCK = 0x01; // CLK down to 15MHz for SD Memory card
}
else
{
// in MP3 mode , SD Host in 12MHz
SDH_CLOCK = 0x00;
}
//SDH_CLOCK = CLK_SEL; //system clock
//DTIMER15_08 = 0x00;
//DTIMER07_00 = 0x2E;
}
/************************************************
函 数 名: SDCIF_CMD0()
功 能:Resets all cards to Idle State
说 明:
调 用:
全局变量:
入口参数:无
出口参数:无
返 回 值:无
************************************************/
//复位SD卡,进入空闲状态
void SDCIF_CMD0( void )
{
ARG31_24 = 0;//argument dont't care
ARG23_16 = 0;
ARG15_08 = 0;
ARG07_00 = 0;
CMDCON = 0;
CMDINDEX = GO_IDLE_STATE;
while( !( STATUS07_00 & CMDSEND ));
STATUS07_00 = 0xFF;
}
/************************************************
函 数 名: SDCIF_CMD1()
功 能:ask MMC to send their Operation Conditions
说 明:
调 用:
全局变量:OCR
入口参数:无
出口参数:无
返 回 值:OK or KO
************************************************/
Bool SDCIF_CMD1(void)// MMC card used
{
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; // short respnse
CMDINDEX = SEND_OP_COND; // CMD1
while( !( STATUS07_00 & CMDSEND ));
while( !( STATUS07_00 & RSPRXVP ))
{
if(( STATUS07_00 & RSPTIMEOUT )/*||( STATUS07_00 & CRC7ERROR )*/)
{
//STATUS07_00 = 0xFF;
//return KO;
status = KO;
break;
}
}
STATUS07_00 = 0xFF;
return status;
}
/************************************************
函 数 名: SDCIF_CMD2()
功 能:Asks any card to send their CID numbers on the CMD line
说 明:
调 用:
全局变量:
入口参数:无
出口参数:无
返 回 值:OK or KO
************************************************/
//获得CID(card identification) 进入识别状态
Bool SDCIF_CMD2( void )
{
Bool status = OK;
idata U8 deleycnt;
//argument dont't care
/*if( SDVar.Info.SDCIF_IF )
{
// for MMC
ARG31_24 = 0;
ARG23_16 = 0;
ARG15_08 = 0;
ARG07_00 = 0;
}*/
CMDCON = LONGRSP | WAITRSP; // Long respnse
CMDINDEX = ALL_SEND_CID; // CMD2
while( !( STATUS07_00 & CMDSEND ));
while( !( STATUS07_00 & RSPRXVP ))
{
/*if(( STATUS07_00 & RSPTIMEOUT )
||( STATUS07_00 & CRC7ERROR ))*/
if( STATUS07_00 &( RSPTIMEOUT | CRC7ERROR ))
{
//STATUS07_00 = 0xFF;
//return KO;
for( deleycnt = 0; deleycnt < 0xF0; deleycnt++ );
status = KO;
break;
}
}
STATUS07_00 = 0xFF;
//return OK;
return status;
}
/************************************************
函 数 名: SDCIF_CMD3()
功 能:Asks the card to publish a new relative address
说 明:get RCA
调 用:
全局变量:RCA
入口参数:无
出口参数:无
返 回 值:OK or KO
************************************************/
//获得RCA(relative card address)
Bool SDCIF_CMD3( void )
{
Bool status = OK;
//argument dont't care if SD
if( SDVar.Info.SDCIF_IF ) //MMC or SDIO
{
SDVar.RCA[ 1 ] = 0;
SDVar.RCA[ 0 ] = 1;
ARG31_24 = SDVar.RCA[ 1 ];
ARG23_16 = SDVar.RCA[ 0 ];
ARG15_08 = 0;
ARG07_00 = 0;
}
CMDCON = WAITRSP; // short respnse
CMDINDEX = SEND_RCA; // CMD3
while( !( STATUS07_00 & CMDSEND ));
while( !( STATUS07_00 & RSPRXVP ))
{
/*if(( STATUS07_00 & RSPTIMEOUT )
||( STATUS07_00 & CRC7ERROR ))*/
if( STATUS07_00 &( RSPTIMEOUT | CRC7ERROR ))
{
//STATUS07_00 = 0xFF;
//return KO;
status = KO;
break;
}
}
STATUS07_00 = 0xFF;
if( !SDVar.Info.SDCIF_IF ) //SD
{
SDVar.RCA[ 1 ] = RESP119_112; //get RCA
SDVar.RCA[ 0 ] = RREP111_104;
}
SDVar.CardStatus[ 1 ] = RREP103_096;
SDVar.CardStatus[ 0 ] = RREP095_088;
ChkCurrentState();
//return OK;
return status;
}
/************************************************
函 数 名: SDCIF_CMD6()
功 能:Checking High-speed mode supported or not
说 明:
调 用:
全局变量:RCA
入口参数:无
出口参数:无
返 回 值:OK or KO
************************************************/
Bool SDCIF_CMD6( U8 modeset )
{
Bool status = OK;
//if( SDVar.Info.CardVer2 == 0 )
{
BLKLEN11_08 = 0x00;
BLKLEN07_00 = 0x40;
}
DATACON = 0x00;
ARG31_24 = modeset;
ARG23_16 = 0xFF;
ARG15_08 = 0xFF;
ARG07_00 = 0x01;
//CMDCON = WAITRSP; // short respnse
CMDCON = WAITRSP | DATA_WITH; // short respnse with data Xfer
CMDINDEX = SWITCH_FUNCTION; //CMD6
while( !( STATUS07_00 & CMDSEND ));
while( !( STATUS07_00 & RSPRXVP ))
{
// maybe re-moved
//if( STATUS07_00 & RSPTIMEOUT )
if( STATUS07_00 &( RSPTIMEOUT | CRC7ERROR | DTIMEOUT | CRC16ERROR ))
{
status = KO;
break;
}
/*if( STATUS07_00 & CRC7ERROR )
{
status = KO;
break;
}*/
//}
//while( !( STATUS07_00 & XFEREND ))
//{
// Marked for USB Testing...Mason@20060302
/*if( STATUS07_00 & DTIMEOUT )
{
status = KO;
break;
}
if( STATUS07_00 & CRC16ERROR )
{
status = KO;
break;
}*/
if( STATUS07_00 & XFEREND )
{
//status = OK;
break;
}
}
STATUS07_00 = 0xFF;
BLKLEN11_08 = 0x02;
BLKLEN07_00 = 0x00;
return status;
}
/************************************************
函 数 名: SDCIF_SDIOCMD7()
功 能:选择/释放SD卡(RCA)
说 明:
调 用:
全局变量:RCA
入口参数:无
出口参数:无
返 回 值:OK or KO
************************************************/
Bool SDCIF_SDIOCMD7( void )
{
Bool status = OK;
ARG31_24 = SDVar.RCA[ 1 ];//argument = RCA, form CMD3
ARG23_16 = SDVar.RCA[ 0 ];
//ARG15_08 = 0;//argument dont't care
//ARG07_00 = 0;
CMDCON = WAITRSP;
CMDINDEX = SELECT_DESELECT;
while( !( STATUS07_00 & CMDSEND ));
while( !( STATUS07_00 & RSPRXVP ))
{
/*if(( STATUS07_00 & RSPTIMEOUT )
||( STATUS07_00 & CRC7ERROR ))*/
if( STATUS07_00 &( RSPTIMEOUT | CRC7ERROR ))
{
//STATUS07_00 = 0xFF;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -