ethdown.c
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 914 行 · 第 1/3 页
C
914 行
FlashWriteCommand(pdwBSR, 0xFFFFFFFFUL);
return 1;
}
if (!FlashBSR0(pdwBSR,0x00100010UL) || !FlashBSR0(pdwBSR,0x00200020UL)) {
*ppszErrorMsg = "FLASH_CONT_ERASE Operation Aborted";
FlashWriteCommand(pdwBSR, 0x50505050UL);
// Reset flash to normal mode
FlashWriteCommand(pdwBSR, 0xFFFFFFFFUL);
return 1;
}
return 1;
} // FlashError()
// The Intel 28F016SV flash chip has twin 256 byte (128 16-bit words) page buffers that can be
// filled with data and then programmed into the flash array. This is faster than issuing
// single address flash commands. This routine will take the data passed in and queue it up
// in the page buffers of twin the flash chips. Once those are full, or I've reached a 256 byte
// address boundary, I'll give the command to burn the data into the flash array and start
// filling the other page buffer.
UINT16 FlashWrite( DWORD dwPhysStart, DWORD dwPhysLen, char **ppszErrorMsg )
{
DWORD *pdwFlashCache;
volatile DWORD *pdwFlash;
DWORD dwStartBlock, dwEndBlock, dwBlocksLeft, dwFirstBlockOffset, dwDWORDsLeft;
DWORD i;
BOOL bErasing=TRUE;
DWORD dwStart;
if(CheckFlashWriteProtect()) {
*ppszErrorMsg = "Error : write protected.";
return 1;
}
dwStartBlock = (dwPhysStart & 0x01FE0000UL) / FLASH_BLOCK_SIZE;
dwEndBlock = ((dwPhysStart + dwPhysLen) & 0x01FE0000UL) / FLASH_BLOCK_SIZE;
// dwStartBlock = (dwPhysStart & (~(FLASH_BLOCK_SIZE-1)) & 0x0FFFFFFFUL) / FLASH_BLOCK_SIZE;
// dwEndBlock = ((dwPhysStart + dwPhysLen) & (~(FLASH_BLOCK_SIZE-1)) & 0x0FFFFFFFUL) / FLASH_BLOCK_SIZE;
dwBlocksLeft = dwEndBlock - dwStartBlock + 1;
// Calculate how far from the beginning of the first block the starting address falls
dwFirstBlockOffset = (dwPhysStart & 0x0FFFFFFFUL) -
((FLASH_START & 0x0FFFFFFFUL) + dwStartBlock * FLASH_BLOCK_SIZE);
EdbgOutputDebugString( "FlashWrite: dwStartBlock %d dwEndBlock %d dwBlocksLeft %d dwFirstBlockOffset %Xh\r\n",
dwStartBlock, dwEndBlock, dwBlocksLeft, dwFirstBlockOffset);
// protect BLOCK 0 (ethernet bootloader block)
for( i = dwStartBlock; i <= dwEndBlock; i++ ) {
if(i == 0) {
*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 (EraseStatus[i] != BLOCK_ERASED) {
// EdbgOutputDebugString( "FlashWrite: Block%x is NOT BLOCK_ERASED\r\n", i );
bErasing=TRUE;
if (FlashErase( FLASH_CONT_ERASE, 0, 0, ppszErrorMsg ))
return 1;
}
}
}
dwStart= OEMEthGetSecs();
while (OEMEthGetSecs()-dwStart < 3) ;
while( dwBlocksLeft ) {
for( i = dwStartBlock ; i <= dwEndBlock ; i++ ) {
EdbgOutputDebugString( "FlashWrite: Block %d\r\n", i );
#if ((SH_PLATFORM != PLATFORM_ASPEN)&&(SH_PLATFORM != PLATFORM_BIGSUR))
DisplayAlphaLED (MAKELONG(v_PacketNum, i));
#endif ((SH_PLATFORM != PLATFORM_ASPEN)&&(SH_PLATFORM != PLATFORM_BIGSUR))
// Attempt to flash all erased blocks
if (EraseStatus[i] == BLOCK_ERASED) {
// 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|0xa0000000UL);
pdwFlashCache = (LPDWORD) FLASH_CACHE + (dwFirstBlockOffset / 4);
dwDWORDsLeft = (FLASH_BLOCK_SIZE - dwFirstBlockOffset) / 4;
// If the whole image is less than one block long
if (dwDWORDsLeft > dwPhysLen / 4)
dwDWORDsLeft = dwPhysLen / 4;
}
else {
pdwFlash = (DWORD *)((FLASH_START | 0xA0000000UL) + i * FLASH_BLOCK_SIZE);
pdwFlashCache = (LPDWORD) FLASH_CACHE +
( ((FLASH_BLOCK_SIZE - dwFirstBlockOffset) + (i-dwStartBlock-1) * FLASH_BLOCK_SIZE) / 4);
// If this is the last block we need to cut short the number of DWORDs written
if (i == dwEndBlock)
dwDWORDsLeft = (dwPhysLen % FLASH_BLOCK_SIZE) / 4;
else
dwDWORDsLeft = FLASH_BLOCK_SIZE / 4;
}
if (FlashPageWrite( pdwFlash, pdwFlashCache, dwDWORDsLeft, ppszErrorMsg ))
return 1;
dwBlocksLeft--;
EraseStatus[i] = BLOCK_FLASHED;
} // 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( dwPhysStart, dwPhysLen, ppszErrorMsg )) {
return 1;
} else {
return 0;
}
}
UINT16 FlashPageWrite( volatile DWORD *pdwFlash, DWORD *pdwFlashCache, DWORD dwDWORDsLeft, char **ppszErrorMsg )
{
volatile DWORD *pdwBSR, *pdwGSR, *pdw;
DWORD i, dwCount;
if(CheckFlashWriteProtect()) {
*ppszErrorMsg = "Error : write protected.";
return 1;
}
pdwBSR = (DWORD *)( ( ((DWORD)pdwFlash) & (~(FLASH_BLOCK_SIZE-1)) ) + 8 ); // 64bit
pdwGSR = pdwBSR + 2; // 64bit
// EdbgOutputDebugString( "FlashPageWrite: BSR=%Xh GSR=%Xh\r\n",pdwBSR,pdwGSR);
EdbgOutputDebugString( "FlashPageWrite: From %Xh to %Xh Length %Xh\r\n",pdwFlashCache,pdwFlash,dwDWORDsLeft*4);
// Loop until we've written the entire page
while( dwDWORDsLeft ) {
// Read Extended Status Registers
FlashWriteCommand(pdwBSR, 0x71717171UL);
// Wait until the block is no longer busy with other page writes
while(!FlashBSR1(pdwBSR,0x00800080UL)) ;
// Wait until a page buffer is available
while(!FlashGSR1(pdwGSR,0x00040004UL))
EdbgOutputDebugString( "GSR=%Xh\r\n",*pdwGSR);
// EdbgOutputDebugString( "Load page BSR=%Xh %d words left.\r\n",pdwBSR,dwDWORDsLeft);
// Start sequential load to page buffer
FlashWriteCommand(pdwBSR, 0xE0E0E0E0UL);
// Write Word Count Low. Decrement once since a count of 0 corresponds to a single write.
if (dwDWORDsLeft & 0xFFFFFF00UL)
dwCount = 128 * 2;
else
dwCount = dwDWORDsLeft;
FlashWriteCommand(pdwBSR, (((dwCount+1)/2-1) << 16) | ((dwCount+1)/2-1));
// Write Word Count High. This is a don't care for 28F016SV because page buffer is only 256 bytes long.
FlashWriteCommand(pdwBSR, 0);
// EdbgOutputDebugString( "pdwFlash=%Xh dwCount=%d : %Xh words left.\r\n",pdwFlash,dwCount,dwDWORDsLeft);
pdw = pdwFlash;
for( i = 0 ; i < (dwCount+1)/2 ; i++ ) { // dwCount x 2 dword
// FlashWriteCommand((pdwFlash + i), *pdwFlashCache++);
*pdwFlash++ = *pdwFlashCache++;
*pdwFlash++ = *pdwFlashCache++;
}
// Read Extended Status Registers
FlashWriteCommand(pdwBSR, 0x71717171UL);
// Wait until there is space in the command queue
while(!FlashBSR0(pdwBSR,0x00080008UL)) ;
FlashWriteCommand(pdwBSR, 0x0C0C0C0CUL);
// Write Word Count Low. Decrement once since a count of 0 corresponds to a single write.
FlashWriteCommand(pdwBSR, (((dwCount+1)/2-1) << 16) | ((dwCount+1)/2-1));
// Write Word Count High. This is a don't care for 28F016SV because page buffer is only 256 bytes long.
FlashWriteCommand(pdw, 0);
// Read Extended Status Registers
FlashWriteCommand(pdwBSR, 0x71717171UL);
// Wait until operation complete
while(!FlashBSR1(pdwBSR,0x00800080UL)) ;
// Check for operation errors
if (!FlashBSR0(pdwBSR, 0x00200020UL)) {
EdbgOutputDebugString( "FlashPageWrite() Error On Page Buffer Write GSR %X, BSR %X\r\n", *pdwGSR, *pdwBSR );
FlashError( pdwBSR, ppszErrorMsg );
return 1;
}
dwDWORDsLeft -= dwCount;
} // while there are still DWORDs to write to the page
return 0;
} // FlashPageWrite()
UINT16 FlashClose( DWORD dwPhysStart, DWORD dwPhysLen, char **ppszErrorMsg )
{
volatile DWORD *pdwBSR;
DWORD dwStartBlock, dwEndBlock, dwCurBlock;
DWORD *pdwFlash, *pdwFlashCache;
DWORD i,j,k;
DWORD dwStart;
// Compute starting and ending block numbers
dwStartBlock = (dwPhysStart & 0x01FE0000UL) / FLASH_BLOCK_SIZE;
dwEndBlock = ((dwPhysStart + dwPhysLen) & 0x01FE0000UL) / FLASH_BLOCK_SIZE;
EdbgOutputDebugString( "Closing Out Flash Image at %X of length %X (Blocks %u to %u)\r\n",
dwPhysStart, dwPhysLen, dwStartBlock, dwEndBlock );
dwStart= OEMEthGetSecs();
while (OEMEthGetSecs()-dwStart < 3) ;
// Make sure that all the blocks have finished before letting them go on, otherwise you
// might get bad values out of it.
pdwBSR = (DWORD *)((FLASH_START | 0xA0000000UL) + dwStartBlock * FLASH_BLOCK_SIZE + 8); // 64bit
for( dwCurBlock = dwStartBlock; dwCurBlock <= dwEndBlock; dwCurBlock++ ) {
pdwBSR = (DWORD *)((FLASH_START | 0xA0000000UL) + dwCurBlock * FLASH_BLOCK_SIZE + 8); // 64bit
FlashWriteCommand(pdwBSR, 0x71717171UL);
// Wait for the page to indicate ready, meaning that everything has been written
while(!FlashBSR1(pdwBSR, 0x00800080UL));
// If we're crossing a bank boundary, reset the last bank's flash to read array mode
if (dwCurBlock % FLASH_BLOCKS_PER_BANK == FLASH_BLOCKS_PER_BANK - 1)
FlashWriteCommand(pdwBSR, 0xFFFFFFFFUL);
}
// Reset flash to read array mode
FlashWriteCommand(pdwBSR, 0xFFFFFFFFUL);
// Disable SH3 writing to the flash
// *pwCpuCsr &= 0xFEFD;
// Do a compare against the FlashCache[] and see if it all looks right
EdbgOutputDebugString( "Comparing Flash vs FlashCache...\r\n dwPhysStart=%Xh FLASH_CACHE=%Xh length=%Xh\r\n",dwPhysStart,FLASH_CACHE,dwPhysLen);
pdwFlash = (DWORD *)dwPhysStart;
pdwFlashCache = (LPDWORD)FLASH_CACHE;
for( i = 0 ; i < dwPhysLen/4 ; i++ ) {
j = *pdwFlash;
k = *pdwFlashCache;
if (j != k) {
EdbgOutputDebugString( "Beat!\r\n" );
EdbgOutputDebugString( "Flash - FlashCache\r\n" );
for( j=0 ; j<16 ; j++ ) {
EdbgOutputDebugString( "%X : %X - %X : %X\r\n", pdwFlash, *pdwFlash, pdwFlashCache, *pdwFlashCache );
pdwFlash++;
pdwFlashCache++;
}
*ppszErrorMsg = "Error Comparing Flash vs FlashCache";
return 1;
}
pdwFlash++;
pdwFlashCache++;
}
EdbgOutputDebugString( "Jammin'!\r\n" );
return 0;
}
void UploadDeviceInfo( DWORD dwBank )
{
volatile DWORD *pdwGSR;
pdwGSR = (DWORD *)((FLASH_START | 0xA0000000UL) + dwBank * 32UL * FLASH_BLOCK_SIZE + 16);
FlashWriteCommand(pdwGSR, 0x71717171UL);
// Wait for command queues to be less than full
while(!FlashGSR0(pdwGSR,0x00080008UL))
EdbgOutputDebugString( "UploadDeviceInfo::Waiting for Command Q %X\r\n", *pdwGSR );
while(!FlashGSR1(pdwGSR,0x00800080UL))
EdbgOutputDebugString( "UploadDeviceInfo::Waiting for Ready 1 %X\r\n", *pdwGSR );
FlashWriteCommand(pdwGSR, 0x99999999UL);
FlashWriteCommand(pdwGSR, 0xD0D0D0D0UL);
// Optionally read out the device info.
/*
FlashWriteCommand(pdwGSR, 0x71717171UL);
while(!FlashGSR1(pdwGSR,0x00800080UL))
EdbgOutputDebugString( "UploadDeviceInfo::Waiting for Ready 2 %X\r\n", *pdwGSR );
if (!FlashGSR0(pdwGSR, 0x20202020UL))
EdbgOutputDebugString( "Page Buffer Read Failed %X%X\r\n", *(pdwGSR), *(pdwGSR+1) );
else {
FlashWriteCommand(pdwGSR, 0x72727272UL);
FlashWriteCommand(pdwGSR, 0x75757575UL);
EdbgOutputDebugString( "Device Revision Code %X%X\r\n", *(pdwGSR+2), *(pdwGSR+3));
FlashWriteCommand(pdwGSR, 0x75757575UL);
EdbgOutputDebugString( "Device Proliferation Code %X%X\r\n", *(pdwGSR+26), *(pdwGSR+27) );
}
*/
}
#endif ((SH_PLATFORM != PLATFORM_ASPEN)&&(SH_PLATFORM != PLATFORM_BIGSUR))
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?