阅读:3047回复:4
WINCE4.2+2440 SD卡驱动目前进度:可读,但写入有问题(附源码)前阵子忙着AP,现在回头搞SD卡驱动 (各位兄弟,先别急着笑话:现在还在搞WINCE4.2) 如标题,插入SD卡,不管如何读OK的啦 可是写入会出问题,从U盘COPY些档案到SD卡, 整着COPY过程,WINCE照跑,就看着剩余多久多久完成 但COPY完后,只有目录,完全没档案, 拜求各位兄弟帮忙看看… #include <atamain.h> #include "DataType.h" #define MAX_INITS 5 #define SDCLK_DV1 120 #define SDCLK_DV2 2 //跟硬件相关的操作放在本文件中 PRIVATE volatile IOPreg *v_pIOPregs; PRIVATE volatile MMCreg *v_pSDMMCregs; BOOL g_bSDMMCIsExist; volatile int RCA; //U32 SDMMC_total_block; #define MMC_CMD_OUTPUT() \ v_pIOPregs->rGPECON&= ~((0x3<<12)); \ v_pIOPregs->rGPECON|=((0x01<<12)) #define MMC_CMD_INPUT() \ v_pIOPregs->rGPECON&= ~((0x3<<12)) #define MMC_DAT_OUTPUT() \ v_pIOPregs->rGPECON&= ~((0x3<<14)); \ v_pIOPregs->rGPECON|=((0x01<<14)) #define MMC_DAT_INPUT() \ v_pIOPregs->rGPECON&= ~((0x3<<14)) #define MMC_CLK_LOW() \ v_pIOPregs->rGPEDAT&= ~((0x01<<5)) #define MMC_CLK_HIGH() \ v_pIOPregs->rGPEDAT|=((0x01<<5)) #define MMC_CMD_LOW() \ v_pIOPregs->rGPEDAT&= ~((0x01<<6)) #define MMC_CMD_HIGH() \ v_pIOPregs->rGPEDAT|=((0x01<<6)) #define MMC_DAT_LOW() \ v_pIOPregs->rGPEDAT&= ~((0x01<<7)) #define MMC_DAT_HIGH() \ v_pIOPregs->rGPEDAT|=((0x01<<7)) #define MMC_DAT_READ() \ ((v_pIOPregs->rGPEDAT&(0x01<<7))>>7) int Wide=0; //0:1bit,1:4bit int gMMC=0; //0:SD,1:MMC BOOL mmc_card_init(void); U8 mmc_read_sector(U8 *buf,U32 secaddrno); U8 mmc_write_sector(U8 *buf,U32 secaddrno); void Set_1bit_bus(void); void Set_4bit_bus(void); void SetBus(void); void Set_Prt(void); void Clr_Prt(void); BOOL SDMMC_InitializeAddresses(VOID) { //初始化IO 地址 BOOL RetValue=TRUE; //IO Register Allocation v_pIOPregs=NULL; v_pSDMMCregs=NULL; v_pIOPregs=(volatile IOPreg *)VirtualAlloc(0,sizeof(IOPreg),MEM_RESERVE,PAGE_NOACCESS); if(v_pIOPregs==NULL) { RETAILMSG(1,(TEXT("For IOPregs:VirtualAlloc failed!\r\n"))); RetValue=FALSE; } else { if(!VirtualCopy((PVOID)v_pIOPregs,(PVOID)(IOP_BASE),sizeof(IOPreg),PAGE_READWRITE|PAGE_NOCACHE)) { RETAILMSG(1,(TEXT("For IOPregs: VirtualCopy failed!\r\n"))); RetValue=FALSE; } } if(!RetValue) { if(v_pIOPregs) { VirtualFree((PVOID) v_pIOPregs,0,MEM_RELEASE); } v_pIOPregs=NULL; } else { v_pSDMMCregs=(volatile MMCreg *)VirtualAlloc(0,sizeof(MMCreg),MEM_RESERVE,PAGE_NOACCESS); if(v_pSDMMCregs==NULL) { RETAILMSG(1,(TEXT("For MMCreg:VirtualAlloc failed!\r\n"))); RetValue=FALSE; } else { if(!VirtualCopy((PVOID)v_pSDMMCregs,(PVOID)(MMC_BACE),sizeof(MMCreg),PAGE_READWRITE|PAGE_NOCACHE)) { RETAILMSG(1,(TEXT("For MMCreg: VirtualCopy failed!\r\n"))); RetValue=FALSE; } } if(!RetValue) { if(v_pSDMMCregs) { VirtualFree((PVOID) v_pSDMMCregs,0,MEM_RELEASE); } v_pSDMMCregs=NULL; } else RETAILMSG(1,(TEXT("SDMMC_InitializeAddresses - Success\r\n"))); } return (RetValue); } int Chk_CMDend(int cmd,int be_resp) { int status; if(!be_resp) //No response { status=v_pSDMMCregs->rSDICMDSTA; while((status&0x800)!=0x800) //Check cmd end status=v_pSDMMCregs->rSDICMDSTA; v_pSDMMCregs->rSDICMDSTA=status;//Clear cmd end state return 1; } else //With response { status=v_pSDMMCregs->rSDICMDSTA; while(!(((status&0x200)==0x200)|((status&0x400)==0x400))) //Check cmd/rsp end status=v_pSDMMCregs->rSDICMDSTA; // RETAILMSG(1,(TEXT("GO Chk_CMD %d \r\n",cmd))); if(cmd==1||cmd==41) //CRC no check { if((status&0xf00)!=0xa00) //Check error { v_pSDMMCregs->rSDICMDSTA=status; //Clear error state if(((status&0x400)==0x400)) return 0; //Timeout error } v_pSDMMCregs->rSDICMDSTA=status; //Clear cmd&rsp end state } else //CRC check { if((status&0x1f00)!=0xa00) //Check error { v_pSDMMCregs->rSDICMDSTA=status; //Clear error state RETAILMSG(1,(TEXT("++STATUS=%x \r\n",status))); if(status&0x400) return 0; //Timeout error } v_pSDMMCregs->rSDICMDSTA=status; } return 1; } } int Chk_DATend(void) { int finish; finish=v_pSDMMCregs->rSDIDATSTA; while(!((finish&0x10)|(finish&0x20))) { finish=v_pSDMMCregs->rSDIDATSTA; } if(!finish&0x10) { RETAILMSG(1,(TEXT("\nDATA:finish=0x%x.\n"),finish)); v_pSDMMCregs->rSDIDATSTA=0xf4; //Clear error state return 0; } return 1; } int Chk_BUSYend(void) { int finish; finish=v_pSDMMCregs->rSDIDATSTA; while( !( (finish&0x08) | (finish&0x20 ))) finish=v_pSDMMCregs->rSDIDATSTA; if( !finish&0x08 ) { RETAILMSG(1,(TEXT("I'm not BUSY:%d.\n"),finish)); v_pSDMMCregs->rSDIDATSTA=0xf4; return 0; } return 1; } void Card_sel_desel(char sel_desel) { //Card select or deselect if(v_pSDMMCregs==NULL) return; if(sel_desel) { RECMDS7: v_pSDMMCregs->rSDICMDARG=RCA<<16; //CMD7(RCA,stuff bit) v_pSDMMCregs->rSDICMDCON=(0x1<<9)|(0x1<<8)|0x47; //sht_resp,wait_resp,start,CMD7 Sleep(1); //Check end of CMD7 if(!Chk_CMDend(7,1)) goto RECMDS7; Sleep(1); v_pSDMMCregs->rSDICMDSTA=0xa00; // Clear cmd_end(with rsp) if(v_pSDMMCregs->rSDIRSP0&0x1e00!=0x800) goto RECMDS7; v_pSDMMCregs->rSDICMDSTA=0xa00; // Clear cmd_end(with rsp) } else { RECMDD7: v_pSDMMCregs->rSDICMDARG=0<<16; //CMD7(RCA,stuff bit) v_pSDMMCregs->rSDICMDCON=(0x1<<8)|0x47; //no_resp,start,CMD7 Sleep(1); //Check end of CMD7 if(!Chk_CMDend(7,0)) goto RECMDD7; Sleep(1); v_pSDMMCregs->rSDICMDSTA=0xa00; // Clear cmd_end(with rsp) } } void CMD0(void) { int nError; if(v_pSDMMCregs==NULL) return; //Make card idle state v_pSDMMCregs->rSDICMDARG=0x0; //CMD0(stuff bit) v_pSDMMCregs->rSDICMDCON=(1<<8)|0x40; //No_resp,start,CMD0 Sleep(1); //Check end of CMD0 nError=Chk_CMDend(0,0); v_pSDMMCregs->rSDICMDSTA=0x800; // Clear cmd_end(no rsp) RETAILMSG(1,(TEXT("\nCMD0 Chk_CMDend:%d.\n"),nError)); } void CMD2() // get sd id { } int CMD9(void)//SEND_CSD { if(v_pSDMMCregs==NULL) return 0; v_pSDMMCregs->rSDICMDARG=RCA<<16; // CMD9(RCA,stuff bit) v_pSDMMCregs->rSDICMDCON=(0x1<<10)|(0x1<<9)|(0x1<<8)|0x49; // long_resp, wait_resp, start, CMD9 //-- Check end of CMD9 if(!Chk_CMDend(9, 1)) return 0; RETAILMSG(1,(TEXT(" SDIRSP0=0x%x\n SDIRSP1=0x%x\n SDIRSP2=0x%x\n SDIRSP3=0x%x\n"), v_pSDMMCregs->rSDIRSP0,v_pSDMMCregs->rSDIRSP1,v_pSDMMCregs->rSDIRSP2,v_pSDMMCregs->rSDIRSP3)); return 1; } int CMD13(void)//SEND_STATUS { int response0; v_pSDMMCregs->rSDICMDARG=RCA<<16; // CMD13(RCA,stuff bit) v_pSDMMCregs->rSDICMDCON=(0x1<<9)|(0x1<<8)|0x4d; // sht_resp, wait_resp, start, CMD13 if(!Chk_CMDend(13, 1)) return 0; ; response0=v_pSDMMCregs->rSDIRSP0; response0 &= 0x3c00; response0 = response0 >> 9; if(response0==5||response0==6) return 0; v_pSDMMCregs->rSDICMDSTA=0xa00; // Clear cmd_end(with rsp) return 1; } int CMD16() { int response0; v_pSDMMCregs->rSDICMDARG=0x200; // block size v_pSDMMCregs->rSDICMDCON=(1<<11)|(0x1<<9)|(0x1<<8)|0x50; // sht_resp, wait_resp, start, CMD16 if(!Chk_CMDend(16, 1)) return 0; response0=v_pSDMMCregs->rSDIRSP0; response0 &= 0x3c00; response0 = response0 >> 9; if(response0==5||response0==6) return 0; v_pSDMMCregs->rSDICMDSTA=0xa00; // Clear cmd_end(with rsp) return 1; } int CMD55(void) { if(v_pSDMMCregs==NULL) return 0; //Make ACMD v_pSDMMCregs->rSDICMDARG=RCA<<16; //CMD7(RCA,stuff bit) v_pSDMMCregs->rSDICMDCON=(0x1<<9)|(0x1<<8)|0x77; //sht_resp,wait_resp,start,CMD55 //Check end of CMD55 if(!Chk_CMDend(55,1)) { return 0; } v_pSDMMCregs->rSDICMDSTA=0xa00; // Clear cmd_end(with rsp) return 1; } void Set_Prt(void) { if(v_pSDMMCregs==NULL) return; //-- Set protection addr.0 ~ 262144(32*16*512) // Uart_Printf("[Set protection(addr.0 ~ 262144) test]\n"); RECMD28: //--Make ACMD v_pSDMMCregs->rSDICMDARG=0; // CMD28(addr) v_pSDMMCregs->rSDICMDCON=(0x1<<9)|(0x1<<8)|0x5c; //sht_resp, wait_resp, start, CMD28 //-- Check end of CMD28 if(!Chk_CMDend(28, 1)) goto RECMD28; v_pSDMMCregs->rSDICMDSTA=0xa00; // Clear cmd_end(with rsp) } void Clr_Prt(void) { if(v_pSDMMCregs==NULL) return; //-- Clear protection addr.0 ~ 262144(32*16*512) //Uart_Printf("[Clear protection(addr.0 ~ 262144) test]\n"); RECMD29: //--Make ACMD v_pSDMMCregs->rSDICMDARG=0; // CMD29(addr) v_pSDMMCregs->rSDICMDCON=(0x1<<9)|(0x1<<8)|0x5d; //sht_resp, wait_resp, start, CMD29 //-- Check end of CMD29 if(!Chk_CMDend(29, 1)) goto RECMD29; v_pSDMMCregs->rSDICMDSTA=0xa00; // Clear cmd_end(with rsp) } void Enable_SDIclk() { if(v_pSDMMCregs==NULL) return; v_pSDMMCregs->rSDICON |=1; } void Disable_SDIclk() { if(v_pSDMMCregs==NULL) return; v_pSDMMCregs->rSDICON &= (~0x01); } int Chk_SD_OCR(void) { int i; for(i=0;i<10;i++) { CMD55(); //Make ACMD v_pSDMMCregs->rSDICMDARG=0xff8000; //ACMD41(OCR:2.7V~3.6V) v_pSDMMCregs->rSDICMDCON=(0x1<<9)|(0x1<<8)|0x69;//sht_resp, wait_resp, start, ACMD41 if(Chk_CMDend(41,1)& (v_pSDMMCregs->rSDIRSP0==0x80ff8000)) //OCR最高位为0表示正在POWER UP { return 1; //Success } // for(j=0;j<500;j++); //Wait Card power up status Sleep(300); } v_pSDMMCregs->rSDICMDSTA=0xa00; // Clear cmd_end(with rsp) return 0; //Fail } int Chk_MMC_OCR(void) { int i; if(v_pSDMMCregs==NULL) return 0; //Negotiate operating condition for MMC,it makes card ready state for(i=0;i<15;i++) { v_pSDMMCregs->rSDICMDARG=0xff8000; //CMD1(OCR:2.7V~3.6V) v_pSDMMCregs->rSDICMDCON=(0x1<<9)|(0x1<<8)|0x41; //sht_resp,wait_resp,start,CMD1 //Check end of CMD1 RETAILMSG(1,(TEXT("Chk_MMC_OCR\r\n"))); if(Chk_CMDend(1,1)&&(v_pSDMMCregs->rSDIRSP0==0x80ff8000))// if(Chk_CMDend(1,1)&&(v_pSDMMCregs->rSDIRSP0)>>16==0x80ff) { v_pSDMMCregs->rSDICMDSTA=0xa00; // Clear cmd_end(with rsp) return 1; //Success } } v_pSDMMCregs->rSDICMDSTA=0xa00; // Clear cmd_end(with rsp) return 0; //Failed } U8 InitSDMMC(void) { //成功返回1 g_bSDMMCIsExist=FALSE; if(v_pIOPregs==NULL) return 0; if(v_pSDMMCregs==NULL) return 0; v_pIOPregs->rGPEUP &= ~(0x3f<<5); //The pull up v_pIOPregs->rGPECON &= ~(0xfff<<10); v_pIOPregs->rGPECON |= (0xaaa<<10); v_pSDMMCregs->rSDIDATSTA = 0xffff; v_pSDMMCregs->rSDIDATCON = 0; v_pSDMMCregs->rSDICMDSTA = 0x1e00;//0xffff; v_pSDMMCregs->rSDICMDCON = 0; v_pSDMMCregs->rSDIPRE=SDCLK_DV1;//400KHz v_pSDMMCregs->rSDICON=(1<<1)|1; //Type A,clk enable v_pSDMMCregs->rSDIFSTA |= (1<<16); //FIFO reset, v_pSDMMCregs->rSDIBSIZE=0x200; //512byte(128word) v_pSDMMCregs->rSDIDTIMER=0x7fffff; //Set timeout count Sleep(2); CMD0(); RETAILMSG(1,(TEXT("\nIn idle.\n"))); //Check MMC card OCR if(Chk_MMC_OCR()) { RETAILMSG(1,(TEXT("\nIn MMC ready.\n"))); gMMC=1; goto RECMD2; } if(Chk_SD_OCR()) RETAILMSG(1,(TEXT("\nIn SD ready.\n"))); else { RETAILMSG(1,(TEXT("\nInitialize fail\nNo Card assertion.\n"))); return 0; } RECMD2: //Check attaced cards,it makes card identification state v_pSDMMCregs->rSDICMDARG=0x0; //CMD2(stuff bit) v_pSDMMCregs->rSDICMDCON=(0x1<<10)|(0x1<<9)|(0x1<<8)|0x42; //lng_resp,wait_resp,start,CMD2 //Check end of CMD2 if(!Chk_CMDend(2,1)) { goto RECMD2; } v_pSDMMCregs->rSDICMDSTA=0xa00; // Clear cmd_end(with rsp) RETAILMSG(1,(TEXT("\nEnd id.\n"))); RECMD3: //Send RCA v_pSDMMCregs->rSDICMDARG=gMMC<<16; //CMD3(MMC:Set RCA,SD:Ask RCA-->SBZ) v_pSDMMCregs->rSDICMDCON=(0x1<<9)|(0x1<<8)|0x43; //sht_resp,wait_resp,start,CMD3 //Check end of CMD3 if(!Chk_CMDend(3,1)) goto RECMD3; v_pSDMMCregs->rSDICMDSTA=0xa00; // Clear cmd_end(with rsp) //Publish RCA if(gMMC) RCA=1; else RCA=(v_pSDMMCregs->rSDIRSP0&0xffff0000)>>16; RETAILMSG(1,(TEXT("\nRCA=0x%x\n"),RCA)); //State(stand-by) check if(v_pSDMMCregs->rSDIRSP0&0x1e00!=0x600) //CURRENT_STATE check goto RECMD3; v_pSDMMCregs->rSDICMDSTA=0xa00; // Clear cmd_end(with rsp) RETAILMSG(1,(TEXT("\nIn stand-by\n"))); v_pSDMMCregs->rSDIPRE=SDCLK_DV2;//PCLK/(2*NORCLK)-1; //Normal clock=25MHz Card_sel_desel(1); //Select if(!gMMC) Set_4bit_bus(); else Set_1bit_bus(); if(mmc_card_init()) { g_bSDMMCIsExist=TRUE; RETAILMSG(1,(TEXT("mmc_card_init OK.\n"))); return 1; } else { g_bSDMMCIsExist=FALSE; RETAILMSG(1,(TEXT("mmc_card_init ERROR.\n"))); return 0; } } unsigned char Del_SDMMC() { if(v_pSDMMCregs==NULL) return 0; Disable_SDIclk(); return 1; } void mmc_spi_cs_low() { //mmc_cs=0 v_pIOPregs->rGPEDAT&= ~((0x01<<10)); } void mmc_spi_cs_high() { //mmc_cs=1 v_pIOPregs->rGPEDAT|=((0x01<<10)); } U8 mmc_spi_io(U8 data_out) { //从MSB开始,把data_out从CMD线发送,并返回DAT线的内容 U8 i,input=0; //从CMD线发送数据 MMC_CMD_OUTPUT(); //从DAT线读数据 MMC_DAT_INPUT(); //从MSB开始发送 for(i=8;i>0;i--) { //lower CLOCK MMC_CLK_LOW(); //put DATA on CMD line if((data_out>>(i-1))&0x01) MMC_CMD_HIGH(); else MMC_CMD_LOW(); //raise CLOCK MMC_CLK_HIGH(); //从DAT线读数据 input<<=1; input|=MMC_DAT_READ(); } //最后把CMD设高 MMC_CMD_HIGH(); return input; } UINT16 calculateCRC7(UCHAR *dBuff,UINT16 offset,UINT16 dLength) { UINT16 ibyte,ibit; UINT16 rreg,crc_byte,dtmp; crc_byte=0x09; rreg=0; for(ibyte=offset;ibyte<dLength;ibyte++) { dtmp=(UINT16)(dBuff[ibyte]); for(ibit=0;ibit<8;ibit++) { rreg<<=1; dtmp&=0xFF; rreg^=(((dtmp^rreg)&0x80)?crc_byte:0); dtmp<<=1; } } return (rreg&0xFF); } void mmc_send_command(U8 cmdindex,U32 para) { t_MMC_COMMAND Command; U8 i=0; memset((U8*)&Command,0,6); Command.b1TransmissionBit=1; Command.b6CommandIndex=cmdindex; Command.Argument.dwArgument[0]=(U8)((para&0xff000000)>>24); Command.Argument.dwArgument[1]=(U8)((para&0x00ff0000)>>16); Command.Argument.dwArgument[2]=(U8)((para&0x0000ff00)>>8); Command.Argument.dwArgument[3]=(U8)(para&0x000000ff); Command.b7CRC7=calculateCRC7((U8*)&Command,0,5); Command.b1EndBit=1; for(i=0;i<6;i++) mmc_spi_io(((U8*)&Command)); } BOOL mmc_card_init(void) { return 1; } void mmc_parse_csd(U8 *buf,t_MMC_CSD* pCSD) { RETAILMSG(1,(TEXT("csd :%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x .\r\n"), buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7], buf[8],buf[9],buf[10],buf[11],buf[12],buf[13],buf[14],buf[15])); pCSD->b2CSDStructure=(buf[0]&0xc0)>>6; pCSD->b4SpecVers=(buf[0]&0x3c)>>2; pCSD->b2Reserved1=buf[0]&0x03; pCSD->byTAAC=buf[1]; pCSD->byNSAC=buf[2]; pCSD->byTranSpeed=buf[3]; pCSD->b12CCC=buf[4]; pCSD->b12CCC<<=4; pCSD->b12CCC|=((buf[5]&0xf0)>>4); pCSD->b4ReadBLLen=(buf[5]&0x0f); pCSD->b1ReadBLPartial=((buf[6]&0x80)>>7); pCSD->b1WriteBlkMisalign=((buf[6]&0x40)>>6); pCSD->b1ReadBlkMisalign=((buf[6]&0x20)>>5); pCSD->b1DSRImp=((buf[6]&0x10)>>4); pCSD->b2Reserved2=((buf[6]&0x0c)>>2); pCSD->b12CSize=(buf[6]&0x03); pCSD->b12CSize<<=8; pCSD->b12CSize|=buf[7]; pCSD->b12CSize<<=2; pCSD->b12CSize|=((buf[8]&0xc0)>>6); pCSD->b3VDDRCurrMin=((buf[8]&0x38)>>3); pCSD->b3VDDRCurrMax=(buf[8]&0x07); pCSD->b3VDDWCurrMin=((buf[9]&0xe0)>>5); pCSD->b3VDDWCurrMax=((buf[9]&0x1c)>>2); pCSD->b3CSizeMult=(buf[9]&0x03); pCSD->b3CSizeMult<<=2; pCSD->b3CSizeMult|=((buf[10]&0x80)>>7); pCSD->b5EraseGrpSize=((buf[10]&0x7c)>>2); pCSD->b5EraseGrpMult=(buf[10]&0x03); pCSD->b5EraseGrpMult<<=3; pCSD->b5EraseGrpMult|=((buf[11]&0xe0)>>5); pCSD->b5WPGrpSize=(buf[11]&0x1f); pCSD->b1WPGrpEnable=((buf[12]&0x80)>>7); pCSD->b2DefaultECC=((buf[12]&0x60)>>5); pCSD->b3R2WFactor=((buf[12]&0x1c)>>2); pCSD->b4WriteBLLen=(buf[12]&0x03); pCSD->b4WriteBLLen<<=2; pCSD->b4WriteBLLen|=((buf[13]&0xc0)>>6); pCSD->b1WriteBLPartial=((buf[13]&0x20)>>5); pCSD->b4Reserved3=((buf[13]&0x1e)>>1); pCSD->b1ContentProtAPP=(buf[13]&0x01); pCSD->b1FileFormatGrp=((buf[14]&0x80)>>7); pCSD->b1Copy=((buf[14]&0x40)>>6); pCSD->b1PermWriteProtect=((buf[14]&0x20)>>5); pCSD->b1TmpWriteProtect=((buf[14]&0x10)>>4); pCSD->b2FileFormat=((buf[14]&0x0c)>>2); pCSD->b2ECC=(buf[14]&0x03); pCSD->b7CRC=((buf[15]&0xfe)>>1); pCSD->b1NouUsed=buf[15]&0x01; } BOOL mmc_send_csd(DISK_INFO *pDiskInfo) { //获取分区表信息 U8 buf[16]; U32 m_Size,rate; t_MMC_CSD m_CSD; memset((U8*)&m_CSD,0,sizeof(t_MMC_CSD)); Card_sel_desel(0); // Card deselect if(!CMD9()) RETAILMSG(1,(TEXT("\nmmc_send_csd::cmd9 error\n"))); buf[0] = ((v_pSDMMCregs->rSDIRSP0)>>24)&0xff; buf[1] = ((v_pSDMMCregs->rSDIRSP0)>>16)&0xff; buf[2] = ((v_pSDMMCregs->rSDIRSP0)>>8)&0xff; buf[3] = (v_pSDMMCregs->rSDIRSP0)&0xff; buf[4] = ((v_pSDMMCregs->rSDIRSP1)>>24)&0xff; buf[5] = ((v_pSDMMCregs->rSDIRSP1)>>16)&0xff; buf[6] = ((v_pSDMMCregs->rSDIRSP1)>>8)&0xff; buf[7] = (v_pSDMMCregs->rSDIRSP1)&0xff; buf[8] = ((v_pSDMMCregs->rSDIRSP2)>>24)&0xff; buf[9] = ((v_pSDMMCregs->rSDIRSP2)>>16)&0xff; buf[10] = ((v_pSDMMCregs->rSDIRSP2)>>8)&0xff; buf[11] = (v_pSDMMCregs->rSDIRSP2)&0xff; buf[12] = ((v_pSDMMCregs->rSDIRSP3)>>24)&0xff; buf[13] = ((v_pSDMMCregs->rSDIRSP3)>>16)&0xff; buf[14] = ((v_pSDMMCregs->rSDIRSP3)>>8)&0xff; buf[15] = (v_pSDMMCregs->rSDIRSP3)&0xff; Card_sel_desel(1); // Card deselect //分析CSD mmc_parse_csd((U8 *)buf,&m_CSD); RETAILMSG(1,(TEXT("---------------------------------\r\n"))); RETAILMSG(1,(TEXT("b2CSDStructure=%d.\r\n"),m_CSD.b2CSDStructure)); RETAILMSG(1,(TEXT("b4SpecVers=%d.\r\n"),m_CSD.b4SpecVers)); RETAILMSG(1,(TEXT("b2Reserved1=%d.\r\n"),m_CSD.b2Reserved1)); RETAILMSG(1,(TEXT("byTAAC=%d.\r\n"),m_CSD.byTAAC)); RETAILMSG(1,(TEXT("byNSAC=%d.\r\n"),m_CSD.byNSAC)); RETAILMSG(1,(TEXT("byTranSpeed=%d.\r\n"),m_CSD.byTranSpeed)); RETAILMSG(1,(TEXT("b12CCC=%d.\r\n"),m_CSD.b12CCC)); RETAILMSG(1,(TEXT("b4ReadBLLen=%d.\r\n"),m_CSD.b4ReadBLLen)); RETAILMSG(1,(TEXT("b1ReadBLPartial=%d.\r\n"),m_CSD.b1ReadBLPartial)); RETAILMSG(1,(TEXT("b1WriteBlkMisalign=%d.\r\n"),m_CSD.b1WriteBlkMisalign)); RETAILMSG(1,(TEXT("b1ReadBlkMisalign=%d.\r\n"),m_CSD.b1ReadBlkMisalign)); RETAILMSG(1,(TEXT("b1DSRImp=%d.\r\n"),m_CSD.b1DSRImp)); RETAILMSG(1,(TEXT("b12CSize=%d.\r\n"),m_CSD.b12CSize)); RETAILMSG(1,(TEXT("b3VDDRCurrMin=%d.\r\n"),m_CSD.b3VDDRCurrMin)); RETAILMSG(1,(TEXT("b3VDDRCurrMax=%d.\r\n"),m_CSD.b3VDDRCurrMax)); RETAILMSG(1,(TEXT("b3VDDWCurrMin=%d.\r\n"),m_CSD.b3VDDWCurrMin)); RETAILMSG(1,(TEXT("b3VDDWCurrMax=%d.\r\n"),m_CSD.b3VDDWCurrMax)); RETAILMSG(1,(TEXT("b3CSizeMult=%d.\r\n"),m_CSD.b3CSizeMult)); RETAILMSG(1,(TEXT("b5EraseGrpSize=%d.\r\n"),m_CSD.b5EraseGrpSize)); RETAILMSG(1,(TEXT("b5EraseGrpMult=%d.\r\n"),m_CSD.b5EraseGrpMult)); RETAILMSG(1,(TEXT("b5WPGrpSize=%d.\r\n"),m_CSD.b5WPGrpSize)); RETAILMSG(1,(TEXT("b1WPGrpEnable=%d.\r\n"),m_CSD.b1WPGrpEnable)); RETAILMSG(1,(TEXT("b2DefaultECC=%d.\r\n"),m_CSD.b2DefaultECC)); RETAILMSG(1,(TEXT("b3R2WFactor=%d.\r\n"),m_CSD.b3R2WFactor)); RETAILMSG(1,(TEXT("b4WriteBLLen=%d.\r\n"),m_CSD.b4WriteBLLen)); RETAILMSG(1,(TEXT("b1WriteBLPartial=%d.\r\n"),m_CSD.b1WriteBLPartial)); RETAILMSG(1,(TEXT("b4Reserved3=%d.\r\n"),m_CSD.b4Reserved3)); RETAILMSG(1,(TEXT("b1ContentProtAPP=%d.\r\n"),m_CSD.b1ContentProtAPP)); RETAILMSG(1,(TEXT("b1FileFormatGrp=%d.\r\n"),m_CSD.b1FileFormatGrp)); RETAILMSG(1,(TEXT("b1Copy=%d.\n"),m_CSD.b1Copy)); RETAILMSG(1,(TEXT("b1PermWriteProtect=%d.\r\n"),m_CSD.b1PermWriteProtect)); RETAILMSG(1,(TEXT("b1TmpWriteProtect=%d.\r\n"),m_CSD.b1TmpWriteProtect)); RETAILMSG(1,(TEXT("b2FileFormat=%d.\r\n"),m_CSD.b2FileFormat)); RETAILMSG(1,(TEXT("b2ECC=%d.\r\n"),m_CSD.b2ECC)); RETAILMSG(1,(TEXT("b7CRC=%d.\r\n"),m_CSD.b7CRC)); RETAILMSG(1,(TEXT("b1NouUsed=%d.\r\n"),m_CSD.b1NouUsed)); RETAILMSG(1,(TEXT("---------------------------------\r\n"))); pDiskInfo->di_bytes_per_sect=MMC_SECTOR_SIZE; //Start with 512,then go with SetInfo changes pDiskInfo->di_cylinders=1; pDiskInfo->di_heads=1; pDiskInfo->di_sectors=32; m_Size=(m_CSD.b12CSize+1)*(pow(2,m_CSD.b3CSizeMult+2))*(pow(2,m_CSD.b4ReadBLLen))/512; pDiskInfo->di_total_sectors=m_Size; pDiskInfo->di_flags=DISK_INFO_FLAG_MBR; return TRUE; } void SDMMC_Identify(DISK_INFO *pDiskInfo) { //获取MMC卡的信息 RETAILMSG(1,(TEXT("SDMMC_Identify\r\n"))); if(g_bSDMMCIsExist==FALSE) return; RETAILMSG(1,(TEXT("SDMMC_Identify in...\r\n"))); if(mmc_send_csd(pDiskInfo)) { RETAILMSG(1,(TEXT("di_bytes_per_sect=%d.\r\n"),pDiskInfo->di_bytes_per_sect)); RETAILMSG(1,(TEXT("di_cylinders=%d.\r\n"),pDiskInfo->di_cylinders)); RETAILMSG(1,(TEXT("di_heads=%d.\r\n"),pDiskInfo->di_heads)); RETAILMSG(1,(TEXT("di_sectors=%d.\r\n"),pDiskInfo->di_sectors)); RETAILMSG(1,(TEXT("di_total_sectors=%d.\r\n"),pDiskInfo->di_total_sectors)); RETAILMSG(1,(TEXT("mmc_send_csd OK.\r\n"))); } else { RETAILMSG(1,(TEXT("mmc_send_csd ERROR.\r\n"))); } } U8 mmc_read_sector(U8 *buf,U32 secaddrno) { U32 addr; U32 rd_data; int status; int rd_cnt=0; unsigned int cnt = 0; if(v_pSDMMCregs==NULL) return 0; if(secaddrno>MMC_MAX_SECTOR*4) return 0; addr = secaddrno*MMC_SECTOR_SIZE; v_pSDMMCregs->rSDIFSTA |= (1<<16); //FIFO reset v_pSDMMCregs->rSDIFSTA &= 0xc000; // clear error status v_pSDMMCregs->rSDICMDSTA = 0x1E00; // clear any pending status flags v_pSDMMCregs->rSDIDATCON=(2<<22)|(1<<19)|(1<<17)|(Wide<<16)|(1<<14)|(2<<12)|(1<<0); //YH 040220 v_pSDMMCregs->rSDICMDARG=addr; //CMD17/18(addr) RERDCMD: v_pSDMMCregs->rSDICMDCON=(0x1<<11)|(0x1<<9)|(0x1<<8)|0x51; //sht_resp,wait_resp,dat,start,CMD17 cnt ++; if(cnt > 4000) { RETAILMSG(1,(TEXT("\ncmd read sector 17 1 while sector = %d , CMDSTATE = 0x%x\n"),secaddrno,v_pSDMMCregs->rSDICMDSTA)); return 0; } Sleep(1); if(!Chk_CMDend(17,1)) //Check end of CMD17 goto RERDCMD; v_pSDMMCregs->rSDICMDSTA=0xa00; // Clear cmd_end(with rsp) v_pSDMMCregs->rSDIDATSTA=0x20; //Clear timeout flag while(rd_cnt<128) //512 bytes { status=v_pSDMMCregs->rSDIDATSTA; if(status&0x20) //Check timeout { RETAILMSG(1,(TEXT("\nRd_Block timeout:%d!\n"),secaddrno)); v_pSDMMCregs->rSDIDATSTA=0x20; //Clear timeout flag return 0; } status=v_pSDMMCregs->rSDIFSTA; if((status&0x1000)==0x1000) //Is Rx data? { rd_data=v_pSDMMCregs->rSDIDAT; buf[rd_cnt*4] =(rd_data>>0 &0xff); buf[rd_cnt*4+1]=(rd_data>>8 &0xff); buf[rd_cnt*4+2]=(rd_data>>16&0xff); buf[rd_cnt*4+3]=(rd_data>>24&0xff); rd_cnt++; } } //Check end of DATA if(!Chk_DATend()) { RETAILMSG(1,(TEXT("\nread check dat end error sector = %d\n"),secaddrno)); return 0; } v_pSDMMCregs->rSDIDATCON = (v_pSDMMCregs->rSDIDATCON)&~(7<<12); //YH 040220, Clear Data Transfer mode => no operation, Cleata Data Transfer start v_pSDMMCregs->rSDIFSTA &= 0x200; //Clear Rx FIFO Last data Ready, YH 040221 v_pSDMMCregs->rSDIDATSTA = 0x10; //Clear data Tx/Rx end v_pSDMMCregs->rSDIPRE=SDCLK_DV2; return 1; } U8 mmc_write_sector(U8 *buf,U32 secaddrno) { int status; int wt_cnt=0; U32 addr; U32 *wdata=(U32 *)buf; unsigned int cnt = 0; if(v_pSDMMCregs==NULL) return 0; if(secaddrno>MMC_MAX_SECTOR) return 0; addr=secaddrno*MMC_SECTOR_SIZE; v_pSDMMCregs->rSDIFSTA |= (1<<16); //FIFO reset v_pSDMMCregs->rSDICMDSTA = 0x1E00; // clear any pending status flags v_pSDMMCregs->rSDIDATCON=(2<<22)|(1<<20)|(1<<17)|(Wide<<16)|(1<<14)|(3<<12)|(1<<0); //YH 040220 v_pSDMMCregs->rSDICMDARG=addr; //CMD24/25(addr) REWTCMD: v_pSDMMCregs->rSDICMDCON=(0x1<<11)|(0x1<<9)|(0x1<<8)|0x58; //sht_resp,wait_resp,dat,start,CMD24 cnt ++; if(cnt > 1000) { RETAILMSG(1,(TEXT("\ncmd write sector 24 1 while sector = %d , CMDSTATE = 0x%x\n"),secaddrno,v_pSDMMCregs->rSDICMDSTA)); return 0; } if(!Chk_CMDend(24,1)) //Check end of CMD24 goto REWTCMD; v_pSDMMCregs->rSDICMDSTA=0xa00; // Clear cmd_end(with rsp) while(wt_cnt<128) { status=v_pSDMMCregs->rSDIFSTA; if((status&0x2000)==0x2000) { v_pSDMMCregs->rSDIDAT= *wdata++; wt_cnt++; } } //Check end of DATA Sleep(10); if(!Chk_DATend()) { } v_pSDMMCregs->rSDIDATCON = v_pSDMMCregs->rSDIDATCON&~(7<<12); //YH 040220, Clear Data Transfer mode => no operation, Cleata Data Transfer start v_pSDMMCregs->rSDIDATSTA=0x10; //Clear data Tx/Rx end v_pSDMMCregs->rSDIPRE=SDCLK_DV2; return 1; } unsigned char sector_busy = 0; void ReadSector(PBYTE pBuffer,DWORD dwStartSector) { while(sector_busy); sector_busy = 1; mmc_read_sector(pBuffer,dwStartSector); sector_busy = 0; } void WriteSector(PBYTE pBuffer,DWORD dwStartSector) { while(sector_busy); sector_busy = 1; mmc_write_sector(pBuffer,dwStartSector); sector_busy = 0; } void Set_1bit_bus(void) { Wide=0; if(!gMMC) SetBus(); } void Set_4bit_bus(void) { Wide=1; SetBus(); } void SetBus(void) { SET_BUS: CMD55(); //Make ACMD //CMD6 implement v_pSDMMCregs->rSDICMDARG=Wide<<1; //Wide 0: 1bit,1: 4bit v_pSDMMCregs->rSDICMDCON=(0x1<<9)|(0x1<<8)|0x46; //sht_resp,wait_resp,start,CMD55 if(!Chk_CMDend(6,1)) //ACMD6 goto SET_BUS; v_pSDMMCregs->rSDICMDSTA=0xa00; // Clear cmd_end(with rsp) } |
|
沙发#
发布于:2008-08-01 11:47
使用MMC卡,COPY一整个目录(約30MB),可以复制过去到MMC卡.
但部分MMC卡上的档案结构会被破坏,导致在PC上无法读取 |
|
板凳#
发布于:2008-08-01 15:29
U8 mmc_write_sector(U8 *buf,U32 secaddrno)
{ int status; int wt_cnt=0; U32 addr; U32 *wdata=(U32 *)buf; unsigned int cnt = 0; if(v_pSDMMCregs==NULL) return 0; addr=secaddrno*MMC_SECTOR_SIZE; v_pSDMMCregs->rSDIFSTA |= (1<<16); //FIFO reset v_pSDMMCregs->rSDIFSTA &= 0xc000; // clear error status v_pSDMMCregs->rSDICMDSTA = 0x1E00; // clear any pending status flags v_pSDMMCregs->rSDIDATCON=(2<<22)|(1<<20)|(1<<17)|(Wide<<16)|(1<<14)|(3<<12)|(1<<0); //YH 040220 v_pSDMMCregs->rSDICMDARG=addr; //CMD24/25(addr) REWTCMD: v_pSDMMCregs->rSDICMDCON=(0x1<<11)|(0x1<<9)|(0x1<<8)|0x58; //sht_resp,wait_resp,dat,start,CMD24 cnt ++; if(cnt > 1000) { RETAILMSG(1,(TEXT("\ncmd write sector 24 1 while sector = %d , CMDSTATE = 0x%x\n"),secaddrno,v_pSDMMCregs->rSDICMDSTA)); return 0; } if(!Chk_CMDend(24,1)) //Check end of CMD24 goto REWTCMD; v_pSDMMCregs->rSDICMDSTA=0xa00; // Clear cmd_end(with rsp) v_pSDMMCregs->rSDIDATSTA=0x20; //Clear timeout flag while(wt_cnt<128) { status=v_pSDMMCregs->rSDIFSTA; if((status&0x2000)==0x2000) { v_pSDMMCregs->rSDIDAT= *wdata++; wt_cnt++; } } //Check end of DATA if(!Chk_DATend()) { RETAILMSG(1,(TEXT("\nread check dat end error sector = %d\n"),secaddrno)); return 0; } v_pSDMMCregs->rSDIDATCON = (v_pSDMMCregs->rSDIDATCON)&~(7<<12); //YH 040220, Clear Data Transfer mode => no operation, Cleata Data Transfer start v_pSDMMCregs->rSDIFSTA &= 0x200; //Clear Rx FIFO Last data Ready, YH 040221 v_pSDMMCregs->rSDIDATSTA = 0x10; //Clear data Tx/Rx end v_pSDMMCregs->rSDIPRE=SDCLK_DV2; return 1; } unsigned char sector_busy = 0; void ReadSector(PBYTE pBuffer,DWORD dwStartSector) { while(sector_busy); sector_busy = 1; mmc_read_sector(pBuffer,dwStartSector); sector_busy = 0; } void WriteSector(PBYTE pBuffer,DWORD dwStartSector) { while(sector_busy); sector_busy = 1; mmc_write_sector(pBuffer,dwStartSector); sector_busy = 0; } 改這樣後,可以寫入檔案了,不過.... 似乎某些檔案寫入後,該檔結構不完整有問題,而無法讀取或寫入~~~ |
|
地板#
发布于:2008-10-10 12:02
楼主,不错。我直接用微软自带的了
|
|
|
地下室#
发布于:2008-10-12 11:25
太长了,做个记号以后看。
|
|
|