Program to update the D7A modem's firmware.
Dependencies: modem_ref_helper DebouncedInterrupt
cup.cpp@36:38fcc2a38d2d, 2021-09-06 (annotated)
- Committer:
- Jeej
- Date:
- Mon Sep 06 15:11:41 2021 +0000
- Revision:
- 36:38fcc2a38d2d
- Parent:
- 33:9cd782e2b423
SH2050 v6.1.80
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Jeej | 0:82a60d86ab2e | 1 | #include "cup.h" |
Jeej | 0:82a60d86ab2e | 2 | #include "bin.h" |
Jeej | 0:82a60d86ab2e | 3 | |
Jeej | 0:82a60d86ab2e | 4 | |
Jeej | 15:24434827c575 | 5 | uint8_t const modem_data[CUP_DATA_SIZE] = CUP_DATA; |
Jeej | 15:24434827c575 | 6 | uint8_t const bootloader_data[BOOTLOADER_DATA_SIZE] = BOOTLOADER_DATA; |
Jeej | 22:f2b01e5e087e | 7 | Semaphore modem_cup_ready(0); |
Jeej | 0:82a60d86ab2e | 8 | |
Jeej | 15:24434827c575 | 9 | cup_param_t const cup_modem = { |
Jeej | 15:24434827c575 | 10 | .data = (uint8_t*)modem_data, |
Jeej | 15:24434827c575 | 11 | .cfg_fid = CUP_CFG_FID, |
Jeej | 15:24434827c575 | 12 | .code_fid = CUP_CODE_FID, |
Jeej | 15:24434827c575 | 13 | .code_size = CUP_CODE_SIZE, |
Jeej | 15:24434827c575 | 14 | .data_size = CUP_DATA_SIZE, |
Jeej | 15:24434827c575 | 15 | .local_mtu = CUP_LOCAL_MTU, |
Jeej | 15:24434827c575 | 16 | .nb_archives = CUP_NB_ARCHIVES, |
Jeej | 15:24434827c575 | 17 | .signature = CUP_SIGNATURE, |
Jeej | 15:24434827c575 | 18 | .mfg_id = CUP_MFG_ID, |
Jeej | 15:24434827c575 | 19 | .dev_id = CUP_DEV_ID, |
Jeej | 15:24434827c575 | 20 | .hw_id = CUP_HW_ID, |
Jeej | 15:24434827c575 | 21 | .fw_major = CUP_FW_MAJOR, |
Jeej | 15:24434827c575 | 22 | .fw_minor = CUP_FW_MINOR, |
Jeej | 15:24434827c575 | 23 | .fw_patch = CUP_FW_PATCH, |
Jeej | 15:24434827c575 | 24 | .fw_hash = CUP_FW_HASH, |
Jeej | 15:24434827c575 | 25 | .target_fw_major = CUP_TARGET_FW_MAJOR, |
Jeej | 15:24434827c575 | 26 | .target_fw_minor = CUP_TARGET_FW_MINOR, |
Jeej | 15:24434827c575 | 27 | }; |
Jeej | 15:24434827c575 | 28 | |
Jeej | 15:24434827c575 | 29 | cup_param_t const cup_bootloader = { |
Jeej | 15:24434827c575 | 30 | .data = (uint8_t*)bootloader_data, |
Jeej | 15:24434827c575 | 31 | .cfg_fid = BOOTLOADER_CFG_FID, |
Jeej | 15:24434827c575 | 32 | .code_fid = BOOTLOADER_CODE_FID, |
Jeej | 15:24434827c575 | 33 | .code_size = BOOTLOADER_CODE_SIZE, |
Jeej | 15:24434827c575 | 34 | .data_size = BOOTLOADER_DATA_SIZE, |
Jeej | 15:24434827c575 | 35 | .local_mtu = BOOTLOADER_LOCAL_MTU, |
Jeej | 15:24434827c575 | 36 | .nb_archives = BOOTLOADER_NB_ARCHIVES, |
Jeej | 15:24434827c575 | 37 | .signature = BOOTLOADER_SIGNATURE, |
Jeej | 15:24434827c575 | 38 | .mfg_id = BOOTLOADER_MFG_ID, |
Jeej | 15:24434827c575 | 39 | .dev_id = BOOTLOADER_DEV_ID, |
Jeej | 15:24434827c575 | 40 | .hw_id = BOOTLOADER_HW_ID, |
Jeej | 15:24434827c575 | 41 | .fw_major = BOOTLOADER_FW_MAJOR, |
Jeej | 15:24434827c575 | 42 | .fw_minor = BOOTLOADER_FW_MINOR, |
Jeej | 15:24434827c575 | 43 | .fw_patch = BOOTLOADER_FW_PATCH, |
Jeej | 15:24434827c575 | 44 | .fw_hash = BOOTLOADER_FW_HASH, |
Jeej | 15:24434827c575 | 45 | .target_fw_major = BOOTLOADER_TARGET_FW_MAJOR, |
Jeej | 15:24434827c575 | 46 | .target_fw_minor = BOOTLOADER_TARGET_FW_MINOR, |
Jeej | 15:24434827c575 | 47 | }; |
Jeej | 15:24434827c575 | 48 | |
Jeej | 22:f2b01e5e087e | 49 | void my_cup_callback(uint8_t terminal, int8_t err, uint8_t id) |
Jeej | 22:f2b01e5e087e | 50 | { |
Jeej | 22:f2b01e5e087e | 51 | (void)id; |
Jeej | 22:f2b01e5e087e | 52 | |
Jeej | 22:f2b01e5e087e | 53 | if (terminal) |
Jeej | 22:f2b01e5e087e | 54 | { |
Jeej | 22:f2b01e5e087e | 55 | if (err) |
Jeej | 22:f2b01e5e087e | 56 | { |
Jeej | 22:f2b01e5e087e | 57 | PRINT("Done err %d\n", err); |
Jeej | 22:f2b01e5e087e | 58 | FLUSH(); |
Jeej | 22:f2b01e5e087e | 59 | while(1); |
Jeej | 22:f2b01e5e087e | 60 | } |
Jeej | 32:e3ee65b5b835 | 61 | else |
Jeej | 32:e3ee65b5b835 | 62 | { |
Jeej | 32:e3ee65b5b835 | 63 | //PRINT("\nDone.\n"); |
Jeej | 32:e3ee65b5b835 | 64 | } |
Jeej | 22:f2b01e5e087e | 65 | modem_cup_ready.release(); |
Jeej | 22:f2b01e5e087e | 66 | } |
Jeej | 22:f2b01e5e087e | 67 | else if (err) |
Jeej | 22:f2b01e5e087e | 68 | { |
Jeej | 22:f2b01e5e087e | 69 | PRINT("Got err %d\n", err); |
Jeej | 22:f2b01e5e087e | 70 | FLUSH(); |
Jeej | 22:f2b01e5e087e | 71 | while(1); |
Jeej | 22:f2b01e5e087e | 72 | } |
Jeej | 22:f2b01e5e087e | 73 | } |
Jeej | 22:f2b01e5e087e | 74 | |
Jeej | 15:24434827c575 | 75 | void cup_start_update(uint32_t offset, bool bootloader) |
Jeej | 0:82a60d86ab2e | 76 | { |
Jeej | 0:82a60d86ab2e | 77 | cup_cfg_t cfg = { |
Jeej | 0:82a60d86ab2e | 78 | .cmd = 0x10AD, |
Jeej | 5:ac38f09fd179 | 79 | .arch_nb = 20, |
Jeej | 0:82a60d86ab2e | 80 | }; |
Jeej | 0:82a60d86ab2e | 81 | |
Jeej | 15:24434827c575 | 82 | cup_param_t* cup; |
Jeej | 15:24434827c575 | 83 | |
Jeej | 0:82a60d86ab2e | 84 | uint32_t fof = 0; |
Jeej | 0:82a60d86ab2e | 85 | uint8_t percent = 0; |
Jeej | 0:82a60d86ab2e | 86 | uint8_t percent_old = 255; |
Jeej | 0:82a60d86ab2e | 87 | Timer tim; |
Jeej | 15:24434827c575 | 88 | int32_t rem; |
Jeej | 32:e3ee65b5b835 | 89 | float now = 0; |
Jeej | 33:9cd782e2b423 | 90 | |
Jeej | 33:9cd782e2b423 | 91 | float speed_before = 0; |
Jeej | 32:e3ee65b5b835 | 92 | float speed = 0; |
Jeej | 32:e3ee65b5b835 | 93 | int speed_data = 0; |
Jeej | 33:9cd782e2b423 | 94 | |
Jeej | 33:9cd782e2b423 | 95 | float time_before = 0; |
Jeej | 32:e3ee65b5b835 | 96 | float time_left = 0; |
Jeej | 0:82a60d86ab2e | 97 | |
Jeej | 33:9cd782e2b423 | 98 | float print_before = 0; |
Jeej | 33:9cd782e2b423 | 99 | |
Jeej | 22:f2b01e5e087e | 100 | uint8_t id = modem_get_id(my_cup_callback); |
Jeej | 22:f2b01e5e087e | 101 | |
Jeej | 15:24434827c575 | 102 | if (bootloader) |
Jeej | 15:24434827c575 | 103 | { |
Jeej | 15:24434827c575 | 104 | PRINT("Uploading Bootloader\r\n"); |
Jeej | 15:24434827c575 | 105 | cup = (cup_param_t*)&cup_bootloader; |
Jeej | 15:24434827c575 | 106 | } |
Jeej | 15:24434827c575 | 107 | else |
Jeej | 15:24434827c575 | 108 | { |
Jeej | 15:24434827c575 | 109 | PRINT("Uploading New version\r\n"); |
Jeej | 15:24434827c575 | 110 | cup = (cup_param_t*)&cup_modem; |
Jeej | 15:24434827c575 | 111 | } |
Jeej | 15:24434827c575 | 112 | |
Jeej | 15:24434827c575 | 113 | rem = cup->data_size; |
Jeej | 22:f2b01e5e087e | 114 | |
Jeej | 15:24434827c575 | 115 | // Start CUP |
Jeej | 22:f2b01e5e087e | 116 | modem_write_file_root(cup->cfg_fid, (uint8_t*)&cfg, 0, 4, root_key, id); |
Jeej | 32:e3ee65b5b835 | 117 | modem_cup_ready.acquire(); |
Jeej | 18:a8a640941018 | 118 | |
Jeej | 0:82a60d86ab2e | 119 | // Upload file |
Jeej | 15:24434827c575 | 120 | PRINT("Uploading %d bytes to CUP file. (offset %d)\r\n", cup->data_size, offset); |
Jeej | 0:82a60d86ab2e | 121 | |
Jeej | 0:82a60d86ab2e | 122 | tim.start(); |
Jeej | 0:82a60d86ab2e | 123 | |
Jeej | 0:82a60d86ab2e | 124 | while (rem > 0) |
Jeej | 0:82a60d86ab2e | 125 | { |
Jeej | 15:24434827c575 | 126 | int32_t chunk = (rem > cup->local_mtu)? cup->local_mtu : rem; |
Jeej | 22:f2b01e5e087e | 127 | modem_write_file(cup->code_fid, &(cup->data[fof]), fof + offset, chunk, id); |
Jeej | 32:e3ee65b5b835 | 128 | modem_cup_ready.acquire(); |
Jeej | 15:24434827c575 | 129 | rem -= chunk; |
Jeej | 15:24434827c575 | 130 | fof += chunk; |
Jeej | 0:82a60d86ab2e | 131 | |
Jeej | 32:e3ee65b5b835 | 132 | now = tim.read(); |
Jeej | 32:e3ee65b5b835 | 133 | speed_data += chunk; |
Jeej | 32:e3ee65b5b835 | 134 | |
Jeej | 33:9cd782e2b423 | 135 | // Update speed |
Jeej | 33:9cd782e2b423 | 136 | if (now - speed_before > 1.0 || speed_before == 0) |
Jeej | 0:82a60d86ab2e | 137 | { |
Jeej | 33:9cd782e2b423 | 138 | speed = (speed_data/(now - speed_before))/1024.0; |
Jeej | 33:9cd782e2b423 | 139 | speed_before = now; |
Jeej | 32:e3ee65b5b835 | 140 | speed_data = 0; |
Jeej | 33:9cd782e2b423 | 141 | } |
Jeej | 33:9cd782e2b423 | 142 | |
Jeej | 33:9cd782e2b423 | 143 | // Update time left |
Jeej | 33:9cd782e2b423 | 144 | if (now - time_before > 0.2 || time_before == 0 || rem == 0) |
Jeej | 33:9cd782e2b423 | 145 | { |
Jeej | 33:9cd782e2b423 | 146 | time_before = now; |
Jeej | 32:e3ee65b5b835 | 147 | time_left = (rem / speed) / 1024.0; |
Jeej | 0:82a60d86ab2e | 148 | } |
Jeej | 0:82a60d86ab2e | 149 | |
Jeej | 33:9cd782e2b423 | 150 | |
Jeej | 33:9cd782e2b423 | 151 | if (now - print_before > 0.1 || print_before == 0 || rem == 0) |
Jeej | 33:9cd782e2b423 | 152 | { |
Jeej | 33:9cd782e2b423 | 153 | percent = (100*fof)/cup->data_size; |
Jeej | 33:9cd782e2b423 | 154 | print_before = now; |
Jeej | 33:9cd782e2b423 | 155 | PRINT("\rUPLOADING CUP FILE %d/%d (%3d%%) %.2f kB/s %.0fs ", fof, cup->data_size, percent, speed, time_left); |
Jeej | 33:9cd782e2b423 | 156 | } |
Jeej | 0:82a60d86ab2e | 157 | } |
Jeej | 0:82a60d86ab2e | 158 | |
Jeej | 32:e3ee65b5b835 | 159 | PRINT("\n"); |
Jeej | 32:e3ee65b5b835 | 160 | |
Jeej | 0:82a60d86ab2e | 161 | float time_s = tim.read(); |
Jeej | 15:24434827c575 | 162 | 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); |
Jeej | 18:a8a640941018 | 163 | |
Jeej | 3:a59c8d77006b | 164 | // Force PFLASH-cache flushing |
Jeej | 22:f2b01e5e087e | 165 | modem_flush_file_root(cup->code_fid, root_key, id); |
Jeej | 32:e3ee65b5b835 | 166 | modem_cup_ready.acquire(); |
Jeej | 0:82a60d86ab2e | 167 | |
Jeej | 0:82a60d86ab2e | 168 | // Send Upgrade command |
Jeej | 0:82a60d86ab2e | 169 | cfg.cmd = 0xC0D5; |
Jeej | 15:24434827c575 | 170 | cfg.arch_nb = cup->nb_archives; |
Jeej | 3:a59c8d77006b | 171 | cfg.src_offset = offset; |
Jeej | 15:24434827c575 | 172 | cfg.signature = cup->signature; |
Jeej | 0:82a60d86ab2e | 173 | |
Jeej | 22:f2b01e5e087e | 174 | modem_write_file_root(cup->cfg_fid, (uint8_t*)&cfg, 0, 12, root_key, id); |
Jeej | 32:e3ee65b5b835 | 175 | modem_cup_ready.acquire(); |
Jeej | 0:82a60d86ab2e | 176 | |
Jeej | 7:5b8648784381 | 177 | PRINT("Waiting self reboot...\r\n"); |
Jeej | 0:82a60d86ab2e | 178 | } |
Jeej | 0:82a60d86ab2e | 179 |