Program to update the D7A modem's firmware.

Dependencies:   modem_ref_helper DebouncedInterrupt

cup.cpp

Committer:
Jeej
Date:
2019-08-20
Revision:
32:e3ee65b5b835
Parent:
26:7fc24677a950
Child:
33:9cd782e2b423

File content as of revision 32:e3ee65b5b835:

#include "cup.h"
#include "bin.h"


uint8_t const modem_data[CUP_DATA_SIZE] = CUP_DATA;
uint8_t const bootloader_data[BOOTLOADER_DATA_SIZE] = BOOTLOADER_DATA;
Semaphore modem_cup_ready(0);

cup_param_t const cup_modem = {
    .data            = (uint8_t*)modem_data,
    .cfg_fid         = CUP_CFG_FID,
    .code_fid        = CUP_CODE_FID,
    .code_size       = CUP_CODE_SIZE,
    .data_size       = CUP_DATA_SIZE,
    .local_mtu       = CUP_LOCAL_MTU,
    .nb_archives     = CUP_NB_ARCHIVES,
    .signature       = CUP_SIGNATURE,
    .mfg_id          = CUP_MFG_ID,
    .dev_id          = CUP_DEV_ID,
    .hw_id           = CUP_HW_ID,
    .fw_major        = CUP_FW_MAJOR,
    .fw_minor        = CUP_FW_MINOR,
    .fw_patch        = CUP_FW_PATCH,
    .fw_hash         = CUP_FW_HASH,
    .target_fw_major = CUP_TARGET_FW_MAJOR,
    .target_fw_minor = CUP_TARGET_FW_MINOR,
};

cup_param_t const cup_bootloader = {
    .data            = (uint8_t*)bootloader_data,
    .cfg_fid         = BOOTLOADER_CFG_FID,
    .code_fid        = BOOTLOADER_CODE_FID,
    .code_size       = BOOTLOADER_CODE_SIZE,
    .data_size       = BOOTLOADER_DATA_SIZE,
    .local_mtu       = BOOTLOADER_LOCAL_MTU,
    .nb_archives     = BOOTLOADER_NB_ARCHIVES,
    .signature       = BOOTLOADER_SIGNATURE,
    .mfg_id          = BOOTLOADER_MFG_ID,
    .dev_id          = BOOTLOADER_DEV_ID,
    .hw_id           = BOOTLOADER_HW_ID,
    .fw_major        = BOOTLOADER_FW_MAJOR,
    .fw_minor        = BOOTLOADER_FW_MINOR,
    .fw_patch        = BOOTLOADER_FW_PATCH,
    .fw_hash         = BOOTLOADER_FW_HASH,
    .target_fw_major = BOOTLOADER_TARGET_FW_MAJOR,
    .target_fw_minor = BOOTLOADER_TARGET_FW_MINOR,
};

void my_cup_callback(uint8_t terminal, int8_t err, uint8_t id)
{
    (void)id;
    
    if (terminal)
    {
        if (err)
        {
            PRINT("Done err %d\n", err);
            FLUSH();
            while(1);
        }
        else
        {
            //PRINT("\nDone.\n");
        }
        modem_cup_ready.release();
    }
    else if (err)
    {
        PRINT("Got err %d\n", err);
        FLUSH();
        while(1);
    }
}

void cup_start_update(uint32_t offset, bool bootloader)
{
    cup_cfg_t cfg = {
        .cmd = 0x10AD,
        .arch_nb = 20,
    };
    
    cup_param_t* cup;
        
    uint32_t fof = 0;
    uint8_t percent = 0;
    uint8_t percent_old = 255;
    Timer tim;
    int32_t rem;
    float now = 0;
    float before = 0;
    float speed = 0;
    int speed_data = 0;
    float time_left = 0;
    
    uint8_t id = modem_get_id(my_cup_callback);
    
    if (bootloader)
    {
        PRINT("Uploading Bootloader\r\n");
        cup = (cup_param_t*)&cup_bootloader;
    }
    else
    {
        PRINT("Uploading New version\r\n");
        cup = (cup_param_t*)&cup_modem;
    }

    rem = cup->data_size;
        
    // Start CUP
    modem_write_file_root(cup->cfg_fid, (uint8_t*)&cfg, 0, 4, root_key, id);
    modem_cup_ready.acquire();
        
    // Upload file
    PRINT("Uploading %d bytes to CUP file. (offset %d)\r\n", cup->data_size, offset);
    
    tim.start();
    
    while (rem > 0)
    {
        int32_t chunk = (rem > cup->local_mtu)? cup->local_mtu : rem;
        modem_write_file(cup->code_fid, &(cup->data[fof]), fof + offset, chunk, id);
        modem_cup_ready.acquire();
        rem -= chunk;
        fof += chunk;
        
        percent = (100*fof)/cup->data_size;
        now = tim.read();
        speed_data += chunk;
        
        if (now - before > 1.0 || before == 0)
        {
            speed = (speed_data/(now - before))/1024.0;
            before = now;
            speed_data = 0;
            time_left = (rem / speed) / 1024.0;
        }
        
        PRINT("\rUPLOADING CUP FILE %d/%d (%3d%%) %.2f kB/s %.0fs    ", fof, cup->data_size, percent, speed, time_left);
    }
    
    PRINT("\n");
    
    float time_s = tim.read();
    PRINT("CUP: %d bytes written in %.2f sec (%.2f kB/s)\r\n", cup->data_size, time_s, (cup->data_size/time_s)/1024.0);
        
    // Force PFLASH-cache flushing
    modem_flush_file_root(cup->code_fid, root_key, id);
    modem_cup_ready.acquire();
        
    // Send Upgrade command
    cfg.cmd = 0xC0D5;
    cfg.arch_nb = cup->nb_archives;
    cfg.src_offset = offset;
    cfg.signature = cup->signature;
        
    modem_write_file_root(cup->cfg_fid, (uint8_t*)&cfg, 0, 12, root_key, id);
    modem_cup_ready.acquire();
    
    PRINT("Waiting self reboot...\r\n");
}