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

📄 km29ux.c

📁 基于44B0的Bootload原代码,详细的设计了 44B0开发平台的BOOT
💻 C
字号:
#include <string.h>
#include "..\inc\44b.h"
#include "..\inc\44blib.h"
#include "..\inc\def.h"
#include "..\inc\km29ux.h"



//KM29U128T

/****************** CAUTION ***********************
 1) PA7,4,2 has to be configured as an output port
 2) PA3 has to be configured as an input port
 3) GCS3 has to be configured as 8-bit, 
    tcos=1,tacc=4 @ 60Mhz, tcos has to exist!!!
 4) caching has to be disabled on nGCS3
 5) write buffer has to be turned off.
 **************************************************/

//The code is made for bi-endian mode

/*
 1999.5 Wireless Div. Circuit for KS32C41000 
 H/W connection.
 F_nSE= L
 F_nRE= nGCS3 | nOE
 F_nWE= nGCS3 | nWE
 F_CLE= PA4
 F_ALE= PA7
 F_RB = PA3
 F_nCE = PA2
*/

// blk0:page0 : reserved
// blk0:page1,2,3,4: Block Information Table :  
//	 good block:used block:logical block number
//	            unused block:FFFF
//       bad block:  F0F0

#define WRITEVERIFY  (1)  //verifing is enable at writing.

#define PAGE2BLOCKID(page32)	(page32>>5)

#define ALE	    (0x80)	
#define CLE	    (0x10)	
#define CE	    (0x04)     
#define RB	    (0x08)

#define FC_CMD	    {rPDATA|=CLE;rPDATA&=~(ALE|CE);}
#define FC_ADDR     {rPDATA|=ALE;rPDATA&=~(CLE|CE);}
#define FC_DATA     {rPDATA&=~(ALE|CLE|CE);}
#define FC_INACTIVE {rPDATA|=CE;rPDATA&=~(ALE|CLE);}

#define WAITRB	    while(!(rPDATA&RB)) 
	    //wait tWB and check R/B pin.   
#define rKM29UXDATA	   (*(volatile U8 *)0x6000000)

static U16 blockLookupTable[1024+8]; //logical blockId # ->physical block #
	                    	     //8 is spare area for loading 528bytes.
static unsigned lastPage=0;
static unsigned isOpen=0;

// 1block=528bytes x 32pages
// 1024block

// A[23:14][13:9]
//  block   page


int Nf_Format(int page32)
//returns the allocated good block excluding BIT. 
{
    int i;
    int error=0,retry=0;
    int blockCnt;
    int blockId;
    U8 buffer[528];
    unsigned int bp0,bp1;
    U8 *phyStTbl=(U8 *)blockLookupTable;

    if((page32%32)!=0)return 0;
    blockCnt=page32/32;
    //check if the flash had been formatted.
    
    if(_CheckId()!=0xec73) //check KM29U128T
    {
	Uart_Printf("ID Error!!!\n");
	return 0;
    }


    _RdPage(0,0,buffer);
    if(buffer[0]=='N')return 0;
    
    blockId=0;
    phyStTbl[0]=0xf5;  //For BIT
    phyStTbl[1]=0xf5;  
    
    for(i=1;i<1024;i++)
    {
	_RdPage(i,0,buffer);bp0=buffer[0];
	_RdPage(i,0,buffer);bp1=buffer[0];
	if(bp0==0xff && bp1==0xff)
	{  //good block
	    
	    if(blockId < blockCnt)
	    {
		//good block have blcokId
		phyStTbl[2*i]=blockId &0xff;  
		phyStTbl[2*i+1]=(blockId>>8) &0xff;  
	    	blockId++; 
	    }
	    else
	    {
		phyStTbl[2*i]=0xff;  //unused good block have 0xffff instead of blcokId
		phyStTbl[2*i+1]=0xff;  
	    }
	}
        else 
	{   //bad block
	    //bad block have 0xffff instead of blcokId
	    phyStTbl[2*i]=0xf0; 
	    phyStTbl[2*i+1]=0xf0; 
	    Uart_Printf("BAD BLOCK #=%d\n",i);
	}
    }

    while(1)
    {
	for(i=0;i<528;i++)buffer[i]=0;
	memcpy(buffer,"NAND 128M MODE2",16);
	if(!_WrPage(0,0,buffer))error++;
   
	memcpy(buffer,phyStTbl+0x0,512);
	if(!_WrPage(0,1,buffer))error++;

	memcpy(buffer,phyStTbl+0x200,512);
	if(!_WrPage(0,2,buffer))error++;
    
	memcpy(buffer,phyStTbl+0x400,512);
	if(!_WrPage(0,3,buffer))error++;
    
	memcpy(buffer,phyStTbl+0x600,512);
	if(!_WrPage(0,4,buffer))error++;
	if(error==0)break;
	error=0;
	if(++retry==3)return 0; //retry error!!! unusable NAND flash

	_EraseBlock(0); //erase physical block #0 for retry
    }

    return blockId; //returns the allocated good block excluding BIT. 
}



int Nf_Open(void)
//returns the last page #
{
    int i,j;
    U8 buffer[2048+16];
    int lBlock=0;

    if(_CheckId()!=0xec73)  //check KM29U128T
    {
	Uart_Printf("ID Error!!!\n");
	return 0;
    }
    _RdPage(0,0,buffer+0); //check if the flash is formatted.
    if(buffer[0]!='N')return 0;
    
    _RdPage(0,1,buffer+0);
    _RdPage(0,2,buffer+0x200);
    _RdPage(0,3,buffer+0x400);
    _RdPage(0,4,buffer+0x600);
    
    for(i=0;i<1024;i++)blockLookupTable[i]=0xffff;

    for(i=1;i<1024;i++)
    {
	j=(U8)buffer[i*2]+((U8)buffer[i*2+1])*0x100;
	if(j!=0xf0f0 && j!=0xffff){blockLookupTable[j]=i;lBlock++;}
    }
    lastPage=(lBlock)*32-1; //total page count.
    
    //check the Block Information Table Integrity.
    for(i=0;i<lBlock;i++)
    {
	if(blockLookupTable[i]==0xffff)return 0; //error!!!
    }

    isOpen=1;
    return lastPage;
}   



int Nf_EraseBlock(unsigned int page32)
{
    if((page32%32)!=0)return 0; //page32[4:0] has to be 00000.
    return _EraseBlock( blockLookupTable[PAGE2BLOCKID(page32)] );
}


int Nf_ReadPage(unsigned int startPage, unsigned int pageCount, U8 *buffer)
{
    int i;
    int page=startPage;
    U8 *pPage=buffer;

    for(i=0;i<pageCount;i++)
    {
    	_RdPage(blockLookupTable[PAGE2BLOCKID(page)],(page&0x1f),pPage);
	pPage+=528;
	page++;
    }
    return 1;
}




int Nf_WritePage(unsigned int startPage, unsigned int pageCount, U8 *buffer)
{
    int i;
    int page=startPage;
    U8 *pPage=buffer;

    for(i=0;i<pageCount;i++)
    {
    	if(!_WrPage(blockLookupTable[PAGE2BLOCKID(page)],(page&0x1f),pPage))
	    return 0;
	pPage+=528;
	page++;
    }
    return 1;
}




int Nf_Add1Block(void)
{
    if(_RepAdd1Block(0)==0)return 0;
    return Nf_Open();
}




int Nf_Replace1Block(int page32)
{
    if(_RepAdd1Block(PAGE2BLOCKID(page32))==0)return 0;
    return Nf_Open();
}



int _RepAdd1Block(int badBlockId)
//if badBlockId==0, replacement doesn't occur.
//blockId is blockLookupTable entry. 0=BIT table, 1=page0-31, 2=page32-63
{
    int i;
    int error=0,retry=0;
    U8 buffer[528];
    U8 reserved[528];
    unsigned int phyBadBlock=0,phyNewBlock,newBlockId;
    U8 *phyStTbl=(U8 *)blockLookupTable;
    
    if(isOpen==0)return 0;

    if(badBlockId!=0) //must remove the bad block.
    {
	newBlockId=badBlockId;
	phyBadBlock=blockLookupTable[badBlockId];
	_RdPage(0,0,reserved);
	_RdPage(0,1,phyStTbl+0x0);
	_RdPage(0,2,phyStTbl+0x200);
	_RdPage(0,3,phyStTbl+0x400);
	_RdPage(0,4,phyStTbl+0x600);
	*((U16 *)phyStTbl+phyBadBlock)=0xf0f0;  //mark bad block
    }
    else
    {
	newBlockId=(lastPage+1)/32;
	_RdPage(0,0,reserved);
	_RdPage(0,1,phyStTbl+0x0);
	_RdPage(0,2,phyStTbl+0x200);
	_RdPage(0,3,phyStTbl+0x400);
	_RdPage(0,4,phyStTbl+0x600);
    }

    for(i=1;i<1024;i++)
    {
        if(*((U16 *)phyStTbl+i)==0xffff)break;
    }

    if(i==1024)return 0;    //no more available empty good block.

    phyNewBlock=i;

    *((U8 *)((U16 *)phyStTbl+phyNewBlock))=0xff & newBlockId;  //replace mark bad block
    *((U8 *)((U16 *)phyStTbl+phyNewBlock)+1)=0xff & (newBlockId>>8);  
    
    Uart_Printf("Bad Block ID:%d(phy. %d) ->New block ID:%d(phy. %d)\n"
    		,badBlockId,phyBadBlock,newBlockId,phyNewBlock);
 
    while(1)
    {
	_EraseBlock(0); //erase physical block #0

	//buffer[528] has the ROM writer maker's information.
	if(!_WrPage(0,0,reserved))error++;
    
	for(i=0;i<528;i++)buffer[i]=0;   
 
	memcpy(buffer,phyStTbl+0x0,512);
	if(!_WrPage(0,1,buffer))error++;

	memcpy(buffer,phyStTbl+0x200,512);
	if(!_WrPage(0,2,buffer))error++;
    
	memcpy(buffer,phyStTbl+0x400,512);
	if(!_WrPage(0,3,buffer))error++;
    
	memcpy(buffer,phyStTbl+0x600,512);
	if(!_WrPage(0,4,buffer))error++;
	if(error==0)break;
	error=0;
	if(++retry==3)return 0; //retry error!!! unusable NAND flash
    }

    return 1; 
}


int _EraseBlock(unsigned int block) 
{
    unsigned int blockPage=(block<<5);
    int i;
    FC_CMD;
    rKM29UXDATA=0x60;
    FC_ADDR;	  
    
    rKM29UXDATA=blockPage&0xff;  
    rKM29UXDATA=(blockPage>>8)&0xff;

    for(i=0;i<2;i++);//tWC  50ns
    
    FC_CMD;
    rKM29UXDATA=0xd0;
    
    for(i=0;i<3;i++);
    
    FC_DATA;
    WAITRB;	//wait max 3ms
    FC_CMD;
    rKM29UXDATA=0x70;
    FC_DATA;
    if (rKM29UXDATA&0x1) //erase error
    {	
	FC_INACTIVE;
	Uart_Printf("[ERASE_ERROR:PB=%d]",block);
	return 0;
    }
    else 
    {
	FC_INACTIVE;   
        return 1;
    }
}




int _VerifyPage(U32 block,U32 page,U8 *buffer)
{
    U8 buf[528];
    _RdPage(block,page,buf);
    if(strncmp((char *)buf,(char *)buffer,528)==0)return 1;
    else return 0;
}

    


int _WrPage(unsigned int block,unsigned int page,U8 *pPage)  
{
    unsigned int blockPage=(block<<5)+page;
    int i;
    FC_CMD;
    rKM29UXDATA=0x80;
    FC_ADDR;
    rKM29UXDATA=0;
    rKM29UXDATA=blockPage&0xff;
    rKM29UXDATA=(blockPage>>8)&0xff;
    FC_DATA;

    //for(i=0;i<528;i++){rKM29UXDATA=*pPage++;}  
    __WrPage528(pPage);

    FC_CMD;
    rKM29UXDATA=0x10;
    for(i=0;i<10;i++);  //twb=100ns. why is it 10? spec is false?  
                        //No. It's because of LED of PE1.
    WAITRB;	//wait max 500us;
    rKM29UXDATA=0x70;
    FC_DATA;
    for(i=0;i<3;i++);  //twhr=60ns
    if((rKM29UXDATA&0x1))
    {
	FC_INACTIVE;	
	rSYSCFG=SYSCFG_8KB;
	Uart_Printf("[WRITE_ERROR:PB=%d]",block);
        return 0;
    }
    else
    {
	FC_INACTIVE;	    
	rSYSCFG=SYSCFG_8KB;
#if (WRITEVERIFY==1)
	return _VerifyPage(block,page,pPage);	
#else
	return 1;
#endif
    }

}



void _RdPage(unsigned int block,unsigned int page,U8 *pPage)  
{
    int i;
    unsigned int blockPage=(block<<5)+page;
    FC_CMD;
    rKM29UXDATA=0x00;
    FC_ADDR;
    rKM29UXDATA=0;
    rKM29UXDATA=blockPage&0xff;
    rKM29UXDATA=(blockPage>>8)&0xff;
    for(i=0;i<3;i++);
    FC_DATA;
    WAITRB;	//wait max. 10us 
    //for(i=0;i<528;i++){*pPage++=rKM29UXDATA;}
    __RdPage528(pPage);
    FC_INACTIVE;
}




int _CheckId(void)
{
    int i;
    int id;
    FC_CMD;
    rKM29UXDATA=0x90;
    FC_ADDR;
    rKM29UXDATA=0;
    FC_DATA;
    for(i=0;i<5;i++); //wait 100ns
    id=rKM29UXDATA<<8;
    id+=rKM29UXDATA;
    FC_INACTIVE;
    return id;
}

⌨️ 快捷键说明

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