Program to update the D7A modem's firmware.

Dependencies:   modem_ref_helper DebouncedInterrupt

Committer:
Jeej
Date:
Wed Nov 02 14:01:03 2016 +0000
Revision:
5:ac38f09fd179
Parent:
4:23cb73bb11b3
Child:
7:5b8648784381
release v4.5.0

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 5:ac38f09fd179 8 #define MODEM_FLASH_PAGE_SIZE (256)
Jeej 5:ac38f09fd179 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_major(CUP_FW_MAJOR),
Jeej 0:82a60d86ab2e 19 fw_minor(CUP_FW_MINOR),
Jeej 0:82a60d86ab2e 20 fw_patch(CUP_FW_PATCH),
Jeej 0:82a60d86ab2e 21 fw_hash(CUP_FW_HASH),
Jeej 0:82a60d86ab2e 22 hw_version(PLATFORM_HW_VERSION)
Jeej 0:82a60d86ab2e 23 {}
Jeej 0:82a60d86ab2e 24
Jeej 3:a59c8d77006b 25 void CUP_Archive::start_update(uint32_t src_offset, uint32_t max_size)
Jeej 0:82a60d86ab2e 26 {
Jeej 0:82a60d86ab2e 27 cup_cfg_t cfg = {
Jeej 0:82a60d86ab2e 28 .cmd = 0x10AD,
Jeej 5:ac38f09fd179 29 .arch_nb = 20,
Jeej 0:82a60d86ab2e 30 };
Jeej 0:82a60d86ab2e 31
Jeej 0:82a60d86ab2e 32 uint32_t fof = 0;
Jeej 0:82a60d86ab2e 33 int32_t rem = this->data_size;
Jeej 0:82a60d86ab2e 34 uint8_t percent = 0;
Jeej 0:82a60d86ab2e 35 uint8_t percent_old = 255;
Jeej 0:82a60d86ab2e 36 Timer tim;
Jeej 0:82a60d86ab2e 37
Jeej 3:a59c8d77006b 38 // get archive address
Jeej 3:a59c8d77006b 39 uint32_t addr = *((uint32_t*)&this->data[4]);
Jeej 3:a59c8d77006b 40 // get uncompressed size
Jeej 3:a59c8d77006b 41 uint32_t dsize = *((uint32_t*)&this->data[9]);
Jeej 3:a59c8d77006b 42 // End address
Jeej 3:a59c8d77006b 43 uint32_t eaddr = addr + dsize;
Jeej 3:a59c8d77006b 44
Jeej 3:a59c8d77006b 45 uint32_t offset = 0;
Jeej 3:a59c8d77006b 46
Jeej 3:a59c8d77006b 47 if (eaddr > src_offset)
Jeej 3:a59c8d77006b 48 {
Jeej 3:a59c8d77006b 49 // Calculate offset if needed
Jeej 3:a59c8d77006b 50 PRINT("/!\\ CUP process will overwrite Archive: 0x%08X + %d > 0x%08X /!\\\r\n", addr, dsize, src_offset);
Jeej 5:ac38f09fd179 51 eaddr = ((eaddr / MODEM_FLASH_PAGE_SIZE) + 1) * MODEM_FLASH_PAGE_SIZE;
Jeej 3:a59c8d77006b 52 offset = eaddr - src_offset;
Jeej 3:a59c8d77006b 53 PRINT("/!\\ CUP Shifting archive storage to 0x%08X (Offset 0x%X) /!\\\r\n", eaddr, offset);
Jeej 3:a59c8d77006b 54 }
Jeej 3:a59c8d77006b 55
Jeej 3:a59c8d77006b 56 max_size -= offset;
Jeej 3:a59c8d77006b 57 int32_t slack = max_size - this->data_size;
Jeej 4:23cb73bb11b3 58 ASSERT(slack >= 0, "Not enough space to store archive! (%d bytes short)\r\n", -slack);
Jeej 3:a59c8d77006b 59
Jeej 3:a59c8d77006b 60 D7A_WRITE((uint8_t*)&cfg, CUP_CFG_FID, 0, 4, root_key);
Jeej 0:82a60d86ab2e 61
Jeej 0:82a60d86ab2e 62 // Upload file
Jeej 3:a59c8d77006b 63 PRINT("Uploading %d bytes at address 0x%08X (%d bytes slack)\r\n", this->data_size, src_offset + offset, slack);
Jeej 0:82a60d86ab2e 64
Jeej 0:82a60d86ab2e 65 tim.start();
Jeej 0:82a60d86ab2e 66
Jeej 0:82a60d86ab2e 67 while (rem > 0)
Jeej 0:82a60d86ab2e 68 {
Jeej 3:a59c8d77006b 69 D7A_WRITE(&(this->data[fof]), CUP_CODE_FID, fof + offset, TU_LOCAL, NULL);
Jeej 0:82a60d86ab2e 70 rem -= TU_LOCAL;
Jeej 0:82a60d86ab2e 71 fof += TU_LOCAL;
Jeej 0:82a60d86ab2e 72
Jeej 0:82a60d86ab2e 73 percent = (100*fof)/this->data_size;
Jeej 0:82a60d86ab2e 74 if (percent != percent_old)
Jeej 0:82a60d86ab2e 75 {
Jeej 0:82a60d86ab2e 76 PRINT("UPLOADING CUP FILE %3d percent\r\n", percent);
Jeej 0:82a60d86ab2e 77 percent_old = percent;
Jeej 0:82a60d86ab2e 78 }
Jeej 0:82a60d86ab2e 79
Jeej 0:82a60d86ab2e 80 // Wait to avoid COM faillure
Jeej 0:82a60d86ab2e 81 Thread::wait(1);
Jeej 0:82a60d86ab2e 82 }
Jeej 0:82a60d86ab2e 83
Jeej 0:82a60d86ab2e 84 float time_s = tim.read();
Jeej 4:23cb73bb11b3 85 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);
Jeej 0:82a60d86ab2e 86
Jeej 3:a59c8d77006b 87 // Force PFLASH-cache flushing
Jeej 0:82a60d86ab2e 88 D7A_FLUSH(CUP_CODE_FID, root_key);
Jeej 0:82a60d86ab2e 89
Jeej 0:82a60d86ab2e 90 // Send Upgrade command
Jeej 0:82a60d86ab2e 91 cfg.cmd = 0xC0D5;
Jeej 0:82a60d86ab2e 92 cfg.arch_nb = this->nb_archives;
Jeej 3:a59c8d77006b 93 cfg.src_offset = offset;
Jeej 0:82a60d86ab2e 94 cfg.signature = this->signature;
Jeej 0:82a60d86ab2e 95
Jeej 0:82a60d86ab2e 96 D7A_WRITE((uint8_t*)&cfg, CUP_CFG_FID, 0, 12, root_key);
Jeej 0:82a60d86ab2e 97
Jeej 5:ac38f09fd179 98 PRINT("Waiting for reboot...\r\n");
Jeej 4:23cb73bb11b3 99
Jeej 4:23cb73bb11b3 100 d7a_wait_ready();
Jeej 4:23cb73bb11b3 101
Jeej 4:23cb73bb11b3 102 D7A_READ(&cfg, CUP_CFG_FID, 0, 2, root_key);
Jeej 4:23cb73bb11b3 103
Jeej 4:23cb73bb11b3 104 if (cfg.cmd)
Jeej 4:23cb73bb11b3 105 {
Jeej 4:23cb73bb11b3 106 PRINT("/!\\ CUP Error %d /!\\\r\n", cfg.cmd);
Jeej 4:23cb73bb11b3 107 }
Jeej 4:23cb73bb11b3 108 else
Jeej 4:23cb73bb11b3 109 {
Jeej 4:23cb73bb11b3 110 PRINT("CUP OK\r\nResetting...\r\n");
Jeej 4:23cb73bb11b3 111 FLUSH();
Jeej 4:23cb73bb11b3 112 NVIC_SystemReset();
Jeej 4:23cb73bb11b3 113 }
Jeej 0:82a60d86ab2e 114 }
Jeej 0:82a60d86ab2e 115