Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/mesh/RadioInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,8 @@ class RadioInterface
protected:
int8_t power = 17; // Set by applyModemConfig()

float savedFreq;
uint32_t savedChannelNum;
float savedFreq = 0.0f;
uint32_t savedChannelNum = 0;

/***
* given a packet set sendingPacket and decode the protobufs into radiobuf. Returns # of bytes to send (including the
Expand Down
17 changes: 17 additions & 0 deletions src/mesh/RadioLibInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ RadioLibInterface::RadioLibInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE c
#endif
}

static bool radioFrequencyChanged(float previousFreq, float currentFreq)
{
const float delta = currentFreq - previousFreq;
return delta > 0.000001f || delta < -0.000001f;
}

#ifdef ARCH_ESP32
// ESP32 doesn't use that flag
#define YIELD_FROM_ISR(x) portYIELD_FROM_ISR()
Expand Down Expand Up @@ -228,6 +234,16 @@ bool RadioLibInterface::canSleep()
return res;
}

bool RadioLibInterface::reconfigure()
{
const float previousFreq = getFreq();
bool result = RadioInterface::reconfigure();
if (result && radioFrequencyChanged(previousFreq, getFreq())) {
resetNoiseFloor();
}
return result;
}

/** Allow other firmware components to ask whether we are currently sending a packet
Initially implemented to protect T-Echo's capacitive touch button from spurious presses during tx
*/
Expand Down Expand Up @@ -331,6 +347,7 @@ void RadioLibInterface::resetNoiseFloor()
{
currentSampleIndex = 0;
isNoiseFloorBufferFull = false;
lastNoiseFloorUpdate = 0;
currentNoiseFloor = NOISE_FLOOR_DEFAULT;
LOG_INFO("Noise floor reset - rolling window collection will restart");
}
Expand Down
2 changes: 2 additions & 0 deletions src/mesh/RadioLibInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
RadioLibInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
RADIOLIB_PIN_TYPE busy, PhysicalLayer *iface = NULL);

virtual bool reconfigure() override;

virtual ErrorCode send(meshtastic_MeshPacket *p) override;

/**
Expand Down
101 changes: 99 additions & 2 deletions test/test_radio/test_main.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,54 @@
#include "MeshRadio.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "RadioInterface.h"
#include "RadioLibInterface.h"
#include "TestUtil.h"
#include <SPI.h>
#include <unity.h>

#include "meshtastic/config.pb.h"

class MockMeshService : public MeshService
{
public:
void sendClientNotification(meshtastic_ClientNotification *n) override { releaseClientNotificationToPool(n); }
};

static MockMeshService *mockMeshService;

static LockingArduinoHal *getTestHal()
{
static LockingArduinoHal hal(SPI, SPISettings(1000000, MSBFIRST, SPI_MODE0));
return &hal;
}

class TestableRadioLibInterface : public RadioLibInterface
{
public:
TestableRadioLibInterface() : RadioLibInterface(getTestHal(), RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, nullptr) {}

void seedNoiseFloorForTest()
{
noiseFloorSamples[0] = -110;
currentSampleIndex = 1;
isNoiseFloorBufferFull = false;
lastNoiseFloorUpdate = 1234;
currentNoiseFloor = -110;
}

uint32_t getLastNoiseFloorUpdateForTest() const { return lastNoiseFloorUpdate; }

protected:
void disableInterrupt() override {}
void enableInterrupt(void (*)()) override {}
bool isChannelActive() override { return false; }
bool isActivelyReceiving() override { return false; }
void addReceiveMetadata(meshtastic_MeshPacket *) override {}
uint32_t getPacketTime(uint32_t, bool) override { return 0; }
int16_t getCurrentRSSI() override { return NOISE_FLOOR_DEFAULT; }
};

static void test_bwCodeToKHz_specialMappings()
{
TEST_ASSERT_FLOAT_WITHIN(0.0001f, 31.25f, bwCodeToKHz(31));
Expand Down Expand Up @@ -77,8 +121,59 @@ static void test_bootstrapLoRaConfigFromPreset_fallsBackIfBandwidthExceedsRegion
TEST_ASSERT_EQUAL_UINT32(11, cfg.spread_factor);
}

void setUp(void) {}
void tearDown(void) {}
static void configureLongFastUs(float frequencyOffset = 0.0f)
{
config.lora = meshtastic_Config_LoRaConfig_init_zero;
config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_US;
config.lora.use_preset = true;
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST;
config.lora.frequency_offset = frequencyOffset;
}

static void test_radioLibReconfigureResetsNoiseFloorWhenFrequencyChanges()
{
TestableRadioLibInterface testRadioLib;
configureLongFastUs();
testRadioLib.reconfigure();
testRadioLib.seedNoiseFloorForTest();

config.lora.frequency_offset = 0.125f;
testRadioLib.reconfigure();

TEST_ASSERT_FALSE(testRadioLib.hasNoiseFloorSamples());
TEST_ASSERT_EQUAL_INT32(-120, testRadioLib.getNoiseFloor());
TEST_ASSERT_EQUAL_UINT32(0, testRadioLib.getLastNoiseFloorUpdateForTest());
}

static void test_radioLibReconfigureKeepsNoiseFloorWhenFrequencyUnchanged()
{
TestableRadioLibInterface testRadioLib;
configureLongFastUs();
testRadioLib.reconfigure();
testRadioLib.seedNoiseFloorForTest();

testRadioLib.reconfigure();

TEST_ASSERT_TRUE(testRadioLib.hasNoiseFloorSamples());
TEST_ASSERT_EQUAL_INT32(-110, testRadioLib.getNoiseFloor());
TEST_ASSERT_EQUAL_UINT32(1234, testRadioLib.getLastNoiseFloorUpdateForTest());
}

void setUp(void)
{
mockMeshService = new MockMeshService();
service = mockMeshService;

config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_US;
initRegion();
}

void tearDown(void)
{
service = nullptr;
delete mockMeshService;
mockMeshService = nullptr;
}

void setup()
{
Expand All @@ -94,6 +189,8 @@ void setup()
RUN_TEST(test_bootstrapLoRaConfigFromPreset_setsDerivedFields_nonWideRegion);
RUN_TEST(test_bootstrapLoRaConfigFromPreset_setsDerivedFields_wideRegion);
RUN_TEST(test_bootstrapLoRaConfigFromPreset_fallsBackIfBandwidthExceedsRegionSpan);
RUN_TEST(test_radioLibReconfigureResetsNoiseFloorWhenFrequencyChanges);
RUN_TEST(test_radioLibReconfigureKeepsNoiseFloorWhenFrequencyUnchanged);
exit(UNITY_END());
}

Expand Down
Loading