On-board packet queue

This commit is contained in:
Mark Qvist 2018-06-27 10:22:44 +02:00
parent 0dd6ce6539
commit 11e3b8908d
3 changed files with 113 additions and 9 deletions

View File

@ -4,7 +4,7 @@
#define CONFIG_H #define CONFIG_H
#define MAJ_VERS 0x01 #define MAJ_VERS 0x01
#define MIN_VERS 0x03 #define MIN_VERS 0x04
#define MCU_328P 0x90 #define MCU_328P 0x90
#define MCU_1284P 0x91 #define MCU_1284P 0x91
@ -51,6 +51,8 @@
#define FLOW_CONTROL_ENABLED true #define FLOW_CONTROL_ENABLED true
#define QUEUE_SIZE 24 #define QUEUE_SIZE 24
#define QUEUE_BUF_SIZE (QUEUE_SIZE+1)
#define QUEUE_MEM QUEUE_BUF_SIZE * MTU
#define EEPROM_SIZE 4096 #define EEPROM_SIZE 4096
#define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED #define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED
@ -86,10 +88,18 @@
uint8_t sbuf[MTU]; uint8_t sbuf[MTU];
uint8_t cbuf[CMD_L]; 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_rx = 0;
uint32_t stat_tx = 0; uint32_t stat_tx = 0;
bool outbound_ready = false; bool outbound_ready = false;
size_t queue_head = 0;
size_t queue_tail = 0;
bool stat_signal_detected = false; bool stat_signal_detected = false;
bool stat_signal_synced = false; bool stat_signal_synced = false;

View File

@ -48,11 +48,15 @@
#define ERROR_INITRADIO 0x01 #define ERROR_INITRADIO 0x01
#define ERROR_TXFAILED 0x02 #define ERROR_TXFAILED 0x02
#define ERROR_EEPROM_LOCKED 0x03 #define ERROR_EEPROM_LOCKED 0x03
#define ERROR_QUEUE_FULL 0x04
// Serial framing variables // Serial framing variables
size_t frame_len; size_t frame_len;
bool IN_FRAME = false; bool IN_FRAME = false;
bool ESCAPE = false; bool ESCAPE = false;
bool SERIAL_READING = false;
uint8_t command = CMD_UNKNOWN; uint8_t command = CMD_UNKNOWN;
uint32_t last_serial_read = 0;
uint32_t serial_read_timeout_ms = 2;
#endif #endif

View File

@ -16,11 +16,16 @@ void setup() {
pinMode(pin_led_rx, OUTPUT); pinMode(pin_led_rx, OUTPUT);
pinMode(pin_led_tx, OUTPUT); pinMode(pin_led_tx, OUTPUT);
// Set up buffers // Initialise buffers
memset(pbuf, 0, sizeof(pbuf)); memset(pbuf, 0, sizeof(pbuf));
memset(sbuf, 0, sizeof(sbuf)); memset(sbuf, 0, sizeof(sbuf));
memset(cbuf, 0, sizeof(cbuf)); 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 // Set chip select, reset and interrupt
// pins for the LoRa module // pins for the LoRa module
LoRa.setPins(pin_cs, pin_reset, pin_dio); LoRa.setPins(pin_cs, pin_reset, pin_dio);
@ -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) { void transmit(size_t size) {
if (radio_online) { if (radio_online) {
led_tx_on(); led_tx_on();
@ -165,7 +228,12 @@ void transmit(size_t size) {
LoRa.write(header); written++; LoRa.write(header); written++;
for (size_t i; i < size; i++) { for (size_t i; i < size; i++) {
#if QUEUE_SIZE > 0
LoRa.write(tbuf[i]);
#else
LoRa.write(sbuf[i]); LoRa.write(sbuf[i]);
#endif
written++; written++;
if (written == 255) { if (written == 255) {
@ -186,14 +254,25 @@ void transmit(size_t size) {
led_indicate_error(5); led_indicate_error(5);
} }
#if QUEUE_SIZE == 0
if (FLOW_CONTROL_ENABLED) if (FLOW_CONTROL_ENABLED)
kiss_indicate_ready(); kiss_indicate_ready();
#endif
} }
void serialCallback(uint8_t sbyte) { void serialCallback(uint8_t sbyte) {
if (IN_FRAME && sbyte == FEND && command == CMD_DATA) { if (IN_FRAME && sbyte == FEND && command == CMD_DATA) {
IN_FRAME = false; IN_FRAME = false;
if (QUEUE_SIZE == 0) {
if (outbound_ready) {
kiss_indicate_error(ERROR_QUEUE_FULL);
} else {
outbound_ready = true; outbound_ready = true;
}
} else {
enqueuePacket(frame_len);
}
} else if (sbyte == FEND) { } else if (sbyte == FEND) {
IN_FRAME = true; IN_FRAME = true;
command = CMD_UNKNOWN; command = CMD_UNKNOWN;
@ -412,20 +491,25 @@ void validateStatus() {
void loop() { void loop() {
if (radio_online) { if (radio_online) {
checkModemStatus(); checkModemStatus();
if (outbound_ready) { if (outboundReady() && !SERIAL_READING) {
if (!dcd_waiting) updateModemStatus(); if (!dcd_waiting) updateModemStatus();
if (!dcd && !dcd_led) { if (!dcd && !dcd_led) {
if (dcd_waiting) delay(lora_rx_turnaround_ms); if (dcd_waiting) delay(lora_rx_turnaround_ms);
updateModemStatus(); updateModemStatus();
if (!dcd) { if (!dcd) {
outbound_ready = false;
dcd_waiting = false; dcd_waiting = false;
#if QUEUE_SIZE > 0
processQueue();
#else
outbound_ready = false;
transmit(frame_len); transmit(frame_len);
#endif
} }
} else { } else {
dcd_waiting = true; dcd_waiting = true;
} }
} }
} else { } else {
if (hw_ready) { if (hw_ready) {
led_indicate_standby(); led_indicate_standby();
@ -436,7 +520,13 @@ void loop() {
} }
if (Serial.available()) { if (Serial.available()) {
SERIAL_READING = true;
char sbyte = Serial.read(); char sbyte = Serial.read();
serialCallback(sbyte); serialCallback(sbyte);
last_serial_read = millis();
} else {
if (SERIAL_READING && millis()-last_serial_read >= serial_read_timeout_ms) {
SERIAL_READING = false;
}
} }
} }