新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > Eclipse開發(fā)調(diào)試ARM裸機(jī)程序(七)sd卡讀寫

Eclipse開發(fā)調(diào)試ARM裸機(jī)程序(七)sd卡讀寫

作者: 時(shí)間:2016-11-19 來源:網(wǎng)絡(luò) 收藏
主要用到了sd card官網(wǎng)上的幾個(gè)文檔,《SD Specifications Part 1 Physical Layer Simplified Specification Version 4.10 January 22, 2013》里邊講了SD卡內(nèi)部的寄存器,一般的時(shí)序。還有《SD Specifications Part A1 Advanced Security SD Extension Simplified Specification Version 2.00 May 18, 2010》和《SD Specifications Part A2 SD Host Controller Simplified Specification Version 3.00 February 25, 2011》都提供了一些信息。另外一個(gè)《SD Specifications Part E1 SDIO Simplified Specification Version 3.00 February 25, 2011》是說SDIO的,是以SDIO為接口的衍生品,包括SDIO wifi等等。這些文檔都可以在

每個(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 //#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);}

本文引用地址:http://m.butianyuan.cn/article/201611/318238.htm

總結(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)試相接合才是王道。



評論


技術(shù)專區(qū)

關(guān)閉