Program to update the D7A modem's firmware.

Dependencies:   modem_ref_helper DebouncedInterrupt

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);
+    }
+}