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

📄 flash.c

📁 ESS3890+SL原代码(1*16内存)
💻 C
字号:
/* Copyright 2002, ESS Technology, Inc.                                 *//* SCCSID @(#)flash.c	4.2 12/03/03 */#ifdef FLASH_UPDATE/***************************************************************************** Flash read/write routines. The flash currently supported is AM29F040B.*****************************************************************************/#include <stdio.h>#include "vcxi.h"#include "flash.h"#include "memmap.h"#include "const.h"#include "timedef.h"#include "cg.h"/*------------------------------------------------------------------------ * Debugging macros *------------------------------------------------------------------------*/#ifdef DEBUG_OSDextern int osdreg;#define CPRINTF(a,b) {osdreg+=3;if(osdreg>13)osdreg=1;debug_osd(a,b,osdreg);}#else#define CPRINTF(a,b)#endif#if 0int bpt;#define BREAKPOINT(x) {bpt=x;while(bpt) VCX_service();}#else#define BREAKPOINT(x) #endif/************************************************************************** * Private defines **************************************************************************/#define ERASETIMEOUT 10000000#define WRITETIMEOUT 1000/************************************************************************** * Public variables **************************************************************************/#define FLASHBASE	ROM_BASE_ADDR#ifdef UPDATE_FLASH_LOGOuchar logo4update[]="LOGO.DAT"; /* customer can change this */#endif#ifdef UPDATE_FLASH_ALLuchar rom4update[]="BANK30.ROM"; /* customer can change this */#endif/************************************************************************** * Private variables **************************************************************************/static int32 COM_ADDR[2];static int32 FlashBlockAddress[TOTALBLOCK];/************************************************************************** * Private functions **************************************************************************/static int32 FlashRead(int32, void FHUGE *, int32);static int FlashWriteBlock(int32, int32, char FHUGE *, int32);static int FlashEraseBlock(int);static int FlashVerify(int *, int *, int);#ifdef UPDATE_FLASH_LOGO/*  * Function: updates the logo file in the flash with the logo file on CD. *  * input: *	where - the sector location of the logo file in msf. *	size - the size of the logo file in bytes. * * output:		       *	0 - flash update failed. *	1 - flash update successful. *//*#define  TEST /* self copy */int update_logo(int where, int size){    volatile unsigned int * ptrDelay = (unsigned int *) bank3safe;    int i, result, start, end, start_blk, end_blk, logo_blk_offset;    uchar *sptr;        if (size > T_powerupScreen_SZ) {	CPRINTF("UPDATE LOGO TOO BIG", size);	return (0);    }        /* Some initializations */    result = FLASHBASE;    for (i=0; i<TOTALBLOCK; i++) {	FlashBlockAddress[i] = result;	result += FlashBlockSize;    }#ifdef FLASH_16BIT    COM_ADDR[0] = ((0x555 << 1) | FLASHBASE);    COM_ADDR[1] = ((0x2aa << 1) | FLASHBASE);#else    COM_ADDR[0] = (0x555 | FLASHBASE);    COM_ADDR[1] = (0x2aa | FLASHBASE);#endif#ifdef TEST    end_blk = start_blk = 0;    end_blk++;    FlashRead(FlashBlockAddress[start_blk], 	      (void FHUGE *)dram_cached(SHARE_start), 	      FlashBlockSize*(end_blk-start_blk));    CPRINTF("TEST: ERASE N UPDATE", glbTimer);    result = FlashEraseBlock(start_blk);    result = FlashWriteBlock(0, FlashBlockAddress[start_blk],			     (char FHUGE *)dram_cached(SHARE_start), 			     FlashBlockSize);#else    /* Calculate block(s) of flash that include the logo.. */    start = FLASHBASE;    start |= (int)T_powerupScreen; /* logo address in flash */    end = start + T_powerupScreen_SZ;    BREAKPOINT(0);        start_blk = end_blk = 0;    for (i=TOTALBLOCK-1; i>=0; i--) {	if (!start_blk && (start > FlashBlockAddress[i])) start_blk = i;	if (!end_blk && (end > FlashBlockAddress[i])) end_blk = i+1;	    }    BREAKPOINT(0);        /* Read logo from flash to dram (SHARE) */    FlashRead(FlashBlockAddress[start_blk], 	      (void FHUGE *)dram_cached(SHARE_start), 	      FlashBlockSize*(end_blk-start_blk));    BREAKPOINT(0);        OUTOSD(1, "READING NEW LOGO", "READING NEW LOGO", 0);    /* Copy logo from disc (to VBV)..     * NOTE: we have limited the size of the logo to 10 sectors */    getSectors(where, (size+2047) >> 11, 2048);    BREAKPOINT(0);    /* Calculate logo start address in SHARE and update from VBV */    logo_blk_offset = start - FlashBlockAddress[start_blk];    memset((char *)(dram_cached(SHARE_start)+logo_blk_offset), 	   0, T_powerupScreen_SZ); /* clear old logo */    BREAKPOINT(0);        memcpy((char *)(dram_cached(SHARE_start)+logo_blk_offset),	   (char *)dram_cached(VBV_start), size);    BREAKPOINT(0);    if (VCX_emulator) {	/* do everything except write back to flash */	goto restart;    }    OUTOSD(1, "UPDATING LOGO", "UPDATING LOGO", 0);    /* NOTE: OSD cannot be used until flash has been updated */    CPRINTF("ERASE N UPDATE FLASH", glbTimer);    BREAKPOINT(0);    /* Erase & Write back to flash the new logo data */    sptr = (uchar *)dram_cached(SHARE_start);    for (i=start_blk; i < end_blk; i++) {	if (FlashEraseBlock(i) != 0) goto restart;	result = FlashWriteBlock(0, FlashBlockAddress[i],				 sptr, FlashBlockSize);	if (result!=0) goto restart;	sptr+=FlashBlockSize;    }#endif TEST    for (i=0;i<2000000;i++) (void)*ptrDelay; /* Let this sink in */    if (result==0) {    	result = FlashVerify((int *)FlashBlockAddress[start_blk], 			     (int *)dram(SHARE_start), 			     (FlashBlockSize*(end_blk-start_blk))/4);    }restart:    /* Reboot if success */    if (result == 0) {	CPRINTF("FLASH UPDATED", glbTimer);	BREAKPOINT(0);	DSC_powerdown();    } else 	return (0);}#endif /* UPDATE_FLASH_LOGO */#ifdef UPDATE_FLASH_ALL/*  * Function: updates the flash with the rom file on CD. *  * input: *	where - the sector location of the rom file in msf. *	size - the size of the rom file in bytes ( value <= 512KB ). * * output:		       *	0 - flash update failed. *	1 - flash update successful. * * NOTE: define your flash type in flash.h *//* #define  TEST /* self copy */int update_flash(int where, int size){    volatile unsigned int * ptrDelay = (unsigned int *) bank3safe;    int i, result, start, end, start_blk, end_blk, logo_blk_offset;    uchar *sptr;        if (size > (SHARE_size<<2)) {	CPRINTF("UPDATE ROM TOO BIG", size);	return (0);    }        /* Some initializations */    result = FLASHBASE;    for (i=0; i<TOTALBLOCK; i++) {	FlashBlockAddress[i] = result;	result += FlashBlockSize;    }#ifdef FLASH_16BIT    COM_ADDR[0] = ((0x555 << 1) | FLASHBASE);    COM_ADDR[1] = ((0x2aa << 1) | FLASHBASE);#else    COM_ADDR[0] = (0x555 | FLASHBASE);    COM_ADDR[1] = (0x2aa | FLASHBASE);#endif    start_blk = 0;    end_blk = TOTALBLOCK; /* all of flash */#ifdef TEST    /* self-copy */    FlashRead(FlashBlockAddress[start_blk], 	      (void FHUGE *)dram_cached(SHARE_start), 	      FlashBlockSize*(end_blk-start_blk));#else    /* Read rom new file from CD to Share */    VBV_start = SHARE_start;    VBV_size  = SHARE_size;    VBV_end   = VBV_start + VBV_size;    OUTOSD(1, "READING NEW ROM", "READING NEW ROM", 0);    BREAKPOINT(size);    /* getSectors() limited by VBV size */    result = getSectors(where, (size+2047) >> 11, 2048);    /* 	-2:	force abort     *	-1:	failed dsa_go() or servo problem     *	 0:	no sync pattern     *	 1:	if successful     */    BREAKPOINT(result);    if (result < 1) return (0);#endif /* TEST */        if (VCX_emulator) {	/* do everything except write back to flash */	goto restart;    }    OUTOSD(1, "UPDATING FLASH", "UPDATING FLASH", 0);    /* Erase & Write back to flash the new rom file */    sptr = (uchar *)dram_cached(SHARE_start);    for (i=start_blk; i < end_blk; i++) {	if (FlashEraseBlock(i) != 0) goto restart;	result = FlashWriteBlock(0, FlashBlockAddress[i],				 sptr, FlashBlockSize);	if (result!=0) goto restart;	sptr+=FlashBlockSize;    }    for (i=0;i<2000000;i++) (void)*ptrDelay; /* Let this sink in */    if (result==0) {    	result = FlashVerify((int *)FlashBlockAddress[start_blk], 			     (int *)dram(SHARE_start), 			     (FlashBlockSize*(end_blk-start_blk))/4);    }restart:    /* Reboot if success */    if (result == 0) {	CPRINTF("FLASH UPDATED", glbTimer);	BREAKPOINT(0);	DSC_powerdown();    } else 	return (0);}#endif /* UPDATE_FLASH_ALL *//************************************************************************  Function:  Description:*************************************************************************/static int32 FlashRead(int32 FlashAddress, void FHUGE *ReadBuffer, 		       int32 ReadSize){    CPRINTF("READ FLASH FROM: ", FlashAddress);    memcpy((char *)ReadBuffer, (char *)FlashAddress, ReadSize);    return(ReadSize);}#ifdef FLASH_16BIT/************************************************************************  Function:  Description:*************************************************************************/static int FlashWriteBlock(int32 StartAddress,int32 target,			   char FHUGE *src,int32 size){    volatile ushort *targetPtr;    volatile ushort temp,temp2;    ushort data = 0;    int loop_count;    int i;    uchar *srcPtr;    srcPtr=(uchar *)src;    targetPtr = (volatile unsigned short*)(target|FLASHBASE);    for (i=0 ; i< size / 2; i++) {    	*(volatile unsigned short *)COM_ADDR[0]=0xaaaa;    	*(volatile unsigned short *)COM_ADDR[1]=0x5555;	*(volatile unsigned short *)COM_ADDR[0]=0xa0a0;	data = *srcPtr++;	data = (*srcPtr++ | (data << 8)) & 0xffff;		*(volatile unsigned short *) targetPtr = data;	loop_count=0;	while(1) {	    temp  = *(volatile short*)targetPtr;	    temp2 = *(volatile short*)targetPtr;	    if (( temp == temp2) && ( temp == data)) break;	    else if (++loop_count>WRITETIMEOUT) {		RESET_FLASH; 		return(-1);	    } 		};	targetPtr++;    }                                               RESET_FLASH;    return (0);}/************************************************************************  Function:  Description:*************************************************************************/static int FlashEraseBlock(int Block){    volatile ushort data;    int erase_retry = 0;	/* retry 3 times most */    int erase_error = 0;    int loop_count  = 0;    do {        *(volatile ushort *)COM_ADDR[0]=0xaaaa;        *(volatile ushort *)COM_ADDR[1]=0x5555;        *(volatile ushort *)COM_ADDR[0]=0x8080;        *(volatile ushort *)COM_ADDR[0]=0xaaaa;        *(volatile ushort *)COM_ADDR[1]=0x5555;        *(volatile ushort *)FlashBlockAddress[Block]=0x3030;	/*need 1ms delay before checking status */	risc_sleep_a_bit(MILLISECOND(1));	erase_error=0;	while(1) {	    data = *(volatile ushort*) FlashBlockAddress[Block];	    if ((data & 0x8080)==0x8080) break;	    else if (((data & 0x2020)==0x2020) || (++loop_count>ERASETIMEOUT)) { 		erase_error=1; 		break;	    }	} 	erase_retry++;    } while(erase_error && (erase_retry<3));	    RESET_FLASH;    if (erase_retry<3) return 0;    else return(-1);}#else/************************************************************************  Function:    This is for x8 configuration.  Description:*************************************************************************/static int FlashWriteBlock(int32 StartAddress,int32 target,			   char FHUGE *src,int32 size){    int loop_count;    int32 i;    char *srcPtr;    volatile int write_error = 0;    volatile char *targetPtr;    volatile char temp,temp2;    volatile int done;    write_error = 0;     srcPtr=(char *)src;    targetPtr = (volatile char*)(target|FLASHBASE);    for (i=0 ; i<size; i++,srcPtr++,targetPtr++)    {    	*(volatile char *)COM_ADDR[0]=0xaa;    	*(volatile char *)COM_ADDR[1]=0x55;	*(volatile char *)COM_ADDR[0]=0xa0;	*(volatile char *)targetPtr = *srcPtr;	done=0;	loop_count=0;	do	{	    temp=*(volatile char*)targetPtr;	    temp2=*(volatile char*)targetPtr;	    if ((temp==temp2) && (temp==*srcPtr)) done = 1;	    else if (++loop_count>WRITETIMEOUT)		 {		    write_error=-1;		    RESET_FLASH; 		    return(-1);		 } 		} while(!done);    }                                            RESET_FLASH;    return (write_error);}static int FlashEraseBlock(int Block){    int erase_retry = 0;	/* retry 3 times most */    volatile char data;    volatile int erase_error = 0;    int loop_count=0;    do {        *(volatile char *)COM_ADDR[0]=0xaa;        *(volatile char *)COM_ADDR[1]=0x55;        *(volatile char *)COM_ADDR[0]=0x80;        *(volatile char *)COM_ADDR[0]=0xaa;        *(volatile char *)COM_ADDR[1]=0x55;        *(volatile char *)FlashBlockAddress[Block]=0x30;	/*need 1ms delay before checking status */	risc_sleep_a_bit(MILLISECOND(1));	erase_error=0;	while(1)	{	    data=*(volatile char*)FlashBlockAddress[Block];	    if (data&0x80) break;	    if ((data&0x20) || (++loop_count>ERASETIMEOUT)) 	    { 		erase_error=1; 		break;	    }	} 	erase_retry++;    }while(erase_error && (erase_retry<3));	    RESET_FLASH;    if (erase_retry<3) return 0;    else return(-1);}#endif FLASH_16BIT/***************************************************************************** Check the result *****************************************************************************/static int FlashVerify(int *copy, int *orig, int size){    int i;    copy++; orig++;    for (i=1; i<size/4; i++) {	if (*copy++ != *orig++) {#ifdef FLASH_16BIT	    if (VCX_emulator && (i != size/4 - 21))#endif	    return(-3);	}    }    return(0);}#endif FLASH_UPDATE

⌨️ 快捷键说明

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