/**@brief Function for handling callbacks from pstorage module. * * @details Handles pstorage results for clear and storage operation. For detailed description of * the parameters provided with the callback, please refer to \ref pstorage_ntf_cb_t. */ static void pstorage_callback_handler(pstorage_handle_t * p_handle, uint8_t op_code, uint32_t result, uint8_t * p_data, uint32_t data_len) { switch (op_code) { case PSTORAGE_STORE_OP_CODE: if ((m_dfu_state == DFU_STATE_RX_DATA_PKT) && (m_data_pkt_cb != NULL)) { m_data_pkt_cb(DATA_PACKET, result, p_data); } break; case PSTORAGE_CLEAR_OP_CODE: if (m_dfu_state == DFU_STATE_PREPARING) { m_functions.cleared(); m_dfu_state = DFU_STATE_RDY; if (m_data_pkt_cb != NULL) { m_data_pkt_cb(START_PACKET, result, p_data); } } break; default: break; } APP_ERROR_CHECK(result); }
/**@brief Function for preparing of flash before receiving SoftDevice image. * * @details This function will erase current application area to ensure sufficient amount of * storage for the SoftDevice image. Upon erase complete a callback will be done. * See \ref dfu_bank_prepare_t for further details. */ static void dfu_prepare_func_app_erase(uint32_t image_size) { if(m_start_packet.sd_image_size != 0) { mp_storage_handle_active = m_storage_handle_sd; } else { mp_storage_handle_active = m_storage_handle_app; } // Doing a SoftDevice update thus current application must be cleared to ensure enough space // for new SoftDevice. m_dfu_state = DFU_STATE_PREPARING; nrf_flash_erase(mp_storage_handle_active, m_image_size); m_functions.cleared(); m_dfu_state = DFU_STATE_RDY; }
uint32_t dfu_image_activate() { uint32_t err_code; switch (m_dfu_state) { case DFU_STATE_WAIT_4_ACTIVATE: // Stop the DFU Timer because the peer activity need not be monitored any longer. err_code = app_timer_stop(m_dfu_timer_id); APP_ERROR_CHECK(err_code); err_code = m_functions.activate(); break; default: err_code = NRF_ERROR_INVALID_STATE; break; } return err_code; }
uint32_t dfu_start_pkt_handle(dfu_update_packet_t * p_packet) { uint32_t err_code; m_start_packet = *(p_packet->params.start_packet); // Check that the requested update procedure is supported. // Currently the following combinations are allowed: // - Application // - SoftDevice // - Bootloader // - SoftDevice with Bootloader if (IS_UPDATING_APP(m_start_packet) && (IS_UPDATING_SD(m_start_packet) || IS_UPDATING_BL(m_start_packet))) { // App update is only supported independently. return NRF_ERROR_NOT_SUPPORTED; } if (!(IS_WORD_SIZED(m_start_packet.sd_image_size) && IS_WORD_SIZED(m_start_packet.bl_image_size) && IS_WORD_SIZED(m_start_packet.app_image_size))) { // Image_sizes are not a multiple of 4 (word size). return NRF_ERROR_NOT_SUPPORTED; } m_image_size = m_start_packet.sd_image_size + m_start_packet.bl_image_size + m_start_packet.app_image_size; if (m_start_packet.bl_image_size > DFU_BL_IMAGE_MAX_SIZE) { return NRF_ERROR_DATA_SIZE; } if (m_image_size > (DFU_IMAGE_MAX_SIZE_FULL)) { return NRF_ERROR_DATA_SIZE; } m_functions.prepare = dfu_prepare_func_app_erase; m_functions.cleared = dfu_cleared_func_app; if (IS_UPDATING_SD(m_start_packet)) { m_functions.activate = dfu_activate_sd; } else if (IS_UPDATING_BL(m_start_packet)) { m_functions.activate = dfu_activate_bl; } else { m_functions.activate = dfu_activate_app; } switch (m_dfu_state) { case DFU_STATE_IDLE: // Valid peer activity detected. Hence restart the DFU timer. err_code = dfu_timer_restart(); if (err_code != NRF_SUCCESS) { return err_code; } m_functions.prepare(m_image_size); break; default: err_code = NRF_ERROR_INVALID_STATE; break; } return err_code; }