📄 flash.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 + -