]> git.tnoah.ca Git - lora-radio.git/commitdiff
Fix various SX1280 issues, revamp RX ISR flow
authorjacob.eva <x00010@disroot.org>
Wed, 3 Jul 2024 10:06:52 +0000 (11:06 +0100)
committerjacob.eva <x00010@disroot.org>
Wed, 3 Jul 2024 10:06:52 +0000 (11:06 +0100)
Boards.h
Config.h
Display.h
RNode_Firmware_CE.ino
Radio.cpp
Radio.h
Utilities.h

index 7321269af93dac4fb9aaeecfc731135af4db7985..8af9fab9beb97ff717656c0544c0fcdb5a326112 100644 (file)
--- a/Boards.h
+++ b/Boards.h
       #define HAS_PMU true
       #define HAS_NP false
       #define HAS_SD false
-      #define HAS_RF_SWITCH_RX_TX true
       #define CONFIG_UART_BUFFER_SIZE 6144
-      #define CONFIG_QUEUE_SIZE 6144
+      #define CONFIG_QUEUE_0_SIZE 6144
       #define CONFIG_QUEUE_MAX_LENGTH 200
       #define EEPROM_SIZE 296
       #define EEPROM_OFFSET EEPROM_SIZE-EEPROM_RESERVED
               true  // DIO2_AS_RF_SWITCH
           }
       };
-      const uint8_t interface_pins[INTERFACE_COUNT][10] = { 
+      const int8_t interface_pins[INTERFACE_COUNT][10] = { 
                   // SX1262
           {
               42, // pin_ss
index f0bb09c01234542de148f906df3738825f14c1d0..53e985f2e36aaafb67dd7e730fd669b30f83e8f8 100644 (file)
--- a/Config.h
+++ b/Config.h
        uint32_t stat_rx                = 0;
        uint32_t stat_tx                = 0;
 
+    unsigned long last_tx   = 0;
+    unsigned long last_rx   = 0;
+
     // Power management
     #define BATTERY_STATE_DISCHARGING 0x01
     #define BATTERY_STATE_CHARGING 0x02
index 54f53b291a60d69b73cfeefb3085123c9276c54e..9bc0098a2a7c66b8795e60609fe36b2bc12358e1 100644 (file)
--- a/Display.h
+++ b/Display.h
@@ -143,6 +143,10 @@ const uint8_t pages = 3;
 uint8_t disp_page = START_PAGE;
 uint8_t interface_page = START_PAGE;
 
+uint8_t* online_interface_list;
+
+uint8_t online_interfaces = 0;
+
 #if DISPLAY == OLED
 #define WATERFALL_SIZE 46
 #elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
@@ -369,7 +373,7 @@ void draw_lora_icon(RadioInterface* radio, int px, int py) {
   // todo: make display show other interfaces
   if (radio_online) {
         #if DISPLAY == OLED
-                if (interface_page == radio->getIndex()) {
+                if (online_interface_list[interface_page] == radio->getIndex()) {
                     stat_area.drawBitmap(px - 2, py - 2, bm_dot_sqr, 18, 18, GxEPD_WHITE, GxEPD_BLACK);
 
                     // redraw stat area on next refresh
@@ -381,7 +385,7 @@ void draw_lora_icon(RadioInterface* radio, int px, int py) {
                 stat_area.drawBitmap(px, py, bm_rf+0*32, 16, 16, GxEPD_WHITE, GxEPD_BLACK);
                   }
         #elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
-                if (interface_page == radio->getIndex()) {
+                if (online_interface_list[interface_page] == radio->getIndex()) {
                     stat_area.drawBitmap(px - 2, py - 2, bm_dot_sqr, 34, 36, GxEPD_WHITE, GxEPD_BLACK);
 
                     // redraw stat area on next refresh
@@ -666,19 +670,38 @@ void draw_stat_area() {
     }
 
     if (millis()-last_interface_page_flip >= page_interval) {
-      int online_interfaces = 0;
+      int online_interfaces_check = 0;
+
+      // todo, is there a more efficient way of doing this?
       for (int i = 0; i < INTERFACE_COUNT; i++) {
           if (interface_obj[i]->getRadioOnline()) {
-              online_interfaces++;
+              online_interfaces_check++;
           }
       }
 
+      if (online_interfaces != online_interfaces_check) {
+          online_interfaces = online_interfaces_check;
+      }
+
       // cap at two for now, as only two boxes to symbolise interfaces
       // available on display
       if (online_interfaces > 2) {
           online_interfaces = 2;
       }
-      interface_page = (++interface_page%online_interfaces);
+
+      online_interface_list = (uint8_t*)malloc(online_interfaces);
+      uint8_t index = 0;
+
+      for (int i = 0; i < INTERFACE_COUNT; i++) {
+          if (interface_obj[i]->getRadioOnline()) {
+              online_interface_list[index] = i;
+              index++;
+          }
+      }
+
+      if (online_interfaces > 0) {
+          interface_page = (++interface_page%online_interfaces);
+      }
       last_interface_page_flip = millis();
     }
 
@@ -789,7 +812,7 @@ void draw_disp_area() {
     if (!disp_ext_fb or bt_ssp_pin != 0) {
       if (radio_online && display_diagnostics) {
         #if DISPLAY == OLED
-          selected_radio = interface_obj[interface_page];
+          selected_radio = interface_obj[online_interface_list[interface_page]];
           disp_area.fillRect(0,8,disp_area.width(),37, SSD1306_BLACK); disp_area.fillRect(0,37,disp_area.width(),27, SSD1306_WHITE);
           disp_area.setFont(SMALL_FONT); disp_area.setTextWrap(false); disp_area.setTextColor(SSD1306_WHITE);
 
@@ -845,7 +868,7 @@ void draw_disp_area() {
           disp_area.drawBitmap(32+2, 50, bm_hg_high, 5, 9, SSD1306_BLACK, SSD1306_WHITE);
 
         #elif DISP_H == 122 && (DISPLAY == EINK_BW || DISPLAY == EINK_3C)
-          selected_radio = interface_obj[interface_page];
+          selected_radio = interface_obj[online_interface_list[interface_page]];
           disp_area.fillRect(0,12,disp_area.width(),57, GxEPD_BLACK); disp_area.fillRect(0,69,disp_area.width(),56, GxEPD_WHITE);
           disp_area.setFont(SMALL_FONT); disp_area.setTextWrap(false); disp_area.setTextColor(GxEPD_WHITE);
           disp_area.setTextSize(2); // scale text 2x
@@ -1096,6 +1119,7 @@ void update_display(bool blank = false) {
       update_disp_area();
       display.display(true);
       #endif
+      free(online_interface_list);
       last_disp_update = millis();
     }
   }
index cc4630b6f6fa0b76a5d3e7846c5a43ad71f685da..ef9fe1dedcc92a155ff5b78d0ac42daf9a5e3486 100644 (file)
 FIFOBuffer serialFIFO;
 uint8_t serialBuffer[CONFIG_UART_BUFFER_SIZE+1];
 
-uint16_t packet_starts_buf[(CONFIG_QUEUE_MAX_LENGTH/INTERFACE_COUNT)+1];
+uint16_t packet_starts_buf[(CONFIG_QUEUE_MAX_LENGTH)+1];
 
-uint16_t packet_lengths_buf[(CONFIG_QUEUE_MAX_LENGTH/INTERFACE_COUNT)+1];
+uint16_t packet_lengths_buf[(CONFIG_QUEUE_MAX_LENGTH)+1];
 
 FIFOBuffer16 packet_starts[INTERFACE_COUNT];
 FIFOBuffer16 packet_lengths[INTERFACE_COUNT];
 
-// The total queue size is split evenly between all the interfaces.
-// todo, bias in size may be needed here for interfaces with higher data rates.
-uint8_t packet_queue[INTERFACE_COUNT][CONFIG_QUEUE_SIZE/INTERFACE_COUNT];
-
 volatile uint8_t queue_height[INTERFACE_COUNT] = {0};
 volatile uint16_t queued_bytes[INTERFACE_COUNT] = {0};
 
@@ -48,7 +44,11 @@ volatile bool serial_buffering = false;
 char sbuf[128];
 
 bool packet_ready = false;
-uint8_t packet_interface;
+
+volatile bool process_packet = false;
+volatile uint8_t packet_interface = 0;
+
+uint8_t *packet_queue[INTERFACE_COUNT];
 
 void setup() {
   #if MCU_VARIANT == MCU_ESP32
@@ -112,11 +112,11 @@ void setup() {
   
   memset(packet_starts_buf, 0, sizeof(packet_starts_buf));
   memset(packet_lengths_buf, 0, sizeof(packet_starts_buf));
-  memset(packet_queue, 0, sizeof(packet_queue));
 
   for (int i = 0; i < INTERFACE_COUNT; i++) {
-      fifo16_init(&packet_starts[i], packet_starts_buf, CONFIG_QUEUE_MAX_LENGTH/INTERFACE_COUNT);
-      fifo16_init(&packet_lengths[i], packet_lengths_buf, CONFIG_QUEUE_MAX_LENGTH/INTERFACE_COUNT);
+      fifo16_init(&packet_starts[i], packet_starts_buf, CONFIG_QUEUE_MAX_LENGTH);
+      fifo16_init(&packet_lengths[i], packet_lengths_buf, CONFIG_QUEUE_MAX_LENGTH);
+      packet_queue[i] = (uint8_t*)malloc(getQueueSize(i));
   }
 
   // Create and configure interface objects
@@ -378,6 +378,7 @@ void ISR_VECT receive_callback(uint8_t index, int packet_size) {
     getPacketData(selected_radio, packet_size);
     packet_ready = true;
   }
+  last_rx = millis();
 }
 
 bool startRadio(RadioInterface* radio) {
@@ -442,7 +443,7 @@ void update_radio_lock(RadioInterface* radio) {
 // Check if the queue is full for the selected radio.
 // Returns true if full, false if not
 bool queueFull(RadioInterface* radio) {
-  return (queue_height[radio->getIndex()] >= (CONFIG_QUEUE_MAX_LENGTH/INTERFACE_COUNT) || queued_bytes[radio->getIndex()] >= (CONFIG_QUEUE_SIZE/INTERFACE_COUNT));
+  return (queue_height[radio->getIndex()] >= (CONFIG_QUEUE_MAX_LENGTH) || queued_bytes[radio->getIndex()] >= (getQueueSize(radio->getIndex())));
 }
 
 volatile bool queue_flushing = false;
@@ -463,7 +464,7 @@ void flushQueue(RadioInterface* radio) {
 
       if (length >= MIN_L && length <= MTU) {
         for (uint16_t i = 0; i < length; i++) {
-          uint16_t pos = (start+i)%(CONFIG_QUEUE_SIZE/INTERFACE_COUNT);
+          uint16_t pos = (start+i)%(getQueueSize(index));
           tbuf[i] = packet_queue[index][pos];
         }
         transmit(radio, length);
@@ -538,6 +539,7 @@ void transmit(RadioInterface* radio, uint16_t size) {
       }
       radio->endPacket(); radio->addAirtime(written);
     }
+    last_tx = millis();
   } else {
     kiss_indicate_error(ERROR_TXFAILED);
     led_indicate_error(5);
@@ -562,13 +564,13 @@ void serialCallback(uint8_t sbyte) {
 
     if (getInterfaceIndex(command) < INTERFACE_COUNT) {
             uint8_t index = getInterfaceIndex(command);
-        if (!fifo16_isfull(&packet_starts[index]) && queued_bytes[index] < (CONFIG_QUEUE_SIZE/INTERFACE_COUNT)) {
+        if (!fifo16_isfull(&packet_starts[index]) && queued_bytes[index] < (getQueueSize(index))) {
             uint16_t s = current_packet_start[index];
-            int16_t e = queue_cursor[index]-1; if (e == -1) e = (CONFIG_QUEUE_SIZE/INTERFACE_COUNT)-1;
+            int16_t e = queue_cursor[index]-1; if (e == -1) e = (getQueueSize(index))-1;
             uint16_t l;
 
             if (s != e) {
-                l = (s < e) ? e - s + 1: (CONFIG_QUEUE_SIZE/INTERFACE_COUNT) - s + e + 1;
+                l = (s < e) ? e - s + 1: (getQueueSize(index)) - s + e + 1;
             } else {
                 l = 1;
             }
@@ -631,10 +633,10 @@ void serialCallback(uint8_t sbyte) {
 
             if (getInterfaceIndex(command) < INTERFACE_COUNT) {
                     uint8_t index = getInterfaceIndex(command);
-                if (queue_height[index] < (CONFIG_QUEUE_MAX_LENGTH/INTERFACE_COUNT) && queued_bytes[index] < (CONFIG_QUEUE_SIZE/INTERFACE_COUNT)) {
+                if (queue_height[index] < CONFIG_QUEUE_MAX_LENGTH && queued_bytes[index] < (getQueueSize(index))) {
                   queued_bytes[index]++;
                   packet_queue[index][queue_cursor[index]++] = sbyte;
-                  if (queue_cursor[index] == (CONFIG_QUEUE_SIZE/INTERFACE_COUNT)) queue_cursor[index] = 0;
+                  if (queue_cursor[index] == (getQueueSize(index))) queue_cursor[index] = 0;
                 }
             }
         }
@@ -1133,44 +1135,40 @@ void validate_status() {
   }
 }
 
-
 void loop() {
+      packet_poll();
+
     bool ready = false;
-  for (int i = 0; i < INTERFACE_COUNT; i++) {
-      selected_radio = interface_obj[i];
-      if (selected_radio->getRadioOnline()) {
-          selected_radio->checkModemStatus();
-          ready = true;
-      }
-  }
+    for (int i = 0; i < INTERFACE_COUNT; i++) {
+        selected_radio = interface_obj[i];
+        if (selected_radio->getRadioOnline()) {
+            selected_radio->checkModemStatus();
+            ready = true;
+        }
+    }
+
 
-  // if at least one radio is online then we can continue
+  // If at least one radio is online then we can continue
   if (ready) {
-    #if MCU_VARIANT == MCU_ESP32
       if (packet_ready) {
         selected_radio = interface_obj[packet_interface];
+        #if MCU_VARIANT == MCU_ESP32
         portENTER_CRITICAL(&update_lock);
-        last_rssi = selected_radio->packetRssi();
-        last_snr_raw = selected_radio->packetSnrRaw();
-        portEXIT_CRITICAL(&update_lock);
-        kiss_indicate_stat_rssi();
-        kiss_indicate_stat_snr();
-        kiss_write_packet(packet_interface);
-      }
-
-    #elif MCU_VARIANT == MCU_NRF52
-      if (packet_ready) {
-        selected_radio = interface_obj[packet_interface];
+        #elif MCU_VARIANT == MCU_NRF52
         portENTER_CRITICAL();
+        #endif
         last_rssi = selected_radio->packetRssi();
         last_snr_raw = selected_radio->packetSnrRaw();
+        #if MCU_VARIANT == MCU_ESP32
+        portEXIT_CRITICAL(&update_lock);
+        #elif MCU_VARIANT == MCU_NRF52
         portEXIT_CRITICAL();
+        #endif
         kiss_indicate_stat_rssi();
         kiss_indicate_stat_snr();
         kiss_write_packet(packet_interface);
       }
-    #endif
-
+        
     for (int i = 0; i < INTERFACE_COUNT; i++) {
         selected_radio = interface_obj_sorted[i];
 
@@ -1182,13 +1180,11 @@ void loop() {
         // If a higher data rate interface has received a packet after its
         // loop, it still needs to be the first to transmit, so check if this
         // is the case.
-        if (i != 0) {
-            for (int j = 0; j < INTERFACE_COUNT; j++) {
-                if (!interface_obj_sorted[j]->calculateALock() || interface_obj_sorted[j]->getRadioOnline()) {
-                    if (interface_obj_sorted[j]->getBitrate() > selected_radio->getBitrate()) {
-                        if (queue_height[interface_obj_sorted[j]->getIndex()] > 0) {
-                            selected_radio = interface_obj_sorted[j];
-                        }
+        for (int j = 0; j < INTERFACE_COUNT; j++) {
+            if (!interface_obj_sorted[j]->calculateALock() || interface_obj_sorted[j]->getRadioOnline()) {
+                if (interface_obj_sorted[j]->getBitrate() > selected_radio->getBitrate()) {
+                    if (queue_height[interface_obj_sorted[j]->getIndex()] > 0) {
+                        selected_radio = interface_obj_sorted[j];
                     }
                 }
             }
@@ -1241,7 +1237,24 @@ void loop() {
   if (!fifo_isempty(&serialFIFO)) serial_poll();
 
   #if HAS_DISPLAY
+    #if DISPLAY == OLED
     if (disp_ready) update_display();
+    #elif DISPLAY == EINK_BW || DISPLAY == EINK_3C
+    // Display refreshes take so long on e-paper displays that they can disrupt
+    // the regular operation of the device. To combat this the time it is
+    // chosen to do so must be strategically chosen. Particularly on the
+    // RAK4631, the display and the potentially installed SX1280 modem share
+    // the same SPI bus. Thus it is not possible to solve this by utilising the
+    // callback functionality to poll the modem in this case. todo, this may be
+    // able to be improved in the future.
+    if (disp_ready) {
+        if (millis() - last_tx >= 4000) {
+            if (millis() - last_rx >= 1000) {
+                update_display();
+            }
+        }
+    }
+    #endif
   #endif
 
   #if HAS_PMU
@@ -1283,6 +1296,30 @@ void button_event(uint8_t event, unsigned long duration) {
   }
 }
 
+void poll_buffers() {
+    process_serial();
+}
+
+void packet_poll() {
+    #if MCU_VARIANT == MCU_ESP32
+    portENTER_CRITICAL(&update_lock);
+    #elif MCU_VARIANT == MCU_NRF52
+    portENTER_CRITICAL();
+    #endif
+    // If we have received a packet on an interface which needs to be processed
+    if (process_packet) {
+        selected_radio = interface_obj[packet_interface];
+        selected_radio->clearIRQStatus();
+        selected_radio->handleDio0Rise();
+        process_packet = false;
+    }
+    #if MCU_VARIANT == MCU_ESP32
+    portEXIT_CRITICAL(&update_lock);
+    #elif MCU_VARIANT == MCU_NRF52
+    portEXIT_CRITICAL();
+    #endif
+}
+
 volatile bool serial_polling = false;
 void serial_poll() {
   serial_polling = true;
index d1ee1c4eeb6e06ac28e420a51d6edf7d70a55006..f7bd4fc502fca080f7ed0b42f49dfce6b6a0e683 100644 (file)
--- a/Radio.cpp
+++ b/Radio.cpp
@@ -15,8 +15,6 @@
   #define ISR_VECT
 #endif
 
-#define MAX_PKT_LENGTH                255
-
 // SX126x registers
 #define OP_RF_FREQ_6X               0x86
 #define OP_SLEEP_6X                 0x84
 #define FREQ_DIV_6X (double)pow(2.0, 25.0)
 #define FREQ_STEP_6X (double)(XTAL_FREQ_6X / FREQ_DIV_6X)
 
-extern int packet_interface;
+extern bool process_packet;
+extern uint8_t packet_interface;
 extern RadioInterface* interface_obj[];
 
 // ISRs cannot provide parameters to the functions they call. Since we have
-// multiple radio objects, we have to read each dio0 pin for each one and see
+// multiple interfaces, we have to read each dio0 pin for each one and see
 // which one is high. We can then use the index of this pin in the 2D array to
-// call the correct object.
-void onDio0Rise() {
+// signal the correct interface to the main loop 
+void ISR_VECT onDio0Rise() {
     for (int i = 0; i < INTERFACE_COUNT; i++) {
         if (digitalRead(interface_pins[i][5]) == HIGH) {
+            process_packet = true;
             packet_interface = i;
-            RadioInterface* obj = interface_obj[i];
-            obj->handleDio0Rise();
             break;
         }
     }
@@ -110,14 +108,13 @@ void onDio0Rise() {
 
 sx126x::sx126x(uint8_t index, SPIClass spi, bool tcxo, bool dio2_as_rf_switch, int ss, int sclk, int mosi, int miso, int reset, int dio0, int busy, int rxen) :
   RadioInterface(index),
-    _spiSettings(8E6, MSBFIRST, SPI_MODE0),
-    _spiModem(spi),
-  _ss(ss), _sclk(sclk), _mosi(mosi), _miso(miso), _reset(reset), _dio0(dio0),
-  _busy(busy), _rxen(rxen), _frequency(0), _txp(0), _sf(0x07), _bw(0x04),
-  _cr(0x01), _ldro(0x00), _packetIndex(0), _implicitHeaderMode(0),
-  _payloadLength(255), _crcMode(1), _fifo_tx_addr_ptr(0), _fifo_rx_addr_ptr(0),
-  _packet({0}), _preinit_done(false), _tcxo(tcxo),
-  _dio2_as_rf_switch(dio2_as_rf_switch)
+    _spiSettings(8E6, MSBFIRST, SPI_MODE0), _spiModem(spi), _ss(ss),
+    _sclk(sclk), _mosi(mosi), _miso(miso), _reset(reset), _dio0(dio0),
+    _busy(busy), _rxen(rxen), _frequency(0), _txp(0), _sf(0x07), _bw(0x04),
+    _cr(0x01), _ldro(0x00), _packetIndex(0), _implicitHeaderMode(0),
+    _payloadLength(255), _crcMode(1), _fifo_tx_addr_ptr(0),
+    _fifo_rx_addr_ptr(0), _preinit_done(false), _tcxo(tcxo),
+    _dio2_as_rf_switch(dio2_as_rf_switch)
 {
   // overide Stream timeout value
   setTimeout(0);
@@ -966,7 +963,7 @@ void sx126x::implicitHeaderMode()
 }
 
 
-void ISR_VECT sx126x::handleDio0Rise()
+void sx126x::handleDio0Rise()
 {
     uint8_t buf[2];
 
@@ -1017,6 +1014,16 @@ void sx126x::updateBitrate() {
     }
 }
 
+void sx126x::clearIRQStatus() {
+    uint8_t buf[2];
+
+    buf[0] = 0x00;
+    buf[1] = 0x00;
+
+    executeOpcodeRead(OP_GET_IRQ_STATUS_6X, buf, 2);
+
+    executeOpcode(OP_CLEAR_IRQ_STATUS_6X, buf, 2);
+}
 // SX127x registers
 #define REG_FIFO_7X                   0x00
 #define REG_OP_MODE_7X                0x01
@@ -1507,7 +1514,7 @@ void sx127x::optimizeModemSensitivity() {
   }
 }
 
-void ISR_VECT sx127x::handleDio0Rise() {
+void sx127x::handleDio0Rise() {
   int irqFlags = readRegister(REG_IRQ_FLAGS_7X);
 
   // Clear IRQs
@@ -1542,6 +1549,10 @@ void sx127x::updateBitrate() {
     }
 }
 
+void sx127x::clearIRQStatus() {
+    // todo, implement
+}
+
 // SX128x registers
 #define OP_RF_FREQ_8X               0x86
 #define OP_SLEEP_8X                 0x84
@@ -1590,10 +1601,10 @@ sx128x::sx128x(uint8_t index, SPIClass spi, bool tcxo, int ss, int sclk, int mos
     _spiSettings(8E6, MSBFIRST, SPI_MODE0),
     _spiModem(spi),
   _ss(ss), _sclk(sclk), _mosi(mosi), _miso(miso), _reset(reset), _dio0(dio0),
-  _busy(busy), _rxen(rxen), _txen(txen), _frequency(0), _txp(0), _sf(0x50),
+  _busy(busy), _rxen(rxen), _txen(txen), _frequency(0), _txp(0), _sf(0x05),
   _bw(0x34), _cr(0x01), _packetIndex(0), _implicitHeaderMode(0),
   _payloadLength(255), _crcMode(0), _fifo_tx_addr_ptr(0), _fifo_rx_addr_ptr(0),
-  _packet({0}), _rxPacketLength(0), _preinit_done(false),
+  _rxPacketLength(0), _preinit_done(false),
   _tcxo(tcxo)
 {
   // overide Stream timeout value
@@ -2137,7 +2148,7 @@ void sx128x::receive(int size)
     implicitHeaderMode();
 
     // tell radio payload length
-    _rxPacketLength = size;
+    //_rxPacketLength = size;
     //_payloadLength = size;
     //setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode);
   } else {
@@ -2358,7 +2369,7 @@ void sx128x::implicitHeaderMode()
 }
 
 
-void ISR_VECT sx128x::handleDio0Rise()
+void sx128x::handleDio0Rise()
 {
     uint8_t buf[2];
 
@@ -2392,8 +2403,14 @@ void sx128x::updateBitrate() {
         _lora_symbol_time_ms = (1.0/_lora_symbol_rate)*1000.0;
         _bitrate = (uint32_t)(_sf * ( (4.0/(float)(_cr+4)) / ((float)(pow(2, _sf))/((float)getSignalBandwidth()/1000.0)) ) * 1000.0);
         _lora_us_per_byte = 1000000.0/((float)_bitrate/8.0);
-        //_csma_slot_ms = _lora_symbol_time_ms*10;
-        float target_preamble_symbols = (LORA_PREAMBLE_TARGET_MS/_lora_symbol_time_ms)-LORA_PREAMBLE_SYMBOLS_HW;
+        _csma_slot_ms = 10;
+
+        float target_preamble_symbols;
+        if (_bitrate <= LORA_FAST_BITRATE_THRESHOLD) {
+            target_preamble_symbols = (LORA_PREAMBLE_TARGET_MS/_lora_symbol_time_ms)-LORA_PREAMBLE_SYMBOLS_HW;
+        } else {
+            target_preamble_symbols = (LORA_PREAMBLE_FAST_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 {
@@ -2405,3 +2422,14 @@ void sx128x::updateBitrate() {
         _bitrate = 0;
     }
 }
+
+void sx128x::clearIRQStatus() {
+    uint8_t buf[2];
+
+    buf[0] = 0x00;
+    buf[1] = 0x00;
+
+    executeOpcodeRead(OP_GET_IRQ_STATUS_8X, buf, 2);
+
+    executeOpcode(OP_CLEAR_IRQ_STATUS_8X, buf, 2);
+}
diff --git a/Radio.h b/Radio.h
index 94e47bcbc1d4fb7f304ddcc4476b2b3718e36d44..9b88114a1b8d93a19aea1989d5c363deab0eef92 100644 (file)
--- a/Radio.h
+++ b/Radio.h
@@ -12,6 +12,8 @@
 #include "Interfaces.h"
 #include "Boards.h"
 
+#define MAX_PKT_LENGTH                255
+
 // TX
 #define PA_OUTPUT_RFO_PIN 0
 #define PA_OUTPUT_PA_BOOST_PIN 1
@@ -31,6 +33,8 @@
 #define LORA_PREAMBLE_SYMBOLS_HW  4
 #define LORA_PREAMBLE_SYMBOLS_MIN 18
 #define LORA_PREAMBLE_TARGET_MS   15
+#define LORA_PREAMBLE_FAST_TARGET_MS 1
+#define LORA_FAST_BITRATE_THRESHOLD 40000
 
 #define RSSI_OFFSET 157
 
@@ -46,6 +50,7 @@ const uint8_t RX_ONGOING = 0x04;
 
 // forward declare Utilities.h LED functions
 void led_rx_on();
+
 void led_rx_off();
 void led_indicate_airtime_lock();
 
@@ -68,7 +73,7 @@ public:
     _post_tx_yield_timeout(0), _csma_slot_ms(50), _csma_p_min(0.1),
     _csma_p_max(0.8), _preambleLength(6), _lora_symbol_time_ms(0.0),
     _lora_symbol_rate(0.0), _lora_us_per_byte(0.0), _bitrate(0),
-    _onReceive(NULL) {};
+    _onReceive(NULL), _packet{0} {};
     virtual int begin();
     virtual void end();
 
@@ -123,6 +128,7 @@ public:
 
     virtual void updateBitrate();
     virtual void handleDio0Rise();
+    virtual void clearIRQStatus();
     uint32_t getBitrate() { return _bitrate; };
     uint8_t getIndex() { return _index; };
     void setRadioLock(bool lock) { _radio_locked = lock; };
@@ -248,6 +254,7 @@ public:
                   _dcd_count = 0;
               }
           }
+
     
           if (_dcd_led) {
               led_rx_on();
@@ -320,6 +327,7 @@ protected:
     float _lora_symbol_rate;
     float _lora_us_per_byte;
     uint32_t _bitrate;
+  uint8_t _packet[255];
     void (*_onReceive)(uint8_t, int);
 };
 
@@ -413,6 +421,7 @@ private:
   void reset(void);
   void calibrate(void);
   void calibrate_image(uint32_t frequency);
+  void clearIRQStatus();
 
 private:
   SPISettings _spiSettings;
@@ -437,7 +446,6 @@ private:
   int _crcMode;
   int _fifo_tx_addr_ptr;
   int _fifo_rx_addr_ptr;
-  uint8_t _packet[255];
   bool _preinit_done;
   uint8_t _index;
   bool _tcxo;
@@ -503,6 +511,7 @@ public:
   void updateBitrate();
 
   void handleDio0Rise();
+  void clearIRQStatus();
 private:
   void setSyncWord(uint8_t sw);
   void explicitHeaderMode();
@@ -598,6 +607,8 @@ public:
   void updateBitrate();
 
   void handleDio0Rise();
+
+  void clearIRQStatus();
 private:
   void writeBuffer(const uint8_t* buffer, size_t size);
   void readBuffer(uint8_t* buffer, size_t size);
@@ -647,7 +658,6 @@ private:
   int _crcMode;
   int _fifo_tx_addr_ptr;
   int _fifo_rx_addr_ptr;
-  uint8_t _packet[255];
   bool _preinit_done;
   int _rxPacketLength;
   uint8_t _index;
index ef18e7fea480c4238cca49ebed7a345aa9fa6457..8156ea4ae51a9d3e5d9d2bc8f93ca078e30e207a 100644 (file)
@@ -1076,6 +1076,57 @@ uint8_t getInterfaceCommandByte(uint8_t index) {
     }
 }
 
+uint32_t getQueueSize(uint8_t index) {
+    switch (index) {
+        case 0:
+            return CONFIG_QUEUE_0_SIZE;
+        #if INTERFACE_COUNT > 1
+        case 1:
+            return CONFIG_QUEUE_1_SIZE;
+        #endif
+        #if INTERFACE_COUNT > 2
+        case 2:
+            return CONFIG_QUEUE_2_SIZE;
+        #endif
+        #if INTERFACE_COUNT > 3
+        case 3:
+            return CONFIG_QUEUE_3_SIZE;
+        #endif
+        #if INTERFACE_COUNT > 4 
+        case 4:
+            return CONFIG_QUEUE_4_SIZE;
+        #endif
+        #if INTERFACE_COUNT > 5
+        case 5:
+            return CONFIG_QUEUE_5_SIZE;
+        #endif
+        #if INTERFACE_COUNT > 6
+        case 6:
+            return CONFIG_QUEUE_6_SIZE;
+        #endif
+        #if INTERFACE_COUNT > 7
+        case 7:
+            return CONFIG_QUEUE_7_SIZE;
+        #endif
+        #if INTERFACE_COUNT > 8
+        case 8:
+            return CONFIG_QUEUE_8_SIZE;
+        #endif
+        #if INTERFACE_COUNT > 9
+        case 9:
+            return CONFIG_QUEUE_9_SIZE;
+        #endif
+        #if INTERFACE_COUNT > 10
+        case 10:
+            return CONFIG_QUEUE_10_SIZE;
+        #endif
+        #if INTERFACE_COUNT > 11
+        case 11:
+            return CONFIG_QUEUE_11_SIZE;
+        #endif
+    }
+}
+
 void promisc_enable() {
        promisc = true;
 }