📄 sd.c
字号:
void Card_sel_desel(char sel_desel){ S3C2410_SDI * const sdi = S3C2410_GetBase_SDI(); //-- Card select or deselect if(sel_desel) {RECMDS7: sdi->SDICARG=RCA<<16; // CMD7(RCA,stuff bit) sdi->SDICCON= (0x1<<9)|(0x1<<8)|0x47; // sht_resp, wait_resp, start, CMD7 //-- Check end of CMD7 if(!Chk_CMDend(7, 1)) goto RECMDS7; sdi->SDICSTA=0xa00; // Clear cmd_end(with rsp) //--State(transfer) check if( sdi->SDIRSP0 & (0x1e00!=0x800) ) goto RECMDS7; } else {RECMDD7: sdi->SDICARG=0<<16; //CMD7(RCA,stuff bit) sdi->SDICCON=(0x1<<8)|0x47; //no_resp, start, CMD7 //-- Check end of CMD7 if(!Chk_CMDend(7, 0)) goto RECMDD7; sdi->SDICSTA=0x800; // Clear cmd_end(no rsp) }}void SD_Read(unsigned char * pucdata, unsigned long ulLBA, unsigned long ulSectors);void SD_Write(unsigned char * pucdata, unsigned long ulLBA, unsigned long ulSectors);unsigned int SD_card_init(void);ulong mmc_bread(int dev_num, ulong blknr, ulong blkcnt, ulong *dst){// int mmc_block_size = MMC_BLOCK_SIZE;// ulong src = blknr * mmc_block_size + CFG_MMC_BASE; if(blkcnt==0) { printf("Why block_cnt == 0?? \n"); return 0; }// mmc_read(src, (uchar *)dst, blkcnt*mmc_block_size);// printf("mmc_bread LBA=%d, Count=%d\n",blknr,blkcnt); SD_Read((uchar *)dst, blknr, blkcnt);// printf("mmc_bread end\n"); return blkcnt;}int mmc_write(uchar *src, ulong dst, int size){ printf("\nmmc_write should not be called !!!!\n"); //SD_Write(}int mmc_read(ulong src, uchar *dst, int size){ printf("\nmmc_read should not be called !!!!\n"); //SD_Write(}#define INICLK 400000#define SDCLK 25000000 #define MMCCLK 15000000 int mmc_init_once = 0;int mmc_init(int verbose){ SD_card_init(); return 0;}#define CFG_MMC_BASE 0int mmc2info(ulong addr){ /* FIXME hard codes to 32 MB device */ if (addr >= CFG_MMC_BASE && addr < CFG_MMC_BASE + (CardSize/512)) { return 1; } return 0;}unsigned int SD_card_init(void){ int i; unsigned long pclk; S3C2410_SDI * const sdi = S3C2410_GetBase_SDI(); if(mmc_init_once==1) return 1;// already done !! pclk = get_PCLK(); //printf("\nSystem Frequency is %dHz\n",pclk); sdi->SDIPRE = pclk/(INICLK)-1; // 400KHz //printf("\nInit. Frequency is %dHz\n",(pclk/(sdi->SDIPRE+1))); sdi->SDICON=(0<<4)|1; // Type A, clk enable (For Little Endian by Salamander) sdi->SDIFSTA = sdi->SDIFSTA|(1<<16); // FIFO reset sdi->SDIBSIZE = 0x200; // 512byte(128word) sdi->SDIDTIMER = 0x7fffff; // Set timeout count for(i=0;i<0x1000;i++); // Wait 74SDCLK for MMC card CMD0(); // Goto idel state //-- Check MMC card OCR if(Chk_MMC_OCR()) { printf("\nMMC found.\n"); isMMC=1; goto RECMD2; } //printf("MMC check end!!\n"); //-- Check SD card OCR if(Chk_SD_OCR()) printf("\nSD found : "); else { printf("\nSD Initialize fail..\n\n"); return 0; }RECMD2: //-- Check attaced cards, it makes card identification state sdi->SDICARG=0x0; // CMD2(stuff bit) sdi->SDICCON=(0x1<<10)|(0x1<<9)|(0x1<<8)|0x42; //lng_resp, wait_resp, start, CMD2 //-- Check end of CMD2 if(!Chk_CMDend(2, 1)) goto RECMD2; sdi->SDICSTA=0xa00; // Clear cmd_end(with rsp) //printf("\nEnd id\n");RECMD3: //--Send RCA sdi->SDICARG = isMMC<<16; // CMD3(MMC:Set RCA, SD:Ask RCA-->SBZ) sdi->SDICCON = (0x1<<9)|(0x1<<8)|0x43; // sht_resp, wait_resp, start, CMD3 //-- Check end of CMD3 if(!Chk_CMDend(3, 1)) goto RECMD3; sdi->SDICSTA = 0xa00; // Clear cmd_end(with rsp) //--Publish RCA if(isMMC) { RCA=1; sdi->SDIPRE=(pclk/MMCCLK)-1; printf("MMC Frequency is %dMHz\n",(pclk/(sdi->SDIPRE+1))/1000000); } else { RCA=( sdi->SDIRSP0 & 0xffff0000 )>>16; //printf("RCA=0x%x\n",RCA); sdi->SDIPRE=pclk/(SDCLK); // Salamander pclk=66Mhz, prescaler = 2, SD_CLK = 22Mhz //sdi->SDIPRE=3; // test 16Mhz //printf("SD Frequency is %dMHz\n",(pclk/(sdi->SDIPRE+1))/1000000); } //--State(stand-by) check if( sdi->SDIRSP0 & (0x1e00!=0x600) ) // CURRENT_STATE check goto RECMD3; //printf("\nIn stand-by\n"); Card_sel_desel(1); // Select if(!isMMC) { CardBusWidth=1; SetBus(); // For SD } else { CardBusWidth=0; SetBus(); // For MMC } Card_sel_desel(0); // DeSelect for IDLE if(!CMD9()) printf("Get CSD fail!!!\n"); Card_sel_desel(1); // Select { /* fill in device description */ mmc_dev.if_type = IF_TYPE_MMC; mmc_dev.dev = 0; mmc_dev.lun = 0; mmc_dev.type = 0; /* FIXME fill in the correct size (is set to 32MByte) */ mmc_dev.blksz = 512; //mmc_dev.lba = 0x10000; mmc_dev.lba = CardSize / 512; mmc_dev.part_type = PART_TYPE_DOS; /* sprintf(mmc_dev.vendor,"Man %02x%02x%02x Snr %02x%02x%02x", cid->id[0], cid->id[1], cid->id[2], cid->sn[0], cid->sn[1], cid->sn[2]); sprintf(mmc_dev.product,"%s",cid->name); sprintf(mmc_dev.revision,"%x %x",cid->hwrev, cid->fwrev); */ sprintf(mmc_dev.vendor,"Man aESOP1 Snr 123456"); sprintf(mmc_dev.product,"%s","SDxxxMB"); sprintf(mmc_dev.revision,"%x %x",0x123,0x456); mmc_dev.removable = 0; mmc_dev.block_read = mmc_bread; fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */ } mmc_init_once = 1; return 1;}unsigned int *Rx_buffer1; //128[word]*16[blk]=8192[byte]void SD_Read(unsigned char * pucdata, unsigned long ulLBA, unsigned long ulSectors){ S3C2410_SDI * const sdi = S3C2410_GetBase_SDI(); int status, state, rd_cnt, total_word; //unsigned int *Rx_buffer1; //128[word]*16[blk]=8192[byte]// unsigned int *Rx_buffer1; //128[word]*16[blk]=8192[byte] Rx_buffer1 = (unsigned int *)(pucdata);// printf("Rx_buffer1 = 0x%x\n",Rx_buffer1); rd_cnt=0; sdi->SDIFSTA = sdi->SDIFSTA|(1<<16); // FIFO reset sdi->SDIDCON=(2<<22)|(1<<19)|(1<<17)|(CardBusWidth<<16)|(1<<14)|(2<<12)|(ulSectors<<0); //Salamander //Word Rx, Rx after cmd, blk, 4bit bus, Rx start, blk num, data start, data transmit mode sdi->SDICARG=ulLBA*512; // CMD17/18(addr)RERDCMD: //printf("RERCMD!!\n"); if(ulSectors<2) // SINGLE_READ { sdi->SDICCON=(0x1<<9)|(0x1<<8)|0x51; // sht_resp, wait_resp, dat, start, CMD17 if(!Chk_CMDend(17, 1)) //-- Check end of CMD17 goto RERDCMD; } else // MULTI_READ { sdi->SDICCON=(0x1<<9)|(0x1<<8)|0x52; // sht_resp, wait_resp, dat, start, CMD18 if(!Chk_CMDend(18, 1)) //-- Check end of CMD18 goto RERDCMD; } state = sdi->SDICSTA; sdi->SDICSTA = state; // Clear cmd_end(with rsp) //printf("\n Read CMD end\n"); total_word = 128*ulSectors; while(rd_cnt < total_word) // 512*block bytes { state = sdi->SDIDSTA; if((state&0x20)==0x20) // Check timeout { sdi->SDIDSTA=(0x1<<0x5); // Clear timeout flag printf("\n[Time Out !!!] %d, state=%x status=%x\n",rd_cnt,state,sdi->SDIFSTA); while(1); break; } status = sdi->SDIFSTA; if( (status&0x1000) == 0x1000 ) // Is Rx data? { *Rx_buffer1++=sdi->SDIDAT; //printf("%08x ",Rx_buffer1[rd_cnt]); rd_cnt++; //if(rd_cnt%8==0) printf("\n"); } } //printf("\n After Read loop %d\n",rd_cnt); //-- Check end of DATA //printf("\n[Start Chk_DATend !!!]\n"); if(!Chk_DATend()) printf("dat error\n"); //printf("\n[End Chk_DATend !!!]\n"); sdi->SDIDCON = sdi->SDIDCON & ~(7<<12); // Clear Data Transfer mode => no operation, Cleata Data Transfer start sdi->SDIFSTA = sdi->SDIFSTA & 0x200; // Clear Rx FIFO Last data Ready, sdi->SDIDSTA = 0x10; // Clear data Tx/Rx end detect if(ulSectors>1) {RERCMD12: //--Stop cmd(CMD12) sdi->SDICARG=0x0; //CMD12(stuff bit) sdi->SDICCON=(0x1<<9)|(0x1<<8)|0x4c; //sht_resp, wait_resp, start, CMD12 //-- Check end of CMD12 if(!Chk_CMDend(12, 1)) goto RERCMD12; sdi->SDICSTA=0xa00; // Clear cmd_end(with rsp) }}void SD_Write(unsigned char * pucdata, unsigned long ulLBA, unsigned long ulSectors){ S3C2410_SDI * const sdi = S3C2410_GetBase_SDI(); int status,wt_cnt; unsigned int *Tx_buffer1; //128[word]*16[blk]=8192[byte] Tx_buffer1 = (unsigned int *)(pucdata); wt_cnt=0; sdi->SDIFSTA = sdi->SDIFSTA|(1<<16); sdi->SDIDCON = (2<<22)|(1<<20)|(1<<17)|(CardBusWidth<<16)|(1<<14)|(3<<12)|(ulSectors<<0); //Word Tx, Tx after rsp, blk, 4bit bus, Tx start, blk num sdi->SDICARG = ulLBA*512; // CMD24/25(addr)REWTCMD: if(ulSectors<2) // SINGLE_WRITE { sdi->SDICCON=(0x1<<9)|(0x1<<8)|0x58; //sht_resp, wait_resp, dat, start, CMD24 if(!Chk_CMDend(24, 1)) //-- Check end of CMD24 goto REWTCMD; } else // MULTI_WRITE { sdi->SDICCON = (0x1<<9)|(0x1<<8)|0x59; //sht_resp, wait_resp, dat, start, CMD25 if(!Chk_CMDend(25, 1)) //-- Check end of CMD25 goto REWTCMD; } sdi->SDICSTA = 0xa00; // Clear cmd_end(with rsp) while(wt_cnt<128*ulSectors) { status = sdi->SDIFSTA; if((status&0x2000)==0x2000) { sdi->SDIDAT = *Tx_buffer1++; wt_cnt++;// printf("Block No.=%d, wt_cnt=%d\n",block,wt_cnt); } } //-- Check end of DATA if(!Chk_DATend()) printf("dat error\n"); sdi->SDIDCON = sdi->SDIDCON & ~(7<<12); //Clear Data Transfer mode => no operation, Cleata Data Transfer start sdi->SDIDSTA = 0x10; // Clear data Tx/Rx end if(ulSectors>1) { //--Stop cmd(CMD12)REWCMD12: sdi->SDIDCON = (1<<18)|(1<<17)|(0<<16)|(1<<14)|(1<<12)|(ulLBA<<0); sdi->SDICARG = 0x0; //CMD12(stuff bit) sdi->SDICCON = (0x1<<9)|(0x1<<8)|0x4c; //sht_resp, wait_resp, start, CMD12 //-- Check end of CMD12 if(!Chk_CMDend(12, 1)) goto REWCMD12; sdi->SDICSTA = 0xa00; // Clear cmd_end(with rsp) //-- Check end of DATA(with busy state) if(!Chk_BUSYend()) printf("Write error!\n"); sdi->SDIDSTA = 0x08; //! Should be cleared by writing '1'. }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -