From 11e3b8908ddaa7859e44530476769b530728d290 Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Wed, 27 Jun 2018 10:22:44 +0200 Subject: [PATCH] On-board packet queue --- Config.h | 12 ++++- Framing.h | 4 ++ RNode_Firmware.ino | 106 +++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 113 insertions(+), 9 deletions(-) diff --git a/Config.h b/Config.h index 73f4717..3452e6d 100644 --- a/Config.h +++ b/Config.h @@ -4,7 +4,7 @@ #define CONFIG_H #define MAJ_VERS 0x01 - #define MIN_VERS 0x03 + #define MIN_VERS 0x04 #define MCU_328P 0x90 #define MCU_1284P 0x91 @@ -51,6 +51,8 @@ #define FLOW_CONTROL_ENABLED true #define QUEUE_SIZE 24 + #define QUEUE_BUF_SIZE (QUEUE_SIZE+1) + #define QUEUE_MEM QUEUE_BUF_SIZE * MTU #define EEPROM_SIZE 4096 #define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED @@ -86,10 +88,18 @@ uint8_t sbuf[MTU]; uint8_t cbuf[CMD_L]; + #if QUEUE_SIZE > 0 + uint8_t tbuf[MTU]; + uint8_t qbuf[QUEUE_MEM]; + size_t queued_lengths[QUEUE_BUF_SIZE]; + #endif + uint32_t stat_rx = 0; uint32_t stat_tx = 0; bool outbound_ready = false; + size_t queue_head = 0; + size_t queue_tail = 0; bool stat_signal_detected = false; bool stat_signal_synced = false; diff --git a/Framing.h b/Framing.h index eda6bb2..6edfac7 100644 --- a/Framing.h +++ b/Framing.h @@ -48,11 +48,15 @@ #define ERROR_INITRADIO 0x01 #define ERROR_TXFAILED 0x02 #define ERROR_EEPROM_LOCKED 0x03 + #define ERROR_QUEUE_FULL 0x04 // Serial framing variables size_t frame_len; bool IN_FRAME = false; bool ESCAPE = false; + bool SERIAL_READING = false; uint8_t command = CMD_UNKNOWN; + uint32_t last_serial_read = 0; + uint32_t serial_read_timeout_ms = 2; #endif \ No newline at end of file diff --git a/RNode_Firmware.ino b/RNode_Firmware.ino index 8aada72..7f629b9 100644 --- a/RNode_Firmware.ino +++ b/RNode_Firmware.ino @@ -16,10 +16,15 @@ void setup() { pinMode(pin_led_rx, OUTPUT); pinMode(pin_led_tx, OUTPUT); - // Set up buffers + // Initialise buffers memset(pbuf, 0, sizeof(pbuf)); memset(sbuf, 0, sizeof(sbuf)); memset(cbuf, 0, sizeof(cbuf)); + + #if QUEUE_SIZE > 0 + memset(qbuf, 0, sizeof(qbuf)); + memset(queued_lengths, 0, sizeof(queued_lengths)); + #endif // Set chip select, reset and interrupt // pins for the LoRa module @@ -151,6 +156,64 @@ void receiveCallback(int packet_size) { } } + +bool outboundReady() { + #if QUEUE_SIZE > 0 + if (queue_head != queue_tail) { + return true; + } else { + return false; + } + #else + return outbound_ready; + #endif +} + +bool queueFull() { + size_t new_queue_head = (queue_head+1)%QUEUE_BUF_SIZE; + if (new_queue_head == queue_tail) { + return true; + } else { + return false; + } +} + +void enqueuePacket(size_t length) { + size_t new_queue_head = (queue_head+1)%QUEUE_BUF_SIZE; + if (new_queue_head != queue_tail) { + queued_lengths[queue_head] = length; + size_t insert_addr = queue_head * MTU; + for (int i = 0; i < length; i++) { + qbuf[insert_addr+i] = sbuf[i]; + } + queue_head = new_queue_head; + } else { + kiss_indicate_error(ERROR_QUEUE_FULL); + } +} + +#if QUEUE_SIZE > 0 +void processQueue() { + size_t fetch_address = queue_tail*MTU; + size_t fetch_length = queued_lengths[queue_tail]; + + for (int i = 0; i < fetch_length; i++) { + tbuf[i] = qbuf[fetch_address+i]; + qbuf[fetch_address+i] = 0x00; + } + + queued_lengths[queue_tail] = 0; + + queue_tail = ++queue_tail%QUEUE_BUF_SIZE; + + transmit(fetch_length); + + if (!queueFull()) { + kiss_indicate_ready(); + } +} +#endif + void transmit(size_t size) { if (radio_online) { led_tx_on(); @@ -165,7 +228,12 @@ void transmit(size_t size) { LoRa.write(header); written++; for (size_t i; i < size; i++) { - LoRa.write(sbuf[i]); + #if QUEUE_SIZE > 0 + LoRa.write(tbuf[i]); + #else + LoRa.write(sbuf[i]); + #endif + written++; if (written == 255) { @@ -186,14 +254,25 @@ void transmit(size_t size) { led_indicate_error(5); } - if (FLOW_CONTROL_ENABLED) - kiss_indicate_ready(); + #if QUEUE_SIZE == 0 + if (FLOW_CONTROL_ENABLED) + kiss_indicate_ready(); + #endif } void serialCallback(uint8_t sbyte) { if (IN_FRAME && sbyte == FEND && command == CMD_DATA) { IN_FRAME = false; - outbound_ready = true; + + if (QUEUE_SIZE == 0) { + if (outbound_ready) { + kiss_indicate_error(ERROR_QUEUE_FULL); + } else { + outbound_ready = true; + } + } else { + enqueuePacket(frame_len); + } } else if (sbyte == FEND) { IN_FRAME = true; command = CMD_UNKNOWN; @@ -412,20 +491,25 @@ void validateStatus() { void loop() { if (radio_online) { checkModemStatus(); - if (outbound_ready) { + if (outboundReady() && !SERIAL_READING) { if (!dcd_waiting) updateModemStatus(); if (!dcd && !dcd_led) { if (dcd_waiting) delay(lora_rx_turnaround_ms); updateModemStatus(); if (!dcd) { - outbound_ready = false; dcd_waiting = false; - transmit(frame_len); + #if QUEUE_SIZE > 0 + processQueue(); + #else + outbound_ready = false; + transmit(frame_len); + #endif } } else { dcd_waiting = true; } } + } else { if (hw_ready) { led_indicate_standby(); @@ -436,7 +520,13 @@ void loop() { } if (Serial.available()) { + SERIAL_READING = true; char sbyte = Serial.read(); serialCallback(sbyte); + last_serial_read = millis(); + } else { + if (SERIAL_READING && millis()-last_serial_read >= serial_read_timeout_ms) { + SERIAL_READING = false; + } } }