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

📄 39vf160.c

📁 Nor Flash的读、写、擦除、编程等操作函数
💻 C
字号:
#include  "config.h"

#define	ROM_BASE	0x80083000 //0x8009C000         
#define	INROM_BASE	0x80008000 
//#define	ROM_BASE	0x8007D000+0x8000  //test //0x800B5000+0x8000 	//地址重定向到  //数据区+显示字库区  
#define	CMD_BASE    0x80000000
#define	CMD_ADDR0	*((volatile uint16 *)(0x5555*2+CMD_BASE))  //+ROM_BASE
#define	CMD_ADDR1	*((volatile uint16 *)(0x2aaa*2+CMD_BASE))  //+ROM_BASE

#define	FLASH_MAXCYCLES  100000       //100ms

uint8 write_flag;
uint8 state;




void CFIQueryExit(void)
{
	CMD_ADDR0 = 0xaaaa;
	CMD_ADDR1 = 0x5555;
	CMD_ADDR0 = 0xf0f0;
	state &= 0xfc;	
}

void SWPIDExit(void)
{
	CMD_ADDR0 = 0xf0f0;
	state &= 0xfc;
}


void CFIQueryEntry(void)
{
	if(state&1)
	{
		if(state&2)
			SWPIDExit();
		else
			return;
	}
	
	CMD_ADDR0 = 0xaaaa;
	CMD_ADDR1 = 0x5555;
	CMD_ADDR0 = 0x9898;
	state |= 1;	
}

void SWPIDEntry(void)
{
	if(state&1)
	{
		if(state&2)
			return;
		else
			CFIQueryExit();
	}

	CMD_ADDR0 = 0xaaaa;
	CMD_ADDR1 = 0x5555;
	CMD_ADDR0 = 0x9090;
	state |= 3;
}

uint32 GetFlashID(void)
{
	uint32 i;
	
	SWPIDEntry();
	i  = *(uint16 *)(0+ROM_BASE);
	i |= (*(uint16 *)(2+ROM_BASE))<<16;
	SWPIDExit();
	return i;	
}

void GetFlashCFI(uint16 *DataPtr)
{
	uint16 i;
	
	CFIQueryEntry();
	for(i = 0x10; i<0x35; DataPtr++, i++)
		*DataPtr = *(uint16 *)(i*2+ROM_BASE);	
	CFIQueryExit();
}

void ChipErase(void)
{
	if(state&1)
	{
		if(state&2)
			SWPIDExit();
		else
			CFIQueryExit();						
	}
	
	CMD_ADDR0 = 0xaaaa;
	CMD_ADDR1 = 0x5555;
	CMD_ADDR0 = 0x8080;
	CMD_ADDR0 = 0xaaaa;
	CMD_ADDR1 = 0x5555;
	CMD_ADDR0 = 0x1010;

	while(1)
	{
		uint16 i;
		i = *((volatile uint16 *)0x6666)&0x40;
		if(i!=*((volatile uint16 *)0x6666)&0x40)	//D6 == D6
			continue;
		if(*((volatile uint16 *)0x8888)&0x80)	
			break;						//D7 == 1
	}		
}
*/
uint8 SectorErase(uint32 sector)
{
    uint16 i;
    uint32 FlashTimeOut;
    uint32 flashSIntEnble;
	/*if(state&1)
	{
		if(state&2)
			SWPIDExit();
		else
			CFIQueryExit();						
	}*/
	if(sector > (0x001ff000-(ROM_BASE-CMD_BASE)))
    {
        return 0;
    }
	
	flashSIntEnble = VICIntEnable;
    VICIntEnClr = 0xffffffff;
	if(write_flag == 1)
	{	   	
		sector += ROM_BASE;	
		CMD_ADDR0 = 0xaaaa;
	    CMD_ADDR1 = 0x5555;
	    CMD_ADDR0 = 0x8080;
	    CMD_ADDR0 = 0xaaaa;
	    CMD_ADDR1 = 0x5555;
		*(volatile uint16 *)sector = 0x3030;
		
		FlashTimeOut = 0;
		while (1)	
		{
		    FlashTimeOut++;
		    if(FlashTimeOut > FLASH_MAXCYCLES)
			{
			    VICIntEnable = flashSIntEnble;
			    return 0;
			}	
			i = *((volatile uint16 *)sector)&0x40;
			if(i!=*((volatile uint16 *)sector)&0x40)	//D6 == D6
				continue;
			if(*((volatile uint16 *)sector)&0x80)	
				break;								//D7 == 1
		}
	
	}
	else 
	{
        VICIntEnable = flashSIntEnble;
	    return 0;
	}
    VICIntEnable = flashSIntEnble;
    return 1;		
  	
}
/*******************************************************************
函数名称: uint8 FlashProg(uint32 ProgStart, uint16 *DataPtr, uint32 WordCnt) 
函数功能: 编程地址
相关调用: 
					
入口参数: ProgStart:编程的起始位置
          DataPtr:要编程的数据指针
          WordCnt:要写的长度
          
返 回 值: 1 成功
          0 失败        
备    注:  
创建信息:	
修改信息:        
********************************************************************/
uint8 FlashProg(uint32 ProgStart, uint16 *DataPtr, uint32 WordCnt)   //wordcnt 表示字长
{
	uint16 i, j;	
	uint32 FlashTimeOut;
    uint32 flashSIntEnble;	
    
	if(write_flag == 1)
	{
        flashSIntEnble = VICIntEnable;
        VICIntEnClr = 0xffffffff;
        
		ProgStart += ROM_BASE;                                       //只能偶地址
		
		for( ; WordCnt; ProgStart+=2, DataPtr++, WordCnt--)
		{	
			j = *DataPtr;
			CMD_ADDR0 = 0xaaaa;
			CMD_ADDR1 = 0x5555;
			CMD_ADDR0 = 0xa0a0;
			*(volatile uint16 *)ProgStart = j;	
			
			FlashTimeOut = 0;
			while (1)	  
			{
			    FlashTimeOut++;
			    if(FlashTimeOut > FLASH_MAXCYCLES)
			    {
			        VICIntEnable = flashSIntEnble;
			        return 0;
			    }	
			    	
				i = *(volatile uint16 *)ProgStart&0x40;
				if(i!=*(volatile uint16 *)ProgStart&0x40)		//D6 == D6
					continue;
				if((*(volatile uint16 *)ProgStart&0x80)==(j&0x80))		//D7 == D7
					break;																		
			}
		}
		VICIntEnable = flashSIntEnble;
		return 1;
	}
	else 
	{
	   return 0;
	}
}

void FlashRead(unsigned int ReadStart, unsigned short *DataPtr, unsigned int Size)  //size 表示要读出的字节长
{
	int i;
//	uint32 flashSIntEnble;
	
//	flashSIntEnble = VICIntEnable;
//    VICIntEnClr = 0xffffffff;
    
	ReadStart += ROM_BASE;

	for(i=0; i<Size/2; i++)
	{
		*(DataPtr+i) = *((unsigned short *)ReadStart+i);	     //只能偶地址
    }
    
//    VICIntEnable = flashSIntEnble;		
	
}

	

void InFlashRead(unsigned int ReadStart, unsigned short *DataPtr, unsigned int Size)  //size 表示要读出的字节长
{
	int i;
//	uint32 flashSIntEnble;
	
//	flashSIntEnble = VICIntEnable;
//    VICIntEnClr = 0xffffffff;
    
	ReadStart += INROM_BASE;

	for(i=0; i<Size/2; i++)
	{
		*(DataPtr+i) = *((unsigned short *)ReadStart+i);	     //只能偶地址
    }
    
//    VICIntEnable = flashSIntEnble;		
	
}






/*******************************************************************
函数名称: uint8 SectorProg(uint32 begin, uint16 *data, uint32 size)
函数功能: 先擦后编程
相关调用: 
					
入口参数: begin:编程的起始位置
          DataPtr:要编程的数据指针
          WordCnt:要写的长度
          
返 回 值: 1 成功
          0 失败        
备    注:  
创建信息:	
修改信息:        
********************************************************************/
uint8 SectorProg(uint32 begin, uint16 *data, uint32 size)    //size 表示要写入的字节长
{	
    uint32 flashSIntEnble;
	uint32 tmp = 0x1000-(begin&0xfff);
	
	flashSIntEnble = VICIntEnable;
    VICIntEnClr = 0xffffffff;
	if(write_flag == 1)
	{
		if(tmp>size)
			tmp = size;
		
		for(; size;)
		{	                 
			if(0 == SectorErase(begin&0xfffff000))	//4K Bytes boudary	
			{
			   VICIntEnable = flashSIntEnble;		
			   return 0;
			}	
			if(0 == FlashProg(begin, data, tmp/2))
			{
			   VICIntEnable = flashSIntEnble;		
			   return 0;
			}	
			
			size  -= tmp;
			begin += tmp;
			data  += tmp/2;
			tmp = (size>0x1000)?0x1000:size;				
		}
	}
	else
	{
	   VICIntEnable = flashSIntEnble;		
	   return 0;
	}
	VICIntEnable = flashSIntEnble;		
	return 1;			
}


⌨️ 快捷键说明

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