Dash7Board Code Upgrade Protocol demonstration code.

Dependencies:   modem_ref_helper CRC

cup_app.cpp

Committer:
Jeej
Date:
2021-02-19
Revision:
9:d110f2b86831
Parent:
8:6b7d38139b43

File content as of revision 9:d110f2b86831:

#include "modem_d7a.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, (uint8_t*)&h, offsetof(cup_cfg_bcast_t, header), sizeofof(cup_cfg_bcast_t, header));
    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, (uint8_t*)&h, 0, sizeof(cup_cfg_bcast_header_t));
            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, (uint8_t*)&h, offsetof(cup_cfg_bcast_t, header), sizeofof(cup_cfg_bcast_t, header));

    // 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, &bmp, fof, 1);
                if (!(bmp & bit))
                {
                    h.missed--;
                    bmp |= bit;
                    ram_fs_write(FID_APP_CUP_CFG_BCAST, &bmp, fof, 1);
                }

                // 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, (uint8_t*)&h, 0, sizeof(cup_cfg_bcast_header_t));
            }
        }
    }

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