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

📄 sddriver.c

📁 基于S3C2440处理器的sd卡驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************Copyright (c)****************************************************                               Guangzhou ZHIYUAN electronics Co.,LTD.**                                     **                                 http://www.zyinside.com****--------------File Info-------------------------------------------------------------------------------** File Name: 				sddriver.c** Last modified Date: 		2006.01.09** Last Version:			V1.0		** Description: 			API funciton of initializ,read,write SD/MMC卡 **							初始化、读、写 SD/MMC卡的 API 函数**------------------------------------------------------------------------------------------------------** Created By: 				MingYuan Zheng 郑明远** Created date: 			2006.01.09** Version: 				V1.0** Descriptions:			The original version 初始版本****------------------------------------------------------------------------------------------------------** Modified by:** Modified date:** Version:** Description:**********************************************************************************************************/#include "drv_extr.h"#include "sd_extr.h"/* SD/MMC卡信息结构体变量 the information structure variable of SD/MMC Card */sd_struct sds = {0};			/* 超时时间单位表(单位:0.000000001ns) timeout unit table */const INT32U time_unit[8] = {1000000000,100000000,10000000,							 1000000,100000,10000,1000,100};/* 超时时间表 timeout value table */							 const INT8U time_value[16] = {0,10,12,13,15,20,25,30,                              35,40,45,50,55,60,70,80}; /* 超时时间因数表 timeout factor table */                              const INT8U r2w_fator[6] = {1,2,4,8,16,32};        /* 与中断相关的全局变量 global variable releated with interrupt */#if SD_INTERRUPT_ENstatic DECLARE_WAIT_QUEUE_HEAD(wq);volatile int reading;           /* 读卡(1)或写卡(1)状态 read card(1) or write card(1) status */INT8U *buffer;                  /* 读卡或写卡缓冲区 	the buffer of read or write card */INT32 bufcnt;                   /* 缓冲区计数器 		buffer counter */INT32 datalen;					/* 读卡或写卡数据长度   the data length of read or write card */volatile int error;#endif    volatile int card_insert = 1;int card_change = 0; 			/* 卡改变,卡插入开拔出 */        volatile INT16U card_id = 0;		/* card slot identify, added 20060330 */    	/*       	***************************************************************************************************			     用户API函数:  初始化,读,写,擦 SD卡  User API Function: Initialize,read,write,erase SD Card 					***************************************************************************************************	*/char *m[12] = 		{"Jan", "Feb", "Mar", "Api", "May", "Jun", "Jul","Aug","Sep", "Oct","Nov","Dec"		};char *tm_unit[] = {	"1ns", "10ns", "100ns", "1us", "10us","100us","1ms","10ms"};char *tm_val[] = {	"Reserved","1.0", "1.2", "1.3","1.5", "2.0", "2.5", "3.0","3.5","4.0","4.5",	"5.0", "5.5", "6.0","7.0","8.0"		};char *rate_unit[]={	"100kbit/s", "1Mbit/s", "10Mbit/s", "100Mbit/s"};char *curr_min[] ={	"0.5mA", "1mA", "5mA", "10mA", "25mA", "35mA", "60mA", "100mA"};char *curr_max[] ={	"1mA", "5mA", "10mA", "25mA", "35mA", "45mA", "80mA", "200mA"	};char *file_format[] = {	"Hard disk-like file system with partition table",	"DOS FAT (floppy-like) with boot sector only (no partition table)",	"Universal File Format",	"Others / Unknown"};char *vtg[]={0,0,0,0,"1.6-1.7", "1.7-1.8", "1.8-1.9", "1.9-2.0", "2.0-2.1", "2.1-2.2", "2.2-2.3",	 "2.3-2.4", "2.4-2.5", "2.5-2.6", "2.6-2.7", "2.7-2.8", "2.8-2.9", "2.9-3.0", "3.0-3.1"	, "3.1-3.2", "3.2-3.3", "3.3-3.4", "3.4-3.5", "3.5-3.6"};volatile int RCA;		void SD_print_info(sd_struct *sds){	int i;	Uart_Printf("\r\n\r\n SD|MMC Card Information \r\n\r\n" );	Uart_Printf("Manufacturer ID			:%d\r\n", sds->MID);	Uart_Printf("OEM/Application ID			:%d\r\n", sds->OID);	Uart_Printf("Product name				:%s\r\n", sds->PNM);	Uart_Printf("Product revision			:%d.%d\r\n", (sds->PRV>>4), sds->PRV & 0xf);	Uart_Printf("Product Serial NUmber		:0x%x\r\n", sds->PSN);	Uart_Printf("Manufacturing date			:%s %d\r\n" ,m[sds->MDT&0xf], ((sds->MDT>>4) & 0xff) + 2000);	Uart_Printf("CSD structure version		:%s\r\n", (sds->CSD_stuc ? "NULL" : "Version 1.0"));	Uart_Printf("data read access time -1	:%s.%s\r\n", tm_unit[sds->TAAC & 0x3], tm_val[(sds->TAAC & 0x7f) >> 3]);	Uart_Printf("data read access time -2	:%d k clock cycles\r\n", sds->NSAC * 100);	Uart_Printf("max data transfer rate		:%s.%s\r\n", rate_unit[sds->NSAC & 0x3], tm_val[(sds->NSAC & 0x7f) >> 3]);	Uart_Printf("card command classes supported	:");	for(i=0;i<12;i++)	{		if((sds->CCC >> i) & 0x1)			Uart_Printf("Class%d  ",i);	}	Uart_Printf("\r\n");	Uart_Printf("VDD voltage Window 		:");	for(i=4; i<25; i++)	{		if( (sds->vtg_win >> i) & 0x1 )			Uart_Printf("%s  ",vtg[i]);	}	Uart_Printf("\r\n");	Uart_Printf("Relative Card Address		:%d\r\n", sds->RCA);	Uart_Printf("Max read data block length	:%d\r\n", 0x1 << sds->read_bl_len );	Uart_Printf("partial block for read allowed(allways = 1 in SD Memory Card) :%d\r\n", sds->read_bl_partial);	Uart_Printf("Write block misalignment	:%s\r\n", sds->write_blk_mis ? "crossing physical boundaries is allowed":"crossing physical boundaries is invalid");	Uart_Printf("Read block misalignment 	:%s\r\n", sds->read_blk_mis ? "crossing physical boundaries is allowed":"crossing physical boundaries is invalid");	Uart_Printf("DSR implemented			:%s\r\n", sds->dsr_imp ? "DSR Implemented":"No DSR");	Uart_Printf("Device_size(C_size)		:%d\r\n", sds->C_size);	Uart_Printf("R/W min current			:%s\r\n", curr_min[sds->vdd_r_curr_min]);	Uart_Printf("R/W max current			:%s\r\n", curr_max[sds->vdd_r_curr_max]);	Uart_Printf("MULT						:%d\r\n", (1 << (sds->C_Size_mult+2)) );	Uart_Printf("Erase Block Enable			:%d\r\n", sds->erase_blk_en);	Uart_Printf("Sector Size				:%d\r\n", sds->sector_size);	Uart_Printf("Size of Write Group		:%d\r\n", sds->wp_grp_size);	Uart_Printf("Write Group Enable			:%d\r\n", sds->wp_grp_enable);	Uart_Printf("R2W Factor					:%d\r\n", sds->r2w_factor);	Uart_Printf("Write Block Size			:%d\r\n", (1<<sds->write_bl_len) );	Uart_Printf("WRITE_BL_PARTIAL			:%d\r\n", sds->write_bl_partial);	Uart_Printf("File Format Group			:%d\r\n", sds->file_format_grp);	Uart_Printf("Copy						:%s\r\n", sds->copy ? "Copied":"Original");	Uart_Printf("Permanently Write Protect	:%d\r\n", sds->perm_write_pro);	Uart_Printf("Temperal Write Protect		:%d\r\n", sds->tmp_write_pro);	Uart_Printf("File Format				:%s\r\n", file_format[sds->file_format]);	Uart_Printf("---------Capacity of SD is	:%d\r\n", (sds->C_size+1)*(1 << (sds->C_Size_mult+2)) * (1<<sds->read_bl_len));}	/*********************************************************************************************************** Function name: SD_Initialize** Descriptions:  initialize SD/MMC card**                初始化SD/MMC卡	** Input: 		  sd_struct *sds: SD卡信息结构体 	sd_struct *sds: the information structure of SD Card** Output: 		  0:   正确    >0:   错误码		  		0:  right		>0:  error code  ** Created by:    MingYuan Zheng 郑明远 ** Created Date:  2006-01-09 **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/INT8U SD_Initialize(sd_struct *sds){	INT8U response[16], ret;	SD_HardWareInit();					    		/* 1. 初始化SD/MMC接口硬件   Initialize the hardware of SD/MMC interface */    ret = SD_ResetSD();   	if (ret!= SD_NO_ERR)							/* 2. 发出CMD0命令复位SD卡   send CMD0 command to reset SD/MMC card */        return ret;									 	 	sds->card_type = Card_Indentify();				/* 3. 判别卡的型号:SD或MMC卡 identify card type: SD or MMC card */					 		ret = SD_ActiveCard(sds);						/* 4. 激活SD/MMC卡			 active SD/MMC card */	if (ret != SD_NO_ERR)		return ret;	  	    	ret = SD_ReadAllCID(16, response);  			/* 5. 请所有卡发送CID寄存器  ask all card send their CID number */  	if (ret != SD_NO_ERR)  		return ret;  	/* cid information */	{		sds->MDT = ((response[2] & 0xf)<<8) | response[1];		sds->PSN = (response[6] << 24) + (response[5] << 16) + (response[4] << 8) + response[3];		sds->PRV = response[7];		sds->PNM[0] = response[8];		sds->PNM[1] = response[9];		sds->PNM[2] = response[10];		sds->PNM[3] = response[11];		sds->PNM[4] = response[12];		sds->PNM[5]	= 0;		sds->OID	=	response[14] << 8 + response[13];		sds->MID 	=	response[15];	}	  	if (sds->RCA == 0)  	{  	    card_id++;		  	    sds->RCA = card_id;								/* 给卡分配一个地址  assign a address */ 	}    	  		    ret = SD_GetRCA(sds->card_type, &sds->RCA);			/* 6. 得到卡的RCA  			 get the RCA of the card */   	if (ret != SD_NO_ERR)  		return ret;           ret = SD_GetCardInfo(sds);						    /* 7. 读CSD寄存器,获取SD卡信息 	  read CSD register, get the information of SD card */    if (ret != SD_NO_ERR)       return ret;	    SD_ClkToMax();										/* 8. 设置读/写SD/MMC时钟到最大值 set clock of reading or writing SD/MMC to maximum */	ret = SD_SetBlockLen(sds->RCA, SD_BLOCKSIZE);		    return ret;											/* 9. 设置块的长度: 512Bytes 	  Set the block length: 512Bytes */}/*********************************************************************************************************** Function name: SD_ReadBlock** Descriptions:  read a block from SD/MMC card**                从SD/MMC卡中读出一个块,先选中卡,然后设置数据控制寄存器,接着发送读块命令,				  最后从数据缓冲区读取数据** Input: 		  sd_struct *sds  : SD/MMC卡信息结构体 			sd_struct *sds  : the information structure of SD/MMC Card				  INT32U blockaddr: 块地址          			INT32U blockaddr: the address of the block				  INT8U *recbuf   : 接收缓冲区,长度512Bytes		INT8U *recbuf   : the buffer of receive,length is 512Bytes** Output: 		  1:   成功    > 0:  错误码						1:  sucessfully	 > 0:  error code   ** Created by:    MingYuan Zheng 郑明远 ** Created Date:  2006-01-09 **-------------------------------------------------------------------------------------------------------** Modified by:	** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/INT8U SD_ReadBlock_1(sd_struct *sds, int blockaddr, int blocknum, INT8U *buf){	int rd_cnt = 0;	INT8U ret,status[4];	INT32U stat = 0;	//Uart_Printf("\r\n[MultiBlock read test]\n\r");	ret = SD_ReadCard_Status(sds->RCA, 4, status);	/* 读取卡的状态  	  	read the status of the card */	if (ret != SD_NO_ERR)		return ret;				ret = SD_SelectCard(sds->RCA);					/* CMD7,进入传输状态  	CMD7, enter tranfer status */    if (ret != SD_NO_ERR)    	return ret;    	  	if (sds->card_type == CARDTYPE_SD)	    {												/* 卡为SD卡           	card is SD card */   		ret = SD_SetBusWidth(sds->RCA, 1);    		/* 设置卡为数据总线方式 set card to wide data bus  */    	if (ret != SD_NO_ERR)    		return ret;     }		SDIBSIZE = SD_BLOCKSIZE;  	/* 复位 FIFO			reset FIFO */	SDIFSTA= SDIFSTA|(1<<16);	//为什么多块读取总是从第一块读取呢	SDIDCON=(00<<22)|(1<<19)|(1<<17)|(1<<16)|(1<<14)|(2<<12)|(blocknum<<0);	//YH 040220	ret = SD_ReadMultipleBlock(blockaddr);			/* 读单块命令 			read single blocks command */							if (ret != SD_NO_ERR) 		return ret;		SDICSTA=0xa00;	// Clear cmd_end(with rsp)	  	//Uart_Printf("\r\n");	//Uart_Printf("%d Block\r\n", blockaddr++);    while(rd_cnt<512*blocknum)	// 512*block bytes    {		if((SDIDSTA&0x20)==0x20) // Check timeout 		{		    SDIDSTA=(0x1<<0x5);  // Clear timeout flag		    break;		}		stat=SDIFSTA;		if((stat&0x1000)==0x1000)	// Is Rx data?		{			//int temp;			//temp = SDIDAT;			//Uart_Printf("0x%02x ", (temp>>24)&0xff);			//Uart_Printf("0x%02x ", (temp>>16)&0xff);			//Uart_Printf("0x%02x ", (temp>>8)&0xff);		    //Uart_Printf("0x%02x ", temp&0xff);		    		    //Uart_Printf("0x%02x ", SDIDAT8);			//*(buf+rd_cnt) = SDIDAT8;			buf[rd_cnt] = SDIDAT8;			rd_cnt++;		/*				if( (rd_cnt & 0xf) == 0 )			{				Uart_Printf("\r\n");			}			if((rd_cnt & 0x1ff) == 0 )			{				Uart_Printf("\r\n%d Block\r\n", blockaddr++);			}					*/					}		    }	SD_StopTransmission();  	ret = SD_DeSelectCard();						/* CMD7, 退出传输状态 */	return ret;	}INT8U SD_ReadBlock(sd_struct *sds, INT32U blockaddr, INT8U *recbuf){	INT8U ret,status[4];		ret = SD_ReadCard_Status(sds->RCA, 4, status);	/* 读取卡的状态  	  	read the status of the card */	if (ret != SD_NO_ERR)		return ret;				ret = SD_SelectCard(sds->RCA);					/* CMD7,进入传输状态  	CMD7, enter tranfer status */    if (ret != SD_NO_ERR)    	return ret;   	  	if (sds->card_type == CARDTYPE_SD)	    {												/* 卡为SD卡           	card is SD card */   		ret = SD_SetBusWidth(sds->RCA, 1);    		/* 设置卡为数据总线方式 set card to wide data bus  */    	if (ret != SD_NO_ERR)    		return ret;     }		SDIBSIZE = SD_BLOCKSIZE;  	/* 复位 FIFO			reset FIFO */	SDIFSTA= SDIFSTA|(1<<16);	SDIDCON=(00<<22)|(1<<19)|(1<<17)|(1<<16)|(1<<14)|(2<<12)|(1<<0);	//YH 040220	ret = SD_ReadSingleBlock(blockaddr);			/* 读单块命令 			read single blocks command */							if (ret != SD_NO_ERR) 		return ret;	SDICSTA=0xa00;	// Clear cmd_end(with rsp)	  	/// read data 	ret = SD_ReadBlockData(SD_BLOCKSIZE, recbuf, sds->timeout_read);	  	if (ret != SD_NO_ERR)												  		return ret;  	  	ret = SD_DeSelectCard();						/* CMD7, 退出传输状态 */  		    return SD_NO_ERR;	}/*********************************************************************************************************** Function name: SD_WriteBlock** Descriptions:  write a block to SD/MMC card**                向SD/MMC卡中写入一个块	** Input: 		  sd_struct *sds  : SD/MMC卡信息结构体 			sd_struct *sds  : the information structure of SD/MMC Card				  INT32U blockaddr: 块地址          			INT32U blockaddr: the address of the block				  INT8U *sendbuf  : 发送缓冲区,长度512Bytes	  	  INT8U *sendbuf  : the buffer of send,length is 512Bytes** Output: 		  1:   成功    > 0:  错误码						1:  sucessfully	 > 0:  error code   ** Created by:    MingYuan Zheng 郑明远 ** Created Date:  2006-01-09 **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/INT8U SD_WriteBlock(sd_struct *sds, INT32U blockaddr, const INT8U *sendbuf){	INT8U ret,tmp[4];		ret = SD_ReadCard_Status(sds->RCA, 4, tmp);		/* 读取卡的状态  	  	read the status of the card */	if (ret != SD_NO_ERR)		return ret;	ret = SD_SelectCard(sds->RCA);					/* CMD7,进入传输状态  	CMD7, enter tranfer status */    if (ret != SD_NO_ERR)    	return ret;	  	if (sds->card_type == CARDTYPE_SD)	    {												/* 卡为SD卡           	card is SD card */   		ret = SD_SetBusWidth(sds->RCA, 1);    		/* 设置卡为数据总线方式 set card to wide data bus  */	    	if (ret != SD_NO_ERR)    		return ret; 

⌨️ 快捷键说明

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