Hi everyone,
I try to implement DFU on nrf52840 with SDK15.3 and softdevice s140.
I use the secure bootloader ble example and in BLE it works well. But I have an issue in modem(OTA).
In the application I received the .bin and .dat files from the server. I write the .bin file into the bank 1 of the internal flash of the nrf52840.
But after receiving the firmware I rewrite the setting to match with the new firmware.
But when I restart on the bootloader the device does not take the new firmware and the setting memory region is corrupted and the device is stuck in DFU mode.
Is there any precaution to have when I set the new setting ?
Here my new settings:
void execute_nrf52_dfu (nrf_dfu_settings_t *dfu_settings, uint32_t bank1_addr)
{
uint32_t err_code;
// Fill the structure of DFU settings
if (*(uint8_t *)(DFU_INIT_CMD_ADDRESS + DFU_BLSD_APP_POS) == DFU_FW_TYPE_APP) {
// DFU for application
dfu_settings->bank_1.bank_code = NRF_DFU_BANK_VALID_APP;
dfu_settings->bank_0.bank_code = NRF_DFU_BANK_INVALID;
dfu_settings->bank_1.image_crc = crc32((uint8_t*) bank1_addr, dfu_settings->bank_1.image_size);
memcpy(dfu_settings->boot_validation_app.bytes, &dfu_settings->bank_1.image_crc, sizeof(uint32_t));
} else if (*(uint8_t *)(DFU_INIT_CMD_ADDRESS + DFU_BLSD_APP_POS) == DFU_FW_TYPE_BL_SD) {
// DFU for bootloader and SoftDevice
dfu_settings->bank_1.bank_code = NRF_DFU_BANK_VALID_SD_BL;
dfu_settings->bank_0.bank_code = NRF_DFU_BANK_VALID_APP;
dfu_settings->sd_size = read_sd_size ((uint8_t *)DFU_INIT_CMD_ADDRESS);
} else {
NRF_LOG_ERROR ("Error in downloaded firmware: bad firmware type.");
}
memcpy(&(dfu_settings->init_command), (void*) DFU_INIT_CMD_ADDRESS, dfu_settings->progress.command_size);
dfu_settings->progress.command_crc = crc32(dfu_settings->init_command, dfu_settings->progress.command_size);
dfu_settings->progress.update_start_address = bank1_addr;
dfu_settings->enter_buttonless_dfu = 1;
dfu_settings->bank_current = NRF_DFU_CURRENT_BANK_1;
dfu_settings->bank_layout = NRF_DFU_BANK_LAYOUT_DUAL;
dfu_settings->boot_validation_softdevice.type = NO_VALIDATION;
dfu_settings->boot_validation_app.type = VALIDATE_CRC;
dfu_settings->boot_validation_bootloader.type = NO_VALIDATION;
dfu_settings->settings_version = NRF_DFU_SETTINGS_VERSION; // NRF_DFU_SETTINGS_VERSION must be 2 with SDK 15.3
dfu_settings->crc = crc32((uint8_t*) &(dfu_settings->settings_version), (uint8_t*) dfu_settings->init_command - (uint8_t*) &(dfu_settings->settings_version)); // number of bytes between crc and init command
// Erase previous settings
NRF_LOG_INFO("%s, %d", __FUNCTION__, __LINE__);
err_code = nrf_dfu_flash_erase(DFU_SETTINGS_ADDRESS, DFU_SETTINGS_PAGE_ERASE, dfu_flash_erase_done);
APP_ERROR_CHECK(err_code);
xEventGroupWaitBits(downloadEventGroup, DFU_ERASE_DONE, pdTRUE, pdFALSE, portMAX_DELAY);
// Write new settings in Flash memory
NRF_LOG_INFO("%s, %d", __FUNCTION__, __LINE__);
dfu_flash_write(DFU_SETTINGS_ADDRESS, (uint8_t*) dfu_settings, sizeof(nrf_dfu_settings_t), true);
// Start DFU, this function will not return
LOG_EEPROM_INFO("Start DFU");
reboot_dfu();
}
Thank you for your help.
Etienne