Optimise packet handling for SX1280 fast data rates

This commit is contained in:
Mark Qvist 2025-01-09 00:01:49 +01:00
parent 729a4099e5
commit 218a38adb7
4 changed files with 56 additions and 5 deletions

View File

@ -445,7 +445,7 @@
const int pin_dio = 33; const int pin_dio = 33;
const int pin_tcxo_enable = -1; const int pin_tcxo_enable = -1;
#elif MODEM == SX1280 #elif MODEM == SX1280
#define CONFIG_QUEUE_SIZE 40960 #define CONFIG_QUEUE_SIZE 6144
#define DIO2_AS_RF_SWITCH false #define DIO2_AS_RF_SWITCH false
#define HAS_BUSY true #define HAS_BUSY true
#define HAS_TCXO true #define HAS_TCXO true

View File

@ -71,6 +71,9 @@
#define PHY_CRC_LORA_BITS 16 #define PHY_CRC_LORA_BITS 16
#define LORA_PREAMBLE_SYMBOLS_MIN 18 #define LORA_PREAMBLE_SYMBOLS_MIN 18
#define LORA_PREAMBLE_TARGET_MS 24 #define LORA_PREAMBLE_TARGET_MS 24
#define LORA_PREAMBLE_FAST_DELTA 18
#define LORA_FAST_THRESHOLD_BPS 30E3
#define LORA_LIMIT_THRESHOLD_BPS 60E3
long lora_preamble_symbols = LORA_PREAMBLE_SYMBOLS_MIN; long lora_preamble_symbols = LORA_PREAMBLE_SYMBOLS_MIN;
long lora_preamble_time_ms = 0; long lora_preamble_time_ms = 0;
long lora_header_time_ms = 0; long lora_header_time_ms = 0;
@ -78,12 +81,14 @@
float lora_symbol_rate = 0.0; float lora_symbol_rate = 0.0;
float lora_us_per_byte = 0.0; float lora_us_per_byte = 0.0;
bool lora_low_datarate = false; bool lora_low_datarate = false;
bool lora_limit_rate = false;
// CSMA Parameters // CSMA Parameters
#define CSMA_SIFS_MS 0 #define CSMA_SIFS_MS 0
#define CSMA_POST_TX_YIELD_SLOTS 3 #define CSMA_POST_TX_YIELD_SLOTS 3
#define CSMA_SLOT_MAX_MS 100 #define CSMA_SLOT_MAX_MS 100
#define CSMA_SLOT_MIN_MS 24 #define CSMA_SLOT_MIN_MS 24
#define CSMA_SLOT_MIN_FAST_DELTA 18
#define CSMA_SLOT_SYMBOLS 12 #define CSMA_SLOT_SYMBOLS 12
#define CSMA_CW_BANDS 4 #define CSMA_CW_BANDS 4
#define CSMA_CW_MIN 0 #define CSMA_CW_MIN 0

View File

@ -553,6 +553,45 @@ void flush_queue(void) {
#endif #endif
} }
void pop_queue() {
if (!queue_flushing) {
queue_flushing = true;
led_tx_on(); uint16_t processed = 0;
#if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
if (!fifo16_isempty(&packet_starts)) {
#else
if (!fifo16_isempty_locked(&packet_starts)) {
#endif
uint16_t start = fifo16_pop(&packet_starts);
uint16_t length = fifo16_pop(&packet_lengths);
if (length >= MIN_L && length <= MTU) {
for (uint16_t i = 0; i < length; i++) {
uint16_t pos = (start+i)%CONFIG_QUEUE_SIZE;
tbuf[i] = packet_queue[pos];
}
transmit(length); processed++;
}
queue_height -= processed;
queued_bytes -= length;
}
lora_receive(); led_tx_off();
}
#if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
update_airtime();
#endif
queue_flushing = false;
#if HAS_DISPLAY
display_tx = true;
#endif
}
void add_airtime(uint16_t written) { void add_airtime(uint16_t written) {
#if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52 #if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
float lora_symbols = 0; float lora_symbols = 0;
@ -1376,9 +1415,8 @@ void tx_queue_handler() {
cw_wait_passed += millis()-cw_wait_start; cw_wait_start = millis(); cw_wait_passed += millis()-cw_wait_start; cw_wait_start = millis();
if (cw_wait_passed < cw_wait_target) { return; } // Contention window wait time has not yet passed, continue waiting if (cw_wait_passed < cw_wait_target) { return; } // Contention window wait time has not yet passed, continue waiting
else { // Wait time has passed, flush the queue else { // Wait time has passed, flush the queue
flush_queue(); if (!lora_limit_rate) { flush_queue(); } else { pop_queue(); }
cw_wait_passed = 0; csma_cw = -1; difs_wait_start = -1; } cw_wait_passed = 0; csma_cw = -1; difs_wait_start = -1; }
} }
} }
} }

View File

@ -1101,12 +1101,20 @@ void updateBitrate() {
lora_bitrate = (uint32_t)(lora_sf * ( (4.0/(float)lora_cr) / ((float)(pow(2, lora_sf))/((float)lora_bw/1000.0)) ) * 1000.0); lora_bitrate = (uint32_t)(lora_sf * ( (4.0/(float)lora_cr) / ((float)(pow(2, lora_sf))/((float)lora_bw/1000.0)) ) * 1000.0);
lora_us_per_byte = 1000000.0/((float)lora_bitrate/8.0); lora_us_per_byte = 1000000.0/((float)lora_bitrate/8.0);
bool fast_rate = lora_bitrate > LORA_FAST_THRESHOLD_BPS;
lora_limit_rate = lora_bitrate > LORA_LIMIT_THRESHOLD_BPS;
int csma_slot_min_ms = CSMA_SLOT_MIN_MS;
float lora_preamble_target_ms = LORA_PREAMBLE_TARGET_MS;
if (fast_rate) { csma_slot_min_ms -= CSMA_SLOT_MIN_FAST_DELTA;
lora_preamble_target_ms -= LORA_PREAMBLE_FAST_DELTA; }
csma_slot_ms = lora_symbol_time_ms*CSMA_SLOT_SYMBOLS; csma_slot_ms = lora_symbol_time_ms*CSMA_SLOT_SYMBOLS;
if (csma_slot_ms > CSMA_SLOT_MAX_MS) { csma_slot_ms = CSMA_SLOT_MAX_MS; } if (csma_slot_ms > CSMA_SLOT_MAX_MS) { csma_slot_ms = CSMA_SLOT_MAX_MS; }
if (csma_slot_ms < CSMA_SLOT_MIN_MS) { csma_slot_ms = CSMA_SLOT_MIN_MS; } if (csma_slot_ms < CSMA_SLOT_MIN_MS) { csma_slot_ms = csma_slot_min_ms; }
difs_ms = CSMA_SIFS_MS + 2*csma_slot_ms; difs_ms = CSMA_SIFS_MS + 2*csma_slot_ms;
float target_preamble_symbols = LORA_PREAMBLE_TARGET_MS/lora_symbol_time_ms; float target_preamble_symbols = lora_preamble_target_ms/lora_symbol_time_ms;
if (target_preamble_symbols < LORA_PREAMBLE_SYMBOLS_MIN) { target_preamble_symbols = LORA_PREAMBLE_SYMBOLS_MIN; } if (target_preamble_symbols < LORA_PREAMBLE_SYMBOLS_MIN) { target_preamble_symbols = LORA_PREAMBLE_SYMBOLS_MIN; }
else { target_preamble_symbols = (ceil)(target_preamble_symbols); } else { target_preamble_symbols = (ceil)(target_preamble_symbols); }