]> git.tnoah.ca Git - lora-radio.git/commitdiff
Reworked SX1262 LoRa carrier detection
authorMark Qvist <mark@unsigned.io>
Tue, 7 Jan 2025 14:14:44 +0000 (15:14 +0100)
committerMark Qvist <mark@unsigned.io>
Tue, 7 Jan 2025 14:14:44 +0000 (15:14 +0100)
Boards.h
Config.h
Makefile
RNode_Firmware.ino
Utilities.h
sx126x.cpp
sx126x.h

index c292a21f6c462f6420ac3ac6ca7eee7f77c3c20b..aa1a4f110b8afc055f74d44bfd39d2b2d323e5a5 100644 (file)
--- a/Boards.h
+++ b/Boards.h
 // You should have received a copy of the GNU General Public License
 // along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
+// TODO: Remove debug setup
+#define PIN_PREAMBLE 7
+#define PIN_HEADER   6
+#define PIN_DCD      5
+#define PIN_TXSIG    4
+
 #include "Modem.h"
 
 #ifndef BOARDS_H
index b4ac7e7dcc41699a2ef288cb8f4b9bcb2ef41957..f6569b49a72a4d00e053775966baa350f75e195e 100644 (file)
--- a/Config.h
+++ b/Config.h
@@ -70,6 +70,8 @@
        const int lora_rx_turnaround_ms = 66;
        const int lora_post_tx_yield_slots = 6;
        uint32_t post_tx_yield_timeout = 0;
+       #define PHY_HEADER_LORA_SYMBOLS   20
+       #define PHY_CRC_LORA_BITS         16
        #define LORA_PREAMBLE_SYMBOLS_MIN 18
        #define LORA_PREAMBLE_TARGET_MS   15
        #define LORA_CAD_SYMBOLS          3
@@ -78,6 +80,8 @@
        #define CSMA_SLOT_MIN_MS          24
        
        long lora_preamble_symbols = 12;
+       long lora_preamble_time_ms = 0;
+       long lora_header_time_ms   = 0;
        float lora_symbol_time_ms  = 0.0;
        float lora_symbol_rate     = 0.0;
        float lora_us_per_byte     = 0.0;
index d3f357c99b80092bf8034e6d4add8e8cc2e32e6f..8f3364c585ba7ffdba530e22349019218ddbf206 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -156,8 +156,8 @@ upload-tbeam_sx1262:
        arduino-cli upload -p /dev/ttyACM0 --fqbn esp32:esp32:t-beam
        @sleep 1
        rnodeconf /dev/ttyACM0 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.t-beam/RNode_Firmware.ino.bin)
-       @sleep 3
-       python ./Release/esptool/esptool.py --chip esp32 --port /dev/ttyACM0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/console_image.bin
+       #@sleep 3
+       #python ./Release/esptool/esptool.py --chip esp32 --port /dev/ttyACM0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/console_image.bin
 
 upload-lora32_v10:
        arduino-cli upload -p /dev/ttyUSB0 --fqbn esp32:esp32:ttgo-lora32
@@ -188,9 +188,9 @@ upload-heltec32_v2:
        python ./Release/esptool/esptool.py --chip esp32 --port /dev/ttyUSB1 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/console_image.bin
 
 upload-heltec32_v3:
-       arduino-cli upload -p /dev/ttyUSB1 --fqbn esp32:esp32:heltec_wifi_lora_32_V3
+       arduino-cli upload -p /dev/ttyUSB2 --fqbn esp32:esp32:heltec_wifi_lora_32_V3
        @sleep 1
-       rnodeconf /dev/ttyUSB1 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.heltec_wifi_lora_32_V3/RNode_Firmware.ino.bin)
+       rnodeconf /dev/ttyUSB2 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.heltec_wifi_lora_32_V3/RNode_Firmware.ino.bin)
        #@sleep 3
        #python ./Release/esptool/esptool.py --chip esp32-s3 --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/console_image.bin
 
index f8d5b3570af36b8fa57c9154b47e88e56b5cdede..f38162b05276c905efd2c49c60f6e32c25c72add 100644 (file)
@@ -59,6 +59,13 @@ char sbuf[128];
 #endif
 
 void setup() {
+  // TODO: Remove debug setup
+  pinMode(PIN_PREAMBLE, OUTPUT);
+  pinMode(PIN_HEADER, OUTPUT);
+  pinMode(PIN_DCD, OUTPUT);
+  pinMode(PIN_TXSIG, OUTPUT);
+  ///////////////////////////
+
   #if MCU_VARIANT == MCU_ESP32
     boot_seq();
     EEPROM.begin(EEPROM_SIZE);
@@ -516,6 +523,10 @@ bool queueFull() {
 volatile bool queue_flushing = false;
 void flushQueue(void) {
   if (!queue_flushing) {
+
+    // TODO: Remove debug
+    digitalWrite(PIN_TXSIG, HIGH);
+
     queue_flushing = true;
 
     led_tx_on();
@@ -557,8 +568,6 @@ void flushQueue(void) {
   #endif
 }
 
-#define PHY_HEADER_LORA_SYMBOLS 20
-#define PHY_CRC_LORA_BITS       16
 void add_airtime(uint16_t written) {
   #if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
     float lora_symbols = 0;
@@ -1197,7 +1206,7 @@ void updateModemStatus() {
     portENTER_CRITICAL();
   #endif
 
-  uint8_t status = LoRa->modemStatus();
+  bool carrier_detected = LoRa->dcd();
   current_rssi = LoRa->currentRssi();
   last_status_update = millis();
 
@@ -1207,47 +1216,13 @@ void updateModemStatus() {
     portEXIT_CRITICAL();
   #endif
 
-  if ((status & SIG_DETECT) == SIG_DETECT) { stat_signal_detected = true; } else { stat_signal_detected = false; }
-  if ((status & SIG_SYNCED) == SIG_SYNCED) { stat_signal_synced = true; } else { stat_signal_synced = false; }
-  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 (stat_signal_detected || stat_signal_synced) {
-    if (stat_rx_ongoing) {
-      if (dcd_count < dcd_threshold) {
-        dcd_count++;
-      } else {
-        last_dcd = last_status_update;
-        dcd_led = true;
-        dcd = true;
-      }
-    }
-  } else {
-    #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;
-    }
-  }
+  if (carrier_detected) { dcd = true; digitalWrite(PIN_DCD, HIGH); /* TODO: Remove debug */ }
+  else { dcd = false; digitalWrite(PIN_DCD, LOW); /* TODO: Remove debug */ }
 
-  if (dcd_led) {
-    led_rx_on();
-  } else {
-    if (airtime_lock) {
-      led_indicate_airtime_lock();
-    } else {
-      led_rx_off();
-    }
-  }
+  dcd_led = dcd;
+  if (dcd_led) { led_rx_on(); }
+  else         { if (airtime_lock) { led_indicate_airtime_lock(); }
+                 else              { led_rx_off(); } }
 }
 
 void checkModemStatus() {
@@ -1463,6 +1438,7 @@ void loop() {
     if (!airtime_lock) {
       if (queue_height > 0) {
         #if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52
+
           long check_time = millis();
           if (check_time > post_tx_yield_timeout) {
             if (dcd_waiting && (check_time >= dcd_wait_until)) { dcd_waiting = false; }
@@ -1486,7 +1462,7 @@ void loop() {
         #else
           if (!dcd_waiting) updateModemStatus();
 
-          if (!dcd && !dcd_led) {
+          if (!dcd) {
             if (dcd_waiting) delay(lora_rx_turnaround_ms);
 
             updateModemStatus();
index 5a981bd2a8c2d1e672c5e9054666a12df76aa3fd..32a1fc679b09b22b2ecd9ba87e17cf005c4bbb99 100644 (file)
@@ -864,7 +864,7 @@ void kiss_indicate_phy_stats() {
                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);
-               uint16_t prt = (uint16_t)((lora_preamble_symbols)*lora_symbol_time_ms);
+               uint16_t prt = (uint16_t)(lora_preamble_time_ms);
                uint16_t cst = (uint16_t)(csma_slot_ms);
                serial_write(FEND);
                serial_write(CMD_STAT_PHYPRM);
@@ -1102,6 +1102,8 @@ void updateBitrate() {
                        
                        lora_preamble_symbols = (long)target_preamble_symbols;
                        setPreamble();
+                       lora_preamble_time_ms = (ceil)(lora_preamble_symbols * lora_symbol_time_ms);
+                       lora_header_time_ms   = (ceil)(PHY_HEADER_LORA_SYMBOLS * lora_symbol_time_ms);
                } else {
                        lora_bitrate = 0;
                }
index 697d97db4ef1f9910bdb5f2f4b324daf09263435..a169f77c9083a65a71934d8e4f2877b2747f01e4 100644 (file)
@@ -97,7 +97,7 @@ extern SPIClass SPI;
 #define MAX_PKT_LENGTH 255
 
 sx126x::sx126x() :
-  _spiSettings(8E6, MSBFIRST, SPI_MODE0),
+  _spiSettings(16E6, MSBFIRST, SPI_MODE0),
   _ss(LORA_DEFAULT_SS_PIN), _reset(LORA_DEFAULT_RESET_PIN), _dio0(LORA_DEFAULT_DIO0_PIN), _busy(LORA_DEFAULT_BUSY_PIN), _rxen(LORA_DEFAULT_RXEN_PIN),
   _frequency(0),
   _txp(0),
@@ -293,11 +293,11 @@ void sx126x::calibrate(void) {
 
 void sx126x::calibrate_image(long frequency) {
   uint8_t image_freq[2] = {0};
-  if (frequency >= 430E6 && frequency <= 440E6)      { image_freq[0] = 0x6B; image_freq[1] = 0x6F; }
+  if      (frequency >= 430E6 && frequency <= 440E6) { image_freq[0] = 0x6B; image_freq[1] = 0x6F; }
   else if (frequency >= 470E6 && frequency <= 510E6) { image_freq[0] = 0x75; image_freq[1] = 0x81; }
   else if (frequency >= 779E6 && frequency <= 787E6) { image_freq[0] = 0xC1; image_freq[1] = 0xC5; }
   else if (frequency >= 863E6 && frequency <= 870E6) { image_freq[0] = 0xD7; image_freq[1] = 0xDB; }
-  else if (frequency >= 902E6 && frequency <= 928E6) { image_freq[0] = 0xE1; image_freq[1] = 0xE9; }
+  else if (frequency >= 902E6 && frequency <= 928E6) { image_freq[0] = 0xE1; image_freq[1] = 0xE9; } // TODO: Allow higher freq calibration
   executeOpcode(OP_CALIBRATE_IMAGE_6X, image_freq, 2);
   waitOnBusy();
 }
@@ -372,6 +372,9 @@ int sx126x::endPacket() {
     yield();
   }
 
+  // TODO: Remove debug
+  digitalWrite(PIN_TXSIG, LOW);
+
   if (!(millis() < w_timeout)) { timed_out = true; }
 
   // Clear IRQs
@@ -382,27 +385,41 @@ int sx126x::endPacket() {
   if (timed_out) { return 0; } else { return 1; }
 }
 
-uint8_t sx126x::modemStatus() {
-  // Imitate the register status from the sx1276 / 78
-  uint8_t buf[2] = {0};
-  executeOpcodeRead(OP_GET_IRQ_STATUS_6X, buf, 2);
-  uint8_t clearbuf[2] = {0};
-  uint8_t byte = 0x00;
+unsigned long preamble_detected_at = 0;
+unsigned long header_detected_at = 0;
+extern long lora_preamble_time_ms;
+extern long lora_header_time_ms;
+bool sx126x::dcd() {
+  bool carrier_detected = false;
+  uint8_t buf[2] = {0}; executeOpcodeRead(OP_GET_IRQ_STATUS_6X, buf, 2);
 
   if ((buf[1] & IRQ_PREAMBLE_DET_MASK_6X) != 0) {
-    byte = byte | 0x01 | 0x04;
-    clearbuf[1] = IRQ_PREAMBLE_DET_MASK_6X; // Clear register after reading
+    carrier_detected = true;
+    if (preamble_detected_at == 0) preamble_detected_at = millis();
+    if (millis() - preamble_detected_at > lora_preamble_time_ms + lora_header_time_ms) {
+      preamble_detected_at = 0;
+      uint8_t clearbuf[2] = {0};
+      clearbuf[1] = IRQ_PREAMBLE_DET_MASK_6X;
+      executeOpcode(OP_CLEAR_IRQ_STATUS_6X, clearbuf, 2);
+    }
+    // TODO: Remove
+    digitalWrite(PIN_PREAMBLE, HIGH);
+  } else {
+    digitalWrite(PIN_PREAMBLE, LOW);
   }
 
   if ((buf[1] & IRQ_HEADER_DET_MASK_6X) != 0) {
-    byte = byte | 0x02 | 0x04;
+    carrier_detected = true;
+    header_detected_at = millis();
+    // TODO: Remove
+    digitalWrite(PIN_HEADER, HIGH);
+  } else {
+    digitalWrite(PIN_HEADER, LOW);
   }
 
-  executeOpcode(OP_CLEAR_IRQ_STATUS_6X, clearbuf, 2);
-  return byte; 
+  return carrier_detected;
 }
 
-
 uint8_t sx126x::currentRssiRaw() {
   uint8_t byte = 0;
   executeOpcodeRead(OP_CURRENT_RSSI_6X, &byte, 1);
index 1edf75089ad1346337fb971b4b0c15b348fa54f5..1703a8fb08f1e263c6f72560207edd26b01c1048 100644 (file)
--- a/sx126x.h
+++ b/sx126x.h
@@ -68,7 +68,7 @@ public:
   void setCodingRate4(int denominator);
   void setPreambleLength(long preamble_symbols);
   void setSyncWord(uint16_t sw);
-  uint8_t modemStatus();
+  bool dcd();
   void enableCrc();
   void disableCrc();
   void enableTCXO();