📄 _flash.c
字号:
/****************************************************************
* *
* Program : FLASH.C *
* *
* Purpose : Handler for SST39VF800AT Flash memory. *
* *
* Compile : ARM SDT Ver2.51 *
* *
* Version : 1.00 *
* *
* Create : 2002-09-01 Sunday By KWM *
* *
* Copyright (C) 2002 Amnokgang Technology Development Corp. *
* All Rights Reserved. *
* *
****************************************************************/
#include <string.h>
#include "_MyType.H"
#include "_Bios.H"
#define FlashSector_SZ 0x1000
WORD gFlashWriteBuff[FlashSector_SZ/2];
WORD gFlashEraseBuff[FlashSector_SZ/2];
/*========================================================================
Function : EraseFlashChip
Description :
Return type : BOOL
Argument
(In/Out) : void *apDst
// Create : 2003-01-23 8:40:55 AM By KWM
========================================================================*/
BOOL EraseFlashChip( void *apDst )
{
// Watchdog timer reset
*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x5555<<1) ) = 0xaa;
*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x2aaa<<1) ) = 0x55;
*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x5555<<1) ) = 0x80;
*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x5555<<1) ) = 0xaa;
*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x2aaa<<1) ) = 0x55;
*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x5555<<1) ) = 0x10;
/* DQ7: Data# Polling */
while( ((*(volatile WORD *)apDst)&0x80) == 0 ) ;
return TRUE;
}
/*========================================================================
// Function : EraseFlashSector
// Description : Erase Sector.
// Return type : BOOL
// Argument
// ( In ) : apSrc=Address of data(64K) to write.
// ( In ) : apDst=First address of flash sector to write.
// Date : 2002/06/13 PM 5:30 - Ver.1.0 - By Kim Won Myong
//========================================================================*/
BOOL EraseFlashSector( void *apDst )
{
WORD vToggle;
// volatile int i;
// Watchdog timer reset
memset( gFlashEraseBuff, 0xff, FlashSector_SZ );
if( memcmp( gFlashEraseBuff, apDst, FlashSector_SZ ) == 0 ) return TRUE;
*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x5555<<1) ) = 0xaaaa;
*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x2aaa<<1) ) = 0x5555;
*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x5555<<1) ) = 0x8080;
*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x5555<<1) ) = 0xaaaa;
*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x2aaa<<1) ) = 0x5555;
*(volatile WORD *)((DWORD)apDst & 0xfffff000) = 0x30;
while(1)
{
vToggle = *(volatile WORD *)((DWORD)apDst & 0xfffff000) & 0x40;
if( vToggle != (*(volatile WORD *)((DWORD)apDst & 0xfffff000) & 0x40) ) //D6 == D6
continue;
// DQ7: Data# Polling
if( (*(volatile WORD *)((DWORD)apDst & 0xfffff000)) & 0x80 )
break; //D7 == 1
}
// for( i=0; i<100;i++){ mcrCPULED_ON; };
return TRUE;
}
/*========================================================================
// Function : FlashWriteWord
// Description : Write 1byte to flash.
// Return type : BOOL
// Argument
// ( In ) : apSrc=Address of data(64K) to write.
// ( In ) : apDst=First address of flash sector to write.
// Date : 2002/06/13 PM 5:30 - Ver.1.0 - By Kim Won Myong
//========================================================================*/
BOOL FlashWriteWord( void *apDst, WORD aData )
{
WORD vToggle;
if( *(WORD *)apDst == aData ) return TRUE;
*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x5555<<1) ) = 0xaa;
*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x2aaa<<1) ) = 0x55;
*(volatile WORD *)( ((DWORD)apDst & 0xffff0000) + (0x5555<<1) ) = 0xa0;
*(volatile WORD *)apDst = aData;
while(1)
{
vToggle = *(volatile WORD *)apDst & 0x40;
if( vToggle != *(volatile WORD *)apDst & 0x40 ) //D6 == D6
continue;
// DQ7: Data# Polling
if( ((*(volatile WORD *)apDst) & 0x80) == (aData & 0x80) )
break; //D7 == D7
}
return TRUE;
}
/*========================================================================
// Function : UpdateFlashSector
// Description : Erase and Write the any sector of flash memory.
// Return type : BOOL
// Argument
// ( In ) : apSrc=Address of data(64K) to write.
// ( In ) : apDst=First address of flash sector to write.
// Date : 2002/06/13 PM 5:30 - Ver.1.0 - By Kim Won Myong
//========================================================================*/
BOOL UpdateFlashSector( void *apSrc, void *apDst )
{
// register int vLoop;
// register WORD *vpSrc = (WORD *)apSrc;
// register WORD *vpDst = (WORD *)apDst;
int vLoop;
WORD *vpSrc = (WORD *)apSrc;
WORD *vpDst = (WORD *)apDst;
if( memcmp( apSrc, apDst, FlashSector_SZ ) == 0 ) return TRUE;
EraseFlashSector( apDst );
vLoop = FlashSector_SZ/2;
while( vLoop-- ){
FlashWriteWord( vpDst++, *vpSrc++ );
}
if( memcmp( apSrc, apDst, FlashSector_SZ ) == 0 ) return TRUE;
return FALSE;
}
/*========================================================================
// Function : WriteFlashSmallThanSector
// Description :
// Return type : BOOL
// Argument
// (In ) : void *apSrc
// (In ) : void *apDst
// (In ) : int aSize
// Create : 2002-09-12 6:09:24 PM By Kim Won Myong
//========================================================================*/
BOOL WriteFlashSmallThanSector( void *apSrc, void *apDst, int aSize )
{
// register DWORD vpSectStart, vpOffset, vBytes;
DWORD vpSectStart, vpOffset, vBytes;
/* when destination address is sector boundary */
if( ((DWORD)apDst%FlashSector_SZ) == 0 ){
memcpy( gFlashWriteBuff, apDst, FlashSector_SZ ) ;
memcpy( gFlashWriteBuff, apSrc, aSize ) ;
return UpdateFlashSector( gFlashWriteBuff, apDst );
}
/* when destination address is not sector boundary */
vpSectStart = (DWORD)apDst / FlashSector_SZ * FlashSector_SZ;/*Start address of sector with [apDst]*/
vpOffset = (DWORD)apDst % FlashSector_SZ;/*Offset of modify data in buffer */
vBytes = FlashSector_SZ - vpOffset;/*Bytes of modify data in buffer */
if( vBytes >= aSize ){
/* when there is in one sector */
memcpy( gFlashWriteBuff, (void*)vpSectStart, FlashSector_SZ );/* Get that sector data */
memcpy( (void*)((DWORD)gFlashWriteBuff+vpOffset), apSrc, aSize );/*modify data to 1st sector */
return UpdateFlashSector( gFlashWriteBuff, (void*)vpSectStart );/* write to flash */
}
else{
/* when there is in two sector */
/* 1st sector write */
memcpy( gFlashWriteBuff, (void*)vpSectStart, FlashSector_SZ );/* Get that sector data */
memcpy( (void*)((DWORD)gFlashWriteBuff+vpOffset), apSrc, vBytes );/*modify data to 1st sector */
if( !UpdateFlashSector( gFlashWriteBuff, (void*)vpSectStart ) ) return FALSE;/* write to flash */
/* next sector write */
memcpy( gFlashWriteBuff, (void*)((DWORD)apDst+vBytes), FlashSector_SZ ) ;
memcpy( gFlashWriteBuff, (void*)((DWORD)apSrc+vBytes), aSize-vBytes ) ;
return UpdateFlashSector( gFlashWriteBuff, (void*)((DWORD)apDst+vBytes) );
}
}
/*========================================================================
// Function : WriteFlash
// Description :
// Return type : BOOL
// Argument
// (In/Out) : void *apSrc
// (In/Out) : void *apDst
// (In/Out) : int aSize
// Create : 2002-09-12 12:02:51 PM By Kim Won Myong
//========================================================================*/
BOOL WriteFlash( void *apSrc, void *apDst, int aSize )
{ DWORD vpData, vpFlash;
DWORD vLoop, vnSector;
/* aSize < FlashSector_SZ */
if( aSize <= FlashSector_SZ ){
if( !WriteFlashSmallThanSector( apSrc, apDst, aSize ) ) return FALSE;
Delay_Nms(10);
return TRUE;
}
vpData = (DWORD)apSrc;
vpFlash = (DWORD)apDst;
/* when destination address is not sector boundary */
if( ((DWORD)apDst%FlashSector_SZ) != 0 ){
register DWORD vBytes;
vBytes = FlashSector_SZ - ((DWORD)apDst%FlashSector_SZ); /* Bytes of data to write in that sector */
if( !WriteFlashSmallThanSector( apSrc, apDst, vBytes ) ) return FALSE;
vpData += vBytes;/* move src pointer */
vpFlash += vBytes;/* move dest pointer */
aSize -= vBytes;
}
/* when destination address is sector boundary */
vnSector = aSize / FlashSector_SZ;
for( vLoop=0; vLoop<vnSector; vLoop++ ){
if( !WriteFlashSmallThanSector( (void *)vpData, (void *)vpFlash, FlashSector_SZ ) ) return FALSE;
vpData += FlashSector_SZ;
vpFlash += FlashSector_SZ;
}
/* remainder */
if( (aSize%FlashSector_SZ) == 0 ) {Delay_Nms(10); return TRUE;}
if( !WriteFlashSmallThanSector( (void *)vpData, (void *)vpFlash, (aSize%FlashSector_SZ) ) ) return FALSE;
Delay_Nms(10);
return TRUE;
}
/*========================================================================
// Function : EraseFlashSmallThanSector
// Description :
// Return type : BOOL
// Argument
// (In ) : void *apDst
// (In ) : int aSize
// Create : 2002-09-12 6:09:24 PM By Kim Won Myong
//========================================================================*/
BOOL EraseFlashSmallThanSector( void *apDst, int aSize )
{
// register DWORD vpSectStart, vpOffset, vBytes;
DWORD vpSectStart, vpOffset, vBytes;
char *apSrc=(char*)gFlashEraseBuff;
memset( gFlashEraseBuff, 0xff, sizeof(gFlashEraseBuff) );
/* when destination address is sector boundary */
if( ((DWORD)apDst%FlashSector_SZ) == 0 ){
memcpy( gFlashWriteBuff, apDst, FlashSector_SZ ) ;
memcpy( gFlashWriteBuff, apSrc, aSize ) ;
return UpdateFlashSector( gFlashWriteBuff, apDst );
}
/* when destination address is not sector boundary */
vpSectStart = (DWORD)apDst / FlashSector_SZ * FlashSector_SZ;/*Start address of sector with [apDst]*/
vpOffset = (DWORD)apDst % FlashSector_SZ;/*Offset of modify data in buffer */
vBytes = FlashSector_SZ - vpOffset;/*Offset of modify data in buffer */
if( vBytes >= aSize ){
/* when there is in one sector */
memcpy( gFlashWriteBuff, (void*)vpSectStart, FlashSector_SZ );/* Get that sector data */
memcpy( (void*)((DWORD)gFlashWriteBuff+vpOffset), apSrc, aSize );/*modify data to 1st sector */
return UpdateFlashSector( gFlashWriteBuff, (void*)vpSectStart );/* write to flash */
}
else{
/* when there is in two sector */
/* 1st sector write */
memcpy( gFlashWriteBuff, (void*)vpSectStart, FlashSector_SZ );/* Get that sector data */
memcpy( (void*)((DWORD)gFlashWriteBuff+vpOffset), apSrc, vBytes );/*modify data to 1st sector */
if( !UpdateFlashSector( gFlashWriteBuff, (void*)vpSectStart ) ) return FALSE;/* write to flash */
/* next sector write */
memcpy( gFlashWriteBuff, (void*)((DWORD)apDst+vBytes), FlashSector_SZ ) ;
memcpy( gFlashWriteBuff, (void*)((DWORD)apSrc+vBytes), aSize-vBytes ) ;
return UpdateFlashSector( gFlashWriteBuff, (void*)((DWORD)apDst+vBytes) );
}
}
/*========================================================================
// Function : EraseFlash
// Description :
// Return type : BOOL
// Argument
// (In/Out) : void *apDst
// (In/Out) : int aSize
// Create : 2002-09-12 12:02:51 PM By Kim Won Myong
//========================================================================*/
BOOL EraseFlash( void *apDst, int aSize )
{ DWORD vpFlash;
DWORD vLoop, vnSector;
/* aSize < FlashSector_SZ */
if( aSize <= FlashSector_SZ ){
return EraseFlashSmallThanSector( apDst, aSize );
}
vpFlash = (DWORD)apDst;
/* when destination address is not sector boundary */
if( ((DWORD)apDst%FlashSector_SZ) != 0 ){
register DWORD vBytes;
vBytes = FlashSector_SZ - ((DWORD)apDst%FlashSector_SZ); /* Bytes of data to write in that sector */
if( !EraseFlashSmallThanSector( apDst, vBytes ) ) return FALSE;
vpFlash += vBytes;/* move dest pointer */
aSize -= vBytes;
}
/* when destination address is sector boundary */
vnSector = aSize / FlashSector_SZ;
for( vLoop=0; vLoop<vnSector; vLoop++ ){
if( !EraseFlashSector( (void *)vpFlash ) ) return FALSE;
vpFlash += FlashSector_SZ;
}
/* remainder */
if( (aSize%FlashSector_SZ) == 0 ) return TRUE;
return EraseFlashSmallThanSector( (void *)vpFlash, (aSize%FlashSector_SZ) );
}
/*========================================================================
// Function : GetFlashSectorSize
// Description :
// Return type : DWORD
// Argument
// (In ) : Chip
// ( Out) : aSize
// Create : 2004-10-25 12:02:51 PM By S.I.G
//========================================================================*/
DWORD GetFlashSectorSize( void )
{
return FlashSector_SZ;
}
/****************************************************************
*
* End of file : FLASH.C
*
****************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -