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

📄 norflash.c

📁 spansion公司的NorFlash:s29al004d的驱动代码。16位读取方式。在东芝32位CPU:TMP92ca25上调试通过。NorFlash的驱动方式基本上相同
💻 C
字号:

#include "basic.h"
#include "Drivers\flash\NorFlash.h"

#define FLASH_START		0xf80000

#define TOP_BOOT 1
#define BOTTOM_BOOT 0

#if TOP_BOOT
const unsigned long SECTOR[] = 
{
	0x0,0x8000,0x10000,0x18000,0x20000,0x28000,0x30000,0x38000,0x3C000,0x3D000,0x3E000,0x40000
};
#elif BOTTOM_BOOT
const unsigned long SECTOR[] =
{
	0x0,0x2000,0x3000,0x4000,0x8000,0x10000,0x18000,0x20000,0x28000,0x30000,0x38000,0x40000
}
#endif

//#define USE_ASM

//#ifndef USE_ASM

//#pragma section code bios_code
//#pragma section const bios_const

/*
function:   short ByteWriteFlash(DWORD addr,DWORD len,BYTE *buf)
parameter:  addr: write address len: read len buf: write buffer 
return:     1:succeed 0:failure
remark:     write the data into the address
 addr:this is a byte address
*/
unsigned short ByteWriteFlash(DWORD addr,DWORD len,BYTE *buf)
{
	unsigned long chip_addr=0;
	unsigned short * address;
	volatile unsigned short *p;
	DWORD i,j;
	WORD flag=OK;
	WORD tmp;
	BYTE dummy1, dummy2;
	BYTE flag1=0, flag2=0;
	DWORD index=0;
	
	chip_addr=(unsigned long)FLASH_START;
	p =  (volatile unsigned short *)FLASH_START; 
		
	if( addr%2 )
	{
		address = (WORD*)(chip_addr+addr-1);
		ByteReadFlash( addr-1, 1L, &dummy1 );
		len++;
		flag1 = 1;
	}
	else
	{
		address = (WORD*)(chip_addr+addr);
	}
	
	if(len%2 )
	{
		ByteReadFlash( addr+len, 1L, &dummy2 );
		flag2 = 1;
		len-=1;
	}
        
	if( flag1 )
	{
		tmp = (WORD)buf[index++]<<8;
		tmp = (tmp&0xFF00)|(WORD)dummy1;
		p[0x555] = 0xaa; 
		__asm("nop");
		p[0x2AA] = 0x55;
		__asm("nop");
		p[0x555] = 0xa0;
		__asm("nop");
		*address = tmp;
		__asm("nop");
		__asm("nop");
	
		for(j=0; j<0x10; j++);

		flag = FlashDataToggle(address);
		if(flag!=OK) return flag;

		address++;
		len-=2;
	} 	

	for(i=0;i<len;i=i+2)
	{
		tmp = (WORD)buf[index++]&0x00FF;
		tmp |=(WORD)buf[index++]<<8;
		
		p[0x555] = 0xaa; 
		__asm("nop");
		p[0x2AA] = 0x55;
		__asm("nop");
		p[0x555] = 0xa0;
		__asm("nop");
		*address = tmp;
		__asm("nop");
		__asm("nop");
		
		for(j=0; j<0x10; j++);

		flag = FlashDataToggle(address);
		if(flag!=OK) return flag;
		address++;
	}
	
	if( flag2 )
	{
		tmp = (WORD)dummy2<<8;
		tmp = (tmp&0xFF00)|(WORD)buf[index++];
		
		p[0x555] = 0xaa; 
		__asm("nop");
		p[0x2AA] = 0x55;
		__asm("nop");
		p[0x555] = 0xa0;
		__asm("nop");
		*address = tmp;
		__asm("nop");
		__asm("nop");
		
		for(j=0; j<0x10; j++) ;
		flag = FlashDataToggle(address);
		if(flag!=OK) return flag;
	}   
	FlashReset();//reset the chip
	return OK;
}


/*
function:   short ByteReadFlash(DWORD addr,DWORD len,BYTE *buf)
parameter:  addr: read address len: read len buf: read buffer 
return:     1:succeed 0:failure
remark:     read the data from the address
 addr:this is a byte address
*/
unsigned short ByteReadFlash(DWORD addr,DWORD len,BYTE *buf)
{
	unsigned long i;
	unsigned long chip_addr=0;
	volatile unsigned short * address;
		
	register tmp;
	BYTE flag1=0;
	BYTE flag2=0;
	
	chip_addr=(unsigned long)FLASH_START;
	
	if(addr%2)
	{
		address = (volatile unsigned short *)(chip_addr+addr-1);
		flag1 = 1;
		
		tmp = *address++;
		*buf++ = (BYTE)((tmp>>8)&0x00FF);
		len-=1;
	}
	else
	{
		address = (volatile unsigned short *)(chip_addr+addr);
	}
	
	if( len%2 )
	{
		flag2 = 1;
		len-=1;
	}
	
	for(i=0;i<len;i=i+2)
	{
		*((unsigned short *)buf)=*address++;
		buf+=2;
	}
        
	if(flag2)
	{
		*buf++ = (BYTE)(*address&0x00FF);
	}

	return OK;
}

//#endif   //#ifndef USE_ASM

/*
function:   WordReadFlash(DWORD addr,DWORD len,WORD *buf)
parameter:  addr: read address len: read len buf: read buffer 
return:     1:succeed 0:failure
remark:     read the data from the address
 addr:this is a word address
*/
unsigned short WordReadFlash(DWORD addr,DWORD len,WORD *buf)
{
	volatile unsigned short * address;
	DWORD i;

	address = (volatile unsigned short *)FLASH_START;
	address += addr;
	for(i=0;i<len;i++)
	{
		*buf = *address;
		address++;
		buf++;
	}
	return OK;
}

/*
function:   short WordWriteFlash(DWORD addr,DWORD len,WORD *buf)
parameter:  addr: write address len: read len buf: write buffer 
return:     1:succeed 0:failure
remark:     write the data into the address
 addr:this is a word address
*/
unsigned short WordWriteFlash(DWORD addr,DWORD len,WORD *buf)
{
	volatile unsigned short * p;
	volatile unsigned short * address;
	short flag;
	DWORD i,j;
	
	unsigned char value=0;
	p =  (volatile unsigned short *)FLASH_START; 
	address = p + addr;

	for(i=0;i<len;i++)
	{
		p[0x555] = 0xaa; 
		__asm("nop");
		p[0x2AA] = 0x55;
		__asm("nop");
		p[0x555] = 0xa0;
		__asm("nop");
		*address = *buf;
		__asm("nop");
		__asm("nop");
		
		buf++;
		address++;
		
		for(j=0; j<0x10; j++);

		flag = FlashDataToggle(address);
		if(flag!=OK) return flag;
	}
	FlashReset();//reset the chip
	return OK;
}

unsigned short ReadDeviceCode(void)
{
	volatile unsigned short * p;
	unsigned short manu_id,device_id; 
	p =  (volatile unsigned short *)FLASH_START; 
	p[0x555] = 0xaa; 
	__asm("nop");
	p[0x2AA] = 0x55;
	__asm("nop");
	p[0x555] = 0x90;
	__asm("nop");
	//manu_id = p[0x00];
	//__asm("nop");
	device_id = p[0x01];
	__asm("nop");
	p[0x00] = 0xf0;
	return device_id;
}
/*
function:   void FlashReset()
parameter:  None
return:     None
remark:     reset the chip
*/
void FlashReset(void)
{
    volatile unsigned short * p;
	p=(volatile unsigned short *)FLASH_START;
	*p=0xf0;
}

/*
function:   short EraseBlock3(unsigned long addr )
parameter:  addr: address
return:     None
remark:     Erase the block
 this is a word address
*/
unsigned short EraseBlock(DWORD addr)
{
	volatile unsigned short *p;
	unsigned short i;
	 
	p = (volatile unsigned short *)FLASH_START;
		
	p[0x555] = 0xaa;// First cycle
	__asm("nop");
	p[0x2AA] = 0x55;// Second cycle
	__asm("nop");
	p[0x555] = 0x80;// Third cycle
	__asm("nop");
	p[0x555] = 0xaa;// Fourth cycle
	__asm("nop");
	p[0x2AA] = 0x55;// Fifth cycle
	__asm("nop");				
	p[addr] = 0x30;	// Sixth cycle
	__asm("nop");
	__asm("nop");

	for(i=0; i<0x20; i++) ;//delay
	return FlashDataToggle(p+addr);
}

/*
function:  short EraseChip()
parameter: None
return:    0:succeed 1:failure
remark:    Erase the chip
*/
unsigned short EraseChip(void)
{
	volatile unsigned short *p;
	unsigned short i;
	 
	p = (unsigned short volatile *)FLASH_START;
		
	p[0x555] = 0xaa;// First cycle
	__asm("nop");
	p[0x2AA] = 0x55;// Second cycle
	__asm("nop");
	p[0x555] = 0x80;// Third cycle
	__asm("nop");
	p[0x555] = 0xaa;// Fourth cycle
	__asm("nop");
	p[0x2AA] = 0x55;// Fifth cycle
	__asm("nop");				
	p[0x555] = 0x10;// Sixth cycle
	__asm("nop");
	__asm("nop");
		
	for(i=0; i<0x20; i++) ;//delay 
	
	return FlashDataToggle(p);
}

/*
function:  short FlashErase(DWORD addr,DWORD len)
parameter: None
return:    0:failure 1:succeed
remark:    
 this is a word address
*/
unsigned short FlashErase(DWORD addr,DWORD len)
{
	short i;
	short rtn;
	short SectorNum;
	short StartSec,EndSec;
	
	SectorNum = 12;//sizeof(SECTOR)/sizeof(unsigned long);
	for(i=0; i< SectorNum ; i++)
	{
		if( addr<SECTOR[i] ) 
		{
			StartSec = i-1;
			break;
		}
	}
	if(i==SectorNum) return FAIL; 

	addr = addr + len -1;
	for(i=0; i< SectorNum ; i++)
	{
		if( addr<SECTOR[i] ) 
		{
			EndSec = i-1;
			break;
		}
	}
	if(i==SectorNum) return FAIL; 
	
	for(i=StartSec;i<=EndSec;i++)
	{
		rtn = EraseBlock(SECTOR[i]);
		if(rtn!=OK) return rtn;
	}
	return OK; 
}

/*
function:  short FlashDataToggle(volatile unsigned short * address)
parameter: None
return:    0:failure 1:succeed
remark:    judge whether the program/erase operation complete
*/
unsigned short FlashDataToggle(volatile unsigned short * address)
{
	unsigned short uc1,uc2;

	while(1)
	{
		uc1 = *address;//read twice
		__asm("nop");
		uc2 = *address;
		__asm("nop");
		if((uc1&0x40)==(uc2&0x40))//if ToggleBit not togging,succeed
		{
			FlashReset();//reset the chip
			return OK;
		}
		if((uc2&0x20)==0x20) break;//if d5 is 1? 
	}
	uc1 = *address;//read twice
	__asm("nop");
	uc2 = *address;
	__asm("nop");
	if((uc1&0x40)==(uc2&0x40))//if ToggleBit not togging,succeed
	{
		FlashReset();//reset the chip
		return OK;
	}
	FlashReset();
	return FAIL;
}

⌨️ 快捷键说明

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