]> git.tnoah.ca Git - lora-radio.git/commitdiff
Improved channel access behaviour. Improved LoRa PHY parameter setup. Added parameter...
authorMark Qvist <mark@unsigned.io>
Sun, 17 Sep 2023 14:23:35 +0000 (16:23 +0200)
committerMark Qvist <mark@unsigned.io>
Sun, 17 Sep 2023 14:23:35 +0000 (16:23 +0200)
Config.h
Framing.h
RNode_Firmware.ino
Utilities.h

index b1affe38c2812ae998149d13f849287b8a12c28d..aef43a205ff1ca05864a293ef89faa3d2b4a736d 100644 (file)
--- a/Config.h
+++ b/Config.h
 
        // MCU independent configuration parameters
        const long serial_baudrate  = 115200;
-       const int lora_rx_turnaround_ms = 50;
-       uint8_t csma_p = 0;
-       float csma_p_min = 0.1;
-       float csma_p_max = 0.8;
-       int csma_slot_ms = lora_rx_turnaround_ms;
 
        // SX1276 RSSI offset to get dBm value from
        // packet RSSI register
        const int  rssi_offset = 157;
 
        // Default LoRa settings
+       const int lora_rx_turnaround_ms = 66;
+       const int lora_post_tx_yield_slots = 6;
+       uint32_t post_tx_yield_timeout = 0;
+       #define LORA_PREAMBLE_SYMBOLS_HW  4
+       #define LORA_PREAMBLE_SYMBOLS_MIN 6
+       #define LORA_PREAMBLE_TARGET_MS   15
+       #define LORA_CAD_SYMBOLS 3
+       int csma_slot_ms = 50;
+       float csma_p_min = 0.1;
+       float csma_p_max = 0.8;
+       uint8_t csma_p = 0;
+
        int  lora_sf               = 0;
        int  lora_cr               = 5;
        int  lora_txp              = 0xFF;
        float lt_airtime_limit = 0.0;
        bool airtime_lock = false;
 
-       bool stat_signal_detected = false;
-       bool stat_signal_synced   = false;
-       bool stat_rx_ongoing      = false;
-       bool dcd                  = false;
-       bool dcd_led              = false;
-       bool dcd_waiting          = false;
-       long dcd_wait_until       = 0;
-       uint16_t dcd_count        = 0;
-       uint16_t dcd_threshold    = 6;
+       bool stat_signal_detected   = false;
+       bool stat_signal_synced     = false;
+       bool stat_rx_ongoing        = false;
+       bool dcd                    = false;
+       bool dcd_led                = false;
+       bool dcd_waiting            = false;
+       long dcd_wait_until         = 0;
+       uint16_t dcd_count          = 0;
+       uint16_t dcd_threshold      = 2;
 
        uint32_t status_interval_ms = STATUS_INTERVAL_MS;
        uint32_t last_status_update = 0;
+       uint32_t last_dcd = 0;
 
        // Status flags
        const uint8_t SIG_DETECT = 0x01;
index 79811b4b58c0559da64ca4dfaa60a2b972139484..97dce7cb6a23e619e48f8e5997465ed6fef977c3 100644 (file)
--- a/Framing.h
+++ b/Framing.h
@@ -43,6 +43,7 @@
   #define CMD_STAT_RSSI   0x23
   #define CMD_STAT_SNR    0x24
   #define CMD_STAT_CHTM   0x25
+  #define CMD_STAT_PHYPRM 0x26
   #define CMD_BLINK       0x30
   #define CMD_RANDOM      0x40
 
index 07a5ceadda280ca5d0e0278190170bc81163d257..e5852ea30116049a2dbe881e7ef721e02958a986 100644 (file)
@@ -318,7 +318,6 @@ bool startRadio() {
         setBandwidth();
         setSpreadingFactor();
         setCodingRate();
-        setPreamble();
         getFrequency();
 
         LoRa.enableCrc();
@@ -398,6 +397,7 @@ void flushQueue(void) {
 
     lora_receive();
     led_tx_off();
+    post_tx_yield_timeout = millis()+(lora_post_tx_yield_slots*csma_slot_ms);
   }
 
   queue_height = 0;
@@ -925,20 +925,30 @@ void updateModemStatus() {
   if (status & RX_ONGOING == RX_ONGOING) { stat_rx_ongoing = true; } else { stat_rx_ongoing = false; }
 
   if (stat_signal_detected || stat_signal_synced || stat_rx_ongoing) {
-    if (dcd_count < dcd_threshold) {
-      dcd_count++;
-      dcd = true;
-    } else {
-      dcd = true;
-      dcd_led = true;
+    if (stat_rx_ongoing) {
+      if (dcd_count < dcd_threshold) {
+        dcd_count++;
+      } else {
+        last_dcd = last_status_update;
+        dcd_led = true;
+        dcd = true;
+      }
     }
   } else {
-    if (dcd_count > 0) {
-      dcd_count = 0;
+    #define DCD_LED_STEP_D 3
+    if (dcd_count == 0) {
+      dcd_led = false;
+    } else if (dcd_count > DCD_LED_STEP_D) {
+      dcd_count -= DCD_LED_STEP_D;
     } else {
+      dcd_count = 0;
+    }
+
+    if (last_status_update > last_dcd+csma_slot_ms) {
+      dcd = false;
       dcd_led = false;
+      dcd_count = 0;
     }
-    dcd = false;
   }
 
   if (dcd_led) {
@@ -1110,8 +1120,6 @@ void validate_status() {
 
 void loop() {
   if (radio_online) {
-    checkModemStatus();
-
     #if MCU_VARIANT == MCU_ESP32
       if (packet_ready) {
         portENTER_CRITICAL(&update_lock);
@@ -1128,22 +1136,26 @@ void loop() {
       if (lt_airtime_limit != 0.0 && longterm_airtime >= lt_airtime_limit) airtime_lock = true;
     #endif
 
+    checkModemStatus();
     if (!airtime_lock) {
       if (queue_height > 0) {
         #if MCU_VARIANT == MCU_ESP32
+          long check_time = millis();
+          if (check_time > post_tx_yield_timeout) {
+            if (dcd_waiting && (check_time >= dcd_wait_until)) { dcd_waiting = false; }
+            if (!dcd_waiting) {
+              for (uint8_t dcd_i = 0; dcd_i < dcd_threshold*2; dcd_i++) {
+                delay(STATUS_INTERVAL_MS); updateModemStatus();
+              }
 
-          if (dcd_waiting && (millis() >= dcd_wait_until)) { dcd_waiting = false; }
-          if (!dcd_waiting) {
-            updateModemStatus();
-            long check_time = millis();
-
-            if (!dcd) {
-              uint8_t csma_r = (uint8_t)random(256);
-              if (csma_p >= csma_r) {
-                flushQueue();
-              } else {
-                dcd_waiting = true;
-                dcd_wait_until = check_time+csma_slot_ms;
+              if (!dcd) {
+                uint8_t csma_r = (uint8_t)random(256);
+                if (csma_p >= csma_r) {
+                  flushQueue();
+                } else {
+                  dcd_waiting = true;
+                  dcd_wait_until = millis()+csma_slot_ms;
+                }
               }
             }
           }
index 3c7161897d0ececf27741db04c45604431b4dc8d..97697b298b00176ce5a5716ccd6a2a88a448b505 100644 (file)
@@ -732,6 +732,29 @@ void kiss_indicate_channel_stats() {
        #endif
 }
 
+void kiss_indicate_phy_stats() {
+       #if MCU_VARIANT == MCU_ESP32
+               uint16_t lst = (uint16_t)(lora_symbol_time_ms*1000);
+               uint16_t lsr = (uint16_t)(lora_symbol_rate);
+               uint16_t prs = (uint16_t)(lora_preamble_symbols+4);
+               uint16_t prt = (uint16_t)((lora_preamble_symbols+4)*lora_symbol_time_ms);
+               uint16_t cst = (uint16_t)(csma_slot_ms);
+               serial_write(FEND);
+               serial_write(CMD_STAT_PHYPRM);
+               escaped_serial_write(lst>>8);
+               escaped_serial_write(lst);
+               escaped_serial_write(lsr>>8);
+               escaped_serial_write(lsr);
+               escaped_serial_write(prs>>8);
+               escaped_serial_write(prs);
+               escaped_serial_write(prt>>8);
+               escaped_serial_write(prt);
+               escaped_serial_write(cst>>8);
+               escaped_serial_write(cst);
+               serial_write(FEND);
+       #endif
+}
+
 void kiss_indicate_btpin() {
        #if HAS_BLUETOOTH
                serial_write(FEND);
@@ -905,6 +928,11 @@ inline uint8_t packetSequence(uint8_t header) {
        return header >> 4;
 }
 
+void setPreamble() {
+       if (radio_online) LoRa.setPreambleLength(lora_preamble_symbols);
+       kiss_indicate_phy_stats();
+}
+
 void updateBitrate() {
        #if MCU_VARIANT == MCU_ESP32
                if (radio_online) {
@@ -912,7 +940,15 @@ void updateBitrate() {
                        lora_symbol_time_ms = (1.0/lora_symbol_rate)*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);
-                       csma_slot_ms = lora_symbol_time_ms*10;
+                       // csma_slot_ms = lora_symbol_time_ms*10;
+                       float target_preamble_symbols = (LORA_PREAMBLE_TARGET_MS/lora_symbol_time_ms)-LORA_PREAMBLE_SYMBOLS_HW;
+                       if (target_preamble_symbols < LORA_PREAMBLE_SYMBOLS_MIN) {
+                               target_preamble_symbols = LORA_PREAMBLE_SYMBOLS_MIN;
+                       } else {
+                               target_preamble_symbols = ceil(target_preamble_symbols);
+                       }
+                       lora_preamble_symbols = (long)target_preamble_symbols;
+                       setPreamble();
                } else {
                        lora_bitrate = 0;
                }
@@ -929,11 +965,6 @@ void setCodingRate() {
        updateBitrate();
 }
 
-void setPreamble() {
-       if (radio_online) LoRa.setPreambleLength(lora_preamble_symbols);
-       updateBitrate();
-}
-
 void set_implicit_length(uint8_t len) {
        implicit_l = len;
        if (implicit_l != 0) {