Program to update the D7A modem's firmware.
Dependencies: modem_ref_helper DebouncedInterrupt
Diff: main.cpp
- Revision:
- 0:82a60d86ab2e
- Child:
- 1:765933092750
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Oct 26 10:03:59 2016 +0000 @@ -0,0 +1,135 @@ +#include "mbed.h" +#include "rtos.h" +#include "d7a.h" +#include "dbg.h" +#include "cup.h" +#include "DebouncedInterrupt.h" + +// File IDs +#define D7A_FID_FIRMWARE_VERSION (2) + + +// callbacks structure +const d7a_callbacks_t callbacks = { + .write_file = NULL, + .read_file = NULL, + .notif_done = NULL, + .unsolicited_msg = NULL, +}; + +// Com configuration for the DASH7 shield +const d7a_com_config_t shield_config = { + .tx = D10, + .rx = D2, + .rts = D13, + .cts = D9, + .rx_buffer_size = 1024, +}; + +// Semaphore for notifiying button presses +Semaphore button_user(0); + +// Interrupt Service Routine on button press. +void button_push_isr( void ) +{ + button_user.release(); +} + +int main() +{ + d7a_revision_t rev; + + // Start & initialize + DBG_OPEN(); + PRINT("\r\n--- D7A WM Updater ---\r\n"); + + DebouncedInterrupt user_interrupt(USER_BUTTON); + user_interrupt.attach(button_push_isr, IRQ_FALL, 200, true); + + d7a_open(&shield_config, A3, &callbacks); + + // Check modem revision + D7A_READ(&rev, D7A_FID_FIRMWARE_VERSION, 0, sizeof(d7a_revision_t), NULL); + + PRINT("-----------------------------------\r\n"); + PRINT("--------- D7A Modem infos ---------\r\n"); + PRINT("Manufacturer ID: 0x%08X\r\n", rev.manufacturer_id); + PRINT("Device ID: 0x%08X\r\n", rev.device_id); + PRINT("Hardware version: 0x%08X\r\n", rev.hw_version); + PRINT("Firmware version: v%d.%d.%d\r\n", rev.fw_version.major, rev.fw_version.minor, rev.fw_version.patch); + PRINT("Firmware hash: 0x%08x\r\n", rev.fw_version.hash); + PRINT("File system CRC: 0x%08x\r\n", rev.fs_crc); + PRINT("-----------------------------------\r\n"); + + // Check package infos + CUP_Archive cup_pkg; + + PRINT("-------- CUP Archive infos --------\r\n"); + PRINT("Firmware version: v%d.%d.%d\r\n", cup_pkg.fw_major, cup_pkg.fw_minor, cup_pkg.fw_patch); + PRINT("Size: %d\r\n", cup_pkg.data_size); + PRINT("Nb archives: %d\r\n", cup_pkg.nb_archives); + PRINT("Signature: 0x%08X\r\n", cup_pkg.signature); + PRINT("-----------------------------------\r\n"); + + // Read CUP config with root permissions + cup_cfg_t cup_cfg; + D7A_READ(&cup_cfg, CUP_CFG_FID, 0, sizeof(cup_cfg_t), root_key); + + PRINT("----- CUP Configuration infos -----\r\n"); + PRINT("Src offset: 0x%08X\r\n", cup_cfg.src_offset); + PRINT("Signature: 0x%08X\r\n", cup_cfg.signature); + PRINT("File max size: %d\r\n", cup_cfg.key); + PRINT("Dbg config: 0x%08X\r\n", cup_cfg.dbg_cfg); + PRINT("-----------------------------------\r\n"); + + uint32_t version_old = (rev.fw_version.major << 24) | (rev.fw_version.minor << 16) | rev.fw_version.patch; + uint32_t version_new = (cup_pkg.fw_major << 24) | (cup_pkg.fw_minor << 16) | cup_pkg.fw_patch; + + if (rev.hw_version != cup_pkg.hw_version) + { + PRINT("Please select the right Hardware in bin.h\r\n"); + } + else if((cup_pkg.data_size % cup_pkg.word_size) != 0) + { + PRINT("Size %d should be multiple of %d.\r\n", cup_pkg.data_size, cup_pkg.word_size); + } + else if (cup_pkg.data_size > cup_cfg.key) + { + PRINT("CUP File too big for upgrade. Available %d needs %d.\r\n", cup_cfg.key, cup_pkg.data_size); + } + else if (version_old == version_new) + { + PRINT("Your modem is already up to date!\r\n"); + } + else + { + if (version_old > version_new) + { + PRINT("/!\\ Your modem is at a more recent version /!\\\r\n/!\\ Are you sure you want to downgrade? /!\\\r\n"); + PRINT("PRESS USER BUTTON TO CONFIRM...\r\n"); + button_user.wait(); + PRINT("Downgrading firmware: v%d.%d.%d --> v%d.%d.%d\r\n", + rev.fw_version.major, rev.fw_version.minor, rev.fw_version.patch, + cup_pkg.fw_major, cup_pkg.fw_minor, cup_pkg.fw_patch); + PRINT("PRESS USER BUTTON TO START DOWNGRADE...\r\n"); + } + else + { + PRINT("Upgrading firmware: v%d.%d.%d --> v%d.%d.%d\r\n", + rev.fw_version.major, rev.fw_version.minor, rev.fw_version.patch, + cup_pkg.fw_major, cup_pkg.fw_minor, cup_pkg.fw_patch); + PRINT("PRESS USER BUTTON TO START UPGRADE...\r\n"); + } + + button_user.wait(); + cup_pkg.start_update(cup_cfg.src_offset); + } + + // Set main task to lowest priority + osThreadSetPriority(osThreadGetId(), osPriorityIdle); + while(true) + { + // Wait to avoid beeing stuck in loop + Thread::wait(200); + } +}