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

📄 am29f800.c

📁 这是三星公司的arm7 s3c44b0x芯片的所有外设中断程序
💻 C
字号:
//44BTEST : am29f800.c
#include "..\inc\44b.h"
#include "..\inc\44blib.h"
#include "..\inc\def.h"
int AM29F800_ProgFlash(U32 realAddr,U16 data);
void AM29F800_EraseSector(int targetAddr);
int AM29F800_CheckId(void);
int BlankCheck(int targetAddr,int targetSize);
int _WAIT(void);
static void InputTargetAddr(void);
// Because S3C44B0X is connected to AM29LV800B,
// the addr parameter has to be a WORD address, so called in AMD specification.
#define _WR(addr,data) *((U16 *)(addr<<1))=(U16)data //the addr should be shifted
#define _RD(addr) ( *((U16 *)(addr<<1)) )
#define _RESET() _WR(0x0,0xf0f0)
#define BADDR2WADDR(addr) (addr>>1)
extern U32 downloadAddress;
extern U32 downloadProgramSize;
U32 srcAddress;
U32 srcOffset;
U32 targetAddress;
U32 targetSize;
void ProgramAM29F800(void)
{
	int i;
	InputTargetAddr();
	srcAddress=downloadAddress+4;
	Uart_Printf("[Check AM29LV800]\n");
	if(!AM29F800_CheckId())
	{
		Uart_Printf("ID Check Error!!!\n");
		return;
	}
	Uart_Printf("\nErase the sector:0x%x.\n",targetAddress);
	AM29F800_EraseSector(targetAddress);
	if(!BlankCheck(targetAddress,targetSize))
	{
		Uart_Printf("Blank Check Error!!!\n");
		return;
	}
	Uart_Printf("\nStart of the data writing.\n");
	for(i=0;i<targetSize;i+=2)
	{
		AM29F800_ProgFlash( i+targetAddress,*( (U16 *)(srcAddress+srcOffset+i) ) );
		if((i%0x1000)==0)
			Uart_Printf("%x ",i);
	}
	Uart_Printf("\nEnd of the data writing!!!\n");
	_RESET();
	Uart_Printf("\nVerifying Start.\n");
	for(i=0x0;i<targetSize;i+=2)
	{
		if(*( (U16 *)(i+targetAddress) )!=*( (U16 *)(srcAddress+srcOffset+i) ) )
		{
			Uart_Printf("%x=verify error\n",i+targetAddress);
			return;
		}
		if((i%0x1000)==0)
			Uart_Printf("%x ",i);
	}
	Uart_Printf("\nVerifying End!!!\n");
	Uart_Printf("Do you want another programming without additional download? [y/n]\n");
	if(Uart_Getch()=='y')
		ProgramAM29F800();
}
static void InputTargetAddr(void)
{
	Uart_Printf("[AM29F800 Writing Program]\n");
	Uart_Printf("\nSource size:0h~%xh\n",downloadProgramSize);
	Uart_Printf("\nAvailable Target/Source Address:\n");
	Uart_Printf(" 0h, 4000h, 6000h, 8000h,10000h,20000h,30000h,40000h,50000h,60000h\n");
	Uart_Printf("70000h,80000h,90000h,a0000h,b0000h,c0000h,d0000h,e0000h,f0000h\n");
	Uart_Printf("Input source offset:");
	srcOffset=Uart_GetIntNum();
	Uart_Printf("Input target address among above addresses:");
	targetAddress=Uart_GetIntNum();
	if(targetAddress<0x4000)
		targetSize=0x4000;
	else if(targetAddress<0x6000)
		targetSize=0x2000;
	else if(targetAddress<0x8000)
		targetSize=0x2000;
	else if(targetAddress<0x10000)
		targetSize=0x8000;
	else
		targetSize=0x10000;
	Uart_Printf("source offset=0x%x\n",srcOffset);
	Uart_Printf("target address=0x%x\n",targetAddress);
	Uart_Printf("target block size=0x%x\n",targetSize);
}
int AM29F800_CheckId(void)
{
	U16 manId,devId;
	_RESET();
	_WR(0x555,0xaaaa);
	_WR(0x2aa,0x5555);
	_WR(0x555,0x9090);
	manId=_RD(0x0);
	_WR(0x555,0xaaaa);
	_WR(0x2aa,0x5555);
	_WR(0x555,0x9090);
	devId=_RD(0x1);
	_RESET();
	Uart_Printf("Manufacture ID=%4x(0x0001), Device ID(0x225B)=%4x\n",manId,devId);
	if(manId==0x0001 && devId==0x225b)
		return 1;
	else
		return 0;
}
void AM29F800_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();
}
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 ) //Time_limit_over check(in case normally end with set DQ5)
		{
			//Uart_Printf("[DQ5=1:%x]\n",flashStatus);
			old=*((volatile U16 *)0x0);
			flashStatus=*((volatile U16 *)0x0);
			if( (old&0x40) == (flashStatus&0x40) )
				return 1; //No toggle
			else
				return 0; //toggling
		}
		//Uart_Printf(".");
		old=flashStatus;
	}
	//Uart_Printf("!\n");
	return 1;
}
int AM29F800_ProgFlash(U32 realAddr,U16 data)
{
	volatile U16 *tempPt;
	int temp,count=0;
	tempPt=(volatile U16 *)realAddr;
	_WR(0x555,0xaaaa);
	_WR(0x2aa,0x5555);
	_WR(0x555,0xa0a0);
	*tempPt=data;
	return _WAIT();
	/* while(1)
	{
	temp=*tempPt;
	if(temp==data || count==100)break;
	if(temp&0x20)
	{
	count++;
	}
	}
	if(count>0)Uart_Printf("Time out is occurred at %x\n",realAddress);
	*/
}

⌨️ 快捷键说明

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