mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-09-01 20:08:32 +00:00
* T096, and Station G3: refactoring the 'FEM' prefs to variant-specific code
* CommonCLI: 'FEM' commands removed * introduced static no-op attachDynamicPrefs() for all boards
This commit is contained in:
@@ -989,8 +989,9 @@ void MyMesh::begin(bool has_display) {
|
||||
radio_driver.setParams(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
|
||||
radio_driver.setTxPower(_prefs.tx_power_dbm);
|
||||
radio_driver.setRxBoostedGainMode(_prefs.rx_boosted_gain);
|
||||
board.setLoRaFemLnaEnabled(_prefs.radio_fem_rxgain);
|
||||
board.setLoRaFemPaGainEnabled(_prefs.radio_fem_txgain);
|
||||
|
||||
board.attachDynamicPrefs(_prefs.getRadioPrefs());
|
||||
|
||||
MESH_DEBUG_PRINTLN("RX Boosted Gain Mode: %s",
|
||||
radio_driver.getRxBoostedGainMode() ? "Enabled" : "Disabled");
|
||||
}
|
||||
@@ -2073,6 +2074,12 @@ bool MyMesh::handleCommand(const char* command, uint32_t sender_timestamp, char*
|
||||
return true;
|
||||
}
|
||||
|
||||
// hook for variant-specific CLI processing
|
||||
if (board.handleCommand(command, sender_timestamp, reply)) {
|
||||
if (_prefs.isDirty()) { savePrefs(); }
|
||||
return true;
|
||||
}
|
||||
|
||||
if (memcmp(command, "set name ", 9) == 0) {
|
||||
if (AdvertDataParser::isValidName(&command[9])) {
|
||||
StrHelper::strncpy(_prefs.node_name, &command[9], sizeof(_prefs.node_name));
|
||||
|
||||
@@ -54,12 +54,8 @@ private:
|
||||
//def("cad", _parent->cad_enabled);
|
||||
//def("int_thr", _parent->interference_threshold);
|
||||
def("rxgain", _parent->rx_boosted_gain);
|
||||
#if 0
|
||||
// NOTE: these cannot be set (yet) so don't load/save until we can.
|
||||
// also, fem_rxgain WAS mapped to wrong JSON property previously
|
||||
def("fem_rxgain", _parent->radio_fem_rxgain);
|
||||
def("fem_rxgain", _parent->radio_fem_rxgain); // fem_rxgain WAS mapped to wrong JSON property previously
|
||||
def("fem_txgain", _parent->radio_fem_txgain);
|
||||
#endif
|
||||
def("tx", _parent->tx_power_dbm);
|
||||
def("af", _parent->airtime_factor);
|
||||
def("rxdelay", _parent->rx_delay_base);
|
||||
@@ -103,6 +99,10 @@ private:
|
||||
void setFloodTxDelay(float d) override { /* no-op */ }
|
||||
float getDirectTxDelay() const override { return 0.2f; } // currently hard-coded
|
||||
void setDirectTxDelay(float d) override { /* no-op */ }
|
||||
uint8_t getFEMRxGain() const override { return _parent->radio_fem_rxgain; }
|
||||
void setFEMRxGain(uint8_t g) override { _parent->radio_fem_rxgain = g; markDirty(); }
|
||||
uint8_t getFEMTxGain() const override { return _parent->radio_fem_txgain; }
|
||||
void setFEMTxGain(uint8_t g) override { _parent->radio_fem_txgain = g; markDirty(); }
|
||||
};
|
||||
RadioPrefs radio;
|
||||
|
||||
@@ -177,5 +177,6 @@ public:
|
||||
void setRepeatEn(bool en) { repeat.disable_fwd = en ? 0 : 1; }
|
||||
|
||||
CommonRadioPrefs* getRadioPrefs() { return &radio; }
|
||||
void clearDirty() { radio.clearDirty(); }
|
||||
bool isDirty() const override { return ConfigSerializer::isDirty() || radio.isDirty(); }
|
||||
void clearDirty() override { ConfigSerializer::clearDirty(); radio.clearDirty(); }
|
||||
};
|
||||
|
||||
@@ -982,8 +982,8 @@ void MyMesh::begin(FILESYSTEM *fs) {
|
||||
radio_driver.setRxBoostedGainMode(_prefs.rx_boosted_gain);
|
||||
MESH_DEBUG_PRINTLN("RX Boosted Gain Mode: %s",
|
||||
radio_driver.getRxBoostedGainMode() ? "Enabled" : "Disabled");
|
||||
board.setLoRaFemLnaEnabled(_prefs.radio_fem_rxgain);
|
||||
board.setLoRaFemPaGainEnabled(_prefs.radio_fem_txgain);
|
||||
|
||||
board.attachDynamicPrefs(_prefs.getRadioPrefs());
|
||||
|
||||
updateAdvertTimer();
|
||||
updateFloodAdvertTimer();
|
||||
|
||||
@@ -725,8 +725,8 @@ void MyMesh::begin(FILESYSTEM *fs) {
|
||||
radio_driver.setParams(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
|
||||
radio_driver.setTxPower(_prefs.tx_power_dbm);
|
||||
radio_driver.setRxBoostedGainMode(_prefs.rx_boosted_gain);
|
||||
board.setLoRaFemLnaEnabled(_prefs.radio_fem_rxgain);
|
||||
board.setLoRaFemPaGainEnabled(_prefs.radio_fem_txgain);
|
||||
|
||||
board.attachDynamicPrefs(_prefs.getRadioPrefs());
|
||||
|
||||
updateAdvertTimer();
|
||||
updateFloodAdvertTimer();
|
||||
|
||||
@@ -771,8 +771,8 @@ void SensorMesh::begin(FILESYSTEM* fs) {
|
||||
|
||||
radio_driver.setParams(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
|
||||
radio_driver.setTxPower(_prefs.tx_power_dbm);
|
||||
board.setLoRaFemLnaEnabled(_prefs.radio_fem_rxgain);
|
||||
board.setLoRaFemPaGainEnabled(_prefs.radio_fem_txgain);
|
||||
|
||||
board.attachDynamicPrefs(_prefs.getRadioPrefs());
|
||||
|
||||
updateAdvertTimer();
|
||||
updateFloodAdvertTimer();
|
||||
|
||||
+2
-7
@@ -64,13 +64,6 @@ public:
|
||||
virtual uint8_t getStartupReason() const = 0;
|
||||
virtual bool getBootloaderVersion(char* version, size_t max_len) { return false; }
|
||||
virtual bool startOTAUpdate(const char* id, char reply[]) { return false; } // not supported
|
||||
virtual bool setLoRaFemLnaEnabled(bool enable) { return false; }
|
||||
virtual bool canControlLoRaFemLna() const { return false; }
|
||||
virtual bool isLoRaFemLnaEnabled() const { return false; }
|
||||
// Software-selectable external FEM transmit gain. This is not a PA power switch.
|
||||
virtual bool setLoRaFemPaGainEnabled(bool enable) { return false; }
|
||||
virtual bool canControlLoRaFemPaGain() const { return false; }
|
||||
virtual bool isLoRaFemPaGainEnabled() const { return false; }
|
||||
|
||||
// Power management interface (boards with power management override these)
|
||||
virtual bool isExternalPowered() { return false; }
|
||||
@@ -79,6 +72,8 @@ public:
|
||||
virtual const char* getResetReasonString(uint32_t reason) { return "Not available"; }
|
||||
virtual uint8_t getShutdownReason() const { return 0; }
|
||||
virtual const char* getShutdownReasonString(uint8_t reason) { return "Not available"; }
|
||||
|
||||
virtual bool handleCommand(const char* command, uint32_t sender_timestamp, char* reply) { return false; }
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -185,6 +185,11 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* re
|
||||
if (_prefs->getRadioPrefs()->isDirty()) { savePrefs(); }
|
||||
return;
|
||||
}
|
||||
// hook for variant-specific CLI processing
|
||||
if (_board->handleCommand(command, sender_timestamp, reply)) {
|
||||
if (_prefs->isDirty()) { savePrefs(); }
|
||||
return;
|
||||
}
|
||||
|
||||
if (memcmp(command, "poweroff", 8) == 0 || memcmp(command, "shutdown", 8) == 0) {
|
||||
_board->powerOff(); // doesn't return
|
||||
@@ -507,50 +512,6 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep
|
||||
_prefs->disable_fwd = memcmp(&config[7], "off", 3) == 0;
|
||||
savePrefs();
|
||||
strcpy(reply, _prefs->disable_fwd ? "OK - repeat is now OFF" : "OK - repeat is now ON");
|
||||
} else if (memcmp(config, "radio.fem.rxgain ", 17) == 0) {
|
||||
if (!_board->canControlLoRaFemLna()) {
|
||||
strcpy(reply, "Error: unsupported");
|
||||
} else if (memcmp(&config[17], "on", 2) == 0) {
|
||||
if (_board->setLoRaFemLnaEnabled(true)) {
|
||||
_prefs->radio_fem_rxgain = 1;
|
||||
savePrefs();
|
||||
strcpy(reply, "OK - LoRa FEM RX gain on");
|
||||
} else {
|
||||
strcpy(reply, "Error: failed to apply LoRa FEM RX gain");
|
||||
}
|
||||
} else if (memcmp(&config[17], "off", 3) == 0) {
|
||||
if (_board->setLoRaFemLnaEnabled(false)) {
|
||||
_prefs->radio_fem_rxgain = 0;
|
||||
savePrefs();
|
||||
strcpy(reply, "OK - LoRa FEM RX gain off");
|
||||
} else {
|
||||
strcpy(reply, "Error: failed to apply LoRa FEM RX gain");
|
||||
}
|
||||
} else {
|
||||
strcpy(reply, "Error: state must be on or off");
|
||||
}
|
||||
} else if (memcmp(config, "radio.fem.txgain ", 17) == 0) {
|
||||
if (!_board->canControlLoRaFemPaGain()) {
|
||||
strcpy(reply, "Error: unsupported");
|
||||
} else if (memcmp(&config[17], "on", 2) == 0) {
|
||||
if (_board->setLoRaFemPaGainEnabled(true)) {
|
||||
_prefs->radio_fem_txgain = 1;
|
||||
savePrefs();
|
||||
strcpy(reply, "OK - LoRa FEM TX gain on");
|
||||
} else {
|
||||
strcpy(reply, "Error: failed to apply LoRa FEM TX gain");
|
||||
}
|
||||
} else if (memcmp(&config[17], "off", 3) == 0) {
|
||||
if (_board->setLoRaFemPaGainEnabled(false)) {
|
||||
_prefs->radio_fem_txgain = 0;
|
||||
savePrefs();
|
||||
strcpy(reply, "OK - LoRa FEM TX gain off");
|
||||
} else {
|
||||
strcpy(reply, "Error: failed to apply LoRa FEM TX gain");
|
||||
}
|
||||
} else {
|
||||
strcpy(reply, "Error: state must be on or off");
|
||||
}
|
||||
} else if (memcmp(config, "lat ", 4) == 0) {
|
||||
_prefs->node_lat = atof(&config[4]);
|
||||
savePrefs();
|
||||
@@ -733,18 +694,6 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* rep
|
||||
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->node_lat));
|
||||
} else if (memcmp(config, "lon", 3) == 0) {
|
||||
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->node_lon));
|
||||
} else if (memcmp(config, "radio.fem.rxgain", 16) == 0) {
|
||||
if (!_board->canControlLoRaFemLna()) {
|
||||
strcpy(reply, "Error: unsupported");
|
||||
} else {
|
||||
sprintf(reply, "> %s", _board->isLoRaFemLnaEnabled() ? "on" : "off");
|
||||
}
|
||||
} else if (memcmp(config, "radio.fem.txgain", 16) == 0) {
|
||||
if (!_board->canControlLoRaFemPaGain()) {
|
||||
strcpy(reply, "Error: unsupported");
|
||||
} else {
|
||||
sprintf(reply, "> %s", _board->isLoRaFemPaGainEnabled() ? "on" : "off");
|
||||
}
|
||||
} else if (memcmp(config, "flood.max.advert", 16) == 0) {
|
||||
sprintf(reply, "> %d", (uint32_t)_prefs->flood_max_advert);
|
||||
} else if (memcmp(config, "flood.max.unscoped", 18) == 0) {
|
||||
|
||||
@@ -128,6 +128,10 @@ private:
|
||||
void setFloodTxDelay(float d) override { _parent->tx_delay_factor = d; markDirty(); }
|
||||
float getDirectTxDelay() const override { return _parent->direct_tx_delay_factor; }
|
||||
void setDirectTxDelay(float d) override { _parent->direct_tx_delay_factor = d; markDirty(); }
|
||||
uint8_t getFEMRxGain() const override { return _parent->radio_fem_rxgain; }
|
||||
void setFEMRxGain(uint8_t g) override { _parent->radio_fem_rxgain = g; markDirty(); }
|
||||
uint8_t getFEMTxGain() const override { return _parent->radio_fem_txgain; }
|
||||
void setFEMTxGain(uint8_t g) override { _parent->radio_fem_txgain = g; markDirty(); }
|
||||
};
|
||||
RadioPrefs radio;
|
||||
|
||||
@@ -226,7 +230,8 @@ public:
|
||||
}
|
||||
|
||||
CommonRadioPrefs* getRadioPrefs() { return &radio; }
|
||||
void clearDirty() { radio.clearDirty(); }
|
||||
bool isDirty() const override { return ConfigSerializer::isDirty() || radio.isDirty(); }
|
||||
void clearDirty() override { ConfigSerializer::clearDirty(); radio.clearDirty(); }
|
||||
};
|
||||
|
||||
class CommonCLICallbacks {
|
||||
|
||||
@@ -3,6 +3,27 @@
|
||||
#include "Utils.h"
|
||||
#include "target.h"
|
||||
|
||||
void CommonRadioPrefs::getByKey(const char* key, char* value, size_t max_len) {
|
||||
if (strcmp(key, "fem_rxgain") == 0) {
|
||||
snprintf(value, max_len, "%d", (uint32_t)getFEMRxGain());
|
||||
} else if (strcmp(key, "fem_txgain") == 0) {
|
||||
snprintf(value, max_len, "%d", (uint32_t)getFEMTxGain());
|
||||
} else {
|
||||
MESH_DEBUG_PRINTLN("Error: getBykey() unknown key: %s", key);
|
||||
}
|
||||
}
|
||||
void CommonRadioPrefs::setByKey(const char* key, const char* value) {
|
||||
if (strcmp(key, "fem_rxgain") == 0) {
|
||||
setFEMRxGain(atoi(value));
|
||||
markDirty();
|
||||
} else if (strcmp(key, "fem_txgain") == 0) {
|
||||
setFEMTxGain(atoi(value));
|
||||
markDirty();
|
||||
} else {
|
||||
MESH_DEBUG_PRINTLN("Error: setBykey() unknown key: %s", key);
|
||||
}
|
||||
}
|
||||
|
||||
bool CommonRadioPrefs::handleCommand(const char* command, uint32_t sender_timestamp, char* reply) {
|
||||
if (strcmp(command, "get radio") == 0) {
|
||||
char freq[16], bw[16];
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
#include "ConfigSerializer.h"
|
||||
#include "KeyValueStore.h"
|
||||
|
||||
class CommonRadioPrefs : public ConfigSerializer {
|
||||
class CommonRadioPrefs : public ConfigSerializer, public KeyValueStore{
|
||||
bool _is_dirty = false;
|
||||
protected:
|
||||
CommonRadioPrefs() { }
|
||||
@@ -54,5 +56,14 @@ public:
|
||||
virtual float getDirectTxDelay() const = 0;
|
||||
virtual void setDirectTxDelay(float d) = 0;
|
||||
|
||||
virtual uint8_t getFEMRxGain() const = 0;
|
||||
virtual void setFEMRxGain(uint8_t g) = 0;
|
||||
|
||||
virtual uint8_t getFEMTxGain() const = 0;
|
||||
virtual void setFEMTxGain(uint8_t g) = 0;
|
||||
|
||||
bool handleCommand(const char* command, uint32_t sender_timestamp, char* reply);
|
||||
|
||||
void setByKey(const char* key, const char* value) override; // for dynamic key/value access
|
||||
void getByKey(const char* key, char* value, size_t max_len) override;
|
||||
};
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
class ConfigSerializer {
|
||||
bool _first;
|
||||
int8_t _depth;
|
||||
bool _dirty = false;
|
||||
|
||||
enum OP { READ, WRITE };
|
||||
|
||||
@@ -62,7 +63,12 @@ protected:
|
||||
|
||||
virtual void structure() = 0;
|
||||
|
||||
void markDirty() { _dirty = true; }
|
||||
|
||||
public:
|
||||
bool loadSerial(Stream& s);
|
||||
bool saveSerial(Stream& s);
|
||||
|
||||
virtual bool isDirty() const { return _dirty; }
|
||||
virtual void clearDirty() { _dirty = false; }
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "soc/rtc.h"
|
||||
#include "esp_system.h"
|
||||
#include <driver/rtc_io.h>
|
||||
#include <helpers/KeyValueStore.h>
|
||||
|
||||
class ESP32Board : public mesh::MainBoard {
|
||||
protected:
|
||||
@@ -51,6 +52,8 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
void attachDynamicPrefs(KeyValueStore* prefs) { } // no-op
|
||||
|
||||
// Temperature from ESP32 MCU
|
||||
float getMCUTemperature() override {
|
||||
uint32_t raw = 0;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
class KeyValueStore {
|
||||
protected:
|
||||
KeyValueStore() { }
|
||||
public:
|
||||
virtual void setByKey(const char* key, const char* value) { }
|
||||
virtual void getByKey(const char* key, char* value, size_t max_len) { }
|
||||
};
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <MeshCore.h>
|
||||
#include <helpers/KeyValueStore.h>
|
||||
|
||||
#if defined(NRF52_PLATFORM)
|
||||
|
||||
@@ -57,6 +58,8 @@ public:
|
||||
virtual void sleep(uint32_t secs) override;
|
||||
bool isExternalPowered() override;
|
||||
|
||||
void attachDynamicPrefs(KeyValueStore* prefs) { } // no-op
|
||||
|
||||
#ifdef NRF52_POWER_MANAGEMENT
|
||||
uint16_t getBootVoltage() override { return boot_voltage_mv; }
|
||||
virtual uint32_t getResetReason() const override { return reset_reason; }
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <MeshCore.h>
|
||||
#include <Arduino.h>
|
||||
#include <helpers/KeyValueStore.h>
|
||||
|
||||
class STM32Board : public mesh::MainBoard {
|
||||
protected:
|
||||
@@ -12,6 +13,8 @@ public:
|
||||
startup_reason = BD_STARTUP_NORMAL;
|
||||
}
|
||||
|
||||
void attachDynamicPrefs(KeyValueStore* prefs) { } // no-op
|
||||
|
||||
uint8_t getStartupReason() const override { return startup_reason; }
|
||||
|
||||
uint16_t getBattMilliVolts() override {
|
||||
|
||||
@@ -131,10 +131,50 @@ bool T096Board::setLoRaFemLnaEnabled(bool enable) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool T096Board::canControlLoRaFemLna() const {
|
||||
return loRaFEMControl.isLnaCanControl();
|
||||
}
|
||||
|
||||
bool T096Board::isLoRaFemLnaEnabled() const {
|
||||
return loRaFEMControl.isLNAEnabled();
|
||||
}
|
||||
|
||||
void T096Board::attachDynamicPrefs(KeyValueStore* prefs) {
|
||||
_prefs = prefs;
|
||||
|
||||
char radio_fem_rxgain[8] = { 0 };
|
||||
_prefs->getByKey("radio.fem_rxgain", radio_fem_rxgain, 7); // get initial values
|
||||
|
||||
setLoRaFemLnaEnabled(strcmp(radio_fem_rxgain, "1") == 0);
|
||||
}
|
||||
|
||||
bool T096Board::handleCommand(const char* command, uint32_t sender_timestamp, char* reply) {
|
||||
if (strcmp(command, "get radio.fem.rxgain") == 0) {
|
||||
if (!loRaFEMControl.isLnaCanControl()) {
|
||||
strcpy(reply, "Error: unsupported");
|
||||
} else {
|
||||
sprintf(reply, "> %s", isLoRaFemLnaEnabled() ? "on" : "off");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (memcmp(command, "set radio.fem.rxgain ", 21) == 0) {
|
||||
if (!loRaFEMControl.isLnaCanControl()) {
|
||||
strcpy(reply, "Error: unsupported");
|
||||
} else if (memcmp(&command[21], "on", 2) == 0) {
|
||||
if (setLoRaFemLnaEnabled(true)) {
|
||||
_prefs->setByKey("radio.fem_rxgain", "1");
|
||||
strcpy(reply, "OK - LoRa FEM RX gain on");
|
||||
} else {
|
||||
strcpy(reply, "Error: failed to apply LoRa FEM RX gain");
|
||||
}
|
||||
} else if (memcmp(&command[21], "off", 3) == 0) {
|
||||
if (setLoRaFemLnaEnabled(false)) {
|
||||
_prefs->setByKey("radio.fem_rxgain", "0");
|
||||
strcpy(reply, "OK - LoRa FEM RX gain off");
|
||||
} else {
|
||||
strcpy(reply, "Error: failed to apply LoRa FEM RX gain");
|
||||
}
|
||||
} else {
|
||||
strcpy(reply, "Error: state must be on or off");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false; // not handled
|
||||
}
|
||||
|
||||
@@ -4,28 +4,34 @@
|
||||
#include <Arduino.h>
|
||||
#include <helpers/NRF52Board.h>
|
||||
#include <helpers/RefCountedDigitalPin.h>
|
||||
#include <helpers/KeyValueStore.h>
|
||||
#include "LoRaFEMControl.h"
|
||||
|
||||
class T096Board : public NRF52BoardDCDC {
|
||||
KeyValueStore* _prefs = NULL;
|
||||
|
||||
protected:
|
||||
#ifdef NRF52_POWER_MANAGEMENT
|
||||
void initiateShutdown(uint8_t reason) override;
|
||||
#endif
|
||||
void variant_shutdown();
|
||||
|
||||
bool setLoRaFemLnaEnabled(bool enable);
|
||||
bool isLoRaFemLnaEnabled() const;
|
||||
|
||||
public:
|
||||
RefCountedDigitalPin periph_power;
|
||||
LoRaFEMControl loRaFEMControl;
|
||||
|
||||
T096Board() :periph_power(PIN_VEXT_EN,PIN_VEXT_EN_ACTIVE), NRF52Board("T096_OTA") {}
|
||||
void begin();
|
||||
void attachDynamicPrefs(KeyValueStore* prefs);
|
||||
|
||||
void onBeforeTransmit(void) override;
|
||||
void onAfterTransmit(void) override;
|
||||
uint16_t getBattMilliVolts() override;
|
||||
const char* getManufacturerName() const override ;
|
||||
void powerOff() override;
|
||||
bool setLoRaFemLnaEnabled(bool enable) override;
|
||||
bool canControlLoRaFemLna() const override;
|
||||
bool isLoRaFemLnaEnabled() const override;
|
||||
|
||||
bool handleCommand(const char* command, uint32_t sender_timestamp, char* reply) override;
|
||||
};
|
||||
|
||||
@@ -21,10 +21,6 @@ bool StationG3Board::setLoRaFemLnaEnabled(bool enable) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StationG3Board::canControlLoRaFemLna() const {
|
||||
return loRaFEMControl.canControlLNA();
|
||||
}
|
||||
|
||||
bool StationG3Board::isLoRaFemLnaEnabled() const {
|
||||
return loRaFEMControl.isLNAEnabled();
|
||||
}
|
||||
@@ -37,10 +33,86 @@ bool StationG3Board::setLoRaFemPaGainEnabled(bool enable) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StationG3Board::canControlLoRaFemPaGain() const {
|
||||
return loRaFEMControl.canControlPAGain();
|
||||
}
|
||||
|
||||
bool StationG3Board::isLoRaFemPaGainEnabled() const {
|
||||
return loRaFEMControl.isPAGainEnabled();
|
||||
}
|
||||
|
||||
void StationG3Board::attachDynamicPrefs(KeyValueStore* prefs) {
|
||||
_prefs = prefs;
|
||||
|
||||
char gain[8];
|
||||
|
||||
gain[0] = 0;
|
||||
_prefs->getByKey("fem_rxgain", gain, 7); // get initial values
|
||||
setLoRaFemLnaEnabled(strcmp(gain, "1") == 0);
|
||||
|
||||
gain[0] = 0;
|
||||
_prefs->getByKey("fem_txgain", gain, 7); // get initial values
|
||||
setLoRaFemPaGainEnabled(strcmp(gain, "1") == 0);
|
||||
}
|
||||
|
||||
bool StationG3Board::handleCommand(const char* command, uint32_t sender_timestamp, char* reply) {
|
||||
if (strcmp(command, "get radio.fem.rxgain") == 0) {
|
||||
if (!loRaFEMControl.canControlLNA()) {
|
||||
strcpy(reply, "Error: unsupported");
|
||||
} else {
|
||||
sprintf(reply, "> %s", isLoRaFemLnaEnabled() ? "on" : "off");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (memcmp(command, "set radio.fem.rxgain ", 21) == 0) {
|
||||
if (!loRaFEMControl.canControlLNA()) {
|
||||
strcpy(reply, "Error: unsupported");
|
||||
} else if (memcmp(&command[21], "on", 2) == 0) {
|
||||
if (setLoRaFemLnaEnabled(true)) {
|
||||
_prefs->setByKey("fem_rxgain", "1");
|
||||
strcpy(reply, "OK - LoRa FEM RX gain on");
|
||||
} else {
|
||||
strcpy(reply, "Error: failed to apply LoRa FEM RX gain");
|
||||
}
|
||||
} else if (memcmp(&command[21], "off", 3) == 0) {
|
||||
if (setLoRaFemLnaEnabled(false)) {
|
||||
_prefs->setByKey("fem_rxgain", "0");
|
||||
strcpy(reply, "OK - LoRa FEM RX gain off");
|
||||
} else {
|
||||
strcpy(reply, "Error: failed to apply LoRa FEM RX gain");
|
||||
}
|
||||
} else {
|
||||
strcpy(reply, "Error: state must be on or off");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strcmp(command, "get radio.fem.txgain") == 0) {
|
||||
if (!loRaFEMControl.canControlPAGain()) {
|
||||
strcpy(reply, "Error: unsupported");
|
||||
} else {
|
||||
sprintf(reply, "> %s", isLoRaFemPaGainEnabled() ? "on" : "off");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (memcmp(command, "set radio.fem.txgain ", 21) == 0) {
|
||||
if (!loRaFEMControl.canControlPAGain()) {
|
||||
strcpy(reply, "Error: unsupported");
|
||||
} else if (memcmp(&command[21], "on", 2) == 0) {
|
||||
if (setLoRaFemPaGainEnabled(true)) {
|
||||
_prefs->setByKey("fem_txgain", "1");
|
||||
strcpy(reply, "OK - LoRa FEM TX gain on");
|
||||
} else {
|
||||
strcpy(reply, "Error: failed to apply LoRa FEM TX gain");
|
||||
}
|
||||
} else if (memcmp(&command[21], "off", 3) == 0) {
|
||||
if (setLoRaFemPaGainEnabled(false)) {
|
||||
_prefs->setByKey("fem_txgain", "0");
|
||||
strcpy(reply, "OK - LoRa FEM TX gain off");
|
||||
} else {
|
||||
strcpy(reply, "Error: failed to apply LoRa FEM TX gain");
|
||||
}
|
||||
} else {
|
||||
strcpy(reply, "Error: state must be on or off");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false; // not handled
|
||||
}
|
||||
|
||||
@@ -6,6 +6,12 @@
|
||||
#include "LoRaFEMControl.h"
|
||||
|
||||
class StationG3Board : public ESP32Board {
|
||||
KeyValueStore* _prefs = NULL;
|
||||
|
||||
bool setLoRaFemLnaEnabled(bool enable);
|
||||
bool isLoRaFemLnaEnabled() const;
|
||||
bool setLoRaFemPaGainEnabled(bool enable);
|
||||
bool isLoRaFemPaGainEnabled() const;
|
||||
public:
|
||||
LoRaFEMControl loRaFEMControl;
|
||||
|
||||
@@ -25,6 +31,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void attachDynamicPrefs(KeyValueStore* prefs);
|
||||
|
||||
bool handleCommand(const char* command, uint32_t sender_timestamp, char* reply) override;
|
||||
|
||||
void setPrimaryLNAEnable(bool enabled) {
|
||||
loRaFEMControl.setLNAEnable(enabled);
|
||||
}
|
||||
@@ -43,13 +53,6 @@ public:
|
||||
loRaFEMControl.setRxModeEnable();
|
||||
}
|
||||
|
||||
bool setLoRaFemLnaEnabled(bool enable) override;
|
||||
bool canControlLoRaFemLna() const override;
|
||||
bool isLoRaFemLnaEnabled() const override;
|
||||
bool setLoRaFemPaGainEnabled(bool enable) override;
|
||||
bool canControlLoRaFemPaGain() const override;
|
||||
bool isLoRaFemPaGainEnabled() const override;
|
||||
|
||||
void powerOff() override;
|
||||
|
||||
uint16_t getBattMilliVolts() override {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <MeshCore.h>
|
||||
#include <helpers/KeyValueStore.h>
|
||||
|
||||
// LoRa radio module pins for Waveshare RP2040-LoRa-HF/LF
|
||||
// https://files.waveshare.com/wiki/RP2040-LoRa/Rp2040-lora-sch.pdf
|
||||
@@ -32,6 +33,8 @@ public:
|
||||
void begin();
|
||||
uint8_t getStartupReason() const override { return startup_reason; }
|
||||
|
||||
void attachDynamicPrefs(KeyValueStore* prefs) { } // no-op
|
||||
|
||||
#ifdef P_LORA_TX_LED
|
||||
void onBeforeTransmit() override { digitalWrite(P_LORA_TX_LED, HIGH); }
|
||||
void onAfterTransmit() override { digitalWrite(P_LORA_TX_LED, LOW); }
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <MeshCore.h>
|
||||
#include <helpers/KeyValueStore.h>
|
||||
|
||||
/*
|
||||
* This board has no built-in way to read battery voltage.
|
||||
@@ -30,6 +31,8 @@ public:
|
||||
void begin();
|
||||
uint8_t getStartupReason() const override { return startup_reason; }
|
||||
|
||||
void attachDynamicPrefs(KeyValueStore* prefs) { } // no-op
|
||||
|
||||
#ifdef P_LORA_TX_LED
|
||||
void onBeforeTransmit() override { digitalWrite(P_LORA_TX_LED, HIGH); }
|
||||
void onAfterTransmit() override { digitalWrite(P_LORA_TX_LED, LOW); }
|
||||
|
||||
Reference in New Issue
Block a user