mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-08-28 18:08:22 +00:00
Scale CAD scan timeouts to radio settings
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace mesh {
|
||||
|
||||
static constexpr uint32_t CAD_SCAN_MIN_TIMEOUT_MS = 100UL;
|
||||
static constexpr uint32_t CAD_SCAN_MAX_TIMEOUT_MS = 3500UL;
|
||||
static constexpr uint32_t CAD_SCAN_FALLBACK_TIMEOUT_MS = 500UL;
|
||||
|
||||
// RadioLib's SX126x CAD default examines four LoRa symbols. Allow six symbols
|
||||
// plus fixed command/TCXO overhead, then clamp the result so normal profiles
|
||||
// fail quickly without rejecting deliberately slow custom radio settings.
|
||||
inline uint32_t calculateCadScanTimeoutMillis(uint8_t sf, float bandwidth_khz) {
|
||||
if (sf < 5 || sf > 12 || bandwidth_khz <= 0.0f) {
|
||||
return CAD_SCAN_FALLBACK_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
const float symbol_ms = static_cast<float>(1UL << sf) / bandwidth_khz;
|
||||
const float padded_ms = symbol_ms * 6.0f + 20.0f;
|
||||
uint32_t timeout_ms = static_cast<uint32_t>(padded_ms + 0.999f);
|
||||
|
||||
if (timeout_ms < CAD_SCAN_MIN_TIMEOUT_MS) return CAD_SCAN_MIN_TIMEOUT_MS;
|
||||
if (timeout_ms > CAD_SCAN_MAX_TIMEOUT_MS) return CAD_SCAN_MAX_TIMEOUT_MS;
|
||||
return timeout_ms;
|
||||
}
|
||||
|
||||
} // namespace mesh
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
|
||||
protected:
|
||||
int16_t performChannelScan() override {
|
||||
return ((CustomSX1276 *)_radio)->tryScanChannel(CAD_SCAN_TIMEOUT_MS, *_board);
|
||||
return ((CustomSX1276 *)_radio)->tryScanChannel(cadScanTimeoutMillis(), *_board);
|
||||
}
|
||||
|
||||
bool radioDeepInit() override {
|
||||
|
||||
@@ -625,9 +625,10 @@ int16_t RadioLibWrapper::performChannelScan() {
|
||||
int16_t result = _radio->startChannelScan();
|
||||
if (result != RADIOLIB_ERR_NONE) return result;
|
||||
|
||||
const unsigned long timeout_ms = cadScanTimeoutMillis();
|
||||
const unsigned long started = millis();
|
||||
unsigned long last_watchdog_service = started;
|
||||
while (millis() - started < CAD_SCAN_TIMEOUT_MS) {
|
||||
while (millis() - started < timeout_ms) {
|
||||
result = _radio->getChannelScanResult();
|
||||
if (result != RADIOLIB_ERR_UNKNOWN) return result;
|
||||
|
||||
@@ -639,7 +640,7 @@ int16_t RadioLibWrapper::performChannelScan() {
|
||||
yield();
|
||||
}
|
||||
|
||||
MESH_DEBUG_PRINTLN("RadioLibWrapper: CAD scan timed out");
|
||||
MESH_DEBUG_PRINTLN("RadioLibWrapper: CAD scan timed out after %lu ms", timeout_ms);
|
||||
return RADIOLIB_ERR_RX_TIMEOUT;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <Mesh.h>
|
||||
#include <RadioLib.h>
|
||||
#include "CadTiming.h"
|
||||
|
||||
// Fallback RX powersaving timings, only used until setRxPowerSaving() is called
|
||||
// (begin() always applies the persisted values). The authoritative defaults live
|
||||
@@ -12,7 +13,6 @@
|
||||
|
||||
class RadioLibWrapper : public mesh::Radio {
|
||||
protected:
|
||||
static constexpr unsigned long CAD_SCAN_TIMEOUT_MS = 10000UL;
|
||||
PhysicalLayer* _radio;
|
||||
mesh::MainBoard* _board;
|
||||
uint32_t n_recv, n_sent, n_recv_errors;
|
||||
@@ -72,6 +72,11 @@ protected:
|
||||
void cacheParams(float freq, float bw, uint8_t sf, uint8_t cr) {
|
||||
_cur_freq = freq; _cur_bw = bw; _cur_sf = sf; _cur_cr = cr; _params_valid = true;
|
||||
}
|
||||
unsigned long cadScanTimeoutMillis() const {
|
||||
const uint8_t sf = _params_valid ? _cur_sf : getSpreadingFactor();
|
||||
const float bw = _params_valid ? _cur_bw : static_cast<float>(LORA_BW);
|
||||
return mesh::calculateCadScanTimeoutMillis(sf, bw);
|
||||
}
|
||||
virtual int startReceiveMode();
|
||||
virtual void stopReceiveDutyCycle();
|
||||
virtual bool isPacketReady();
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <helpers/radiolib/CadTiming.h>
|
||||
|
||||
TEST(CadTiming, UsesShortDeadlineForCascadeProfile) {
|
||||
EXPECT_EQ(mesh::calculateCadScanTimeoutMillis(7, 62.5f), 100UL);
|
||||
}
|
||||
|
||||
TEST(CadTiming, ScalesForSlowRadioSettings) {
|
||||
EXPECT_EQ(mesh::calculateCadScanTimeoutMillis(12, 62.5f), 414UL);
|
||||
EXPECT_EQ(mesh::calculateCadScanTimeoutMillis(12, 7.8f), 3171UL);
|
||||
}
|
||||
|
||||
TEST(CadTiming, BoundsInvalidAndExtremeInputs) {
|
||||
EXPECT_EQ(mesh::calculateCadScanTimeoutMillis(0, 62.5f), 500UL);
|
||||
EXPECT_EQ(mesh::calculateCadScanTimeoutMillis(7, 0.0f), 500UL);
|
||||
EXPECT_EQ(mesh::calculateCadScanTimeoutMillis(12, 1.0f), 3500UL);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
Reference in New Issue
Block a user