In my bootlodaer program, I need to erase flash region 0x1000000 - 0x127ffff on the 5748G. This time when I erase the falsh, some error condition occurs that causes the erase to fail, and I'm not sure exactly what causes the failure and this bootloader has worked fine for a long time. When I connected the debugger and checked the flash I found another region on the flash (0xFB0000 - 0xFB7FFFF) was corrupted. I would like to know what possible reasons could cause this to happen and what I can do in the software after the flash data is corrupted. Also is there some documentation about erasing and programing of the flash on 5748G. Thanks!
This is the erase function
static blt_bool FlashEraseSectors(blt_int8u first_sector_idx, blt_int8u last_sector_idx)
{
blt_bool result = BLT_TRUE;
blt_int8u sectorIdx;
blt_addr sectorBaseAddr;
blt_int32u timeout_val;
uint32_t *lockReg;
uint32_t *selReg;
blt_bool bNeedErase = BLT_FALSE;
uint32_t sectorSize;
/* validate the sector numbers */
if (first_sector_idx > last_sector_idx)
{
result = BLT_FALSE;
}
/* only continue if all is okay so far */
if (result == BLT_TRUE)
{
if (last_sector_idx > (FLASH_TOTAL_SECTORS - 1))
{
result = BLT_FALSE;
}
}
/* only continue if all is okay so far */
if (BLT_TRUE == result)
{
DISABLE_INTERRUPTS();
// initiate the erase operation
C55FMC.MCR.B.ERS = 1;
for (sectorIdx = first_sector_idx; sectorIdx <= last_sector_idx; sectorIdx++)
{
if (flashLayout[sectorIdx].erased == BLT_FALSE)
{
bNeedErase = BLT_TRUE;
sectorBaseAddr = flashLayout[sectorIdx].sector_start;
sectorSize = flashLayout[sectorIdx].sector_size;
// unlock the block
lockReg = (uint32_t*) ((uint32_t) &C55FMC.LOCK0.R + (flashLayout[sectorIdx].sel_reg * 4));
*lockReg &= ~(1UL << flashLayout[sectorIdx].sel_bit);
// select the block to erase
selReg = (uint32_t*) ((uint32_t) &C55FMC.SEL0.R + (flashLayout[sectorIdx].sel_reg * 4));
*selReg |= (1UL << flashLayout[sectorIdx].sel_bit);
// write the first address in flash memory. (erase interlock write)
*(blt_int32u*) sectorBaseAddr = 0xFFFFFFFF; /* Interlock write */
flashLayout[sectorIdx].erased = BLT_TRUE;
}
if (BLT_TRUE == bNeedErase)
{
// start the internal erase sequence
C55FMC.MCR.B.EHV = 1;
// wait until erase completed
// erasing a 256KB sector takes about 1.2s to complete
timeout_val = TimerGet() + ERASE_TIMEOUT_MS;
while (C55FMC.MCR.B.DONE == 0)
{
// reset the watchdog
CopService();
if (TimerGet() > timeout_val)
{
result = BLT_FALSE;
break;
}
}
// confirm erase was successful
if (C55FMC.MCR.B.PEG != 1)
{
result = BLT_FALSE;
}
// de-select all blocks
C55FMC.SEL0.R = 0;
C55FMC.SEL1.R = 0;
C55FMC.SEL2.R = 0;
// end internal erase sequence
C55FMC.MCR.B.EHV = 0;
}
}
// end the erase operation
C55FMC.MCR.B.ERS = 0;
ENABLE_INTERRUPTS();
}
(void) sectorSize;
/* give the result back to the caller */
return result;
} /*** end of FlashEraseSectors ***/
