Merge remote-tracking branch 'origin/master' into NextHopRouter

This commit is contained in:
GUVWAF
2024-11-01 09:41:43 +01:00
469 changed files with 11896 additions and 7255 deletions

View File

@@ -1,3 +1,4 @@
#include "../userPrefs.h"
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_GPS
#include "GPS.h"
@@ -11,34 +12,33 @@
#include "airtime.h"
#include "buzz.h"
#include "error.h"
#include "power.h"
// #include "debug.h"
#include "FSCommon.h"
#include "Led.h"
#include "RTC.h"
#include "SPILock.h"
#include "Throttle.h"
#include "concurrency/OSThread.h"
#include "concurrency/Periodic.h"
#include "detect/ScanI2C.h"
#include "error.h"
#include "power.h"
#if !MESHTASTIC_EXCLUDE_I2C
#include "detect/ScanI2CTwoWire.h"
#include <Wire.h>
#endif
#include "detect/axpDebug.h"
#include "detect/einkScan.h"
#include "graphics/RAKled.h"
#include "graphics/Screen.h"
#include "main.h"
#include "mesh/generated/meshtastic/config.pb.h"
#include "meshUtils.h"
#include "modules/Modules.h"
#include "shutdown.h"
#include "sleep.h"
#include "target_specific.h"
#include <memory>
#include <utility>
// #include <driver/rtc_io.h>
#ifdef ARCH_ESP32
#if !MESHTASTIC_EXCLUDE_WEBSERVER
@@ -72,6 +72,7 @@ NRF52Bluetooth *nrf52Bluetooth = nullptr;
#include "LLCC68Interface.h"
#include "LR1110Interface.h"
#include "LR1120Interface.h"
#include "LR1121Interface.h"
#include "RF95Interface.h"
#include "SX1262Interface.h"
#include "SX1268Interface.h"
@@ -102,8 +103,8 @@ NRF52Bluetooth *nrf52Bluetooth = nullptr;
#include "AmbientLightingThread.h"
#include "PowerFSMThread.h"
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "AccelerometerThread.h"
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C
#include "motion/AccelerometerThread.h"
AccelerometerThread *accelerometerThread = nullptr;
#endif
@@ -118,6 +119,8 @@ float tcxoVoltage = SX126X_DIO3_TCXO_VOLTAGE; // if TCXO is optional, put this h
using namespace concurrency;
volatile static const char slipstreamTZString[] = USERPREFS_TZ_STRING;
// We always create a screen object, but we only init it if we find the hardware
graphics::Screen *screen = nullptr;
@@ -234,7 +237,7 @@ void lateInitVariant() {}
*/
void printInfo()
{
LOG_INFO("S:B:%d,%s\n", HW_VENDOR, optstr(APP_VERSION));
LOG_INFO("S:B:%d,%s", HW_VENDOR, optstr(APP_VERSION));
}
#ifndef PIO_UNIT_TESTING
void setup()
@@ -263,17 +266,22 @@ void setup()
#ifdef DEBUG_PORT
consoleInit(); // Set serial baud rate and init our mesh console
#endif
#ifdef UNPHONE
unphone.printStore();
#endif
#if ARCH_PORTDUINO
struct timeval tv;
tv.tv_sec = time(NULL);
tv.tv_usec = 0;
perhapsSetRTC(RTCQualityNTP, &tv);
#endif
powerMonInit();
powerMonInit();
serialSinceMsec = millis();
LOG_INFO("\n\n//\\ E S H T /\\ S T / C\n\n");
LOG_INFO("\n\n//\\ E S H T /\\ S T / C\n");
initDeepSleep();
@@ -294,6 +302,11 @@ void setup()
digitalWrite(VEXT_ENABLE, VEXT_ON_VALUE); // turn on the display power
#endif
#if defined(BIAS_T_ENABLE)
pinMode(BIAS_T_ENABLE, OUTPUT);
digitalWrite(BIAS_T_ENABLE, BIAS_T_VALUE); // turn on 5V for GPS Antenna
#endif
#if defined(VTFT_CTRL)
pinMode(VTFT_CTRL, OUTPUT);
digitalWrite(VTFT_CTRL, LOW);
@@ -315,22 +328,26 @@ void setup()
#ifdef PERIPHERAL_WARMUP_MS
// Some peripherals may require additional time to stabilize after power is connected
// e.g. I2C on Heltec Vision Master
LOG_INFO("Waiting for peripherals to stabilize\n");
LOG_INFO("Waiting for peripherals to stabilize");
delay(PERIPHERAL_WARMUP_MS);
#endif
#ifdef BUTTON_PIN
#ifdef ARCH_ESP32
// If the button is connected to GPIO 12, don't enable the ability to use
// meshtasticAdmin on the device.
pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT);
#if ESP_ARDUINO_VERSION_MAJOR >= 3
#ifdef BUTTON_NEED_PULLUP
pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT_PULLUP);
#else
pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT); // default to BUTTON_PIN
#endif
#else
pinMode(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, INPUT); // default to BUTTON_PIN
#ifdef BUTTON_NEED_PULLUP
gpio_pullup_en((gpio_num_t)(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN));
delay(10);
#endif
#endif
#endif
#endif
@@ -360,6 +377,8 @@ void setup()
Wire1.begin();
#elif defined(I2C_SDA1) && !defined(ARCH_RP2040)
Wire1.begin(I2C_SDA1, I2C_SCL1);
#elif WIRE_INTERFACES_COUNT == 2
Wire1.begin();
#endif
#if defined(I2C_SDA) && defined(ARCH_RP2040)
@@ -370,10 +389,10 @@ void setup()
Wire.begin(I2C_SDA, I2C_SCL);
#elif defined(ARCH_PORTDUINO)
if (settingsStrings[i2cdev] != "") {
LOG_INFO("Using %s as I2C device.\n", settingsStrings[i2cdev].c_str());
LOG_INFO("Using %s as I2C device.", settingsStrings[i2cdev].c_str());
Wire.begin(settingsStrings[i2cdev].c_str());
} else {
LOG_INFO("No I2C device configured, skipping.\n");
LOG_INFO("No I2C device configured, skipping.");
}
#elif HAS_WIRE
Wire.begin();
@@ -390,7 +409,7 @@ void setup()
#endif
#ifdef AQ_SET_PIN
// RAK-12039 set pin for Air quality sensor
// RAK-12039 set pin for Air quality sensor. Detectable on I2C after ~3 seconds, so we need to rescan later
pinMode(AQ_SET_PIN, OUTPUT);
digitalWrite(AQ_SET_PIN, HIGH);
#endif
@@ -416,7 +435,7 @@ void setup()
// accessories
auto i2cScanner = std::unique_ptr<ScanI2CTwoWire>(new ScanI2CTwoWire());
#if HAS_WIRE
LOG_INFO("Scanning for i2c devices...\n");
LOG_INFO("Scanning for i2c devices...");
#endif
#if defined(I2C_SDA1) && defined(ARCH_RP2040)
@@ -427,6 +446,8 @@ void setup()
#elif defined(I2C_SDA1) && !defined(ARCH_RP2040)
Wire1.begin(I2C_SDA1, I2C_SCL1);
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE1);
#elif defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2)
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE1);
#endif
#if defined(I2C_SDA) && defined(ARCH_RP2040)
@@ -439,7 +460,7 @@ void setup()
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE);
#elif defined(ARCH_PORTDUINO)
if (settingsStrings[i2cdev] != "") {
LOG_INFO("Scanning for i2c devices...\n");
LOG_INFO("Scanning for i2c devices...");
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE);
}
#elif HAS_WIRE
@@ -448,9 +469,9 @@ void setup()
auto i2cCount = i2cScanner->countDevices();
if (i2cCount == 0) {
LOG_INFO("No I2C devices found\n");
LOG_INFO("No I2C devices found");
} else {
LOG_INFO("%i I2C devices found\n", i2cCount);
LOG_INFO("%i I2C devices found", i2cCount);
#ifdef SENSOR_GPS_CONFLICT
sensor_detected = true;
#endif
@@ -506,9 +527,13 @@ void setup()
// assign an arbitrary value to distinguish from other models
kb_model = 0x11;
break;
case ScanI2C::DeviceType::MPR121KB:
// assign an arbitrary value to distinguish from other models
kb_model = 0x37;
break;
default:
// use this as default since it's also just zero
LOG_WARN("kb_info.type is unknown(0x%02x), setting kb_model=0x00\n", kb_info.type);
LOG_WARN("kb_info.type is unknown(0x%02x), setting kb_model=0x00", kb_info.type);
kb_model = 0x00;
}
}
@@ -526,10 +551,25 @@ void setup()
rgb_found = i2cScanner->find(ScanI2C::DeviceType::NCP5623);
#endif
#ifdef HAS_TPS65233
// TPS65233 is a power management IC for satellite modems, used in the Dreamcatcher
// We are switching it off here since we don't use an LNB.
if (i2cScanner->exists(ScanI2C::DeviceType::TPS65233)) {
Wire.beginTransmission(TPS65233_ADDR);
Wire.write(0); // Register 0
Wire.write(128); // Turn off the LNB power, keep I2C Control enabled
Wire.endTransmission();
Wire.beginTransmission(TPS65233_ADDR);
Wire.write(1); // Register 1
Wire.write(0); // Turn off Tone Generator 22kHz
Wire.endTransmission();
}
#endif
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
auto acc_info = i2cScanner->firstAccelerometer();
accelerometer_found = acc_info.type != ScanI2C::DeviceType::NONE ? acc_info.address : accelerometer_found;
LOG_DEBUG("acc_info = %i\n", acc_info.type);
LOG_DEBUG("acc_info = %i", acc_info.type);
#endif
#define STRING(S) #S
@@ -540,7 +580,7 @@ void setup()
if (found.type != ScanI2C::DeviceType::NONE) { \
nodeTelemetrySensorsMap[PB_T].first = found.address.address; \
nodeTelemetrySensorsMap[PB_T].second = i2cScanner->fetchI2CBus(found.address); \
LOG_DEBUG("found i2c sensor %s\n", STRING(PB_T)); \
LOG_DEBUG("found i2c sensor %s", STRING(PB_T)); \
} \
}
@@ -552,6 +592,7 @@ void setup()
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::INA260, meshtastic_TelemetrySensorType_INA260)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::INA219, meshtastic_TelemetrySensorType_INA219)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::INA3221, meshtastic_TelemetrySensorType_INA3221)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MAX17048, meshtastic_TelemetrySensorType_MAX17048)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MCP9808, meshtastic_TelemetrySensorType_MCP9808)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MCP9808, meshtastic_TelemetrySensorType_MCP9808)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::SHT31, meshtastic_TelemetrySensorType_SHT31)
@@ -560,15 +601,19 @@ void setup()
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::QMC6310, meshtastic_TelemetrySensorType_QMC6310)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::QMI8658, meshtastic_TelemetrySensorType_QMI8658)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::QMC5883L, meshtastic_TelemetrySensorType_QMC5883L)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::HMC5883L, meshtastic_TelemetrySensorType_QMC5883L)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::PMSA0031, meshtastic_TelemetrySensorType_PMSA003I)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::RCWL9620, meshtastic_TelemetrySensorType_RCWL9620)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::VEML7700, meshtastic_TelemetrySensorType_VEML7700)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::TSL2591, meshtastic_TelemetrySensorType_TSL25911FN)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::OPT3001, meshtastic_TelemetrySensorType_OPT3001)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MLX90632, meshtastic_TelemetrySensorType_MLX90632)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MLX90614, meshtastic_TelemetrySensorType_MLX90614)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::SHT4X, meshtastic_TelemetrySensorType_SHT4X)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::AHT10, meshtastic_TelemetrySensorType_AHT10)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::DFROBOT_LARK, meshtastic_TelemetrySensorType_DFROBOT_LARK)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::ICM20948, meshtastic_TelemetrySensorType_ICM20948)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MAX30102, meshtastic_TelemetrySensorType_MAX30102)
i2cScanner.reset();
#endif
@@ -586,6 +631,9 @@ void setup()
// Hello
printInfo();
#ifdef BUILD_EPOCH
LOG_INFO("Build timestamp: %ld", BUILD_EPOCH);
#endif
#ifdef ARCH_ESP32
esp32Setup();
@@ -599,6 +647,8 @@ void setup()
rp2040Setup();
#endif
initSPI(); // needed here before reading from littleFS
// We do this as early as possible because this loads preferences from flash
// but we need to do this after main cpu init (esp32setup), because we need the random seed set
nodeDB = new NodeDB;
@@ -617,7 +667,13 @@ void setup()
buttonThread = new ButtonThread();
#endif
playStartMelody();
// only play start melody when role is not tracker or sensor
if (config.power.is_power_saving == true &&
IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_TRACKER,
meshtastic_Config_DeviceConfig_Role_TAK_TRACKER, meshtastic_Config_DeviceConfig_Role_SENSOR))
LOG_DEBUG("Tracker/Sensor: Skipping start melody");
else
playStartMelody();
// fixed screen override?
if (config.display.oled != meshtastic_Config_DisplayConfig_OledType_OLED_AUTO)
@@ -625,7 +681,7 @@ void setup()
#if defined(USE_SH1107)
screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1107; // set dimension of 128x128
display_geometry = GEOMETRY_128_128;
screen_geometry = GEOMETRY_128_128;
#endif
#if defined(USE_SH1107_128_64)
@@ -633,10 +689,8 @@ void setup()
#endif
#if !MESHTASTIC_EXCLUDE_I2C
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
if (acc_info.type != ScanI2C::DeviceType::NONE) {
config.display.wake_on_tap_or_motion = true;
moduleConfig.external_notification.enabled = true;
accelerometerThread = new AccelerometerThread(acc_info.type);
}
#endif
@@ -658,7 +712,6 @@ void setup()
#endif
// Init our SPI controller (must be before screen and lora)
initSPI();
#ifdef ARCH_RP2040
#ifdef HW_SPI1_DEVICE
SPI1.setSCK(LORA_SCK);
@@ -678,7 +731,7 @@ void setup()
#else
// ESP32
SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
LOG_DEBUG("SPI.begin(SCK=%d, MISO=%d, MOSI=%d, NSS=%d)\n", LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
LOG_DEBUG("SPI.begin(SCK=%d, MISO=%d, MOSI=%d, NSS=%d)", LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
SPI.setFrequency(4000000);
#endif
@@ -687,13 +740,20 @@ void setup()
// setup TZ prior to time actions.
#if !MESHTASTIC_EXCLUDE_TZ
if (*config.device.tzdef) {
LOG_DEBUG("Using compiled/slipstreamed %s", slipstreamTZString); // important, removing this clobbers our magic string
if (*config.device.tzdef && config.device.tzdef[0] != 0) {
LOG_DEBUG("Saved TZ: %s ", config.device.tzdef);
setenv("TZ", config.device.tzdef, 1);
} else {
setenv("TZ", "GMT0", 1);
if (strncmp((const char *)slipstreamTZString, "tzpl", 4) == 0) {
setenv("TZ", "GMT0", 1);
} else {
setenv("TZ", (const char *)slipstreamTZString, 1);
strcpy(config.device.tzdef, (const char *)slipstreamTZString);
}
}
tzset();
LOG_DEBUG("Set Timezone to %s\n", getenv("TZ"));
LOG_DEBUG("Set Timezone to %s", getenv("TZ"));
#endif
readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time)
@@ -710,7 +770,7 @@ void setup()
if (gps) {
gpsStatus->observe(&gps->newStatus);
} else {
LOG_DEBUG("Running without GPS.\n");
LOG_DEBUG("Running without GPS.");
}
}
}
@@ -723,7 +783,7 @@ void setup()
nodeStatus->observe(&nodeDB->newStatus);
#ifdef HAS_I2S
LOG_DEBUG("Starting audio thread\n");
LOG_DEBUG("Starting audio thread");
audioThread = new AudioThread();
#endif
@@ -747,8 +807,8 @@ void setup()
#if !MESHTASTIC_EXCLUDE_I2C
// Don't call screen setup until after nodedb is setup (because we need
// the current region name)
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7789_CS) || defined(HX8357_CS) || \
defined(USE_ST7789)
#if defined(ST7701_CS) || defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || \
defined(ST7789_CS) || defined(HX8357_CS) || defined(USE_ST7789)
screen->setup();
#elif defined(ARCH_PORTDUINO)
if (screen_found.port != ScanI2C::I2CPort::NO_I2C || settingsMap[displayPanel]) {
@@ -762,12 +822,6 @@ void setup()
screen->print("Started...\n");
#ifdef SX126X_ANT_SW
// make analog PA vs not PA switch on SX126x eval board work properly
pinMode(SX126X_ANT_SW, OUTPUT);
digitalWrite(SX126X_ANT_SW, 1);
#endif
#ifdef PIN_PWR_DELAY_MS
// This may be required to give the peripherals time to power up.
delay(PIN_PWR_DELAY_MS);
@@ -776,63 +830,63 @@ void setup()
#ifdef ARCH_PORTDUINO
if (settingsMap[use_sx1262]) {
if (!rIf) {
LOG_DEBUG("Attempting to activate sx1262 radio on SPI port %s\n", settingsStrings[spidev].c_str());
LOG_DEBUG("Attempting to activate sx1262 radio on SPI port %s", settingsStrings[spidev].c_str());
LockingArduinoHal *RadioLibHAL =
new LockingArduinoHal(SPI, spiSettings, (settingsMap[ch341Quirk] ? settingsMap[busy] : RADIOLIB_NC));
rIf = new SX1262Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
settingsMap[busy]);
if (!rIf->init()) {
LOG_ERROR("Failed to find SX1262 radio\n");
LOG_ERROR("Failed to find SX1262 radio");
delete rIf;
exit(EXIT_FAILURE);
} else {
LOG_INFO("SX1262 Radio init succeeded, using SX1262 radio\n");
LOG_INFO("SX1262 Radio init succeeded, using SX1262 radio");
}
}
} else if (settingsMap[use_rf95]) {
if (!rIf) {
LOG_DEBUG("Attempting to activate rf95 radio on SPI port %s\n", settingsStrings[spidev].c_str());
LOG_DEBUG("Attempting to activate rf95 radio on SPI port %s", settingsStrings[spidev].c_str());
LockingArduinoHal *RadioLibHAL =
new LockingArduinoHal(SPI, spiSettings, (settingsMap[ch341Quirk] ? settingsMap[busy] : RADIOLIB_NC));
rIf = new RF95Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
settingsMap[busy]);
if (!rIf->init()) {
LOG_ERROR("Failed to find RF95 radio\n");
LOG_ERROR("Failed to find RF95 radio");
delete rIf;
rIf = NULL;
exit(EXIT_FAILURE);
} else {
LOG_INFO("RF95 Radio init succeeded, using RF95 radio\n");
LOG_INFO("RF95 Radio init succeeded, using RF95 radio");
}
}
} else if (settingsMap[use_sx1280]) {
if (!rIf) {
LOG_DEBUG("Attempting to activate sx1280 radio on SPI port %s\n", settingsStrings[spidev].c_str());
LOG_DEBUG("Attempting to activate sx1280 radio on SPI port %s", settingsStrings[spidev].c_str());
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
rIf = new SX1280Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
settingsMap[busy]);
if (!rIf->init()) {
LOG_ERROR("Failed to find SX1280 radio\n");
LOG_ERROR("Failed to find SX1280 radio");
delete rIf;
rIf = NULL;
exit(EXIT_FAILURE);
} else {
LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio\n");
LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio");
}
}
} else if (settingsMap[use_sx1268]) {
if (!rIf) {
LOG_DEBUG("Attempting to activate sx1268 radio on SPI port %s\n", settingsStrings[spidev].c_str());
LOG_DEBUG("Attempting to activate sx1268 radio on SPI port %s", settingsStrings[spidev].c_str());
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
rIf = new SX1268Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
settingsMap[busy]);
if (!rIf->init()) {
LOG_ERROR("Failed to find SX1268 radio\n");
LOG_ERROR("Failed to find SX1268 radio");
delete rIf;
rIf = NULL;
exit(EXIT_FAILURE);
} else {
LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio\n");
LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio");
}
}
}
@@ -848,11 +902,11 @@ void setup()
if (!rIf) {
rIf = new STM32WLE5JCInterface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
if (!rIf->init()) {
LOG_WARN("Failed to find STM32WL radio\n");
LOG_WARN("Failed to find STM32WL radio");
delete rIf;
rIf = NULL;
} else {
LOG_INFO("STM32WL Radio init succeeded, using STM32WL radio\n");
LOG_INFO("STM32WL Radio init succeeded, using STM32WL radio");
radioType = STM32WLx_RADIO;
}
}
@@ -862,154 +916,165 @@ void setup()
if (!rIf) {
rIf = new SimRadio;
if (!rIf->init()) {
LOG_WARN("Failed to find simulated radio\n");
LOG_WARN("Failed to find simulated radio");
delete rIf;
rIf = NULL;
} else {
LOG_INFO("Using SIMULATED radio!\n");
LOG_INFO("Using SIMULATED radio!");
radioType = SIM_RADIO;
}
}
#endif
#if defined(RF95_IRQ)
if (!rIf) {
#if defined(RF95_IRQ) && RADIOLIB_EXCLUDE_SX127X != 1
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
rIf = new RF95Interface(RadioLibHAL, LORA_CS, RF95_IRQ, RF95_RESET, RF95_DIO1);
if (!rIf->init()) {
LOG_WARN("Failed to find RF95 radio\n");
LOG_WARN("Failed to find RF95 radio");
delete rIf;
rIf = NULL;
} else {
LOG_INFO("RF95 Radio init succeeded, using RF95 radio\n");
LOG_INFO("RF95 Radio init succeeded, using RF95 radio");
radioType = RF95_RADIO;
}
}
#endif
#if defined(USE_SX1262) && !defined(ARCH_PORTDUINO) && !defined(TCXO_OPTIONAL)
if (!rIf) {
#if defined(USE_SX1262) && !defined(ARCH_PORTDUINO) && !defined(TCXO_OPTIONAL) && RADIOLIB_EXCLUDE_SX126X != 1
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
if (!rIf->init()) {
LOG_WARN("Failed to find SX1262 radio\n");
LOG_WARN("Failed to find SX1262 radio");
delete rIf;
rIf = NULL;
} else {
LOG_INFO("SX1262 Radio init succeeded, using SX1262 radio\n");
LOG_INFO("SX1262 Radio init succeeded, using SX1262 radio");
radioType = SX1262_RADIO;
}
}
#endif
#if defined(USE_SX1262) && !defined(ARCH_PORTDUINO) && defined(TCXO_OPTIONAL)
if (!rIf) {
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
// Try using the specified TCXO voltage
rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
if (!rIf->init()) {
LOG_WARN("Failed to find SX1262 radio with TCXO using DIO3 reference voltage at %f V\n", tcxoVoltage);
LOG_WARN("Failed to find SX1262 radio with TCXO, Vref %f V", tcxoVoltage);
delete rIf;
rIf = NULL;
tcxoVoltage = 0; // if it fails, set the TCXO voltage to zero for the next attempt
} else {
LOG_INFO("SX1262 Radio init succeeded, using ");
LOG_WARN("SX1262 Radio with TCXO");
LOG_INFO(", reference voltage at %f V\n", tcxoVoltage);
LOG_WARN("SX1262 Radio init succeeded, TCXO, Vref %f V", tcxoVoltage);
radioType = SX1262_RADIO;
}
}
if (!rIf) {
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
// If specified TCXO voltage fails, attempt to use DIO3 as a reference instea
rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
if (!rIf->init()) {
LOG_WARN("Failed to find SX1262 radio with XTAL using DIO3 reference voltage at %f V\n", tcxoVoltage);
LOG_WARN("Failed to find SX1262 radio with XTAL, Vref %f V", tcxoVoltage);
delete rIf;
rIf = NULL;
tcxoVoltage = SX126X_DIO3_TCXO_VOLTAGE; // if it fails, set the TCXO voltage back for the next radio search
} else {
LOG_INFO("SX1262 Radio init succeeded, using ");
LOG_WARN("SX1262 Radio with XTAL");
LOG_INFO(", reference voltage at %f V\n", tcxoVoltage);
LOG_INFO("SX1262 Radio init succeeded, XTAL, Vref %f V", tcxoVoltage);
radioType = SX1262_RADIO;
}
}
#endif
#if defined(USE_SX1268)
if (!rIf) {
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
rIf = new SX1268Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
if (!rIf->init()) {
LOG_WARN("Failed to find SX1268 radio\n");
LOG_WARN("Failed to find SX1268 radio");
delete rIf;
rIf = NULL;
} else {
LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio\n");
LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio");
radioType = SX1268_RADIO;
}
}
#endif
#if defined(USE_LLCC68)
if (!rIf) {
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
rIf = new LLCC68Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
if (!rIf->init()) {
LOG_WARN("Failed to find LLCC68 radio\n");
LOG_WARN("Failed to find LLCC68 radio");
delete rIf;
rIf = NULL;
} else {
LOG_INFO("LLCC68 Radio init succeeded, using LLCC68 radio\n");
LOG_INFO("LLCC68 Radio init succeeded, using LLCC68 radio");
radioType = LLCC68_RADIO;
}
}
#endif
#if defined(USE_LR1110)
if (!rIf) {
rIf = new LR1110Interface(RadioLibHAL, LR1110_SPI_NSS_PIN, LR1110_IRQ_PIN, LR1110_NRESER_PIN, LR1110_BUSY_PIN);
#if defined(USE_LR1110) && RADIOLIB_EXCLUDE_LR11X0 != 1
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
rIf = new LR1110Interface(RadioLibHAL, LR1110_SPI_NSS_PIN, LR1110_IRQ_PIN, LR1110_NRESET_PIN, LR1110_BUSY_PIN);
if (!rIf->init()) {
LOG_WARN("Failed to find LR1110 radio\n");
LOG_WARN("Failed to find LR1110 radio");
delete rIf;
rIf = NULL;
} else {
LOG_INFO("LR1110 Radio init succeeded, using LR1110 radio\n");
LOG_INFO("LR1110 Radio init succeeded, using LR1110 radio");
radioType = LR1110_RADIO;
}
}
#endif
#if defined(USE_LR1120)
#if defined(USE_LR1120) && RADIOLIB_EXCLUDE_LR11X0 != 1
if (!rIf) {
rIf = new LR1120Interface(RadioLibHAL, LR1120_SPI_NSS_PIN, LR1120_IRQ_PIN, LR1120_NRESER_PIN, LR1120_BUSY_PIN);
rIf = new LR1120Interface(RadioLibHAL, LR1120_SPI_NSS_PIN, LR1120_IRQ_PIN, LR1120_NRESET_PIN, LR1120_BUSY_PIN);
if (!rIf->init()) {
LOG_WARN("Failed to find LR1120 radio\n");
LOG_WARN("Failed to find LR1120 radio");
delete rIf;
rIf = NULL;
} else {
LOG_INFO("LR1120 Radio init succeeded, using LR1120 radio\n");
LOG_INFO("LR1120 Radio init succeeded, using LR1120 radio");
radioType = LR1120_RADIO;
}
}
#endif
#if defined(USE_SX1280)
#if defined(USE_LR1121) && RADIOLIB_EXCLUDE_LR11X0 != 1
if (!rIf) {
rIf = new LR1121Interface(RadioLibHAL, LR1121_SPI_NSS_PIN, LR1121_IRQ_PIN, LR1121_NRESET_PIN, LR1121_BUSY_PIN);
if (!rIf->init()) {
LOG_WARN("Failed to find LR1121 radio");
delete rIf;
rIf = NULL;
} else {
LOG_INFO("LR1121 Radio init succeeded, using LR1121 radio");
radioType = LR1121_RADIO;
}
}
#endif
#if defined(USE_SX1280) && RADIOLIB_EXCLUDE_SX128X != 1
if (!rIf) {
rIf = new SX1280Interface(RadioLibHAL, SX128X_CS, SX128X_DIO1, SX128X_RESET, SX128X_BUSY);
if (!rIf->init()) {
LOG_WARN("Failed to find SX1280 radio\n");
LOG_WARN("Failed to find SX1280 radio");
delete rIf;
rIf = NULL;
} else {
LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio\n");
LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio");
radioType = SX1280_RADIO;
}
}
#endif
// check if the radio chip matches the selected region
if ((config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_LORA_24) && (!rIf->wideLora())) {
LOG_WARN("Radio chip does not support 2.4GHz LoRa. Reverting to unset.\n");
LOG_WARN("Radio chip does not support 2.4GHz LoRa. Reverting to unset.");
config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_UNSET;
nodeDB->saveToDisk(SEGMENT_CONFIG);
if (!rIf->reconfigure()) {
LOG_WARN("Reconfigure failed, rebooting\n");
LOG_WARN("Reconfigure failed, rebooting");
screen->startAlert("Rebooting...");
rebootAtMsec = millis() + 5000;
}
@@ -1064,9 +1129,9 @@ void setup()
router->addInterface(rIf);
// Log bit rate to debug output
LOG_DEBUG("LoRA bitrate = %f bytes / sec\n", (float(meshtastic_Constants_DATA_PAYLOAD_LEN) /
(float(rIf->getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN)))) *
1000);
LOG_DEBUG("LoRA bitrate = %f bytes / sec", (float(meshtastic_Constants_DATA_PAYLOAD_LEN) /
(float(rIf->getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN)))) *
1000);
}
// This must be _after_ service.init because we need our preferences loaded from flash to have proper timeout values
@@ -1095,6 +1160,9 @@ extern meshtastic_DeviceMetadata getDeviceMetadata()
deviceMetadata.position_flags = config.position.position_flags;
deviceMetadata.hw_model = HW_VENDOR;
deviceMetadata.hasRemoteHardware = moduleConfig.remote_hardware.enabled;
#if !(MESHTASTIC_EXCLUDE_PKI)
deviceMetadata.hasPKC = true;
#endif
return deviceMetadata;
}
#ifndef PIO_UNIT_TESTING
@@ -1102,10 +1170,6 @@ void loop()
{
runASAP = false;
// axpDebugOutput.loop();
// heap_caps_check_integrity_all(true); // FIXME - disable this expensive check
#ifdef ARCH_ESP32
esp32Loop();
#endif
@@ -1114,33 +1178,21 @@ void loop()
#endif
powerCommandsCheck();
// For debugging
// if (rIf) ((RadioLibInterface *)rIf)->isActivelyReceiving();
#ifdef DEBUG_STACK
static uint32_t lastPrint = 0;
if (millis() - lastPrint > 10 * 1000L) {
if (!Throttle::isWithinTimespanMs(lastPrint, 10 * 1000L)) {
lastPrint = millis();
meshtastic::printThreadInfo("main");
}
#endif
// TODO: This should go into a thread handled by FreeRTOS.
// handleWebResponse();
service->loop();
long delayMsec = mainController.runOrDelay();
/* if (mainController.nextThread && delayMsec)
LOG_DEBUG("Next %s in %ld\n", mainController.nextThread->ThreadName.c_str(),
mainController.nextThread->tillRun(millis())); */
// We want to sleep as long as possible here - because it saves power
if (!runASAP && loopCanSleep()) {
// if(delayMsec > 100) LOG_DEBUG("sleeping %ld\n", delayMsec);
mainDelay.delay(delayMsec);
}
// if (didWake) LOG_DEBUG("wake!\n");
}
#endif
#endif