📄 sdmmc.c
字号:
XBYTE[REG_DMASIZE7_0] = 0xff;//REG_DMASIZE7_0 = 0xB302
XBYTE[REG_DMASIZE10_8] = 0x01;//actual size = DMAsize+1;//REG_DMASIZE10_8 = 0xB303
XBYTE[REG_DMA_STATE] = 0x09;//REG_DMA_STATE = 0xB304
XBYTE[REG_DMA_STATE] = 0x08;//Set Inernal buffer 4 Byte,and Reset DMA
XBYTE[REG_DMACMP] = 0x00; //clear DMA interrupt//REG_DMACMP = 0xB3C0
XBYTE[REG_DMASTART] = 0x01; //Start DMA from Bank1 To SD//REG_DMASTART = 0xB3B0
tdw_WriteSectorNumber--;
if(tdw_WriteSectorNumber == 0)
{
if(UsbReadWaitSD(K_WRITE_CARD))//wait Bank1 To SD
{
gc_ReadWriteTimeOut = 1;
tc_WriteError = 1;
}
break;
}
XBYTE[REG_BULK_EN0] = 0x02;//start USB to Bank0;//REG_BULK_EN0 = 0xB5A1
}while(1);
XBYTE[REG_BULK_ACK] = XBYTE[REG_BULK_ACK] & 0xdd;//clear Bank0 Bulkout ACK//REG_BULK_ACK = 0xB5C2
XBYTE[REG_BULKOUTAUTO] = 0x00; //disable usb auto //REG_BULKOUTAUTO = 0xB511
if(tc_WriteError)
{
XBYTE[0xB519] = 0x00; //512B (default)
//Clean Bulk IN/OUT Buffer pointer and Data linker setting
XBYTE[0xb5E9] = 0xff;
XBYTE[0xb5EA] = 0xff;
XBYTE[0xb5A0] &= 0xfc;
XBYTE[0xb5A1] = 0x02;
XBYTE[0xb5A2] = 0x00;
XBYTE[0xB5eb] = K_USB_CLASS_OUT_ACK_MASK;//0x01;
gw_WaitTimeOut = K_CARD_TIMEOUTSECONDS; //lizhn add for fail
while (XBYTE[0xB5ee] == 0)
{
if(gw_WaitTimeOut == 0)
{
XBYTE[REG_SDRST] = 0x03;//Reset SD Interface //REG_SDRST = 0xB450
gc_ReadWriteTimeOut = 1;//Set timeout flag
break;
}
gw_WaitTimeOut--;
}
XBYTE[0xB5e8] = K_USB_CLASS_OUT_STALL; //OUT STALL
}
}
// CMD12
tc_ComBuff[0] = 0x4C;
tc_ComBuff[1] = 0;
tc_ComBuff[2] = 0;
tc_ComBuff[3] = 0;
tc_ComBuff[4] = 0;
CommandToSd(tc_ComBuff);
tc_Ture=SDToRespond(tc_RespBuff,C_48BitRsp,C_NeedCrcCheck);
//检查传送命令是否成功
if((tc_Ture)||(tc_RespBuff[0]!=0x0C))
{
gc_ReadWriteTimeOut = 1;
return 1;
}
//等待not busy信号
gw_WaitTimeOut = K_CARD_TIMEOUTSECONDS;
do{
SdTxDummy();
tc_Ture=SDCheckDat0();
if(gw_WaitTimeOut == 0)
{
XBYTE[0xB450] = 0x03;
gc_ReadWriteTimeOut = 1;
return 0xff;
}
gw_WaitTimeOut--;
} while(tc_Ture == 0);
SdTxDummy();
SDWaitIdle();
return tc_WriteError;
}
U8 SD_Read_LogicSector(U32 tdw_LogicSectorAddr,U32 tdw_ReadSectorNumber)
{
U8 tc_ComBuff[5],tc_RespBuff[17];
U8 tc_Ture;
U16 TmpAddr;
U8 tc_ReadError;
U8 tc_FirstEnterLoopFlag;
U8 tc_ET0;
tc_ReadError = 0;
if(SDHC==0)
{
tdw_LogicSectorAddr<<=9;
}
// CMD18
tc_ComBuff[0] = 0x52;
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) >> 0;
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]!=0x12))
{
gc_ReadWriteTimeOut = 1;
return 1;
}
if(gc_ReadWriteDataArea < 2)//if MCU Read SD
{
while(tdw_ReadSectorNumber)//
{
//设置DMA送数据的方向为 sd to sramm
if(gc_ReadWriteDataArea == 0)
{
TmpAddr = &gc_PlayRecordDataBuf;
}
else
{
TmpAddr = &gc_UserDataBuf;
}
XBYTE[REG_DMA_STATE] |= 0x01; //REG_DMA_STATE = 0xB304
XBYTE[REG_DMA_STATE] &= 0xfe; //reset DMA
XBYTE[REG_DMA_SEL] = 0x02;//set the DMA from Flash memory to Sram
XBYTE[REG_SRAMDMADSTIDX7_0] = (unsigned char)(TmpAddr & 0xff);//set DMA Sram Address //REG_SRAMDMADSTIDX7_0 = 0xB114
XBYTE[REG_SRAMDMADSTIDX15_8] = (unsigned char)((TmpAddr>>8) & 0xff);//REG_SRAMDMADSTIDX15_8 = 0xB115
XBYTE[REG_DMASIZE7_0] = 0xFF;//set dma size //REG_DMASIZE7_0 = 0xB302
XBYTE[REG_DMASIZE10_8] = 0x01;//the transfer number is the size + 1 //REG_DMASIZE10_8 = 0xB303
XBYTE[REG_DMACMP] = 0;////clear DMA interrupt //REG_DMACMP = 0xB3C0
XBYTE[REG_DMA_STATE] = 0x09; //REG_DMA_STATE = 0xB304
XBYTE[REG_DMA_STATE] = 0x08;//set four bytes internal buffer and reset DMA
XBYTE[REG_DMASTART] = 0x01;//start DMA //REG_DMASTART = 0xB3B0
if(UsbReadWaitSD(K_READ_CARD))//wait Read DMA Over
{
tc_ReadError = 1;
gc_ReadWriteTimeOut = 1;
break;
}
tdw_ReadSectorNumber--;
}
}
else
{
XBYTE[REG_SRAMDMASRCIDX15_8] = 0xff;
XBYTE[REG_SRAMDMADSTIDX15_8] = 0xff;
tc_FirstEnterLoopFlag = 1;
XBYTE[REG_BINLASTEN]=0x00;//Set Not auto turn on BulkIn when DMA over
XBYTE[REG_BULK_ACK] = XBYTE[REG_BULK_ACK] & 0xee; //clear transfer ack //REG_BULK_ACK = 0xB5C2
XBYTE[REG_BULK_BUF_CLR] = 0x11;//clear Bulk in Buffer //REG_BULK_BUF_CLR = 0xB5E9
XBYTE[REG_BULKINAUTO] = 0x1;//Set Bulkin Auto //REG_BULKINAUTO = 0xB510
XBYTE[REG_DMA_STATE] |= 0x01; //REG_DMA_STATE = 0xB304
XBYTE[REG_DMA_STATE] &= 0xfe; //reset DMA
XBYTE[REG_DMA_SEL] = 0x02;//Set DMA from FM to Sram // REG_DMA_SEL = 0xB301
XBYTE[REG_SRAMDMADSTIDX7_0] = K_USB_BANK0_LOW_ADDR;
XBYTE[REG_SRAMDMADSTIDX15_8] = K_USB_BANK0_HIGH_ADDR;//set Sram Address for DMA(USB Bank0)
XBYTE[REG_DMASIZE7_0] = 0xFF;//dma size low Byte //REG_DMASIZE7_0 = 0xB302
XBYTE[REG_DMASIZE10_8] = 0x01;//dma size high Byte //REG_DMASIZE10_8 = 0xB303
XBYTE[REG_DMACMP] = 0x00;////clear DMA interrupt //REG_DMACMP = 0xB3C0
XBYTE[REG_DMA_STATE] = 0x09; //REG_DMA_STATE = 0xB304
XBYTE[REG_DMA_STATE] = 0x08;//sent four Bytes internal buffer and Reset DMA
XBYTE[REG_DMASTART] = 0x01;//start DMA(SD Card -> Bank0) // REG_DMASTART = 0xB3B0
do{
if(!tc_FirstEnterLoopFlag)//If It is not the first time enter the transfering loop,
{ //there will be useful data in Bank1 to be transfered
if(UsbReadWaitBank1USB(K_READ_CARD))//wait Bank1 to USB
{
tc_ReadError = 1;
gc_ReadWriteTimeOut = 1;
break;
}
}
tc_FirstEnterLoopFlag = 0;
if(UsbReadWaitSD(K_READ_CARD))//wait SD to Bank0 DMA
{
tc_ReadError = 1;
gc_ReadWriteTimeOut = 1;
break;
}
tdw_ReadSectorNumber--;
XBYTE[REG_USBBANK0WRIDX7_0] = 0x00;//REG_USBBANK0WRIDX7_0 = 0xB515
XBYTE[REG_USBBANK0WRIDX11_8] = 0x02; //REG_USBBANK0WRIDX11_8 = 0xB516
//set how many bytes will transfer to USB while command mode
XBYTE[REG_BULK_EN0] = 0x1;//Trigger Bank0 To USB DMA //REG_BULK_EN0 = 0xB5A1
if(tdw_ReadSectorNumber == 0)
{
break;
}
XBYTE[REG_SRAMDMADSTIDX7_0] = K_USB_BANK1_LOW_ADDR; //REG_SRAMDMADSTIDX7_0 = 0xB114
XBYTE[REG_SRAMDMADSTIDX15_8] = K_USB_BANK1_HIGH_ADDR;//REG_SRAMDMADSTIDX15_8 = 0xB115
//set Sram address for DMA (USB Bank1)
XBYTE[REG_DMASIZE7_0] = 0xFF;//dma size//REG_DMASIZE7_0 = 0xB302
XBYTE[REG_DMASIZE10_8] = 0x01;//REG_DMASIZE10_8 = 0xB303
XBYTE[REG_DMA_STATE] = 0x09; //REG_DMA_STATE = 0xB304
XBYTE[REG_DMA_STATE] = 0x08;//set internal buffer four bytes ,and reset DMA
XBYTE[REG_DMASTART] = 0x01;//Start DMA from SD ->Bank1 //REG_DMASTART = 0xB3B0
if(UsbReadWaitSD(K_READ_CARD))//wait SD to Bank1
{
tc_ReadError = 1;
gc_ReadWriteTimeOut =1;
break;
}
tdw_ReadSectorNumber-- ;
XBYTE[REG_USBBANK1WRIDX7_0] = 0x00; //REG_USBBANK1WRIDX7_0 = 0xB517
XBYTE[REG_USBBANK1WRIDX11_8] = 0x02; //REG_USBBANK1WRIDX11_8 = 0xB518
//set how many bytes will transfer to USB while command mode
XBYTE[REG_BULK_EN1] = 0x01;//启动Bank1 To USB //REG_BULK_EN1 = 0xB5A2
if(tdw_ReadSectorNumber == 0)
{//判断是否读完
if(UsbReadWaitBank1USB(K_READ_CARD))
{
tc_ReadError = 1;
gc_ReadWriteTimeOut = 1;
}
break;
}
XBYTE[REG_SRAMDMADSTIDX7_0] = K_USB_BANK0_LOW_ADDR;//REG_SRAMDMADSTIDX7_0 = 0xB114;
XBYTE[REG_SRAMDMADSTIDX15_8] = K_USB_BANK0_HIGH_ADDR;//set sram address for DMA(USB Bank0)//REG_SRAMDMADSTIDX15_8 = 0xB115
XBYTE[REG_DMASIZE7_0] = 0xFF;//dma size //REG_DMASIZE7_0 = 0xB302
XBYTE[REG_DMASIZE10_8] = 0x01;//设置传输字节数 //REG_DMASIZE10_8 = 0xB303
XBYTE[REG_DMA_STATE] = 0x09; //REG_DMA_STATE = 0xB304
XBYTE[REG_DMA_STATE] = 0x08; //set internal buffer 4 bytes,and reset DMA
XBYTE[0xB3B0] = 0x01;//start SD To Bank0;
}while(1);
//clear bulk in transaction ACK.
XBYTE[REG_BULKINAUTO] =0x00;//disable Bulk in auto // REG_BULKINAUTO = 0xB510
XBYTE[REG_BULK_ACK] = XBYTE[REG_BULK_ACK] & 0xee; //clear usb ACK //REG_BULK_ACK = 0xB5C2
if(tc_ReadError) //Read Error
{
//Clean Bulk IN/OUT Buffer pointer and Data linker setting
XBYTE[0xb5E9] = 0xff;
XBYTE[0xb5EA] = 0xff;
XBYTE[0xb5A0] &= 0xfc;
XBYTE[0xb5A1] = 0x02;
XBYTE[0xb5A2] = 0x00;
XBYTE[0xB5eb] = K_USB_CLASS_IN_ACK_MASK;//0x01;
gw_WaitTimeOut = K_CARD_TIMEOUTSECONDS; //lizhn add for fail
while (XBYTE[0xB5ee] == 0)
{
if(gw_WaitTimeOut == 0)
{
XBYTE[REG_SDRST] = 0x03;//Reset SD Interface //REG_SDRST = 0xB450
gc_ReadWriteTimeOut = 1;//Set timeout flag
break;
}
gw_WaitTimeOut--;
}
XBYTE[0xB5e8] = K_USB_CLASS_IN_STALL;//IN STALL //
}
}
//TX "CMD12" to stop read Multi block data
tc_ComBuff[0] = 0x4C;
tc_ComBuff[1] = 0;
tc_ComBuff[2] = 0;
tc_ComBuff[3] = 0;
tc_ComBuff[4] = 0;
CommandToSd(tc_ComBuff);
tc_Ture=SDToRespond(tc_RespBuff,C_48BitRsp,C_NeedCrcCheck);
//检查传送命令是否成功
if((tc_Ture)||(tc_RespBuff[0]!=0x0C))
{
gc_ReadWriteTimeOut = 1;
return 1;
}
SdTxDummy();
SDWaitIdle();
return tc_ReadError;
}
U8 SD_STORAGE_Initialize(void)
{
U8 tc_InitSts = 1;
gc_SectorUnit=1;
if (!gc_SysCardInsert)
{//if have card insert
if (!SD_SetInterface(CURRENT_MEDIA_SD))
{
gc_CurrentCard = CURRENT_MEDIA_SD;
gc_CurrentExistMedia |= 0x40;
tc_InitSts = 0;
}
else if (!SD_SetInterface(CURRENT_MEDIA_MMC))
{
gc_CurrentCard = CURRENT_MEDIA_MMC;
gc_CurrentExistMedia |= 0x40;
tc_InitSts = 0;
}
}
if (tc_InitSts == 0)
{
tc_InitSts = SD_Initializes(gc_CurrentCard);
}
if(tc_InitSts == 0)
{
tc_InitSts = DOS_Initialize();
}
else
{
tc_InitSts = 0xff; //dos error
}
gc_DOS_Status = tc_InitSts;//record DOS status
gc_ReadWriteTimeOut = 0;
return tc_InitSts;
}
U8 UsbReadWaitSD(U8 tc_ReadOrWrite)
{
gw_WaitTimeOut = K_CARD_TIMEOUTSECONDS;
while(XBYTE[REG_DMACMP]==0)//wait DMA complete //REG_DMACMP = 0xB3C0
{
if(gw_WaitTimeOut == 0)
{
XBYTE[REG_SDRST] = 0x03;//Reset SD Interface //REG_SDRST = 0xB450
gc_ReadWriteTimeOut = 1;//Set timeout flag
return 0xff;
}
gw_WaitTimeOut--;
}
XBYTE[REG_DMACMP] = 0x00; //clear DMA interrupt //REG_DMACMP = 0xB3C0
if(tc_ReadOrWrite)//if Read SD Card,Only Check the CRC
{
if(!XBYTE[REG_CRC16COR]) //REG_CRC16COR = 0xB46F;
{//检查CRC16是否正确
gc_ReadWriteTimeOut = 1;
return 1;
}
XBYTE[REG_SRAMDMADSTIDX15_8] = 0xff;//When DMA Over,must Set this Register 0xff to release the SRAM Buffer
}else{//if write sd card
U8 tc_Ture;
XBYTE[REG_SD_TRIGGER] = 0x10;//trigger CRC
if(((XBYTE[REG_SD_STATE1])&0x70)!=0x20)//check crc Right or Error
{
gc_ReadWriteTimeOut = 1;
return 1;
}
//wait Card to idle
gw_WaitTimeOut = K_CARD_TIMEOUTSECONDS;
do{
SdTxDummy();
tc_Ture=SDCheckDat0();//
if(gw_WaitTimeOut == 0)
{
XBYTE[REG_SDRST] = 0x03; //reset sd interface //REG_SDRST = 0xB450
gc_ReadWriteTimeOut = 1;//set time out flag
return 0xff;
}
gw_WaitTimeOut--;
} while(tc_Ture == 0);
XBYTE[REG_SRAMDMASRCIDX15_8] = 0xff;//When DMA Over,must Set this Register 0xff to release the SRAM Buffer
}
SDWaitIdle();//wait sd interface to idle
return 0;
}
U8 UsbReadWaitBank1USB(U8 tc_ReadOrWrite)
{
gw_WaitTimeOut = K_CARD_TIMEOUTSECONDS;
if(tc_ReadOrWrite)//if read
{
while(XBYTE[REG_BULK_EN1])//wait Bulk in over
{//REG_BULK_EN1 = 0xB5A2
if(gw_WaitTimeOut == 0)
{
XBYTE[REG_SDRST] = 0x03;//reset sd interface //REG_SDRST = 0xB450
gc_ReadWriteTimeOut = 1;
return 0xff;
}
gw_WaitTimeOut--;
}
}
else
{
while(XBYTE[REG_BULK_EN1])
{//REG_BULK_ACK = 0x25c2
if(gw_WaitTimeOut == 0)
{
XBYTE[REG_SDRST] = 0x03;//reset sd interface //REG_SDRST = 0xB450
gc_ReadWriteTimeOut = 1;
return 0xff;
}
gw_WaitTimeOut--;
}; //wait pc ack
XBYTE[REG_BULK_ACK] = XBYTE[REG_BULK_ACK] & 0xdf;//Clear ACK ;REG_BULK_ACK = 0x25c2
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -