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.
    }
}
Exemplo n.º 2
0
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.
    }
}
Exemplo n.º 4
0
/**@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;
    }
}
Exemplo n.º 5
0
/**@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;
    }
}