AMD flash擦除和编程源代码 2008-10-24 23:23
说明:这是参考相关资料,xiyong8260的编写的flash擦除和编程源代码
CPU:PPC8260,
操作系统:vxworks
FLASH:AMD29LV256,使用片选2,16bit数据接口,基地址设置为0x50000000,该FLASH的块大小为0x10000,64K
该flash编程的关键点:16位数据读写地址的变换,wait函数的实现
/*****************************************************************************************************************
flash erase and prog code
Author: xiyong8260
****************************************************************************************************************/
#define ULONG unsigned long
#define UWORD unsigned short
#define FLASH2_ADDR 0x50000000 /*flash2 use CS2*/
#define FLASH3_ADDR 0x54000000 /*flash3 use CS4**/
#define ST16554_ADDR 0x60000000 /*16554,use CS5*/
#define CPLD_ADDR 0x61000000 /*16554,use CS6*/
/*初始化PPC8260的内存BANK,使得能够正常访问FLASH*/
void init_memory()
{
*(ULONG *)(IMMR_ADDR+BR2_ADDR)= FLASH2_ADDR + 0x1001; /*16bit wide */
*(ULONG *)(IMMR_ADDR+OR2_ADDR)= 0xfc000954; /*32MB*/
*(ULONG *)(IMMR_ADDR+BR4_ADDR)= FLASH3_ADDR + 0x1001; /*16bit wide*/
*(ULONG *)(IMMR_ADDR+OR4_ADDR)= 0xfc000954; /*32MB*/
*(ULONG *)(IMMR_ADDR+BR5_ADDR)= ST16554_ADDR + 0x0801; /*8bit wide*/
*(ULONG *)(IMMR_ADDR+OR5_ADDR)= 0xfff00856; /*1M*/
*(ULONG *)(IMMR_ADDR+BR6_ADDR)= CPLD_ADDR + 0x0801; /*8bit wide*/
*(ULONG *)(IMMR_ADDR+OR6_ADDR)= 0xfff00856; /*1M*/
}
/*flash test*/
ULONG FLASH_ADDR=FLASH2_ADDR;
#define _WR(addr,data) *((UWORD *)((addr<<1)+FLASH_ADDR))=(UWORD)data
#define _RD(addr) ( *((UWORD *)((addr<<1)+FLASH_ADDR)) )
#define _RESET() _WR((0x0),0xf0f0)
#define BADDR2WADDR(addr) (addr>>1)
/*WAIT函数的实现,判断FLASH是否完成操作*/
int _WAIT(void) /*Check if the bit6 toggle ends.*/
{
volatile UWORD flashStatus,old;
int i;
old=*((volatile UWORD *)(0x0+FLASH_ADDR));
while(1)
{
flashStatus=*((volatile UWORD *)(0x0+FLASH_ADDR));
if( (old&0x40) == (flashStatus&0x40) )break;
if( flashStatus&0x20 )
{
old=*((volatile UWORD *)(0x0+FLASH_ADDR));
flashStatus=*((volatile UWORD *)(0x0+FLASH_ADDR));
if( (old&0x40) == (flashStatus&0x40) )
return 0;
else
return 1;
}
old=flashStatus;
}
return 1;
}
/*擦除一块flash,输入参数为该块的起始地址*/
void EraseSector(unsigned long targetAddr)
{
int level;
printf("Sector Erase from %x is started!/n",targetAddr);
level = intLock();
_RESET();
_WR(0x555,0xaaaa);
_WR(0x2aa,0x5555);
_WR(0x555,0x8080);
_WR(0x555,0xaaaa);
_WR(0x2aa,0x5555);
_WR(BADDR2WADDR(targetAddr),0x3030);
_WAIT();
_RESET();
intUnlock(level);
}
int BlankCheck(unsigned long targetAddr, unsigned long targetSize)
{
unsigned long i,j;
for(i=0;i
j=*((UWORD *)(i+targetAddr+FLASH_ADDR));
if( j!=0xffff)
{
printf("E:%x=%x/n",(i+targetAddr+FLASH_ADDR),j);
return 0;
}
}
return 1;
}
/*以word为单位写入flash*/
int ProgFlash(unsigned long realAddr,UWORD data)
{
volatile UWORD *tempPt; /*???为什么定义一个多余的tempPt?*/
tempPt=(volatile UWORD *)(realAddr+FLASH_ADDR);
_WR(0x555,0xaaaa);
_WR(0x2aa,0x5555);
_WR(0x555,0xa0a0);
*tempPt=data;
return _WAIT();
}
/*多数据的写入,写入前需要保证该数据区域是空的,也就是0XFF*/
int ChipProg(unsigned long romAddr,unsigned long ramAddr, unsigned long progRomSize)
{
unsigned long i,j;
int level;
level = intLock();
for(i=0;i
for(j=0;j<50;j++); /*delay*/
ProgFlash((i + romAddr),*((UWORD *)(ramAddr + i) ) );
}
intUnlock(level);
/*taskDelay(1);*/
for(i=0;i
if(*( (UWORD *)( i+ romAddr+FLASH_ADDR) )!=*((UWORD *)(ramAddr + i) ) )
{
printf("%x=verify error/n",romAddr);
return 0;
}
}
return 1;
}
/*测试代码,输入参数为哪个flash*/
void flash_test(int flash) /*flash 的测试程序*/
{
char *p;
char flash2[]="hi,this is flash2!";
char flash3[]="hi,this is flash3!";
if (flash==2)
{
FLASH_ADDR=FLASH2_ADDR;
p=flash2;
}
else
{
FLASH_ADDR=FLASH3_ADDR;
p=flash3;
}
EraseSector(0x0);
ChipProg(0x0,p,18);
}
在vxworks调试界面下,看到的测试结果为:
-> d 0x50000000
50000000: 6869 2c74 6869 7320 6973 2066 6c61 7368 *hi,this is flash*
50000010: 3221 ffff ffff ffff ffff ffff ffff ffff *2!..............*
来自:http://xiyong8260.blog.163.com/blog/static/665146212008924112335306/