Compare commits

..

5 Commits

Author SHA1 Message Date
renovate[bot]
e95c6077cd chore(deps): update meshtastic-esp32_https_server digest to b0f3960 2026-01-22 04:30:58 +00:00
renovate[bot]
3e3299f549 Update meshtastic/device-ui digest to 613c095 (#9383)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-22 09:07:23 +11:00
Ben Meadors
fb3bf783dd Implement graduated scaling for NodeInfo send timeout based on active mesh size (#9364)
* Implement graduated scaling for NodeInfo send timeout based on active mesh size

* Shorter timeout still needed for pubkey unkown and ad-hoc send

* Update src/modules/NodeInfoModule.cpp

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-19 20:00:41 -06:00
Ben Meadors
fc268d43d0 Add Meshtastic exclusion flags for webserver and paxcounter in platformio.ini 2026-01-19 16:57:21 -06:00
Jonathan Bennett
c38aff7e52 Add interrupt for external charge detection (#9332)
Tested on Thinknode m4, m6, and T1000-e
2026-01-19 15:39:24 -06:00
32 changed files with 185 additions and 1484 deletions

View File

@@ -119,7 +119,7 @@ lib_deps =
[device-ui_base] [device-ui_base]
lib_deps = lib_deps =
# renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master # renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master
https://github.com/meshtastic/device-ui/archive/3480b731d28b10d73414cf0dd7975bff745de8cf.zip https://github.com/meshtastic/device-ui/archive/613c0953313bbd236f4ddc5ede447e9edf8e890a.zip
; Common libs for environmental measurements in telemetry module ; Common libs for environmental measurements in telemetry module
[environmental_base] [environmental_base]

View File

@@ -723,6 +723,16 @@ bool Power::setup()
runASAP = true; runASAP = true;
}, },
CHANGE); CHANGE);
#endif
#ifdef EXT_CHRG_DETECT
attachInterrupt(
EXT_CHRG_DETECT,
[]() {
power->setIntervalFromNow(0);
runASAP = true;
BaseType_t higherWake = 0;
},
CHANGE);
#endif #endif
enabled = found; enabled = found;
low_voltage_counter = 0; low_voltage_counter = 0;

View File

@@ -155,10 +155,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#endif #endif
// Default system gain to 0 if not defined // Default system gain to 0 if not defined
#ifndef NUM_PA_POINTS
#define NUM_PA_POINTS 1
#endif
#ifndef TX_GAIN_LORA #ifndef TX_GAIN_LORA
#define TX_GAIN_LORA 0 #define TX_GAIN_LORA 0
#endif #endif

View File

@@ -155,18 +155,6 @@ void InkHUD::LogoApplet::onShutdown()
// This is then drawn by InkHUD::Events::onShutdown, with a blocking FULL update, after InkHUD's flash write is complete // This is then drawn by InkHUD::Events::onShutdown, with a blocking FULL update, after InkHUD's flash write is complete
} }
void InkHUD::LogoApplet::onApplyingChanges()
{
bringToForeground();
textLeft = "";
textRight = "";
textTitle = "Applying changes";
fontTitle = fontSmall;
inkhud->forceUpdate(Drivers::EInk::FAST, false);
}
void InkHUD::LogoApplet::onReboot() void InkHUD::LogoApplet::onReboot()
{ {
bringToForeground(); bringToForeground();

View File

@@ -26,7 +26,6 @@ class LogoApplet : public SystemApplet, public concurrency::OSThread
void onBackground() override; void onBackground() override;
void onShutdown() override; void onShutdown() override;
void onReboot() override; void onReboot() override;
void onApplyingChanges();
protected: protected:
int32_t runOnce() override; int32_t runOnce() override;

View File

@@ -22,7 +22,6 @@ enum MenuAction {
STORE_CANNEDMESSAGE_SELECTION, STORE_CANNEDMESSAGE_SELECTION,
SEND_CANNEDMESSAGE, SEND_CANNEDMESSAGE,
SHUTDOWN, SHUTDOWN,
BACK,
NEXT_TILE, NEXT_TILE,
TOGGLE_BACKLIGHT, TOGGLE_BACKLIGHT,
TOGGLE_GPS, TOGGLE_GPS,
@@ -37,84 +36,6 @@ enum MenuAction {
TOGGLE_NOTIFICATIONS, TOGGLE_NOTIFICATIONS,
TOGGLE_INVERT_COLOR, TOGGLE_INVERT_COLOR,
TOGGLE_12H_CLOCK, TOGGLE_12H_CLOCK,
// Regions
SET_REGION_US,
SET_REGION_EU_868,
SET_REGION_EU_433,
SET_REGION_CN,
SET_REGION_JP,
SET_REGION_ANZ,
SET_REGION_KR,
SET_REGION_TW,
SET_REGION_RU,
SET_REGION_IN,
SET_REGION_NZ_865,
SET_REGION_TH,
SET_REGION_LORA_24,
SET_REGION_UA_433,
SET_REGION_UA_868,
SET_REGION_MY_433,
SET_REGION_MY_919,
SET_REGION_SG_923,
SET_REGION_PH_433,
SET_REGION_PH_868,
SET_REGION_PH_915,
SET_REGION_ANZ_433,
SET_REGION_KZ_433,
SET_REGION_KZ_863,
SET_REGION_NP_865,
SET_REGION_BR_902,
// Device Roles
SET_ROLE_CLIENT,
SET_ROLE_CLIENT_MUTE,
SET_ROLE_ROUTER,
SET_ROLE_REPEATER,
// Presets
SET_PRESET_LONG_SLOW,
SET_PRESET_LONG_MODERATE,
SET_PRESET_LONG_FAST,
SET_PRESET_MEDIUM_SLOW,
SET_PRESET_MEDIUM_FAST,
SET_PRESET_SHORT_SLOW,
SET_PRESET_SHORT_FAST,
SET_PRESET_SHORT_TURBO,
// Timezones
SET_TZ_US_HAWAII,
SET_TZ_US_ALASKA,
SET_TZ_US_PACIFIC,
SET_TZ_US_ARIZONA,
SET_TZ_US_MOUNTAIN,
SET_TZ_US_CENTRAL,
SET_TZ_US_EASTERN,
SET_TZ_BR_BRAZILIA,
SET_TZ_UTC,
SET_TZ_EU_WESTERN,
SET_TZ_EU_CENTRAL,
SET_TZ_EU_EASTERN,
SET_TZ_ASIA_KOLKATA,
SET_TZ_ASIA_HONG_KONG,
SET_TZ_AU_AWST,
SET_TZ_AU_ACST,
SET_TZ_AU_AEST,
SET_TZ_PACIFIC_NZ,
// Power
TOGGLE_POWER_SAVE,
CALIBRATE_ADC,
// Bluetooth
TOGGLE_BLUETOOTH,
TOGGLE_BLUETOOTH_PAIR_MODE,
// Channel
TOGGLE_CHANNEL_UPLINK,
TOGGLE_CHANNEL_DOWNLINK,
TOGGLE_CHANNEL_POSITION,
SET_CHANNEL_PRECISION,
// Display
TOGGLE_DISPLAY_UNITS,
// Network
TOGGLE_WIFI,
// Administration
RESET_NODEDB_ALL,
RESET_NODEDB_KEEP_FAVORITES,
}; };
} // namespace NicheGraphics::InkHUD } // namespace NicheGraphics::InkHUD

File diff suppressed because it is too large Load Diff

View File

@@ -35,7 +35,6 @@ class MenuApplet : public SystemApplet, public concurrency::OSThread
void onRender() override; void onRender() override;
void show(Tile *t); // Open the menu, onto a user tile void show(Tile *t); // Open the menu, onto a user tile
void setStartPage(MenuPage page);
protected: protected:
Drivers::LatchingBacklight *backlight = nullptr; // Convenient access to the backlight singleton Drivers::LatchingBacklight *backlight = nullptr; // Convenient access to the backlight singleton
@@ -57,7 +56,6 @@ class MenuApplet : public SystemApplet, public concurrency::OSThread
void sendText(NodeNum dest, ChannelIndex channel, const char *message); // Send a text message to mesh void sendText(NodeNum dest, ChannelIndex channel, const char *message); // Send a text message to mesh
void freeCannedMessageResources(); // Clear MenuApplet's canned message processing data void freeCannedMessageResources(); // Clear MenuApplet's canned message processing data
MenuPage startPageOverride = MenuPage::ROOT;
MenuPage currentPage = MenuPage::ROOT; MenuPage currentPage = MenuPage::ROOT;
MenuPage previousPage = MenuPage::EXIT; MenuPage previousPage = MenuPage::EXIT;
uint8_t cursor = 0; // Which menu item is currently highlighted uint8_t cursor = 0; // Which menu item is currently highlighted
@@ -65,15 +63,7 @@ class MenuApplet : public SystemApplet, public concurrency::OSThread
uint16_t systemInfoPanelHeight = 0; // Need to know before we render uint16_t systemInfoPanelHeight = 0; // Need to know before we render
std::vector<MenuItem> items; // MenuItems for the current page. Filled by ShowPage std::vector<MenuItem> items; // MenuItems for the current page. Filled by ShowPage
std::vector<std::string> nodeConfigLabels; // Persistent labels for Node Config pages
uint8_t selectedChannelIndex = 0; // Currently selected LoRa channel (Node Config → Radio → Channel)
bool channelPositionEnabled = false;
bool gpsEnabled = false;
// Recents menu checkbox state (derived from settings.recentlyActiveSeconds)
static constexpr uint8_t RECENTS_COUNT = 6;
bool recentsSelected[RECENTS_COUNT] = {};
// Data for selecting and sending canned messages via the menu // Data for selecting and sending canned messages via the menu
// Placed into a sub-class for organization only // Placed into a sub-class for organization only

View File

@@ -30,7 +30,6 @@ class MenuItem
MenuAction action = NO_ACTION; MenuAction action = NO_ACTION;
MenuPage nextPage = EXIT; MenuPage nextPage = EXIT;
bool *checkState = nullptr; bool *checkState = nullptr;
bool isHeader = false; // Non-selectable section label
// Various constructors, depending on the intended function of the item // Various constructors, depending on the intended function of the item
@@ -41,12 +40,6 @@ class MenuItem
: label(label), action(action), nextPage(nextPage), checkState(checkState) : label(label), action(action), nextPage(nextPage), checkState(checkState)
{ {
} }
static MenuItem Header(const char *label)
{
MenuItem item(label, NO_ACTION, EXIT);
item.isHeader = true;
return item;
}
}; };
} // namespace NicheGraphics::InkHUD } // namespace NicheGraphics::InkHUD

View File

@@ -20,27 +20,10 @@ enum MenuPage : uint8_t {
SEND, SEND,
CANNEDMESSAGE_RECIPIENT, // Select destination for a canned message CANNEDMESSAGE_RECIPIENT, // Select destination for a canned message
OPTIONS, OPTIONS,
NODE_CONFIG,
NODE_CONFIG_LORA,
NODE_CONFIG_CHANNELS, // List of channels
NODE_CONFIG_CHANNEL_DETAIL, // Per-channel options
NODE_CONFIG_CHANNEL_PRECISION,
NODE_CONFIG_PRESET,
NODE_CONFIG_DEVICE,
NODE_CONFIG_DEVICE_ROLE,
NODE_CONFIG_POWER,
NODE_CONFIG_POWER_ADC_CAL,
NODE_CONFIG_NETWORK,
NODE_CONFIG_DISPLAY,
NODE_CONFIG_BLUETOOTH,
NODE_CONFIG_POSITION,
NODE_CONFIG_ADMIN_RESET,
TIMEZONE,
APPLETS, APPLETS,
AUTOSHOW, AUTOSHOW,
RECENTS, // Select length of "recentlyActiveSeconds" RECENTS, // Select length of "recentlyActiveSeconds"
REGION, EXIT, // Dismiss the menu applet
EXIT, // Dismiss the menu applet
}; };
} // namespace NicheGraphics::InkHUD } // namespace NicheGraphics::InkHUD

View File

@@ -10,37 +10,34 @@ using namespace NicheGraphics;
InkHUD::TipsApplet::TipsApplet() InkHUD::TipsApplet::TipsApplet()
{ {
bool needsRegion = (config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET); // Decide which tips (if any) should be shown to user after the boot screen
bool showTutorialTips = (settings->tips.firstBoot || needsRegion);
// Welcome screen // Welcome screen
if (showTutorialTips) if (settings->tips.firstBoot)
tipQueue.push_back(Tip::WELCOME); tipQueue.push_back(Tip::WELCOME);
// Finish setup // Antenna, region, timezone
if (needsRegion) // Shown at boot if region not yet set
if (config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET)
tipQueue.push_back(Tip::FINISH_SETUP); tipQueue.push_back(Tip::FINISH_SETUP);
// Using the UI
if (showTutorialTips) {
tipQueue.push_back(Tip::CUSTOMIZATION);
tipQueue.push_back(Tip::BUTTONS);
}
// Shutdown info // Shutdown info
// Shown until user performs one valid shutdown // Shown until user performs one valid shutdown
if (!settings->tips.safeShutdownSeen) if (!settings->tips.safeShutdownSeen)
tipQueue.push_back(Tip::SAFE_SHUTDOWN); tipQueue.push_back(Tip::SAFE_SHUTDOWN);
// Using the UI
if (settings->tips.firstBoot) {
tipQueue.push_back(Tip::CUSTOMIZATION);
tipQueue.push_back(Tip::BUTTONS);
}
// Catch an incorrect attempt at rotating display // Catch an incorrect attempt at rotating display
if (config.display.flip_screen) if (config.display.flip_screen)
tipQueue.push_back(Tip::ROTATION); tipQueue.push_back(Tip::ROTATION);
// Region picker // Applet is foreground immediately at boot, but is obscured by LogoApplet, which is also foreground
if (needsRegion) // LogoApplet can be considered to have a higher Z-index, because it is placed before TipsApplet in the systemApplets vector
tipQueue.push_back(Tip::PICK_REGION);
if (!tipQueue.empty()) if (!tipQueue.empty())
bringToForeground(); bringToForeground();
} }
@@ -54,109 +51,81 @@ void InkHUD::TipsApplet::onRender()
case Tip::FINISH_SETUP: { case Tip::FINISH_SETUP: {
setFont(fontMedium); setFont(fontMedium);
const char *title = "Tip: Finish Setup"; printAt(0, 0, "Tip: Finish Setup");
uint16_t h = getWrappedTextHeight(0, width(), title);
printWrapped(0, 0, width(), title);
setFont(fontSmall); setFont(fontSmall);
int16_t cursorY = h + fontSmall.lineHeight(); int16_t cursorY = fontMedium.lineHeight() * 1.5;
printAt(0, cursorY, "- connect antenna");
auto drawBullet = [&](const char *text) { cursorY += fontSmall.lineHeight() * 1.2;
uint16_t bh = getWrappedTextHeight(0, width(), text); printAt(0, cursorY, "- connect a client app");
printWrapped(0, cursorY, width(), text);
cursorY += bh + (fontSmall.lineHeight() / 3);
};
drawBullet("- connect antenna"); // Only if region not set
drawBullet("- connect a client app"); if (config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET) {
cursorY += fontSmall.lineHeight() * 1.2;
printAt(0, cursorY, "- set region");
}
if (config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET) // Only if tz not set
drawBullet("- set region"); if (!(*config.device.tzdef && config.device.tzdef[0] != 0)) {
cursorY += fontSmall.lineHeight() * 1.2;
printAt(0, cursorY, "- set timezone");
}
if (!(*config.device.tzdef && config.device.tzdef[0] != 0)) cursorY += fontSmall.lineHeight() * 1.5;
drawBullet("- set timezone"); printAt(0, cursorY, "More info at meshtastic.org");
cursorY += fontSmall.lineHeight() / 2;
drawBullet("More info at meshtastic.org");
setFont(fontSmall);
printAt(0, Y(1.0), "Press button to continue", LEFT, BOTTOM); printAt(0, Y(1.0), "Press button to continue", LEFT, BOTTOM);
} break; } break;
case Tip::PICK_REGION: {
setFont(fontMedium);
printAt(0, 0, "Set Region");
setFont(fontSmall);
printWrapped(0, fontMedium.lineHeight() * 1.5, width(), "Please select your LoRa region to complete setup.");
printAt(0, Y(1.0), "Press button to choose", LEFT, BOTTOM);
} break;
case Tip::SAFE_SHUTDOWN: { case Tip::SAFE_SHUTDOWN: {
setFont(fontMedium); setFont(fontMedium);
printAt(0, 0, "Tip: Shutdown");
const char *title = "Tip: Shutdown";
uint16_t h = getWrappedTextHeight(0, width(), title);
printWrapped(0, 0, width(), title);
setFont(fontSmall); setFont(fontSmall);
int16_t cursorY = h + fontSmall.lineHeight(); std::string shutdown;
shutdown += "Before removing power, please shut down from InkHUD menu, or a client app. \n";
const char *body = "Before removing power, please shut down from InkHUD menu, or a client app.\n\n" shutdown += "\n";
"This ensures data is saved."; shutdown += "This ensures data is saved.";
printWrapped(0, fontMedium.lineHeight() * 1.5, width(), shutdown);
uint16_t bodyH = getWrappedTextHeight(0, width(), body);
printWrapped(0, cursorY, width(), body);
cursorY += bodyH + (fontSmall.lineHeight() / 2);
printAt(0, Y(1.0), "Press button to continue", LEFT, BOTTOM); printAt(0, Y(1.0), "Press button to continue", LEFT, BOTTOM);
} break; } break;
case Tip::CUSTOMIZATION: { case Tip::CUSTOMIZATION: {
setFont(fontMedium); setFont(fontMedium);
printAt(0, 0, "Tip: Customization");
const char *title = "Tip: Customization";
uint16_t h = getWrappedTextHeight(0, width(), title);
printWrapped(0, 0, width(), title);
setFont(fontSmall); setFont(fontSmall);
int16_t cursorY = h + fontSmall.lineHeight(); printWrapped(0, fontMedium.lineHeight() * 1.5, width(),
"Configure & control display with the InkHUD menu. Optional features, layout, rotation, and more.");
const char *body = "Configure & control display with the InkHUD menu. "
"Optional features, layout, rotation, and more.";
uint16_t bodyH = getWrappedTextHeight(0, width(), body);
printWrapped(0, cursorY, width(), body);
cursorY += bodyH + (fontSmall.lineHeight() / 2);
printAt(0, Y(1.0), "Press button to continue", LEFT, BOTTOM); printAt(0, Y(1.0), "Press button to continue", LEFT, BOTTOM);
} break; } break;
case Tip::BUTTONS: { case Tip::BUTTONS: {
setFont(fontMedium); setFont(fontMedium);
printAt(0, 0, "Tip: Buttons");
const char *title = "Tip: Buttons";
uint16_t h = getWrappedTextHeight(0, width(), title);
printWrapped(0, 0, width(), title);
setFont(fontSmall); setFont(fontSmall);
int16_t cursorY = h + fontSmall.lineHeight(); int16_t cursorY = fontMedium.lineHeight() * 1.5;
auto drawBullet = [&](const char *text) {
uint16_t bh = getWrappedTextHeight(0, width(), text);
printWrapped(0, cursorY, width(), text);
cursorY += bh + (fontSmall.lineHeight() / 3);
};
if (!settings->joystick.enabled) { if (!settings->joystick.enabled) {
drawBullet("User Button"); printAt(0, cursorY, "User Button");
drawBullet("- short press: next"); cursorY += fontSmall.lineHeight() * 1.2;
drawBullet("- long press: select or open menu"); printAt(0, cursorY, "- short press: next");
cursorY += fontSmall.lineHeight() * 1.2;
printAt(0, cursorY, "- long press: select / open menu");
} else { } else {
drawBullet("Joystick"); printAt(0, cursorY, "Joystick");
drawBullet("- press: open menu or select"); cursorY += fontSmall.lineHeight() * 1.2;
drawBullet("Exit Button"); printAt(0, cursorY, "- open menu / select");
drawBullet("- press: switch tile or close menu"); cursorY += fontSmall.lineHeight() * 1.5;
printAt(0, cursorY, "Exit Button");
cursorY += fontSmall.lineHeight() * 1.2;
printAt(0, cursorY, "- switch tile / close menu");
} }
printAt(0, Y(1.0), "Press button to continue", LEFT, BOTTOM); printAt(0, Y(1.0), "Press button to continue", LEFT, BOTTOM);
@@ -164,21 +133,12 @@ void InkHUD::TipsApplet::onRender()
case Tip::ROTATION: { case Tip::ROTATION: {
setFont(fontMedium); setFont(fontMedium);
printAt(0, 0, "Tip: Rotation");
const char *title = "Tip: Rotation";
uint16_t h = getWrappedTextHeight(0, width(), title);
printWrapped(0, 0, width(), title);
setFont(fontSmall); setFont(fontSmall);
if (!settings->joystick.enabled) { if (!settings->joystick.enabled) {
int16_t cursorY = h + fontSmall.lineHeight(); printWrapped(0, fontMedium.lineHeight() * 1.5, width(),
"To rotate the display, use the InkHUD menu. Long-press the user button > Options > Rotate.");
const char *body = "To rotate the display, use the InkHUD menu. "
"Long-press the user button > Options > Rotate.";
uint16_t bh = getWrappedTextHeight(0, width(), body);
printWrapped(0, cursorY, width(), body);
cursorY += bh + (fontSmall.lineHeight() / 2);
} else { } else {
printWrapped(0, fontMedium.lineHeight() * 1.5, width(), printWrapped(0, fontMedium.lineHeight() * 1.5, width(),
"To rotate the display, use the InkHUD menu. Press the user button > Options > Rotate."); "To rotate the display, use the InkHUD menu. Press the user button > Options > Rotate.");
@@ -199,15 +159,12 @@ void InkHUD::TipsApplet::renderWelcome()
{ {
uint16_t padW = X(0.05); uint16_t padW = X(0.05);
// Detect portrait orientation
bool portrait = height() > width();
// Block 1 - logo & title // Block 1 - logo & title
// ======================== // ========================
// Logo size // Logo size
uint16_t logoWLimit = portrait ? X(0.5) : X(0.3); uint16_t logoWLimit = X(0.3);
uint16_t logoHLimit = portrait ? Y(0.25) : Y(0.3); uint16_t logoHLimit = Y(0.3);
uint16_t logoW = getLogoWidth(logoWLimit, logoHLimit); uint16_t logoW = getLogoWidth(logoWLimit, logoHLimit);
uint16_t logoH = getLogoHeight(logoWLimit, logoHLimit); uint16_t logoH = getLogoHeight(logoWLimit, logoHLimit);
@@ -220,7 +177,7 @@ void InkHUD::TipsApplet::renderWelcome()
// Center the block // Center the block
// Desired effect: equal margin from display edge for logo left and title right // Desired effect: equal margin from display edge for logo left and title right
int16_t block1Y = portrait ? Y(0.2) : Y(0.3); int16_t block1Y = Y(0.3);
int16_t block1CX = X(0.5) + (logoW / 2) - (titleW / 2); int16_t block1CX = X(0.5) + (logoW / 2) - (titleW / 2);
int16_t logoCX = block1CX - (logoW / 2) - (padW / 2); int16_t logoCX = block1CX - (logoW / 2) - (padW / 2);
int16_t titleCX = block1CX + (titleW / 2) + (padW / 2); int16_t titleCX = block1CX + (titleW / 2) + (padW / 2);
@@ -235,7 +192,7 @@ void InkHUD::TipsApplet::renderWelcome()
std::string subtitle = "InkHUD"; std::string subtitle = "InkHUD";
if (width() >= 200) if (width() >= 200)
subtitle += " - A Heads-Up Display"; // Future proofing: narrower for tiny display subtitle += " - A Heads-Up Display"; // Future proofing: narrower for tiny display
printAt(X(0.5), portrait ? Y(0.45) : Y(0.6), subtitle, CENTER, MIDDLE); printAt(X(0.5), Y(0.6), subtitle, CENTER, MIDDLE);
// Block 3 - press to continue // Block 3 - press to continue
// ============================ // ============================
@@ -267,37 +224,26 @@ void InkHUD::TipsApplet::onBackground()
// While our SystemApplet::handleInput flag is true // While our SystemApplet::handleInput flag is true
void InkHUD::TipsApplet::onButtonShortPress() void InkHUD::TipsApplet::onButtonShortPress()
{ {
bool needsRegion = (config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET);
// If we're prompting the user to pick a region, hand off to the menu
if (!tipQueue.empty() && tipQueue.front() == Tip::PICK_REGION) {
tipQueue.pop_front();
// Signal InkHUD to open the menu on Region page
inkhud->forceRegionMenu = true;
// Close tips and open menu
sendToBackground();
inkhud->openMenu();
return;
}
// Consume current tip
tipQueue.pop_front(); tipQueue.pop_front();
// All tips done // All tips done
if (tipQueue.empty()) { if (tipQueue.empty()) {
// Record that user has now seen the "tutorial" set of tips // Record that user has now seen the "tutorial" set of tips
// Don't show them on subsequent boots // Don't show them on subsequent boots
if (settings->tips.firstBoot && !needsRegion) { if (settings->tips.firstBoot) {
settings->tips.firstBoot = false; settings->tips.firstBoot = false;
inkhud->persistence->saveSettings(); inkhud->persistence->saveSettings();
} }
// Close applet and clean the screen // Close applet, and full refresh to clean the screen
// Need to force update, because our request would be ignored otherwise, as we are now background
sendToBackground(); sendToBackground();
inkhud->forceUpdate(EInk::UpdateTypes::FULL); inkhud->forceUpdate(EInk::UpdateTypes::FULL);
} else {
requestUpdate();
} }
// More tips left
else
requestUpdate();
} }
// Functions the same as the user button in this instance // Functions the same as the user button in this instance

View File

@@ -23,7 +23,6 @@ class TipsApplet : public SystemApplet
enum class Tip { enum class Tip {
WELCOME, WELCOME,
FINISH_SETUP, FINISH_SETUP,
PICK_REGION,
SAFE_SHUTDOWN, SAFE_SHUTDOWN,
CUSTOMIZATION, CUSTOMIZATION,
BUTTONS, BUTTONS,

View File

@@ -276,15 +276,6 @@ int InkHUD::Events::beforeDeepSleep(void *unused)
return 0; // We agree: deep sleep now return 0; // We agree: deep sleep now
} }
// Display an intermediate screen while configuration changes are applied
void InkHUD::Events::applyingChanges()
{
// Bring the logo applet forward with a temporary message
for (SystemApplet *sa : inkhud->systemApplets) {
sa->onApplyingChanges();
}
}
// Callback for rebootObserver // Callback for rebootObserver
// Same as shutdown, without drawing the logoApplet // Same as shutdown, without drawing the logoApplet
// Makes sure we don't lose message history / InkHUD config // Makes sure we don't lose message history / InkHUD config

View File

@@ -29,13 +29,12 @@ class Events
void onButtonShort(); // User button: short press void onButtonShort(); // User button: short press
void onButtonLong(); // User button: long press void onButtonLong(); // User button: long press
void applyingChanges(); void onExitShort(); // Exit button: short press
void onExitShort(); // Exit button: short press void onExitLong(); // Exit button: long press
void onExitLong(); // Exit button: long press void onNavUp(); // Navigate up
void onNavUp(); // Navigate up void onNavDown(); // Navigate down
void onNavDown(); // Navigate down void onNavLeft(); // Navigate left
void onNavLeft(); // Navigate left void onNavRight(); // Navigate right
void onNavRight(); // Navigate right
int beforeDeepSleep(void *unused); // Prepare for shutdown int beforeDeepSleep(void *unused); // Prepare for shutdown
int beforeReboot(void *unused); // Prepare for reboot int beforeReboot(void *unused); // Prepare for reboot

View File

@@ -53,13 +53,6 @@ void InkHUD::InkHUD::addApplet(const char *name, Applet *a, bool defaultActive,
windowManager->addApplet(name, a, defaultActive, defaultAutoshow, onTile); windowManager->addApplet(name, a, defaultActive, defaultAutoshow, onTile);
} }
void InkHUD::InkHUD::notifyApplyingChanges()
{
if (events) {
events->applyingChanges();
}
}
// Start InkHUD! // Start InkHUD!
// Call this only after you have configured InkHUD // Call this only after you have configured InkHUD
void InkHUD::InkHUD::begin() void InkHUD::InkHUD::begin()

View File

@@ -47,7 +47,6 @@ class InkHUD
void setDriver(Drivers::EInk *driver); void setDriver(Drivers::EInk *driver);
void setDisplayResilience(uint8_t fastPerFull = 5, float stressMultiplier = 2.0); void setDisplayResilience(uint8_t fastPerFull = 5, float stressMultiplier = 2.0);
void addApplet(const char *name, Applet *a, bool defaultActive = false, bool defaultAutoshow = false, uint8_t onTile = -1); void addApplet(const char *name, Applet *a, bool defaultActive = false, bool defaultAutoshow = false, uint8_t onTile = -1);
void notifyApplyingChanges();
void begin(); void begin();
@@ -77,9 +76,6 @@ class InkHUD
void rotateJoystick(uint8_t angle = 1); // rotate 90 deg by default void rotateJoystick(uint8_t angle = 1); // rotate 90 deg by default
void toggleBatteryIcon(); void toggleBatteryIcon();
// Used by TipsApplet to force menu to start on Region selection
bool forceRegionMenu = false;
// Updating the display // Updating the display
// - called by various InkHUD components // - called by various InkHUD components

View File

@@ -27,7 +27,6 @@ class SystemApplet : public Applet
bool lockRequests = false; // - prevent other applets from triggering display updates bool lockRequests = false; // - prevent other applets from triggering display updates
virtual void onReboot() { onShutdown(); } // - handle reboot specially virtual void onReboot() { onShutdown(); } // - handle reboot specially
virtual void onApplyingChanges() {}
// Other system applets may take precedence over our own system applet though // Other system applets may take precedence over our own system applet though
// The order an applet is passed to WindowManager::addSystemApplet determines this hierarchy (added earlier = higher rank) // The order an applet is passed to WindowManager::addSystemApplet determines this hierarchy (added earlier = higher rank)

View File

@@ -666,24 +666,18 @@ void RadioInterface::limitPower(int8_t loraMaxPower)
power = maxPower; power = maxPower;
} }
#ifdef ARCH_PORTDUINO #ifndef NUM_PA_POINTS
size_t num_pa_points = portduino_config.num_pa_points; if (TX_GAIN_LORA > 0 && !devicestate.owner.is_licensed) {
const uint16_t *tx_gain = portduino_config.tx_gain_lora; LOG_INFO("Requested Tx power: %d dBm; Device LoRa Tx gain: %d dB", power, TX_GAIN_LORA);
power -= TX_GAIN_LORA;
}
#else #else
size_t num_pa_points = NUM_PA_POINTS; if (!devicestate.owner.is_licensed) {
const uint16_t tx_gain[NUM_PA_POINTS] = {TX_GAIN_LORA};
#endif
if (num_pa_points == 1) {
if (tx_gain[0] > 0 && !devicestate.owner.is_licensed) {
LOG_INFO("Requested Tx power: %d dBm; Device LoRa Tx gain: %d dB", power, tx_gain[0]);
power -= tx_gain[0];
}
} else if (!devicestate.owner.is_licensed) {
// we have an array of PA gain values. Find the highest power setting that works. // we have an array of PA gain values. Find the highest power setting that works.
for (int radio_dbm = 0; radio_dbm < num_pa_points; radio_dbm++) { const uint16_t tx_gain[NUM_PA_POINTS] = {TX_GAIN_LORA};
for (int radio_dbm = 0; radio_dbm < NUM_PA_POINTS; radio_dbm++) {
if (((radio_dbm + tx_gain[radio_dbm]) > power) || if (((radio_dbm + tx_gain[radio_dbm]) > power) ||
((radio_dbm == (num_pa_points - 1)) && ((radio_dbm + tx_gain[radio_dbm]) <= power))) { ((radio_dbm == (NUM_PA_POINTS - 1)) && ((radio_dbm + tx_gain[radio_dbm]) <= power))) {
// we've exceeded the power limit, or hit the max we can do // we've exceeded the power limit, or hit the max we can do
LOG_INFO("Requested Tx power: %d dBm; Device LoRa Tx gain: %d dB", power, tx_gain[radio_dbm]); LOG_INFO("Requested Tx power: %d dBm; Device LoRa Tx gain: %d dB", power, tx_gain[radio_dbm]);
power -= tx_gain[radio_dbm]; power -= tx_gain[radio_dbm];
@@ -691,7 +685,7 @@ void RadioInterface::limitPower(int8_t loraMaxPower)
} }
} }
} }
#endif
if (power > loraMaxPower) // Clamp power to maximum defined level if (power > loraMaxPower) // Clamp power to maximum defined level
power = loraMaxPower; power = loraMaxPower;

View File

@@ -77,9 +77,7 @@ typedef enum _meshtastic_AdminMessage_ModuleConfigType {
/* TODO: REPLACE */ /* TODO: REPLACE */
meshtastic_AdminMessage_ModuleConfigType_DETECTIONSENSOR_CONFIG = 11, meshtastic_AdminMessage_ModuleConfigType_DETECTIONSENSOR_CONFIG = 11,
/* TODO: REPLACE */ /* TODO: REPLACE */
meshtastic_AdminMessage_ModuleConfigType_PAXCOUNTER_CONFIG = 12, meshtastic_AdminMessage_ModuleConfigType_PAXCOUNTER_CONFIG = 12
/* TODO: REPLACE */
meshtastic_AdminMessage_ModuleConfigType_STATUSMESSAGE_CONFIG = 13
} meshtastic_AdminMessage_ModuleConfigType; } meshtastic_AdminMessage_ModuleConfigType;
typedef enum _meshtastic_AdminMessage_BackupLocation { typedef enum _meshtastic_AdminMessage_BackupLocation {
@@ -325,8 +323,8 @@ extern "C" {
#define _meshtastic_AdminMessage_ConfigType_ARRAYSIZE ((meshtastic_AdminMessage_ConfigType)(meshtastic_AdminMessage_ConfigType_DEVICEUI_CONFIG+1)) #define _meshtastic_AdminMessage_ConfigType_ARRAYSIZE ((meshtastic_AdminMessage_ConfigType)(meshtastic_AdminMessage_ConfigType_DEVICEUI_CONFIG+1))
#define _meshtastic_AdminMessage_ModuleConfigType_MIN meshtastic_AdminMessage_ModuleConfigType_MQTT_CONFIG #define _meshtastic_AdminMessage_ModuleConfigType_MIN meshtastic_AdminMessage_ModuleConfigType_MQTT_CONFIG
#define _meshtastic_AdminMessage_ModuleConfigType_MAX meshtastic_AdminMessage_ModuleConfigType_STATUSMESSAGE_CONFIG #define _meshtastic_AdminMessage_ModuleConfigType_MAX meshtastic_AdminMessage_ModuleConfigType_PAXCOUNTER_CONFIG
#define _meshtastic_AdminMessage_ModuleConfigType_ARRAYSIZE ((meshtastic_AdminMessage_ModuleConfigType)(meshtastic_AdminMessage_ModuleConfigType_STATUSMESSAGE_CONFIG+1)) #define _meshtastic_AdminMessage_ModuleConfigType_ARRAYSIZE ((meshtastic_AdminMessage_ModuleConfigType)(meshtastic_AdminMessage_ModuleConfigType_PAXCOUNTER_CONFIG+1))
#define _meshtastic_AdminMessage_BackupLocation_MIN meshtastic_AdminMessage_BackupLocation_FLASH #define _meshtastic_AdminMessage_BackupLocation_MIN meshtastic_AdminMessage_BackupLocation_FLASH
#define _meshtastic_AdminMessage_BackupLocation_MAX meshtastic_AdminMessage_BackupLocation_SD #define _meshtastic_AdminMessage_BackupLocation_MAX meshtastic_AdminMessage_BackupLocation_SD

View File

@@ -361,7 +361,7 @@ extern const pb_msgdesc_t meshtastic_BackupPreferences_msg;
/* Maximum encoded size of messages (where known) */ /* Maximum encoded size of messages (where known) */
/* meshtastic_NodeDatabase_size depends on runtime parameters */ /* meshtastic_NodeDatabase_size depends on runtime parameters */
#define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_BackupPreferences_size #define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_BackupPreferences_size
#define meshtastic_BackupPreferences_size 2362 #define meshtastic_BackupPreferences_size 2279
#define meshtastic_ChannelFile_size 718 #define meshtastic_ChannelFile_size 718
#define meshtastic_DeviceState_size 1737 #define meshtastic_DeviceState_size 1737
#define meshtastic_NodeInfoLite_size 196 #define meshtastic_NodeInfoLite_size 196

View File

@@ -87,9 +87,6 @@ typedef struct _meshtastic_LocalModuleConfig {
/* Paxcounter Config */ /* Paxcounter Config */
bool has_paxcounter; bool has_paxcounter;
meshtastic_ModuleConfig_PaxcounterConfig paxcounter; meshtastic_ModuleConfig_PaxcounterConfig paxcounter;
/* StatusMessage Config */
bool has_statusmessage;
meshtastic_ModuleConfig_StatusMessageConfig statusmessage;
} meshtastic_LocalModuleConfig; } meshtastic_LocalModuleConfig;
@@ -99,9 +96,9 @@ extern "C" {
/* Initializer values for message structs */ /* Initializer values for message structs */
#define meshtastic_LocalConfig_init_default {false, meshtastic_Config_DeviceConfig_init_default, false, meshtastic_Config_PositionConfig_init_default, false, meshtastic_Config_PowerConfig_init_default, false, meshtastic_Config_NetworkConfig_init_default, false, meshtastic_Config_DisplayConfig_init_default, false, meshtastic_Config_LoRaConfig_init_default, false, meshtastic_Config_BluetoothConfig_init_default, 0, false, meshtastic_Config_SecurityConfig_init_default} #define meshtastic_LocalConfig_init_default {false, meshtastic_Config_DeviceConfig_init_default, false, meshtastic_Config_PositionConfig_init_default, false, meshtastic_Config_PowerConfig_init_default, false, meshtastic_Config_NetworkConfig_init_default, false, meshtastic_Config_DisplayConfig_init_default, false, meshtastic_Config_LoRaConfig_init_default, false, meshtastic_Config_BluetoothConfig_init_default, 0, false, meshtastic_Config_SecurityConfig_init_default}
#define meshtastic_LocalModuleConfig_init_default {false, meshtastic_ModuleConfig_MQTTConfig_init_default, false, meshtastic_ModuleConfig_SerialConfig_init_default, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_default, false, meshtastic_ModuleConfig_StoreForwardConfig_init_default, false, meshtastic_ModuleConfig_RangeTestConfig_init_default, false, meshtastic_ModuleConfig_TelemetryConfig_init_default, false, meshtastic_ModuleConfig_CannedMessageConfig_init_default, 0, false, meshtastic_ModuleConfig_AudioConfig_init_default, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_default, false, meshtastic_ModuleConfig_NeighborInfoConfig_init_default, false, meshtastic_ModuleConfig_AmbientLightingConfig_init_default, false, meshtastic_ModuleConfig_DetectionSensorConfig_init_default, false, meshtastic_ModuleConfig_PaxcounterConfig_init_default, false, meshtastic_ModuleConfig_StatusMessageConfig_init_default} #define meshtastic_LocalModuleConfig_init_default {false, meshtastic_ModuleConfig_MQTTConfig_init_default, false, meshtastic_ModuleConfig_SerialConfig_init_default, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_default, false, meshtastic_ModuleConfig_StoreForwardConfig_init_default, false, meshtastic_ModuleConfig_RangeTestConfig_init_default, false, meshtastic_ModuleConfig_TelemetryConfig_init_default, false, meshtastic_ModuleConfig_CannedMessageConfig_init_default, 0, false, meshtastic_ModuleConfig_AudioConfig_init_default, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_default, false, meshtastic_ModuleConfig_NeighborInfoConfig_init_default, false, meshtastic_ModuleConfig_AmbientLightingConfig_init_default, false, meshtastic_ModuleConfig_DetectionSensorConfig_init_default, false, meshtastic_ModuleConfig_PaxcounterConfig_init_default}
#define meshtastic_LocalConfig_init_zero {false, meshtastic_Config_DeviceConfig_init_zero, false, meshtastic_Config_PositionConfig_init_zero, false, meshtastic_Config_PowerConfig_init_zero, false, meshtastic_Config_NetworkConfig_init_zero, false, meshtastic_Config_DisplayConfig_init_zero, false, meshtastic_Config_LoRaConfig_init_zero, false, meshtastic_Config_BluetoothConfig_init_zero, 0, false, meshtastic_Config_SecurityConfig_init_zero} #define meshtastic_LocalConfig_init_zero {false, meshtastic_Config_DeviceConfig_init_zero, false, meshtastic_Config_PositionConfig_init_zero, false, meshtastic_Config_PowerConfig_init_zero, false, meshtastic_Config_NetworkConfig_init_zero, false, meshtastic_Config_DisplayConfig_init_zero, false, meshtastic_Config_LoRaConfig_init_zero, false, meshtastic_Config_BluetoothConfig_init_zero, 0, false, meshtastic_Config_SecurityConfig_init_zero}
#define meshtastic_LocalModuleConfig_init_zero {false, meshtastic_ModuleConfig_MQTTConfig_init_zero, false, meshtastic_ModuleConfig_SerialConfig_init_zero, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero, false, meshtastic_ModuleConfig_StoreForwardConfig_init_zero, false, meshtastic_ModuleConfig_RangeTestConfig_init_zero, false, meshtastic_ModuleConfig_TelemetryConfig_init_zero, false, meshtastic_ModuleConfig_CannedMessageConfig_init_zero, 0, false, meshtastic_ModuleConfig_AudioConfig_init_zero, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero, false, meshtastic_ModuleConfig_NeighborInfoConfig_init_zero, false, meshtastic_ModuleConfig_AmbientLightingConfig_init_zero, false, meshtastic_ModuleConfig_DetectionSensorConfig_init_zero, false, meshtastic_ModuleConfig_PaxcounterConfig_init_zero, false, meshtastic_ModuleConfig_StatusMessageConfig_init_zero} #define meshtastic_LocalModuleConfig_init_zero {false, meshtastic_ModuleConfig_MQTTConfig_init_zero, false, meshtastic_ModuleConfig_SerialConfig_init_zero, false, meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero, false, meshtastic_ModuleConfig_StoreForwardConfig_init_zero, false, meshtastic_ModuleConfig_RangeTestConfig_init_zero, false, meshtastic_ModuleConfig_TelemetryConfig_init_zero, false, meshtastic_ModuleConfig_CannedMessageConfig_init_zero, 0, false, meshtastic_ModuleConfig_AudioConfig_init_zero, false, meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero, false, meshtastic_ModuleConfig_NeighborInfoConfig_init_zero, false, meshtastic_ModuleConfig_AmbientLightingConfig_init_zero, false, meshtastic_ModuleConfig_DetectionSensorConfig_init_zero, false, meshtastic_ModuleConfig_PaxcounterConfig_init_zero}
/* Field tags (for use in manual encoding/decoding) */ /* Field tags (for use in manual encoding/decoding) */
#define meshtastic_LocalConfig_device_tag 1 #define meshtastic_LocalConfig_device_tag 1
@@ -127,7 +124,6 @@ extern "C" {
#define meshtastic_LocalModuleConfig_ambient_lighting_tag 12 #define meshtastic_LocalModuleConfig_ambient_lighting_tag 12
#define meshtastic_LocalModuleConfig_detection_sensor_tag 13 #define meshtastic_LocalModuleConfig_detection_sensor_tag 13
#define meshtastic_LocalModuleConfig_paxcounter_tag 14 #define meshtastic_LocalModuleConfig_paxcounter_tag 14
#define meshtastic_LocalModuleConfig_statusmessage_tag 15
/* Struct field encoding specification for nanopb */ /* Struct field encoding specification for nanopb */
#define meshtastic_LocalConfig_FIELDLIST(X, a) \ #define meshtastic_LocalConfig_FIELDLIST(X, a) \
@@ -165,8 +161,7 @@ X(a, STATIC, OPTIONAL, MESSAGE, remote_hardware, 10) \
X(a, STATIC, OPTIONAL, MESSAGE, neighbor_info, 11) \ X(a, STATIC, OPTIONAL, MESSAGE, neighbor_info, 11) \
X(a, STATIC, OPTIONAL, MESSAGE, ambient_lighting, 12) \ X(a, STATIC, OPTIONAL, MESSAGE, ambient_lighting, 12) \
X(a, STATIC, OPTIONAL, MESSAGE, detection_sensor, 13) \ X(a, STATIC, OPTIONAL, MESSAGE, detection_sensor, 13) \
X(a, STATIC, OPTIONAL, MESSAGE, paxcounter, 14) \ X(a, STATIC, OPTIONAL, MESSAGE, paxcounter, 14)
X(a, STATIC, OPTIONAL, MESSAGE, statusmessage, 15)
#define meshtastic_LocalModuleConfig_CALLBACK NULL #define meshtastic_LocalModuleConfig_CALLBACK NULL
#define meshtastic_LocalModuleConfig_DEFAULT NULL #define meshtastic_LocalModuleConfig_DEFAULT NULL
#define meshtastic_LocalModuleConfig_mqtt_MSGTYPE meshtastic_ModuleConfig_MQTTConfig #define meshtastic_LocalModuleConfig_mqtt_MSGTYPE meshtastic_ModuleConfig_MQTTConfig
@@ -182,7 +177,6 @@ X(a, STATIC, OPTIONAL, MESSAGE, statusmessage, 15)
#define meshtastic_LocalModuleConfig_ambient_lighting_MSGTYPE meshtastic_ModuleConfig_AmbientLightingConfig #define meshtastic_LocalModuleConfig_ambient_lighting_MSGTYPE meshtastic_ModuleConfig_AmbientLightingConfig
#define meshtastic_LocalModuleConfig_detection_sensor_MSGTYPE meshtastic_ModuleConfig_DetectionSensorConfig #define meshtastic_LocalModuleConfig_detection_sensor_MSGTYPE meshtastic_ModuleConfig_DetectionSensorConfig
#define meshtastic_LocalModuleConfig_paxcounter_MSGTYPE meshtastic_ModuleConfig_PaxcounterConfig #define meshtastic_LocalModuleConfig_paxcounter_MSGTYPE meshtastic_ModuleConfig_PaxcounterConfig
#define meshtastic_LocalModuleConfig_statusmessage_MSGTYPE meshtastic_ModuleConfig_StatusMessageConfig
extern const pb_msgdesc_t meshtastic_LocalConfig_msg; extern const pb_msgdesc_t meshtastic_LocalConfig_msg;
extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg; extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
@@ -192,9 +186,9 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
#define meshtastic_LocalModuleConfig_fields &meshtastic_LocalModuleConfig_msg #define meshtastic_LocalModuleConfig_fields &meshtastic_LocalModuleConfig_msg
/* Maximum encoded size of messages (where known) */ /* Maximum encoded size of messages (where known) */
#define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalModuleConfig_size #define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalConfig_size
#define meshtastic_LocalConfig_size 749 #define meshtastic_LocalConfig_size 749
#define meshtastic_LocalModuleConfig_size 758 #define meshtastic_LocalModuleConfig_size 675
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View File

@@ -2,6 +2,7 @@
#include "Default.h" #include "Default.h"
#include "MeshService.h" #include "MeshService.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "NodeStatus.h"
#include "RTC.h" #include "RTC.h"
#include "Router.h" #include "Router.h"
#include "configuration.h" #include "configuration.h"
@@ -129,14 +130,17 @@ meshtastic_MeshPacket *NodeInfoModule::allocReply()
LOG_DEBUG("Skip send NodeInfo > 40%% ch. util"); LOG_DEBUG("Skip send NodeInfo > 40%% ch. util");
return NULL; return NULL;
} }
// If we sent our NodeInfo less than 5 min. ago, don't send it again as it may be still underway.
if (!shorterTimeout && lastSentToMesh && Throttle::isWithinTimespanMs(lastSentToMesh, 5 * 60 * 1000)) { // Use graduated scaling based on active mesh size (10 minute base, scales with congestion coefficient)
LOG_DEBUG("Skip send NodeInfo since we sent it <5min ago"); uint32_t timeoutMs = Default::getConfiguredOrDefaultMsScaled(0, 10 * 60, nodeStatus->getNumOnline());
if (!shorterTimeout && lastSentToMesh && Throttle::isWithinTimespanMs(lastSentToMesh, timeoutMs)) {
LOG_DEBUG("Skip send NodeInfo since we sent it <%us ago", timeoutMs / 1000);
ignoreRequest = true; // Mark it as ignored for MeshModule ignoreRequest = true; // Mark it as ignored for MeshModule
return NULL; return NULL;
} else if (shorterTimeout && lastSentToMesh && Throttle::isWithinTimespanMs(lastSentToMesh, 60 * 1000)) { } else if (shorterTimeout && lastSentToMesh && Throttle::isWithinTimespanMs(lastSentToMesh, 60 * 1000)) {
// For interactive/urgent requests (e.g., user-triggered or implicit requests), use a shorter 60s timeout
LOG_DEBUG("Skip send NodeInfo since we sent it <60s ago"); LOG_DEBUG("Skip send NodeInfo since we sent it <60s ago");
ignoreRequest = true; // Mark it as ignored for MeshModule ignoreRequest = true;
return NULL; return NULL;
} else { } else {
ignoreRequest = false; // Don't ignore requests anymore ignoreRequest = false; // Don't ignore requests anymore

View File

@@ -649,19 +649,6 @@ bool loadConfig(const char *configPath)
if (yamlConfig["Lora"]["RF95_MAX_POWER"]) if (yamlConfig["Lora"]["RF95_MAX_POWER"])
portduino_config.rf95_max_power = yamlConfig["Lora"]["RF95_MAX_POWER"].as<int>(20); portduino_config.rf95_max_power = yamlConfig["Lora"]["RF95_MAX_POWER"].as<int>(20);
if (yamlConfig["Lora"]["TX_GAIN_LORA"]) {
YAML::Node tx_gain_node = yamlConfig["Lora"]["TX_GAIN_LORA"];
if (tx_gain_node.IsSequence() && tx_gain_node.size() != 0) {
portduino_config.num_pa_points = min(tx_gain_node.size(), std::size(portduino_config.tx_gain_lora));
for (int i = 0; i < portduino_config.num_pa_points; i++) {
portduino_config.tx_gain_lora[i] = tx_gain_node[i].as<int>();
}
} else {
portduino_config.num_pa_points = 1;
portduino_config.tx_gain_lora[0] = tx_gain_node.as<int>(0);
}
}
if (portduino_config.lora_module != use_autoconf && portduino_config.lora_module != use_simradio && if (portduino_config.lora_module != use_autoconf && portduino_config.lora_module != use_simradio &&
!portduino_config.force_simradio) { !portduino_config.force_simradio) {
portduino_config.dio2_as_rf_switch = yamlConfig["Lora"]["DIO2_AS_RF_SWITCH"].as<bool>(false); portduino_config.dio2_as_rf_switch = yamlConfig["Lora"]["DIO2_AS_RF_SWITCH"].as<bool>(false);

View File

@@ -91,8 +91,6 @@ extern struct portduino_config_struct {
int lora_usb_pid = 0x5512; int lora_usb_pid = 0x5512;
int lora_usb_vid = 0x1A86; int lora_usb_vid = 0x1A86;
int spiSpeed = 2000000; int spiSpeed = 2000000;
int num_pa_points = 1; // default to 1 point, with 0 gain
uint16_t tx_gain_lora[22] = {0};
pinMapping lora_cs_pin = {"Lora", "CS"}; pinMapping lora_cs_pin = {"Lora", "CS"};
pinMapping lora_irq_pin = {"Lora", "IRQ"}; pinMapping lora_irq_pin = {"Lora", "IRQ"};
pinMapping lora_busy_pin = {"Lora", "Busy"}; pinMapping lora_busy_pin = {"Lora", "Busy"};
@@ -233,17 +231,6 @@ extern struct portduino_config_struct {
out << YAML::Key << "LR1120_MAX_POWER" << YAML::Value << lr1120_max_power; out << YAML::Key << "LR1120_MAX_POWER" << YAML::Value << lr1120_max_power;
if (rf95_max_power != 20) if (rf95_max_power != 20)
out << YAML::Key << "RF95_MAX_POWER" << YAML::Value << rf95_max_power; out << YAML::Key << "RF95_MAX_POWER" << YAML::Value << rf95_max_power;
if (num_pa_points > 1) {
out << YAML::Key << "TX_GAIN_LORA" << YAML::Value << YAML::Flow << YAML::BeginSeq;
for (int i = 0; i < num_pa_points; i++) {
out << YAML::Value << tx_gain_lora[i];
}
out << YAML::EndSeq;
} else if (tx_gain_lora[0] != 0) {
out << YAML::Key << "TX_GAIN_LORA" << YAML::Value << tx_gain_lora[0];
}
out << YAML::Key << "DIO2_AS_RF_SWITCH" << YAML::Value << dio2_as_rf_switch; out << YAML::Key << "DIO2_AS_RF_SWITCH" << YAML::Value << dio2_as_rf_switch;
if (dio3_tcxo_voltage != 0) if (dio3_tcxo_voltage != 0)
out << YAML::Key << "DIO3_TCXO_VOLTAGE" << YAML::Value << YAML::Precision(3) << (float)dio3_tcxo_voltage / 1000; out << YAML::Key << "DIO3_TCXO_VOLTAGE" << YAML::Value << YAML::Precision(3) << (float)dio3_tcxo_voltage / 1000;

View File

@@ -6,6 +6,8 @@ build_flags =
${esp32_base.build_flags} ${esp32_base.build_flags}
-D CHATTER_2 -D CHATTER_2
-I variants/esp32/chatter2 -I variants/esp32/chatter2
-DMESHTASTIC_EXCLUDE_WEBSERVER=1
-DMESHTASTIC_EXCLUDE_PAXCOUNTER=1
lib_deps = lib_deps =
${esp32_base.lib_deps} ${esp32_base.lib_deps}

View File

@@ -59,7 +59,7 @@ lib_deps =
${environmental_extra.lib_deps} ${environmental_extra.lib_deps}
${radiolib_base.lib_deps} ${radiolib_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-esp32_https_server packageName=https://github.com/meshtastic/esp32_https_server gitBranch=master # renovate: datasource=git-refs depName=meshtastic-esp32_https_server packageName=https://github.com/meshtastic/esp32_https_server gitBranch=master
https://github.com/meshtastic/esp32_https_server/archive/3223704846752e6d545139204837bdb2a55459ca.zip https://github.com/meshtastic/esp32_https_server/archive/b0f3960b3e8444563280656d88e22b5899481884.zip
# renovate: datasource=custom.pio depName=NimBLE-Arduino packageName=h2zero/library/NimBLE-Arduino # renovate: datasource=custom.pio depName=NimBLE-Arduino packageName=h2zero/library/NimBLE-Arduino
h2zero/NimBLE-Arduino@^1.4.3 h2zero/NimBLE-Arduino@^1.4.3
# renovate: datasource=git-refs depName=libpax packageName=https://github.com/dbinfrago/libpax gitBranch=master # renovate: datasource=git-refs depName=libpax packageName=https://github.com/dbinfrago/libpax gitBranch=master

View File

@@ -17,7 +17,7 @@ lib_deps =
${environmental_extra_no_bsec.lib_deps} ${environmental_extra_no_bsec.lib_deps}
${radiolib_base.lib_deps} ${radiolib_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-esp32_https_server packageName=https://github.com/meshtastic/esp32_https_server gitBranch=master # renovate: datasource=git-refs depName=meshtastic-esp32_https_server packageName=https://github.com/meshtastic/esp32_https_server gitBranch=master
https://github.com/meshtastic/esp32_https_server/archive/3223704846752e6d545139204837bdb2a55459ca.zip https://github.com/meshtastic/esp32_https_server/archive/b0f3960b3e8444563280656d88e22b5899481884.zip
# renovate: datasource=custom.pio depName=NimBLE-Arduino packageName=h2zero/library/NimBLE-Arduino # renovate: datasource=custom.pio depName=NimBLE-Arduino packageName=h2zero/library/NimBLE-Arduino
h2zero/NimBLE-Arduino@^1.4.3 h2zero/NimBLE-Arduino@^1.4.3
# renovate: datasource=git-refs depName=libpax packageName=https://github.com/dbinfrago/libpax gitBranch=master # renovate: datasource=git-refs depName=libpax packageName=https://github.com/dbinfrago/libpax gitBranch=master

View File

@@ -16,6 +16,8 @@ build_flags =
${esp32_base.build_flags} ${esp32_base.build_flags}
-I variants/esp32/m5stack_core -I variants/esp32/m5stack_core
-DM5STACK -DM5STACK
-DMESHTASTIC_EXCLUDE_WEBSERVER=1
-DMESHTASTIC_EXCLUDE_PAXCOUNTER=1
-DUSER_SETUP_LOADED -DUSER_SETUP_LOADED
-DTFT_SDA_READ -DTFT_SDA_READ
-DTFT_DRIVER=0x9341 -DTFT_DRIVER=0x9341

View File

@@ -1,21 +0,0 @@
; Russell is a board designed to mount on an ER34615/IFR32700 cell and go Up! on a balloon
; Hardware repository: https://github.com/Meshtastic-Malaysia/russell
; - RAK3172 STM32WLE5CCU6 MCU + integrated SX1262 LoRa
; - CDtop CD-PA1010D GPS
; - Bosch Sensortec BME280 sensor
; - Consonance CN3158 LiFePO4 solar charger
[env:russell]
extends = stm32_base
board = wiscore_rak3172
board_level = extra
board_upload.maximum_size = 233472 ; reserve the last 28KB for filesystem
build_flags =
${stm32_base.build_flags}
-Ivariants/stm32/russell
-DPRIVATE_HW
lib_deps =
${stm32_base.lib_deps}
# renovate: datasource=custom.pio depName=Adafruit BME280 packageName=adafruit/library/Adafruit BME280 Library
adafruit/Adafruit BME280 Library@2.3.0
upload_port = stlink

View File

@@ -1,7 +0,0 @@
// Pins from https://forum.rakwireless.com/t/rak3172-internal-schematic/4557/2
// PB8, PC13
static const RADIOLIB_PIN_TYPE rfswitch_pins[5] = {PB8, PC13, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC};
static const Module::RfSwitchMode_t rfswitch_table[4] = {
{STM32WLx::MODE_IDLE, {LOW, LOW}}, {STM32WLx::MODE_RX, {HIGH, LOW}}, {STM32WLx::MODE_TX_HP, {LOW, HIGH}}, END_OF_MODE_TABLE};

View File

@@ -1,41 +0,0 @@
#ifndef _VARIANT_RUSSELL_
#define _VARIANT_RUSSELL_
#define USE_STM32WLx
// I/O
#define LED_PIN PA0 // Red LED
#define LED_STATE_ON 1
#define BUTTON_PIN PH3 // Shared with BOOT0
#define BUTTON_NEED_PULLUP
// Charger IC charge/standby pins are open-drain with no hardware pull-up:
// Internal pull-up is needed on STM32 (TODO)
// #define EXT_CHRG_DETECT PA5
// #define EXT_PWR_DETECT PA4
// Bosch Sensortec BME280
#define HAS_SENSOR 1
// CDtop CD-PA1010D
#define ENABLE_HWSERIAL1
#define PIN_SERIAL1_RX PB7
#define PIN_SERIAL1_TX PB6
#define HAS_GPS 1
#define PIN_GPS_STANDBY PA15
#define GPS_RX_PIN PB7
#define GPS_TX_PIN PB6
// LoRa
/*
* RAK3172 (-2085°C) -> No TCXO
* RAK3172-T (-4085°C) -> 3.0V TCXO
* https://github.com/RAKWireless/RAK-STM32-RUI/blob/e5a28be8fab1a492bd9223dd425ca33a8a297d90/variants/WisDuo_RAK3172-T_Board/radio_conf.h#L91
*/
#define TCXO_OPTIONAL
#define SX126X_DIO3_TCXO_VOLTAGE 3.0
// Required to avoid Serial1 conflicts due to board definition here:
// https://github.com/stm32duino/Arduino_Core_STM32/blob/main/variants/STM32WLxx/WL54CCU_WL55CCU_WLE4C(8-B-C)U_WLE5C(8-B-C)U/variant_RAK3172_MODULE.h
#define RAK3172
#endif