?? flash.c
字號:
// Indicate status
EdbgOutputDebugString( "-OEMStartEraseFlash(rc=1)\r\n" );
return TRUE;
}
//------------------------------------------------------------------------------
// Function: OEMFinishEraseFlash
//
// Desc...
//
BOOL OEMFinishEraseFlash( void )
{
BOOL rc;
EdbgOutputDebugString( "+OEMFinishEraseFlash\r\n" );
if( !gnBlocks )
{
EdbgOutputDebugString( "ERROR: OEMFinishEraseFlash: not initialized\r\n" );
return( FALSE );
}
// Continue erasing flash until all blocks are erased
while( (gnRetries < MAX_RETRIES) && (gnBlocks != gnErased) )
{
OEMContinueEraseFlash();
}
// Indicate status
rc = (gnBlocks == gnErased);
EdbgOutputDebugString( "-OEMFinishEraseFlash(rc=%d)\r\n", rc );
return( rc );
}
//------------------------------------------------------------------------------
// Function: name( args )
//
// Desc...
//
void OEMContinueEraseFlash (void)
{
volatile DWORD *pdwSR;
char *pszErrorMsg;
BOOL bByteMode = dwFlashPageSize == 32 ? TRUE : FALSE; // See FlashPageWrite_IntelStrata().
// EdbgOutputDebugString( "+OEMContinueEraseFlash\r\n" );
pdwSR= (DWORD *)(gdwFlashAreaBase + dwBlockIndex * dwFlashBlockSize);
// TBD - the following 2 tests don't appear necessary looking at
// TBD - above function.
if( !gnBlocks || (gnBlocks == gnErased) )
{
EdbgOutputDebugString( "ERROR: OEMCcontinueEraseFlash: done or not initialized\r\n" );
return;
}
if( gnRetries >= MAX_RETRIES )
{
EdbgOutputDebugString( "ERROR: OEMCcontinueEraseFlash: exceeded retries\r\n" );
return;
}
// Now fill the command queue with erase block commands
// Converting Block to address
switch( gStatus[dwBlockIndex] )
{
case eDIRTY:
// Initialize reading of ESRs
FlashWriteCommand(pdwSR, bByteMode ? 0x70707070 : 0x00700070);
// If the block is busy, come back to it later
if ( FlashSR1(pdwSR, bByteMode ? 0x80808080 : 0x00800080) )
{
// Tell it to erase the next block
FlashWriteCommand(pdwSR, bByteMode ? 0x20202020 : 0x00200020);
FlashWriteCommand(pdwSR, bByteMode ? 0xD0D0D0D0 : 0x00D000D0);
gStatus[dwBlockIndex]=ePENDING;
}
break;
case ePENDING:
// Initialize reading of ESRs
FlashWriteCommand(pdwSR, bByteMode ? 0x70707070 : 0x00700070);
// If the block is busy, come back to it later
if( FlashSR1(pdwSR, bByteMode ? 0x80808080 : 0x00800080) )
{
// Check for operation errors
if( FlashError( pdwSR, &pszErrorMsg ) )
{
// This will make the routine loop back and try to erase the block again.
gStatus[dwBlockIndex] = eDIRTY;
EdbgOutputDebugString( "ERROR: Attempting To Erase Block %u: %s\r\n", dwBlockIndex, pszErrorMsg );
gnRetries++;
}
else
{
// Success. advance to next block
// EdbgOutputDebugString( "eERASED:%u\r\n", dwBlock );
EdbgOutputDebugString( "INFO: eERASED:%u (%X)\r\n", dwBlockIndex, pdwSR );
gStatus[dwBlockIndex] = eERASED;
gnErased ++;
dwBlockIndex++;
};
}
break;
case eERASED:
break; // already erased
default:
// Erasing a written block!! should never happen
EdbgOutputDebugString ("ERROR: Flash block %u written and erased again!!!\r\n", dwBlockIndex);
return;
}
}
//------------------------------------------------------------------------------
// Function: name( args )
//
// Desc...
//
void DumpDwords(PDWORD pdw, int len)
{
int lc;
lc = 0;
EdbgOutputDebugString("Dumpping %d dwords", len);
for( lc = 0 ; len ; ++pdw, ++lc, --len )
{
if( !(lc & 3) )
EdbgOutputDebugString("\r\n%X -", pdw);
EdbgOutputDebugString(" %X", *pdw);
}
EdbgOutputDebugString("\r\n");
}
UINT16 FlashError_IntelStrata( volatile DWORD *pdwSR, char **ppszErrorMsg )
{
BOOL bByteMode = dwFlashPageSize == 32 ? TRUE : FALSE; // See FlashPageWrite_IntelStrata().
BOOL bError = FALSE;
int reason = 0;
// Read Status Register command
FlashWriteCommand(pdwSR, bByteMode ? 0x70707070UL : 0x00700070);
// Check DEVICE PROTECT STATUS
if (!FlashSR0(pdwSR, bByteMode ? 0x02020202 : 0x00020002)) reason += 1;
// Check PROGRAMMING VOLTAGE STATUS
if (!FlashSR0(pdwSR, bByteMode ? 0x08080808 : 0x00080008)) reason += 2;
// Check PROGRAMMING AND SET LOCK-BIT STATUS
if (!FlashSR0(pdwSR, bByteMode ? 0x10101010 : 0x00100010)) reason += 4;
// Check ERASE AND CLEAR LOCK-BITS STATUS
if (!FlashSR0(pdwSR, bByteMode ? 0x20202020 : 0x00200020)) reason += 8;
switch (reason) {
case 0: // no error
return 0;
case 4: // simple programming error
*ppszErrorMsg = "Device programming error.";
break;
case 8: // simple erasing error
*ppszErrorMsg = "Device erasing error.";
break;
case 5: // write failed by block protection
case 9: // erase failed by block protection
*ppszErrorMsg = "This block is protected.";
break;
case 6: // write failed by low Vpen
case 10:// erase failed by low Vpen
*ppszErrorMsg = "Vpen is low, cannot erase/program device.";
break;
case 12: // command sequence error
*ppszErrorMsg = "Bad command sequence.";
break;
case 13:
// I don't know why, but actually Intel 28F128J3A device returns
// 0xAA error status in lock bit clear when Vpen is low.
*ppszErrorMsg = "Vpen is low, cannot erase/program device";
break;
default: // unexpected state
*ppszErrorMsg = "Unexpected device state.";
break;
}
FlashWriteCommand(pdwSR, 0x50505050UL); // Clear Status Register command
// If the error is simple erase or write error, allows retry.
if (reason == 4 || reason == 8) return 1;
else return 2; // fatal error
}
UINT16 FlashWrite_IntelStrata( DWORD dwPhysStart, DWORD dwPhysLen, char **ppszErrorMsg )
{
DWORD *pdwFlashCache;
volatile DWORD *pdwFlash;
DWORD dwStartBlock, dwEndBlock, dwBlocksLeft, dwFirstBlockOffset, dwDWORDsLeft;
DWORD dwFlashAreaBase;
DWORD i;
BOOL bErasing=TRUE;
DWORD dwStart;
if (CheckFlashWriteProtect()) {
*ppszErrorMsg = "Error : write protected.";
return 1;
}
dwFlashAreaBase = (dwPhysStart & 0x1C000000) | UNCACHED_BASE; // top of each area
dwStartBlock = (dwPhysStart & (0x04000000 - dwFlashBlockSize)) / dwFlashBlockSize;
dwEndBlock = ((dwPhysStart + dwPhysLen) & (0x04000000 - dwFlashBlockSize)) / dwFlashBlockSize;
dwBlocksLeft = dwEndBlock - dwStartBlock + 1;
// Calculate how far from the beginning of the first block the starting address falls
dwFirstBlockOffset = dwPhysStart & (dwFlashBlockSize - 1);
EdbgOutputDebugString("FlashWrite: dwStartBlock %d dwEndBlock %d dwBlocksLeft %d dwFirstBlockOffset %Xh\r\n",
dwStartBlock, dwEndBlock, dwBlocksLeft, dwFirstBlockOffset);
// protect BLOCK 0 (ethernet bootloader block)
if (dwStartBlock == 0 && dwFlashAreaBase == (AREA_0 + UNCACHED_BASE)) {
*ppszErrorMsg = "Error : Block 0 is the bootloader block. Check the image start address.";
return 1;
}
while (bErasing) {
bErasing=FALSE;
for (i = dwStartBlock; i <= dwEndBlock; i++) {
if (gStatus[i] != eERASED) {
bErasing=TRUE;
OEMContinueEraseFlash();
}
}
}
dwStart= OEMEthGetSecs();
while (OEMEthGetSecs() - dwStart < 3) ;
while (dwBlocksLeft) {
for (i = dwStartBlock; i <= dwEndBlock; i++) {
EdbgOutputDebugString( "FlashWrite: Block %d\r\n", i );
// Attempt to flash all erased blocks
if (gStatus[i] == eERASED) {
// Set up the FlashCache pointer and number of words to write
// If this is the first block, we need to start further along
if (i == dwStartBlock) {
pdwFlash = (DWORD *)(dwPhysStart | UNCACHED_BASE);
pdwFlashCache = (DWORD*)FLASH_CACHE;
dwDWORDsLeft = (dwFlashBlockSize - dwFirstBlockOffset) / 4;
// If the whole image is less than one block long
if (dwDWORDsLeft > dwPhysLen / 4)
dwDWORDsLeft = dwPhysLen / 4;
}
else {
pdwFlash = (DWORD *)(dwFlashAreaBase + i * dwFlashBlockSize);
pdwFlashCache = (DWORD*)(FLASH_CACHE
+ (i - dwStartBlock) * dwFlashBlockSize - dwFirstBlockOffset);
// If this is the last block we need to cut short the number of DWORDs written
if (i == dwEndBlock) dwDWORDsLeft = (dwPhysLen % dwFlashBlockSize) / 4;
else dwDWORDsLeft = dwFlashBlockSize / 4;
}
if (FlashPageWrite_IntelStrata(pdwFlash, pdwFlashCache, dwDWORDsLeft, ppszErrorMsg))
return 1;
dwBlocksLeft--;
gStatus[i] = eFLASHED;
} // If the block was successfully erased
}
} // while there are still blocks left to program
// Close out all the pages. Wait until they have finished programming and then compare them against
// the cache image for consistency.
if (FlashClose_IntelStrata((dwPhysStart | UNCACHED_BASE), dwPhysLen, ppszErrorMsg)) return 1;
else return 0;
}
UINT16 FlashPageWrite_IntelStrata(
volatile DWORD *pdwFlash,
DWORD *pdwFlashCache,
DWORD dwDWORDsLeft,
char **ppszErrorMsg )
{
volatile DWORD *pdwSR;
DWORD i, dwCount;
BOOL bByteMode = dwFlashPageSize == 32 ? TRUE : FALSE;
// Strata series has 4 word or 8 byte page buffer for programming (J5/J3) and
// reading (J3 only). In byte mode (4 devices in 32-bit bus), page size is set
// to 32 bytes, and in word mode (2 devices in 32-bit bus), it is set to 16.
if (CheckFlashWriteProtect()) {
*ppszErrorMsg = "Error : write protected.";
return 1;
}
pdwSR = (DWORD*)( ((DWORD)pdwFlash) & (~(dwFlashBlockSize - 1)) ); // 32bit
EdbgOutputDebugString( "FlashPageWrite: From %Xh to %Xh Length %Xh\r\n",
pdwFlashCache, pdwFlash, dwDWORDsLeft*4);
// Loop until we've written the entire page
while ( (long)dwDWORDsLeft > 0 ) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -