ソースを参照

* repeater and room server: new CLI setting "agc.reset.interval" (seconds)

Scott Powell 1 年間 前
コミット
32ca3dc9d0

+ 3 - 0
examples/simple_repeater/main.cpp

@@ -337,6 +337,9 @@ protected:
   int getInterferenceThreshold() const override {
     return _prefs.interference_threshold;
   }
+  int getAGCResetInterval() const override {
+    return ((int)_prefs.agc_reset_interval) * 4000;   // milliseconds
+  }
 
   void onAnonDataRecv(mesh::Packet* packet, uint8_t type, const mesh::Identity& sender, uint8_t* data, size_t len) override {
     if (type == PAYLOAD_TYPE_ANON_REQ) {  // received an initial request by a possible admin client (unknown at this stage)

+ 3 - 0
examples/simple_room_server/main.cpp

@@ -420,6 +420,9 @@ protected:
   int getInterferenceThreshold() const override {
     return _prefs.interference_threshold;
   }
+  int getAGCResetInterval() const override {
+    return ((int)_prefs.agc_reset_interval) * 4000;   // milliseconds
+  }
 
   bool allowPacketForward(const mesh::Packet* packet) override {
     if (_prefs.disable_fwd) return false;

+ 8 - 0
src/Dispatcher.cpp

@@ -87,6 +87,14 @@ void Dispatcher::loop() {
     } else {
       return;  // can't do any more radio activity until send is complete or timed out
     }
+
+    // going back into receive mode now...
+    next_agc_reset_time = futureMillis(getAGCResetInterval());
+  }
+
+  if (millisHasNowPassed(next_agc_reset_time)) {
+    _radio->resetAGC();
+    next_agc_reset_time = futureMillis(getAGCResetInterval());
   }
 
   // check inbound (delayed) queue

+ 5 - 2
src/Dispatcher.h

@@ -65,6 +65,8 @@ public:
 
   virtual void triggerNoiseFloorCalibrate(int threshold) { }
 
+  virtual void resetAGC() { }
+
   virtual bool isInRecvMode() const = 0;
 
   /**
@@ -116,7 +118,7 @@ class Dispatcher {
   unsigned long next_tx_time;
   unsigned long cad_busy_start;
   unsigned long radio_nonrx_start;
-  unsigned long next_floor_calib_time;
+  unsigned long next_floor_calib_time, next_agc_reset_time;
   bool  prev_isrecv_mode;
   uint32_t n_sent_flood, n_sent_direct;
   uint32_t n_recv_flood, n_recv_direct;
@@ -134,7 +136,7 @@ protected:
   {
     outbound = NULL; total_air_time = 0; next_tx_time = 0;
     cad_busy_start = 0;
-    next_floor_calib_time = 0;
+    next_floor_calib_time = next_agc_reset_time = 0;
     _err_flags = 0;
     radio_nonrx_start = 0;
     prev_isrecv_mode = true;
@@ -154,6 +156,7 @@ protected:
   virtual uint32_t getCADFailRetryDelay() const;
   virtual uint32_t getCADFailMaxDuration() const;
   virtual int getInterferenceThreshold() const { return 0; }    // disabled by default
+  virtual int getAGCResetInterval() const { return 0; }    // disabled by default
 
 public:
   void begin();

+ 10 - 2
src/helpers/CommonCLI.cpp

@@ -53,7 +53,8 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
     file.read((uint8_t *) &_prefs->allow_read_only, sizeof(_prefs->allow_read_only));  // 114
     file.read((uint8_t *) &_prefs->reserved2, sizeof(_prefs->reserved2));  // 115
     file.read((uint8_t *) &_prefs->bw, sizeof(_prefs->bw));  // 116
-    file.read(pad, 4);   // 120
+    file.read((uint8_t *) &_prefs->agc_reset_interval, sizeof(_prefs->agc_reset_interval));  // 120
+    file.read(pad, 3);   // 121
     file.read((uint8_t *) &_prefs->flood_max, sizeof(_prefs->flood_max));   // 124
     file.read((uint8_t *) &_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval));  // 125
     file.read((uint8_t *) &_prefs->interference_threshold, sizeof(_prefs->interference_threshold));  // 126
@@ -107,7 +108,8 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
     file.write((uint8_t *) &_prefs->allow_read_only, sizeof(_prefs->allow_read_only));  // 114
     file.write((uint8_t *) &_prefs->reserved2, sizeof(_prefs->reserved2));  // 115
     file.write((uint8_t *) &_prefs->bw, sizeof(_prefs->bw));  // 116
-    file.write(pad, 4);   // 120
+    file.write((uint8_t *) &_prefs->agc_reset_interval, sizeof(_prefs->agc_reset_interval));  // 120
+    file.write(pad, 3);   // 121
     file.write((uint8_t *) &_prefs->flood_max, sizeof(_prefs->flood_max));   // 124
     file.write((uint8_t *) &_prefs->flood_advert_interval, sizeof(_prefs->flood_advert_interval));  // 125
     file.write((uint8_t *) &_prefs->interference_threshold, sizeof(_prefs->interference_threshold));  // 126
@@ -180,6 +182,8 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
         sprintf(reply, "> %s", StrHelper::ftoa(_prefs->airtime_factor));
       } else if (memcmp(config, "int.thresh", 10) == 0) {
         sprintf(reply, "> %d", (uint32_t) _prefs->interference_threshold);
+      } else if (memcmp(config, "agc.reset.interval", 18) == 0) {
+        sprintf(reply, "> %d", ((uint32_t) _prefs->agc_reset_interval) * 4);
       } else if (memcmp(config, "allow.read.only", 15) == 0) {
         sprintf(reply, "> %s", _prefs->allow_read_only ? "on" : "off");
       } else if (memcmp(config, "flood.advert.interval", 21) == 0) {
@@ -231,6 +235,10 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
         _prefs->interference_threshold = atoi(&config[11]);
         savePrefs();
         strcpy(reply, "OK");
+      } else if (memcmp(config, "agc.reset.interval ", 19) == 0) {
+        _prefs->agc_reset_interval = atoi(&config[19]) / 4;
+        savePrefs();
+        strcpy(reply, "OK");
       } else if (memcmp(config, "allow.read.only ", 16) == 0) {
         _prefs->allow_read_only = memcmp(&config[16], "on", 2) == 0;
         savePrefs();

+ 1 - 0
src/helpers/CommonCLI.h

@@ -25,6 +25,7 @@ struct NodePrefs {  // persisted to file
     float bw;
     uint8_t flood_max;
     uint8_t interference_threshold;
+    uint8_t agc_reset_interval;   // secs / 4
 };
 
 class CommonCLICallbacks {

+ 9 - 0
src/helpers/RadioLibWrappers.cpp

@@ -52,6 +52,15 @@ void RadioLibWrapper::triggerNoiseFloorCalibrate(int threshold) {
   }
 }
 
+void RadioLibWrapper::resetAGC() {
+  // make sure we're not mid-receive of packet!
+  if ((state & STATE_INT_READY) != 0 || isReceivingPacket()) return;
+
+  // NOTE: according to higher powers, just issuing RadioLib's startReceive() will reset the AGC.
+  //      revisit this if a better impl is discovered.
+  state = STATE_IDLE;   // trigger a startReceive()
+}
+
 void RadioLibWrapper::loop() {
   if (state == STATE_RX && _num_floor_samples < NUM_NOISE_FLOOR_SAMPLES) {
     if (!isReceivingPacket()) {

+ 1 - 0
src/helpers/RadioLibWrappers.h

@@ -39,6 +39,7 @@ public:
 
   int getNoiseFloor() const override { return _noise_floor; }
   void triggerNoiseFloorCalibrate(int threshold) override;
+  void resetAGC() override;
 
   void loop() override;