Hi,
working on custom bootloader on nRF52840 with S140 v7.2.0(not enabled in bootloader) with SDK.
This is code for erase and write:
static void eraseFW(void)
{
static constexpr uint32_t end = MemoryMap::mcuFWAddress + MemoryMap::mcuFWSize;
uint32_t address = MemoryMap::mcuFWAddress;
_PRINTN("FW erase\n", 9);
// Wait for flash
while (!nrf_nvmc_ready_check(NRF_NVMC))
{
}
// Erase sector by sector
while (address < end)
{
System::watchdogFeed();
nrf_nvmc_page_erase(address);
address += __KiB_2_B(4);
}
_PRINTN_INFO("FW erased\n", 10);
}
static void writeFW(const uint32_t address, const void* data, const uint16_t len)
{
// Wait for flash
while (!nrf_nvmc_ready_check(NRF_NVMC))
{
}
uint8_t* fwBytes = (uint8_t*)address;
for (uint16_t i = 0; i < len; i++)
{
if (fwBytes[i] != 0xFF)
{
_PRINTF_ERROR("%08X: Not erased %02X\n", &fwBytes[i], fwBytes[i]);
break;
}
}
_PRINTF("FW W %08X %uB\n", address, len);
nrf_nvmc_write_words(address, (const uint32_t*)data, len);
// SOON: Tests
uint8_t* dataBytes = (uint8_t*)data;
for (uint16_t i = 0; i < len; i++)
{
if (dataBytes[i] != fwBytes[i])
{
_PRINTF_ERROR("%08X: %02X-%02X\n", &fwBytes[i], dataBytes[i], fwBytes[i]);
break;
}
}
}
Now, when writing I get prints "0002F400: Not erased 00". Why bytes are set to 0x00 after erase? Seems like erase failed.
I also tried to use SD flash erase but it did not help, result is always 0x00 after erase.
With that firmware update fails because checksum(from update file) does not match with calculated checksum after firmware write.
4KiB to bytes is 4096. FW address is 0x2F000 and size is 512KiB.
Thanks.
@EDIT
One thing I did notice - firmware is written in chunks of 1024B and on first write 0x00 is not detected. Seems like erase does not fail, something wrong is with write. If erase is the problem then first 0x00 should be detected on 0x2F000, not 0x2F400(second write chunk).
00> FW W 0002F000 1024B
00> 0002F400: Not erased 00
00> FW W 0002F400 1024B