Dash7Board Code Upgrade Protocol demonstration code.

Dependencies:   modem_ref_helper CRC

Revision:
8:6b7d38139b43
Child:
9:d110f2b86831
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cup_app.cpp	Thu May 28 09:11:58 2020 +0000
@@ -0,0 +1,111 @@
+#include "modem_ref_helper.h"
+#include "cup_app.h"
+#include "cup.h"
+#include "ram_fs.h"
+#include "files.h"
+
+//======================================================================
+// cup_cfg_bcast_init
+//----------------------------------------------------------------------
+/// @brief  Init CUP status file.
+///         Called when a new CUP upload is started
+/// @param              void
+/// @retval             u8                  TRUE when the CFG (UCAST) file is touched
+//======================================================================
+uint8_t cup_cfg_bcast_init(void)
+{
+    cup_cfg_bcast_header_t h;
+    ram_fs_read(FID_APP_CUP_CFG_BCAST, offsetof(cup_cfg_bcast_t, header), sizeofof(cup_cfg_bcast_t, header), (uint8_t*)&h);
+    PRINT("CUP BCAST START 0x%08x CHUNK %d LEN %d CMD 0x%04X TO %d SIG 0x%08x\r\n",
+            h.start, h.chunk, h.len, h.cmd, h.to, h.sig_new);
+
+    // Update the status only when a valid command is present
+    if (((h.cmd == CUP_CMD_UPGRADE_UPLOAD) || (h.cmd == CUP_CMD_UPGRADE_UPLOAD_ALT) || (h.cmd == CUP_CMD_UPGRADE_FILE_START))
+            && (h.len) && (h.chunk) && (h.sig_new) && (h.to))
+    {
+        if ((h.sig_curr != h.sig_new) || (!h.missed))
+        {
+            // the signature changed, start over
+            memset(&f_cup_cfg_bcast.bitmap, 0, sizeofof(cup_cfg_bcast_t, bitmap));
+
+            // Init the transfer status
+            h.sig_curr = h.sig_new;
+            h.missed = KAL_DIV_CEILING(h.len, h.chunk);
+            h.crc_ok = 0;
+            ram_fs_write(FID_APP_CUP_CFG_BCAST, 0, sizeof(cup_cfg_bcast_header_t), (uint8_t*)&h);
+            PRINT("CUP BCAST RESET, MISSED %d\r\n", h.missed);
+        }
+        else
+        {
+            PRINT("CUP BCAST CONTINUE, MISSED %d\r\n", h.missed);
+        }
+
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+//======================================================================
+// cup_cfg_bcast_update
+//----------------------------------------------------------------------
+/// @brief  Update CUP status file.
+///         Called when data is written in the CUP data file
+/// @param  offset      uint32_t             offset of the new chunk
+/// @param  plen        uint32_t             length of the new chunk
+/// @retval             void
+//======================================================================
+uint8_t cup_cfg_bcast_update(uint32_t offset, uint32_t plen)
+{
+    // update header
+    cup_cfg_bcast_header_t h;
+    ram_fs_read(FID_APP_CUP_CFG_BCAST, offsetof(cup_cfg_bcast_t, header), sizeofof(cup_cfg_bcast_t, header), (uint8_t*)&h);
+
+    // Update the status only when a valid command is present
+    if (((h.cmd == CUP_CMD_UPGRADE_UPLOAD) || (h.cmd == CUP_CMD_UPGRADE_UPLOAD_ALT) || (h.cmd == CUP_CMD_UPGRADE_FILE_START))
+            && (h.chunk) && (h.missed))
+    {
+        // check that the plen is compatible
+        if ((plen == h.chunk) || (plen == (h.len % h.chunk)))
+        {
+            uint16_t idx = (offset - h.start) / h.chunk;
+            uint32_t fof = idx/8 + sizeof(cup_cfg_bcast_header_t);
+
+            // update bitmap
+            if (fof < sizeof(cup_cfg_bcast_t))
+            {
+                // read-modify-write one bit
+                u8 bmp, bit = (1 << (idx & 7));
+                ram_fs_read(FID_APP_CUP_CFG_BCAST, fof, 1, &bmp);
+                if (!(bmp & bit))
+                {
+                    h.missed--;
+                    bmp |= bit;
+                    ram_fs_write(FID_APP_CUP_CFG_BCAST, fof, 1, &bmp);
+                }
+
+                // CRC check when done or on the last chunk
+                if ((!h.missed) || (idx == (h.len/h.chunk)))
+                {
+                    extern uint32_t stream_crc;
+
+                    // Archive / Command check (~ 30 ms on 80k archive)
+                    h.crc_ok = (stream_crc == h.sig_curr) ? TRUE : FALSE;
+                    PRINT("CUP BCAST CRC=%08x / Expect %08x\r\n", stream_crc, h.sig_curr);
+                }
+
+                ram_fs_write(FID_APP_CUP_CFG_BCAST, 0, sizeof(cup_cfg_bcast_header_t), (uint8_t*)&h);
+            }
+        }
+    }
+
+    PRINT("CUP OFF %d CHUNK %d/%d LEN %d MISSING %d\r\n",
+        offset,
+        ((offset - h.start) / h.chunk) + 1,
+        (h.len / h.chunk) + 1,
+        plen,
+        h.missed
+        );
+    
+    return h.crc_ok;
+}
\ No newline at end of file