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

📄 sd.c

📁 blackfin平台实现对SD卡的支持
💻 C
字号:

/*****************************************************************************/
#include "sd.h"
/*****************************************************************************/
/****************************************************************************
* 名称 : sd_Init
* 功能 : 初始化SD卡,入口参数为设备号,可自行设置
* 入口参数 :iface
* 出口参数 :返回初始化状态
****************************************************************************/
esint8 sd_Init(hwInterface *iface)
{
	esint16 i;
	euint8 resp;
	i=100;
	do
	{
		sd_Command(iface,0, 0, 0);
		resp=sd_Resp8b(iface);
	}
	while(resp!=1 && i--);
	if(resp!=1)
	{
		if(resp==0xff)
		{
		return(-1);
		}
		else
		{
			sd_Resp8bError(iface,resp);
			return(-2);
		}
	}
	i=32000;
	do
	{
		sd_Command(iface,1, 0, 0);
		resp=sd_Resp8b(iface);
		if(resp!=0)
		sd_Resp8bError(iface,resp);
	}
	while(resp==1 && i--);
	if(resp!=0)
	{
		sd_Resp8bError(iface,resp);
		return(-3);
	}	
	return(0);
}
/****************************************************************************
* 名称 : sd_Command
* 功能 : 写命令,分两次将命令送入
* 入口参数 :paramx,paramy
* 出口参数 :无
****************************************************************************/
void sd_Command(hwInterface *iface,euint8 cmd, euint16 paramx, euint16 paramy)
{
	if_spiSend(iface,0xff);
	if_spiSend(iface,0x40 | cmd);
	if_spiSend(iface,(euint8) (paramx >> 8)); /* MSB of parameter x */
	if_spiSend(iface,(euint8) (paramx)); /* LSB of parameter x */
	if_spiSend(iface,(euint8) (paramy >> 8)); /* MSB of parameter y */
	if_spiSend(iface,(euint8) (paramy)); /* LSB of parameter y */
	if_spiSend(iface,0x95); /* Checksum (should be only valid for first command (0) */
	if_spiSend(iface,0xff); /* eat empty command - response */
}
/****************************************************************************
* 名称 : sd_Resp8b
* 功能 : 读取一个字节,送入设备号
* 入口参数 :iface
* 出口参数 :无
****************************************************************************/
euint8 sd_Resp8b(hwInterface *iface)
{
	euint8 i;
	euint8 resp;
	for(i=0;i<8;i++)
	{
		resp = if_spiSend(iface,0xff);
		if(resp != 0xff)
		return(resp);
	}	
	return(resp);
}
/****************************************************************************
* 名称 : sd_Resp16b
* 功能 : 读取两个个字节,送入设备号
* 入口参数 :iface
* 出口参数 :无
****************************************************************************/
euint16 sd_Resp16b(hwInterface *iface)
{
	euint16 resp;
	resp = ( sd_Resp8b(iface) << 8 ) & 0xff00;
	resp |= if_spiSend(iface,0xff);	
	return(resp);
}
/****************************************************************************
* 名称 : sd_Resp8bError
* 功能 : 送入错误代码value,打印错误信息
* 入口参数 :iface,value
* 出口参数 :无
****************************************************************************/
void sd_Resp8bError(hwInterface *iface,euint8 value)
{
	switch(value)
	{
		case 0x40:
			printf("Argument out of bounds.\n");
			break;
		case 0x20:
			printf("Address out of bounds.\n");
			break;
		case 0x10:
			printf("Error during erase sequence.\n");
			break;
		case 0x08:
			printf("CRC failed.\n");
			break;
		case 0x04:
			printf("Illegal command.\n");
			break;
		case 0x02:
			printf("Erase reset (see SanDisk docs p5-13).\n");
			break;
		case 0x01:
			printf("Card is initialising.\n");
			break;
		default:
			printf("Unknown error 0x%x (see SanDisk docs p5-13).\n",value);
			break;
	}
}
/****************************************************************************
* 名称 : sd_State
* 功能 : 打印卡状态
* 入口参数 :iface
* 出口参数 :返回状态
****************************************************************************/
esint8 sd_State(hwInterface *iface)
{
	short value;	
	sd_Command(iface,13, 0, 0);
	value=sd_Resp16b(iface);
	switch(value)
	{
		case 0x000:
			return(1);
		case 0x0001:
			printf("Card is Locked.\n");
			break;
		case 0x0002:
			printf("WP Erase Skip, Lock/Unlock Cmd Failed.\n");
			break;
		case 0x0004:
			printf("General / Unknown error -- card broken?.\n");
			break;
		case 0x0008:
			printf("Internal card controller error.\n");
			break;
		case 0x0010:
			printf("Card internal ECC was applied, but failed to correct the data.\n");
			break;
		case 0x0020:
			printf("Write protect violation.\n");
			break;
		case 0x0040:
			printf("An invalid selection, sectors for erase.\n");
			break;
		case 0x0080:
			printf("Out of Range, CSD_Overwrite.\n");
			break;
		default:
			if(value>0x00FF)
				sd_Resp8bError(iface,(unsigned char ) (value>>8));
			else
				printf("Unknown error: 0x%x (see SanDisk docs p5-14).\n",value);
			break;
	}
	return(-1);
}
/****************************************************************************
* 名称 : sd_writeSector
* 功能 : 写SD卡扇区,送入设备号,要写的扇区地址,将buf中的数据写入该扇区
* 入口参数 :iface,address,buf
* 出口参数 :返回状态
****************************************************************************/
esint8 sd_writeSector(hwInterface *iface,euint32 address, euint8* buf)
{
	euint32 place;
	euint16 i;
	euint16 t=0;
	place=512*address;
	sd_Command(iface,CMDWRITE, (euint16) (place >> 16), (euint16) place);
	sd_Resp8b(iface); /* Card response */
	if_spiSend(iface,0xfe); /* Start block */
	for(i=0;i<512;i++) 
	if_spiSend(iface,buf[i]); /* Send data */
	if_spiSend(iface,0xff); /* Checksum part 1 */
	if_spiSend(iface,0xff); /* Checksum part 2 */
	if_spiSend(iface,0xff);
	while(if_spiSend(iface,0xff)!=0xff)
	{
		t++;
	}
	return(0);
}
/****************************************************************************
* 名称 : sd_readSector
* 功能 : 读取SD卡数据,送入设备号iface,要读取的扇区地址address,读取的长度len,将读到的数据送入buf
* 入口参数 :iface,address,buf,len
* 出口参数 :返回状态
****************************************************************************/
esint8 sd_readSector(hwInterface *iface,euint32 address, euint8* buf, euint16 len)
{
	euint8 cardresp;
	euint8 firstblock;
	euint8 c;
	euint16 fb_timeout=0xffff;
	euint32 i;
	euint32 place;
	place=512*address;
	sd_Command(iface,CMDREAD, (euint16) (place >> 16), (euint16) place);
	cardresp=sd_Resp8b(iface); /* Card response */ 
	do
		firstblock=sd_Resp8b(iface); 
	while(firstblock==0xff && fb_timeout--);
	if(cardresp!=0x00 || firstblock!=0xfe)
	{
		sd_Resp8bError(iface,firstblock);
		return(-1);
	}
	for(i=0;i<512;i++){
	c = if_spiSend(iface,0xff);
	if(i<len)
		buf[i] = c;
	}
	if_spiSend(iface,0xff);
	if_spiSend(iface,0xff);
	return(0);
}
/****************************************************************************
* 名称 : sd_getDriveSize
* 功能 : 获得drive_size
* 入口参数 :iface,drive_size
* 出口参数 :返回0
****************************************************************************/
esint8 sd_getDriveSize(hwInterface *iface, euint32* drive_size )
{
	euint8 cardresp, i, by;
	euint8 iob[16];
	euint16 c_size, c_size_mult, read_bl_len;	
	sd_Command(iface, CMDREADCSD, 0, 0);
	do  {
		cardresp = sd_Resp8b(iface);
		} while ( cardresp != 0xFE );
	printf("CSD:");
	for( i=0; i<16; i++) 
	{
		iob[i] = sd_Resp8b(iface);
		printf("%02x", iob[i]);
	}
	printf("\n");
	if_spiSend(iface,0xff);
	if_spiSend(iface,0xff);
	c_size = iob[6] & 0x03; // bits 1..0
	c_size <<= 10;
	c_size += (euint16)iob[7]<<2;
	c_size += iob[8]>>6;
	by= iob[5] & 0x0F;
	read_bl_len = 1;
	read_bl_len <<= by;
	by=iob[9] & 0x03;
	by <<= 1;
	by += iob[10] >> 7;
	c_size_mult = 1;
	c_size_mult <<= (2+by);
	*drive_size = (euint32)(c_size+1) * (euint32)c_size_mult * (euint32)read_bl_len;
	return 0;
}

⌨️ 快捷键说明

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