📄 flash.c
字号:
if ((i & 0x00000008) == 0x00000008)
EdbgOutputDebugString("ERROR: FlashErase: voltage range error ... lower flash.\r\n");
if ((i & 0x00080000) == 0x00080000)
EdbgOutputDebugString("ERROR: FlashErase: voltage range error ... upper flash.\r\n");
if ((i & 0x00000030) == 0x00000030)
EdbgOutputDebugString("ERROR: FlashErase: command sequence error ... lower flash.\r\n");
if ((i & 0x00300000) == 0x00300000)
EdbgOutputDebugString("ERROR: FlashErase: command sequence error ... upper flash.\r\n");
if ((i & 0x00000020) == 0x00000020)
EdbgOutputDebugString("ERROR: FlashErase: clear lock bits error ... lower flash.\r\n");
if ((i & 0x00200000) == 0x00200000)
EdbgOutputDebugString("ERROR: FlashErase: clear lock bits error ... upper flash.\r\n");
if (i != 0x00800080)
{
EdbgOutputDebugString("ERROR: FlashErase: status register returned 0x%X\r\n", i);
EdbgOutputDebugString("ERROR: FlashErase: unrecoverable failure encountered while erasing flash. System halted!\r\n");
return(FALSE);
}
if ( ((g_FlashDeviceType == L18) || (g_FlashDeviceType == L30)) && (num_l3_blocks_erased > 0) )
{
// We need to take care of the first 16K blocks if there are any
pFlash += (L3_BLOCK_SIZE / 4);
num_l3_blocks_erased--;
}
else
{
pFlash += (BLOCK_SIZE / 4);
}
}
pFlash = (volatile UINT32 *)(FlashStart);
// Clear the status register
*pFlash = 0x00500050;
if ( ((g_FlashDeviceType == L18) || (g_FlashDeviceType == L30)) && (num_l3_blocks_to_erase > 0) )
{
EdbgOutputDebugString("INFO: FlashErase: erasing flash %X to %X. Please wait... \r\n", FlashStart, FlashStart + (((num_blocks-num_l3_blocks_to_erase)*256*1024) + (num_l3_blocks_to_erase*64*1024)) - 1);
}
else
{
EdbgOutputDebugString("INFO: FlashErase: erasing flash %X to %X. Please wait... \r\n", FlashStart, FlashStart + (num_blocks*256*1024) - 1);
}
// For L3, need to set for use within the FOR loop
num_l3_blocks_erased = num_l3_blocks_to_erase;
// Erase each block.
for (j = 0; j < num_blocks; j++)
{
// Issue erase and confirm command
*pFlash = 0x00200020;
*pFlash = 0x00d000d0;
while ((*pFlash & 0x00800080) != 0x00800080);
// Check if the flash block erased successfully.
// Was either block locked?
status = *pFlash;
if ((status & 0x00200000) || (status & 0x00000020))
{
if (status & 0x00200000)
{
EdbgOutputDebugString("ERROR: FlashErase: block erase failure. Lock bit upper flash set!\r\n");
}
if (status & 0x00000020)
{
EdbgOutputDebugString("ERROR: FlashErase: block erase failure. Lock bit lower flash set!\r\n");
}
EdbgOutputDebugString("ERROR: FlashErase: unrecoverable failure encountered while erasing flash.\r\n");
return(FALSE);
}
EdbgOutputDebugString(".");
if ( ((g_FlashDeviceType == L18) || (g_FlashDeviceType == L30)) && (num_l3_blocks_erased > 0) )
{
pFlash += (L3_BLOCK_SIZE / 4);
num_l3_blocks_erased--;
}
else
{
pFlash += (BLOCK_SIZE / 4);
}
}
EdbgOutputDebugString("\r\n");
pFlash = (volatile UINT32 *)(FlashStart);
// Put the flash back into read mode
if ((g_FlashDeviceType == L18) || (g_FlashDeviceType == L30))
{
// Setting the number of 16K blocks that we have to deal with
num_l3_blocks_erased = num_l3_blocks_to_erase;
// Put each block back into read mode
for (j = 0; j < num_blocks; j++)
{
*pFlash = 0x00FF00FF;
if ( num_l3_blocks_erased )
{
pFlash += (L3_BLOCK_SIZE / 4);
num_l3_blocks_erased--;
}
else
{
pFlash += (BLOCK_SIZE / 4);
}
}
// Now reset the flash pointer
pFlash = (volatile UINT32 *)(FlashStart);
}
else
{
*pFlash = 0x00FF00FF;
}
// Flash erase verification.
for (i = 0; i < FlashLength / 4; i++)
{
if (*pFlash++ != 0xFFFFFFFF)
{
EdbgOutputDebugString("ERROR: FlashErase: erase verification failure at address 0x%X Data 0x%X.\r\n", pFlash-1, *(pFlash-1));
EdbgOutputDebugString("ERROR: FlashErase: unrecoverable failure encountered while erasing flash.\r\n");
return(FALSE);
}
}
return(TRUE);
}
BOOL FlashInit(UINT32 FlashStart, UINT32 FlashLength)
{
// Read the device ID and determine the flash part type.
//
g_FlashDeviceType = DetectFlashDevice(FlashStart);
return((g_FlashDeviceType != NONE) ? TRUE : FALSE);
}
BOOL FlashRead(UINT32 FlashStart, UINT8 *pDataBuffer, UINT32 DataLength)
{
if (!pDataBuffer) return(FALSE);
// TODO - check flash address...
memcpy((void *)pDataBuffer, (const void *)FlashStart, DataLength);
return(TRUE);
}
// TODO - block-aligned address.
BOOL FlashWrite(UINT32 FlashStart, UINT8 *pDataBuffer, UINT32 DataLength)
{
UINT32 i,j,b;
UINT32 sizeFlashCache; // size in bytes of the flash cache
UINT32 chunksPerBlock;
UINT32 count;
UINT32 val = 0;
UINT32 dwLength = DataLength;
volatile UINT32 *pFlash = (volatile UINT32 *) FlashStart;
volatile UINT32 *pBlockAddress = (volatile UINT32 *) (FlashStart);
volatile UINT32 *pDeviceAddress = (volatile UINT32 *) FlashStart;
volatile UINT32 *pFlashCache = (UINT32 *) pDataBuffer;
volatile UINT32 *pdwFlashStart;
volatile UINT32 *pdwRamStart;
if (g_FlashDeviceType == NONE)
{
EdbgOutputDebugString("ERROR: FlashWrite: unrecognized flash part.\r\n");
return(FALSE);
}
if (!FlashErase(FlashStart, DataLength))
{
return(FALSE);
}
b = 0;
if (g_FlashDeviceType == J3)
{
sizeFlashCache = 64; // 64 bytes total, 32 bytes per device
chunksPerBlock = 4096; // 256K / 64bytes = 4096
}
else if ((g_FlashDeviceType == K3) || (g_FlashDeviceType == K18) || (g_FlashDeviceType == L18) || (g_FlashDeviceType == L30))
{
sizeFlashCache = 128; // 128 bytes total, 64 bytes per device
chunksPerBlock = 2048; // 256K / 128bytes = 2048
}
EdbgOutputDebugString("INFO: FlashWrite: writing to flash...\r\n");
while (DataLength > 0)
{
// Calculate the number of DWORDS to program in each iteration based on the size in bytes
// of the flash cache.
if (DataLength > sizeFlashCache)
count = sizeFlashCache / 4;
else
count = DataLength / 4;
// Issue Write to Buffer Command
*pBlockAddress = 0x00E800E8;
// Check that the write buffer is available.
// Read the Extended Status Register and
// wait for the assertion of XSR[7] before continuing.
while ( (*pBlockAddress & 0x00800080) != 0x00800080)
{
*pBlockAddress = 0x00E800E8;
}
// Configure the size of the buffer that we will write.
// Write the word count (device expects a 0 based number)
*pBlockAddress = ((count - 1) << 16 | (count - 1));
pdwFlashStart = pDeviceAddress;
pdwRamStart = pFlashCache;
// Write up to "count" DWORDS into the Flash memory staging area
for (i = 0; i < count; i++)
{
*pDeviceAddress++ = *pFlashCache++;
}
// increment the number of 64 or 128 byte segments written.
b++;
// Now program the buffer into Flash
*pBlockAddress = 0x00D000D0;
i = 0;
while ((i & 0x00800080) != 0x00800080)
{
i = *pBlockAddress;
}
DataLength -= count << 2;
// Read back the segment just written
*pFlash = 0x00FF00FF;
for (i = 0; i < count; i++)
{
if ((g_FlashDeviceType == L18) || (g_FlashDeviceType == L30))
{
*pdwFlashStart = 0x00FF00FF;
}
if (*pdwFlashStart++ != *pdwRamStart++)
{
EdbgOutputDebugString("ERROR: FlashWrite: flash programming failure at address 0x%x (expected 0x%x actual 0x%x).\r\n", pdwFlashStart-1, *(pdwRamStart-1), *(pdwFlashStart-1));
return(FALSE);
}
}
if ((b % chunksPerBlock) == 0)
{
EdbgOutputDebugString(".");
}
}
// Verify the data written to flash...
//
pFlash = (volatile UINT32 *) FlashStart;
pFlashCache = (UINT32 *) pDataBuffer;
// Put Flash into read mode.
*pFlash = 0x00FF00FF;
EdbgOutputDebugString("INFO: FlashWrite: verifying the data written to flash...\r\n");
for ( j = 0; j < dwLength/4; j++ )
{
if (*pFlash++ != *pFlashCache++)
{
EdbgOutputDebugString( "ERROR: FlashWrite: verification failure at address 0x%x (expected 0x%x actual 0x%x))\r\n", pFlash-1, *(pFlashCache-1), *(pFlash-1) );
return(FALSE);
}
}
EdbgOutputDebugString("INFO: FlashWrite: flash programmed successfully!\r\n");
return(TRUE);
}
// END: these routines will be replaced by the FMD when it's done.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -