]> git.tnoah.ca Git - lora-radio.git/commitdiff
Optimise packet handling for SX1280 fast data rates
authorMark Qvist <mark@unsigned.io>
Wed, 8 Jan 2025 23:01:49 +0000 (00:01 +0100)
committerMark Qvist <mark@unsigned.io>
Wed, 8 Jan 2025 23:01:49 +0000 (00:01 +0100)
Boards.h
Config.h
RNode_Firmware.ino
Utilities.h

index c292a21f6c462f6420ac3ac6ca7eee7f77c3c20b..6cf0e6b8c1fe97c70125d60a8055b6a8bd7e8acd 100644 (file)
--- a/Boards.h
+++ b/Boards.h
         const int pin_dio = 33;
         const int pin_tcxo_enable = -1;
       #elif MODEM == SX1280
-        #define CONFIG_QUEUE_SIZE 40960
+        #define CONFIG_QUEUE_SIZE 6144
         #define DIO2_AS_RF_SWITCH false
         #define HAS_BUSY true
         #define HAS_TCXO true
index 80865d68b445cd17dd7e2af0fb7e683f2f7b4260..4649895e7d6376eb59dfae38b946a6551dd7c5b5 100644 (file)
--- a/Config.h
+++ b/Config.h
@@ -71,6 +71,9 @@
        #define PHY_CRC_LORA_BITS          16
        #define LORA_PREAMBLE_SYMBOLS_MIN  18
        #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_time_ms      =  0;
        long lora_header_time_ms        =  0;
        float lora_symbol_rate          =  0.0;
        float lora_us_per_byte          =  0.0;
        bool lora_low_datarate          =  false;
+       bool lora_limit_rate            =  false;
 
        // CSMA Parameters
        #define CSMA_SIFS_MS               0
        #define CSMA_POST_TX_YIELD_SLOTS   3
        #define CSMA_SLOT_MAX_MS           100
        #define CSMA_SLOT_MIN_MS           24
+       #define CSMA_SLOT_MIN_FAST_DELTA   18
        #define CSMA_SLOT_SYMBOLS          12
        #define CSMA_CW_BANDS              4
        #define CSMA_CW_MIN                0
index 880aed5f376d4afa306e383b5cc9454eab0f0e58..463ee55b883e71162c47bca4f96d320671187551 100644 (file)
@@ -553,6 +553,45 @@ void flush_queue(void) {
   #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) {
   #if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
     float lora_symbols = 0;
@@ -1376,9 +1415,8 @@ void tx_queue_handler() {
             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
             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; }
-
           }
         }
       }
index 2dc102aff832dfd624461208fd6849d71ef166ce..3b54629635acf9143631d725dc8c110022098c9a 100644 (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_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;
                        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;
                        
-                       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; }
                        else { target_preamble_symbols = (ceil)(target_preamble_symbols); }