Program to update the D7A modem's firmware.

Dependencies:   modem_ref_helper DebouncedInterrupt

cup.h

Committer:
Jeej
Date:
2017-03-10
Revision:
15:24434827c575
Parent:
9:bd53ca2aece5
Child:
22:f2b01e5e087e

File content as of revision 15:24434827c575:

#include "mbed.h"
#include "d7a.h"
#include "bin.h"

#define D7A_READ(_ret, _fid, _offset, _size, _root_key)     do{\
    d7a_msg_t** _msg = d7a_read((_fid), (_offset), (_size), (_root_key));\
    ASSERT(_msg[0]->err >= D7A_ERR_NONE, "READ failed. err %d\r\n", _msg[0]->err);\
    ASSERT(_msg[0]->data, "READ failed. No data in response\r\n");\
    ASSERT(_msg[0]->data->offset == 0, "READ failed. Wrong data offset %d/%d\r\n", _msg[0]->data->offset, (_offset));\
    ASSERT(_msg[0]->data->length == (_size), "READ failed. Wrong data length %d/%d\r\n", _msg[0]->data->length, (_size));\
    memcpy((_ret), _msg[0]->data->buf, (_size));\
    d7a_free_msg(_msg);\
} while (0)

#define D7A_WRITE(_data, _fid, _offset, _size, _root_key)     do{\
    d7a_msg_t** _msg = d7a_write((_fid), (_offset), (_size), (_data), (_root_key));\
    ASSERT(_msg[0]->err == D7A_ERR_NONE, "WRITE failed. err %d\r\n", _msg[0]->err);\
    d7a_free_msg(_msg);\
} while (0)

#define D7A_FLUSH(_fid, _root_key)     do{\
    d7a_msg_t** _msg = d7a_flush((_fid), (_root_key));\
    ASSERT(_msg[0]->err >= D7A_ERR_NONE, "FLUSH failed. err %d\r\n", _msg[0]->err);\
    d7a_free_msg(_msg);\
} while (0)

//------------------------------------------------------------------
// CUP Package files structure:
//   | SIZE |  ADDR  |      BINARY        |  PAD    | CRC  | Next Archive
//   |  4B  |   4B   |        XB          | 0-3 B   |  4B  | ...
//   |                                              |      | ...
//   |<------------------CRC----------------------->|      | ...
//   |<-----------------------SIZE------------------------>| ...
//
// Archive must be word-aligned
// Archives can be concatenated
// ADDR is the destination address of the installed archive
// SIZE accounts for whole archive (including itself)
// Binary size must be multiple of word (i.e pad=4)
// CRC calculated on whole archive (obviously excluding itself)
// Values (size,addr) are stored little-endian


extern uint8_t root_key[CUP_DEFAULT_KEY_SIZE];
extern uint8_t root_key_size;



//======================================================================
// cup_cfg_t
//----------------------------------------------------------------------
/// @brief  This is the structure of the CUP Config FILE.
///         This file _MUST_ always be located a the same place (EEPROM
///         Origin) as BOOT/CUP access it in a hardcoded way.
/// !! Do NOT touch this except if you're a CUP Master !!
//======================================================================
TYPEDEF_STRUCT_PACKED
{
    // The CUP Command
    uint16_t  cmd;
    // Number of Archives to be CUP'ed
    uint16_t  arch_nb;
    // This field has 2 meanings:
    // - when read-out it gives start address of CUP-Code file
    // - when written (for a CUP start) it gives the offset (in bytes) at
    //   which the first archive is stored in CUP-Code file
    uint32_t  src_offset;
    // CRC32 of the arch_nb concatenated archives starting at offset
    uint32_t  signature;
    // TODO: Deciphering key. For now CUP MAX size
    uint32_t  key;
    // Debug / Uart config
    uint32_t  dbg_cfg;
} cup_cfg_t;    

TYPEDEF_STRUCT_PACKED
{
    uint8_t* data;
    uint8_t cfg_fid;
    uint8_t code_fid;
    uint32_t code_size;
    uint32_t data_size;
    uint32_t local_mtu;
    uint32_t nb_archives;
    uint32_t signature;
    uint32_t mfg_id;
    uint32_t dev_id;
    uint32_t hw_id;
    uint8_t fw_id;
    uint8_t fw_major;
    uint8_t fw_minor;
    uint16_t fw_patch;
    uint32_t fw_hash;
    uint8_t target_fw_id;
    uint8_t target_fw_major;
    uint8_t target_fw_minor;
} cup_param_t;


extern cup_param_t const cup_modem;
extern cup_param_t const cup_bootloader;

void cup_start_update(uint32_t offset, bool bootloader = false);