Program to update the D7A modem's firmware.

Dependencies:   modem_ref_helper DebouncedInterrupt

Committer:
Jeej
Date:
Fri Oct 20 13:35:45 2017 +0000
Revision:
25:cf50a4098334
Parent:
24:3aa9b3b4a89c
Child:
26:7fc24677a950
Release SH2050 v4.11.3 for v4.10.x; Enables the modem's LoRaWAN stack.

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 25:cf50a4098334 213
Jeej 25:cf50a4098334 214 PRINT("\r\n"
Jeej 25:cf50a4098334 215 "This new version enables the LoRaWAN stack on the modem.\n"
Jeej 25:cf50a4098334 216 "If you want to use LoRaWAN with the Dash7Board, please contact us at support@wizzilab.com\n"
Jeej 25:cf50a4098334 217 "We will enable your device to work with it.\n"
Jeej 25:cf50a4098334 218 "A demo application is available here to get started with the LoRaWAN stack:\n"
Jeej 25:cf50a4098334 219 "https://os.mbed.com/teams/WizziLab/code/D7A_1x_demo_LoRaWAN/\n"
Jeej 25:cf50a4098334 220 );
Jeej 15:24434827c575 221 break;
Jeej 15:24434827c575 222 }
Jeej 15:24434827c575 223
Jeej 22:f2b01e5e087e 224 cup_slack = check_slack(rev.cup_max_size, cup->data_size);
Jeej 15:24434827c575 225
Jeej 15:24434827c575 226 if (cup_slack < 0)
Jeej 15:24434827c575 227 {
Jeej 16:5a6168dbe7bb 228 PRINT("\r\n"
Jeej 16:5a6168dbe7bb 229 "/!\\ Not enough space for full modem firmware binary /!\\\r\n"
Jeej 16:5a6168dbe7bb 230 "/!\\ Checking for bootloader firmware /!\\\r\n"
Jeej 16:5a6168dbe7bb 231 "\r\n"
Jeej 16:5a6168dbe7bb 232 );
Jeej 22:f2b01e5e087e 233
Jeej 22:f2b01e5e087e 234 cup_slack = check_slack(rev.cup_max_size, ((cup_param_t*)&cup_bootloader)->data_size);
Jeej 15:24434827c575 235
Jeej 15:24434827c575 236 if (cup_slack < 0)
Jeej 15:24434827c575 237 {
Jeej 15:24434827c575 238 PRINT("/!\\ Not enough space for bootloader /!\\\r\n");
Jeej 15:24434827c575 239 break;
Jeej 15:24434827c575 240 }
Jeej 15:24434827c575 241
Jeej 15:24434827c575 242 bootloader = true;
Jeej 16:5a6168dbe7bb 243
Jeej 16:5a6168dbe7bb 244 PRINT("\r\n"
Jeej 16:5a6168dbe7bb 245 "/!\\ This update will be done in 2 steps. /!\\\r\n"
Jeej 16:5a6168dbe7bb 246 "/!\\ Step 1/2: Upgrading modem to bootloader. /!\\\r\n"
Jeej 16:5a6168dbe7bb 247 "/!\\ Do no push the reset button or turn off the board during upgrade. /!\\\r\n"
Jeej 16:5a6168dbe7bb 248 );
Jeej 15:24434827c575 249 }
Jeej 15:24434827c575 250 else
Jeej 15:24434827c575 251 {
Jeej 15:24434827c575 252 bootloader = false;
Jeej 15:24434827c575 253 }
Jeej 15:24434827c575 254
Jeej 15:24434827c575 255 if (version_old > version_new)
Jeej 15:24434827c575 256 {
Jeej 15:24434827c575 257 PRINT("/!\\ Your modem is at a more recent version (v%d.%d.%d)/!\\\r\n"
Jeej 15:24434827c575 258 "/!\\ Are you sure you want to downgrade to v%d.%d.%d ? /!\\\r\n",
Jeej 15:24434827c575 259 rev.fw_version.major, rev.fw_version.minor, rev.fw_version.patch,
Jeej 15:24434827c575 260 cup->fw_major, cup->fw_minor, cup->fw_patch);
Jeej 18:a8a640941018 261 #ifdef DEBUG_BUTTON
Jeej 15:24434827c575 262 PRINT("PRESS USER BUTTON TO CONFIRM...\r\n");
Jeej 15:24434827c575 263 button_user.wait();
Jeej 18:a8a640941018 264 #endif
Jeej 15:24434827c575 265 PRINT("\r\nDowngrading firmware: v%d.%d.%d --> v%d.%d.%d\r\n",
Jeej 15:24434827c575 266 rev.fw_version.major, rev.fw_version.minor, rev.fw_version.patch,
Jeej 15:24434827c575 267 cup->fw_major, cup->fw_minor, cup->fw_patch);
Jeej 18:a8a640941018 268 #ifdef DEBUG_BUTTON
Jeej 15:24434827c575 269 PRINT("PRESS USER BUTTON TO START DOWNGRADE...\r\n");
Jeej 15:24434827c575 270 button_user.wait();
Jeej 18:a8a640941018 271 #endif
Jeej 15:24434827c575 272 }
Jeej 15:24434827c575 273 else if (version_old != version_new)
Jeej 15:24434827c575 274 {
Jeej 15:24434827c575 275 PRINT("\r\nUpgrading firmware: v%d.%d.%d --> v%d.%d.%d\r\n",
Jeej 15:24434827c575 276 rev.fw_version.major, rev.fw_version.minor, rev.fw_version.patch,
Jeej 15:24434827c575 277 cup->fw_major, cup->fw_minor, cup->fw_patch);
Jeej 18:a8a640941018 278 #ifdef DEBUG_BUTTON
Jeej 15:24434827c575 279 PRINT("PRESS USER BUTTON TO START UPGRADE...\r\n");
Jeej 15:24434827c575 280 button_user.wait();
Jeej 18:a8a640941018 281 #endif
Jeej 15:24434827c575 282 }
Jeej 20:100143cecc41 283 else
Jeej 20:100143cecc41 284 {
Jeej 20:100143cecc41 285 PRINT("\r\nReseting firmware: v%d.%d.%d --> v%d.%d.%d\r\n",
Jeej 20:100143cecc41 286 rev.fw_version.major, rev.fw_version.minor, rev.fw_version.patch,
Jeej 20:100143cecc41 287 cup->fw_major, cup->fw_minor, cup->fw_patch);
Jeej 20:100143cecc41 288 #ifdef DEBUG_BUTTON
Jeej 20:100143cecc41 289 PRINT("PRESS USER BUTTON TO START UPGRADE...\r\n");
Jeej 20:100143cecc41 290 button_user.wait();
Jeej 20:100143cecc41 291 #endif
Jeej 20:100143cecc41 292 }
Jeej 15:24434827c575 293
Jeej 16:5a6168dbe7bb 294 cup_start_update(cup_slack, bootloader);
Jeej 12:beabd59e0c35 295 }
Jeej 13:c3324b26d473 296
Jeej 13:c3324b26d473 297 } while (0);
Jeej 0:82a60d86ab2e 298
Jeej 0:82a60d86ab2e 299 // Set main task to lowest priority
Jeej 0:82a60d86ab2e 300 osThreadSetPriority(osThreadGetId(), osPriorityIdle);
Jeej 0:82a60d86ab2e 301 while(true)
Jeej 0:82a60d86ab2e 302 {
Jeej 0:82a60d86ab2e 303 // Wait to avoid beeing stuck in loop
Jeej 0:82a60d86ab2e 304 Thread::wait(200);
Jeej 0:82a60d86ab2e 305 }
Jeej 0:82a60d86ab2e 306 }