Dash7Board Code Upgrade Protocol demonstration code.
Dependencies: modem_ref_helper CRC
Diff: cup_app.cpp
- 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