Program to update the D7A modem's firmware.
Dependencies: modem_ref_helper DebouncedInterrupt
main.cpp
- Committer:
- Jeej
- Date:
- 2019-08-20
- Revision:
- 32:e3ee65b5b835
- Parent:
- 29:aa16a927f0eb
- Child:
- 33:9cd782e2b423
File content as of revision 32:e3ee65b5b835:
#include "DebouncedInterrupt.h" #include "modem_ref_helper.h" #include "modem_callbacks.h" #include "bin.h" #include "cup.h" // To udate your firmware: // - Specify your root key // - Choose your Hardware in bin.h // - Program your NUCLEO with your modem stacked // - Follow the instructions printed on the debug port // This is the default root key // if you have changed this key, please specify it here uint8_t root_key[CUP_DEFAULT_KEY_SIZE] = CUP_DEFAULT_KEY; uint8_t root_key_size = CUP_DEFAULT_KEY_SIZE; // Semaphore for notifiying button presses Semaphore button_user(0); Semaphore modem_ready(0); // Interrupt Service Routine on button press. void button_push_isr( void ) { button_user.release(); } uint8_t check_parameter(const char* str, uint32_t param1, uint32_t param2) { PRINT("Checking %s ", str); if (param1 != param2) { PRINT("Failed. (0x%08X != 0x%08X)\r\n", param1, param2); return 1; } else { PRINT("OK. (0x%08X)\r\n", param1); return 0; } } void print_check_rev(void) { PRINT("\r\n" "/!\\ Please, check that you are at the right commit in the mbed revision tree /!\\\r\n" ); } void print_check_hardware(void) { PRINT("Please, check that you chose the right Hardware in bin.h\r\n"); } int32_t check_slack(uint32_t cup_max_size, uint32_t cup_data_size) { //PRINT("key: %d data: %d code: %d src: %d\r\n", cup_cfg->key, cup->data_size, cup->code_size, cup_cfg->src_offset); PRINT("Checking CUP Slack... "); //int32_t data_size = (((cup->data_size/256)+1)*256); int32_t cup_slack = cup_max_size - cup_data_size; cup_slack = ((cup_slack/256)*256); if (cup_slack < 0) { PRINT("Failed. (%d bytes short)\r\n", -cup_slack); } else { PRINT("OK. (%d bytes)\r\n", cup_slack); } return cup_slack; } modem_callbacks_t callbacks = { .read = my_read, .write = my_write, .read_fprop = my_read_fprop, .flush = my_flush, .remove = my_delete, .udata = my_udata, .lqual = my_lqual, .ldown = my_ldown, .reset = my_reset, .boot = my_boot, .busy = my_busy, }; // Callback for g_main_id User void my_main_callback(uint8_t terminal, int8_t err, uint8_t id) { (void)id; if (terminal) { if (err) { PRINT("Done err %d\n", err); FLUSH(); while(1); } modem_ready.release(); } else if (err) { PRINT("Got err %d\n", err); FLUSH(); while(1); } } uint8_t g_main_id; int main() { bool bootloader; revision_t rev; cup_param_t* cup = (cup_param_t*)&cup_modem; int32_t cup_slack = 0; // Start & initialize #ifdef DEBUG_LED DBG_OPEN(DEBUG_LED); #else DBG_OPEN(NC); #endif PRINT("\r\n" "-----------------------------------------\r\n" "------------- D7A WM Updater ------------\r\n" "-----------------------------------------\r\n"); PRINT("SystemCoreClock is %d Hz\r\n", SystemCoreClock); #ifdef DEBUG_BUTTON DebouncedInterrupt user_interrupt(DEBUG_BUTTON); user_interrupt.attach(button_push_isr, IRQ_FALL, 200, true); #endif modem_helper_open(&callbacks); g_main_id = modem_get_id(my_main_callback); do { // Check modem revision modem_read_file(D7A_FID_FIRMWARE_VERSION, &rev, 0, sizeof(revision_t), g_main_id); modem_ready.acquire(); if (check_parameter("Manufacturer ID... ", rev.manufacturer_id, cup->mfg_id)) { print_check_rev(); break; } if (check_parameter("Hardware version... ", rev.hw_version, cup->hw_id)) { print_check_hardware(); break; } if (rev.device_id == BOOTLOADER_DEV_ID) { // Update bootloader PRINT("\r\n" "/!\\ This modem has a bootloader firmware. /!\\\r\n" "/!\\ Step 2/2: Upgrading to full modem firmware. /!\\\r\n" ); /* cup_slack = check_slack(rev.cup_max_size, cup->data_size); if (cup_slack < 0) { PRINT("/!\\ Not enough space for firmware /!\\\r\n"); break; } */ cup_start_update(0); } else { uint32_t version_old = (rev.fw_version.major << 24) | (rev.fw_version.minor << 16) | rev.fw_version.patch; uint32_t version_new = (cup->fw_major << 24) | (cup->fw_minor << 16) | cup->fw_patch; // Update modem if (check_parameter("Device ID... ", rev.device_id, cup->dev_id)) { print_check_rev(); break; } if (version_old != version_new) { PRINT("Checking Firmware version major... "); if (rev.fw_version.major < cup->target_fw_major) { PRINT("Failed. (0x%08X != 0x%08X)\r\n", rev.fw_version.major, cup->target_fw_major); print_check_rev(); break; } else { PRINT("OK. (0x%08X)\r\n", rev.fw_version.major); } PRINT("Checking Firmware version minor... "); if (rev.fw_version.minor < cup->target_fw_minor && rev.fw_version.major == cup->target_fw_major) { PRINT("Failed. (0x%08X != 0x%08X)\r\n", rev.fw_version.minor, cup->target_fw_minor); print_check_rev(); break; } else { PRINT("OK. (0x%08X)\r\n", rev.fw_version.minor); } } else { PRINT("\r\nYour modem is up to date! (v%d.%d.%d)\r\n", rev.fw_version.major, rev.fw_version.minor, rev.fw_version.patch); } cup_slack = check_slack(rev.cup_max_size, cup->data_size); if (cup_slack < 0) { PRINT("\r\n" "/!\\ Not enough space for full modem firmware binary. /!\\\r\n" "/!\\ Checking for bootloader firmware. /!\\\r\n" "\r\n" ); cup_slack = check_slack(rev.cup_max_size, ((cup_param_t*)&cup_bootloader)->data_size); if (cup_slack < 0) { PRINT("/!\\ Not enough space for bootloader /!\\\r\n"); break; } bootloader = true; PRINT("\r\n" "/!\\ This update will be done in 2 steps. /!\\\r\n" "/!\\ Step 1/2: Upgrading modem to bootloader. /!\\\r\n" "/!\\ Do no push the reset button or turn off the board during upgrade. /!\\\r\n" ); } else { bootloader = false; } if (version_old > version_new) { PRINT("/!\\ Your modem is at a more recent version (v%d.%d.%d)/!\\\r\n" "/!\\ Are you sure you want to downgrade to v%d.%d.%d ? /!\\\r\n", rev.fw_version.major, rev.fw_version.minor, rev.fw_version.patch, cup->fw_major, cup->fw_minor, cup->fw_patch); #ifdef DEBUG_BUTTON PRINT("PRESS USER BUTTON TO CONFIRM...\r\n"); button_user.acquire(); #endif PRINT("\r\nDowngrading firmware: v%d.%d.%d --> v%d.%d.%d\r\n", rev.fw_version.major, rev.fw_version.minor, rev.fw_version.patch, cup->fw_major, cup->fw_minor, cup->fw_patch); #ifdef DEBUG_BUTTON PRINT("PRESS USER BUTTON TO START DOWNGRADE...\r\n"); button_user.acquire(); #endif } else if (version_old != version_new) { PRINT("\r\nUpgrading firmware: v%d.%d.%d --> v%d.%d.%d\r\n", rev.fw_version.major, rev.fw_version.minor, rev.fw_version.patch, cup->fw_major, cup->fw_minor, cup->fw_patch); #ifdef DEBUG_BUTTON PRINT("PRESS USER BUTTON TO START UPGRADE...\r\n"); button_user.acquire(); #endif } else { #ifdef DEBUG_BUTTON PRINT("\r\nReseting firmware: v%d.%d.%d --> v%d.%d.%d\r\n", rev.fw_version.major, rev.fw_version.minor, rev.fw_version.patch, cup->fw_major, cup->fw_minor, cup->fw_patch); PRINT("PRESS USER BUTTON TO START RESET...\r\n"); button_user.acquire(); #else // No button to stop code break; #endif } cup_start_update(cup_slack, bootloader); } } while (0); // Set main task to lowest priority osThreadSetPriority(osThreadGetId(), osPriorityLow); while(true) { // Wait to avoid beeing stuck in loop ThisThread::sleep_for(200); } }