⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdms.c

📁 嵌入式linux(arm9)的平台下
💻 C
字号:
#include "sdms.h"#define SDMS_DEBUG 1#ifdef PB1100	#define SDMS_CAPABLE#endif#ifdef DB1100	#define SDMS_CAPABLE#endif#ifdef HYDROGEN3	#define SDMS_CAPABLE#endifunsigned char Data;sdms_param sd0_param, sd1_param;int sdms_rca, sdms_base;int sdms_blksze = 512;				// default block size: 512int sdms_blkcnt = 1;				// default block count: 1int sdms_sectorsize = 512;int sdmsInit (int base){	int i, rca, busy, resp;		// initial config,  must set I bit for interrupts - not used right now	sdms_config (base) = 0x00000200		// set DE					| 0x000000cf;		// set divider	sync ();	sdms_ctrl (base) = 0x00000002		// set FF to flush & reset					| 0x00000001;		// set EN	sync ();	sdms_ctrl (base) = 0x00000001;		// clear FF to exit reset	sync ();	sdms_blksze (base) = 0x00000000;	// block size & count = 1	sync ();	sdms_tocnt (base) = 0x001fffff;		// max timeout	sync ();		// reset to idle	sdms_CMD00 (base, 0x00000000);	while (sdms_cmd (base) & 0x00000001);			// wait when CBSY = 1	while (sdms_status (base) & 0x00000010);   		// wait when CRBSY = 1		// check for response & set voltage	do	{		sdms_CMD55(base, 0x00000000);		while (!(sdms_cmd (base) & 0x00000002))		// wait when RRDY = 0		{			if (sdms_status (base) & 0x00020000)	// if timeout on response			{				return (0);			}		}				sdms_ACMD41 (base, 0x00ff8000);				// operating voltage range 		while (!(sdms_cmd (base) & 0x00000002))		// wait when RRDY = 0		{			if (sdms_status (base) & 0x00020000)	// if timeout on response			{			 				return (0);			} 		}				busy = (sdms_resp0 (base) >> 31);		nop();				// wait 1 ms		i = 0;		while( i < 400000 ) { i++; }			} while (!busy);		for (i = 0; i < 400000; i++);		// obtain rca	sdms_CMD02 (base, 0x00000000);	while (sdms_cmd (base) & 0x00000001);		// wait when CBSY = 1	while (!(sdms_cmd (base) & 0x00000002));	// wait when RRDY = 0		sdms_CMD03 (base, 0x00000000);	while (sdms_cmd (base) & 0x00000001);		// wait when CBSY = 1	while (!(sdms_cmd (base) & 0x00000002));	// wait when RRDY = 0		rca = sdms_resp0 (base);	rca = ((rca & 0xffff0000) >> 16);		return (rca);}sdms_param sdmsParam (int base, int rca)	// this function taken from testsuite2's sdms_walk.c{	sdms_param param;	int resp;	int c_size;	int c_size_mult;	int data;	int tmp;		param.rca = rca;		sdms_CMD09(base, (param.rca << 16) | 0x00000000);		while(sdms_cmd(base) & 0x00000001) {}		// wait when CBSY = 1	while(!(sdms_cmd(base) & 0x00000002)) {}	// wait when RRDY = 0		tmp = ((sdms_resp2(base) & 0x00000f00) >> 8);	param.rd_blk_len = (0x00000001 << tmp);		tmp = ((sdms_resp2(base) & 0x00000080) >> 7); 	param.rd_blk_partial = tmp;		c_size = (((sdms_resp2(base) & 0x00000003) << 10) | ((sdms_resp1(base) & 0xffc00000) >> 22)); 		c_size_mult = ((sdms_resp1(base) & 0x00000380) >> 7); 		param.mem_capacity = (c_size+1)*(0x00000001 << (c_size_mult+2))*param.rd_blk_len;		tmp = ((sdms_resp0(base) & 0x0003c000) >> 14);	param.wr_blk_len = 0x00000001 << tmp;		tmp = ((sdms_resp0(base) & 0x00002000) >> 13);	param.wr_blk_partial = tmp;		// host control	// change clock frequency to 25 MHz	sdms_config(base) = 0x00008201;  // clock divided by 4 to 25 MHz		sdms_CMD07(base, (param.rca << 16) | 0x00000000);	// response is R1b, check DBSY bit	while(sdms_status(base) & 0x00000020) {}	// wait when DBSY = 1 		while(sdms_cmd(base) & 0x00000001) {} 	 	// wait when CBSY = 1	while(!(sdms_cmd(base) & 0x00000002)) {}	// wait when RRDY = 0		sdms_CMD13(base, (param.rca << 16) | 0x00000000);		while(sdms_cmd(base) & 0x00000001) {}		// wait when CBSY = 1	while(!(sdms_cmd(base) & 0x00000002)) {}	// wait when RRDY = 0		sdms_CMD13(base, (param.rca << 16) | 0x00000000);		while(sdms_cmd(base) & 0x00000001) {}		// wait when CBSY = 1	while(!(sdms_cmd(base) & 0x00000002)) {}	// wait when RRDY = 0		// flush the fifo	sdms_ctrl(base) = (sdms_ctrl(base) | 0x00000002);		sdms_CMD55(base, (param.rca << 16) | 0x00000000);		while(sdms_cmd(base) & 0x00000001) {}		// wait when CBSY = 1	while(!(sdms_cmd(base) & 0x00000002)) {}	// wait when RRDY = 0		// ACMD51, treated as single block read	// need to set the host blk size to 7 (meaning 7 + 1 = 8 bytes block) 	sdms_blksze(base) = 0x00000007;	sdms_ACMD51(base, (param.rca << 16) | 0x00000000);		while(sdms_cmd(base) & 0x00000001) {}		// wait when CBSY = 1	while(!(sdms_cmd(base) & 0x00000002)) {}	// wait when RRDY = 0		// read response	resp = sdms_resp0(base);		while(sdms_status(base) & 0x00000010) {}	// wait when CRBSY = 1 	while(sdms_status(base) & 0x00000020) {}	// wait when DBSY = 1	while(!(sdms_status(base) & 0x00040000)) {}	// wait when DTD = 0		data = sdms_rxfifo(base);	data = sdms_rxfifo(base);		sdms_ctrl(base) = (sdms_ctrl(base) | 0x00000002);	// flush the fifo	param.bus_width = data & 0x0000000f;	sync();		// set blksze back to 511 (meaning 512 bytes)	sdms_blksze(base) = 0x000001ff;	//printf("SET: p_sd0_blksze = 0x%08x\n", sdms_blksze(base));		return param;}int sdmsOpen (int slot){	int i, rca, base, resp;	volatile unsigned *memory_cards;	sdms_param sd_param;		printf("SDMS Opnen\n");	if (!slot)		base = sd0;	else		#ifdef PB1100			base = sd1;		#else			return (0);		// only Pb1100 has two SD slots		#endif		// power up (board-specific)	#ifdef SDMS_CAPABLE		#ifdef DB1100			memory_cards = (uint32 *)0xae000014;			*memory_cards = 0x000000C0;		#endif		#ifdef PB1100			memory_cards = (uint32 *)0xae000010;			*memory_cards = (3<<10) << 16;		#endif		#ifdef HYDROGEN3			// no power up required		#endif	#else		return (0);	#endif		// enable sd slot	sdms_enable (base) = 0x00000001;	// reset	sync ();	for (i = 0; i < 400000; i++);		// give it some time or else won't function correctly	sdms_enable (base) = 0x00000003;	// take out of reset	sync ();	for (i = 0; i < 400000; i++);		// give it some time or else won't function correctly		sdms_status (base) = 0xffffffff;	// clear status register	sync ();		// initialize & obtain card parameters	rca = sdmsInit (base);	if (rca)	{		sd_param = sdmsParam (base, rca);//		printf ("sd card found in slot %d, capacity = %dkB\n", slot, sd_param.mem_capacity/1024);				sdms_config (base) = 0x00000200		// set DE							| 0x00000002;	// set divider [0x000000cf]		sync ();	}	else	{//		printf ("no sd card found in slot %d\n", slot);		return (0);	}		if (!slot)	{		sd0_param = sd_param;		sdms_rca = sd0_param.rca;		sdms_base = sd0;	}	else	{		sd1_param = sd_param;		sdms_rca = sd1_param.rca;		sdms_base = sd1;	}	// for some reason 'set bus width' and 'set block size' won't work inside sdmsInit, will try to figure out later	// set bus width to 4 bits (comment this out for 1 wire mode)	sdms_ctrl (sdms_base) = 0x00000101;									// 4-bit bus	sdms_CMD55 (sdms_base, (sdms_rca << 16) | 0x00000000);	sdms_ACMD06 (sdms_base, 0x00000002);								// set to 4-bit		// set block size	sdms_blksze (sdms_base) = (((sdms_blkcnt - 1) & 0x000001ff) << 16)	// block count [24:16]					| ((sdms_blksze - 1) & 0x000007ff); 				// block size [10:0]	sync ();	sdms_CMD16 (sdms_base, sdms_blksze);	while (sdms_cmd (sdms_base) & 0x00000001);							// wait when CBSY = 1	while (!(sdms_cmd (sdms_base) & 0x00000002));						// wait when RRDY = 0	resp = sdms_resp0 (sdms_base);		return (1);}int sdmsEject (){/*	sdms_status (sd0) = 0xffffffff;	sdms_enable (sd0) = 0x00000000;	sync ();		sdms_status (sd1) = 0xffffffff;	sdms_enable (sd1) = 0x00000000;	sync ();		printf ("sd slots disabled; it is safe to remove sd cards\n");*/		return (1);}void sdmsStopX (void){	sdms_cmdarg (sdms_base) = 0x00000000;	sync ();	sdms_cmd (sdms_base) = 0x00010c71;									// STOP_TRANSMISSION	sync ();	sdms_ctrl (sdms_base) = (sdms_ctrl (sdms_base) | 0x00000008);		// set CFDIS to force clk to be on	sync ();		while (sdms_cmd (sdms_base) & 0x00000001);							// wait until CBSY = 0	while (sdms_status (sdms_base) & 0x00000020);						// wait until DBSY = 0	while (!(sdms_status (sdms_base) & 0x00010000));					// wait when CRD = 0	while (!(sdms_cmd (sdms_base) & 0x00000002));						// wait when RRDY = 0		sdms_ctrl (sdms_base) = (sdms_ctrl (sdms_base) & 0xfffffff7);		// reset CFDIS to 0	sync ();	sdms_status (sdms_base) = (sdms_status (sdms_base) | 0x00040000);	// reset data done bit	sync ();}int sdmsRead (int sect, int n, void* buf){	int t, bytesToRead, startAddress;	bytesToRead = n * sdms_sectorsize;	startAddress = sect * sdms_sectorsize;	if (SDMS_DEBUG)		printf ("sector: %d\n", sect);		t = sdmsReadBytes (bytesToRead, startAddress, buf);		return (t);}int sdmsReadBytes (int bytesToRead, int startAddress, uint8* buf){	int i, temp;		if (SDMS_DEBUG)		printf ("start address: 0x%04X (%d)\n", startAddress, startAddress);		// flush RxFIFO of any extraneous bytes from previous read	sdms_ctrl (sdms_base) |= 0x00000002;	// set FF to flush & reset	sync ();	sdms_ctrl (sdms_base) &= ~0x00000002;	// clear FF to exit reset	sync ();		sdms_CMD18 (sdms_base, startAddress);		for (i = 0; i < bytesToRead; i++)	{		while (!(sdms_status (sdms_base) & 0x00000400))		;//		{//			if (sdms_status(sdms_base) & 0x00080000)//			{//				printf ("ERROR:  SDMS communication error\n");//				sdmsStopTxRx ();//				return (i);//			}//		}		buf[i] = (uint8) sdms_rxfifo (sdms_base);	}	if (SDMS_DEBUG)	{		for (i = 0; i < bytesToRead; i++)		{			if (!(i % 10)) printf ("\n%d\t", i);			printf ("%02X  ", buf[i]);		}		printf ("\n\n");	}		sdmsStopX ();		return (i);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -