Compare commits

..

No commits in common. "5f19982b69f45075e56677fef57e15598f90107c" and "33a12147c5c9c879acbe8cd05b23ea245fa247dc" have entirely different histories.

27 changed files with 126 additions and 172 deletions

View File

@ -8,15 +8,15 @@ plugins:
uri: https://github.com/trunk-io/plugins uri: https://github.com/trunk-io/plugins
lint: lint:
enabled: enabled:
- checkov@3.2.467 - checkov@3.2.465
- renovate@41.90.1 - renovate@41.82.10
- prettier@3.6.2 - prettier@3.6.2
- trufflehog@3.90.5 - trufflehog@3.90.5
- yamllint@1.37.1 - yamllint@1.37.1
- bandit@1.8.6 - bandit@1.8.6
- trivy@0.65.0 - trivy@0.65.0
- taplo@0.10.0 - taplo@0.10.0
- ruff@0.12.11 - ruff@0.12.10
- isort@6.0.1 - isort@6.0.1
- markdownlint@0.45.0 - markdownlint@0.45.0
- oxipng@9.1.5 - oxipng@9.1.5

View File

@ -100,6 +100,7 @@ IF NOT "!FILENAME:update=!"=="!FILENAME!" (
) )
:skip-filename :skip-filename
SET "ESPTOOL_BAUD=1200"
CALL :LOG_MESSAGE DEBUG "Determine the correct esptool command to use..." CALL :LOG_MESSAGE DEBUG "Determine the correct esptool command to use..."
IF NOT "__%PYTHON%__"=="____" ( IF NOT "__%PYTHON%__"=="____" (
@ -141,7 +142,7 @@ CALL :LOG_MESSAGE INFO "Using esptool baud: !ESPTOOL_BAUD!."
IF %BPS_RESET% EQU 1 ( IF %BPS_RESET% EQU 1 (
@REM Attempt to change mode via 1200bps Reset. @REM Attempt to change mode via 1200bps Reset.
CALL :RUN_ESPTOOL 1200 --after no_reset read_flash_status CALL :RUN_ESPTOOL !ESPTOOL_BAUD! --after no_reset read_flash_status
GOTO eof GOTO eof
) )

View File

@ -5,7 +5,7 @@
}, },
"core": "stm32", "core": "stm32",
"cpu": "cortex-m4", "cpu": "cortex-m4",
"extra_flags": "-DSTM32WLxx -DSTM32WLE5xx -DARDUINO_RAK3172_MODULE", "extra_flags": "-DSTM32WLxx -DSTM32WLE5xx -DARDUINO_GENERIC_WLE5CCUX",
"f_cpu": "48000000L", "f_cpu": "48000000L",
"mcu": "stm32wle5ccu", "mcu": "stm32wle5ccu",
"variant": "STM32WLxx/WL54CCU_WL55CCU_WLE4C(8-B-C)U_WLE5C(8-B-C)U", "variant": "STM32WLxx/WL54CCU_WL55CCU_WLE4C(8-B-C)U_WLE5C(8-B-C)U",

View File

@ -1,14 +1,7 @@
#include "DisplayFormatters.h" #include "DisplayFormatters.h"
const char *DisplayFormatters::getModemPresetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset, bool useShortName, const char *DisplayFormatters::getModemPresetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset, bool useShortName)
bool usePreset)
{ {
// If use_preset is false, always return "Custom"
if (!usePreset) {
return "Custom";
}
switch (preset) { switch (preset) {
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO: case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO:
return useShortName ? "ShortT" : "ShortTurbo"; return useShortName ? "ShortT" : "ShortTurbo";

View File

@ -4,8 +4,7 @@
class DisplayFormatters class DisplayFormatters
{ {
public: public:
static const char *getModemPresetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset, bool useShortName, static const char *getModemPresetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset, bool useShortName);
bool usePreset);
public: public:
static const char *getDeviceRole(meshtastic_Config_DeviceConfig_Role role); static const char *getDeviceRole(meshtastic_Config_DeviceConfig_Role role);

View File

@ -128,7 +128,6 @@ RAK9154Sensor rak9154Sensor;
#ifdef HAS_PPM #ifdef HAS_PPM
// note: XPOWERS_CHIP_XXX must be defined in variant.h // note: XPOWERS_CHIP_XXX must be defined in variant.h
#include <XPowersLib.h> #include <XPowersLib.h>
XPowersPPM *PPM = NULL;
#endif #endif
#ifdef HAS_BQ27220 #ifdef HAS_BQ27220
@ -682,7 +681,7 @@ bool Power::setup()
found = true; found = true;
} else if (lipoChargerInit()) { } else if (lipoChargerInit()) {
found = true; found = true;
} else if (meshSolarInit()) { } else if (meshSolarInit()) {
found = true; found = true;
} else if (analogInit()) { } else if (analogInit()) {
found = true; found = true;
@ -746,11 +745,7 @@ void Power::shutdown()
#if HAS_SCREEN #if HAS_SCREEN
if (screen) { if (screen) {
#ifdef T_DECK_PRO
screen->showSimpleBanner("Device is powered off.\nConnect USB to start!", 0); // T-Deck Pro has no power button
#else
screen->showSimpleBanner("Shutting Down...", 0); // stays on screen screen->showSimpleBanner("Shutting Down...", 0); // stays on screen
#endif
} }
#endif #endif
#if !defined(ARCH_STM32WL) #if !defined(ARCH_STM32WL)
@ -768,7 +763,7 @@ void Power::shutdown()
#ifdef PIN_LED3 #ifdef PIN_LED3
ledOff(PIN_LED3); ledOff(PIN_LED3);
#endif #endif
doDeepSleep(DELAY_FOREVER, true, true); doDeepSleep(DELAY_FOREVER, false, true);
#elif defined(ARCH_PORTDUINO) #elif defined(ARCH_PORTDUINO)
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
#else #else
@ -1325,6 +1320,7 @@ bool Power::lipoInit()
class LipoCharger : public HasBatteryLevel class LipoCharger : public HasBatteryLevel
{ {
private: private:
XPowersPPM *ppm = nullptr;
BQ27220 *bq = nullptr; BQ27220 *bq = nullptr;
public: public:
@ -1333,41 +1329,41 @@ class LipoCharger : public HasBatteryLevel
*/ */
bool runOnce() bool runOnce()
{ {
if (PPM == nullptr) { if (ppm == nullptr) {
PPM = new XPowersPPM; ppm = new XPowersPPM;
bool result = PPM->init(Wire, I2C_SDA, I2C_SCL, BQ25896_ADDR); bool result = ppm->init(Wire, I2C_SDA, I2C_SCL, BQ25896_ADDR);
if (result) { if (result) {
LOG_INFO("PPM BQ25896 init succeeded"); LOG_INFO("PPM BQ25896 init succeeded");
// Set the minimum operating voltage. Below this voltage, the PPM will protect // Set the minimum operating voltage. Below this voltage, the PPM will protect
// PPM->setSysPowerDownVoltage(3100); // ppm->setSysPowerDownVoltage(3100);
// Set input current limit, default is 500mA // Set input current limit, default is 500mA
// PPM->setInputCurrentLimit(800); // ppm->setInputCurrentLimit(800);
// Disable current limit pin // Disable current limit pin
// PPM->disableCurrentLimitPin(); // ppm->disableCurrentLimitPin();
// Set the charging target voltage, Range:3840 ~ 4608mV ,step:16 mV // Set the charging target voltage, Range:3840 ~ 4608mV ,step:16 mV
PPM->setChargeTargetVoltage(4288); ppm->setChargeTargetVoltage(4288);
// Set the precharge current , Range: 64mA ~ 1024mA ,step:64mA // Set the precharge current , Range: 64mA ~ 1024mA ,step:64mA
// PPM->setPrechargeCurr(64); // ppm->setPrechargeCurr(64);
// The premise is that limit pin is disabled, or it will // The premise is that limit pin is disabled, or it will
// only follow the maximum charging current set by limit pin. // only follow the maximum charging current set by limit pin.
// Set the charging current , Range:0~5056mA ,step:64mA // Set the charging current , Range:0~5056mA ,step:64mA
PPM->setChargerConstantCurr(1024); ppm->setChargerConstantCurr(1024);
// To obtain voltage data, the ADC must be enabled first // To obtain voltage data, the ADC must be enabled first
PPM->enableMeasure(); ppm->enableMeasure();
// Turn on charging function // Turn on charging function
// If there is no battery connected, do not turn on the charging function // If there is no battery connected, do not turn on the charging function
PPM->enableCharge(); ppm->enableCharge();
} else { } else {
LOG_WARN("PPM BQ25896 init failed"); LOG_WARN("PPM BQ25896 init failed");
delete PPM; delete ppm;
PPM = nullptr; ppm = nullptr;
return false; return false;
} }
} }
@ -1408,23 +1404,23 @@ class LipoCharger : public HasBatteryLevel
/** /**
* return true if there is a battery installed in this unit * return true if there is a battery installed in this unit
*/ */
virtual bool isBatteryConnect() override { return PPM->getBattVoltage() > 0; } virtual bool isBatteryConnect() override { return ppm->getBattVoltage() > 0; }
/** /**
* return true if there is an external power source detected * return true if there is an external power source detected
*/ */
virtual bool isVbusIn() override { return PPM->getVbusVoltage() > 0; } virtual bool isVbusIn() override { return ppm->getVbusVoltage() > 0; }
/** /**
* return true if the battery is currently charging * return true if the battery is currently charging
*/ */
virtual bool isCharging() override virtual bool isCharging() override
{ {
bool isCharging = PPM->isCharging(); bool isCharging = ppm->isCharging();
if (isCharging) { if (isCharging) {
LOG_DEBUG("BQ27220 time to full charge: %d min", bq->getTimeToFull()); LOG_DEBUG("BQ27220 time to full charge: %d min", bq->getTimeToFull());
} else { } else {
if (!PPM->isVbusIn()) { if (!ppm->isVbusIn()) {
LOG_DEBUG("BQ27220 time to empty: %d min (%d mAh)", bq->getTimeToEmpty(), bq->getRemainingCapacity()); LOG_DEBUG("BQ27220 time to empty: %d min (%d mAh)", bq->getTimeToEmpty(), bq->getRemainingCapacity());
} }
} }
@ -1457,6 +1453,8 @@ bool Power::lipoChargerInit()
} }
#endif #endif
#ifdef HELTEC_MESH_SOLAR #ifdef HELTEC_MESH_SOLAR
#include "meshSolarApp.h" #include "meshSolarApp.h"
@ -1494,7 +1492,7 @@ class meshSolarBatteryLevel : public HasBatteryLevel
/** /**
* return true if there is an external power source detected * return true if there is an external power source detected
*/ */
virtual bool isVbusIn() override { return meshSolarIsVbusIn(); } virtual bool isVbusIn() override { return meshSolarIsVbusIn();}
/** /**
* return true if the battery is currently charging * return true if the battery is currently charging

View File

@ -26,10 +26,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <Arduino.h> #include <Arduino.h>
#if __has_include("Melopero_RV3028.h") #ifdef RV3028_RTC
#include "Melopero_RV3028.h" #include "Melopero_RV3028.h"
#endif #endif
#if __has_include("pcf8563.h") #ifdef PCF8563_RTC
#include "pcf8563.h" #include "pcf8563.h"
#endif #endif

View File

@ -843,6 +843,9 @@ void GPS::setPowerState(GPSPowerState newState, uint32_t sleepTime)
setPowerPMU(true); // Power (PMU): on setPowerPMU(true); // Power (PMU): on
writePinStandby(false); // Standby (pin): awake (not standby) writePinStandby(false); // Standby (pin): awake (not standby)
setPowerUBLOX(true); // Standby (UBLOX): awake setPowerUBLOX(true); // Standby (UBLOX): awake
#ifdef GNSS_AIROHA
lastFixStartMsec = 0;
#endif
break; break;
case GPS_SOFTSLEEP: case GPS_SOFTSLEEP:
@ -860,7 +863,9 @@ void GPS::setPowerState(GPSPowerState newState, uint32_t sleepTime)
writePinStandby(true); // Standby (pin): asleep (not awake) writePinStandby(true); // Standby (pin): asleep (not awake)
setPowerUBLOX(false, sleepTime); // Standby (UBLOX): asleep, timed setPowerUBLOX(false, sleepTime); // Standby (UBLOX): asleep, timed
#ifdef GNSS_AIROHA #ifdef GNSS_AIROHA
digitalWrite(PIN_GPS_EN, LOW); if (config.position.gps_update_interval * 1000 >= GPS_FIX_HOLD_TIME * 2) {
digitalWrite(PIN_GPS_EN, LOW);
}
#endif #endif
break; break;
@ -872,7 +877,9 @@ void GPS::setPowerState(GPSPowerState newState, uint32_t sleepTime)
writePinStandby(true); // Standby (pin): asleep writePinStandby(true); // Standby (pin): asleep
setPowerUBLOX(false, 0); // Standby (UBLOX): asleep, indefinitely setPowerUBLOX(false, 0); // Standby (UBLOX): asleep, indefinitely
#ifdef GNSS_AIROHA #ifdef GNSS_AIROHA
digitalWrite(PIN_GPS_EN, LOW); if (config.position.gps_update_interval * 1000 >= GPS_FIX_HOLD_TIME * 2) {
digitalWrite(PIN_GPS_EN, LOW);
}
#endif #endif
break; break;
} }
@ -1055,8 +1062,6 @@ void GPS::down()
} }
// If update interval long enough (or softsleep unsupported): hardsleep instead // If update interval long enough (or softsleep unsupported): hardsleep instead
setPowerState(GPS_HARDSLEEP, sleepTime); setPowerState(GPS_HARDSLEEP, sleepTime);
// Reset the fix quality to 0, since we're off.
fixQual = 0;
} }
} }
@ -1116,19 +1121,11 @@ int32_t GPS::runOnce()
shouldPublish = true; shouldPublish = true;
} }
uint8_t prev_fixQual = fixQual;
bool gotLoc = lookForLocation(); bool gotLoc = lookForLocation();
if (gotLoc && !hasValidLocation) { // declare that we have location ASAP if (gotLoc && !hasValidLocation) { // declare that we have location ASAP
LOG_DEBUG("hasValidLocation RISING EDGE"); LOG_DEBUG("hasValidLocation RISING EDGE");
hasValidLocation = true; hasValidLocation = true;
shouldPublish = true; shouldPublish = true;
// Hold for 20secs after getting a lock to download ephemeris etc
fixHoldEnds = millis() + 20000;
}
if (gotLoc && prev_fixQual == 0) { // just got a lock after turning back on.
fixHoldEnds = millis() + 20000;
shouldPublish = true; // Publish immediately, since next publish is at end of hold
} }
bool tooLong = scheduling.searchedTooLong(); bool tooLong = scheduling.searchedTooLong();
@ -1137,7 +1134,8 @@ int32_t GPS::runOnce()
// Once we get a location we no longer desperately want an update // Once we get a location we no longer desperately want an update
if ((gotLoc && gotTime) || tooLong) { if ((gotLoc && gotTime) || tooLong) {
if (tooLong && !gotLoc) {
if (tooLong) {
// we didn't get a location during this ack window, therefore declare loss of lock // we didn't get a location during this ack window, therefore declare loss of lock
if (hasValidLocation) { if (hasValidLocation) {
LOG_DEBUG("hasValidLocation FALLING EDGE"); LOG_DEBUG("hasValidLocation FALLING EDGE");
@ -1145,15 +1143,9 @@ int32_t GPS::runOnce()
p = meshtastic_Position_init_default; p = meshtastic_Position_init_default;
hasValidLocation = false; hasValidLocation = false;
} }
if (millis() > fixHoldEnds) {
shouldPublish = true; // publish our update at the end of the lock hold down();
publishUpdate(); shouldPublish = true; // publish our update for this just finished acquisition window
down();
#ifdef GPS_DEBUG
} else {
LOG_DEBUG("Holding for GPS data download: %d ms (numSats=%d)", fixHoldEnds - millis(), p.sats_in_view);
#endif
}
} }
// If state has changed do a publish // If state has changed do a publish
@ -1516,6 +1508,24 @@ static int32_t toDegInt(RawDegrees d)
*/ */
bool GPS::lookForTime() bool GPS::lookForTime()
{ {
#ifdef GNSS_AIROHA
uint8_t fix = reader.fixQuality();
if (fix >= 1 && fix <= 5) {
if (lastFixStartMsec > 0) {
if (Throttle::isWithinTimespanMs(lastFixStartMsec, GPS_FIX_HOLD_TIME)) {
return false;
} else {
clearBuffer();
}
} else {
lastFixStartMsec = millis();
return false;
}
} else {
return false;
}
#endif
auto ti = reader.time; auto ti = reader.time;
auto d = reader.date; auto d = reader.date;
if (ti.isValid() && d.isValid()) { // Note: we don't check for updated, because we'll only be called if needed if (ti.isValid() && d.isValid()) { // Note: we don't check for updated, because we'll only be called if needed
@ -1554,6 +1564,25 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
*/ */
bool GPS::lookForLocation() bool GPS::lookForLocation()
{ {
#ifdef GNSS_AIROHA
if ((config.position.gps_update_interval * 1000) >= (GPS_FIX_HOLD_TIME * 2)) {
uint8_t fix = reader.fixQuality();
if (fix >= 1 && fix <= 5) {
if (lastFixStartMsec > 0) {
if (Throttle::isWithinTimespanMs(lastFixStartMsec, GPS_FIX_HOLD_TIME)) {
return false;
} else {
clearBuffer();
}
} else {
lastFixStartMsec = millis();
return false;
}
} else {
return false;
}
}
#endif
// By default, TinyGPS++ does not parse GPGSA lines, which give us // By default, TinyGPS++ does not parse GPGSA lines, which give us
// the 2D/3D fixType (see NMEAGPS.h) // the 2D/3D fixType (see NMEAGPS.h)
// At a minimum, use the fixQuality indicator in GPGGA (FIXME?) // At a minimum, use the fixQuality indicator in GPGGA (FIXME?)

View File

@ -159,7 +159,7 @@ class GPS : private concurrency::OSThread
uint8_t fixType = 0; // fix type from GPGSA uint8_t fixType = 0; // fix type from GPGSA
#endif #endif
uint32_t fixHoldEnds = 0; uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0, lastFixStartMsec = 0;
uint32_t rx_gpio = 0; uint32_t rx_gpio = 0;
uint32_t tx_gpio = 0; uint32_t tx_gpio = 0;

View File

@ -55,9 +55,9 @@ RTCSetResult readFromRTC()
LOG_DEBUG("Read RTC time from RV3028 getTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)", t.tm_year + 1900, t.tm_mon + 1, LOG_DEBUG("Read RTC time from RV3028 getTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)", t.tm_year + 1900, t.tm_mon + 1,
t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, printableEpoch); t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, printableEpoch);
timeStartMsec = now;
zeroOffsetSecs = tv.tv_sec;
if (currentQuality == RTCQualityNone) { if (currentQuality == RTCQualityNone) {
timeStartMsec = now;
zeroOffsetSecs = tv.tv_sec;
currentQuality = RTCQualityDevice; currentQuality = RTCQualityDevice;
} }
return RTCSetResultSuccess; return RTCSetResultSuccess;
@ -94,9 +94,9 @@ RTCSetResult readFromRTC()
LOG_DEBUG("Read RTC time from PCF8563 getDateTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)", t.tm_year + 1900, t.tm_mon + 1, LOG_DEBUG("Read RTC time from PCF8563 getDateTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)", t.tm_year + 1900, t.tm_mon + 1,
t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, printableEpoch); t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, printableEpoch);
timeStartMsec = now;
zeroOffsetSecs = tv.tv_sec;
if (currentQuality == RTCQualityNone) { if (currentQuality == RTCQualityNone) {
timeStartMsec = now;
zeroOffsetSecs = tv.tv_sec;
currentQuality = RTCQualityDevice; currentQuality = RTCQualityDevice;
} }
return RTCSetResultSuccess; return RTCSetResultSuccess;
@ -132,10 +132,6 @@ RTCSetResult perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpd
if (tv->tv_sec < BUILD_EPOCH) { if (tv->tv_sec < BUILD_EPOCH) {
LOG_WARN("Ignore time (%ld) before build epoch (%ld)!", printableEpoch, BUILD_EPOCH); LOG_WARN("Ignore time (%ld) before build epoch (%ld)!", printableEpoch, BUILD_EPOCH);
return RTCSetResultInvalidTime; return RTCSetResultInvalidTime;
} else if (tv->tv_sec > (BUILD_EPOCH + FORTY_YEARS)) {
LOG_WARN("Ignore time (%ld) too far in the future (build epoch: %ld, max allowed: %ld)!", printableEpoch, BUILD_EPOCH,
BUILD_EPOCH + FORTY_YEARS);
return RTCSetResultInvalidTime;
} }
#endif #endif
@ -254,10 +250,6 @@ RTCSetResult perhapsSetRTC(RTCQuality q, struct tm &t)
if (tv.tv_sec < BUILD_EPOCH) { if (tv.tv_sec < BUILD_EPOCH) {
LOG_WARN("Ignore time (%ld) before build epoch (%ld)!", printableEpoch, BUILD_EPOCH); LOG_WARN("Ignore time (%ld) before build epoch (%ld)!", printableEpoch, BUILD_EPOCH);
return RTCSetResultInvalidTime; return RTCSetResultInvalidTime;
} else if (tv.tv_sec > (BUILD_EPOCH + FORTY_YEARS)) {
LOG_WARN("Ignore time (%ld) too far in the future (build epoch: %ld, max allowed: %ld)!", printableEpoch, BUILD_EPOCH,
BUILD_EPOCH + FORTY_YEARS);
return RTCSetResultInvalidTime;
} }
#endif #endif

View File

@ -55,6 +55,3 @@ time_t gm_mktime(struct tm *tm);
#define SEC_PER_DAY 86400 #define SEC_PER_DAY 86400
#define SEC_PER_HOUR 3600 #define SEC_PER_HOUR 3600
#define SEC_PER_MIN 60 #define SEC_PER_MIN 60
#ifdef BUILD_EPOCH
#define FORTY_YEARS (40UL * 365 * SEC_PER_DAY) // probably time to update your firmware
#endif

View File

@ -263,6 +263,12 @@ void drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t
display->drawString(x + 1, y, "USB"); display->drawString(x + 1, y, "USB");
} }
// auto mode = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, true);
// display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode), y, mode);
// if (config.display.heading_bold)
// display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode) - 1, y, mode);
uint32_t currentMillis = millis(); uint32_t currentMillis = millis();
uint32_t seconds = currentMillis / 1000; uint32_t seconds = currentMillis / 1000;
uint32_t minutes = seconds / 60; uint32_t minutes = seconds / 60;
@ -400,8 +406,7 @@ void drawLoRaFocused(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x,
display->drawString(nameX, getTextPositions(display)[line++], device_role); display->drawString(nameX, getTextPositions(display)[line++], device_role);
// === Third Row: Radio Preset === // === Third Row: Radio Preset ===
auto mode = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, false, config.lora.use_preset); auto mode = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, false);
char regionradiopreset[25]; char regionradiopreset[25];
const char *region = myRegion ? myRegion->name : NULL; const char *region = myRegion ? myRegion->name : NULL;
if (region != nullptr) { if (region != nullptr) {

View File

@ -421,7 +421,7 @@ void setup()
struct timeval tv; struct timeval tv;
tv.tv_sec = time(NULL); tv.tv_sec = time(NULL);
tv.tv_usec = 0; tv.tv_usec = 0;
perhapsSetRTC(RTCQualityDevice, &tv); perhapsSetRTC(RTCQualityNTP, &tv);
#endif #endif
powerMonInit(); powerMonInit();
@ -1531,7 +1531,7 @@ extern meshtastic_DeviceMetadata getDeviceMetadata()
#if ((!HAS_SCREEN || NO_EXT_GPIO) || MESHTASTIC_EXCLUDE_CANNEDMESSAGES) && !defined(MESHTASTIC_INCLUDE_NICHE_GRAPHICS) #if ((!HAS_SCREEN || NO_EXT_GPIO) || MESHTASTIC_EXCLUDE_CANNEDMESSAGES) && !defined(MESHTASTIC_INCLUDE_NICHE_GRAPHICS)
deviceMetadata.excluded_modules |= meshtastic_ExcludedModules_CANNEDMSG_CONFIG; deviceMetadata.excluded_modules |= meshtastic_ExcludedModules_CANNEDMSG_CONFIG;
#endif #endif
#if NO_EXT_GPIO || MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION #if NO_EXT_GPIO
deviceMetadata.excluded_modules |= meshtastic_ExcludedModules_EXTNOTIF_CONFIG; deviceMetadata.excluded_modules |= meshtastic_ExcludedModules_EXTNOTIF_CONFIG;
#endif #endif
// Only edge case here is if we apply this a device with built in Accelerometer and want to detect interrupts // Only edge case here is if we apply this a device with built in Accelerometer and want to detect interrupts

View File

@ -368,7 +368,7 @@ const char *Channels::getName(size_t chIndex)
// Per mesh.proto spec, if bandwidth is specified we must ignore modemPreset enum, we assume that in that case // Per mesh.proto spec, if bandwidth is specified we must ignore modemPreset enum, we assume that in that case
// the app effed up and forgot to set channelSettings.name // the app effed up and forgot to set channelSettings.name
if (config.lora.use_preset) { if (config.lora.use_preset) {
channelName = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, false, config.lora.use_preset); channelName = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, false);
} else { } else {
channelName = "Custom"; channelName = "Custom";
} }
@ -382,8 +382,7 @@ bool Channels::isDefaultChannel(ChannelIndex chIndex)
const auto &ch = getByIndex(chIndex); const auto &ch = getByIndex(chIndex);
if (ch.settings.psk.size == 1 && ch.settings.psk.bytes[0] == 1) { if (ch.settings.psk.size == 1 && ch.settings.psk.bytes[0] == 1) {
const char *name = getName(chIndex); const char *name = getName(chIndex);
const char *presetName = const char *presetName = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, false);
DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, false, config.lora.use_preset);
// Check if the name is the default derived from the modem preset // Check if the name is the default derived from the modem preset
if (strcmp(name, presetName) == 0) if (strcmp(name, presetName) == 0)
return true; return true;

View File

@ -589,8 +589,7 @@ void RadioInterface::applyModemConfig()
// Check if we use the default frequency slot // Check if we use the default frequency slot
RadioInterface::uses_default_frequency_slot = RadioInterface::uses_default_frequency_slot =
channel_num == channel_num == hash(DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, false)) % numChannels;
hash(DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, false, config.lora.use_preset)) % numChannels;
// Old frequency selection formula // Old frequency selection formula
// float freq = myRegion->freqStart + ((((myRegion->freqEnd - myRegion->freqStart) / numChannels) / 2) * channel_num); // float freq = myRegion->freqStart + ((((myRegion->freqEnd - myRegion->freqStart) / numChannels) / 2) * channel_num);

View File

@ -364,10 +364,9 @@ ExternalNotificationModule::ExternalNotificationModule()
// moduleConfig.external_notification.alert_message_buzzer = true; // moduleConfig.external_notification.alert_message_buzzer = true;
if (moduleConfig.external_notification.enabled) { if (moduleConfig.external_notification.enabled) {
#if !defined(MESHTASTIC_EXCLUDE_INPUTBROKER)
if (inputBroker) // put our callback in the inputObserver list if (inputBroker) // put our callback in the inputObserver list
inputObserver.observe(inputBroker); inputObserver.observe(inputBroker);
#endif
if (nodeDB->loadProto(rtttlConfigFile, meshtastic_RTTTLConfig_size, sizeof(meshtastic_RTTTLConfig), if (nodeDB->loadProto(rtttlConfigFile, meshtastic_RTTTLConfig_size, sizeof(meshtastic_RTTTLConfig),
&meshtastic_RTTTLConfig_msg, &rtttlConfig) != LoadFileResult::LOAD_SUCCESS) { &meshtastic_RTTTLConfig_msg, &rtttlConfig) != LoadFileResult::LOAD_SUCCESS) {
memset(rtttlConfig.ringtone, 0, sizeof(rtttlConfig.ringtone)); memset(rtttlConfig.ringtone, 0, sizeof(rtttlConfig.ringtone));

View File

@ -88,7 +88,7 @@
#include "modules/StoreForwardModule.h" #include "modules/StoreForwardModule.h"
#endif #endif
#endif #endif
#if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO)
#if !MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION #if !MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION
#include "modules/ExternalNotificationModule.h" #include "modules/ExternalNotificationModule.h"
#endif #endif
@ -98,6 +98,7 @@
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !MESHTASTIC_EXCLUDE_SERIAL #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !MESHTASTIC_EXCLUDE_SERIAL
#include "modules/SerialModule.h" #include "modules/SerialModule.h"
#endif #endif
#endif
#if !MESHTASTIC_EXCLUDE_DROPZONE #if !MESHTASTIC_EXCLUDE_DROPZONE
#include "modules/DropzoneModule.h" #include "modules/DropzoneModule.h"
@ -245,8 +246,8 @@ void setupModules()
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_POWER_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR #if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_POWER_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
new PowerTelemetryModule(); new PowerTelemetryModule();
#endif #endif
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040) || defined(ARCH_STM32WL)) && \ #if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
!defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) !defined(CONFIG_IDF_TARGET_ESP32C3)
#if !MESHTASTIC_EXCLUDE_SERIAL #if !MESHTASTIC_EXCLUDE_SERIAL
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) { if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) {
new SerialModule(); new SerialModule();
@ -267,11 +268,13 @@ void setupModules()
storeForwardModule = new StoreForwardModule(); storeForwardModule = new StoreForwardModule();
#endif #endif
#endif #endif
#if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO)
#if !MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION #if !MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION
externalNotificationModule = new ExternalNotificationModule(); externalNotificationModule = new ExternalNotificationModule();
#endif #endif
#if !MESHTASTIC_EXCLUDE_RANGETEST && !MESHTASTIC_EXCLUDE_GPS #if !MESHTASTIC_EXCLUDE_RANGETEST && !MESHTASTIC_EXCLUDE_GPS
new RangeTestModule(); new RangeTestModule();
#endif
#endif #endif
} else { } else {
#if !MESHTASTIC_EXCLUDE_ADMIN #if !MESHTASTIC_EXCLUDE_ADMIN

View File

@ -31,7 +31,7 @@ uint32_t packetSequence = 0;
int32_t RangeTestModule::runOnce() int32_t RangeTestModule::runOnce()
{ {
#if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_STM32WL) || defined(ARCH_PORTDUINO) #if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_PORTDUINO)
/* /*
Uncomment the preferences below if you want to use the module Uncomment the preferences below if you want to use the module
@ -130,7 +130,7 @@ void RangeTestModuleRadio::sendPayload(NodeNum dest, bool wantReplies)
ProcessMessage RangeTestModuleRadio::handleReceived(const meshtastic_MeshPacket &mp) ProcessMessage RangeTestModuleRadio::handleReceived(const meshtastic_MeshPacket &mp)
{ {
#if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_STM32WL) || defined(ARCH_PORTDUINO) #if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_PORTDUINO)
if (moduleConfig.range_test.enabled) { if (moduleConfig.range_test.enabled) {

View File

@ -49,8 +49,8 @@
#include "meshSolarApp.h" #include "meshSolarApp.h"
#endif #endif
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040) || defined(ARCH_STM32WL)) && \ #if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
!defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) !defined(CONFIG_IDF_TARGET_ESP32C3)
#define RX_BUFFER 256 #define RX_BUFFER 256
#define TIMEOUT 250 #define TIMEOUT 250
@ -67,7 +67,7 @@ SerialModuleRadio *serialModuleRadio;
defined(ELECROW_ThinkNode_M5) || defined(HELTEC_MESH_SOLAR) || defined(T_ECHO_LITE) defined(ELECROW_ThinkNode_M5) || defined(HELTEC_MESH_SOLAR) || defined(T_ECHO_LITE)
SerialModule::SerialModule() : StreamAPI(&Serial), concurrency::OSThread("Serial") {} SerialModule::SerialModule() : StreamAPI(&Serial), concurrency::OSThread("Serial") {}
static Print *serialPrint = &Serial; static Print *serialPrint = &Serial;
#elif defined(CONFIG_IDF_TARGET_ESP32C6) || defined(RAK3172) #elif defined(CONFIG_IDF_TARGET_ESP32C6)
SerialModule::SerialModule() : StreamAPI(&Serial1), concurrency::OSThread("Serial") {} SerialModule::SerialModule() : StreamAPI(&Serial1), concurrency::OSThread("Serial") {}
static Print *serialPrint = &Serial1; static Print *serialPrint = &Serial1;
#else #else
@ -173,18 +173,7 @@ int32_t SerialModule::runOnce()
Serial.begin(baud); Serial.begin(baud);
Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT); Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
} }
#elif defined(ARCH_STM32WL)
#ifndef RAK3172
HardwareSerial *serialInstance = &Serial2;
#else
HardwareSerial *serialInstance = &Serial1;
#endif
if (moduleConfig.serial.rxd && moduleConfig.serial.txd) {
serialInstance->setTx(moduleConfig.serial.txd);
serialInstance->setRx(moduleConfig.serial.rxd);
}
serialInstance->begin(baud);
serialInstance->setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
#elif defined(ARCH_ESP32) #elif defined(ARCH_ESP32)
if (moduleConfig.serial.rxd && moduleConfig.serial.txd) { if (moduleConfig.serial.rxd && moduleConfig.serial.txd) {
@ -271,13 +260,8 @@ int32_t SerialModule::runOnce()
while (Serial1.available()) { while (Serial1.available()) {
serialPayloadSize = Serial1.readBytes(serialBytes, meshtastic_Constants_DATA_PAYLOAD_LEN); serialPayloadSize = Serial1.readBytes(serialBytes, meshtastic_Constants_DATA_PAYLOAD_LEN);
#else #else
#ifndef RAK3172 while (Serial2.available()) {
HardwareSerial *serialInstance = &Serial2; serialPayloadSize = Serial2.readBytes(serialBytes, meshtastic_Constants_DATA_PAYLOAD_LEN);
#else
HardwareSerial *serialInstance = &Serial1;
#endif
while (serialInstance->available()) {
serialPayloadSize = serialInstance->readBytes(serialBytes, meshtastic_Constants_DATA_PAYLOAD_LEN);
#endif #endif
serialModuleRadio->sendPayload(); serialModuleRadio->sendPayload();
} }
@ -527,7 +511,7 @@ ParsedLine parseLine(const char *line)
void SerialModule::processWXSerial() void SerialModule::processWXSerial()
{ {
#if !defined(TTGO_T_ECHO) && !defined(T_ECHO_LITE) && !defined(CANARYONE) && !defined(CONFIG_IDF_TARGET_ESP32C6) && \ #if !defined(TTGO_T_ECHO) && !defined(T_ECHO_LITE) && !defined(CANARYONE) && !defined(CONFIG_IDF_TARGET_ESP32C6) && \
!defined(MESHLINK) && !defined(ELECROW_ThinkNode_M1) && !defined(ELECROW_ThinkNode_M5) && !defined(ARCH_STM32WL) !defined(MESHLINK) && !defined(ELECROW_ThinkNode_M1) && !defined(ELECROW_ThinkNode_M5)
static unsigned int lastAveraged = 0; static unsigned int lastAveraged = 0;
static unsigned int averageIntervalMillis = 300000; // 5 minutes hard coded. static unsigned int averageIntervalMillis = 300000; // 5 minutes hard coded.
static double dir_sum_sin = 0; static double dir_sum_sin = 0;

View File

@ -8,8 +8,8 @@
#include <Arduino.h> #include <Arduino.h>
#include <functional> #include <functional>
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040) || defined(ARCH_STM32WL)) && \ #if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
!defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) !defined(CONFIG_IDF_TARGET_ESP32C3)
class SerialModule : public StreamAPI, private concurrency::OSThread class SerialModule : public StreamAPI, private concurrency::OSThread
{ {

View File

@ -32,16 +32,6 @@ esp_sleep_source_t wakeCause; // the reason we booted this time
#endif #endif
#include "Throttle.h" #include "Throttle.h"
#ifdef USE_XL9555
#include "ExtensionIOXL9555.hpp"
extern ExtensionIOXL9555 io;
#endif
#ifdef HAS_PPM
#include <XPowersLib.h>
extern XPowersPPM *PPM;
#endif
#ifndef INCLUDE_vTaskSuspend #ifndef INCLUDE_vTaskSuspend
#define INCLUDE_vTaskSuspend 0 #define INCLUDE_vTaskSuspend 0
#endif #endif
@ -307,14 +297,6 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false, bool skipSaveN
#endif #endif
#endif #endif
#ifdef HAS_PPM
if (PPM) {
LOG_INFO("PMM shutdown");
console->flush();
PPM->shutdown();
}
#endif
#ifdef HAS_PMU #ifdef HAS_PMU
if (pmu_found && PMU) { if (pmu_found && PMU) {
// Obsolete comment: from back when we we used to receive lora packets while CPU was in deep sleep. // Obsolete comment: from back when we we used to receive lora packets while CPU was in deep sleep.
@ -430,16 +412,6 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
if (pmu_found) if (pmu_found)
gpio_wakeup_enable((gpio_num_t)PMU_IRQ, GPIO_INTR_LOW_LEVEL); // pmu irq gpio_wakeup_enable((gpio_num_t)PMU_IRQ, GPIO_INTR_LOW_LEVEL); // pmu irq
#endif #endif
#ifdef T_LORA_PAGER
LOG_DEBUG("power down XL9555 io");
io.digitalWrite(EXPANDS_DRV_EN, LOW);
io.digitalWrite(EXPANDS_AMP_EN, LOW);
io.digitalWrite(EXPANDS_KB_EN, LOW);
io.digitalWrite(EXPANDS_SD_EN, LOW);
io.digitalWrite(EXPANDS_GPIO_EN, LOW);
#endif
auto res = esp_sleep_enable_gpio_wakeup(); auto res = esp_sleep_enable_gpio_wakeup();
if (res != ESP_OK) { if (res != ESP_OK) {
LOG_ERROR("esp_sleep_enable_gpio_wakeup result %d", res); LOG_ERROR("esp_sleep_enable_gpio_wakeup result %d", res);
@ -480,14 +452,6 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
gpio_wakeup_disable((gpio_num_t)RF95_IRQ); gpio_wakeup_disable((gpio_num_t)RF95_IRQ);
} }
#endif #endif
#ifdef T_LORA_PAGER
LOG_DEBUG("power up XL9555 io");
io.digitalWrite(EXPANDS_DRV_EN, HIGH);
io.digitalWrite(EXPANDS_AMP_EN, HIGH);
io.digitalWrite(EXPANDS_KB_EN, HIGH);
io.digitalWrite(EXPANDS_SD_EN, HIGH);
io.digitalWrite(EXPANDS_GPIO_EN, HIGH);
#endif
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause(); esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
notifyLightSleepEnd.notifyObservers(cause); // Button interrupts are reattached here notifyLightSleepEnd.notifyObservers(cause); // Button interrupts are reattached here

View File

@ -3,10 +3,7 @@ extends = portduino_base
build_flags = ${portduino_base.build_flags} -I variants/native/portduino build_flags = ${portduino_base.build_flags} -I variants/native/portduino
-I /usr/include -I /usr/include
board = cross_platform board = cross_platform
lib_deps = lib_deps = ${portduino_base.lib_deps}
${portduino_base.lib_deps}
melopero/Melopero RV3028@^1.1.0
build_src_filter = ${portduino_base.build_src_filter} build_src_filter = ${portduino_base.build_src_filter}
[env:native] [env:native]

View File

@ -4,7 +4,4 @@
#define CANNED_MESSAGE_MODULE_ENABLE 1 #define CANNED_MESSAGE_MODULE_ENABLE 1
#define HAS_GPS 1 #define HAS_GPS 1
#define MAX_RX_TOPHONE settingsMap[maxtophone] #define MAX_RX_TOPHONE settingsMap[maxtophone]
#define MAX_NUM_NODES settingsMap[maxnodes] #define MAX_NUM_NODES settingsMap[maxnodes]
// RAK12002 RTC Module
#define RV3028_RTC (uint8_t)0b1010010

View File

@ -208,7 +208,7 @@ No longer populated on PCB
#undef AREF_VOLTAGE #undef AREF_VOLTAGE
#define AREF_VOLTAGE 3.0 #define AREF_VOLTAGE 3.0
#define VBAT_AR_INTERNAL AR_INTERNAL_3_0 #define VBAT_AR_INTERNAL AR_INTERNAL_3_0
#define ADC_MULTIPLIER (4.99F) #define ADC_MULTIPLIER (4.90F)
#define HAS_RTC 0 #define HAS_RTC 0
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -124,7 +124,8 @@ extern "C" {
#define GPS_RTC_INT (0 + 15) // P0.15, normal is LOW, wake by HIGH #define GPS_RTC_INT (0 + 15) // P0.15, normal is LOW, wake by HIGH
#define GPS_RESETB_OUT (32 + 14) // P1.14, always input pull_up #define GPS_RESETB_OUT (32 + 14) // P1.14, always input pull_up
#define BATTERY_PIN 2 // P0.02/AIN0, BAT_ADC #define GPS_FIX_HOLD_TIME 15000 // ms
#define BATTERY_PIN 2 // P0.02/AIN0, BAT_ADC
#define BATTERY_IMMUTABLE #define BATTERY_IMMUTABLE
#define ADC_MULTIPLIER (2.0F) #define ADC_MULTIPLIER (2.0F)
// P0.04/AIN2 is VCC_ADC, P0.05/AIN3 is CHARGER_DET, P1.03 is CHARGE_STA, P1.04 is CHARGE_DONE // P0.04/AIN2 is VCC_ADC, P0.05/AIN3 is CHARGER_DET, P1.03 is CHARGE_STA, P1.04 is CHARGE_DONE

View File

@ -123,6 +123,7 @@ extern "C" {
#define GPS_RESETB_OUT (32 + 14) // P1.14, awlays input pull_up #define GPS_RESETB_OUT (32 + 14) // P1.14, awlays input pull_up
// #define GPS_THREAD_INTERVAL 50 // #define GPS_THREAD_INTERVAL 50
#define GPS_FIX_HOLD_TIME 15000 // ms
#define BATTERY_PIN 2 #define BATTERY_PIN 2
// #define ADC_CHANNEL ADC1_GPIO2_CHANNEL // #define ADC_CHANNEL ADC1_GPIO2_CHANNEL
@ -156,4 +157,4 @@ extern "C" {
* Arduino objects - C++ only * Arduino objects - C++ only
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#endif // _VARIANT_WIO_SDK_WM1110_ #endif // _VARIANT_WIO_SDK_WM1110_

View File

@ -6,10 +6,6 @@ board_upload.maximum_size = 233472 ; reserve the last 28KB for filesystem
build_flags = build_flags =
${stm32_base.build_flags} ${stm32_base.build_flags}
-Ivariants/stm32/rak3172 -Ivariants/stm32/rak3172
-DRAK3172
-DENABLE_HWSERIAL1
-DPIN_SERIAL1_RX=PB7
-DPIN_SERIAL1_TX=PB6
-DPIN_WIRE_SDA=PA11 -DPIN_WIRE_SDA=PA11
-DPIN_WIRE_SCL=PA12 -DPIN_WIRE_SCL=PA12
-DMESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR=1 -DMESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR=1