void bootloader_dfu_update_process(dfu_update_status_t update_status) { static bootloader_settings_t settings; const bootloader_settings_t * p_bootloader_settings; bootloader_util_settings_get(&p_bootloader_settings); if (update_status.status_code == DFU_UPDATE_COMPLETE) { settings.bank_0_crc = update_status.app_crc; settings.bank_0_size = update_status.app_size; settings.bank_0 = BANK_VALID_APP; settings.bank_1 = BANK_INVALID_APP; m_update_status = BOOTLOADER_SETTINGS_SAVING; bootloader_settings_save(&settings); } else if (update_status.status_code == DFU_TIMEOUT) { // Timeout has occurred. Close the connection with the DFU Controller. uint32_t err_code = dfu_transport_close(); APP_ERROR_CHECK(err_code); m_update_status = BOOTLOADER_TIMEOUT; } else if (update_status.status_code == DFU_BANK_0_ERASED) { settings.bank_0_crc = 0; settings.bank_0_size = 0; settings.bank_0 = BANK_ERASED; settings.bank_1 = p_bootloader_settings->bank_1; bootloader_settings_save(&settings); } else if (update_status.status_code == DFU_BANK_1_ERASED) { settings.bank_0 = p_bootloader_settings->bank_0; settings.bank_0_crc = p_bootloader_settings->bank_0_crc; settings.bank_0_size = p_bootloader_settings->bank_0_size; settings.bank_1 = BANK_ERASED; bootloader_settings_save(&settings); } else if (update_status.status_code == DFU_RESET) { // Timeout has occurred. Close the connection with the DFU Controller. uint32_t err_code = dfu_transport_close(); APP_ERROR_CHECK(err_code); m_update_status = BOOTLOADER_RESET; } else { // No implementation needed. } }
uint32_t bootloader_dfu_start(void) { uint32_t err_code = NRF_SUCCESS; err_code = dfu_init(); if (err_code != NRF_SUCCESS) { return err_code; } err_code = dfu_transport_update_start(); wait_for_events(); err_code = dfu_transport_close(); return err_code; }
void bootloader_dfu_update_process(dfu_update_status_t update_status) { static bootloader_settings_t settings; const bootloader_settings_t * p_bootloader_settings; bootloader_util_settings_get(&p_bootloader_settings); if (update_status.status_code == DFU_UPDATE_APP_COMPLETE) { settings.bank_0_crc = update_status.app_crc; settings.bank_0_size = update_status.app_size; settings.bank_0 = BANK_VALID_APP; settings.bank_1 = BANK_INVALID_APP; m_update_status = BOOTLOADER_SETTINGS_SAVING; bootloader_settings_save(&settings); } else if (update_status.status_code == DFU_UPDATE_SD_COMPLETE) { settings.bank_0_crc = update_status.app_crc; settings.bank_0_size = update_status.sd_size + update_status.bl_size + update_status.app_size; settings.bank_0 = BANK_VALID_SD; settings.bank_1 = BANK_INVALID_APP; settings.sd_image_size = update_status.sd_size; settings.bl_image_size = update_status.bl_size; settings.app_image_size = update_status.app_size; settings.sd_image_start = update_status.sd_image_start; m_update_status = BOOTLOADER_SETTINGS_SAVING; bootloader_settings_save(&settings); } else if (update_status.status_code == DFU_UPDATE_BOOT_COMPLETE) { settings.bank_0 = p_bootloader_settings->bank_0; settings.bank_0_crc = p_bootloader_settings->bank_0_crc; settings.bank_0_size = p_bootloader_settings->bank_0_size; settings.bank_1 = BANK_VALID_BOOT; settings.sd_image_size = update_status.sd_size; settings.bl_image_size = update_status.bl_size; settings.app_image_size = update_status.app_size; settings.bl_image_start = CODE_REGION_1_START; m_update_status = BOOTLOADER_SETTINGS_SAVING; bootloader_settings_save(&settings); } else if (update_status.status_code == DFU_UPDATE_SD_SWAPPED) { if (p_bootloader_settings->bank_0 == BANK_VALID_SD) { settings.bank_0_crc = 0; settings.bank_0_size = 0; settings.bank_0 = BANK_INVALID_APP; } // This handles cases where SoftDevice was not updated, hence bank0 keeps its settings. else { settings.bank_0 = p_bootloader_settings->bank_0; settings.bank_0_crc = p_bootloader_settings->bank_0_crc; settings.bank_0_size = p_bootloader_settings->bank_0_size; } settings.bank_1 = BANK_INVALID_APP; settings.sd_image_size = 0; settings.bl_image_size = 0; settings.app_image_size = 0; m_update_status = BOOTLOADER_SETTINGS_SAVING; bootloader_settings_save(&settings); } else if (update_status.status_code == DFU_TIMEOUT) { // Timeout has occurred. Close the connection with the DFU Controller. uint32_t err_code = dfu_transport_close(); APP_ERROR_CHECK(err_code); m_update_status = BOOTLOADER_TIMEOUT; } else if (update_status.status_code == DFU_BANK_0_ERASED) { settings.bank_0_crc = 0; settings.bank_0_size = 0; settings.bank_0 = BANK_INVALID_APP; settings.bank_1 = p_bootloader_settings->bank_1; bootloader_settings_save(&settings); } else if (update_status.status_code == DFU_RESET) { m_update_status = BOOTLOADER_RESET; } else { // No implementation needed. } }
/**@brief Function for the Device Firmware Update Service event handler. * * @details This function will be called for all Device Firmware Update Service events which * are passed to the application. * * @param[in] p_dfu Device Firmware Update Service structure. * @param[in] p_evt Event received from the Device Firmware Update Service. */ static void on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt) { uint32_t err_code; switch (p_evt->ble_dfu_evt_type) { case BLE_DFU_VALIDATE: err_code = dfu_image_validate(); // Translate the err_code returned by the above function to DFU Response Value. ble_dfu_resp_val_t resp_val; resp_val = nrf_err_code_translate(err_code, BLE_DFU_VALIDATE_PROCEDURE); err_code = ble_dfu_response_send(p_dfu, BLE_DFU_VALIDATE_PROCEDURE, resp_val); APP_ERROR_CHECK(err_code); break; case BLE_DFU_ACTIVATE_N_RESET: err_code = dfu_transport_close(); APP_ERROR_CHECK(err_code); // With the S110 Flash API it is safe to initiate the activate before connection is // fully closed. err_code = dfu_image_activate(); if (err_code != NRF_SUCCESS) { dfu_reset(); } break; case BLE_DFU_SYS_RESET: err_code = dfu_transport_close(); APP_ERROR_CHECK(err_code); dfu_reset(); break; case BLE_DFU_START: m_pkt_type = PKT_TYPE_START; if (p_evt->evt.ble_dfu_pkt_write.len == 0) { m_update_mode = DFU_UPDATE_APP; } else { m_update_mode = (uint8_t)p_evt->evt.ble_dfu_pkt_write.p_data[0]; } break; case BLE_DFU_RECEIVE_INIT_DATA: m_pkt_type = PKT_TYPE_INIT; break; case BLE_DFU_RECEIVE_APP_DATA: m_pkt_type = PKT_TYPE_FIRMWARE_DATA; break; case BLE_DFU_PACKET_WRITE: on_dfu_pkt_write(p_dfu, p_evt); break; case BLE_DFU_PKT_RCPT_NOTIF_ENABLED: m_pkt_rcpt_notif_enabled = true; m_pkt_notif_target = p_evt->evt.pkt_rcpt_notif_req.num_of_pkts; m_pkt_notif_target_cnt = p_evt->evt.pkt_rcpt_notif_req.num_of_pkts; break; case BLE_DFU_PKT_RCPT_NOTIF_DISABLED: m_pkt_rcpt_notif_enabled = false; m_pkt_notif_target = 0; break; case BLE_DFU_BYTES_RECEIVED_SEND: err_code = ble_dfu_bytes_rcvd_report(p_dfu, m_num_of_firmware_bytes_rcvd); APP_ERROR_CHECK(err_code); break; default: // Unsupported event received from DFU Service. Ignore. break; } }
/**@brief Function for the Device Firmware Update Service event handler. * * @details This function will be called for all Device Firmware Update Service events which * are passed to the application. * * @param[in] p_dfu Device Firmware Update Service structure. * @param[in] p_evt Event received from the Device Firmware Update Service. */ static void on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt) { uint32_t err_code; switch (p_evt->ble_dfu_evt_type) { case BLE_DFU_VALIDATE: err_code = dfu_image_validate(); // Translate the err_code returned by the above function to DFU Response Value. ble_dfu_resp_val_t resp_val; resp_val = nrf_error_to_dfu_resp_val(err_code, BLE_DFU_VALIDATE_PROCEDURE); err_code = ble_dfu_response_send(p_dfu, BLE_DFU_VALIDATE_PROCEDURE, resp_val); APP_ERROR_CHECK(err_code); break; case BLE_DFU_ACTIVATE_N_RESET: // Final state of DFU is reached. m_activate_img_after_tear_down = true; err_code = dfu_transport_close(); APP_ERROR_CHECK(err_code); break; case BLE_DFU_SYS_RESET: err_code = dfu_transport_close(); APP_ERROR_CHECK(err_code); break; case BLE_DFU_START: m_pkt_type = PKT_TYPE_START; break; case BLE_DFU_RECEIVE_INIT_DATA: m_pkt_type = PKT_TYPE_INIT; break; case BLE_DFU_RECEIVE_APP_DATA: m_pkt_type = PKT_TYPE_FIRMWARE_DATA; break; case BLE_DFU_PACKET_WRITE: on_dfu_pkt_write(p_dfu, p_evt); break; case BLE_DFU_PKT_RCPT_NOTIF_ENABLED: m_pkt_rcpt_notif_enabled = true; m_pkt_notif_target = p_evt->evt.pkt_rcpt_notif_req.num_of_pkts; m_pkt_notif_target_cnt = p_evt->evt.pkt_rcpt_notif_req.num_of_pkts; break; case BLE_DFU_PKT_RCPT_NOTIF_DISABLED: m_pkt_rcpt_notif_enabled = false; m_pkt_notif_target = 0; break; case BLE_DFU_BYTES_RECEIVED_SEND: err_code = ble_dfu_bytes_rcvd_report(p_dfu, m_num_of_firmware_bytes_rcvd); APP_ERROR_CHECK(err_code); break; default: // Unsupported event received from DFU Service. Ignore. break; } }