Helper library to use modem_ref driver.
Dependencies: WizziCom WizziDebug ram_fs modem_ref
Dependents: D7A_Localisation D7A_1x_demo_send_file_data_and_forget D7A_1x_demo_CodeUpgradeProtocol D7A_1x_demo_LoRaWAN ... more
modem_cup.cpp
00001 #include "DebouncedInterrupt.h" 00002 #include "modem_cup.h" 00003 00004 // Semaphore for notifiying button presses 00005 static Semaphore button_user(0); 00006 static Semaphore boot(0); 00007 00008 uint8_t const modem_data[CUP_DATA_SIZE] = CUP_DATA; 00009 uint8_t const libex_data[LIBEX_DATA_SIZE] = LIBEX_DATA; 00010 uint8_t const bootloader_data[BOOTLOADER_DATA_SIZE] = BOOTLOADER_DATA; 00011 00012 // Interrupt Service Routine on button press. 00013 static void button_push_isr( void ) 00014 { 00015 button_user.release(); 00016 } 00017 00018 static void cup_boot(u8 cause, u16 number) 00019 { 00020 PRINT("Modem BOOT[%c] #%d\r\n", cause, number); 00021 boot.release(); 00022 } 00023 00024 cup_param_t const cup_modem = { 00025 .data = (uint8_t*)modem_data, 00026 .cfg_fid = CUP_CFG_FID, 00027 .code_fid = CUP_CODE_FID, 00028 .code_size = CUP_CODE_SIZE, 00029 .data_size = CUP_DATA_SIZE, 00030 .local_mtu = CUP_LOCAL_MTU, 00031 .nb_archives = CUP_NB_ARCHIVES, 00032 .signature = CUP_SIGNATURE, 00033 .mfg_id = CUP_MFG_ID, 00034 .dev_id = CUP_DEV_ID, 00035 .hw_id = CUP_HW_ID, 00036 .fw_major = CUP_FW_MAJOR, 00037 .fw_minor = CUP_FW_MINOR, 00038 .fw_patch = CUP_FW_PATCH, 00039 .fw_hash = CUP_FW_HASH, 00040 .target_fw_major = CUP_TARGET_FW_MAJOR, 00041 .target_fw_minor = CUP_TARGET_FW_MINOR, 00042 .target_fw_patch = 0, 00043 .target_fw_hash = 0, 00044 }; 00045 00046 cup_param_t const cup_libex = { 00047 .data = (uint8_t*)libex_data, 00048 .cfg_fid = CUP_CFG_FID, 00049 .code_fid = CUP_CODE_FID, 00050 .code_size = CUP_CODE_SIZE, 00051 .data_size = LIBEX_DATA_SIZE, 00052 .local_mtu = CUP_LOCAL_MTU, 00053 .nb_archives = 1, 00054 .signature = LIBEX_SIGNATURE, 00055 .mfg_id = CUP_MFG_ID, 00056 .dev_id = CUP_DEV_ID, 00057 .hw_id = CUP_HW_ID, 00058 .fw_major = CUP_FW_MAJOR, 00059 .fw_minor = CUP_FW_MINOR, 00060 .fw_patch = CUP_FW_PATCH, 00061 .fw_hash = CUP_FW_HASH, 00062 .target_fw_major = CUP_FW_MAJOR, 00063 .target_fw_minor = CUP_FW_MINOR, 00064 .target_fw_patch = CUP_FW_PATCH, 00065 .target_fw_hash = CUP_FW_HASH, 00066 }; 00067 00068 cup_param_t const cup_bootloader = { 00069 .data = (uint8_t*)bootloader_data, 00070 .cfg_fid = BOOTLOADER_CFG_FID, 00071 .code_fid = BOOTLOADER_CODE_FID, 00072 .code_size = BOOTLOADER_CODE_SIZE, 00073 .data_size = BOOTLOADER_DATA_SIZE, 00074 .local_mtu = BOOTLOADER_LOCAL_MTU, 00075 .nb_archives = BOOTLOADER_NB_ARCHIVES, 00076 .signature = BOOTLOADER_SIGNATURE, 00077 .mfg_id = BOOTLOADER_MFG_ID, 00078 .dev_id = BOOTLOADER_DEV_ID, 00079 .hw_id = BOOTLOADER_HW_ID, 00080 .fw_major = BOOTLOADER_FW_MAJOR, 00081 .fw_minor = BOOTLOADER_FW_MINOR, 00082 .fw_patch = BOOTLOADER_FW_PATCH, 00083 .fw_hash = BOOTLOADER_FW_HASH, 00084 .target_fw_major = BOOTLOADER_TARGET_FW_MAJOR, 00085 .target_fw_minor = BOOTLOADER_TARGET_FW_MINOR, 00086 }; 00087 00088 static void modem_cup_start_update(uint32_t offset, cup_param_t* cup) 00089 { 00090 cup_cfg_t cfg = { 00091 .cmd = 0x10AD, 00092 .arch_nb = 20, 00093 }; 00094 00095 uint32_t fof = 0; 00096 uint8_t percent = 0; 00097 uint8_t percent_old = 255; 00098 Timer tim; 00099 int32_t rem; 00100 float now = 0; 00101 00102 float speed_before = 0; 00103 float speed = 0; 00104 int speed_data = 0; 00105 00106 float time_before = 0; 00107 float time_left = 0; 00108 00109 float print_before = 0; 00110 00111 rem = cup->data_size; 00112 00113 // Start CUP 00114 modem_write_file(cup->cfg_fid, (uint8_t*)&cfg, 0, 4); 00115 00116 // Upload file 00117 PRINT("Uploading %d bytes to CUP file. (offset %d)\r\n", cup->data_size, offset); 00118 00119 tim.start(); 00120 00121 while (rem > 0) 00122 { 00123 int32_t chunk = (rem > cup->local_mtu)? cup->local_mtu : rem; 00124 modem_write_file(cup->code_fid, &(cup->data[fof]), fof + offset, chunk); 00125 rem -= chunk; 00126 fof += chunk; 00127 00128 now = tim.read(); 00129 speed_data += chunk; 00130 00131 // Update speed 00132 if (now - speed_before > 1.0 || speed_before == 0) 00133 { 00134 speed = (speed_data/(now - speed_before))/1024.0; 00135 speed_before = now; 00136 speed_data = 0; 00137 } 00138 00139 // Update time left 00140 if (now - time_before > 0.2 || time_before == 0 || rem == 0) 00141 { 00142 time_before = now; 00143 time_left = (rem / speed) / 1024.0; 00144 } 00145 00146 // Print 00147 if (now - print_before > 0.1 || print_before == 0 || rem == 0) 00148 { 00149 percent = (100*fof)/cup->data_size; 00150 print_before = now; 00151 PRINT("\rUPLOADING NEW FIRMWARE %d/%d (%3d%%) %.2f kB/s %.0fs ", fof, cup->data_size, percent, speed, time_left); 00152 } 00153 } 00154 00155 PRINT("\n"); 00156 00157 float time_s = tim.read(); 00158 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); 00159 00160 // Force PFLASH-cache flushing 00161 modem_flush_file(cup->code_fid); 00162 00163 // Send Upgrade command 00164 cfg.cmd = 0xC0D5; 00165 cfg.arch_nb = cup->nb_archives; 00166 cfg.src_offset = offset; 00167 cfg.signature = cup->signature; 00168 00169 modem_write_file(cup->cfg_fid, (uint8_t*)&cfg, 0, 12); 00170 00171 PRINT("Waiting self reboot...\r\n"); 00172 00173 boot.acquire(); 00174 } 00175 00176 static uint8_t check_parameter(const char* str, uint32_t param1, uint32_t param2) 00177 { 00178 PRINT("Checking %s ", str); 00179 if (param1 != param2) 00180 { 00181 PRINT("Failed. (0x%08X != 0x%08X)\r\n", param1, param2); 00182 return 1; 00183 } 00184 else 00185 { 00186 PRINT("OK. (0x%08X)\r\n", param1); 00187 return 0; 00188 } 00189 } 00190 00191 static void print_check_rev(void) 00192 { 00193 PRINT("\r\n" 00194 "/!\\ Please, check that you are at the right commit in the mbed revision tree /!\\\r\n" 00195 ); 00196 } 00197 00198 static void print_check_hardware(void) 00199 { 00200 PRINT("Please, check that you chose the right Hardware in bin.h\r\n"); 00201 } 00202 00203 static int32_t check_slack(uint32_t cup_max_size, uint32_t cup_data_size) 00204 { 00205 //PRINT("key: %d data: %d code: %d src: %d\r\n", cup_cfg->key, cup->data_size, cup->code_size, cup_cfg->src_offset); 00206 PRINT("Checking CUP Slack... "); 00207 00208 //int32_t data_size = (((cup->data_size/256)+1)*256); 00209 int32_t cup_slack = cup_max_size - cup_data_size; 00210 00211 cup_slack = ((cup_slack/256)*256); 00212 00213 if (cup_slack < 0) 00214 { 00215 PRINT("Failed. (%d bytes short)\r\n", -cup_slack); 00216 } 00217 else 00218 { 00219 PRINT("OK. (%d bytes)\r\n", cup_slack); 00220 } 00221 00222 return cup_slack; 00223 } 00224 00225 static int modem_cup_check(revision_t* rev, cup_param_t* cup) 00226 { 00227 int cup_slack = -1; 00228 00229 do 00230 { 00231 // Check modem revision 00232 if (check_parameter("Manufacturer ID... ", rev->manufacturer_id, cup->mfg_id)) 00233 { 00234 print_check_rev(); 00235 break; 00236 } 00237 00238 if (check_parameter("Hardware version... ", rev->hw_version, cup->hw_id)) 00239 { 00240 print_check_hardware(); 00241 break; 00242 } 00243 00244 if (rev->device_id != cup->dev_id) 00245 { 00246 // Update bootloader 00247 PRINT("\r\n" 00248 "/!\\ Not a modem firmware. /!\\\r\n" 00249 ); 00250 break; 00251 } 00252 else 00253 { 00254 // Update modem 00255 if (check_parameter("Device ID... ", rev->device_id, cup->dev_id)) 00256 { 00257 print_check_rev(); 00258 break; 00259 } 00260 00261 if (&cup_libex != cup) 00262 { 00263 PRINT("Checking Firmware version major... "); 00264 if (rev->fw_version.major < cup->target_fw_major) 00265 { 00266 PRINT("Failed. (0x%08X != 0x%08X)\r\n", rev->fw_version.major, cup->target_fw_major); 00267 print_check_rev(); 00268 break; 00269 } 00270 else 00271 { 00272 PRINT("OK. (0x%08X)\r\n", rev->fw_version.major); 00273 } 00274 00275 PRINT("Checking Firmware version minor... "); 00276 if (rev->fw_version.minor < cup->target_fw_minor && rev->fw_version.major == cup->target_fw_major) 00277 { 00278 PRINT("Failed. (0x%08X != 0x%08X)\r\n", rev->fw_version.minor, cup->target_fw_minor); 00279 print_check_rev(); 00280 break; 00281 } 00282 else 00283 { 00284 PRINT("OK. (0x%08X)\r\n", rev->fw_version.minor); 00285 } 00286 } 00287 else 00288 { 00289 if (check_parameter("Firmware version major...", rev->fw_version.major, cup->target_fw_major)) 00290 { 00291 print_check_rev(); 00292 break; 00293 } 00294 00295 if (check_parameter("Firmware version minor...", rev->fw_version.minor, cup->target_fw_minor)) 00296 { 00297 print_check_rev(); 00298 break; 00299 } 00300 00301 if (check_parameter("Firmware version patch...", rev->fw_version.patch, cup->target_fw_patch)) 00302 { 00303 print_check_rev(); 00304 break; 00305 } 00306 00307 if (check_parameter("Firmware version hash... ", rev->fw_version.hash, cup->target_fw_hash)) 00308 { 00309 print_check_rev(); 00310 break; 00311 } 00312 } 00313 00314 cup_slack = check_slack(rev->cup_max_size, cup->data_size); 00315 00316 if (cup_slack < 0) 00317 { 00318 PRINT("\r\n" 00319 "/!\\ Not enough space for modem firmware binary. /!\\\r\n" 00320 "\r\n" 00321 ); 00322 break; 00323 } 00324 } 00325 00326 return cup_slack; 00327 00328 } while (0); 00329 00330 FLUSH(); 00331 while(true) 00332 { 00333 ThisThread::sleep_for(500); 00334 } 00335 } 00336 00337 void modem_cup_update(revision_t* rev) 00338 { 00339 bool bootloader; 00340 cup_param_t* cup = (cup_param_t*)&cup_modem; 00341 int32_t cup_slack = 0; 00342 uint32_t version_old = (rev->fw_version.major << 24) | (rev->fw_version.minor << 16) | rev->fw_version.patch; 00343 uint32_t version_new = (cup->fw_major << 24) | (cup->fw_minor << 16) | cup->fw_patch; 00344 00345 if (version_old < version_new) 00346 { 00347 #ifdef DEBUG_BUTTON 00348 DebouncedInterrupt user_interrupt(DEBUG_BUTTON); 00349 user_interrupt.attach(button_push_isr, IRQ_FALL, 200, true); 00350 #endif 00351 modem_ref_set_boot_cb(cup_boot); 00352 00353 cup_slack = modem_cup_check(rev, cup); 00354 00355 PRINT("\r\nYour modem version is behind the recommended version for this driver."); 00356 PRINT("\r\nUpgrading modem firmware: v%d.%d.%d --> v%d.%d.%d\r\n", 00357 rev->fw_version.major, rev->fw_version.minor, rev->fw_version.patch, 00358 cup->fw_major, cup->fw_minor, cup->fw_patch); 00359 #ifdef DEBUG_BUTTON 00360 PRINT("PRESS USER BUTTON TO START UPGRADE...\r\n"); 00361 button_user.acquire(); 00362 #endif 00363 modem_cup_start_update(cup_slack, cup); 00364 00365 if (LIBEX_NB_ARCHIVES) 00366 { 00367 ThisThread::sleep_for(500); 00368 PRINT("Updating Libex...\r\n"); 00369 00370 modem_read_file(D7A_FID_FIRMWARE_VERSION, (uint8_t*)rev, 0, sizeof(revision_t)); 00371 00372 cup = (cup_param_t*)&cup_libex; 00373 cup_slack = modem_cup_check(rev, cup); 00374 00375 modem_cup_start_update(cup_slack, cup); 00376 } 00377 00378 PRINT("Restarting application...\r\n"); 00379 FLUSH(); 00380 NVIC_SystemReset(); 00381 } 00382 }
Generated on Sun Jul 17 2022 05:41:35 by 1.7.2