]> git.tnoah.ca Git - lora-radio.git/commitdiff
Fix race condition on multiple interfaces receiving at once
authorjacob.eva <x00010@disroot.org>
Wed, 4 Sep 2024 16:37:09 +0000 (17:37 +0100)
committerjacob.eva <x00010@disroot.org>
Wed, 4 Sep 2024 16:37:09 +0000 (17:37 +0100)
Config.h
RNode_Firmware_CE.ino
Radio.cpp
Radio.hpp

index aa862baf82c31ad357331e9e44f2f1011b6cc715..7fe2140e31a0a7c49b15e0c576ec3edeb0e1d802 100644 (file)
--- a/Config.h
+++ b/Config.h
@@ -28,6 +28,8 @@
        #define CABLE_STATE_DISCONNECTED 0x00
        #define CABLE_STATE_CONNECTED    0x01
        uint8_t cable_state = CABLE_STATE_DISCONNECTED;
+
+    #define MAX_INTERFACES 12
        
        #define BT_STATE_NA        0xff
        #define BT_STATE_OFF       0x00
        uint8_t seq                             = 0xFF;
        uint16_t read_len               = 0;
 
+
+    FIFOBuffer packet_rdy_interfaces;
+
+    uint8_t packet_rdy_interfaces_buf[MAX_INTERFACES];
+
        // Incoming packet buffer
        uint8_t pbuf[MTU];
 
index c45eace2f233207de43f99d3cb28593f8a127614..e208b5c42667cb32e421ac60a3e333b9ce7f4081 100644 (file)
@@ -66,9 +66,6 @@ char sbuf[128];
 
 bool packet_ready = false;
 
-volatile bool process_packet = false;
-volatile uint8_t packet_interface = 0;
-
 uint8_t *packet_queue[INTERFACE_COUNT];
 
 void setup() {
@@ -140,6 +137,10 @@ void setup() {
       packet_queue[i] = (uint8_t*)malloc(getQueueSize(i)+1);
   }
 
+  memset(packet_rdy_interfaces_buf, 0, sizeof(packet_rdy_interfaces_buf));
+
+  fifo_init(&packet_rdy_interfaces, packet_rdy_interfaces_buf, MAX_INTERFACES);
+
   // Create and configure interface objects
   for (uint8_t i = 0; i < INTERFACE_COUNT; i++) {
       switch (interfaces[i]) {
@@ -330,7 +331,7 @@ inline void getPacketData(RadioInterface* radio, uint16_t len) {
   }
 }
 
-void ISR_VECT receive_callback(uint8_t index, int packet_size) {
+void receive_callback(uint8_t index, int packet_size) {
   if (!promisc) {
     selected_radio = interface_obj[index];
 
@@ -399,6 +400,24 @@ void ISR_VECT receive_callback(uint8_t index, int packet_size) {
     getPacketData(selected_radio, packet_size);
     packet_ready = true;
   }
+
+  if (packet_ready) {
+        #if MCU_VARIANT == MCU_ESP32
+        portENTER_CRITICAL(&update_lock);
+        #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(index);
+  }
   last_rx = millis();
 }
 
@@ -1170,25 +1189,6 @@ void loop() {
 
   // If at least one radio is online then we can continue
   if (ready) {
-      if (packet_ready) {
-        selected_radio = interface_obj[packet_interface];
-        #if MCU_VARIANT == MCU_ESP32
-        portENTER_CRITICAL(&update_lock);
-        #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);
-      }
-        
     for (int i = 0; i < INTERFACE_COUNT; i++) {
         selected_radio = interface_obj_sorted[i];
 
@@ -1321,23 +1321,13 @@ void poll_buffers() {
 }
 
 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];
+    while (!fifo_isempty(&packet_rdy_interfaces)) {
+        uint8_t packet_int = fifo_pop(&packet_rdy_interfaces);
+        selected_radio = interface_obj[packet_int];
         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;
index cb949c299130f3aec9497a2463b56d24b9d4fb06..6b2557fb47858ac8db38c473ca4da6122c0322d4 100644 (file)
--- a/Radio.cpp
+++ b/Radio.cpp
@@ -88,8 +88,7 @@
 #define FREQ_DIV_6X (double)pow(2.0, 25.0)
 #define FREQ_STEP_6X (double)(XTAL_FREQ_6X / FREQ_DIV_6X)
 
-extern bool process_packet;
-extern uint8_t packet_interface;
+extern FIFOBuffer packet_rdy_interfaces;
 extern RadioInterface* interface_obj[];
 
 // ISRs cannot provide parameters to the functions they call. Since we have
@@ -99,9 +98,7 @@ extern RadioInterface* interface_obj[];
 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;
-            break;
+            fifo_push(&packet_rdy_interfaces, i);
         }
     }
 }
index fa42abdd76e72b3eb7d8ab06739b7fff1e7ddd12..44ce5a9a2ce4a4b6fd7202be86e85a428f70c1a3 100644 (file)
--- a/Radio.hpp
+++ b/Radio.hpp
@@ -11,6 +11,7 @@
 #include <SPI.h>
 #include "Interfaces.h"
 #include "Boards.h"
+#include "src/misc/FIFOBuffer.h"
 
 #define MAX_PKT_LENGTH                255