radio: extract CadController and NoiseFloorEstimator, one prefs source

- CadController (stats, window, re-anchor, visits, staircase, safety,
  starvation relax) and NoiseFloorEstimator split out of LoRaRadioBase
  behind a 4-call CadHw interface; Zephyr-free, host unit tests added
- prefs mandatory: setPrefs() before begin(), LoRaConfig fallbacks and the
  companion/observer placeholder prefs removed; LoRaConfig is the one
  defaults source (invalid-prefs fallback now uses the board TX default)
- TX-wait thread stack owned by the base; reconfigureWithParams removed
- driver extension headers on the public include path
  (zephyr/drivers/lora/*.h); patch 0003 include updated
- comment diet (image-identical); rationale moved to devdocs LLD 03
This commit is contained in:
liquidraver
2026-09-23 14:33:29 +02:00
parent a7d073900e
commit fd2cbe9d62
36 changed files with 935 additions and 1629 deletions
+6 -10
View File
@@ -63,18 +63,16 @@ public:
*/
virtual void onSendFinished() = 0;
/**
* \brief do any processing needed on each loop cycle
*/
virtual void loop() { }
// ZEPHCORE: no loop() -- the Dispatcher never polls the radio; periodic radio
// work is deadline-driven through msUntilNextMaintenance()/radioMaintenance().
virtual int getNoiseFloor() const { return 0; }
virtual void triggerNoiseFloorCalibrate(int threshold) { }
virtual void setCADEnabled(bool enable) { }
virtual void resetAGC() { }
// ZEPHCORE: no setCADEnabled() (CAD is always LBT inside the driver) and no
// resetAGC() (the AGC unstick is part of radioMaintenance()). Left out so a
// port calling them fails to compile instead of silently doing nothing.
virtual bool isInRecvMode() const = 0;
@@ -86,9 +84,7 @@ public:
virtual float getLastRSSI() const { return 0; }
virtual float getLastSNR() const { return 0; }
// ZEPHCORE: radio extensions used by the Dispatcher and the roles. CAD is
// always LBT inside the driver (setCADEnabled unused) and the AGC unstick is
// part of radioMaintenance() (resetAGC unused).
// ZEPHCORE: radio extensions used by the Dispatcher and the roles.
// Radio not command-ready (e.g. BUSY high); the Dispatcher defers TX.
virtual bool isRadioReady() { return true; }
+8 -10
View File
@@ -70,11 +70,8 @@ public:
virtual void onPacketReceived() { }
virtual void reboot() = 0;
virtual void powerOff() { /* no op */ }
// Called by example setup() functions to signal that boot is complete.
// Boards may override to stop a boot-indicator LED sequence or similar.
// Default no-op: boards that don't care need not implement anything.
virtual void onBootComplete() { /* no op */ }
virtual uint32_t getIRQGpio() { return -1; } // not supported. Returns DIO1 (SX1262) and DIO0 (SX127x)
// ZEPHCORE: no onBootComplete() (Arduino setup() hook) and no getIRQGpio()
// (Arduino sleep-wake pin) -- nothing on Zephyr would call them.
virtual void sleep(uint32_t secs) { /* no op */ }
virtual uint32_t getGpio() { return 0; }
virtual void setGpio(uint32_t values) {}
@@ -83,10 +80,10 @@ public:
virtual bool startOTAUpdate(const char* id, char reply[]) { return false; } // not supported
// Power management interface (boards with power management override these)
virtual bool isPwrMgtInitialised() const { return false; }
// ZEPHCORE: no isPwrMgtInitialised() / getWakeLpcompSupported() -- upstream's
// nRF52 Arduino power manager; Zephyr PM covers this.
virtual bool isExternalPowered() { return false; }
virtual uint16_t getBootVoltage() { return 0; }
virtual bool getWakeLpcompSupported() const { return false; }
virtual uint32_t getResetReason() const { return 0; }
virtual const char* getResetReasonString(uint32_t reason) { return "Not available"; }
virtual uint8_t getShutdownReason() const { return 0; }
@@ -94,9 +91,10 @@ public:
virtual bool handleCommand(const char* command, uint32_t sender_timestamp, char* reply) { return false; }
// Called from the example main loops. Lets a board feed its watchdog and
// run periodic housekeeping. Default no-op.
virtual void loop() { /* no op */ }
// ZEPHCORE: no loop() -- upstream polls it from the Arduino main loop. The mesh
// thread here is event-driven and never polls; a board with periodic work owns
// a timer or work item. Left out so a port calling board.loop() fails to
// compile instead of silently doing nothing.
};
/**