diff --git a/components/libraries/bootloader_dfu/dfu_dual_bank.c b/components/libraries/bootloader_dfu/dfu_dual_bank.c index d634a19..4d523c6 100644 --- a/components/libraries/bootloader_dfu/dfu_dual_bank.c +++ b/components/libraries/bootloader_dfu/dfu_dual_bank.c @@ -24,6 +24,7 @@ #include "nrf_mbr.h" #include "dfu_init.h" #include "sdk_common.h" +#include "app_util_platform.h" static dfu_state_t m_dfu_state; /**< Current DFU state. */ static uint32_t m_image_size; /**< Size of the image that will be transmitted. */ @@ -366,7 +367,8 @@ uint32_t dfu_start_pkt_handle(dfu_update_packet_t * p_packet) if (m_start_packet.bl_image_size > DFU_BL_IMAGE_MAX_SIZE) { - return NRF_ERROR_DATA_SIZE; + // Ignore Max Bootloader Image Check + //return NRF_ERROR_DATA_SIZE; } if (IS_UPDATING_SD(m_start_packet)) @@ -669,6 +671,7 @@ static uint32_t dfu_sd_img_block_swap(uint32_t * src, // and verifucation of data in case power reset occurs during write to flash. // To ensure the robustness of swapping the images are compared backwards till start of // image swap. If the back is identical everything is swapped. + uint32_t err_code = dfu_compare_block(src, dst, len); if (err_code == NRF_SUCCESS) { @@ -707,11 +710,15 @@ uint32_t dfu_sd_image_swap(void) uint32_t err_code; uint32_t sd_start = SOFTDEVICE_REGION_START; uint32_t block_size = (boot_settings.sd_image_start - sd_start) / 2; + block_size &= ~(uint32_t)(CODE_PAGE_SIZE - 1); + uint32_t image_end = boot_settings.sd_image_start + boot_settings.sd_image_size; uint32_t img_block_start = boot_settings.sd_image_start + 2 * block_size; uint32_t sd_block_start = sd_start + 2 * block_size; + + if (SD_SIZE_GET(MBR_SIZE) < boot_settings.sd_image_size) { // This will clear a page thus ensuring the old image is invalidated before swapping. @@ -741,6 +748,10 @@ uint32_t dfu_sd_image_swap(void) return NRF_SUCCESS; } +void softdevice_fault_handler_bl(uint32_t id, uint32_t pc, uint32_t info) +{ + app_error_fault_handler(id, pc, info); +} uint32_t dfu_bl_image_swap(void) @@ -749,9 +760,71 @@ uint32_t dfu_bl_image_swap(void) sd_mbr_command_t sd_mbr_cmd; bootloader_settings_get(&bootloader_settings); - + + // Storage buffers and variables to hold the UICR register content + static uint32_t uicr_buffer[59] = {0x00000000}; + static uint32_t pselreset_0 = 0x00000000; + static uint32_t pselreset_1 = 0x00000000; + static uint32_t approtect = 0x00000000; + static uint32_t nfcpins = 0x00000000; + if (bootloader_settings.bl_image_size != 0) { + CRITICAL_REGION_ENTER(); + + // Read and buffer UICR register content prior to erase + uint32_t uicr_address = 0x10001014; + + for(int i = 0; iREADY == NVMC_READY_READY_Busy){} + // Set UICR address to the next register + uicr_address += 0x04; + } + + pselreset_0 = NRF_UICR->PSELRESET[0]; + pselreset_1 = NRF_UICR->PSELRESET[1]; + approtect = NRF_UICR->APPROTECT; + nfcpins = NRF_UICR->NFCPINS; + + //Modify the Bootloader start address to correspond to the new bootloader + uicr_buffer[0] = 0x00078000; + + // Enable Erase mode + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een << NVMC_CONFIG_WEN_Pos; //0x02; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + + // Erase the UICR registers + NRF_NVMC->ERASEUICR = NVMC_ERASEUICR_ERASEUICR_Erase << NVMC_ERASEUICR_ERASEUICR_Pos; //0x00000001; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + + // Enable WRITE mode + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; //0x01; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + + // Write the modified UICR content back to the UICR registers + uicr_address = 0x10001014; + for(int j = 0; jREADY == NVMC_READY_READY_Busy){} + } + // Set UICR address to the next register + uicr_address += 0x04; + } + + NRF_UICR->PSELRESET[0] = pselreset_0; + NRF_UICR->PSELRESET[1] = pselreset_1; + NRF_UICR->APPROTECT = approtect; + NRF_UICR->NFCPINS = nfcpins; + + CRITICAL_REGION_EXIT(); + uint32_t bl_image_start = (bootloader_settings.sd_image_size == 0) ? DFU_BANK_1_REGION_START : bootloader_settings.sd_image_start +