diff --git a/lib/comms/comms.cpp b/lib/comms/comms.cpp index b4824b7..b31fe13 100644 --- a/lib/comms/comms.cpp +++ b/lib/comms/comms.cpp @@ -184,19 +184,18 @@ String _scan_str(ScanTask &); String _scan_result_str(ScanTaskResult &); String _wrap_str(String); -#define POLY 0x1021 -uint16_t crc16(String v, uint16_t c) +uint16_t crc16(uint16_t poly, uint16_t c, size_t sz, uint8_t *v) { c ^= 0xffff; - for (int i = 0; i < v.length(); i++) + for (int i = 0; i < sz; i++) { - uint16_t ch = v.charAt(i); + uint16_t ch = v[i]; c = c ^ (ch << 8); for (int j = 0; j < 8; j++) { if (c & 0x8000) { - c = (c << 1) ^ POLY; + c = (c << 1) ^ poly; } else { @@ -208,6 +207,12 @@ uint16_t crc16(String v, uint16_t c) return c ^ 0xffff; } +#define POLY 0x1021 +uint16_t crc16(String v, uint16_t c) +{ + return crc16(POLY, c, v.length(), (uint8_t *)v.c_str()); +} + void ReadlineComms::_onReceive() { while (serial.available() > 0) diff --git a/lib/comms/comms.h b/lib/comms/comms.h index 2b5124a..4154e36 100644 --- a/lib/comms/comms.h +++ b/lib/comms/comms.h @@ -90,6 +90,7 @@ struct Endpoint { union { + struct { uint8_t loop : 1, // self @@ -158,14 +159,35 @@ extern Comms *Comms0; extern Comms *Comms1; +struct LoRaStats +{ + uint64_t t0; + int64_t rssi_60; + int64_t snr_60; + + int16_t last_rssi; + int16_t last_snr; + + int64_t messages_60; + int64_t errors_60; + + LoRaStats() + : t0(0), rssi_60(0), snr_60(0), last_rssi(0), last_snr(0), messages_60(0), + errors_60(0) + { + } +}; + struct RadioComms { String name; RADIO_TYPE &radio; LoRaConfig &loraCfg; + LoRaStats stats; + RadioComms(String name, RADIO_TYPE &radio, LoRaConfig &cfg) - : name(name), radio(radio), loraCfg(cfg) + : name(name), radio(radio), loraCfg(cfg), stats() { } @@ -176,6 +198,15 @@ struct RadioComms Message *receive(uint16_t timeout_ms); }; +uint16_t crc16(uint16_t poly, uint16_t c, size_t sz, uint8_t *v); + +/* + * Given halflife (i.e. time it takes the accumulator to decay to 50%), compute + * the updated cumulate at new time. That is, acc_now = decay(acc_t, inc). + */ +int64_t updateExpDecay(uint16_t halflife, int64_t acc, uint64_t t, uint64_t now, + int64_t inc); + extern RadioComms *RxComms; extern RadioComms *TxComms; diff --git a/lib/comms/radio_comms.cpp b/lib/comms/radio_comms.cpp index 488e09f..2048359 100644 --- a/lib/comms/radio_comms.cpp +++ b/lib/comms/radio_comms.cpp @@ -188,6 +188,11 @@ int16_t RadioComms::send(Message &m) size_t p = MAX_MSG; uint8_t *msg = NULL; + if (loraCfg.crc) + { + p -= 2; + } + if (m.type == SCAN_RESULT) { msg = _serialize_scan_result(m, p, msg_buf); @@ -207,6 +212,13 @@ int16_t RadioComms::send(Message &m) return RADIOLIB_ERR_INVALID_FUNCTION; } + if (loraCfg.crc) + { + uint16_t c = loraCfg.crc_seed ^ 0xffff; + c = crc16(loraCfg.crc_poly, c, p, msg); + _write(msg, MAX_MSG, p, (uint8_t *)&c, 2); + } + int16_t status = radio.transmit(msg, p); if (msg != msg_buf) @@ -385,7 +397,7 @@ Message *RadioComms::receive(uint16_t timeout_ms) radio.clearDio1Action(); packetRssi = radio.getRSSI(true); - Serial.println("LORA_RSSI: " + String(packetRssi)); + // Serial.println("LORA_RSSI:" + String(packetRssi)); size_t len = radio.getPacketLength(true); uint8_t *packet = msg; diff --git a/lib/config/config.cpp b/lib/config/config.cpp index 469de55..28c8779 100644 --- a/lib/config/config.cpp +++ b/lib/config/config.cpp @@ -189,7 +189,9 @@ String loraConfigToStr(LoRaConfig *cfg) String(",tx_power:") + String(cfg->tx_power) + String(",preamble_len:") + String(cfg->preamble_len) + String(",sync_word:") + String(cfg->sync_word, 16) + String(",crc:") + String(cfg->crc ? "1" : "0") + - String(",implicit_header:") + String(cfg->implicit_header); + String(",crc_seed:") + String(cfg->crc_seed, 16) + String(",crc_poly:") + + String(cfg->crc_poly, 16) + String(",implicit_header:") + + String(cfg->implicit_header); } String detectionStrategyToStr(Config &c) @@ -356,6 +358,8 @@ LoRaConfig *configureLora(String cfg) preamble_len : 8, sync_word : 0x1e, crc : false, + crc_seed : 0, + crc_poly : 0x1021, implicit_header : 0 }); @@ -383,6 +387,18 @@ LoRaConfig *configureLora(String cfg) continue; } + if (k.equalsIgnoreCase("crc_seed")) + { + lora->crc_seed = (uint16_t)fromHex(param); + continue; + } + + if (k.equalsIgnoreCase("crc_poly")) + { + lora->crc_poly = (uint16_t)fromHex(param); + continue; + } + if (k.equalsIgnoreCase("freq")) { lora->freq = param.toFloat(); diff --git a/lib/config/config.h b/lib/config/config.h index c09107b..b52e740 100644 --- a/lib/config/config.h +++ b/lib/config/config.h @@ -46,6 +46,8 @@ struct LoRaConfig uint16_t preamble_len; uint8_t sync_word; bool crc; + uint16_t crc_seed; + uint16_t crc_poly; uint8_t implicit_header; };