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

📄 am29lv800.c

📁 MBA2440(s3c2440)的 源代码文件 ARM920T内核。
💻 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 + -