am29lv160.c

来自「arm7 s3c44b0x开发板fs44b的bios启动源代码及使用说明 下载方」· C语言 代码 · 共 340 行

C
340
字号
#include "../inc/def.h"
#include "../inc/config.h"
#include "../inc/utils.h"
#include "../inc/board.h"

#ifdef	AM29LV160_SUPPORT

//#define	ROM_BASE	0x10000000	//地址重定向到0x10000000
//#define	CMD_ADDR0	*((volatile U16 *)(0x5555*2+ROM_BASE))
//#define	CMD_ADDR1	*((volatile U16 *)(0x2aaa*2+ROM_BASE))

#define	CHECK_DELAY	150000

static U16 state;
static U16 support;
static U32 chip_id; 

/*static U32 ChkAddr;
static int ChkD6Stat(void)
{	
	return ((inportw(ChkAddr)^inportw(ChkAddr))&0x40);
}
*/

static void CFIQueryExit(void)
{
	outportw(0xaaaa, ROM_BASE+0xaaaa);//CMD_ADDR0 = 0xaaaa;
	outportw(0x5555, ROM_BASE+0x5554);//CMD_ADDR1 = 0x5555;
	outportw(0xf0f0, ROM_BASE+0xaaaa);//CMD_ADDR0 = 0xf0f0;
	state &= 0xfc;	
}

static void SWPIDExit(void)
{
	outportw(0xf0f0, ROM_BASE+0xaaaa);//CMD_ADDR0 = 0xf0f0;
	state &= 0xfc;
}

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

	outportw(0xaaaa, ROM_BASE+0xaaaa);//CMD_ADDR0 = 0xaaaa;
	outportw(0x5555, ROM_BASE+0x5554);//CMD_ADDR1 = 0x5555;
	outportw(0x9090, ROM_BASE+0xaaaa);//CMD_ADDR0 = 0x9090;
	state |= 3;
}

static U32 GetFlashID(void)
{
	U32 i;
	
	SWPIDEntry();
	//i  = *(U16 *)(0x0+ROM_BASE);
	//i |= (*(U16 *)(2+ROM_BASE))<<16;
	i  = inportw(ROM_BASE);
	i |= inportw(ROM_BASE+2)<<16;
	SWPIDExit();
	return i;	
}


/******************************************************************************
[功能说明] 扇区删除操作
******************************************************************************/
static int SectorErase(U32 sector)
{
	U32 rd;
		
	if(state&1) 
	{
		if(state&2)
			SWPIDExit();
		else
			CFIQueryExit();						
	}
	
	sector += ROM_BASE;
	
	outportw(0xaaaa, ROM_BASE+0xaaaa);
	outportw(0x5555, ROM_BASE+0x5554);
	outportw(0x8080, ROM_BASE+0xaaaa);
	outportw(0xaaaa, ROM_BASE+0xaaaa);
	outportw(0x5555, ROM_BASE+0x5554);
	outportw(0x3030, sector);	
	
/*	d2 = inportw(sector);
	while(1) 
	{
		d1 = d2;
		d2 = inportw(sector);
		if((d1^d2)&(0x40))//D6 == D6
		{
			if(d2&0x20)//DQ5 == 1
			{
				if((inportw(sector)^inportw(sector))&(0x40))//D6==D6
					return -1;
				else
					return 0;
			}
			continue;
		}
		
		if(inportw(sector) == 0xffff) //D7 == 1
		{
			return 0;
		}
	}*/
	while(1)
	{
		rd = inportw(sector);
		if(rd == 0xffff)
		{
			return 0;
		}
		if(rd & 0x20)//DQ5=1
		{
			if(inportw(sector) == 0xffff)
				return 0;
			else
				return -1;
		}
	}
}

/******************************************************************************
【功能说明】从指定地址 ProgStart 开始,将 WordCnt 个来自指针 DataPtr 的数据编程到Flash
******************************************************************************/
static int FlashProg(U32 ProgStart, U16 *DataPtr, U32 WordCnt)
{	
	U32 rd1, rd2;
	
	ProgStart += ROM_BASE;
	for( ; WordCnt; ProgStart+=2, DataPtr++, WordCnt--) 
	{
		//如果数据是 0xFFFF 时,继续下一个数据
		if(*DataPtr == 0xffff)
			continue;
		outportw(0xaaaa, ROM_BASE+0xaaaa);
		outportw(0x5555, ROM_BASE+0x5554);
		outportw(0xa0a0, ROM_BASE+0xaaaa);
		outportw(*DataPtr, ProgStart);

		rd2 = inportw(ProgStart);
		while(1) 
		{
			rd1 = rd2;
			rd2 = inportw(ProgStart);
			if((rd1^rd2)&(0x40))//D6 == D6
			{
				if(rd2&0x20)//DQ5 == 1
				{
					if((inportw(ProgStart)^inportw(ProgStart))&(0x40))//D6==D6
						return -1;
					else
						break;
				}
			} 
			else if(inportw(ProgStart) == *DataPtr) //success
			{
				break;
			}
		}
		
/*		while(1)
		{
			rd = inportw(ProgStart); 
			if(rd == *DataPtr)
			{
				break;
			}
			if(rd & 0x20)//DQ5 == 1
			{
				if(inportw(ProgStart)==*DataPtr)
					break;
				else
					return -1;
			}
		}*/
	}
	return 0;
}

/******************************************************************************
【功能说明】从指定扇区 src 开始,将 size 个数据读取到指定的指针 des 中 (已取消)
******************************************************************************/
/*
void NorFlashRead(U32 dst, U32 src, U32 size)
{
	int i;
	U32 src_add = src;
	U32 tmp = 0x1000-(src&0xfff);
	if(support)	
	{
		if((src > ROM_SIZE) || (src & 1)) 
		{
			printf("Invalid flash address, the address is from 0~0x%x, 16Bits aligned\n", ROM_SIZE);
			return;
		}
	
		if(tmp > size)
			tmp = size;
		if(tmp & 1)
			tmp++;
		for(i = 0; i < tmp; i++)
		{
			*(char *)dst = inportw(src_add); 
			dst++;
			src_add += 2;
		}
	}	
}*/

/******************************************************************************
【功能说明】从指定扇区 dst 开始,将size个来自指针 src 的数据编程到Flash
******************************************************************************/
void NorFlashProg(U32 dst, U32 src, U32 size)
{
	char buf[0x1000];
	U32 tmp = 0x1000-(dst&0xfff);
	int err;
	U32 start_addr = 0;
	if(support)	
	{
		if((dst > ROM_SIZE) || (dst & 1)) 
		{
			printf("Invalid flash address, the address is from 0~0x%x, 16Bits aligned\n", ROM_SIZE);
			return;
		}
	
		if(tmp > size)
			tmp = size;
		if(tmp & 1)
			tmp++;
	
		while(size > 0)
		{
			if(tmp < 0x1000) 
			{
				NorFlashRead(buf, (dst&(~0xfff)), 0x1000);
				memcpy(buf+(dst&0xfff), (char *)src, tmp);
			} 
			else 
			{
				memcpy(buf, (char *)src, 0x1000);
			}

			//删除指定扇区中的数据
			if( (dst <= 0x3fff && dst - start_addr >= 0xffff ) || //SA0
				((dst >= 0x004000 && dst < 0x008000) && (dst - start_addr) >= 0xfff) ||//SA1-SA2
				(dst >= 0x010000) && (dst - start_addr) >= 0xffff)//SA3-SA34
			{
				start_addr = dst;
				err = SectorErase(dst&(dst < 0x010000 ? ~0xfff : ~0xffff));
				if(err) //4K Bytes boundary
				{	
					printf("\t\tErase 0x%x Fail!!!\n", dst&(~0xffff));
					return;
				}
			}
/*			err = SectorErase(dst&(~0xfff));
			if(err) //4K Bytes boundary
			{	
				printf("\t\tErase 0x%x Fail!!!\n", dst&(~0xfff));
				return;
			}
*/			
			
			//写入数据
			if(FlashProg(dst&~0xfff, (U16 *)buf, 0x1000>>1))
			{
				printf("Program 0x%x Fail!!! Error!!!\n", dst&(~0xfff));
			}
			else
			{
				printf("Program 0x%x OK\n", dst&(~0xfff));
			}
		
			size -= tmp;
			dst  += tmp;
			src  += tmp;
			tmp  = (size > 0x1000) ? 0x1000 : size;
		}	
	}
}
//*****************************************************************************

void NorFlashInit(void)
{
	chip_id = GetFlashID();
	
	support = 0;
	if( (chip_id==0x278200bf) ||
		(chip_id==0x22c400c2) ||
		(chip_id==0x234b00bf) ||
		(chip_id==0x224900c2) ||
		(chip_id==0x22490001))
	{
		support = 1;
	}
}
//*****************************************************************************

void NorFlashStatusRep(void)
{
	printf("Nor Flash ID is : %x\n", chip_id);
	if(support) 
	{		
		if(chip_id==0x278200bf)
			printf("SST39VF160 Found\n");
		if(chip_id==0x234b00bf)
			printf("SST39VF1601 Found\n");
		if(chip_id==0x22c400c2)
			printf("MX29LV160 (Top Boot Black) Found\n");
		if(chip_id==0x224900c2)
			printf("MX29LV160 (Bottom Boot Black) Found\n");
		if(chip_id==0x22c40001)
			printf("AM29LV160B/DB (Top Boot Black) Found\n");
		if(chip_id==0x22490001)
			printf("AM29LV160B/DB (Bottom Boot Black) Found\n");
	} 
	else
	{
		printf("Unknown Flash Type\n");
	}
}
//*****************************************************************************

//全局变量初始化
//void (*pNorFlashInit)(void) = NorFlashInit;
//void (*pNorFlashProg)(U32, U32, U32) = NorFlashProg;

#endif

⌨️ 快捷键说明

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