Program to update the D7A modem's firmware.
Dependencies: modem_ref_helper DebouncedInterrupt
main.cpp@24:3aa9b3b4a89c, 2017-09-25 (annotated)
- Committer:
- Jeej
- Date:
- Mon Sep 25 16:24:06 2017 +0000
- Revision:
- 24:3aa9b3b4a89c
- Parent:
- 22:f2b01e5e087e
- Child:
- 25:cf50a4098334
Release SH2050 v4.10.0 (ECC) for v4.9.x (revised)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Jeej | 22:f2b01e5e087e | 1 | #include "DebouncedInterrupt.h" |
Jeej | 22:f2b01e5e087e | 2 | #include "modem_ref_helper.h" |
Jeej | 22:f2b01e5e087e | 3 | #include "modem_callbacks.h" |
Jeej | 22:f2b01e5e087e | 4 | #include "bin.h" |
Jeej | 0:82a60d86ab2e | 5 | #include "cup.h" |
Jeej | 0:82a60d86ab2e | 6 | |
Jeej | 0:82a60d86ab2e | 7 | |
Jeej | 2:e0cdfa7d2a8b | 8 | // To udate your firmware: |
Jeej | 2:e0cdfa7d2a8b | 9 | // - Specify your root key |
Jeej | 2:e0cdfa7d2a8b | 10 | // - Choose your Hardware in bin.h |
Jeej | 2:e0cdfa7d2a8b | 11 | // - Program your NUCLEO with your modem stacked |
Jeej | 2:e0cdfa7d2a8b | 12 | // - Follow the instructions printed on the debug port |
Jeej | 2:e0cdfa7d2a8b | 13 | |
Jeej | 2:e0cdfa7d2a8b | 14 | |
Jeej | 2:e0cdfa7d2a8b | 15 | // This is the default root key |
Jeej | 2:e0cdfa7d2a8b | 16 | // if you have changed this key, please specify it here |
Jeej | 12:beabd59e0c35 | 17 | uint8_t root_key[CUP_DEFAULT_KEY_SIZE] = CUP_DEFAULT_KEY; |
Jeej | 12:beabd59e0c35 | 18 | uint8_t root_key_size = CUP_DEFAULT_KEY_SIZE; |
Jeej | 12:beabd59e0c35 | 19 | |
Jeej | 0:82a60d86ab2e | 20 | // Semaphore for notifiying button presses |
Jeej | 0:82a60d86ab2e | 21 | Semaphore button_user(0); |
Jeej | 22:f2b01e5e087e | 22 | Semaphore modem_ready(0); |
Jeej | 0:82a60d86ab2e | 23 | |
Jeej | 0:82a60d86ab2e | 24 | // Interrupt Service Routine on button press. |
Jeej | 0:82a60d86ab2e | 25 | void button_push_isr( void ) |
Jeej | 0:82a60d86ab2e | 26 | { |
Jeej | 0:82a60d86ab2e | 27 | button_user.release(); |
Jeej | 0:82a60d86ab2e | 28 | } |
Jeej | 0:82a60d86ab2e | 29 | |
Jeej | 7:5b8648784381 | 30 | uint8_t check_parameter(const char* str, uint32_t param1, uint32_t param2) |
Jeej | 7:5b8648784381 | 31 | { |
Jeej | 7:5b8648784381 | 32 | PRINT("Checking %s ", str); |
Jeej | 7:5b8648784381 | 33 | if (param1 != param2) |
Jeej | 7:5b8648784381 | 34 | { |
Jeej | 7:5b8648784381 | 35 | PRINT("Failed. (0x%08X != 0x%08X)\r\n", param1, param2); |
Jeej | 7:5b8648784381 | 36 | return 1; |
Jeej | 7:5b8648784381 | 37 | } |
Jeej | 7:5b8648784381 | 38 | else |
Jeej | 7:5b8648784381 | 39 | { |
Jeej | 7:5b8648784381 | 40 | PRINT("OK. (0x%08X)\r\n", param1); |
Jeej | 7:5b8648784381 | 41 | return 0; |
Jeej | 7:5b8648784381 | 42 | } |
Jeej | 7:5b8648784381 | 43 | } |
Jeej | 7:5b8648784381 | 44 | |
Jeej | 15:24434827c575 | 45 | void print_check_rev(void) |
Jeej | 15:24434827c575 | 46 | { |
Jeej | 17:05c9ec970a6d | 47 | PRINT("\r\n" |
Jeej | 17:05c9ec970a6d | 48 | "/!\\ Please, check that you are at the right commit in the mbed revision tree /!\\\r\n" |
Jeej | 17:05c9ec970a6d | 49 | ); |
Jeej | 15:24434827c575 | 50 | } |
Jeej | 15:24434827c575 | 51 | |
Jeej | 15:24434827c575 | 52 | void print_check_hardware(void) |
Jeej | 15:24434827c575 | 53 | { |
Jeej | 15:24434827c575 | 54 | PRINT("Please, check that you chose the right Hardware in bin.h\r\n"); |
Jeej | 15:24434827c575 | 55 | } |
Jeej | 15:24434827c575 | 56 | |
Jeej | 22:f2b01e5e087e | 57 | int32_t check_slack(uint32_t cup_max_size, uint32_t cup_data_size) |
Jeej | 15:24434827c575 | 58 | { |
Jeej | 16:5a6168dbe7bb | 59 | //PRINT("key: %d data: %d code: %d src: %d\r\n", cup_cfg->key, cup->data_size, cup->code_size, cup_cfg->src_offset); |
Jeej | 15:24434827c575 | 60 | PRINT("Checking CUP Slack... "); |
Jeej | 16:5a6168dbe7bb | 61 | |
Jeej | 18:a8a640941018 | 62 | //int32_t data_size = (((cup->data_size/256)+1)*256); |
Jeej | 22:f2b01e5e087e | 63 | int32_t cup_slack = cup_max_size - cup_data_size; |
Jeej | 18:a8a640941018 | 64 | |
Jeej | 18:a8a640941018 | 65 | cup_slack = ((cup_slack/256)*256); |
Jeej | 15:24434827c575 | 66 | |
Jeej | 15:24434827c575 | 67 | if (cup_slack < 0) |
Jeej | 15:24434827c575 | 68 | { |
Jeej | 15:24434827c575 | 69 | PRINT("Failed. (%d bytes short)\r\n", -cup_slack); |
Jeej | 15:24434827c575 | 70 | } |
Jeej | 15:24434827c575 | 71 | else |
Jeej | 15:24434827c575 | 72 | { |
Jeej | 15:24434827c575 | 73 | PRINT("OK. (%d bytes)\r\n", cup_slack); |
Jeej | 15:24434827c575 | 74 | } |
Jeej | 15:24434827c575 | 75 | |
Jeej | 15:24434827c575 | 76 | return cup_slack; |
Jeej | 15:24434827c575 | 77 | } |
Jeej | 15:24434827c575 | 78 | |
Jeej | 22:f2b01e5e087e | 79 | modem_callbacks_t callbacks = { |
Jeej | 22:f2b01e5e087e | 80 | .read = my_read, |
Jeej | 22:f2b01e5e087e | 81 | .write = my_write, |
Jeej | 22:f2b01e5e087e | 82 | .read_fprop = my_read_fprop, |
Jeej | 22:f2b01e5e087e | 83 | .flush = my_flush, |
Jeej | 22:f2b01e5e087e | 84 | .remove = my_delete, |
Jeej | 22:f2b01e5e087e | 85 | .udata = my_udata, |
Jeej | 22:f2b01e5e087e | 86 | .lqual = my_lqual, |
Jeej | 22:f2b01e5e087e | 87 | .ldown = my_ldown, |
Jeej | 22:f2b01e5e087e | 88 | .reset = my_reset, |
Jeej | 22:f2b01e5e087e | 89 | .boot = my_boot |
Jeej | 22:f2b01e5e087e | 90 | }; |
Jeej | 22:f2b01e5e087e | 91 | |
Jeej | 22:f2b01e5e087e | 92 | // Callback for g_main_id User |
Jeej | 22:f2b01e5e087e | 93 | void my_main_callback(uint8_t terminal, int8_t err, uint8_t id) |
Jeej | 22:f2b01e5e087e | 94 | { |
Jeej | 22:f2b01e5e087e | 95 | (void)id; |
Jeej | 22:f2b01e5e087e | 96 | |
Jeej | 22:f2b01e5e087e | 97 | if (terminal) |
Jeej | 22:f2b01e5e087e | 98 | { |
Jeej | 22:f2b01e5e087e | 99 | if (err) |
Jeej | 22:f2b01e5e087e | 100 | { |
Jeej | 22:f2b01e5e087e | 101 | PRINT("Done err %d\n", err); |
Jeej | 22:f2b01e5e087e | 102 | FLUSH(); |
Jeej | 22:f2b01e5e087e | 103 | while(1); |
Jeej | 22:f2b01e5e087e | 104 | } |
Jeej | 22:f2b01e5e087e | 105 | modem_ready.release(); |
Jeej | 22:f2b01e5e087e | 106 | } |
Jeej | 22:f2b01e5e087e | 107 | else if (err) |
Jeej | 22:f2b01e5e087e | 108 | { |
Jeej | 22:f2b01e5e087e | 109 | PRINT("Got err %d\n", err); |
Jeej | 22:f2b01e5e087e | 110 | FLUSH(); |
Jeej | 22:f2b01e5e087e | 111 | while(1); |
Jeej | 22:f2b01e5e087e | 112 | } |
Jeej | 22:f2b01e5e087e | 113 | } |
Jeej | 22:f2b01e5e087e | 114 | |
Jeej | 22:f2b01e5e087e | 115 | uint8_t g_main_id; |
Jeej | 22:f2b01e5e087e | 116 | |
Jeej | 0:82a60d86ab2e | 117 | int main() |
Jeej | 0:82a60d86ab2e | 118 | { |
Jeej | 15:24434827c575 | 119 | bool bootloader; |
Jeej | 22:f2b01e5e087e | 120 | revision_t rev; |
Jeej | 15:24434827c575 | 121 | cup_param_t* cup = (cup_param_t*)&cup_modem; |
Jeej | 22:f2b01e5e087e | 122 | int32_t cup_slack = 0; |
Jeej | 0:82a60d86ab2e | 123 | |
Jeej | 0:82a60d86ab2e | 124 | // Start & initialize |
Jeej | 12:beabd59e0c35 | 125 | DBG_OPEN(DEBUG_LED); |
Jeej | 13:c3324b26d473 | 126 | PRINT("\r\n" |
Jeej | 24:3aa9b3b4a89c | 127 | "-----------------------------------------\r\n" |
Jeej | 24:3aa9b3b4a89c | 128 | "------------- D7A WM Updater ------------\r\n" |
Jeej | 24:3aa9b3b4a89c | 129 | "-----------------------------------------\r\n"); |
Jeej | 0:82a60d86ab2e | 130 | |
Jeej | 12:beabd59e0c35 | 131 | #ifdef DEBUG_BUTTON |
Jeej | 12:beabd59e0c35 | 132 | DebouncedInterrupt user_interrupt(DEBUG_BUTTON); |
Jeej | 0:82a60d86ab2e | 133 | user_interrupt.attach(button_push_isr, IRQ_FALL, 200, true); |
Jeej | 12:beabd59e0c35 | 134 | #endif |
Jeej | 0:82a60d86ab2e | 135 | |
Jeej | 22:f2b01e5e087e | 136 | modem_helper_open(&callbacks); |
Jeej | 22:f2b01e5e087e | 137 | |
Jeej | 22:f2b01e5e087e | 138 | g_main_id = modem_get_id(my_main_callback); |
Jeej | 0:82a60d86ab2e | 139 | |
Jeej | 13:c3324b26d473 | 140 | do |
Jeej | 0:82a60d86ab2e | 141 | { |
Jeej | 13:c3324b26d473 | 142 | // Check modem revision |
Jeej | 22:f2b01e5e087e | 143 | modem_read_file(D7A_FID_FIRMWARE_VERSION, &rev, 0, sizeof(revision_t), g_main_id); |
Jeej | 22:f2b01e5e087e | 144 | modem_ready.wait(); |
Jeej | 13:c3324b26d473 | 145 | |
Jeej | 15:24434827c575 | 146 | if (check_parameter("Manufacturer ID... ", rev.manufacturer_id, cup->mfg_id)) |
Jeej | 13:c3324b26d473 | 147 | { |
Jeej | 15:24434827c575 | 148 | print_check_rev(); |
Jeej | 13:c3324b26d473 | 149 | break; |
Jeej | 13:c3324b26d473 | 150 | } |
Jeej | 13:c3324b26d473 | 151 | |
Jeej | 22:f2b01e5e087e | 152 | if (check_parameter("Hardware version... ", rev.hw_version, cup->hw_id)) |
Jeej | 13:c3324b26d473 | 153 | { |
Jeej | 15:24434827c575 | 154 | print_check_hardware(); |
Jeej | 13:c3324b26d473 | 155 | break; |
Jeej | 13:c3324b26d473 | 156 | } |
Jeej | 13:c3324b26d473 | 157 | |
Jeej | 15:24434827c575 | 158 | if (rev.device_id == BOOTLOADER_DEV_ID) |
Jeej | 13:c3324b26d473 | 159 | { |
Jeej | 15:24434827c575 | 160 | // Update bootloader |
Jeej | 16:5a6168dbe7bb | 161 | PRINT("\r\n" |
Jeej | 16:5a6168dbe7bb | 162 | "/!\\ This modem has a 4.7.x bootloader firmware. /!\\\r\n" |
Jeej | 16:5a6168dbe7bb | 163 | "/!\\ Step 2/2: Upgrading to full modem firmware. /!\\\r\n" |
Jeej | 16:5a6168dbe7bb | 164 | ); |
Jeej | 15:24434827c575 | 165 | |
Jeej | 22:f2b01e5e087e | 166 | cup_slack = check_slack(rev.cup_max_size, cup->data_size); |
Jeej | 15:24434827c575 | 167 | |
Jeej | 15:24434827c575 | 168 | if (cup_slack < 0) |
Jeej | 15:24434827c575 | 169 | { |
Jeej | 15:24434827c575 | 170 | PRINT("/!\\ Not enough space for bootloader /!\\\r\n"); |
Jeej | 15:24434827c575 | 171 | break; |
Jeej | 15:24434827c575 | 172 | } |
Jeej | 16:5a6168dbe7bb | 173 | |
Jeej | 16:5a6168dbe7bb | 174 | cup_start_update(cup_slack); |
Jeej | 13:c3324b26d473 | 175 | } |
Jeej | 15:24434827c575 | 176 | else |
Jeej | 0:82a60d86ab2e | 177 | { |
Jeej | 15:24434827c575 | 178 | uint32_t version_old = (rev.fw_version.major << 24) | (rev.fw_version.minor << 16) | rev.fw_version.patch; |
Jeej | 15:24434827c575 | 179 | uint32_t version_new = (cup->fw_major << 24) | (cup->fw_minor << 16) | cup->fw_patch; |
Jeej | 15:24434827c575 | 180 | |
Jeej | 15:24434827c575 | 181 | // Update modem |
Jeej | 15:24434827c575 | 182 | if (check_parameter("Device ID... ", rev.device_id, cup->dev_id)) |
Jeej | 15:24434827c575 | 183 | { |
Jeej | 15:24434827c575 | 184 | print_check_rev(); |
Jeej | 15:24434827c575 | 185 | break; |
Jeej | 15:24434827c575 | 186 | } |
Jeej | 15:24434827c575 | 187 | |
Jeej | 24:3aa9b3b4a89c | 188 | /* |
Jeej | 22:f2b01e5e087e | 189 | if (check_parameter("Firmware id... ", rev.fw_version.id&0x7F, cup->fw_id)) |
Jeej | 15:24434827c575 | 190 | { |
Jeej | 15:24434827c575 | 191 | print_check_rev(); |
Jeej | 15:24434827c575 | 192 | break; |
Jeej | 24:3aa9b3b4a89c | 193 | }*/ |
Jeej | 15:24434827c575 | 194 | |
Jeej | 15:24434827c575 | 195 | if (version_old != version_new) |
Jeej | 15:24434827c575 | 196 | { |
Jeej | 15:24434827c575 | 197 | if (check_parameter("Firmware version major...", rev.fw_version.major, cup->target_fw_major)) |
Jeej | 15:24434827c575 | 198 | { |
Jeej | 15:24434827c575 | 199 | print_check_rev(); |
Jeej | 15:24434827c575 | 200 | break; |
Jeej | 15:24434827c575 | 201 | } |
Jeej | 17:05c9ec970a6d | 202 | |
Jeej | 15:24434827c575 | 203 | if (check_parameter("Firmware version minor...", rev.fw_version.minor, cup->target_fw_minor)) |
Jeej | 15:24434827c575 | 204 | { |
Jeej | 15:24434827c575 | 205 | print_check_rev(); |
Jeej | 15:24434827c575 | 206 | break; |
Jeej | 17:05c9ec970a6d | 207 | } |
Jeej | 15:24434827c575 | 208 | } |
Jeej | 15:24434827c575 | 209 | else |
Jeej | 15:24434827c575 | 210 | { |
Jeej | 15:24434827c575 | 211 | PRINT("\r\nYour modem is up to date! (v%d.%d.%d)\r\n", |
Jeej | 15:24434827c575 | 212 | rev.fw_version.major, rev.fw_version.minor, rev.fw_version.patch); |
Jeej | 15:24434827c575 | 213 | break; |
Jeej | 15:24434827c575 | 214 | } |
Jeej | 15:24434827c575 | 215 | |
Jeej | 22:f2b01e5e087e | 216 | cup_slack = check_slack(rev.cup_max_size, cup->data_size); |
Jeej | 15:24434827c575 | 217 | |
Jeej | 15:24434827c575 | 218 | if (cup_slack < 0) |
Jeej | 15:24434827c575 | 219 | { |
Jeej | 16:5a6168dbe7bb | 220 | PRINT("\r\n" |
Jeej | 16:5a6168dbe7bb | 221 | "/!\\ Not enough space for full modem firmware binary /!\\\r\n" |
Jeej | 16:5a6168dbe7bb | 222 | "/!\\ Checking for bootloader firmware /!\\\r\n" |
Jeej | 16:5a6168dbe7bb | 223 | "\r\n" |
Jeej | 16:5a6168dbe7bb | 224 | ); |
Jeej | 22:f2b01e5e087e | 225 | |
Jeej | 22:f2b01e5e087e | 226 | cup_slack = check_slack(rev.cup_max_size, ((cup_param_t*)&cup_bootloader)->data_size); |
Jeej | 15:24434827c575 | 227 | |
Jeej | 15:24434827c575 | 228 | if (cup_slack < 0) |
Jeej | 15:24434827c575 | 229 | { |
Jeej | 15:24434827c575 | 230 | PRINT("/!\\ Not enough space for bootloader /!\\\r\n"); |
Jeej | 15:24434827c575 | 231 | break; |
Jeej | 15:24434827c575 | 232 | } |
Jeej | 15:24434827c575 | 233 | |
Jeej | 15:24434827c575 | 234 | bootloader = true; |
Jeej | 16:5a6168dbe7bb | 235 | |
Jeej | 16:5a6168dbe7bb | 236 | PRINT("\r\n" |
Jeej | 16:5a6168dbe7bb | 237 | "/!\\ This update will be done in 2 steps. /!\\\r\n" |
Jeej | 16:5a6168dbe7bb | 238 | "/!\\ Step 1/2: Upgrading modem to bootloader. /!\\\r\n" |
Jeej | 16:5a6168dbe7bb | 239 | "/!\\ Do no push the reset button or turn off the board during upgrade. /!\\\r\n" |
Jeej | 16:5a6168dbe7bb | 240 | ); |
Jeej | 15:24434827c575 | 241 | } |
Jeej | 15:24434827c575 | 242 | else |
Jeej | 15:24434827c575 | 243 | { |
Jeej | 15:24434827c575 | 244 | bootloader = false; |
Jeej | 15:24434827c575 | 245 | } |
Jeej | 15:24434827c575 | 246 | |
Jeej | 15:24434827c575 | 247 | if (version_old > version_new) |
Jeej | 15:24434827c575 | 248 | { |
Jeej | 15:24434827c575 | 249 | PRINT("/!\\ Your modem is at a more recent version (v%d.%d.%d)/!\\\r\n" |
Jeej | 15:24434827c575 | 250 | "/!\\ Are you sure you want to downgrade to v%d.%d.%d ? /!\\\r\n", |
Jeej | 15:24434827c575 | 251 | rev.fw_version.major, rev.fw_version.minor, rev.fw_version.patch, |
Jeej | 15:24434827c575 | 252 | cup->fw_major, cup->fw_minor, cup->fw_patch); |
Jeej | 18:a8a640941018 | 253 | #ifdef DEBUG_BUTTON |
Jeej | 15:24434827c575 | 254 | PRINT("PRESS USER BUTTON TO CONFIRM...\r\n"); |
Jeej | 15:24434827c575 | 255 | button_user.wait(); |
Jeej | 18:a8a640941018 | 256 | #endif |
Jeej | 15:24434827c575 | 257 | PRINT("\r\nDowngrading firmware: v%d.%d.%d --> v%d.%d.%d\r\n", |
Jeej | 15:24434827c575 | 258 | rev.fw_version.major, rev.fw_version.minor, rev.fw_version.patch, |
Jeej | 15:24434827c575 | 259 | cup->fw_major, cup->fw_minor, cup->fw_patch); |
Jeej | 18:a8a640941018 | 260 | #ifdef DEBUG_BUTTON |
Jeej | 15:24434827c575 | 261 | PRINT("PRESS USER BUTTON TO START DOWNGRADE...\r\n"); |
Jeej | 15:24434827c575 | 262 | button_user.wait(); |
Jeej | 18:a8a640941018 | 263 | #endif |
Jeej | 15:24434827c575 | 264 | } |
Jeej | 15:24434827c575 | 265 | else if (version_old != version_new) |
Jeej | 15:24434827c575 | 266 | { |
Jeej | 15:24434827c575 | 267 | PRINT("\r\nUpgrading firmware: v%d.%d.%d --> v%d.%d.%d\r\n", |
Jeej | 15:24434827c575 | 268 | rev.fw_version.major, rev.fw_version.minor, rev.fw_version.patch, |
Jeej | 15:24434827c575 | 269 | cup->fw_major, cup->fw_minor, cup->fw_patch); |
Jeej | 18:a8a640941018 | 270 | #ifdef DEBUG_BUTTON |
Jeej | 15:24434827c575 | 271 | PRINT("PRESS USER BUTTON TO START UPGRADE...\r\n"); |
Jeej | 15:24434827c575 | 272 | button_user.wait(); |
Jeej | 18:a8a640941018 | 273 | #endif |
Jeej | 15:24434827c575 | 274 | } |
Jeej | 20:100143cecc41 | 275 | else |
Jeej | 20:100143cecc41 | 276 | { |
Jeej | 20:100143cecc41 | 277 | PRINT("\r\nReseting firmware: v%d.%d.%d --> v%d.%d.%d\r\n", |
Jeej | 20:100143cecc41 | 278 | rev.fw_version.major, rev.fw_version.minor, rev.fw_version.patch, |
Jeej | 20:100143cecc41 | 279 | cup->fw_major, cup->fw_minor, cup->fw_patch); |
Jeej | 20:100143cecc41 | 280 | #ifdef DEBUG_BUTTON |
Jeej | 20:100143cecc41 | 281 | PRINT("PRESS USER BUTTON TO START UPGRADE...\r\n"); |
Jeej | 20:100143cecc41 | 282 | button_user.wait(); |
Jeej | 20:100143cecc41 | 283 | #endif |
Jeej | 20:100143cecc41 | 284 | } |
Jeej | 15:24434827c575 | 285 | |
Jeej | 16:5a6168dbe7bb | 286 | cup_start_update(cup_slack, bootloader); |
Jeej | 12:beabd59e0c35 | 287 | } |
Jeej | 13:c3324b26d473 | 288 | |
Jeej | 13:c3324b26d473 | 289 | } while (0); |
Jeej | 0:82a60d86ab2e | 290 | |
Jeej | 0:82a60d86ab2e | 291 | // Set main task to lowest priority |
Jeej | 0:82a60d86ab2e | 292 | osThreadSetPriority(osThreadGetId(), osPriorityIdle); |
Jeej | 0:82a60d86ab2e | 293 | while(true) |
Jeej | 0:82a60d86ab2e | 294 | { |
Jeej | 0:82a60d86ab2e | 295 | // Wait to avoid beeing stuck in loop |
Jeej | 0:82a60d86ab2e | 296 | Thread::wait(200); |
Jeej | 0:82a60d86ab2e | 297 | } |
Jeej | 0:82a60d86ab2e | 298 | } |