Dash7Board Code Upgrade Protocol demonstration code.

Dependencies:   modem_ref_helper CRC

Committer:
Jeej
Date:
Fri Feb 19 11:00:25 2021 +0000
Revision:
9:d110f2b86831
Parent:
8:6b7d38139b43
v2.0.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jeej 0:5589104abba0 1 // @autor: jeremie@wizzilab.com
Jeej 0:5589104abba0 2 // @date: 2017-12-14
Jeej 0:5589104abba0 3
Jeej 9:d110f2b86831 4 #include "modem_d7a.h"
Jeej 0:5589104abba0 5 #include "modem_callbacks.h"
Jeej 0:5589104abba0 6 #include "files.h"
Jeej 0:5589104abba0 7 #include "crc.h"
Jeej 8:6b7d38139b43 8 #include "cup_app.h"
Jeej 0:5589104abba0 9
Jeej 0:5589104abba0 10 #define CHUNK_SIZE (128)
Jeej 0:5589104abba0 11
Jeej 0:5589104abba0 12 Queue<touch_t, 8> g_file_modified;
Jeej 0:5589104abba0 13
Jeej 0:5589104abba0 14 // CRC calculated on the incoming data stream
Jeej 0:5589104abba0 15 extern uint32_t stream_crc;
mikl_andre 3:cfe26c2bb78b 16 extern int32_t last_end;
Jeej 0:5589104abba0 17
Jeej 9:d110f2b86831 18 modem_ref_callbacks_t callbacks = {
Jeej 0:5589104abba0 19 .read = my_read,
Jeej 0:5589104abba0 20 .write = my_write,
Jeej 0:5589104abba0 21 .read_fprop = my_read_fprop,
Jeej 0:5589104abba0 22 .flush = my_flush,
Jeej 0:5589104abba0 23 .remove = my_delete,
Jeej 0:5589104abba0 24 .udata = my_udata,
Jeej 0:5589104abba0 25 .lqual = my_lqual,
Jeej 0:5589104abba0 26 .ldown = my_ldown,
Jeej 0:5589104abba0 27 .reset = my_reset,
Jeej 1:dd4e18b267a1 28 .boot = my_boot,
Jeej 1:dd4e18b267a1 29 .busy = my_busy
Jeej 0:5589104abba0 30 };
Jeej 0:5589104abba0 31
Jeej 0:5589104abba0 32 void thread_file_modified()
Jeej 0:5589104abba0 33 {
Jeej 0:5589104abba0 34 touch_t* touch;
Jeej 0:5589104abba0 35 osEvent evt;
Jeej 0:5589104abba0 36 Timer tim;
Jeej 0:5589104abba0 37 uint32_t total = 0;
Jeej 0:5589104abba0 38 uint32_t next_chunk = 0;
mikl_andre 3:cfe26c2bb78b 39 uint32_t chunks=0;
Jeej 0:5589104abba0 40
Jeej 0:5589104abba0 41 PRINT("Ready\n");
Jeej 0:5589104abba0 42
Jeej 0:5589104abba0 43 while (true)
Jeej 0:5589104abba0 44 {
Jeej 0:5589104abba0 45 evt = g_file_modified.get();
Jeej 0:5589104abba0 46 touch = (evt.status == osEventMessage)? (touch_t*)evt.value.p : NULL;
Jeej 0:5589104abba0 47 ASSERT(touch != NULL, "NULL touch pointer!\n");
Jeej 0:5589104abba0 48
Jeej 0:5589104abba0 49 switch (touch->fid)
Jeej 0:5589104abba0 50 {
Jeej 7:bfe920ee44f2 51 case FID_APP_CUP_CFG_BCAST:
Jeej 8:6b7d38139b43 52 {
Jeej 7:bfe920ee44f2 53 cup_cfg_bcast_header_t cup_cfg;
Jeej 0:5589104abba0 54
Jeej 9:d110f2b86831 55 ram_fs_read(FID_APP_CUP_CFG_BCAST, (uint8_t*)&cup_cfg, 0, sizeof(cup_cfg_bcast_header_t));
Jeej 0:5589104abba0 56
Jeej 0:5589104abba0 57 if (CUP_CMD_UPGRADE_FILE_START == cup_cfg.cmd)
Jeej 0:5589104abba0 58 {
Jeej 8:6b7d38139b43 59 if (cup_cfg_bcast_init())
Jeej 0:5589104abba0 60 {
Jeej 8:6b7d38139b43 61 PRINT("Enter upload mode. Watchdog %ds\n", cup_cfg.to);
Jeej 8:6b7d38139b43 62
Jeej 8:6b7d38139b43 63 tim.stop();
Jeej 8:6b7d38139b43 64 tim.reset();
Jeej 8:6b7d38139b43 65 total = 0;
Jeej 8:6b7d38139b43 66 next_chunk = 0;
Jeej 8:6b7d38139b43 67 stream_crc = 0;
Jeej 8:6b7d38139b43 68 chunks = 0;
Jeej 8:6b7d38139b43 69
Jeej 8:6b7d38139b43 70 // Write to the modem CUP config file (as root)
Jeej 8:6b7d38139b43 71 // to enter upload mode
Jeej 8:6b7d38139b43 72 cup_cfg_t cup_start = {
Jeej 8:6b7d38139b43 73 .cmd = CUP_CMD_UPGRADE_UPLOAD,
Jeej 8:6b7d38139b43 74 .arch_nb = cup_cfg.to,
Jeej 8:6b7d38139b43 75 };
Jeej 9:d110f2b86831 76 modem_write_file(FID_CUP_CFG, (uint8_t*)&cup_start, 0, 4);
Jeej 0:5589104abba0 77 }
Jeej 0:5589104abba0 78 else
Jeej 0:5589104abba0 79 {
Jeej 8:6b7d38139b43 80 PRINT("Failed bcast init\n");
Jeej 0:5589104abba0 81 }
Jeej 8:6b7d38139b43 82 }
Jeej 8:6b7d38139b43 83 else
Jeej 8:6b7d38139b43 84 {
Jeej 8:6b7d38139b43 85 PRINT("CUP command 0x%04X\n", cup_cfg.cmd);
Jeej 8:6b7d38139b43 86 }
Jeej 8:6b7d38139b43 87
Jeej 8:6b7d38139b43 88 break;
Jeej 8:6b7d38139b43 89 }
Jeej 8:6b7d38139b43 90 case FID_APP_CUP_CFG:
Jeej 8:6b7d38139b43 91 {
Jeej 8:6b7d38139b43 92 cup_cfg_t cup_cfg = { 0 };
Jeej 8:6b7d38139b43 93 uint8_t* data = (uint8_t*)((uint8_t*)&cup_cfg + touch->offset);
Jeej 8:6b7d38139b43 94
Jeej 9:d110f2b86831 95 ram_fs_read(touch->fid, data, touch->offset, touch->length);
Jeej 8:6b7d38139b43 96
Jeej 8:6b7d38139b43 97 if (CUP_CMD_UPGRADE_FILE_END == cup_cfg.cmd)
Jeej 8:6b7d38139b43 98 {
Jeej 8:6b7d38139b43 99 PRINT("Done.\n");
Jeej 8:6b7d38139b43 100
Jeej 0:5589104abba0 101 // Actual check is done here since we could have received some of the missed data in a previous session.
Jeej 0:5589104abba0 102
Jeej 0:5589104abba0 103 /******************************/
Jeej 0:5589104abba0 104 /* Compute CRC on saved data. */
Jeej 0:5589104abba0 105 /******************************/
Jeej 0:5589104abba0 106
Jeej 0:5589104abba0 107 // If you have the full binary data,
Jeej 0:5589104abba0 108 // You can use this function to compute CRC
Jeej 0:5589104abba0 109 //binary_crc = crc32((char*)binary_data, expected_size);
Jeej 0:5589104abba0 110
Jeej 0:5589104abba0 111 // Else just do a loop and a fast CRC on data chunks like in my_write
Jeej 0:5589104abba0 112 }
Jeej 0:5589104abba0 113 else
Jeej 0:5589104abba0 114 {
Jeej 0:5589104abba0 115 PRINT("CUP command 0x%04X\n", cup_cfg.cmd);
Jeej 0:5589104abba0 116 }
Jeej 8:6b7d38139b43 117
Jeej 0:5589104abba0 118 break;
Jeej 8:6b7d38139b43 119 }
Jeej 0:5589104abba0 120 case FID_APP_CUP_CODE:
Jeej 8:6b7d38139b43 121 {
Jeej 8:6b7d38139b43 122 cup_cfg_bcast_update(touch->offset, touch->length);
Jeej 8:6b7d38139b43 123
Jeej 0:5589104abba0 124 // Chunk data should be saved in my_write callback
Jeej 0:5589104abba0 125
Jeej 0:5589104abba0 126 // Notify modem code file to reset upload watchdog
Jeej 0:5589104abba0 127 // else the device will exit upload mode after the watchdog timeout
Jeej 9:d110f2b86831 128 modem_notify_file(FID_CUP_CODE, 0, 1);
Jeej 0:5589104abba0 129
Jeej 0:5589104abba0 130 break;
Jeej 8:6b7d38139b43 131 }
Jeej 0:5589104abba0 132 default:
Jeej 0:5589104abba0 133 PRINT("TOUCH FID %d OFF %d LEN %d\n", touch->fid, touch->offset, touch->length);
Jeej 0:5589104abba0 134 break;
Jeej 0:5589104abba0 135 }
Jeej 0:5589104abba0 136
Jeej 0:5589104abba0 137 FREE(touch);
Jeej 0:5589104abba0 138 }
Jeej 0:5589104abba0 139 }
Jeej 0:5589104abba0 140
Jeej 0:5589104abba0 141 /*** Main function ------------------------------------------------------------- ***/
Jeej 0:5589104abba0 142 int main() {
Jeej 0:5589104abba0 143 // Start & initialize
Jeej 0:5589104abba0 144 #ifdef DEBUG_LED
Jeej 0:5589104abba0 145 DBG_OPEN(DEBUG_LED);
Jeej 0:5589104abba0 146 #else
Jeej 0:5589104abba0 147 DBG_OPEN(NC);
Jeej 0:5589104abba0 148 #endif
Jeej 0:5589104abba0 149 PRINT("\n"
Jeej 0:5589104abba0 150 "-----------------------------------------\n"
Jeej 0:5589104abba0 151 "---------------- Demo CUP ---------------\n"
Jeej 0:5589104abba0 152 "-----------------------------------------\n");
Jeej 0:5589104abba0 153
Jeej 9:d110f2b86831 154 modem_open(&callbacks);
Jeej 0:5589104abba0 155
Jeej 0:5589104abba0 156 PRINT("--------------- APP infos ---------------\r\n");
Jeej 0:5589104abba0 157 PRINT(" - Manufacturer ID: %08X\r\n", f_rev.manufacturer_id);
Jeej 0:5589104abba0 158 PRINT(" - Device ID: %08X\r\n", f_rev.device_id);
Jeej 0:5589104abba0 159 PRINT(" - Hardware version: %08X\r\n", f_rev.hw_version);
Jeej 0:5589104abba0 160 PRINT(" - Firmware version: v%d.%d.%d [%02X]\r\n", f_rev.fw_version.major, f_rev.fw_version.minor, f_rev.fw_version.patch, f_rev.fw_version.id);
Jeej 0:5589104abba0 161 PRINT(" - CUP max size: %d\r\n", f_rev.cup_max_size);
Jeej 0:5589104abba0 162 PRINT("-----------------------------------------\r\n");
Jeej 0:5589104abba0 163
Jeej 0:5589104abba0 164 PRINT("Register Files\n");
Jeej 9:d110f2b86831 165 ram_fs_new(FID_APP_CUP_CFG, (uint8_t*)&h_cup_cfg, (uint8_t*)&f_cup_cfg);
Jeej 9:d110f2b86831 166 ram_fs_new(FID_APP_CUP_CFG_BCAST, (uint8_t*)&h_cup_cfg_bcast, (uint8_t*)&f_cup_cfg_bcast);
Jeej 9:d110f2b86831 167 modem_declare_file(FID_APP_CUP_CFG, (alp_file_header_t*)&h_cup_cfg);
Jeej 9:d110f2b86831 168 modem_declare_file(FID_APP_CUP_CFG_BCAST, (alp_file_header_t*)&h_cup_cfg_bcast);
Jeej 0:5589104abba0 169
Jeej 0:5589104abba0 170 // Declare the cup code file
Jeej 0:5589104abba0 171 // It needs a special handling of its data in my_write callback since we want to keep them.
Jeej 0:5589104abba0 172 // (can't be done with the current RAM file system)
Jeej 9:d110f2b86831 173 modem_declare_file(FID_APP_CUP_CODE, (alp_file_header_t*)&h_cup_code);
Jeej 0:5589104abba0 174
Jeej 9:d110f2b86831 175 PRINT("Enable D7A interface\n");
Jeej 9:d110f2b86831 176 modem_d7a_enable_itf();
Jeej 9:d110f2b86831 177
Jeej 9:d110f2b86831 178 // Host revision file is in the modem. Update it.
Jeej 9:d110f2b86831 179 PRINT("Update host revision\n");
Jeej 9:d110f2b86831 180 modem_write_file(FID_HOST_REV, &f_rev, 0, sizeof(revision_t));
Jeej 0:5589104abba0 181
Jeej 9:d110f2b86831 182 // Retrieve modem revision
Jeej 9:d110f2b86831 183 PRINT("Send revision\n");
Jeej 9:d110f2b86831 184 revision_t rev;
Jeej 9:d110f2b86831 185 modem_read_file(FID_WM_REV, &rev, 0, sizeof(revision_t));
Jeej 0:5589104abba0 186
Jeej 9:d110f2b86831 187 // Send both to the server
Jeej 9:d110f2b86831 188 // Build payload
Jeej 9:d110f2b86831 189 alp_payload_t* alp = NULL;
Jeej 9:d110f2b86831 190 alp = alp_payload_rsp_f_data(alp, FID_WM_REV, &rev, 0, sizeof(revision_t));
Jeej 9:d110f2b86831 191 alp = alp_payload_rsp_f_data(alp, FID_HOST_REV, &f_rev, 0, sizeof(revision_t));
Jeej 0:5589104abba0 192
Jeej 9:d110f2b86831 193 // Send
Jeej 9:d110f2b86831 194 alp_itf_d7a_cfg_t report_itf;
Jeej 9:d110f2b86831 195 modem_read_file(IFID_REPORT, &report_itf, 0, sizeof(alp_itf_d7a_cfg_t));
Jeej 9:d110f2b86831 196 modem_remote_raw_alp((void*)&report_itf, alp, NULL, 10000);
Jeej 0:5589104abba0 197
Jeej 0:5589104abba0 198 // Start file modified thread
Jeej 0:5589104abba0 199 Thread th_file_modified(osPriorityNormal, 1024, NULL);
Jeej 0:5589104abba0 200 osStatus status = th_file_modified.start(thread_file_modified);
Jeej 0:5589104abba0 201 ASSERT(status == osOK, "Failed to start thread_file_modified (err: %d)\r\n", status);
Jeej 0:5589104abba0 202
Jeej 0:5589104abba0 203 #ifdef DEBUG_LED
Jeej 0:5589104abba0 204 DigitalOut my_led(DEBUG_LED);
Jeej 0:5589104abba0 205 #endif
Jeej 0:5589104abba0 206
Jeej 0:5589104abba0 207 // Set main task to lowest priority
Jeej 7:bfe920ee44f2 208 osThreadSetPriority(osThreadGetId(), osPriorityLow);
Jeej 0:5589104abba0 209 while(true)
Jeej 0:5589104abba0 210 {
Jeej 7:bfe920ee44f2 211 ThisThread::sleep_for(500);
Jeej 0:5589104abba0 212 #ifdef DEBUG_LED
Jeej 0:5589104abba0 213 my_led = !my_led;
Jeej 0:5589104abba0 214 #endif
Jeej 0:5589104abba0 215 }
Jeej 0:5589104abba0 216 }