📄 am29lv800.c
字号:
/****************************************************************************
* file name : Am29lv800.c
* Date : 15. 04. 2005
* Version : 1.0
* Description : AM29LV800BB NOR flash test menu display function
*
*
****************************************************************************/
#include <string.h>
#include "Def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#include "Am29lv800.h"
//Revision History
// 2001.8.25:purnnamu:If the data is downloaded by ICE, the writing isn't done correct.
void AM29LV800_menu(void);
void EraseAM29LV800();
void ReadAM29LV800();
void WriteAM29LV800(void);
int AM29LV800_ProgFlash(U32 realAddr,U16 data);
void AM29LV800_EraseSector(int targetAddr);
void AM29LV800_CheckID(void);
int CheckID(void);
int BlankCheck(int targetAddr,int targetSize);
int _WAIT(void);
//extern U32 downloadAddress;
//extern U32 downloadProgramSize;
static U32 srcAddress;
static U32 srcSize;
static U32 targetAddress;
static U32 targetSize;
// Because KS32C41000_A1 is connected to AM29LV800_A0,
// the addr parameter has to be a WORD address, so called in AMD specification.
#define _WR(addr,data) *((U16 *)((addr<<1)))=(U16)data
#define _RD(addr) *((U16 *)((addr<<1)))
#define _RESET() _WR(0x0, 0xf0f0)
#define BADDR2WADDR(addr) (addr>>1)
void AM29LV800_menu(void)
{
int sel = 0;
while(1){
Uart_Printf("+--------------[ AM29LV800BB test ]---------------+\n");
Uart_Printf("| 1:Check ID\n");
Uart_Printf("| 2:Erase\n");
Uart_Printf("| 3:Read data\n");
Uart_Printf("| 4:Write data\n");
Uart_Printf("| 5:Previous menu\n");
Uart_Printf("+-------------------------------------------------+\n");
Uart_Printf(" Select number : ");
sel = Uart_GetIntNum();
Uart_Printf("+-------------------------------------------------+\n\n\n");
switch(sel){
case 1 :
AM29LV800_CheckID();
break;
case 2 :
EraseAM29LV800();
break;
case 3 :
ReadAM29LV800();
break;
case 4 :
WriteAM29LV800();
break;
case 5 :
return;
default:
Uart_Printf("Wrong number seleted.. Try again!!\n\n\n");
break;
}
}
}
//========================================================================
int CheckID(void)
{
U16 manId,devId;
// _RESET();
_WR(0x555,0xaaaa);
_WR(0x2aa,0x5555);
_WR(0x555,0x9090);
manId=_RD(0x0);
// _RESET(); // New 5V AM29LV800 needs this command.
_WR(0x555,0xaaaa);
_WR(0x2aa,0x5555);
_WR(0x555,0x9090);
devId=_RD(0x1);
// _RESET();
return (manId << 16) + devId;
}
void AM29LV800_CheckID(void)
{
int ID_value;
U16 manID, devID;
ID_value = CheckID();
manID = (ID_value >> 16) & 0xffff;
devID = ID_value & 0xffff;
Uart_Printf("Manufacture ID = 0x%x, Device ID = 0x%x\n", manID, devID);
if(manID==0x0001 && devID==0x22bf)
Uart_Printf("This device is AM29LV200B\n");
else if(manID==0x0001 && devID==0x22ba)
Uart_Printf("This device is AM29LV400B\n");
else if(manID==0x0001 && devID==0x225b)
Uart_Printf("This device is AM29LV800B\n");
else if(manID==0x0001 && devID==0x2249)
Uart_Printf("This device is AM29LV160B\n");
else
Uart_Printf("ID Check Error!!!\n");
Uart_Printf("\n\n");
return;
}
//========================================================================
void AM29LV800_EraseSector(int targetAddr)
{
Uart_Printf("Sector Erase is started!\n");
// _RESET();
_WR(0x555,0xaaaa);
_WR(0x2aa,0x5555);
_WR(0x555,0x8080);
_WR(0x555,0xaaaa);
_WR(0x2aa,0x5555);
_WR(BADDR2WADDR(targetAddr),0x3030);
_WAIT();
// _RESET();
}
void EraseAM29LV800()
{
Uart_Printf("AMD NOR flash Erase Test\nThis test erases only one block you select\n");
do{
Uart_Printf("\n\nAvailable Target Address:\n");
Uart_Printf(" 0x0, 0x4000, 0x6000, 0x8000,0x10000,0x20000,0x30000,0x40000,\n");
Uart_Printf("0x50000,0x60000,0x70000,0x80000,0x90000,0xa0000,0xb0000,0xc0000,\n");
Uart_Printf("0xd0000,0xe0000,0xf0000\n\n\n");
Uart_Printf("Input target address among above addresses[0x...]: ");
targetAddress = Uart_GetIntNum();
Uart_Printf("\n\n");
AM29LV800_EraseSector(targetAddress);
if(targetAddress<0x4000) srcSize = targetSize=0x4000;
else if(targetAddress<0x6000) srcSize = targetSize=0x2000;
else if(targetAddress<0x8000) srcSize = targetSize=0x2000;
else if(targetAddress<0x10000) srcSize = targetSize=0x8000;
else srcSize = targetSize=0x10000;
if(!BlankCheck(targetAddress,targetSize)){
Uart_Printf("Blank Check Error!!!\n\n\n");
return;
}
Uart_Printf("Block erase complete...\n\n\n");
Uart_Printf("\nDo you want to continue erasing block?[y/n]");
}while(Uart_Getch()=='y');
Uart_Printf("\n\n\n");
}
//========================================================================
void ReadAM29LV800(void)
{
U16 *rd_src, *rd_dst;
int i;
Uart_Printf("AMD NOR flash Read Test\n");
Uart_Printf("This test reads data from AMD flash and copies data to memory\n");
Uart_Printf("This test reads only one block you select\n");
do{
Uart_Printf("\n\nAvailable Target Address:\n");
Uart_Printf(" 0x0, 0x4000, 0x6000, 0x8000,0x10000,0x20000,0x30000,0x40000,\n");
Uart_Printf("0x50000,0x60000,0x70000,0x80000,0x90000,0xa0000,0xb0000,0xc0000,\n");
Uart_Printf("0xd0000,0xe0000,0xf0000\n\n\n");
Uart_Printf("Input the source address you wanna read among above addresses[0x...]: ");
srcAddress = Uart_GetIntNum();
Uart_Printf("Input the target address to copy in memory[0x...]: ");
targetAddress = Uart_GetIntNum();
Uart_Printf("\n\ntarget address = 0x%x\n",targetAddress);
Uart_Printf("source address = 0x%x\n",srcAddress);
if(srcAddress<0x4000) srcSize = 0x4000;
else if(srcAddress<0x6000) srcSize = 0x2000;
else if(srcAddress<0x8000) srcSize = 0x2000;
else if(srcAddress<0x10000) srcSize = 0x8000;
else srcSize = 0x10000;
Uart_Printf("\nStart of the data reading.. size[0x%x]\n", srcSize);
rd_dst = (U16 *)targetAddress;
rd_src = (U16 *)srcAddress;
for(i=0;i<srcSize;i+=2) *rd_dst++ = *rd_src++;
Uart_Printf("\nEnd of the data reading!!!\n");
Uart_Printf("\nStart Verifying data\n");
for(i=0;i<srcSize;i+=2)
{
if(*( (U16 *)(i+targetAddress) )!=*( (U16 *)(srcAddress+i) ) )
{
Uart_Printf("\n%x = verify error\n\n\n",i+targetAddress);
return;
}
if((i%0x2000)==0)Uart_Printf("%x ",i);
}
Uart_Printf("\nVerifying End!!!\n");
Uart_Printf("\nDo you want to continue reading additional data?[y/n]");
}while(Uart_Getch()=='y');
Uart_Printf("\n\n\n");
}
//========================================================================
int AM29LV800_ProgFlash(U32 realAddr,U16 data)
{// Write only one half word
volatile U16 *tempPt;
tempPt=(volatile U16 *)realAddr;
_WR(0x555,0xaaaa);
_WR(0x2aa,0x5555);
_WR(0x555,0xa0a0);
*tempPt=data;
return _WAIT();
}
void WriteAM29LV800(void)
{
int i;
Uart_Printf("AMD NOR flash Write Test\n");
Uart_Printf("This test reads data from memory and writes data to AMD flash\n");
Uart_Printf("This test writes only one block you select\n");
do{
Uart_Printf("\n\nAvailable Target Address:\n");
Uart_Printf(" 0x0, 0x4000, 0x6000, 0x8000,0x10000,0x20000,0x30000,0x40000,\n");
Uart_Printf("0x50000,0x60000,0x70000,0x80000,0x90000,0xa0000,0xb0000,0xc0000,\n");
Uart_Printf("0xd0000,0xe0000,0xf0000\n\n\n");
Uart_Printf("Input target address among above addresses[0x...]: ");
targetAddress = Uart_GetIntNum();
Uart_Printf("Input source data address in memory[0x...]: ");
srcAddress = Uart_GetIntNum();
Uart_Printf("\n\ntarget address = 0x%x\n",targetAddress);
Uart_Printf("source address = 0x%x\n",srcAddress);
if(targetAddress<0x4000) srcSize = targetSize=0x4000;
else if(targetAddress<0x6000) srcSize = targetSize=0x2000;
else if(targetAddress<0x8000) srcSize = targetSize=0x2000;
else if(targetAddress<0x10000) srcSize = targetSize=0x8000;
else srcSize = targetSize=0x10000;
// Uart_Printf("\nErase the block you select[0x%x]\n", targetAddress);
// AM29LV800_EraseSector(targetAddress);
if(!BlankCheck(targetAddress,targetSize)){
Uart_Printf("Blank Check Error!!!\n");
return;
}
Uart_Printf("\nStart of the data writing.. size[0x%x]\n", srcSize);
for(i=0x0;i<targetSize;i+=2)
{
AM29LV800_ProgFlash(targetAddress+i, *((U16 *)(srcAddress+i)) );
if((i%0x2000)==0)Uart_Printf("%x ",i);
}
Uart_Printf("\nEnd of the data writing!!!\n");
_RESET();
Uart_Printf("\nStart Verifying data\n");
for(i=0x0;i<targetSize;i+=2)
{
if(*( (U16 *)(i+targetAddress) )!=*( (U16 *)(srcAddress+i) ) )
{
Uart_Printf("\n%x = verify error\n\n\n",i+targetAddress);
return;
}
if((i%0x2000)==0)Uart_Printf("%x ",i);
}
Uart_Printf("\nVerifying End!!!\n");
Uart_Printf("\nDo you want to continue writing additional data?[y/n] ");
}while(Uart_Getch()=='y');
Uart_Printf("\n\n\n");
}
//========================================================================
int BlankCheck(int targetAddr,int targetSize)
{
int i,j;
for(i=0;i<targetSize;i+=2)
{
j=*((U16 *)(i+targetAddr));
if( j!=0xffff)
{
Uart_Printf("E:%x=%x\n",(i+targetAddr),j);
return 0;
}
}
return 1;
}
int _WAIT(void) //Check if the bit6 toggle ends.
{
volatile U16 flashStatus,old;
old=*((volatile U16 *)0x0);
while(1)
{
flashStatus=*((volatile U16 *)0x0);
if( (old&0x40) == (flashStatus&0x40) )break;
if( flashStatus&0x20 )
{
//Uart_Printf("[DQ5=1:%x]\n",flashStatus);
old=*((volatile U16 *)0x0);
flashStatus=*((volatile U16 *)0x0);
if( (old&0x40) == (flashStatus&0x40) )
return 0;
else return 1;
}
//Uart_Printf(".");
old=flashStatus;
}
//Uart_Printf("!\n");
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -