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

📄 intl_flash.c

📁 pxa270 NOR FLASH驱动代码
💻 C
字号:
#include <stdio.h>
#include "systypes.h"
#include "utils.h"

typedef unsigned short U16;
typedef unsigned int   U32;

#include "norflash.h"

/***************************************************************************
Function name: memcpy
Parameter    : *s1:目的地址 *s2:源地址 n:要拷贝的数据的长度
Description  : 将长度为n的数据拷贝从源地址拷贝到目的地址
Return	     : void
Argument     : 
Autor & date :
****************************************************************************/
void memcpy(void *s1, const void *s2, int n)
{
	int i;

	for (i = 0; i < n; i++)
		((char *)(s1))[i] = ((const char *)(s2))[i];
}
#define	NorFlashRead(dst, src, size)	memcpy((char *)(dst), (char *)(ROM_BASE+(src)), (int)(size))

#define	out_l(v, a)	(*(volatile U32 *)(a) = (v))
#define	in_l(a)		(*(volatile U32 *)(a))

#define	ROM_BASE		0

static U32 FlashSize;
static void ReadArray(void)
{
	out_l(0x00ff00ff, ROM_BASE);
}

static void ClrStatus(void)
{
	out_l(0x00500050, ROM_BASE);
}

static int ReadStatus(void)
{
	int ret;
	
	out_l(0x00700070, ROM_BASE);
	ret = in_l(ROM_BASE);
	ReadArray();
	return ret;
}
/*
static int GetBlkProtStat(U32 addr)
{
	addr &= ~0x3ffff;
	out_l(0x00900090, ROM_BASE+addr+8);
	return in_l(ROM_BASE+addr+8)&0x10001;
}
*/
static int LockBlk(U32 addr)
{
	int ret;
	
	addr &= ~0x3ffff;
	out_l(0x00600060, ROM_BASE);
	out_l(0x10001, ROM_BASE+addr);
	do {
		ret = ReadStatus();
	} while((ret&0x00800080)!=0x00800080);
	ClrStatus();
	
	printf("Lock Block 0x%x ", addr);
	if(ret&0x1a) {
		printf("Fail, status=%x\n", ret);
		return -1;
	}
	printf("OK\n");
	return 0;
}

int UnlockAllBlks(void)
{
	int ret;
	
	out_l(0x00600060, ROM_BASE);
	out_l(0x00d000d0, ROM_BASE);
	do {
		ret = ReadStatus();
	} while((ret&0x00800080)!=0x00800080);
	ClrStatus();
	
	printf("Unprotect All Blocks\n");
	if(ret&0x002a002a) {
		printf("Fail, status=%x\n", ret);
	}
	printf("OK\n");
	return 0;
}

static int EraseBlk(U32 addr)
{
	int ret;
	
	addr &= ~0x3ffff;
	addr += ROM_BASE;
	out_l(0x00200020, addr);
	out_l(0x00d000d0, addr);
	do {
		ret = ReadStatus();
	} while((ret&0x00800080)!=0x00800080);
	ClrStatus();
	
	printf("Erase Block 0x%x ", addr);
	if(ret&0x006a006a) {
		printf("Fail, status=%x\n", ret);
		return -1;	
	}
	printf("OK\n");
	return 0;
}

static int ProgramBlk(U32 addr, U32 src, U32 len)
{
	int ret;
	U32 i;
	
	addr += ROM_BASE;
	
/*	for(i=0; i<len; i+=4) {
		out_l(0x00400040, addr+i);
		out_l(*(U32 *)(src+i), addr+i);
		do {
			ret = ReadStatus();
		} while((ret&0x00800080)!=0x00800080);
		ClrStatus();
		
		if(ret&0x1e) {
			printf("Program addr 0x%x Fail, status=%x\n", addr, ret);
			return -1;
		}
	}
*/	
	for(i=0; i<len; i+=64) {
		int j;
		do {
			out_l(0x00e800e8, addr);
			ret = in_l(ROM_BASE);//ReadStatus();
		} while((ret&0x00800080)!=0x00800080);
		out_l(0x000f000f, addr);
		for(j=0; j<16; j++)
			out_l(*(U32 *)(src+i+j*4), addr+i+j*4);
		out_l(0x00d000d0, addr);
		do {
			ret = ReadStatus();
		} while((ret&0x00800080)!=0x00800080);
		ClrStatus();
		
		if(ret&0x001e001e) {
			printf("Program addr 0x%x Fail, status=%x\n", addr, ret);
			return -1;
		}		
	}
		

	ReadArray();
	for(i=0; i<len; i+=4)
		if(in_l(addr+i)!=*(U32 *)(src+i)) {
			printf("Program addr 0x%x Fail, wr=0x%x, rd=0x%x\n", addr+i, *(U32 *)(src+i), in_l(addr+i));			
			return -1;
		}
	
	ret = 0;//LockBlk(addr);
	
	return ret;
}

void ProgNorFlash(U32 addr, U32 src, U32 len)
{
	U32 prog_len;
	
	if((addr&0x3ffff)||(src&3)) {
		printf("Flash Address Must Be 256KBytes And Source Address Must Be 4Bytes aligned\n");
		return;
	}
	if(!len) {
		printf("Write 0 Bytes!\n");
		return;
	}
	if(UnlockAllBlks())
		return;
//	ReadArray();
	for(; len; ) {
		show_led(0x1, addr&0x40000);
		prog_len = (len>0x40000)?0x40000:len;		
		EraseBlk(addr);
//		ReadArray();
		//printf("data at 0x%x = 0x%x\n", addr, in_l(ROM_BASE+addr));
		//printf("data at 0x%x = 0x%x\n", src,  *(U32 *)(src));
		if(ProgramBlk(addr, src, prog_len))
			break;//return;
//		ReadArray();
		//for(i=0; i<prog_len; i+=4)
		//	printf("%x\n", in_l(addr+i));
		addr += prog_len;
		src  += prog_len;
		len  -= prog_len;
	}
	show_led(0x1, 0);
}

int ChkNorFlash(void)
{
	U32 id;
	
	out_l(0x00900090, ROM_BASE);
	id = in_l(ROM_BASE);		
	printf("NOR Flash Man. ID is 0x%x\n", id);
	if(id==0x00890089) {
		printf("Intel Flash Found With 32 Bits Bus Width\n");
	} else {
		printf("Unsupported Flash Type!\n");
		return -1;
	}
	
	out_l(0x00900090, ROM_BASE+4);
	id = in_l(ROM_BASE+4);
	
	ReadArray();
	
	printf("NOR Flash Dev. ID is 0x%x\n", id);
	id &= 0xffff;
	if(id==0x16) {
		FlashSize = 4;	//4MBytes
	} else if(id==0x17) {
		FlashSize = 8;	//8MBytes
	} else if(id==0x18) {
		FlashSize = 16;	//16MBytes		
	} else {
		puts("Unsupported Intel Flash Type!\n");
		return -1;
	}
	printf("Total FlashSize = 2x%d = %dMBytes\n", FlashSize, 2*FlashSize);
	return 0;
}

/***************************************************************/
int BaseAddr=0x1f00000;//Nor Flash Write/Read Address
void TestNorFlash(void)
{
	char data[256];
	int i;
	ChkNorFlash();
	for(i=0;i<64;i++)
		data[i]=i;
	printf("Write data\n");
	for(i=0;i<64;i++)
	{
		printf("%4x",data[i]);
		if(!((i+1)%16))
			printf("\n");
	}
	
	//将data数组烧写到BaseAddr地址
	ProgNorFlash(BaseAddr,(U32)data,64);
	printf("Read data\n");
	for(i=0;i<64;i++)
		data[i]=0;
		
	//将BaseAddr地址数据读到data数组
	NorFlashRead(data,BaseAddr,64);
	for(i=0;i<64;i++)
	{
		printf("%4x",data[i]);
		if(!((i+1)%16))
			printf("\n");
		if(data[i]!=i)
			printf("Data Error\n");
	}
	
	if(i==64)printf(" \nRead/Write is OK\n");
	getchar();
}

⌨️ 快捷键说明

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