Program to update the D7A modem's firmware.

Dependencies:   modem_ref_helper DebouncedInterrupt

Committer:
Jeej
Date:
Wed Oct 26 14:13:58 2016 +0000
Revision:
3:a59c8d77006b
Parent:
2:e0cdfa7d2a8b
Child:
4:23cb73bb11b3
Implemented automatic src offset shift.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jeej 0:82a60d86ab2e 1 #include "mbed.h"
Jeej 0:82a60d86ab2e 2 #include "cup.h"
Jeej 0:82a60d86ab2e 3 #include "bin.h"
Jeej 0:82a60d86ab2e 4 #include "crc.h"
Jeej 0:82a60d86ab2e 5 #include "d7a.h"
Jeej 0:82a60d86ab2e 6 #include "dbg.h"
Jeej 0:82a60d86ab2e 7
Jeej 0:82a60d86ab2e 8 #define FLASH_PAGE_SIZE (256)
Jeej 0:82a60d86ab2e 9 #define TU_LOCAL (220)
Jeej 0:82a60d86ab2e 10
Jeej 0:82a60d86ab2e 11
Jeej 0:82a60d86ab2e 12 CUP_Archive::CUP_Archive(void) :
Jeej 0:82a60d86ab2e 13 data(cup_data),
Jeej 0:82a60d86ab2e 14 data_size(CUP_DATA_SIZE),
Jeej 0:82a60d86ab2e 15 signature(CUP_SIGNATURE),
Jeej 0:82a60d86ab2e 16 nb_archives(CUP_NB_ARCHIVES),
Jeej 0:82a60d86ab2e 17 word_size(CUP_WORD_SIZE),
Jeej 0:82a60d86ab2e 18 fw_id(0),
Jeej 0:82a60d86ab2e 19 fw_major(CUP_FW_MAJOR),
Jeej 0:82a60d86ab2e 20 fw_minor(CUP_FW_MINOR),
Jeej 0:82a60d86ab2e 21 fw_patch(CUP_FW_PATCH),
Jeej 0:82a60d86ab2e 22 fw_hash(CUP_FW_HASH),
Jeej 0:82a60d86ab2e 23 hw_version(PLATFORM_HW_VERSION)
Jeej 0:82a60d86ab2e 24 {}
Jeej 0:82a60d86ab2e 25
Jeej 3:a59c8d77006b 26 void CUP_Archive::start_update(uint32_t src_offset, uint32_t max_size)
Jeej 0:82a60d86ab2e 27 {
Jeej 0:82a60d86ab2e 28 cup_cfg_t cfg = {
Jeej 0:82a60d86ab2e 29 .cmd = 0x10AD,
Jeej 0:82a60d86ab2e 30 .arch_nb = 100,
Jeej 0:82a60d86ab2e 31 };
Jeej 0:82a60d86ab2e 32
Jeej 0:82a60d86ab2e 33 uint32_t fof = 0;
Jeej 0:82a60d86ab2e 34 int32_t rem = this->data_size;
Jeej 0:82a60d86ab2e 35 uint8_t percent = 0;
Jeej 0:82a60d86ab2e 36 uint8_t percent_old = 255;
Jeej 0:82a60d86ab2e 37 Timer tim;
Jeej 0:82a60d86ab2e 38
Jeej 3:a59c8d77006b 39 // get archive address
Jeej 3:a59c8d77006b 40 uint32_t addr = *((uint32_t*)&this->data[4]);
Jeej 3:a59c8d77006b 41 // get uncompressed size
Jeej 3:a59c8d77006b 42 uint32_t dsize = *((uint32_t*)&this->data[9]);
Jeej 3:a59c8d77006b 43 // End address
Jeej 3:a59c8d77006b 44 uint32_t eaddr = addr + dsize;
Jeej 3:a59c8d77006b 45
Jeej 3:a59c8d77006b 46 uint32_t offset = 0;
Jeej 3:a59c8d77006b 47
Jeej 3:a59c8d77006b 48 if (eaddr > src_offset)
Jeej 3:a59c8d77006b 49 {
Jeej 3:a59c8d77006b 50 // Calculate offset if needed
Jeej 3:a59c8d77006b 51 PRINT("/!\\ CUP process will overwrite Archive: 0x%08X + %d > 0x%08X /!\\\r\n", addr, dsize, src_offset);
Jeej 3:a59c8d77006b 52 eaddr = ((eaddr / FLASH_PAGE_SIZE) + 1) * FLASH_PAGE_SIZE;
Jeej 3:a59c8d77006b 53 offset = eaddr - src_offset;
Jeej 3:a59c8d77006b 54 PRINT("/!\\ CUP Shifting archive storage to 0x%08X (Offset 0x%X) /!\\\r\n", eaddr, offset);
Jeej 3:a59c8d77006b 55 }
Jeej 3:a59c8d77006b 56
Jeej 3:a59c8d77006b 57 max_size -= offset;
Jeej 3:a59c8d77006b 58 int32_t slack = max_size - this->data_size;
Jeej 3:a59c8d77006b 59 ASSERT(slack >= 0, "Not enough space to store archive! (%d bytes short)\r\n", slack);
Jeej 3:a59c8d77006b 60
Jeej 3:a59c8d77006b 61 D7A_WRITE((uint8_t*)&cfg, CUP_CFG_FID, 0, 4, root_key);
Jeej 0:82a60d86ab2e 62
Jeej 0:82a60d86ab2e 63 // Upload file
Jeej 3:a59c8d77006b 64 PRINT("Uploading %d bytes at address 0x%08X (%d bytes slack)\r\n", this->data_size, src_offset + offset, slack);
Jeej 0:82a60d86ab2e 65
Jeej 0:82a60d86ab2e 66 tim.start();
Jeej 0:82a60d86ab2e 67
Jeej 0:82a60d86ab2e 68 while (rem > 0)
Jeej 0:82a60d86ab2e 69 {
Jeej 3:a59c8d77006b 70 D7A_WRITE(&(this->data[fof]), CUP_CODE_FID, fof + offset, TU_LOCAL, NULL);
Jeej 0:82a60d86ab2e 71 rem -= TU_LOCAL;
Jeej 0:82a60d86ab2e 72 fof += TU_LOCAL;
Jeej 0:82a60d86ab2e 73
Jeej 0:82a60d86ab2e 74 percent = (100*fof)/this->data_size;
Jeej 0:82a60d86ab2e 75 if (percent != percent_old)
Jeej 0:82a60d86ab2e 76 {
Jeej 0:82a60d86ab2e 77 PRINT("UPLOADING CUP FILE %3d percent\r\n", percent);
Jeej 0:82a60d86ab2e 78 percent_old = percent;
Jeej 0:82a60d86ab2e 79 }
Jeej 0:82a60d86ab2e 80
Jeej 0:82a60d86ab2e 81 // Wait to avoid COM faillure
Jeej 0:82a60d86ab2e 82 Thread::wait(1);
Jeej 0:82a60d86ab2e 83 }
Jeej 0:82a60d86ab2e 84
Jeej 0:82a60d86ab2e 85 float time_s = tim.read();
Jeej 2:e0cdfa7d2a8b 86 PRINT("File[%d] %d bytes written in %.2f sec (%.2f kB/s)\r\n", CUP_CODE_FID, this->data_size, time_s, (this->data_size/time_s)/1024.0);
Jeej 0:82a60d86ab2e 87
Jeej 3:a59c8d77006b 88 // Force PFLASH-cache flushing
Jeej 0:82a60d86ab2e 89 D7A_FLUSH(CUP_CODE_FID, root_key);
Jeej 0:82a60d86ab2e 90
Jeej 0:82a60d86ab2e 91 // Send Upgrade command
Jeej 0:82a60d86ab2e 92 cfg.cmd = 0xC0D5;
Jeej 0:82a60d86ab2e 93 cfg.arch_nb = this->nb_archives;
Jeej 3:a59c8d77006b 94 cfg.src_offset = offset;
Jeej 0:82a60d86ab2e 95 cfg.signature = this->signature;
Jeej 0:82a60d86ab2e 96
Jeej 0:82a60d86ab2e 97 D7A_WRITE((uint8_t*)&cfg, CUP_CFG_FID, 0, 12, root_key);
Jeej 0:82a60d86ab2e 98
Jeej 1:765933092750 99 PRINT("CUP Done.\r\nPlease wait for reboot...\r\n");
Jeej 0:82a60d86ab2e 100 }
Jeej 0:82a60d86ab2e 101