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

📄 spi_sd.c

📁 嵌入式linux系统下hi3510平台的osd开发源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		tmp=sdcard_command2(CMD55);
		if(tmp !=1) 
			continue;
		tmp=sdcard_command1(ACMD41);
		if(timeout++>1000)
		{
			return 2;
		}
	}
 	
 	return 0;
}

/*
 * sdcard multiple block read routine.
 * @param addr: data address
 * @param buf : data buf
 * @param block_num: data block num
 * @param off: data offset address
 * @return value: 
 * 0-- sdcard read ok             1-- CMD18 send failture   
 * 2-- read ready state error     3-- read ready timeout error   
 * 4-- wait read ready ok flag tineout error    5-- CMD18 send failture   
 * 6-- wait sdcard free timeout error  10-- sdcard dma mode transfer failture
 *
 */
#ifdef CONFIG_SSP_DMA
unsigned int sdcard_read(unsigned int addr,unsigned int off,unsigned int block_num)
#else
unsigned int sdcard_read(unsigned int addr,unsigned char *buf,unsigned int block_num)
#endif
{
	 unsigned char CMD18[] = {0x52,0x00,0x00,0x00,0x00,0xFF};
	 unsigned char CMD12[] = {0x4c,0x00,0x00,0x00,0x00,0xFF};
	 unsigned int i=0,num=0,timeout=0;
	 unsigned char temp=0; 
	 
	#ifdef CONFIG_SSP_DMA
	DECLARE_WAITQUEUE(wait, current);
  #endif
  
	CMD18[1] = ((addr & 0xFF000000) >> 24); 
	CMD18[2] = ((addr & 0x00FF0000) >> 16); 
	CMD18[3] = ((addr & 0x0000FF00) >> 8); 

	sdcard_disable();
	for (i=0;i<64;i++)
	{ 
		sdcard_read_byte(); 
	} 
	
	temp=sdcard_command2(CMD18);
	if (temp!=0) 
        	return 1;
     	
	for(num=0;num<block_num;num++)
	{
		timeout=0;
		do{
			temp=sdcard_read_byte();
			if(temp == 15) 
				return(2);
			if(timeout++ > timeout_read) 
				return(3);
		}while (temp != 0xff);
		timeout=0;
		do{
			temp=sdcard_read_byte();
			if(timeout++ > timeout_read)
				return(4);
		}while(temp != 0xfe);
		
		#ifdef CONFIG_SSP_DMA
			sd_add_wait(&wait);
			if(hi_ssp_dmac_transfer((dmac_ssp_s.ssprxchbufaddress + off+512*num),dmac_ssp_temp_s.txbufaddress,0x200) !=0)
				return 10;
			schedule();
			sd_rm_wait(&wait);
		#else
			for(i=0;i<512;i++)
			{
				*(buf+i+512*num) = sdcard_read_byte(); 
			}
		#endif
		sdcard_read_byte();
		sdcard_read_byte();
		
	}    
	timeout=0;
	do{
		temp=sdcard_command2(CMD12); 
	    	if(timeout++ >10000)
	    	{
	    		return (5);
		}
	}while(temp!=0);
	timeout=0;
	do{
		temp=sdcard_read_byte();
		if(timeout++ > 10000) 
		{
			return(6);
		}
	}while (temp != 0xff);
	sdcard_disable(); 
	for(i=0;i<64;i++)
	{
		sdcard_read_byte();
	}

	return 0;
}

/*
 * sdcard multiple block write routine.
 * @param addr: data address
 * @param buf : data buf
 * @param block_num: data block num
 * @param off: data offset address
 * @return value: 
 * 0-- sdcard write ok     1-- CMD25 send failture   
 * 2-- wait ack error      3-- wait sdcard free timeout error   
 * 4-- wait sdcard write stop free timeout error     
 * 10-- sdcard dma mode transfer failture   
 *
 */
#ifdef CONFIG_SSP_DMA
unsigned int sdcard_write(unsigned int addr,unsigned int off,unsigned int block_num)
#else
unsigned int sdcard_write(unsigned int addr,unsigned char *buf,unsigned int block_num)
#endif
{
	unsigned char CMD25[] = {0x59,0x00,0x00,0x00,0x00,0x95}; 
	unsigned int  i=0,num=0,timeout=0;
	unsigned char temp;

#ifdef CONFIG_SSP_DMA
	DECLARE_WAITQUEUE(wait, current);
#endif

	CMD25[1] = ((addr & 0xFF000000) >> 24); 
	CMD25[2] = ((addr & 0x00FF0000) >> 16); 
	CMD25[3] = ((addr & 0x0000FF00) >> 8); 

	sdcard_disable();
	for (i=0;i<64;i++)
	{ 
		sdcard_read_byte(); 
	} 

	temp = sdcard_command2(CMD25); 
	if (temp!=0)
        	return 1;
	
     	for(num=0;num<block_num;num++)
	{
		sdcard_write_byte(0xFC);
		
		#ifdef CONFIG_SSP_DMA
			sd_add_wait(&wait);
			if(hi_ssp_dmac_transfer(dmac_ssp_temp_s.rxbufaddress,(dmac_ssp_s.ssptxchbufaddress + off+512*num),0x200) !=0)
				return 10;
			schedule();
			sd_rm_wait(&wait);
		#else
			for (i = 0; i < 512; i++) 
			{ 
				sdcard_write_byte(*(buf+i+512*num)); 
			} 
		#endif
		timeout=0;
    		do{
			temp=sdcard_read_byte();
			if(timeout++ >timeout_write)
			{
				return 2;
			}
    		}while (temp != 0xe5);
    		timeout=0;
    		do{
			temp=sdcard_read_byte();
			if(timeout++ >timeout_write)
			{
				return 3;
			}
    		}while(temp!=0xff);
	}
	
	
	sdcard_write_byte(0xFD);
	timeout=0;
	do{
		temp=sdcard_read_byte();
		if(timeout++ >1000)
		{
			return(4);
		}
	}while(temp!=0xff);

	sdcard_disable(); 
	
	for (i = 0; i < 64; ++i) 
	{ 
		sdcard_write_byte(0xFF);
	} 

	return 0;
}
/*
 * read sdcard cid routine.
 *
 * @return value: 
 * 0-- success; 1-- cmd10 send failture.
 * 2-- wait read ready ok flag tineout error
 *
 */
unsigned int sdcard_cid_read(void)
{
	unsigned int temp=0xff,i,timeout=0;
	unsigned char CMD10[]={0x4a,0x00,0x00,0x00,0x00,0x95};
	unsigned char cid[16];
	unsigned char mid;
	unsigned short oid;
	unsigned char pnm[5];
	unsigned char prv;
	unsigned int psn;
	unsigned short mdt;
	
  	sdcard_disable();
       
  	for(i=0;i<0xf;i++)
  	{
    		while (hi_ssp_busystate_check());
       		hi_ssp_writedata(0xff);
  	}
  	    
	while (hi_ssp_busystate_check());
   	hi_ssp_writedata(0xff);
	sdcard_enable();

	for(i=0;i<6;i++)
	{
		while (hi_ssp_busystate_check());
		hi_ssp_writedata(CMD10[i]);
	}
   
	while (temp != 0x0)
	{
	    	while (hi_ssp_busystate_check());
	       	hi_ssp_writedata(0xff);
		while (hi_ssp_busystate_check());
		temp = hi_ssp_readdata(); 
		if (timeout++ > 100)
		{
	 		sdcard_disable();
	 		return (1);
		}
	}

	while (temp != 0xfe)
	{
    		while (hi_ssp_busystate_check());
       		hi_ssp_writedata(0xff);
		while (hi_ssp_busystate_check());
		temp = hi_ssp_readdata(); 
		if (timeout++ > 100)
		{
	 		sdcard_disable();
	 		return (2);
		}
	}
	
	for(i=0;i<16;i++)
		cid[i]=sdcard_read_byte();
	sdcard_write_byte(0xFF);
	sdcard_write_byte(0xFF);
	for(i=0;i<16;i++)
	{
		sdcard_read_byte();
	}
	sdcard_disable(); 

	mid=cid[0];
	oid=cid[1]*256+cid[2];
	pnm[0]=cid[3+0];pnm[1]=cid[3+1];pnm[2]=cid[3+2];pnm[3]=cid[3+3];pnm[4]=cid[3+4];
	prv=cid[8];
	psn=cid[9]*256*256*256+cid[10]*256*256+cid[11]*256+cid[12];
	mdt=cid[13]*256+cid[14];mdt&=0x0fff;
	
	printk(" %c%c%c%c%c ",pnm[0],pnm[1],pnm[2],pnm[3],pnm[4]);
	
	return(0);
}
/*
 * read sdcard csd routine.
 *
 * @return value: 
 * 0-- sdcard capacity get error       size-- get sdcard capacity (Byte)
 *
 */
unsigned int sdcard_csd_read(void)
{
	unsigned int temp=0xff,i;
	unsigned char CMD9[]={0x49,0x00,0x00,0x00,0x00,0x95};
	unsigned char csd[32];
	unsigned int c_size;
	unsigned int c_size_mult;
	unsigned int mult;
	unsigned int read_bl_len;
	unsigned int blocknr = 0;
	unsigned int block_len = 0;
	unsigned int size = 0;
	unsigned int timeout=0;
	unsigned int taac=0,nsac=0,tmp;
	unsigned int read_timeout_100ms,write_timeout_250ms;
	unsigned char time_u, time_v, fator;
	struct clk *clk_temp;
	unsigned long ahb_clk,spi_clock;
	
  	sdcard_disable();
       
  	for(i=0;i<0xf;i++)
  	{
    		while (hi_ssp_busystate_check());
       		hi_ssp_writedata(0xff);
  	}
  	    
	while (hi_ssp_busystate_check());
   	hi_ssp_writedata(0xff);
	sdcard_enable();

	for(i=0;i<6;i++)
	{
		while (hi_ssp_busystate_check());
		hi_ssp_writedata((CMD9[i]));
	}
   
	while (temp != 0x0)
	{
		while (hi_ssp_busystate_check());
       		hi_ssp_writedata(0xff);
		while (hi_ssp_busystate_check());
		temp = hi_ssp_readdata(); 
		if (timeout++ > 100)
		{
	 		sdcard_disable();
	 		return (0);
		}
	}

	while (temp != 0xfe)
	{
		while (hi_ssp_busystate_check());
		hi_ssp_writedata(0xff);
		while (hi_ssp_busystate_check());
		temp = hi_ssp_readdata();
		if (timeout++ > 100)
		{
	 		sdcard_disable();
	 		return (0);
		}
	}
	
	for(i=0;i<16;i++)
		csd[i]=sdcard_read_byte();
	sdcard_write_byte(0xFF);
	sdcard_write_byte(0xFF);
	for(i=0;i<16;i++)
	{
		sdcard_read_byte();
	}
	sdcard_disable(); 

	c_size = csd[8] + csd[7] * 256 + (csd[6] & 0x03) * 256 * 256;
	c_size >>= 6;
	c_size_mult = csd[10] + (csd[9] & 0x03) * 256;
	c_size_mult >>= 7;
	read_bl_len = csd[5] & 0x0f;
	mult = 1;
	mult <<= c_size_mult + 2;
	blocknr = (c_size + 1) * mult;
	block_len = 1;
	block_len <<= read_bl_len;
	size = block_len * blocknr;
	taac = csd[1];
	nsac = csd[2];
	time_u = csd[1] & 0x07;
	time_v = (csd[1] & 0x78) >> 3;
	fator = (csd[12] & 0x1c) >> 3;
	
	if(time_v == 0)
	{
		printk("time_v = 0\n");
		return 0;
	}
	if(fator >= 6)
	{
		printk("fator >= 6\n");
	  return 0;
	}

clk_temp = clk_get(NULL,"AHBCLK");
ahb_clk = clk_get_rate(clk_temp);

#ifdef CONFIG_SSP_DMA
	spi_clock = ahb_clk/10;
#else 
	spi_clock = ahb_clk/6;
#endif

	if(spi_clock > 25000000)
	{
			printk("spi clock is more than 25MHZ!\n");
			return 0;
	}

  tmp = spi_clock * time_value[time_v] / 10 / time_unit[time_u];
	tmp = tmp + csd[2] * 100;	
	
	timeout_read = tmp;
	timeout_write = tmp * r2w_fator[fator];
	
	timeout_read = timeout_read * 100/8;	
	timeout_write = timeout_write * 100/8;
	
	read_timeout_100ms = 100 * (spi_clock/1000) / 8;
	write_timeout_250ms = 250 * (spi_clock/1000) / 8;


	if(timeout_read <	read_timeout_100ms)
			timeout_read = read_timeout_100ms;
	if(timeout_write < write_timeout_250ms)
			timeout_write = write_timeout_250ms;
	
		return(size);
}


⌨️ 快捷键说明

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