Eclipse開發(fā)調(diào)試ARM裸機(jī)程序(七)sd卡讀寫
每個(gè)寄存器都有特定的含義,我這里真分析的CSD寄存器,并用一個(gè)小程序算出每個(gè)參數(shù)的值。
先用Android手機(jī)或者開發(fā)板下載一個(gè)應(yīng)用 “sd tools”,這樣可以顯示出SD卡的CSD,然后根據(jù)手冊《SD Specifications Part 1 Physical Layer Simplified Specification Version 4.10 January 22, 2013》。測試的SD卡的CSD碼值如圖所示:
小程序如下:
#include#include typedef unsigned int u_size;int main(){u_size a = 0, b = 0, c = 0, d = 0;//CSD = 003e00325b5a83c5e597ffff12800000a = 0x003e0032; //[127:96]b = 0x5b5a83c5; //[95 :64]c = 0xe597ffff; //[63 :32]d = 0x12800000; //[31 :0 ]u_size CSD_STRUCTURE = a / (u_size)pow(2,30) & 0x3; // [127:126 - 96]u_size TAAC = a/(u_size)pow(2,16) & 0xff; // [119:112]u_size NSAC = a/(u_size)pow(2,8) & 0xff; // [111:104]u_size TRAN_SPEED = a/(u_size)pow(2,0) & 0xff; // [103:96 - 96]u_size CCC = b/(u_size)pow(2,20) & 0xfff;u_size READ_BL_LEN = b/(u_size)pow(2,16) & 0xf; // [83:80-64]u_size READ_BL_PARTIA = b/(u_size)pow(2,15) & 0x1;u_size WRITE_BLK_MISALIGN = b/(u_size)pow(2,14) & 0x1;u_size READ_BLK_MISALIGN = b/(u_size)pow(2,13) & 0x1;u_size DSR_IMP = b/(u_size)pow(2,12) & 0x1;u_size C_SIZE = (b & 0x3ff)*(u_size)pow(2,2) + ((c /(u_size)pow(2,30)) & 0x3); // [73:62]u_size VDD_R_CURR_MIN = c/(u_size)pow(2,27) & 0x7;u_size VDD_R_CURR_MAX = c/(u_size)pow(2,24) & 0x7;u_size VDD_W_CURR_MIN = c/(u_size)pow(2,21) & 0x7;u_size VDD_W_CURR_MAX = c/(u_size)pow(2,18) & 0x7;u_size C_SIZE_MULT = c/(u_size)pow(2,15) & 0x7; // [49:47]u_size ERASE_BLK_EN = d/(u_size)pow(2,14) & 0x1;u_size SECTOR_SIZE = d/(u_size)pow(2,7) & 0xef;u_size WP_GRP_SIZE = c/(u_size)pow(2,0) & 0xef;u_size WP_GRP_ENABLE = d/(u_size)pow(2,31) & 0x1;u_size R2W_FACTOR = d/(u_size)pow(2,26) & 0x7;u_size WRITE_BL_LEN = d/(u_size)pow(2,22) & 0xf;u_size WRITE_BL_PARTIAL = d/(u_size)pow(2,21) & 0x1;u_size TMP_WRITE_PROTECT = d/(u_size)pow(2,12) & 0x1;u_size FILE_FORMAT = d/(u_size)pow(2,10) & 0x3;u_size CRC = d/(u_size)pow(2,1) & 0xff;long C = (C_SIZE + 1) * pow(2, (C_SIZE_MULT+2)) * pow(2, READ_BL_LEN);// C = (3863 + 1) * 512 * 1024printf(" 1. CSD_STRUCTURE = 0x%xn", CSD_STRUCTURE);printf(" 3. TAAC = 0x%xn", TAAC);printf(" 4. NSAC = 0x%xn", NSAC);printf(" 5. TRAN_SPEED = 0x%x (0x32==>25MHz;0x5a==>50MHz)n", TRAN_SPEED);printf(" 6. CCC = 0x%xn", CCC);printf(" 7. READ_BL_LEN = %dn", READ_BL_LEN);printf(" 8. READ_BL_PARTIA = %dn", READ_BL_PARTIA);printf(" 9. WRITE_BLK_MISALIGN = %dn", WRITE_BLK_MISALIGN);printf("10. READ_BLK_MISALIGN = %dn", READ_BLK_MISALIGN);printf("11. DSR_IMP = %dn", DSR_IMP);printf("12. / *No Use* /n");printf("13. C_SIZE = %dn", C_SIZE);printf("14. VDD_R_CURR_MIN = %dn", VDD_R_CURR_MIN);printf("15. VDD_R_CURR_MAX = %dn", VDD_R_CURR_MAX);printf("16. VDD_W_CURR_MIN = %dn", VDD_W_CURR_MIN);printf("17. VDD_W_CURR_MAX = %dn", VDD_W_CURR_MAX);printf("18. C_SIZE_MULT = %dt""(本SD卡容量 = %f G)n", C_SIZE_MULT, (float)C/1073741824);printf("19. ERASE_BLK_EN = 0x%xn", ERASE_BLK_EN);printf("20. SECTOR_SIZE = 0x%xn", SECTOR_SIZE);printf("21. WP_GRP_SIZE = 0x%xn", WP_GRP_SIZE);printf("22. WP_GRP_ENABLE = 0x%xn", WP_GRP_ENABLE);printf("23. / *No Use* /n");printf("24. R2W_FACTOR = 0x%xn", R2W_FACTOR);printf("25. WRITE_BL_LEN = 0x%xn", WRITE_BL_LEN);printf("26. WRITE_BL_PARTIAL = 0x%xn", WRITE_BL_PARTIAL);printf("31. TMP_WRITE_PROTECT = 0x%xn", TMP_WRITE_PROTECT);printf("32. FILE_FORMAT = 0x%xn", FILE_FORMAT);printf("34. CRC = 0x%xt", CRC);return 0;}
運(yùn)行結(jié)果如下:
S3C2440上的寄存器就多了,有幾個(gè)難以理解的寫下來:SDICCON的后7位是發(fā)送命令值。但是真正填寫的時(shí)候并不是命令值而是&上了一個(gè)值(0x64),這個(gè)還沒有找出原因所在。例如如果發(fā)送命令2,SDICCON的后7位應(yīng)該是這樣的:(0x40 | 2)。
四、文件系統(tǒng)
如果只是簡單的放一個(gè)數(shù)據(jù),沒有文件系統(tǒng)會(huì)顯示無力,就無法在PC直接上查看。SD卡應(yīng)該有一個(gè)文件系統(tǒng)如常用的fat32。這個(gè)u-boot中有實(shí)現(xiàn),這里就先不做了。
五、代碼
完整代碼這里下載:http://download.csdn.net/detail/kangear/5303482
這里貼出sdi.c:
/* @file sdi.c* @brief sd卡 讀寫* @details 本程序?qū)崿F(xiàn)了,讀SD卡的CSD寄存器;讀寫SD卡,并用LED顯示。* 程序正常:led1首先點(diǎn)亮,然后是0-15的二進(jìn)制顯示* 程序出錯(cuò):led2首先點(diǎn)亮,然后是亂無序的二進(jìn)制顯示* 目前只能讀寫2G以下的SD卡* (啟動(dòng)代碼是適用于mini2440 nand 256M的開發(fā)板)* 讀寫SD有三種模式:中斷,DMA中斷,查詢。本程序使用的是查詢* @author kangear* @date 2013-4-26* @version A001* @par Copyright (c):* XXX公司* @par History:* version: author, date, descn** docs 1.SD Specifications Part 1 Physical Layer Simplified Specification Version 4.10 January 22, 2013.pdf* 2.SD Specifications Part A1 Advanced Security SD Extension Simplified Specification Version 2.00 May 18, 2010.pdf* 3.SD Specifications Part A2 SD Host Controller Simplified Specification Version 3.00 February 25, 2011.pdf* 4.SD Specifications Part E1 SDIO Simplified Specification Version 3.00 February 25, 2011.pdf** download addr:https://www.sdcard.org/downloads/pls/simplified_specs/*///#include本文引用地址:http://m.butianyuan.cn/article/201611/318238.htm//#include #include "def.h"http://#include "option.h"http://#include "2440addr.h"#include "s3c24xx.h"http://#include "2440lib.h"#include "sdi.h"/** 用在SDICCON中的[7:0] 現(xiàn)在沒有搞懂它的實(shí)際意義* CMD1 = MAGIC_NUMBER | 1*/#define MAGIC_NUMBER 64#define INICLK 300000#define SDCLK 24000000 //PCLK=49.392MHz#define POL 0#define INT 1#define DMA 2int CMD13(void); // Send card statusint CMD9(void);unsigned int *Tx_buffer; //128[word]*16[blk]=8192[byte]unsigned int *Rx_buffer; //128[word]*16[blk]=8192[byte]volatile unsigned int rd_cnt;volatile unsigned int wt_cnt;volatile unsigned int block;volatile unsigned int TR_end=0;int Wide=0; // 0:1bit, 1:4bitint MMC=0; // 0:SD , 1:MMCint Maker_ID;char Product_Name[7]; int Serial_Num;int PCLK = 50000000;volatile int RCA;void Test_SDI(void){U32 save_rGPEUP, save_rGPECON;RCA=0;MMC=0;block=3072; //3072Blocks=1.5MByte, ((2Block=1024Byte)*1024Block=1MByte)save_rGPEUP=GPEUP;save_rGPECON=GPECON;GPEUP = 0xf83f; // SDCMD, SDDAT[3:0] => PU En.GPECON = 0xaaaaaaaa; //SDCMD, SDDAT[3:0]//Uart_Printf("nSDI Card Write and Read Testn");if(!SD_card_init())return;TR_Buf_new();Wt_Block();Rd_Block();View_Rx_buf();Card_sel_desel(0); // Card deselectif(!CMD9())//Uart_Printf("Get CSD fail!!!n");SDIDCON=0;//tark???SDICSTA=0xffff;GPEUP=save_rGPEUP;GPECON=save_rGPECON;}void TR_Buf_new(void){//-- Tx & Rx Buffer initializeint i, j;Tx_buffer=(unsigned int *)0x31000000;j=0;for(i=0;i<2048;i++) //128[word]*16[blk]=8192[byte]*(Tx_buffer+i)=i+j;Flush_Rx_buf();}void Flush_Rx_buf(void){//-- Flushing Rx buffer int i;Rx_buffer=(unsigned int *)0x31800000;for(i=0;i<2048;i++) //128[word]*16[blk]=8192[byte]*(Rx_buffer+i)=0;//Uart_Printf("End Rx buffer flushn");}void View_Rx_buf(){//-- Display Rx buffer int i,error=0;Tx_buffer=(unsigned int *)0x31000000;Rx_buffer=(unsigned int *)0x31800000;//Uart_Printf("Check Rx datan");for(i=0;i<128*block;i++){if(Rx_buffer[i] != Tx_buffer[i]){//Uart_Printf("nTx/Rx errorn");//Uart_Printf("%d:Tx-0x%08x, Rx-0x%08xn",i,Tx_buffer[i], Rx_buffer[i]);error=1;break;}////Uart_Printf(".");}if(!error){//Uart_Printf("nThe Tx_buffer is same to Rx_buffer!n");//Uart_Printf("SD CARD Write and Read test is OK!n");}}void View_Tx_buf(void){}int SD_card_init(void){//-- SD controller & card initialize int i;/* Important notice for MMC test condition *//* Cmd & Data lines must be enabled by pull up resister */SDIPRE=PCLK/(INICLK)-1; // 400KHz//Uart_Printf("Init. Frequency is %dHzn",(PCLK/(SDIPRE+1)));SDICON=(1<<4)|1; // Type B, clk enableSDIFSTA=SDIFSTA|(1<<16); //YH 040223 FIFO resetSDIBSIZE=0x200; // 512byte(128word)SDIDTIMER=0x7fffff; // Set timeout countfor(i=0;i<0x1000;i++); // Wait 74SDCLK for MMC cardCMD0();//Uart_Printf("In idlen");//-- Check SD card OCRif(!Chk_SD_OCR()){// failGPBDAT = (~(2<<5)); // 點(diǎn)亮LED2//Uart_Printf("Initialize failnNo Card assertionn");return 0;}// Uart_Printf("In SD readyn");GPBDAT = (~(1<<5)); // 點(diǎn)亮LED1do{//-- Check attaced cards, it makes card identification stateSDICARG = 0x0; // CMD2(stuff bit)SDICCON = (0x1 << 10) | (0x1 << 9) | (0x1 << 8) | (MAGIC_NUMBER | 2); //lng_resp, wait_resp, start, CMD2//-- Check end of CMD2} while (!Chk_CMDend(2, 1));SDICSTA=0xa00; // Clear cmd_end(with rsp)//Uart_Printf("End idn");do{//--Send RCASDICARG = MMC << 16; // CMD3(MMC:Set RCA, SD:Ask RCA-->SBZ)SDICCON = (0x1 << 9) | (0x1 << 8) | (MAGIC_NUMBER | 3); // sht_resp, wait_resp, start, CMD3//-- Check end of CMD3if (!Chk_CMDend(3, 1))continue;SDICSTA = 0xa00; // Clear cmd_end(with rsp)//--Publish RCARCA = (SDIRSP0 & 0xffff0000) >> 16;//Uart_Printf("RCA=0x%xn",RCA);SDIPRE = PCLK / (SDCLK) - 1; // Normal clock=25MHz//Uart_Printf("SD Frequency is %dHzn",(PCLK/(SDIPRE+1)));//--State(stand-by) checkif (SDIRSP0 & 0x1e00 != 0x600) // CURRENT_STATE checkcontinue;} while (0);//Uart_Printf("In stand-byn");Card_sel_desel(1); // SelectSet_4bit_bus();return 1;}void Card_sel_desel(char sel_desel){//-- Card select or deselectif(sel_desel){do{SDICARG = RCA << 16; // CMD7(RCA,stuff bit)SDICCON = (0x1 << 9) | (0x1 << 8) | (MAGIC_NUMBER | 7); // sht_resp, wait_resp, start, CMD7//-- Check end of CMD7if (!Chk_CMDend(7, 1))continue;SDICSTA = 0xa00; // Clear cmd_end(with rsp)//--State(transfer) checkif (SDIRSP0 & 0x1e00 != 0x800)continue;} while (0);}else{do{SDICARG = 0 << 16; //CMD7(RCA,stuff bit)SDICCON = (0x1 << 8) | (MAGIC_NUMBER | 7); //no_resp, start, CMD7//-- Check end of CMD7if (!Chk_CMDend(7, 0))continue;} while (0);SDICSTA=0x800; // Clear cmd_end(no rsp)}}//void __irq Rd_Int(void)//{// U32 i,status;//// status=SDIFSTA;// if( (status&0x200) == 0x200 ) // Check Last interrupt?// {// for(i=(status & 0x7f)/4;i>0;i--)// {// *Rx_buffer++=SDIDAT;// rd_cnt++;// }// SDIFSTA=SDIFSTA&0x200; //Clear Rx FIFO Last data Ready, YH 040221// }// else if( (status&0x80) == 0x80 ) // Check Half interrupt?// {// for(i=0;i<8;i++)// {// *Rx_buffer++=SDIDAT;// rd_cnt++;// }// }//// ClearPending(BIT_SDI);//}//void __irq Wt_Int(void)//{// ClearPending(BIT_SDI);//// SDIDAT=*Tx_buffer++;// wt_cnt++;//// if(wt_cnt==128*block)// {// rINTMSK |= BIT_SDI;// SDIDAT=*Tx_buffer;// TR_end=1;// }//}////void __irq DMA_end(void)//{// ClearPending(BIT_DMA0);//// TR_end=1;//}void Rd_Block(void){U32 mode;int status;rd_cnt=0; //Uart_Printf("Block read test[ Polling read ]n");mode = 0 ;SDIFSTA=SDIFSTA|(1<<16); // FIFO resetif(mode!=2)SDIDCON=(2<<22)|(1<<19)|(1<<17)|(Wide<<16)|(1<<14)|(2<<12)|(block<<0); //YH 040220SDICARG=0x0; // CMD17/18(addr)RERDCMD:switch(mode){case POL:if(block<2) // SINGLE_READ{SDICCON=(0x1<<9)|(0x1<<8)|(MAGIC_NUMBER | 17); // sht_resp, wait_resp, dat, start, CMD17if(!Chk_CMDend(17, 1)) //-- Check end of CMD17goto RERDCMD; }else // MULTI_READ{SDICCON=(0x1<<9)|(0x1<<8)|(MAGIC_NUMBER | 18); // sht_resp, wait_resp, dat, start, CMD18if(!Chk_CMDend(18, 1)) //-- Check end of CMD18 goto RERDCMD;}SDICSTA=0xa00; // Clear cmd_end(with rsp)while(rd_cnt<128*block) // 512*block bytes{if((SDIDSTA&0x20)==0x20) // Check timeout{SDIDSTA=(0x1<<0x5); // Clear timeout flagbreak;}status=SDIFSTA;if((status&0x1000)==0x1000) // Is Rx data?{*Rx_buffer++=SDIDAT;rd_cnt++;}}break;// case INT:// pISR_SDI=(unsigned)Rd_Int;// rINTMSK = ~(BIT_SDI);//// rSDIIMSK=5; // Last & Rx FIFO half int.//// if(block<2) // SINGLE_READ// {// SDICCON=(0x1<<9)|(0x1<<8)|(MAGIC_NUMBER | 17); // sht_resp, wait_resp, dat, start, CMD17// if(!Chk_CMDend(17, 1)) //-- Check end of CMD17// goto RERDCMD;// }// else // MULTI_READ// {// SDICCON=(0x1<<9)|(0x1<<8)|(MAGIC_NUMBER | 18); // sht_resp, wait_resp, dat, start, CMD18// if(!Chk_CMDend(18, 1)) //-- Check end of CMD18// goto RERDCMD;// }//// SDICSTA=0xa00; // Clear cmd_end(with rsp)//// while(rd_cnt<128*block);//// rINTMSK |= (BIT_SDI);// rSDIIMSK=0; // All mask// break;//// case DMA:// pISR_DMA0=(unsigned)DMA_end;// rINTMSK = ~(BIT_DMA0);// SDIDCON=SDIDCON|(1<<24); //YH 040227, Burst4 Enable//// rDISRC0=(int)(SDIDAT); // SDIDAT// rDISRCC0=(1<<1)+(1<<0); // APB, fix// rDIDST0=(U32)(Rx_buffer); // Rx_buffer// rDIDSTC0=(0<<1)+(0<<0); // AHB, inc// rDCON0=(1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(2<<24)+(1<<23)+(1<<22)+(2<<20)+128*block;//// rDMASKTRIG0=(0<<2)+(1<<1)+0; //no-stop, DMA2 channel on, no-sw trigger//// SDIDCON=(2<<22)|(1<<19)|(1<<17)|(Wide<<16)|(1<<15)|(1<<14)|(2<<12)|(block<<0);// if(block<2) // SINGLE_READ// {// SDICCON=(0x1<<9)|(0x1<<8)|(MAGIC_NUMBER | 17); // sht_resp, wait_resp, dat, start, CMD17// if(!Chk_CMDend(17, 1)) //-- Check end of CMD17// goto RERDCMD;// }// else // MULTI_READ// {// SDICCON=(0x1<<9)|(0x1<<8)|(MAGIC_NUMBER | 18); // sht_resp, wait_resp, dat, start, CMD18// if(!Chk_CMDend(18, 1)) //-- Check end of CMD18// goto RERDCMD;// }//// SDICSTA=0xa00; // Clear cmd_end(with rsp)// while(!TR_end);// ////Uart_Printf("SDIFSTA=0x%xn",SDIFSTA);// rINTMSK |= (BIT_DMA0);// TR_end=0;// rDMASKTRIG0=(1<<2); //DMA0 stop// break;default:break;}//-- Check end of DATAif(!Chk_DATend()) //Uart_Printf("dat errorn");SDIDCON=SDIDCON&~(7<<12);SDIFSTA=SDIFSTA&0x200; //Clear Rx FIFO Last data Ready, YH 040221SDIDSTA=0x10; // Clear data Tx/Rx end detectif(block>1){RERCMD12: //--Stop cmd(CMD12)SDICARG=0x0; //CMD12(stuff bit)SDICCON=(0x1<<9)|(0x1<<8)|(MAGIC_NUMBER | 12);//sht_resp, wait_resp, start, CMD12//-- Check end of CMD12if(!Chk_CMDend(12, 1)) goto RERCMD12;SDICSTA=0xa00; // Clear cmd_end(with rsp)}}void Wt_Block(void){U32 mode;int status;wt_cnt=0; //Uart_Printf("Block write test[ Polling write ]n");mode = 0 ;SDIFSTA=SDIFSTA|(1<<16); //YH 040223 FIFO resetif(mode!=2)SDIDCON=(2<<22)|(1<<20)|(1<<17)|(Wide<<16)|(1<<14)|(3<<12)|(block<<0); //YH 040220SDICARG=0x0; // CMD24/25(addr)REWTCMD:switch(mode){case POL:if(block<2) // SINGLE_WRITE{SDICCON=(0x1<<9)|(0x1<<8)|(MAGIC_NUMBER | 24); //sht_resp, wait_resp, dat, start, CMD24if(!Chk_CMDend(24, 1)) //-- Check end of CMD24goto REWTCMD;}else // MULTI_WRITE{SDICCON=(0x1<<9)|(0x1<<8)|(MAGIC_NUMBER | 25); //sht_resp, wait_resp, dat, start, CMD25if(!Chk_CMDend(25, 1)) //-- Check end of CMD25goto REWTCMD; }SDICSTA=0xa00; // Clear cmd_end(with rsp)while(wt_cnt<128*block){status=SDIFSTA;if((status&0x2000)==0x2000) {SDIDAT=*Tx_buffer++;wt_cnt++;////Uart_Printf("Block No.=%d, wt_cnt=%dn",block,wt_cnt);}}break;// case INT:// pISR_SDI=(unsigned)Wt_Int;// rINTMSK = ~(BIT_SDI);//// rSDIIMSK=0x10; // Tx FIFO half int.//// if(block<2) // SINGLE_WRITE// {// SDICCON=(0x1<<9)|(0x1<<8)|(MAGIC_NUMBER | 24); //sht_resp, wait_resp, dat, start, CMD24// if(!Chk_CMDend(24, 1)) //-- Check end of CMD24// goto REWTCMD;// }// else // MULTI_WRITE// {// SDICCON=(0x1<<9)|(0x1<<8)|(MAGIC_NUMBER | 25); //sht_resp, wait_resp, dat, start, CMD25// if(!Chk_CMDend(25, 1)) //-- Check end of CMD25// goto REWTCMD;// }//// SDICSTA=0xa00; // Clear cmd_end(with rsp)//// while(!TR_end);// //while(wt_cnt<128);//// rINTMSK |= (BIT_SDI);// TR_end=0;// rSDIIMSK=0; // All mask// break;//// case DMA:// pISR_DMA0=(unsigned)DMA_end;// rINTMSK = ~(BIT_DMA0);// SDIDCON=SDIDCON|(1<<24); //YH 040227, Burst4 Enable//// rDISRC0=(int)(Tx_buffer); // Tx_buffer// rDISRCC0=(0<<1)+(0<<0); // AHB, inc// rDIDST0=(U32)(SDIDAT); // SDIDAT// rDIDSTC0=(1<<1)+(1<<0); // APB, fix// rDCON0=(1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(2<<24)+(1<<23)+(1<<22)+(2<<20)+128*block;// //handshake, sync PCLK, TC int, single tx, single service, SDI, H/W request,// //auto-reload off, word, 128blk*num// rDMASKTRIG0=(0<<2)+(1<<1)+0; //no-stop, DMA0 channel on, no-sw trigger//// SDIDCON=(2<<22)|(1<<20)|(1<<17)|(Wide<<16)|(1<<15)|(1<<14)|(3<<12)|(block<<0); //YH 040220//// // Word Tx, Tx after rsp, blk, 4bit bus, dma enable, Tx start, blk num// if(block<2) // SINGLE_WRITE// {// SDICCON=(0x1<<9)|(0x1<<8)|(MAGIC_NUMBER | 24); //sht_resp, wait_resp, dat, start, CMD24// if(!Chk_CMDend(24, 1)) //-- Check end of CMD24// goto REWTCMD;// }// else // MULTI_WRITE// {// SDICCON=(0x1<<9)|(0x1<<8)|(MAGIC_NUMBER | 25); //sht_resp, wait_resp, dat, start, CMD25// if(!Chk_CMDend(25, 1)) //-- Check end of CMD25// goto REWTCMD;// }//// SDICSTA=0xa00; // Clear cmd_end(with rsp)//// while(!TR_end);//// rINTMSK |= (BIT_DMA0);// TR_end=0;// rDMASKTRIG0=(1<<2); //DMA0 stop//// break;default:break;}//-- Check end of DATAif(!Chk_DATend()) //Uart_Printf("dat errorn");SDIDCON=SDIDCON&~(7<<12); //YH 040220, Clear Data Transfer mode => no operation, Cleata Data Transfer startSDIDSTA=0x10; // Clear data Tx/Rx endif(block>1){//--Stop cmd(CMD12)REWCMD12: SDIDCON=(1<<18)|(1<<17)|(0<<16)|(1<<14)|(1<<12)|(block<<0); //YH 040220SDICARG=0x0; //CMD12(stuff bit)SDICCON=(0x1<<9)|(0x1<<8)|(MAGIC_NUMBER | 12); //sht_resp, wait_resp, start, CMD12//-- Check end of CMD12if(!Chk_CMDend(12, 1)) goto REWCMD12;SDICSTA=0xa00; // Clear cmd_end(with rsp)//-- Check end of DATA(with busy state)if(!Chk_BUSYend()) //Uart_Printf("errorn");SDIDSTA=0x08; //! Should be cleared by writing 1.}}void Delay(volatile unsigned long dly){for(; dly > 0; dly--);}int Chk_CMDend(int cmd, int be_resp)//0: Timeout{int finish0;if(!be_resp) // No response{finish0=SDICSTA;while((finish0&0x800)!=0x800) // Check cmd endfinish0=SDICSTA;SDICSTA=finish0;// Clear cmd end statereturn 1;}else // With response{finish0=SDICSTA;while( !( ((finish0&0x200)==0x200) | ((finish0&0x400)==0x400) )) // Check cmd/rsp endfinish0=SDICSTA;if(cmd==1 | cmd==41) // CRC no check, CMD9 is a long Resp. command.{if( (finish0&0xf00) != 0xa00 ) // Check error{SDICSTA=finish0; // Clear error stateif(((finish0&0x400)==0x400))return 0; // Timeout error}SDICSTA=finish0; // Clear cmd & rsp end state}else // CRC check{if( (finish0&0x1f00) != 0xa00 ) // Check error{//Uart_Printf("CMD%d:SDICSTA=0x%x, SDIRSP0=0x%xn",cmd, SDICSTA, SDIRSP0);SDICSTA=finish0; // Clear error stateif(((finish0&0x400)==0x400))return 0; // Timeout error}SDICSTA=finish0;}return 1;}}int Chk_DATend(void){int finish;finish=SDIDSTA;while( !( ((finish&0x10)==0x10) | ((finish&0x20)==0x20) )) // Chek timeout or data endfinish=SDIDSTA;if( (finish&0xfc) != 0x10 ){//Uart_Printf("DATA:finish=0x%xn", finish);SDIDSTA=0xec; // Clear error statereturn 0;}return 1;}int Chk_BUSYend(void){int finish;finish=SDIDSTA;while( !( ((finish&0x08)==0x08) | ((finish&0x20)==0x20) ))finish=SDIDSTA;if( (finish&0xfc) != 0x08 ){//Uart_Printf("DATA:finish=0x%xn", finish);SDIDSTA=0xf4; //clear error statereturn 0;}return 1;}void CMD0(void){//-- Make card idle state SDICARG=0x0; // CMD0(stuff bit)SDICCON=(1<<8)|(MAGIC_NUMBER | 0); // No_resp, start, CMD0//-- Check end of CMD0Chk_CMDend(0, 0);SDICSTA=0x800; // Clear cmd_end(no rsp)}int Chk_SD_OCR(void){int i;//-- Negotiate operating condition for SD, it makes card ready statefor(i=0;i<50;i++) //If this time is short, init. can be fail.{CMD55(); // Make ACMDSDICARG=0xff8000; //ACMD41(SD OCR:2.7V~3.6V)SDICCON=(0x1<<9)|(0x1<<8)|(MAGIC_NUMBER | 41);//sht_resp, wait_resp, start, ACMD41//-- Check end of ACMD41if( Chk_CMDend(41, 1) & SDIRSP0==0x80ff8000 ){SDICSTA=0xa00; // Clear cmd_end(with rsp)return 1; // Success }Delay(20000); // Wait Card power up status 1Sec//Delay(200); // Wait Card power up status}////Uart_Printf("SDIRSP0=0x%xn",SDIRSP0);SDICSTA=0xa00; // Clear cmd_end(with rsp)return 0; // Fail}int CMD55(void){//--Make ACMDSDICARG=RCA<<16; //CMD7(RCA,stuff bit)SDICCON=(0x1<<9)|(0x1<<8)|(MAGIC_NUMBER | 55); //sht_resp, wait_resp, start, CMD55//-- Check end of CMD55if(!Chk_CMDend(55, 1)) return 0;SDICSTA=0xa00; // Clear cmd_end(with rsp)return 1;}int CMD13(void)//SEND_STATUS{int response0;SDICARG=RCA<<16; // CMD13(RCA,stuff bit)SDICCON=(0x1<<9)|(0x1<<8)|(MAGIC_NUMBER | 13); // sht_resp, wait_resp, start, CMD13//-- Check end of CMD13if(!Chk_CMDend(13, 1)) return 0;////Uart_Printf("SDIRSP0=0x%xn", SDIRSP0);if(SDIRSP0&0x100)////Uart_Printf("Ready for Datan");//else ////Uart_Printf("Not Readyn");response0=SDIRSP0;response0 &= 0x3c00;response0 = response0 >> 9;////Uart_Printf("Current Status=%dn", response0);if(response0==6)Test_SDI();SDICSTA=0xa00; // Clear cmd_end(with rsp)return 1;}int CMD9(void)//SEND_CSD{SDICARG=RCA<<16; // CMD9(RCA,stuff bit)SDICCON=(0x1<<10)|(0x1<<9)|(0x1<<8)|(MAGIC_NUMBER | 9); // long_resp, wait_resp, start, CMD9//Uart_Printf("nCSD register :n");//-- Check end of CMD9if(!Chk_CMDend(9, 1)) return 0;//Uart_Printf("SDIRSP0=0x%xnSDIRSP1=0x%xnSDIRSP2=0x%xnSDIRSP3=0x%xn", SDIRSP0,rSDIRSP1,rSDIRSP2,rSDIRSP3);return 1;}void Set_4bit_bus(void){Wide=1;SetBus();////Uart_Printf("n4bit busn");}void SetBus(void){do{CMD55(); // Make ACMD//-- CMD6 implementSDICARG = Wide << 1; //Wide 0: 1bit, 1: 4bitSDICCON = (0x1 << 9) | (0x1 << 8) | (MAGIC_NUMBER | 6); //sht_resp, wait_resp, start, CMD55if (!Chk_CMDend(6, 1)) // ACMD6continue;SDICSTA = 0xa00; // Clear cmd_end(with rsp)} while (0);}void Set_Prt(void){//-- Set protection addr.0 ~ 262144(32*16*512) //Uart_Printf("[Set protection(addr.0 ~ 262144) test]n");do{//--Make ACMDSDICARG = 0; // CMD28(addr)SDICCON = (0x1 << 9) | (0x1 << 8) | (MAGIC_NUMBER | 28); //sht_resp, wait_resp, start, CMD28//-- Check end of CMD28if (!Chk_CMDend(28, 1))continue;SDICSTA = 0xa00; // Clear cmd_end(with rsp)} while (0);}void Clr_Prt(void){//-- Clear protection addr.0 ~ 262144(32*16*512) ////Uart_Printf("[Clear protection(addr.0 ~ 262144) test]n");do{//--Make ACMDSDICARG = 0; // CMD29(addr)SDICCON = (0x1 << 9) | (0x1 << 8) | (MAGIC_NUMBER | 29); //sht_resp, wait_resp, start, CMD29//-- Check end of CMD29if (!Chk_CMDend(29, 1))continue;SDICSTA = 0xa00; // Clear cmd_end(with rsp)} while (0);}
總結(jié):調(diào)試和運(yùn)行還是用很在的差別的,eclipse調(diào)試沒有問題的,運(yùn)行就會(huì)有點(diǎn)小問題,eclipse可以確定程序的框架,運(yùn)行可以細(xì)節(jié)地顯示問題,那個(gè)延時(shí)Delay(200)沒有問題,到運(yùn)行時(shí)候調(diào)整為Delay(2000)才可以正常。jlink的速率什么的都會(huì)影響,并不能代碼整個(gè)實(shí)時(shí)的運(yùn)行效果。在線調(diào)試和下載運(yùn)行調(diào)試相接合才是王道。
評論