Program to update the D7A modem's firmware.

Dependencies:   modem_ref_helper DebouncedInterrupt

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?

UserRevisionLine numberNew 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 }