Dash7Board Code Upgrade Protocol demonstration code.

Dependencies:   modem_ref_helper CRC

Committer:
Jeej
Date:
Tue Aug 20 13:55:45 2019 +0000
Revision:
7:bfe920ee44f2
Parent:
3:cfe26c2bb78b
Child:
8:6b7d38139b43
WizziCom now uses DMA instead of interrupts.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jeej 0:5589104abba0 1 #include "modem_ref_helper.h"
Jeej 0:5589104abba0 2 #include "files.h"
Jeej 0:5589104abba0 3 #include "fast_crc32.h"
Jeej 0:5589104abba0 4
Jeej 0:5589104abba0 5 #define SERIAL_MAX_PACKET_SIZE (255)
Jeej 0:5589104abba0 6
Jeej 0:5589104abba0 7 uint32_t stream_crc = 0;
mikl_andre 3:cfe26c2bb78b 8 uint16_t last_end=0;
Jeej 0:5589104abba0 9
Jeej 0:5589104abba0 10 // ============================================================}}}
Jeej 0:5589104abba0 11
Jeej 0:5589104abba0 12 // Callbacks to MODEM's ALP requests
Jeej 0:5589104abba0 13 // ============================================================{{{
Jeej 0:5589104abba0 14 void my_read(u8 fid, u32 offset, u32 length, int id)
Jeej 0:5589104abba0 15 {
Jeej 0:5589104abba0 16 u8 data[SERIAL_MAX_PACKET_SIZE];
Jeej 0:5589104abba0 17
Jeej 0:5589104abba0 18 ASSERT((ALP_ACTION_RSP_TAG_SIZE + ALP_ACTION_RSP_F_DATA_SIZE(offset, length)) <= SERIAL_MAX_PACKET_SIZE,
Jeej 0:5589104abba0 19 "Read response too big for serial protocol (%d/%dmax)\r\n", length, ALP_ACTION_RSP_TAG_SIZE + ALP_ACTION_RSP_F_DATA_SIZE(offset,SERIAL_MAX_PACKET_SIZE));
Jeej 0:5589104abba0 20
Jeej 0:5589104abba0 21 if (ram_fs_read(fid, offset, length, data))
Jeej 0:5589104abba0 22 {
Jeej 7:bfe920ee44f2 23 modem_respond(ALP_ERR_FILE_NOT_FOUND, id);
Jeej 0:5589104abba0 24 }
Jeej 0:5589104abba0 25 else
Jeej 0:5589104abba0 26 {
Jeej 0:5589104abba0 27 modem_respond_read(fid, data, offset, length, id);
Jeej 0:5589104abba0 28 }
Jeej 0:5589104abba0 29 }
Jeej 0:5589104abba0 30
Jeej 0:5589104abba0 31 void my_write(u8 fid, void *data, u32 offset, u32 length, int id)
Jeej 0:5589104abba0 32 {
Jeej 0:5589104abba0 33 if (!ram_fs_write(fid, offset, length, (uint8_t*)data) || FID_APP_CUP_CODE == fid)
Jeej 0:5589104abba0 34 {
Jeej 0:5589104abba0 35 touch_t* touch = (touch_t*)MALLOC(sizeof(touch_t));
Jeej 0:5589104abba0 36
Jeej 0:5589104abba0 37 if (FID_APP_CUP_CODE == fid)
Jeej 0:5589104abba0 38 {
Jeej 0:5589104abba0 39 // Calculate crc on chunk
mikl_andre 3:cfe26c2bb78b 40 if (offset+length>last_end)
mikl_andre 3:cfe26c2bb78b 41 {
mikl_andre 3:cfe26c2bb78b 42 // Only calculate on new chunks, ignore repeated chunks
mikl_andre 3:cfe26c2bb78b 43 // If we missed some chunks the CRC will be bad anyway
mikl_andre 3:cfe26c2bb78b 44 stream_crc = crc32_fast(data, length, stream_crc);
mikl_andre 3:cfe26c2bb78b 45 }
mikl_andre 3:cfe26c2bb78b 46 last_end=offset+length;
mikl_andre 3:cfe26c2bb78b 47
Jeej 0:5589104abba0 48 /************************/
Jeej 0:5589104abba0 49 /* Save the chunk data. */
Jeej 0:5589104abba0 50 /************************/
mikl_andre 3:cfe26c2bb78b 51 } else if (FID_APP_CUP_CFG==fid)
mikl_andre 3:cfe26c2bb78b 52 {
mikl_andre 3:cfe26c2bb78b 53 // Reset last offset when entering CUP mode (and also exiting)
mikl_andre 3:cfe26c2bb78b 54 last_end=0;
Jeej 0:5589104abba0 55 }
Jeej 0:5589104abba0 56
Jeej 0:5589104abba0 57 touch->fid = fid;
Jeej 0:5589104abba0 58 touch->offset = offset;
Jeej 0:5589104abba0 59 touch->length = length;
Jeej 0:5589104abba0 60
Jeej 0:5589104abba0 61 g_file_modified.put(touch);
Jeej 0:5589104abba0 62
Jeej 7:bfe920ee44f2 63 modem_respond(ALP_ERR_NONE, id);
Jeej 0:5589104abba0 64 }
Jeej 0:5589104abba0 65 else
Jeej 0:5589104abba0 66 {
Jeej 7:bfe920ee44f2 67 modem_respond(ALP_ERR_FILE_NOT_FOUND, id);
Jeej 0:5589104abba0 68 }
Jeej 0:5589104abba0 69 }
Jeej 0:5589104abba0 70
Jeej 0:5589104abba0 71 void my_read_fprop(u8 fid, int id)
Jeej 0:5589104abba0 72 {
Jeej 0:5589104abba0 73 u8* hdr = (u8*)ram_fs_get_header(fid);
Jeej 0:5589104abba0 74
Jeej 0:5589104abba0 75 if (hdr != NULL)
Jeej 0:5589104abba0 76 {
Jeej 0:5589104abba0 77 modem_respond_fprop(fid, hdr, id);
Jeej 0:5589104abba0 78 }
Jeej 0:5589104abba0 79 else
Jeej 0:5589104abba0 80 {
Jeej 7:bfe920ee44f2 81 modem_respond(ALP_ERR_FILE_NOT_FOUND, id);
Jeej 0:5589104abba0 82 }
Jeej 0:5589104abba0 83 }
Jeej 0:5589104abba0 84
Jeej 0:5589104abba0 85 void my_flush(u8 fid, int id)
Jeej 0:5589104abba0 86 {
Jeej 0:5589104abba0 87 // No flush in this file system
Jeej 7:bfe920ee44f2 88 modem_respond(ALP_ERR_NONE, id);
Jeej 0:5589104abba0 89 }
Jeej 0:5589104abba0 90
Jeej 0:5589104abba0 91 void my_delete(u8 fid, int id)
Jeej 0:5589104abba0 92 {
Jeej 7:bfe920ee44f2 93 modem_respond(ALP_ERR_FILE_NOT_FOUND, id);
Jeej 0:5589104abba0 94 }
Jeej 0:5589104abba0 95
Jeej 2:49acddddec25 96 void my_udata(void *data, u32 length)
Jeej 2:49acddddec25 97 {
Jeej 2:49acddddec25 98 uint8_t* p = (uint8_t*)data;
Jeej 2:49acddddec25 99 int32_t rem = length;
Jeej 2:49acddddec25 100 alp_parsed_chunk_t r;
Jeej 2:49acddddec25 101 d7a_sp_res_t* istat;
Jeej 2:49acddddec25 102
Jeej 2:49acddddec25 103 do {
Jeej 2:49acddddec25 104 uint32_t parsed = alp_parse_chunk(&p, &r);
Jeej 2:49acddddec25 105 if (!parsed)
Jeej 2:49acddddec25 106 {
Jeej 2:49acddddec25 107 // Discard the payload in case of parsing error.
Jeej 2:49acddddec25 108 PRINT("Parsing error!\r\n");
Jeej 2:49acddddec25 109 break;
Jeej 2:49acddddec25 110 }
Jeej 2:49acddddec25 111 rem -= parsed;
Jeej 2:49acddddec25 112
Jeej 2:49acddddec25 113 switch (r.type)
Jeej 2:49acddddec25 114 {
Jeej 2:49acddddec25 115 // Interface status
Jeej 2:49acddddec25 116 case ALP_OPCODE_RSP_ISTATUS:
Jeej 2:49acddddec25 117 // D7A Interface
Jeej 2:49acddddec25 118 if (ALP_ITF_TYPE_D7A == r.meta.itf.type)
Jeej 2:49acddddec25 119 {
Jeej 2:49acddddec25 120 union {
Jeej 2:49acddddec25 121 u8 b[8];
Jeej 2:49acddddec25 122 u32 w[2];
Jeej 2:49acddddec25 123 } uid;
Jeej 2:49acddddec25 124
Jeej 2:49acddddec25 125 // ISTATUS can come either alone or together with ALP_OPCODE_RSP_F_DATA
Jeej 2:49acddddec25 126 // but there should be only one per payload, moreover it will come first
Jeej 2:49acddddec25 127 istat = (d7a_sp_res_t*)r.data;
Jeej 2:49acddddec25 128 memcpy(uid.b,istat->addressee.id,8);
Jeej 2:49acddddec25 129
Jeej 2:49acddddec25 130 PRINT("Got accessed by UID:%08X%08X SNR: %3ddB RXLEV: -%-3ddBm LB: %3ddB\n",
Jeej 2:49acddddec25 131 HAL_U32_BYTE_SWAP(uid.w[0]), HAL_U32_BYTE_SWAP(uid.w[1]),
Jeej 2:49acddddec25 132 istat->snr, istat->rxlev, istat->lb);
Jeej 2:49acddddec25 133 }
Jeej 2:49acddddec25 134 else
Jeej 2:49acddddec25 135 {
Jeej 2:49acddddec25 136 PRINT("Got accessed by unknown Interface 0x%02X\n", r.meta.itf.type);
Jeej 2:49acddddec25 137 }
Jeej 2:49acddddec25 138 break;
Jeej 2:49acddddec25 139 // Data return
Jeej 2:49acddddec25 140 case ALP_OPCODE_RSP_F_DATA:
Jeej 2:49acddddec25 141 // RSP_F_DATA can come either alone or together with ISTATUS
Jeej 2:49acddddec25 142 PRINT("Got UNS File[%3d]@%d %d Bytes\n", r.meta.f_data.fid, r.meta.f_data.offset, r.meta.f_data.length);
Jeej 2:49acddddec25 143 break;
Jeej 2:49acddddec25 144 default:
Jeej 2:49acddddec25 145 PRINT("Untreated OPCODE %d\n", r.type);
Jeej 2:49acddddec25 146 break;
Jeej 2:49acddddec25 147 }
Jeej 2:49acddddec25 148 } while (rem > 0);
Jeej 0:5589104abba0 149 }
Jeej 0:5589104abba0 150
Jeej 0:5589104abba0 151 void my_lqual(u8 ifid, int per)
Jeej 0:5589104abba0 152 {
Jeej 0:5589104abba0 153 PRINT("Interface File [%3d] LQUAL : %d%% PER\r\n", ifid, per);
Jeej 0:5589104abba0 154 }
Jeej 0:5589104abba0 155
Jeej 0:5589104abba0 156 void my_ldown(u8 ifid)
Jeej 0:5589104abba0 157 {
Jeej 0:5589104abba0 158 PRINT("Interface File [%3d] LDOWN\r\n", ifid);
Jeej 0:5589104abba0 159 }
Jeej 0:5589104abba0 160
Jeej 0:5589104abba0 161 void my_reset(void)
Jeej 0:5589104abba0 162 {
Jeej 0:5589104abba0 163 PRINT("Restarting application...\r\n");
Jeej 0:5589104abba0 164 FLUSH();
Jeej 0:5589104abba0 165 NVIC_SystemReset();
Jeej 0:5589104abba0 166 }
Jeej 0:5589104abba0 167
Jeej 0:5589104abba0 168 void my_boot(u8 cause, u16 number)
Jeej 0:5589104abba0 169 {
Jeej 0:5589104abba0 170 PRINT("Modem BOOT[%c] #%d\r\n", cause, number);
Jeej 0:5589104abba0 171
Jeej 0:5589104abba0 172 // Modem re-booted, restart APP
Jeej 0:5589104abba0 173 my_reset();
Jeej 1:dd4e18b267a1 174 }
Jeej 1:dd4e18b267a1 175
Jeej 1:dd4e18b267a1 176 void my_busy(u8 busy)
Jeej 1:dd4e18b267a1 177 {
Jeej 1:dd4e18b267a1 178 if (busy)
Jeej 1:dd4e18b267a1 179 {
Jeej 1:dd4e18b267a1 180 PRINT("Modem Busy\r\n");
Jeej 1:dd4e18b267a1 181
Jeej 2:49acddddec25 182 /* Stop report, do not use modem */
Jeej 1:dd4e18b267a1 183 /* Wait for modem reboot or modem not busy */
Jeej 1:dd4e18b267a1 184 }
Jeej 1:dd4e18b267a1 185 else
Jeej 1:dd4e18b267a1 186 {
Jeej 1:dd4e18b267a1 187 PRINT("Modem not Busy\r\n");
Jeej 1:dd4e18b267a1 188
Jeej 2:49acddddec25 189 /* Resume reports */
Jeej 1:dd4e18b267a1 190 }
Jeej 0:5589104abba0 191 }