📄 flashop_intel320_.c
字号:
int FWBLock(bit32u from,bit32 size)
{
bit32u *uip,uitmp;
int sts;
bit32u ad,to,blocksize;
if (size==0) return(TRUE);
to=from+size;
blocksize=FWBGetBlockSize(from);
from&=~(blocksize-1);
for(sts=0,ad=from;(ad<to)&&(!sts)&&(blocksize);ad+=blocksize)
{
uip=(bit32u *)ad;
uitmp=*uip;
MEM_WRITE(ad,FLASH_LOCK_CMD);
MEM_WRITE(ad,FLASH_LOCK);
sts&=_FlashOperationComplete(ad,uitmp,650*FLASH_MAX_WAIT);
_FlashErrorOut("Lock Block",sts);
blocksize=FWBGetBlockSize(ad);
}
return(sts==0);
}
int FWBGetBlockSize(bit32u base)
{
int itmp = 0;
base&=0x1fffffff;
base|=0xa0000000;
if ((base >= CS0_BASE) && (base<(CS0_BASE+total_flash)) )
{
if(base >= (CS0_BASE+FLASH2_OFFSET)) /* bank 2 */
{
base -= (CS0_BASE+FLASH2_OFFSET);
if(base <= flash_size[1])
{
if( base >= (flash_size[1] -FLASH_SECTOR_SIZE))
{
itmp = FLASH_ENV_SECTOR_SIZE;
}
else
{
itmp = FLASH_SECTOR_SIZE;
}
}
}
else
{
base -= CS0_BASE;
if(base <= flash_size[0])
{
if( base >= (flash_size[0] -FLASH_SECTOR_SIZE))
{
itmp = FLASH_ENV_SECTOR_SIZE;
}
else
{
itmp = FLASH_SECTOR_SIZE;
}
}
}
}
return(itmp);
}
/* This function returns back the next block/sector in flash */
bit32u FWBGetNextBlock(bit32u base)
{
bit32u current_blk_sz;
bit32u new_blk;
base&=0x1fffffff;
base|=0xa0000000;
current_blk_sz = FWBGetBlockSize(base);
if(current_blk_sz == 0)
{
return(0);
}
base &= ~(current_blk_sz-1);
new_blk = base + current_blk_sz;
/* Does the new block belong in the next bank? */
if( (base < (CS0_BASE + flash_size[0]))
&& (new_blk >= (CS0_BASE + flash_size[0])))
{
new_blk = CS0_BASE+FLASH2_OFFSET;
}
return(new_blk);
}
/* Start at base and erase at least size bytes */
int FWBErase(bit32u base,int size, int verbose)
{
bit32u i,sts,blocksize,from;
bit32u erased_bytes = 0;
FWBopen=FALSE;
if (size==0)
return(0);
size--;
from = base;
/* Check if we have a valid flash address */
blocksize = FWBGetBlockSize(base);
if ( (FWBGetBlockSize(from)==0) || (blocksize == 0) )
{
sys_printf ("Invalid flash address %x\n",from);
return(0);
}
MEM_WRITE(EPLD_FLASH_WP,1); /* Enable write on EPLD */
from&=~(blocksize-1);
if (verbose) sys_printf ("FlashEraseBlock(%08x);\n",from);
for(i=from,sts=0;(erased_bytes <size)&&(!sts);)
{
MEM_WRITE(i,FLASH_LOCK_CMD);
MEM_WRITE(i,FLASH_UNLOCK);
MEM_WRITE(i,FLASH_READ_CMD);
MEM_WRITE(i,FLASH_ERASE_SECTOR);
MEM_WRITE(i,FLASH_COMMIT_CMD);
MEM_WRITE(i,FLASH_READ_STAT_CMD);
sts = _FlashOperationComplete(i,0xffffffff,FLASH_MAX_WAIT*5000000);
_FlashErrorOut("Erase Block",sts);
/*sys_printf ("%08x\n",i);*/
if (verbose) sys_printf (".");
MEM_WRITE(i,FLASH_READ_CMD);
erased_bytes += FWBGetBlockSize(i);
i=FWBGetNextBlock(i);
if (i == 0)
{
if (verbose) sys_printf ("invalid flash address %x\n",i);
MEM_WRITE(EPLD_FLASH_WP,0);
return(0);
}
}
MEM_WRITE(EPLD_FLASH_WP,0);
return(sts==0);
}
int FWBOpen(bit32u base)
{
int i;
FWBopen=FALSE;
if (FWBGetBlockSize(base)==0)
return(FALSE);
for(i=0;i<64;i++)
FWBwdata[i]=(char)0xff;
FWBBaseAdr=0xffffffff;
FWBvalid=0;
FWBopen=TRUE;
return(TRUE);
}
int FWBWriteByte(bit32u adr, bit8 cVal)
{
int sts,i;
bit32u *isp,*idp;
if (!FWBopen)
return(FALSE);
sts=TRUE;
if((adr&(~0x3f))!=FWBBaseAdr)
sts=FWBClose();
if (FWBvalid==0)
{
for(i=0,isp=(bit32u *)(adr&~0x3f),idp=(bit32u *)FWBwdata;i<16;i++)
*idp++=*isp++;
}
sys_printf ("FWBWriteByte(%x,%x);\n",adr,cVal&0x0ff);
FWBBaseAdr=adr&(~0x3f);
i=adr&0x3f;
FWBvalid++;
FWBwdata[i]=cVal;
return(sts);
}
int FWBClose(void)
{
int sts,i;
if (!FWBopen)
return(FALSE);
if (FWBvalid==0)
return(TRUE);
for(i=0,sts=1;(sts)&&(i<5);i++)
{
sts=_FWBWriteBlock();
if (sts)
{
MEM_WRITE(FWBBaseAdr,FLASH_READ_CMD);
MEM_WRITE(FWBBaseAdr,FLASH_CLEAR_SR_CMD);
}
}
_FlashErrorOut("Program Block",sts);
for(i=0;i<64;i++)
FWBwdata[i]=(char)0xff;
FWBBaseAdr=0xffffffff;
FWBvalid=0;
return(sts==0);
}
/*Used to decode Flash error values */
void _FlashErrorOut(char *str,int sts)
{
if (sts)
sys_printf ("Flash '%s' operation Failed: sts=%08x\n",str,sts);
}
/*Returns 0 for success and !=0 for error */
int _FWBWriteBlock(void)
{
int icount,i,done;
bit32u *uip,uitmp;
MEM_WRITE(EPLD_FLASH_WP,1); /* Enable write on EPLD */
MEM_WRITE(FWBBaseAdr,FLASH_LOCK_CMD);
MEM_WRITE(FWBBaseAdr,FLASH_UNLOCK);
for(uip=(bit32u *)FWBwdata,i=0;i<16;i++,uip++)
{
/* wait until the WSMS state is ready for more data */
icount=0;
do
{
uitmp=MEM_READ(FWBBaseAdr);
done = ((uitmp&FLASH_WSMS)==FLASH_WSMS);
if ((!done)&&(icount>(FLASH_MAX_WAIT*650)))
return(0xeeee0002);
icount++;
}while(!done);
MEM_WRITE(FWBBaseAdr+(i*4),FLASH_WRITE_CMD);
MEM_WRITE(FWBBaseAdr+(i*4),*uip);
}
icount=0;
do
{
uitmp=MEM_READ(FWBBaseAdr);
done = ((uitmp&FLASH_WSMS)==FLASH_WSMS);
if ((!done)&&(icount>(FLASH_MAX_WAIT*650)))
return(0xeeee0002);
icount++;
}while(!done);
uip=(bit32u *)FWBwdata;
MEM_WRITE(FWBBaseAdr,FLASH_READ_CMD);
MEM_WRITE(FWBBaseAdr,FLASH_LOCK_CMD);
MEM_WRITE(FWBBaseAdr,FLASH_LOCK);
MEM_WRITE(FWBBaseAdr,FLASH_READ_STAT_CMD);
MEM_WRITE(EPLD_FLASH_WP,0); /* Disable write on EPLD */
return(_FlashOperationComplete(FWBBaseAdr,*uip,FLASH_MAX_WAIT*650));
}
/*Returns 0 for success and !=0 for failure */
int _FlashOperationComplete(bit32u adr,bit32u dat,int timeoutloops)
{
bit32u sts,fnd;
int icount=0;
int err;
int i;
do
{
if (++icount>timeoutloops)
{
MEM_WRITE(adr,FLASH_READ_CMD); /*Reset to read mode */
return(0xeeee0001);
}
sts=MEM_READ(adr);
if ((sts&FLASH_WSMS)==FLASH_WSMS)
{
/* Check for errors */
err = (sts&FLASH_ERROR_MASK);
MEM_WRITE(adr,FLASH_READ_CMD); /*Reset to read mode */
if (!err)
{
for(i= 0; i < 20; i++)
{
fnd=MEM_READ(adr);
if (fnd==dat)
return(0);
}
}
else
MEM_WRITE(adr,FLASH_CLEAR_SR_CMD); /*Reset error bits */
MEM_WRITE(adr,FLASH_READ_CMD); /*Reset to read mode */
return(sts);
}
}while(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -