📄 sdmmc.c
字号:
{
XBYTE[REG_CMDBUF1] = ComBuff[0];
XBYTE[REG_CMDBUF2] = ComBuff[1];
XBYTE[REG_CMDBUF3] = ComBuff[2];
XBYTE[REG_CMDBUF4] = ComBuff[3];
XBYTE[REG_CMDBUF5] = ComBuff[4];
// trigger to TX command 转换命令
XBYTE[REG_SD_TRIGGER] = C_bit_TxCmd; //0x01;
{
U16 tw_TimeOut;
tw_TimeOut = K_CARD_TIMEOUTSECONDS;
while ((XBYTE[REG_SD_STATE1] & 0x0F) != 0x00)
{
tw_TimeOut --;
if (gc_SysCardInsert)
{//if CD pin is HIGH,the C
tw_TimeOut = 0;
}
if (!tw_TimeOut)
{
XBYTE[0xB450] = 0x03;//reset SD interface
gc_ReadWriteTimeOut = 1;
break;
}
}
}
}
void SdTxDummy(void) //USING_0
{
U8 i;
XBYTE[REG_SD_TRIGGER] = 0x20;
for(i=0;i<10;i++);
}
void SDWaitIdle(void) //USING_0
{
{
U16 tw_TimeOut;
tw_TimeOut = K_CARD_TIMEOUTSECONDS;
while ((XBYTE[REG_SD_STATE1] & 0x0F) != 0x00) //wait the card into idle
{
tw_TimeOut --;
if (gc_SysCardInsert)
{
tw_TimeOut = 0;
}
if (!tw_TimeOut)
{
XBYTE[0xB450] = 0x03;//reset SD interface
gc_ReadWriteTimeOut = 1;
break;
}
}
}
}
U8 SDCheckDat0(void)
{
//data0 is high, not busy state
if(XBYTE[REG_SD_STATE0]&0x20)
{
return 1;
}
return 0;
}
U8 SD_SetBusWidth(U8 tc_BusMode)
{
U8 tc_ComBuff[5],tc_RespBuff[17];
U8 tc_Ture;
// SD_SetClock(0);
if(tc_BusMode==C_1BITBUS)
{
XBYTE[REG_SD_TIMER]&=0xfb;
}
//four data bus
else
{
XBYTE[REG_SD_TIMER]|=0x04;
}
//发送CMD55命令和ACMD42命令
tc_ComBuff[0] = 0x77;
tc_ComBuff[1] = gc_SD_RCA[0];
tc_ComBuff[2] = gc_SD_RCA[1];
tc_ComBuff[3] = 0x00;
tc_ComBuff[4] = 0x00;
CommandToSd(tc_ComBuff);
tc_Ture=SDToRespond(tc_RespBuff,C_48BitRsp,C_NeedCrcCheck);
// check the response number
if((tc_Ture)||(tc_RespBuff[0]!=0x37))
{
//error happen
return 0x01;
}
//发送ACMD42命令
tc_ComBuff[0] = 0x6A;
tc_ComBuff[1] = 0x00;
tc_ComBuff[2] = 0x00;
tc_ComBuff[3] = 0x00;
// TX "ACMD42" to connect the pull-up resistor on line 'data3'
if(tc_BusMode==C_1BITBUS)
{
tc_ComBuff[4] = 0x01;
}
// TX "ACMD42" to disconnect the pull-up resistor on line 'data3'
else
{
tc_ComBuff[4] = 0x00;
}
CommandToSd(tc_ComBuff);
tc_Ture=SDToRespond(tc_RespBuff,C_48BitRsp,C_NeedCrcCheck);
// check the response number
if((tc_Ture)||(tc_RespBuff[0]!=0x2a))
{
//error happen
return 0x01;
}
//发送CMD55命令和ACMD6命令
tc_ComBuff[0] = 0x77;
tc_ComBuff[1] = gc_SD_RCA[0];
tc_ComBuff[2] = gc_SD_RCA[1];
tc_ComBuff[3] = 0x00;
tc_ComBuff[4] = 0x00;
CommandToSd(tc_ComBuff);
tc_Ture=SDToRespond(tc_RespBuff,C_48BitRsp,C_NeedCrcCheck);
// check the response number
if((tc_Ture)||(tc_RespBuff[0]!=0x37))
{
//error happen
return 0x01;
}
//发送ACMD6命令
tc_ComBuff[0] = 0x46;
tc_ComBuff[1] = 0x00;
tc_ComBuff[2] = 0x00;
tc_ComBuff[3] = 0x00;
if(tc_BusMode==0)
{
//设置bus的宽度为1bit
tc_ComBuff[4] = 0x00;
}
else
{
//设置bus的宽度为4bit
tc_ComBuff[4] = 0x02;
}
CommandToSd(tc_ComBuff);
tc_Ture=SDToRespond(tc_RespBuff,C_48BitRsp,C_NeedCrcCheck);
// check the response number
if((tc_Ture)||(tc_RespBuff[0]!=0x06))
{
return 0x01;
}
return 0x00;
}
U8 SD_Initializes(U8 tc_CurrCard)
{
if(SD_SetInterface(tc_CurrCard))
{
return 0;
}
SdDetect();
//将SD卡的状态由standy-by改为transfer状态
if(SD_StandByToTrans())
{
return 1;
}
//如果当前卡是SD卡
if(tc_CurrCard==CURRENT_MEDIA_SD)
{
if(SD_SetBusWidth(C_4BITBUS))
{
return 1;
}
}
SD_SetClock(1); //set SD interface clock is 12MHz
return 0;
}
U8 SD_StandByToTrans(void)
{
U8 tc_ComBuff[5],tc_RespBuff[17];
U8 tc_Ture;
// CMD13
tc_ComBuff[0] = 0x4D;
tc_ComBuff[1] = gc_SD_RCA[0];
tc_ComBuff[2] = gc_SD_RCA[1];
tc_ComBuff[3] = 0x00;
tc_ComBuff[4] = 0x00;
CommandToSd(tc_ComBuff);
tc_Ture=SDToRespond(tc_RespBuff,C_48BitRsp,C_NeedCrcCheck);
if((tc_Ture)||(tc_RespBuff[0]!=0x0d))
{
return 0x01;
}
if((tc_RespBuff[3] &0x1e)==C_State_Stby)
{
// CMD7
tc_ComBuff[0] = 0x47;
tc_ComBuff[1] = gc_SD_RCA[0];
tc_ComBuff[2] = gc_SD_RCA[1];
tc_ComBuff[3] = 0x00;
tc_ComBuff[4] = 0x00;
CommandToSd(tc_ComBuff);
tc_Ture=SDToRespond(tc_RespBuff,0,1);
if((tc_Ture)||(tc_RespBuff[0]!=0x07))
{
return 0x01;
}
}
else
{
//是否已经处于transfer状态
if((tc_RespBuff[3] &0x1e)!= C_State_Tran)
{
return 0x01;
}
}
//发送"CMD13"得到卡的状态,检查卡的状态是否转化为transfer状态
tc_ComBuff[0] = 0x4D;
tc_ComBuff[1] = gc_SD_RCA[0];
tc_ComBuff[2] = gc_SD_RCA[1];
tc_ComBuff[3] = 0x00;
tc_ComBuff[4] = 0x00;
CommandToSd(tc_ComBuff);
tc_Ture=SDToRespond(tc_RespBuff,0,1);
//检查回应是否出错
if((tc_Ture)||(tc_RespBuff[0]!=0x0d))
{
return 0x01;
}
//检查卡的状态是否为transfer状态
if((tc_RespBuff[3] &0x1e)!= C_State_Tran)
{
return 0x01;
}
return 0x00;
}
void SD_SetBlockLen(U16 BlockSize)
{
//ECC mode bytes/page
XBYTE[REG_ECCMODE] = 0x01;
XBYTE[REG_DATALEN7_0] = (U8)(BlockSize);
XBYTE[REG_DATALEN9_8] = (U8)(BlockSize>>8);
}
bit STORAGE_Detect()
{
U8 tc_BattValue;
tc_BattValue=USER_READSAR(1);
if(tc_BattValue<0x50)
{
// SD exist
gc_SysCardInsert = 0;
return 0;
}
gc_SysCardInsert = 1;
return 1;
}
U8 SD_Write_LogicSector(U32 tdw_LogicSectorAddr,U32 tdw_WriteSectorNumber)
{
U8 tc_ComBuff[5],tc_RespBuff[17];
U8 tc_Ture;
U16 TmpAddr;
U8 tc_WriteError;
U8 tc_FirstEnterLoopFlag;
U8 tc_ET0;
tc_WriteError = 0;
if(SDHC==0)
{
tdw_LogicSectorAddr=tdw_LogicSectorAddr<<9;
}
// CMD25
tc_ComBuff[0] = 0x59;
tc_ComBuff[1] = (tdw_LogicSectorAddr & 0xFF000000) >> 24;
tc_ComBuff[2] = (tdw_LogicSectorAddr & 0x00FF0000) >> 16;
tc_ComBuff[3] = (tdw_LogicSectorAddr & 0x0000FF00) >> 8;
tc_ComBuff[4] = (tdw_LogicSectorAddr & 0x000000FF);
tc_ET0 = ET0;
ET0 = 0;//必须关闭中断,否则会影响数据读写
CommandToSd(tc_ComBuff);
tc_Ture=SDToRespond(tc_RespBuff,C_48BitRsp,C_NeedCrcCheck);
ET0 = tc_ET0;//必须打开中断
if((tc_Ture)||(tc_RespBuff[0]!=0x19))
{
gc_ReadWriteTimeOut = 1;
return 1;
}
if(gc_ReadWriteDataArea < 2)
{
while(tdw_WriteSectorNumber)
{
if(gc_ReadWriteDataArea == 0)
{
TmpAddr = &gc_PlayRecordDataBuf;
}
else
{
TmpAddr = &gc_UserDataBuf;
}
SdTxDummy(); //lizhn
SDWaitIdle(); //lizhn
XBYTE[0xB304] |= 0x01; //Reset DMA
XBYTE[0xB304] &= 0xfe; //this bit will not auto clear by HW, so must clear it by firmwire
XBYTE[0xB301] = 0x20;//set the DMA Direction from Sram to Flash Memory
XBYTE[0xB112] =(unsigned char)(TmpAddr & 0xff);//set DMA scr Address
XBYTE[0xB113] =(unsigned char)((TmpAddr>>8) & 0xff);
XBYTE[0xB3C0] = 0x00; //clear DMA interrupt
XBYTE[0xB302] = 0xff;//(UCHAR)nByte;
XBYTE[0xB303] = 0x01;//(UCHAR)(nByte>>8);//actual size = DMAsize+1;注意是字节数减一;
XBYTE[0xB304] = 0x09;
XBYTE[0xB304] = 0x08;//set internal buffer is four byte and reset the DMA
XBYTE[0xB3B0] = 0x01; //start DMA
if(UsbReadWaitSD(K_WRITE_CARD))
{
tc_WriteError = 1;
gc_ReadWriteTimeOut = 1;
break;
}
tdw_WriteSectorNumber-- ;
}
}
else
{
XBYTE[REG_SRAMDMASRCIDX15_8] = 0xff;
XBYTE[REG_SRAMDMADSTIDX15_8] = 0xff;
tc_FirstEnterLoopFlag = 1;
XBYTE[REG_BULKOUTACKCTR] = 0x00;//set got Bulkout ACK when USB Device acceptd 512 byte
XBYTE[REG_BULKOUTAUTO]=0x01;//set bulk auto //REG_BULKOUTAUTO = 0xB511
XBYTE[REG_BULK_BUF_CLR]=0x22; //REG_BULK_BUF_CLR = 0xB5E9
XBYTE[REG_DMA_STATE] |= 0x01; //Reset DMA //REG_DMA_STATE = 0xB304
XBYTE[REG_DMA_STATE] &= 0xfe; //该位不能硬件清除,所以必须将其清掉,不然DMA不能正常传输
XBYTE[REG_DMA_SEL] = 0x20;//Set DMA transfer from Sram to FM //REG_DMA_SEL = 0xB301
XBYTE[REG_BULK_EN0] = 0x02;// star DMA from USB to Bank0 //REG_BULK_EN0 = 0xB5A1
do{
if(!tc_FirstEnterLoopFlag)
{
if(UsbReadWaitSD(K_WRITE_CARD))//wait Bank1 To SD Card;
{
tc_WriteError = 1;
gc_ReadWriteTimeOut = 1;
break;
}
} //wait pc ack
SdTxDummy(); //lizhn
SDWaitIdle(); //lizhn
tc_FirstEnterLoopFlag = 0;
XBYTE[REG_SRAMDMASRCIDX7_0] = K_USB_BANK0_LOW_ADDR;//set DMA transfer Size //REG_SRAMDMASRCIDX7_0 = 0xB112
XBYTE[REG_SRAMDMASRCIDX15_8] = K_USB_BANK0_HIGH_ADDR;//actual size = DMAsize+1;//REG_SRAMDMASRCIDX15_8 = 0xB113
XBYTE[REG_DMASIZE7_0] = 0xff; // REG_DMASIZE7_0 = 0xB302
XBYTE[REG_DMASIZE10_8] = 0x01; //REG_DMASIZE10_8 = 0xB303//set DMA Size
XBYTE[REG_DMA_STATE] = 0x09; //REG_DMA_STATE = 0xB304
XBYTE[REG_DMA_STATE] = 0x08;//set Inernal buffer four bytes,and reset DMA
XBYTE[REG_DMACMP] = 0x00; //clear DMA interrupt //REG_DMACMP = 0xB3C0
XBYTE[REG_DMASTART] = 0x01;//start DMA from Bank0 to SD Card //REG_DMASTART = 0xB3B0
tdw_WriteSectorNumber -- ;
if(tdw_WriteSectorNumber == 0)
{
if(UsbReadWaitSD(K_WRITE_CARD))//wait Bank0 To SD Card
{
tc_WriteError = 1;
gc_ReadWriteTimeOut = 1;
}
break;
}
XBYTE[REG_BULK_EN1] = 0x02;//start DMA from USB to Bank1;//REG_BULK_EN1 = 0xB5A2
if(UsbReadWaitSD(K_WRITE_CARD))//wait Bank0 to SD Card
{
tc_WriteError = 1;
gc_ReadWriteTimeOut = 1;
break;
}
SdTxDummy(); //lizhn
SDWaitIdle(); //lizhn
if(UsbReadWaitBank1USB(K_WRITE_CARD))//wait USB to Bank1
{
tc_WriteError = 1;
gc_ReadWriteTimeOut = 1;
break;
}
XBYTE[REG_SRAMDMASRCIDX7_0] = K_USB_BANK1_LOW_ADDR;//REG_SRAMDMASRCIDX7_0 = 0xB112
XBYTE[REG_SRAMDMASRCIDX15_8] = K_USB_BANK1_HIGH_ADDR; //REG_SRAMDMASRCIDX15_8 = 0xB113
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -