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

📄 sd.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *      A     EEEE  SSSS   OOO  PPPP  *     A A    E     S     O   O P   P *    AAAAA   EEEE  SSSS  O   O PPPP *   A     A  E         S O   O P *   A     A  EEEE  SSSS   OOO  P * *  An Entertainment Solution On a Platform (AESOP) is a completely Open Source  *  based graphical user environment and suite of applications for PDAs and other  *  devices running Linux. It is included in various embedded Linux distributions  *  such as OpenZaurus - http://www.aesop-embedded.org  * * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * * *	Title           : sd.c *	Author          :  *	Created date    : 2005. 06. 26. 23:05:59 KST *	Description     :  * *	$Revision: 1.2 $ *	$Log: sd.c,v $ *	Revision 1.2  2005/07/07 15:46:59  linux4go *	*** empty log message *** *	 *	Revision 1.1.1.1  2005/06/27 17:03:53  linuxpark *	Initial import. *	 *	 * */ #ident  "@(*) $Header: /cvsroot/aesop-embedded/u-boot-aesop/board/aesop2440/sd.c,v 1.2 2005/07/07 15:46:59 linux4go Exp $"/* * Copyright (c) 2005 * Salamander, aesop-embedded.org  kernelproject.org, <omega5@dreamwiz.com> * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */#include <common.h>#include <s3c2440.h>#include <part.h>#if 1extern intfat_register_device(block_dev_desc_t *dev_desc, int part_no);static block_dev_desc_t mmc_dev;block_dev_desc_t * mmc_get_dev(int dev){	return ((block_dev_desc_t *)&mmc_dev);}//#if 1int isMMC;	// 1:MMC, 0:SDint RCA=0;	// Relative card addressunsigned int CardSize=0; // SD capacity in byte		 /*  * CSD register, rwe == read/write/erase  */typedef struct {	unsigned char csd;		/* CSD structure */	unsigned char spec_vers;		/* Spec version, MMC only */	struct {		unsigned char man;	/* time mantissa */		unsigned char exp;	/* time exponent */	} taac;			/* Data read access-time-1 */	unsigned char nsac;		/* Data read access-time-2 in CLK cycle */	struct {		unsigned char man;	/* rate mantissa */		unsigned char exp;	/* rate exponent */	} tran_speed;		/* Max. data transfer rate */	unsigned short ccc;		/* Card command classes */	unsigned char read_len;		/* Max. read data block length */	unsigned char read_part;		/* Partial blocks for read allowed */	unsigned char write_mis;		/* write block misalignment */	unsigned char read_mis;		/* read block misalignment */	unsigned char dsr;		/* DSR implemented */	unsigned short  c_size;		/* Device size */	unsigned char vcc_r_min;		/* Max. read current at Vcc min */	unsigned char vcc_r_max;		/* Max. read current at Vcc max */	unsigned char vcc_w_min;		/* Max. write current at Vcc min */	unsigned char vcc_w_max;		/* Max. write current at Vcc max */	unsigned char c_size_mult;	/* Device size multiplier */	unsigned char er_size;		/* Erase sector size, MMC only */	unsigned char er_grp_size;	/* Erase group size, MMC only */	unsigned char wp_grp_size;	/* Write protect group size */	unsigned char wp_grp_en;		/* Write protect group enable */	unsigned char dflt_ecc;		/* Manufacturer default ECC, MMC only */	unsigned char r2w_factor;	/* Write speed factor */	unsigned char write_len;		/* Max. write data block length */	unsigned char write_part;	/* Partial blocks for write allowed */	unsigned char ffmt_grp;		/* File format group, rw */	unsigned char copy;		/* Copy flag (OTP), rw */	unsigned char perm_wp;		/* Permanent write protection, rw */	unsigned char tmp_wp;		/* temporary write protection, rwe */	unsigned char ffmt;		/* file format, rw */	unsigned char ecc;		/* ECC, rwe, MMC only */	/* SD only */	unsigned char er_blk_en;		/* Erase single block enable, SD only */	unsigned char er_sec_size;	/* Erase sector size, SD only */} CSD_regs;int Chk_CMDend(int cmd, int be_resp){	S3C2410_SDI * const sdi = S3C2410_GetBase_SDI();	int volatile finish0;	if(!be_resp)    // No response		{		finish0=sdi->SDICSTA;		while((finish0&0x800) != 0x800)	// Check cmd end		{			finish0=sdi->SDICSTA;		}		sdi->SDICSTA=finish0;// Clear cmd end state		return 1;	}	else	// With response		{		finish0=sdi->SDICSTA;		while( !( ((finish0&0x200)==0x200) | ((finish0&0x400)==0x400) ))    // Check cmd/rsp end			finish0=sdi->SDICSTA;		if( (cmd==1) | (cmd==41))	// CRC no check, CMD9 is a long Resp. command.		{			if( (finish0&0xf00) != 0xa00 )  // Check error			{				sdi->SDICSTA=finish0;   // Clear error state				if(((finish0&0x400)==0x400))					return 0;	// Timeout error			}			sdi->SDICSTA=finish0;	// Clear cmd & rsp end state		}		else	// CRC check		{			if( (finish0&0x1f00) != 0xa00 )	// Check error			{								//printf("CMD%d:rSDICSTA=0x%x,rSDIRSP0=0x%x\n",cmd, sdi->SDICSTA, sdi->SDIRSP0);				sdi->SDICSTA=finish0;   // Clear error state				if(((finish0&0x400)==0x400))					return 0;	// Timeout error			}			sdi->SDICSTA=finish0;		}		return 1;	}}int Chk_DATend(void){	S3C2410_SDI * const sdi = S3C2410_GetBase_SDI();	int finish;	finish = sdi->SDIDSTA;	while( !( ((finish&0x10)==0x10) | ((finish&0x20)==0x20) ))		{		// Chek timeout or data end		finish = sdi->SDIDSTA;		//printf("DATA:finish=0x%x\n", finish);	}	if( (finish&0xfc) != 0x10 )	{		printf("DATA:finish=0x%x\n", finish); // Something wrong !!		sdi->SDIDSTA = 0xec;  // Clear error state		return 0;	}	return 1;}int Chk_BUSYend(void){	S3C2410_SDI * const sdi = S3C2410_GetBase_SDI();	int finish;	finish = sdi->SDIDSTA;	while( !( ((finish&0x08)==0x08) | ((finish&0x20)==0x20) ))		finish = sdi->SDIDSTA;	if( (finish&0xfc) != 0x08 )	{		printf("BUSY:finish=0x%x\n", finish);		sdi->SDIDSTA = 0xf4;  //clear error state		return 0;	}	return 1;}void CMD0(void){	S3C2410_SDI * const sdi = S3C2410_GetBase_SDI();	//-- Make card idle state 	sdi->SDICARG=0x0;	    // CMD0(stuff bit)	sdi->SDICCON=(1<<8)|0x40;   // No_resp, start, CMD0	//-- Check end of CMD0	Chk_CMDend(0, 0);	sdi->SDICSTA=0x800;	    // Clear cmd_end(no rsp)}int CMD55(void){	S3C2410_SDI * const sdi = S3C2410_GetBase_SDI();	//--Make ACMD	sdi->SDICARG=RCA<<16;			//CMD7(RCA,stuff bit)	sdi->SDICCON=(0x1<<9)|(0x1<<8)|0x77;	//sht_resp, wait_resp, start, CMD55	//-- Check end of CMD55	if(!Chk_CMDend(55, 1)) 		return 0;	sdi->SDICSTA=0xa00;	// Clear cmd_end(with rsp)	return 1;}CSD_regs csd;int CMD9(void)//SEND_CSD{	S3C2410_SDI * const sdi = S3C2410_GetBase_SDI();	unsigned char buff[16];	//	unsigned long card_size;		sdi->SDICARG=RCA<<16;				// CMD9(RCA,stuff bit)	sdi->SDICCON=(0x1<<10)|(0x1<<9)|(0x1<<8)|0x49;	// long_resp, wait_resp, start, CMD9//	printf("\n****CSD register****\n");	//-- Check end of CMD9	if(!Chk_CMDend(9, 1)) return 0;	buff[0]=(unsigned char)(sdi->SDIRSP0>>24);	buff[1]=(unsigned char)(sdi->SDIRSP0>>16);	buff[2]=(unsigned char)(sdi->SDIRSP0>>8);	buff[3]=(unsigned char)(sdi->SDIRSP0);	buff[4]=(unsigned char)(sdi->SDIRSP1>>24);	buff[5]=(unsigned char)(sdi->SDIRSP1>>16);	buff[6]=(unsigned char)(sdi->SDIRSP1>>8);	buff[7]=(unsigned char)(sdi->SDIRSP1);	buff[8]=(unsigned char)(sdi->SDIRSP2>>24);	buff[9]=(unsigned char)(sdi->SDIRSP2>>16);	buff[10]=(unsigned char)(sdi->SDIRSP2>>8);	buff[11]=(unsigned char)(sdi->SDIRSP2);	buff[12]=(unsigned char)(sdi->SDIRSP3>>24);	buff[13]=(unsigned char)(sdi->SDIRSP3>>16);	buff[14]=(unsigned char)(sdi->SDIRSP3>>8);	buff[15]=(unsigned char)(sdi->SDIRSP3);	{		csd.csd		= (buff[0] & 0xc0) >> 6;		csd.spec_vers	= (buff[0] & 0x3c) >> 2;		(csd.taac).man	= (buff[1] & 0x78) >> 3;		(csd.taac).exp	= (buff[1]) & 0x07;		csd.nsac	= buff[2];		(csd.tran_speed).man = (buff[3] & 0x78) >> 3;		(csd.tran_speed).exp = (buff[3]) & 0x07;		csd.ccc		= (buff[4] << 4) | ((buff[5] & 0xf0) >> 4);		csd.read_len	= (buff[5] & 0x0f);		csd.read_part	= (buff[6] & 0x80) ? 1 : 0;		csd.write_mis	= (buff[6] & 0x40) ? 1 : 0;		csd.read_mis	= (buff[6] & 0x20) ? 1 : 0;		csd.dsr		= (buff[6] & 0x10) ? 1 : 0;		csd.c_size	= ((buff[6] & 0x03) << 10) |	(buff[7] << 2) | ((buff[8] & 0xc0) >> 6);		csd.vcc_r_min	= (buff[8] & 0x38) >> 3;		csd.vcc_r_max	= (buff[8] & 0x07);		csd.vcc_w_min	= (buff[9] & 0xe0) >> 5;		csd.vcc_w_max	= (buff[9] & 0x1c) >> 2;		csd.c_size_mult = ((buff[9] & 0x03) << 1) | ((buff[10] & 0x80) >> 7);		csd.er_size     = (buff[10] & 0x7c) >> 2;		csd.er_grp_size = ((buff[10] & 0x03) << 3) | ((buff[11] & 0xe0) >> 5);		csd.wp_grp_size = (buff[11] & 0x1f);		csd.wp_grp_en	= (buff[12] & 0x80) ? 1 : 0;		csd.dflt_ecc	= (buff[12] & 0x60) >> 5;		csd.r2w_factor	= (buff[12] & 0x1c) >> 2;		csd.write_len 	= ((buff[12] & 0x03) << 2) | ((buff[13] & 0xc0) >> 6);		csd.write_part	= (buff[13] & 0x20) ? 1 : 0;		csd.ffmt_grp	= (buff[14] & 0x80) ? 1 : 0;		csd.copy	= (buff[14] & 0x40) ? 1 : 0;		csd.perm_wp	= (buff[14] & 0x20) ? 1 : 0;		csd.tmp_wp	= (buff[14] & 0x10) ? 1 : 0;		csd.ffmt	= (buff[14] & 0x0c) >> 2;		csd.ecc		= (buff[14] & 0x03);	}	/* calculate total card size in bytes */	CardSize = (1 + csd.c_size) * (0x01 << (csd.c_size_mult + 2)) * (0x01 << csd.read_len);	printf("Size = %d KBytes  ", CardSize/1024);	return 1;}int Chk_MMC_OCR(void){	S3C2410_SDI * const sdi = S3C2410_GetBase_SDI();	int i;	//-- Negotiate operating condition for MMC, it makes card ready state	for(i=0;i<100;i++)	//Negotiation time is dependent on CARD Vendors.	{		//    	sdi->SDICARG=0xffc000;	    	    //CMD1(MMC OCR:2.6V~3.6V)		sdi->SDICARG=0xff8000;	    	    //CMD1(SD OCR:2.7V~3.6V)		sdi->SDICCON=(0x1<<9)|(0x1<<8)|0x41;    //sht_resp, wait_resp, start, CMD1		//-- Check end of CMD1		// 	if(Chk_CMDend(1, 1) & sdi->SDIRSP0==0x80ffc000)	//[31]:Card Power up status bit (busy)		//0xffc000 is Voltage window		if(Chk_CMDend(1, 1) && (sdi->SDIRSP0>>16)==0x80ff) 		{			sdi->SDICSTA=0xa00;	// Clear cmd_end(with rsp)			return 1;	// Success		}	}	sdi->SDICSTA=0xa00;	// Clear cmd_end(with rsp)	return 0;		// Fail}int Chk_SD_OCR(void){	S3C2410_SDI * const sdi = S3C2410_GetBase_SDI();	int i;	//-- Negotiate operating condition for SD, it makes card ready state	for(i=0;i<50;i++)	//If this time is short, init. can be fail.	{		CMD55();    // Make ACMD		sdi->SDICARG=0xff8000;	//ACMD41(SD OCR:2.7V~3.6V)		sdi->SDICCON=(0x1<<9)|(0x1<<8)|0x69;//sht_resp, wait_resp, start, ACMD41		//-- Check end of ACMD41		if( Chk_CMDend(41, 1) & (sdi->SDIRSP0==0x80ff8000) )		{			sdi->SDICSTA=0xa00;	// Clear cmd_end(with rsp)			return 1;	// Success	    		}		udelay(20000); // Wait Card power up status	}	sdi->SDICSTA=0xa00;	// Clear cmd_end(with rsp)	return 0;		// Fail}int CardBusWidth;void SetBus(void){	S3C2410_SDI * const sdi = S3C2410_GetBase_SDI();SET_BUS:	CMD55();	// Make ACMD	//-- CMD6 implement	sdi->SDICARG=CardBusWidth<<1;	    	//Width 0: 1bit, 1: 4bit	sdi->SDICCON=(0x1<<9)|(0x1<<8)|0x46;	//sht_resp, wait_resp, start, CMD55	if(!Chk_CMDend(6, 1))   // ACMD6		goto SET_BUS;	sdi->SDICSTA=0xa00;	    // Clear cmd_end(with rsp)}

⌨️ 快捷键说明

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