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

📄 39vf160.c

📁 GEC的BIOS
💻 C
字号:
#include "def.h"
#include "2410lib.h"

#ifdef _FLASH_TYPE_SST39VF_

//
// program norflash type SST39VF160x  
//


#define	ROM_BASE	0x08000000	//地址重定向到0x08000000
#define	CMD_ADDR0	*((volatile U16 *)(0x5555*2+ROM_BASE))
#define	CMD_ADDR1	*((volatile U16 *)(0x2aaa*2+ROM_BASE))

static U8 state = 0;

static void CFIQueryExit(void)
{
	CMD_ADDR0 = 0xaaaa;
	CMD_ADDR1 = 0x5555;
	CMD_ADDR0 = 0xf0f0;
	state &= 0xfc;	
}

static void SWPIDExit(void)
{
	CMD_ADDR0 = 0xf0f0;
	state &= 0xfc;
}

static void CFIQueryEntry(void)
{
	if(state&1)
	{
		if(state&2)
			SWPIDExit();
		else
			return;
	}
	
	CMD_ADDR0 = 0xaaaa;
	CMD_ADDR1 = 0x5555;
	CMD_ADDR0 = 0x9898;
	state |= 1;	
}

static void SWPIDEntry(void)
{
	if(state&1)
	{
		if(state&2)
			return;
		else
			CFIQueryExit();
	}

	CMD_ADDR0 = 0xaaaa;
	CMD_ADDR1 = 0x5555;
	CMD_ADDR0 = 0x9090;
	state |= 3;
}

U32 GetFlashID(void)
{
	U32 i;
	
	SWPIDEntry();
	i  = *(U16 *)(0+ROM_BASE);
	i |= (*(U16 *)(2+ROM_BASE))<<16;
	SWPIDExit();
	return i;	
}

void GetFlashCFI(U16 *DataPtr)
{
	U16 i;
	
	CFIQueryEntry();
	for(i = 0x10; i<0x35; DataPtr++, i++)
		*DataPtr = *(U16 *)(i*2+ROM_BASE);	
	CFIQueryExit();
}

void ChipErase(void)
{
	if(state&1)
	{
		if(state&2)
			SWPIDExit();
		else
			CFIQueryExit();						
	}
	
	CMD_ADDR0 = 0xaaaa;
	CMD_ADDR1 = 0x5555;
	CMD_ADDR0 = 0x8080;
	CMD_ADDR0 = 0xaaaa;
	CMD_ADDR1 = 0x5555;
	CMD_ADDR0 = 0x1010;

	while(1)
	{
		U16 i;
		i = *((volatile U16 *)0x6666)&0x40;
		if(i!=*((volatile U16 *)0x6666)&0x40)	//D6 == D6
			continue;
		if(*((volatile U16 *)0x8888)&0x80)	
			break;						//D7 == 1
	}		
}

void SectorErase(U32 sector)
{
	if(state&1)
	{
		if(state&2)
			SWPIDExit();
		else
			CFIQueryExit();						
	}
	
	sector += ROM_BASE;	
	
	CMD_ADDR0 = 0xaaaa;
	CMD_ADDR1 = 0x5555;
	CMD_ADDR0 = 0x8080;
	CMD_ADDR0 = 0xaaaa;
	CMD_ADDR1 = 0x5555;
	*(volatile U16 *)sector = 0x3030;
	
	while(1)
	{
		U16 i;
		i = *((volatile U16 *)sector)&0x40;
		if(i!=*((volatile U16 *)sector)&0x40)	//D6 == D6
			continue;
		if(*((volatile U16 *)sector)&0x80)	
			break;								//D7 == 1
	}
	
//	printf("Erase sector 0x%x	ok\n", sector-ROM_BASE);				

}

void FlashProg(U32 ProgStart, U16 *DataPtr, U32 WordCnt)
{
	U16 i, j;	
	
	ProgStart += ROM_BASE;
	
	for( ; WordCnt; ProgStart+=2, DataPtr++, WordCnt--)
	{	
		j = *DataPtr;
		CMD_ADDR0 = 0xaaaa;
		CMD_ADDR1 = 0x5555;
		CMD_ADDR0 = 0xa0a0;
		*(volatile U16 *)ProgStart = j;	
		
		while(1)
		{
			i = *(volatile U16 *)ProgStart&0x40;
			if(i!=*(volatile U16 *)ProgStart&0x40)		//D6 == D6
				continue;
			if((*(volatile U16 *)ProgStart&0x80)==(j&0x80))	
				break;					//D7 == D7
		}
	}
	
}

void FlashRead(unsigned int ReadStart, unsigned short *DataPtr, unsigned int Size)
{
	int i;
	
	ReadStart += ROM_BASE;
	
	for(i=0; i<Size/2; i++)
		*(DataPtr+i) = *((unsigned short *)ReadStart+i);	
	
}

int SectorProg(U32 begin, U16 *data, U32 size)
{		
	U32 tmp = 0x1000-(begin&0xfff);
	
	if(tmp>size)
		tmp = size;
	
	for(; size;)
	{	
		SectorErase(begin&0xfffff000);	//4K Bytes boudary		
		FlashProg(begin, data, tmp/2);
		printf("Program %x ok\n", begin);
		
		size  -= tmp;
		begin += tmp;
		data  += tmp/2;
		tmp = (size>0x1000)?0x1000:size;				
	}
	return 0;			
}

#else  //_FLASH_TYPE_SST39VF_

//
// program norflash type AM29LV800BB  
//
unsigned long rom_base = 0x08000000;    //set to nGCS0 or nGCS1 when detected 
#define CMD_ADDR(x)  *((volatile U16 *)((x)*2+rom_base))

U32 GetFlashID(void)
{
	U32 id;

    // reset flash
    CMD_ADDR(0) = 0x00F0;
    
    // read id
    CMD_ADDR(0x555) = 0x00AA;
    CMD_ADDR(0x2aa) = 0x0055;
    CMD_ADDR(0x555) = 0x0090;

    id = (CMD_ADDR(0x001) & 0xffff);

    // reset flash
    CMD_ADDR(0) = 0x00F0;
    
	return id;
}

void SectorErase(U32 SecAddr)
{
    U32 Addr;
    
    Addr = SecAddr & 0x7f000;
    Addr /= 2;
    
    // reset flash
    CMD_ADDR(0) = 0x00F0;
    
    CMD_ADDR(0x555) = 0x00AA;
    CMD_ADDR(0x2aa) = 0x0055;
    CMD_ADDR(0x555) = 0x0080;
    CMD_ADDR(0x555) = 0x00AA;
    CMD_ADDR(0x2aa) = 0x0055;
    CMD_ADDR(Addr)  = 0x0030;
    
    // wait complete
    while(!(CMD_ADDR(Addr) & (1<<7)))
        ;
    
    // reset flash
    CMD_ADDR(0) = 0x00F0;
}


void FlashProg(U32 ProgStart, U16 *DataPtr, U32 WordCnt)
{
    U32 l;
    U32 AddrNow;
    
    if(ProgStart + WordCnt * 2 >= 0x100000) {
        printf("FlashProg: exceed the limit of flash\n");
        return;
    }
    
    // reset flash
    CMD_ADDR(0) = 0x00F0;

    AddrNow = ProgStart/2;
    for(l = 0; l < WordCnt; ++l) {
        // write program command
        CMD_ADDR(0x555) = 0x00AA;
        CMD_ADDR(0x2aa) = 0x0055;
        CMD_ADDR(0x555) = 0x00A0;
        CMD_ADDR(AddrNow) = *DataPtr;
        
        // wait complete
        while( (( CMD_ADDR(AddrNow)^(*DataPtr) ) & (1<<7)) )
            ;
            
        ++AddrNow;
        ++DataPtr;
    }

    // reset flash
    CMD_ADDR(0) = 0x00F0;
}

int SectorProg(U32 begin, U16 *data, U32 size)
{
    U32 blkAddr;
    U32 blkSize, wsize;
    
    U16 *start;
    U16 *data1;
    U32 len;

    start = (U16*)(begin + rom_base);
    data1 = data;
    
    if(begin & 0xfff) {
        printf("Flash program must be block alain\n");
        return -1;
    }
    
    /* size must be odd */
    if(size & 1)
        ++size;
        
    len = size;
    
    blkAddr = begin;
    for( ; size > 0; ) {
        switch(blkAddr) {
            case 0:
               blkSize = 0x4000;
               break;
            case 0x4000:
            case 0x6000:
               blkSize = 0x2000;
               break;
            case 0x8000:
               blkSize = 0x8000;
               break;
            default:
               blkSize = 0x10000;
               break;
        }
        wsize = (size > blkSize) ? blkSize : size;
        
//        printf("blkaddr=0x%x, data=0x%x, wsize=0x%x\n", blkAddr, (U32)data, wsize);
        
        SectorErase(blkAddr);
        FlashProg(blkAddr, data, wsize/2);
        
        putch('.');
        
        blkAddr += wsize;
        data += (wsize/2);
        size -= wsize;
    }
    
    printf("\nVerify...");
    for( ; len > 1; len -= 2) {
        if(*start != *data1) {
            printf("error, addr=0x%x, flashdata=0x%x, memdata=0x%x\n", 
                    (U32)start, *start, *data1);
            break;
        }
        ++start;
        ++data1;
    }
    if(len == 0)
        printf("ok\n");
    
    
    printf("\nFinish write nor flash\n");
	return 0;
}


#endif

⌨️ 快捷键说明

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