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

📄 flash.c

📁 详细介绍了arm7-at91r40008,的开发全过程
💻 C
字号:
/*------------------------------------------------------------------*/
/*模块名称:flash.c            	                                	*/
/*模块功能:flash底层驱动程序						    			*/
/*编写日期:2004年9月                                         		*/
/*编写者:  zxd														*/
/*------------------------------------------------------------------*/

#include "../ucos_ii/includes.h"




/*------------------------------------------------------------------*/
/*函数名称:FlashisEmpty()											*/
/*函数功能:检查flash是否为空										*/
/*输入说明:base--flash基址;sector--检查的扇区						*/
/*输出说明:为空时返回TRUE											*/
/*------------------------------------------------------------------*/
BOOL FlashisEmpty(u_int base, u_char sector)
{
	u_int	c, offset;
	u_int	aa;
	u_int	SECTOR_SIZE;	
	
	if (sector >= SECTOR_NUM) 
		return FALSE;
	
	if(sector<8)	//前8个扇区
	{
		SECTOR_SIZE = 0x1000;
		offset = sector*SECTOR_SIZE;
	}
	else if(sector<39)	//后31个扇区
	{
		SECTOR_SIZE = 0x8000;
		offset = 8*0x1000 + (sector-8)*SECTOR_SIZE;
	}
	else		//整片flash
	{
		SECTOR_SIZE = 0x100000;
		offset = 0;
	}
	
	IDExit(base);
	for(c=0; c<SECTOR_SIZE; c++,offset++)
	{
		aa = REG16(base+(offset<<1));
		if(aa != 0xffff)
			return FALSE;
	}
	
	return TRUE;
}

/*------------------------------------------------------------------*/
/*函数名称:FlashErase()											*/
/*函数功能:扇区擦除,不成功重擦,最多擦三遍						*/
/*输入说明:base--flash基址;sector--扇区							*/
/*输出说明:成功返回TRUE											*/
/*------------------------------------------------------------------*/
BOOL FlashErase(u_int base,u_char sector)
{
	BOOL	rc = TRUE, flag = FALSE;
	u_char	i;
	u_int	offset;

	if (sector > SECTOR_NUM) 
		return FALSE;
		
	if(sector<8)	//前8个扇区
	{
		offset = sector*0x1000;
	}
	else if(sector<39)	//后31个扇区
	{
		offset = 8*0x1000 + (sector-8)*0x8000;
	}
	else		//整片flash
	{
		offset = 0;
		flag = TRUE;
	}

	for (i=0; i<2; i++)
	{
		if (rc)
		{
			rc = FlashisEmpty(base, sector);
			if (rc)
			{
				IDExit(base);
				return (TRUE);
			}
		}
		
		rc = FlashEraseCore(base, offset, flag);
	}
	
	IDExit(base);
	return (FALSE);
}

/*------------------------------------------------------------------------
 Procedure:     FlashEraseCore ID:1
 Purpose:       扇区擦除[可以代替整片擦除,时间相同,更灵活]
 Input:         base:基址;sector:扇区号[从0计数].
 Output:		0: 成功
 Errors:        
------------------------------------------------------------------------*/
BOOL FlashEraseCore(u_int base, u_int offset, BOOL flag)
{	
	flash_word	value, value_new;

	REG16(base+(0x555<<1)) = (0xAAAA);
	REG16(base+(0xAAA<<1)) = (0x5555);
	REG16(base+(0x555<<1)) = (0x8080);
	REG16(base+(0x555<<1)) = (0xAAAA);
	REG16(base+(0xAAA<<1)) = (0x5555);	
	if (flag)
		REG16(base+(0x555<<1)) = (0x1010);
	else
		REG16(base+(offset<<1)) = (0x3030);

	value = REG16(base+(offset<<1));
	while(1)
	{
				
		value_new = REG16(base+(offset<<1));
		if((value & 0x44) == (value_new & 0x44))
			break;
			
		if (value_new & (DQ5 | DQ3))
		{
			value = REG16(base+(offset<<1));
			value_new = REG16(base+(offset<<1));
			if((value & 0x44) == (value_new & 0x44))
				break;
			else
			{				
				IDExit(base);
				return FALSE;
			}
		}			
		value = value_new;
	}

	IDExit(base);
	return TRUE;
}

/*------------------------------------------------------------------------
 Procedure:     FlashWrite ID:1
 Purpose:       写入[不考虑扇区擦除]
 Input:         base:基址;offset:偏移地址.
 Output:		
 Errors:        
------------------------------------------------------------------------*/
int FlashWrite(u_int base,u_int offset, u_char *pbuf, u_int count)
{
	u_int dd, c, rc;
	u_short val, tmp;
	flash_word value, value_new;

	rc = 0;	
	dd = (count + 1) / 2;
	for (c=0; c<dd; c++,offset+=2)
	{
		if ((count%2) && (c == (dd-1)))
		{
			val = *(pbuf+rc) | 0xFF00;
			rc++;			
		}
		else
		{
			val = *(pbuf+rc) | (*(pbuf+rc+1))<<8;
			rc+=2;			
		}
		
		REG16(base+(0x555<<1)) = 0xAAAA;
		tmp++;
		tmp++;
		REG16(base+(0xAAA<<1)) = 0x5555;
		tmp++;
		tmp++;
		REG16(base+(0x555<<1)) = 0xA0A0;
		tmp++;
		tmp++;
		REG16(base+(offset)) = val;
		tmp++;
		tmp++;

		value = REG16(base+(offset));
		tmp++;
		tmp++;
		tmp++;
		tmp++;
		while(1)
		{
			value_new = REG16(base+(offset));
			if((value & DQ6) == (value_new & DQ6)) 
				break;

			if (value_new & (DQ5 | DQ3))
			{
				value = REG16(base+(offset));
				tmp++;
				tmp++;
				tmp++;
				tmp++;
				value_new = REG16(base+(offset));
				if((value & DQ6) == (value_new & DQ6))
					break;
				else
				{				
					IDExit(base);
					return -1;
				}
			}
			value = value_new;									
		}
		
		//校验
		IDExit(base);
		value = REG16(base+(offset));
		if (val != value)
			return -1;
	}	
	
	return rc;
}
/*------------------------------------------------------------------------
 Procedure:     Flashread ID:1
 Purpose:       读出[不考虑扇区擦除]
 Input:         base:基址;offset:偏移地址.
 Output:		
 Errors:        
------------------------------------------------------------------------*/
int FlashRead(u_int base,u_int offset, u_char *pbuf, u_int count)
{
	u_int i, rc;
	u_short	val;
	
	IDExit(base);
	rc = 0;
	for(i=0; i<(count/2)*2; i+=2,offset+=2) 
	{
		rc += 2;
		val = REG16(base+(offset));
		 *(pbuf+i) = (u_char)(val & 0xFF);
		 *(pbuf+i+1) = (u_char)((val & 0xFF00) >>8);
	}
	if (count%2)
	{
		rc++;
		val = REG16(base+(offset));
		*(pbuf+i) = (u_char)(val & 0xFF);
	}	
	return rc;
}

/*------------------------------------------------------------------*/
/*函数名称:IDExit()												*/
/*函数功能:退出相关操作进入正常读模式								*/
/*输入说明:base--flash基址											*/
/*------------------------------------------------------------------*/
void IDExit(u_int base)
{
	
	REG16(base+(0x555)) = (0xAAAA);
	REG16(base+(0xAAA)) = (0x5555);
	REG16(base+(0x555)) = (0xF0F0);

}

/*------------------------------------------------------------------*/
/*函数名称:SetCFG()												*/
/*函数功能:设置flash模式											*/
/*输入说明:base--flash基址											*/
/*------------------------------------------------------------------*/
void SetCFG(u_int base)
{
	REG16(base+(0x555)) = (0xAAAA);
	REG16(base+(0xAAA)) = (0x5555);
	REG16(base+(0x555)) = (0xD0D0);
	REG16(base) = (0x0101);	
	IDExit(base);
}

/*------------------------------------------------------------------*/
/*函数名称:Read_Manufactuer_Code()									*/
/*函数功能:读出falsh出厂信息										*/
/*输入说明:base--flash基址											*/
/*------------------------------------------------------------------*/
int Read_Manufactuer_Code(u_int base)
{
	int Manufactuer,Code;

	REG16(base+(0x555<<1)) = (0xAAAA);
	REG16(base+(0xAAA<<1)) = (0x5555);
	REG16(base+(0x555<<1)) = (0x9090);
		
	Manufactuer = REG16(base);
	Code = REG16(base + 2);
	
	REG16(base) = (0xF0F0);	
	return (Manufactuer + (Code<<8));
}

void ReadCFI(u_int base, INT16U* pData)
{
	INT16U	i;
	
	REG16(base+(0x55<<1)) = (0x9898);
	
	for (i=0; i<37; i++)
	{
		pData[i] = REG16(base + ((i+0x10)<<1));
	}
	
	IDExit(base);
}



int SectorCpy(u_char DSector, u_char SSector)
{
	u_int	size;
	u_int	saddr, daddr;
	
	if (((SSector<8) && (DSector>=8)) || ((SSector>=8) && (DSector<8)))
		return (0);
	
	if (SSector<8)
	{
		size = 0x2000;
		saddr = SSector * 0x2000;
		daddr = DSector * 0x2000;
	}
	else
	{
		size = 0x10000;
		saddr = SSector * 0x10000;
		daddr = DSector * 0x10000;
	}
	return (FlashCpy(daddr, saddr, size));
}


int FlashCpy(u_int Daddr, u_int Saddr, u_int count)
{
	u_int	offset;
	u_int	i, base;
	u_short	tmp;
	flash_word	val, value, value_new;
	
	base = FLASH_BASE;
	IDExit(base);
		
	offset = 0;
	for(i=0; i<(count+1)/2; i++,offset+=2) 
	{

		IDExit(base);
		val = REG16(base + Saddr +(offset));
		REG16(base+(0x555<<1)) = 0xAAAA;
		tmp++;
		REG16(base+(0xAAA<<1)) = 0x5555;
		tmp++;
		REG16(base+(0x555<<1)) = 0xA0A0;
		tmp++;
		REG16(base + Daddr + offset) = val;
		tmp++;
		REG16(base) = 0x3030;
		tmp++;
		value = REG16(base + Daddr + offset);
		tmp++;
		tmp++;
		tmp++;
		tmp++;
		while(1)
		{
				
			value_new = REG16(base + Daddr + offset);
			if((value & 0x40) == (value_new & 0x40)) 
				break;
						
			if (value_new & (DQ5 | DQ3))
			{
				value = REG16(base + Daddr + offset);
				tmp++;
				tmp++;
				tmp++;
				tmp++;
				value_new = REG16(base + Daddr + offset);
				if((value & 0x40) == (value_new & 0x40))
					break;
				else
				{				
					IDExit(base);
					return -1;
				}
			}
			value = value_new;									
		}
		
		IDExit(base);
	}	
	
	return (offset);

}

⌨️ 快捷键说明

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