Program to update the D7A modem's firmware.
Dependencies: modem_ref_helper DebouncedInterrupt
cup.cpp
- Committer:
- Jeej
- Date:
- 2016-11-02
- Revision:
- 5:ac38f09fd179
- Parent:
- 4:23cb73bb11b3
- Child:
- 7:5b8648784381
File content as of revision 5:ac38f09fd179:
#include "mbed.h" #include "cup.h" #include "bin.h" #include "crc.h" #include "d7a.h" #include "dbg.h" #define MODEM_FLASH_PAGE_SIZE (256) #define TU_LOCAL (220) CUP_Archive::CUP_Archive(void) : data(cup_data), data_size(CUP_DATA_SIZE), signature(CUP_SIGNATURE), nb_archives(CUP_NB_ARCHIVES), word_size(CUP_WORD_SIZE), fw_major(CUP_FW_MAJOR), fw_minor(CUP_FW_MINOR), fw_patch(CUP_FW_PATCH), fw_hash(CUP_FW_HASH), hw_version(PLATFORM_HW_VERSION) {} void CUP_Archive::start_update(uint32_t src_offset, uint32_t max_size) { cup_cfg_t cfg = { .cmd = 0x10AD, .arch_nb = 20, }; uint32_t fof = 0; int32_t rem = this->data_size; uint8_t percent = 0; uint8_t percent_old = 255; Timer tim; // get archive address uint32_t addr = *((uint32_t*)&this->data[4]); // get uncompressed size uint32_t dsize = *((uint32_t*)&this->data[9]); // End address uint32_t eaddr = addr + dsize; uint32_t offset = 0; if (eaddr > src_offset) { // Calculate offset if needed PRINT("/!\\ CUP process will overwrite Archive: 0x%08X + %d > 0x%08X /!\\\r\n", addr, dsize, src_offset); eaddr = ((eaddr / MODEM_FLASH_PAGE_SIZE) + 1) * MODEM_FLASH_PAGE_SIZE; offset = eaddr - src_offset; PRINT("/!\\ CUP Shifting archive storage to 0x%08X (Offset 0x%X) /!\\\r\n", eaddr, offset); } max_size -= offset; int32_t slack = max_size - this->data_size; ASSERT(slack >= 0, "Not enough space to store archive! (%d bytes short)\r\n", -slack); D7A_WRITE((uint8_t*)&cfg, CUP_CFG_FID, 0, 4, root_key); // Upload file PRINT("Uploading %d bytes at address 0x%08X (%d bytes slack)\r\n", this->data_size, src_offset + offset, slack); tim.start(); while (rem > 0) { D7A_WRITE(&(this->data[fof]), CUP_CODE_FID, fof + offset, TU_LOCAL, NULL); rem -= TU_LOCAL; fof += TU_LOCAL; percent = (100*fof)/this->data_size; if (percent != percent_old) { PRINT("UPLOADING CUP FILE %3d percent\r\n", percent); percent_old = percent; } // Wait to avoid COM faillure Thread::wait(1); } float time_s = tim.read(); PRINT("CUP: %d bytes written in %.2f sec (%.2f kB/s)\r\n", this->data_size, time_s, (this->data_size/time_s)/1024.0); // Force PFLASH-cache flushing D7A_FLUSH(CUP_CODE_FID, root_key); // Send Upgrade command cfg.cmd = 0xC0D5; cfg.arch_nb = this->nb_archives; cfg.src_offset = offset; cfg.signature = this->signature; D7A_WRITE((uint8_t*)&cfg, CUP_CFG_FID, 0, 12, root_key); PRINT("Waiting for reboot...\r\n"); d7a_wait_ready(); D7A_READ(&cfg, CUP_CFG_FID, 0, 2, root_key); if (cfg.cmd) { PRINT("/!\\ CUP Error %d /!\\\r\n", cfg.cmd); } else { PRINT("CUP OK\r\nResetting...\r\n"); FLUSH(); NVIC_SystemReset(); } }