Merge branch 'master' into add-traceroute

This commit is contained in:
whywilson 2025-07-21 11:50:01 +08:00
commit d7a3dee1be
282 changed files with 673 additions and 406 deletions

24
.github/workflows/pr_enforce_labels.yml vendored Normal file
View File

@ -0,0 +1,24 @@
name: Check PR Labels
on:
pull_request:
types: [opened, edited, labeled, unlabeled, synchronize, reopened]
permissions:
pull-requests: read
contents: read
jobs:
check-label:
runs-on: ubuntu-24.04
steps:
- name: Check for PR labels
uses: actions/github-script@v7
with:
script: |
const labels = context.payload.pull_request.labels.map(label => label.name);
const requiredLabels = ['bugfix', 'enhancement', 'hardware-support', 'dependencies', 'submodules', 'github_actions', 'trunk'];
const hasRequiredLabel = labels.some(label => requiredLabels.includes(label));
if (!hasRequiredLabel) {
core.setFailed(`PR must have at least one of the following labels before it can be merged: ${requiredLabels.join(', ')}.`);
}

View File

@ -103,8 +103,9 @@ jobs:
with:
base: ${{ github.event.repository.default_branch }}
branch: create-pull-request/bump-version
labels: github_actions
title: Bump release version
commit-message: automated bumps
commit-message: Automated version bumps
add-paths: |
version.properties
debian/changelog

View File

@ -34,7 +34,9 @@ jobs:
uses: peter-evans/create-pull-request@v7
with:
branch: create-pull-request/update-protobufs
labels: submodules
title: Update protobufs and classes
commit-message: Update protobufs
add-paths: |
protobufs
src/mesh

View File

@ -8,15 +8,15 @@ plugins:
uri: https://github.com/trunk-io/plugins
lint:
enabled:
- checkov@3.2.450
- renovate@41.30.5
- checkov@3.2.451
- renovate@41.37.9
- prettier@3.6.2
- trufflehog@3.89.2
- trufflehog@3.90.0
- yamllint@1.37.1
- bandit@1.8.6
- trivy@0.64.1
- taplo@0.9.3
- ruff@0.12.2
- ruff@0.12.3
- isort@6.0.1
- markdownlint@0.45.0
- oxipng@9.1.5

View File

@ -39,7 +39,7 @@ build_flags =
-Isrc/platform/portduino
-DRADIOLIB_EEPROM_UNSUPPORTED
-DPORTDUINO_LINUX_HARDWARE
-DHAS_UDP_MULTICAST
-DHAS_UDP_MULTICAST=1
-lpthread
-lstdc++fs
-lbluetooth

View File

@ -87,6 +87,9 @@
</screenshots>
<releases>
<release version="2.7.4" date="2025-07-19">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.4</url>
</release>
<release version="2.7.3" date="2025-07-10">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.3</url>
</release>

7
debian/changelog vendored
View File

@ -1,4 +1,4 @@
meshtasticd (2.7.3.0) UNRELEASED; urgency=medium
meshtasticd (2.7.4.0) UNRELEASED; urgency=medium
[ Austin Lane ]
* Initial packaging
@ -31,4 +31,7 @@ meshtasticd (2.7.3.0) UNRELEASED; urgency=medium
[ Ubuntu ]
* GitHub Actions Automatic version bump
-- Ubuntu <github-actions[bot]@users.noreply.github.com> Thu, 10 Jul 2025 16:29:27 +0000
[ ]
* GitHub Actions Automatic version bump
-- <github-actions[bot]@users.noreply.github.com> Sat, 19 Jul 2025 11:36:55 +0000

View File

@ -6,7 +6,9 @@ default_envs = tbeam
extra_configs =
arch/*/*.ini
variants/*/platformio.ini
variants/*/platformio.ini ; Remove when all variants migrated to new dir structure
variants/*/*/platformio.ini
variants/*/diy/*/platformio.ini
src/graphics/niche/InkHUD/PlatformioConfig.ini
description = Meshtastic

@ -1 +1 @@
Subproject commit f6448be7770a3521bf52407ff8f5fa5b9b06da7b
Subproject commit 15c1fbde882de953dec279160fa984d0e00569d0

View File

@ -681,7 +681,16 @@ bool Power::setup()
void Power::shutdown()
{
LOG_INFO("Shutting Down");
#if HAS_SCREEN
if (screen) {
screen->showSimpleBanner("Shutting Down...", 0); // stays on screen
}
#endif
#if !defined(ARCH_STM32WL)
playShutdownMelody();
#endif
nodeDB->saveToDisk();
#if defined(ARCH_NRF52) || defined(ARCH_ESP32) || defined(ARCH_RP2040)
#ifdef PIN_LED1
@ -693,7 +702,11 @@ void Power::shutdown()
#ifdef PIN_LED3
ledOff(PIN_LED3);
#endif
doDeepSleep(DELAY_FOREVER, false, false);
doDeepSleep(DELAY_FOREVER, false, true);
#elif defined(ARCH_PORTDUINO)
exit(EXIT_SUCCESS);
#else
LOG_WARN("FIXME implement shutdown for this platform");
#endif
}

View File

@ -47,10 +47,6 @@ int BuzzerFeedbackThread::handleInputEvent(const InputEvent *event)
playComboTune(); // Ping sent feedback
break;
case INPUT_BROKER_SHUTDOWN:
playShutdownMelody(); // Shutdown feedback
break;
default:
// For other events, check if it's a printable character
if (event->kbchar >= 32 && event->kbchar <= 126) {
@ -69,10 +65,7 @@ int32_t BuzzerFeedbackThread::runOnce()
// This thread is primarily event-driven, but we can use runOnce
// for any periodic tasks if needed in the future
if (needsUpdate) {
needsUpdate = false;
// Could add any periodic processing here
}
needsUpdate = false;
// Run every 100ms when active, less frequently when idle
return needsUpdate ? 100 : 1000;

View File

@ -1001,7 +1001,7 @@ void Screen::setFrames(FrameFocus focus)
// Insert favorite frames *after* collecting them all
if (!favoriteFrames.empty()) {
fsi.positions.firstFavorite = numframes;
for (auto &f : favoriteFrames) {
for (const auto &f : favoriteFrames) {
normalFrames[numframes++] = f;
indicatorIcons.push_back(icon_node);
}

View File

@ -218,7 +218,6 @@ void drawDigitalClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int1
hour %= 12;
if (hour == 0)
hour = 12;
bool isPM = hour >= 12;
snprintf(timeString, sizeof(timeString), "%d:%02d", hour, minute);
} else {
snprintf(timeString, sizeof(timeString), "%02d:%02d", hour, minute);
@ -367,7 +366,7 @@ void drawAnalogClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
// hour hand radius and y coordinate
int16_t hourHandRadius = radius * 0.35;
if (isHighResolution) {
int16_t hourHandRadius = radius * 0.55;
hourHandRadius = radius * 0.55;
}
int16_t hourHandNoonY = centerY - hourHandRadius;
@ -386,7 +385,7 @@ void drawAnalogClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
bool isPM = hour >= 12;
if (config.display.use_12h_clock) {
bool isPM = hour >= 12;
isPM = hour >= 12;
display->setFont(FONT_SMALL);
int yOffset = isHighResolution ? 1 : 0;
#ifdef USE_EINK

View File

@ -825,9 +825,8 @@ void menuHandler::shutdownMenu()
bannerOptions.optionsCount = 2;
bannerOptions.bannerCallback = [](int selected) -> void {
if (selected == 1) {
IF_SCREEN(screen->showSimpleBanner("Shutting Down...", 0));
nodeDB->saveToDisk();
power->shutdown();
InputEvent event = {.inputEvent = (input_broker_event)INPUT_BROKER_SHUTDOWN, .kbchar = 0, .touchX = 0, .touchY = 0};
inputBroker->injectInputEvent(&event);
} else {
menuQueue = power_menu;
screen->runNow();

View File

@ -53,23 +53,21 @@ bool ButtonThread::initButton(const ButtonConfig &config)
},
this);
if (config.longPress != INPUT_BROKER_NONE) {
_longPress = config.longPress;
userButton.attachLongPressStart(
[](void *callerThread) -> void {
ButtonThread *thread = (ButtonThread *)callerThread;
// if (millis() > 30000) // hold off 30s after boot
thread->btnEvent = BUTTON_EVENT_LONG_PRESSED;
},
this);
userButton.attachLongPressStop(
[](void *callerThread) -> void {
ButtonThread *thread = (ButtonThread *)callerThread;
// if (millis() > 30000) // hold off 30s after boot
thread->btnEvent = BUTTON_EVENT_LONG_RELEASED;
},
this);
}
_longPress = config.longPress;
userButton.attachLongPressStart(
[](void *callerThread) -> void {
ButtonThread *thread = (ButtonThread *)callerThread;
// if (millis() > 30000) // hold off 30s after boot
thread->btnEvent = BUTTON_EVENT_LONG_PRESSED;
},
this);
userButton.attachLongPressStop(
[](void *callerThread) -> void {
ButtonThread *thread = (ButtonThread *)callerThread;
// if (millis() > 30000) // hold off 30s after boot
thread->btnEvent = BUTTON_EVENT_LONG_RELEASED;
},
this);
if (config.doublePress != INPUT_BROKER_NONE) {
_doublePress = config.doublePress;
@ -202,11 +200,11 @@ int32_t ButtonThread::runOnce()
break;
}
// Forward long press to InputBroker (but NOT as DOWN/SELECT, just forward a "button long press" event)
evt.inputEvent = _longPress;
this->notifyObservers(&evt);
if (_longPress != INPUT_BROKER_NONE) {
// Forward long press to InputBroker (but NOT as DOWN/SELECT, just forward a "button long press" event)
evt.inputEvent = _longPress;
this->notifyObservers(&evt);
}
// Reset combination tracking
waitingForLongPress = false;
@ -253,7 +251,7 @@ int32_t ButtonThread::runOnce()
// may wake the board immediatedly.
case BUTTON_EVENT_LONG_RELEASED: {
LOG_INFO("LONG PRESS RELEASE");
LOG_INFO("LONG PRESS RELEASE AFTER %u MILLIS", millis() - buttonPressStartTime);
if (millis() > 30000 && _longLongPress != INPUT_BROKER_NONE &&
(millis() - buttonPressStartTime) >= _longLongPressTime) {
evt.inputEvent = _longLongPress;

View File

@ -18,13 +18,13 @@ struct ButtonConfig {
uint16_t longPressTime = 500;
input_broker_event doublePress = INPUT_BROKER_NONE;
input_broker_event longLongPress = INPUT_BROKER_NONE;
uint16_t longLongPressTime = 5000;
uint16_t longLongPressTime = 3900;
input_broker_event triplePress = INPUT_BROKER_NONE;
input_broker_event shortLong = INPUT_BROKER_NONE;
bool touchQuirk = false;
// Constructor to set required parameter
ButtonConfig(uint8_t pin = 0) : pinNumber(pin) {}
explicit ButtonConfig(uint8_t pin = 0) : pinNumber(pin) {}
};
#ifndef BUTTON_CLICK_MS
@ -62,7 +62,7 @@ class ButtonThread : public Observable<const InputEvent *>, public concurrency::
BUTTON_EVENT_COMBO_SHORT_LONG,
};
ButtonThread(const char *name);
explicit ButtonThread(const char *name);
int32_t runOnce() override;
OneButton userButton;
void attachButtonInterrupts();

View File

@ -233,14 +233,7 @@ void ExpressLRSFiveWay::sendAdhocPing()
// Contained as one method for easier remapping of buttons by user
void ExpressLRSFiveWay::shutdown()
{
LOG_INFO("Shutdown from long press");
powerFSM.trigger(EVENT_PRESS);
screen->startAlert("Shutting Down...");
// Don't set alerting = true. We don't want to auto-dismiss this alert.
playShutdownMelody(); // In case user adds a buzzer
shutdownAtMsec = millis() + 3000;
sendKey(INPUT_BROKER_SHUTDOWN);
}
void ExpressLRSFiveWay::click()

View File

@ -1042,8 +1042,9 @@ void setup()
mainDelay.interruptFromISR(&higherWake);
};
userConfigNoScreen.singlePress = INPUT_BROKER_USER_PRESS;
userConfigNoScreen.longPress = INPUT_BROKER_SHUTDOWN;
userConfigNoScreen.longPressTime = 5000;
userConfigNoScreen.longPress = INPUT_BROKER_NONE;
userConfigNoScreen.longPressTime = 500;
userConfigNoScreen.longLongPress = INPUT_BROKER_SHUTDOWN;
userConfigNoScreen.doublePress = INPUT_BROKER_SEND_PING;
userConfigNoScreen.triplePress = INPUT_BROKER_GPS_TOGGLE;
UserButtonThread->initButton(userConfigNoScreen);

View File

@ -121,7 +121,7 @@ meshtastic_MeshPacket *MeshPacketQueue::remove(NodeNum from, PacketId id, bool t
bool MeshPacketQueue::find(const NodeNum from, const PacketId id)
{
for (auto it = queue.begin(); it != queue.end(); it++) {
const auto p = (*it);
const auto *p = *it;
if (getFrom(p) == from && p->id == id) {
return true;
}

View File

@ -16,6 +16,7 @@
#include "meshUtils.h"
#include "modules/NodeInfoModule.h"
#include "modules/PositionModule.h"
#include "modules/RoutingModule.h"
#include "power.h"
#include <assert.h>
#include <string>
@ -333,6 +334,21 @@ void MeshService::sendMqttMessageToClientProxy(meshtastic_MqttClientProxyMessage
fromNum++;
}
void MeshService::sendRoutingErrorResponse(meshtastic_Routing_Error error, const meshtastic_MeshPacket *mp)
{
if (!mp) {
LOG_WARN("Cannot send routing error response: null packet");
return;
}
// Use the routing module to send the error response
if (routingModule) {
routingModule->sendAckNak(error, mp->from, mp->id, mp->channel);
} else {
LOG_ERROR("Cannot send routing error response: no routing module");
}
}
void MeshService::sendClientNotification(meshtastic_ClientNotification *n)
{
LOG_DEBUG("Send client notification to phone");

View File

@ -148,6 +148,9 @@ class MeshService
/// Send a ClientNotification to the phone
void sendClientNotification(meshtastic_ClientNotification *cn);
/// Send an error response to the phone
void sendRoutingErrorResponse(meshtastic_Routing_Error error, const meshtastic_MeshPacket *mp);
bool isToPhoneQueueEmpty();
ErrorCode sendQueueStatusToPhone(const meshtastic_QueueStatus &qs, ErrorCode res, uint32_t mesh_packet_id);

View File

@ -1868,7 +1868,7 @@ UserLicenseStatus NodeDB::getLicenseStatus(uint32_t nodeNum)
return info->user.is_licensed ? UserLicenseStatus::Licensed : UserLicenseStatus::NotLicensed;
}
bool NodeDB::checkLowEntropyPublicKey(const meshtastic_Config_SecurityConfig_public_key_t keyToTest)
bool NodeDB::checkLowEntropyPublicKey(const meshtastic_Config_SecurityConfig_public_key_t &keyToTest)
{
if (keyToTest.size == 32) {
uint8_t keyHash[32] = {0};

View File

@ -279,7 +279,7 @@ class NodeDB
bool hasValidPosition(const meshtastic_NodeInfoLite *n);
bool checkLowEntropyPublicKey(const meshtastic_Config_SecurityConfig_public_key_t keyToTest);
bool checkLowEntropyPublicKey(const meshtastic_Config_SecurityConfig_public_key_t &keyToTest);
bool backupPreferences(meshtastic_AdminMessage_BackupLocation location);
bool restorePreferences(meshtastic_AdminMessage_BackupLocation location,

View File

@ -181,7 +181,7 @@ PacketHistory::PacketRecord *PacketHistory::find(NodeNum sender, PacketId id)
}
/** Insert/Replace oldest PacketRecord in recentPackets. */
void PacketHistory::insert(PacketRecord &r)
void PacketHistory::insert(const PacketRecord &r)
{
uint32_t now_millis = millis(); // Should not jump with time changes
uint32_t OldtrxTimeMsec = 0;
@ -308,7 +308,7 @@ bool PacketHistory::wasRelayer(const uint8_t relayer, const uint32_t id, const N
return false;
}
PacketRecord *found = find(sender, id);
const PacketRecord *found = find(sender, id);
if (found == NULL) {
#if VERBOSE_PACKET_HISTORY
@ -327,7 +327,7 @@ bool PacketHistory::wasRelayer(const uint8_t relayer, const uint32_t id, const N
/* Check if a certain node was a relayer of a packet in the history given iterator
* @return true if node was indeed a relayer, false if not */
bool PacketHistory::wasRelayer(const uint8_t relayer, PacketRecord &r)
bool PacketHistory::wasRelayer(const uint8_t relayer, const PacketRecord &r)
{
for (uint8_t i = 0; i < NUM_RELAYERS; i++) {
if (r.relayed_by[i] == relayer) {

View File

@ -31,11 +31,11 @@ class PacketHistory
/** Insert/Replace oldest PacketRecord in mx_recentPackets.
* @param r PacketRecord to insert or replace */
void insert(PacketRecord &r); // Insert or replace a packet record in the history
void insert(const PacketRecord &r); // Insert or replace a packet record in the history
/* Check if a certain node was a relayer of a packet in the history given iterator
* @return true if node was indeed a relayer, false if not */
bool wasRelayer(const uint8_t relayer, PacketRecord &r);
bool wasRelayer(const uint8_t relayer, const PacketRecord &r);
PacketHistory(const PacketHistory &); // non construction-copyable
PacketHistory &operator=(const PacketHistory &); // non copyable

View File

@ -686,7 +686,8 @@ bool PhoneAPI::handleToRadioPacket(meshtastic_MeshPacket &p)
LOG_WARN("Rate limit portnum %d", p.decoded.portnum);
meshtastic_QueueStatus qs = router->getQueueStatus();
service->sendQueueStatusToPhone(qs, 0, p.id);
sendNotification(meshtastic_LogRecord_Level_WARNING, p.id, "Text messages can only be sent once every 2 seconds");
service->sendRoutingErrorResponse(meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED, &p);
// sendNotification(meshtastic_LogRecord_Level_WARNING, p.id, "Text messages can only be sent once every 2 seconds");
return false;
}
lastPortNumToRadio[p.decoded.portnum] = millis();

View File

@ -68,6 +68,11 @@ static int32_t reconnectETH()
initApiServer();
}
#endif
#if HAS_UDP_MULTICAST
if (udpHandler && config.network.enabled_protocols & meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST) {
udpHandler->start();
}
#endif
ethStartupComplete = true;
}

View File

@ -2,7 +2,6 @@
#include "configuration.h"
#include <Arduino.h>
#include <functional>
bool initEthernet();
bool isEthernetAvailable();

View File

@ -480,7 +480,8 @@ typedef struct _meshtastic_Config_DisplayConfig {
/* Number of seconds the screen stays on after pressing the user button or receiving a message
0 for default of one minute MAXUINT for always on */
uint32_t screen_on_secs;
/* How the GPS coordinates are formatted on the OLED screen. */
/* Deprecated in 2.7.4: Unused
How the GPS coordinates are formatted on the OLED screen. */
meshtastic_Config_DisplayConfig_GpsCoordinateFormat gps_format;
/* Automatically toggles to the next page on the screen like a carousel, based the specified interval in seconds.
Potentially useful for devices without user buttons. */

View File

@ -426,7 +426,10 @@ typedef enum _meshtastic_Routing_Error {
/* Admin packet otherwise checks out, but uses a bogus or expired session key */
meshtastic_Routing_Error_ADMIN_BAD_SESSION_KEY = 36,
/* Admin packet sent using PKC, but not from a public key on the admin key list */
meshtastic_Routing_Error_ADMIN_PUBLIC_KEY_UNAUTHORIZED = 37
meshtastic_Routing_Error_ADMIN_PUBLIC_KEY_UNAUTHORIZED = 37,
/* Airtime fairness rate limit exceeded for a packet
This typically enforced per portnum and is used to prevent a single node from monopolizing airtime */
meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED = 38
} meshtastic_Routing_Error;
/* The priority of this message for sending.
@ -1222,8 +1225,8 @@ extern "C" {
#define _meshtastic_Position_AltSource_ARRAYSIZE ((meshtastic_Position_AltSource)(meshtastic_Position_AltSource_ALT_BAROMETRIC+1))
#define _meshtastic_Routing_Error_MIN meshtastic_Routing_Error_NONE
#define _meshtastic_Routing_Error_MAX meshtastic_Routing_Error_ADMIN_PUBLIC_KEY_UNAUTHORIZED
#define _meshtastic_Routing_Error_ARRAYSIZE ((meshtastic_Routing_Error)(meshtastic_Routing_Error_ADMIN_PUBLIC_KEY_UNAUTHORIZED+1))
#define _meshtastic_Routing_Error_MAX meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED
#define _meshtastic_Routing_Error_ARRAYSIZE ((meshtastic_Routing_Error)(meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED+1))
#define _meshtastic_MeshPacket_Priority_MIN meshtastic_MeshPacket_Priority_UNSET
#define _meshtastic_MeshPacket_Priority_MAX meshtastic_MeshPacket_Priority_MAX

View File

@ -93,7 +93,11 @@ typedef enum _meshtastic_TelemetrySensorType {
/* PCT2075 Temperature Sensor */
meshtastic_TelemetrySensorType_PCT2075 = 39,
/* ADS1X15 ADC */
meshtastic_TelemetrySensorType_ADS1X15 = 40
meshtastic_TelemetrySensorType_ADS1X15 = 40,
/* ADS1X15 ADC_ALT */
meshtastic_TelemetrySensorType_ADS1X15_ALT = 41,
/* Sensirion SFA30 Formaldehyde sensor */
meshtastic_TelemetrySensorType_SFA30 = 42
} meshtastic_TelemetrySensorType;
/* Struct definitions */
@ -287,6 +291,15 @@ typedef struct _meshtastic_AirQualityMetrics {
/* CO2 sensor relative humidity in % */
bool has_co2_humidity;
float co2_humidity;
/* Formaldehyde sensor formaldehyde concentration in ppb */
bool has_form_formaldehyde;
float form_formaldehyde;
/* Formaldehyde sensor relative humidity in %RH */
bool has_form_humidity;
float form_humidity;
/* Formaldehyde sensor temperature in degrees Celsius */
bool has_form_temperature;
float form_temperature;
} meshtastic_AirQualityMetrics;
/* Local device mesh statistics */
@ -398,8 +411,8 @@ extern "C" {
/* Helper constants for enums */
#define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_ADS1X15
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_ADS1X15+1))
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_SFA30
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_SFA30+1))
@ -415,7 +428,7 @@ extern "C" {
#define meshtastic_DeviceMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_EnvironmentMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_PowerMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_AirQualityMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_AirQualityMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_LocalStats_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_HealthMetrics_init_default {false, 0, false, 0, false, 0}
#define meshtastic_HostMetrics_init_default {0, 0, 0, false, 0, false, 0, 0, 0, 0, false, ""}
@ -424,7 +437,7 @@ extern "C" {
#define meshtastic_DeviceMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_EnvironmentMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_PowerMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_AirQualityMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_AirQualityMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_LocalStats_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_HealthMetrics_init_zero {false, 0, false, 0, false, 0}
#define meshtastic_HostMetrics_init_zero {0, 0, 0, false, 0, false, 0, 0, 0, 0, false, ""}
@ -490,6 +503,9 @@ extern "C" {
#define meshtastic_AirQualityMetrics_co2_tag 13
#define meshtastic_AirQualityMetrics_co2_temperature_tag 14
#define meshtastic_AirQualityMetrics_co2_humidity_tag 15
#define meshtastic_AirQualityMetrics_form_formaldehyde_tag 16
#define meshtastic_AirQualityMetrics_form_humidity_tag 17
#define meshtastic_AirQualityMetrics_form_temperature_tag 18
#define meshtastic_LocalStats_uptime_seconds_tag 1
#define meshtastic_LocalStats_channel_utilization_tag 2
#define meshtastic_LocalStats_air_util_tx_tag 3
@ -597,7 +613,10 @@ X(a, STATIC, OPTIONAL, UINT32, particles_50um, 11) \
X(a, STATIC, OPTIONAL, UINT32, particles_100um, 12) \
X(a, STATIC, OPTIONAL, UINT32, co2, 13) \
X(a, STATIC, OPTIONAL, FLOAT, co2_temperature, 14) \
X(a, STATIC, OPTIONAL, FLOAT, co2_humidity, 15)
X(a, STATIC, OPTIONAL, FLOAT, co2_humidity, 15) \
X(a, STATIC, OPTIONAL, FLOAT, form_formaldehyde, 16) \
X(a, STATIC, OPTIONAL, FLOAT, form_humidity, 17) \
X(a, STATIC, OPTIONAL, FLOAT, form_temperature, 18)
#define meshtastic_AirQualityMetrics_CALLBACK NULL
#define meshtastic_AirQualityMetrics_DEFAULT NULL
@ -686,7 +705,7 @@ extern const pb_msgdesc_t meshtastic_Nau7802Config_msg;
/* Maximum encoded size of messages (where known) */
#define MESHTASTIC_MESHTASTIC_TELEMETRY_PB_H_MAX_SIZE meshtastic_Telemetry_size
#define meshtastic_AirQualityMetrics_size 88
#define meshtastic_AirQualityMetrics_size 106
#define meshtastic_DeviceMetrics_size 27
#define meshtastic_EnvironmentMetrics_size 113
#define meshtastic_HealthMetrics_size 11

View File

@ -4,8 +4,13 @@
#include "main.h"
#include "mesh/Router.h"
#include <AsyncUDP.h>
#if HAS_ETHERNET && defined(ARCH_NRF52)
#include "mesh/eth/ethClient.h"
#else
#include <WiFi.h>
#endif
#include <AsyncUDP.h>
#if HAS_ETHERNET && defined(USE_WS5500)
#include <ETHClass2.h>
@ -22,11 +27,11 @@ class UdpMulticastHandler final
void start()
{
if (udp.listenMulticast(udpIpAddress, UDP_MULTICAST_DEFAUL_PORT, 64)) {
#ifndef ARCH_PORTDUINO
// FIXME(PORTDUINO): arduino lacks IPAddress::toString()
LOG_DEBUG("UDP Listening on IP: %s", WiFi.localIP().toString().c_str());
#if defined(ARCH_NRF52) || defined(ARCH_PORTDUINO)
LOG_DEBUG("UDP Listening on IP: %u.%u.%u.%u:%u", udpIpAddress[0], udpIpAddress[1], udpIpAddress[2], udpIpAddress[3],
UDP_MULTICAST_DEFAUL_PORT);
#else
LOG_DEBUG("UDP Listening");
LOG_DEBUG("UDP Listening on IP: %s", WiFi.localIP().toString().c_str());
#endif
udp.onPacket([this](AsyncUDPPacket packet) { onReceive(packet); });
} else {
@ -37,7 +42,10 @@ class UdpMulticastHandler final
void onReceive(AsyncUDPPacket packet)
{
size_t packetLength = packet.length();
#ifndef ARCH_PORTDUINO
#if defined(ARCH_NRF52)
IPAddress ip = packet.remoteIP();
LOG_DEBUG("UDP broadcast from: %u.%u.%u.%u, len=%u", ip[0], ip[1], ip[2], ip[3], packetLength);
#elif !defined(ARCH_PORTDUINO)
// FIXME(PORTDUINO): arduino lacks IPAddress::toString()
LOG_DEBUG("UDP broadcast from: %s, len=%u", packet.remoteIP().toString().c_str(), packetLength);
#endif
@ -61,7 +69,11 @@ class UdpMulticastHandler final
if (!mp || !udp) {
return false;
}
#ifndef ARCH_PORTDUINO
#if defined(ARCH_NRF52)
if (!isEthernetAvailable()) {
return false;
}
#elif !defined(ARCH_PORTDUINO)
if (WiFi.status() != WL_CONNECTED) {
return false;
}

View File

@ -1447,7 +1447,7 @@ void CannedMessageModule::drawEmotePickerScreen(OLEDDisplay *display, OLEDDispla
int headerY = y;
int listTop = headerY + headerFontHeight + headerMargin;
int visibleRows = (display->getHeight() - listTop - 2) / rowHeight;
int _visibleRows = (display->getHeight() - listTop - 2) / rowHeight;
int numEmotes = graphics::numEmotes;
// Clamp highlight index
@ -1457,11 +1457,11 @@ void CannedMessageModule::drawEmotePickerScreen(OLEDDisplay *display, OLEDDispla
emotePickerIndex = numEmotes - 1;
// Determine which emote is at the top
int topIndex = emotePickerIndex - visibleRows / 2;
int topIndex = emotePickerIndex - _visibleRows / 2;
if (topIndex < 0)
topIndex = 0;
if (topIndex > numEmotes - visibleRows)
topIndex = std::max(0, numEmotes - visibleRows);
if (topIndex > numEmotes - _visibleRows)
topIndex = std::max(0, numEmotes - _visibleRows);
// Draw header/title
display->setFont(FONT_SMALL);
@ -1709,7 +1709,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
} else {
// Text: split by words and wrap inside word if needed
String text = token.second;
uint16_t pos = 0;
pos = 0;
while (pos < text.length()) {
// Find next space (or end)
int spacePos = text.indexOf(' ', pos);
@ -1753,7 +1753,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
int yLine = inputY;
for (auto &line : lines) {
int nextX = x;
for (auto &token : line) {
for (const auto &token : line) {
if (token.first) {
const graphics::Emote *emote = nullptr;
for (int j = 0; j < graphics::numEmotes; j++) {
@ -1789,19 +1789,20 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
int topMsg;
std::vector<int> rowHeights;
int visibleRows;
int _visibleRows;
// Draw header (To: ...)
drawHeader(display, x, y, buffer);
// Shift message list upward by 3 pixels to reduce spacing between header and first message
const int listYOffset = y + FONT_HEIGHT_SMALL - 3;
visibleRows = (display->getHeight() - listYOffset) / baseRowSpacing;
_visibleRows = (display->getHeight() - listYOffset) / baseRowSpacing;
// Figure out which messages are visible and their needed heights
topMsg =
(messagesCount > visibleRows && currentMessageIndex >= visibleRows - 1) ? currentMessageIndex - visibleRows + 2 : 0;
int countRows = std::min(messagesCount, visibleRows);
topMsg = (messagesCount > _visibleRows && currentMessageIndex >= _visibleRows - 1)
? currentMessageIndex - _visibleRows + 2
: 0;
int countRows = std::min(messagesCount, _visibleRows);
// --- Build per-row max height based on all emotes in line ---
for (int i = 0; i < countRows; i++) {
@ -1828,7 +1829,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
int lineY = yCursor;
const char *msg = getMessageByIndex(msgIdx);
int rowHeight = rowHeights[vis];
bool highlight = (msgIdx == currentMessageIndex);
bool _highlight = (msgIdx == currentMessageIndex);
// --- Multi-emote tokenization ---
std::vector<std::pair<bool, String>> tokens; // (isEmote, token)
@ -1881,20 +1882,20 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
int textYOffset = (rowHeight - FONT_HEIGHT_SMALL) / 2;
#ifdef USE_EINK
int nextX = x + (highlight ? 12 : 0);
if (highlight)
int nextX = x + (_highlight ? 12 : 0);
if (_highlight)
display->drawString(x + 0, lineY + textYOffset, ">");
#else
int scrollPadding = 8;
if (highlight) {
if (_highlight) {
display->fillRect(x + 0, lineY, display->getWidth() - scrollPadding, rowHeight);
display->setColor(BLACK);
}
int nextX = x + (highlight ? 2 : 0);
int nextX = x + (_highlight ? 2 : 0);
#endif
// Draw all tokens left to right
for (auto &token : tokens) {
for (const auto &token : tokens) {
if (token.first) {
// Emote
const graphics::Emote *emote = nullptr;
@ -1916,7 +1917,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
}
}
#ifndef USE_EINK
if (highlight)
if (_highlight)
display->setColor(WHITE);
#endif
@ -1924,11 +1925,11 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
}
// Scrollbar
if (messagesCount > visibleRows) {
if (messagesCount > _visibleRows) {
int scrollHeight = display->getHeight() - listYOffset;
int scrollTrackX = display->getWidth() - 6;
display->drawRect(scrollTrackX, listYOffset, 4, scrollHeight);
int barHeight = (scrollHeight * visibleRows) / messagesCount;
int barHeight = (scrollHeight * _visibleRows) / messagesCount;
int scrollPos = listYOffset + (scrollHeight * topMsg) / messagesCount;
display->fillRect(scrollTrackX, scrollPos, 4, barHeight);
}

View File

@ -107,11 +107,7 @@ int SystemCommandsModule::handleInputEvent(const InputEvent *event)
return true;
// Power control
case INPUT_BROKER_SHUTDOWN:
LOG_ERROR("Shutting Down");
IF_SCREEN(screen->showSimpleBanner("Shutting Down..."));
nodeDB->saveToDisk();
shutdownAtMsec = millis() + DEFAULT_SHUTDOWN_SECONDS * 1000;
// runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
shutdownAtMsec = millis();
return true;
default:

View File

@ -0,0 +1,73 @@
#include "AsyncUDP.h"
#if HAS_ETHERNET
AsyncUDP::AsyncUDP() : OSThread("AsyncUDP"), localPort(0) {}
bool AsyncUDP::listenMulticast(IPAddress multicastIP, uint16_t port, uint8_t ttl)
{
if (!isMulticast(multicastIP))
return false;
localPort = port;
udp.beginMulticast(multicastIP, port);
return true;
}
size_t AsyncUDP::write(uint8_t b)
{
return udp.write(&b, 1);
}
size_t AsyncUDP::write(const uint8_t *data, size_t len)
{
return udp.write(data, len);
}
void AsyncUDP::onPacket(const std::function<void(AsyncUDPPacket)> &callback)
{
_onPacket = callback;
}
bool AsyncUDP::writeTo(const uint8_t *data, size_t len, IPAddress ip, uint16_t port)
{
if (!udp.beginPacket(ip, port))
return false;
udp.write(data, len);
return udp.endPacket();
}
// AsyncUDPPacket
AsyncUDPPacket::AsyncUDPPacket(EthernetUDP &source) : _udp(source), _remoteIP(source.remoteIP()), _remotePort(source.remotePort())
{
if (_udp.available() > 0) {
_readLength = _udp.read(_buffer, sizeof(_buffer));
} else {
_readLength = 0;
}
}
IPAddress AsyncUDPPacket::remoteIP()
{
return _remoteIP;
}
uint16_t AsyncUDPPacket::length()
{
return _readLength;
}
const uint8_t *AsyncUDPPacket::data()
{
return _buffer;
}
int32_t AsyncUDP::runOnce()
{
if (_onPacket && udp.parsePacket() > 0) {
AsyncUDPPacket packet(udp);
_onPacket(packet);
}
return 5; // check every 5ms
}
#endif // HAS_ETHERNET

View File

@ -0,0 +1,63 @@
#ifndef ASYNC_UDP_H
#define ASYNC_UDP_H
#include "configuration.h"
#if HAS_ETHERNET
#include "concurrency/OSThread.h"
#include <IPAddress.h>
#include <Print.h>
#include <RAK13800_W5100S.h>
#include <cstdint>
#include <functional>
class AsyncUDPPacket;
class AsyncUDP : public Print, private concurrency::OSThread
{
public:
AsyncUDP();
explicit operator bool() const { return localPort != 0; }
bool listenMulticast(IPAddress multicastIP, uint16_t port, uint8_t ttl = 64);
bool writeTo(const uint8_t *data, size_t len, IPAddress ip, uint16_t port);
size_t write(uint8_t b) override;
size_t write(const uint8_t *data, size_t len) override;
void onPacket(const std::function<void(AsyncUDPPacket)> &callback);
private:
EthernetUDP udp;
uint16_t localPort;
std::function<void(AsyncUDPPacket)> _onPacket;
virtual int32_t runOnce() override;
};
class AsyncUDPPacket
{
public:
AsyncUDPPacket(EthernetUDP &source);
IPAddress remoteIP();
uint16_t length();
const uint8_t *data();
private:
EthernetUDP &_udp;
IPAddress _remoteIP;
uint16_t _remotePort;
size_t _readLength = 0;
static constexpr size_t BUF_SIZE = 512;
uint8_t _buffer[BUF_SIZE];
};
inline bool isMulticast(const IPAddress &ip)
{
return (ip[0] & 0xF0) == 0xE0;
}
#endif // HAS_ETHERNET
#endif // ASYNC_UDP_H

View File

@ -40,21 +40,8 @@ void powerCommandsCheck()
#endif
}
#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
if (shutdownAtMsec && screen) {
screen->showSimpleBanner("Shutting Down...", 0); // stays on screen
}
#endif
if (shutdownAtMsec && millis() > shutdownAtMsec) {
LOG_INFO("Shut down from admin command");
#if defined(ARCH_NRF52) || defined(ARCH_ESP32) || defined(ARCH_RP2040)
playShutdownMelody();
shutdownAtMsec = 0;
power->shutdown();
#elif defined(ARCH_PORTDUINO)
exit(EXIT_SUCCESS);
#else
LOG_WARN("FIXME implement shutdown for this platform");
#endif
}
}

View File

@ -1,47 +1,3 @@
; Meshtastic DIY v1 by Nano VHF Schematic based on ESP32-WROOM-32 (38 pins) devkit & EBYTE E22 SX1262/SX1268 module
[env:meshtastic-diy-v1]
extends = esp32_base
board = esp32doit-devkit-v1
board_check = true
build_flags =
${esp32_base.build_flags}
-D DIY_V1
-D EBYTE_E22
-I variants/diy/v1
; Meshtastic DIY v1.1 new schematic based on ESP32-WROOM-32 & SX1262/SX1268 modules
[env:meshtastic-diy-v1_1]
extends = esp32_base
board = esp32doit-devkit-v1
board_level = extra
build_flags =
${esp32_base.build_flags}
-D DIY_V1
-D EBYTE_E22
-I variants/diy/v1_1
; Port to Disaster Radio's ESP32-v3 Dev Board
[env:meshtastic-dr-dev]
extends = esp32_base
board = esp32doit-devkit-v1
board_upload.maximum_size = 4194304
board_upload.maximum_ram_size = 532480
build_flags =
${esp32_base.build_flags}
-D DR_DEV
-D EBYTE_E22
-I variants/diy/dr-dev
; Hydra - Meshtastic DIY v1 hardware with some specific changes
[env:hydra]
extends = esp32_base
board = esp32doit-devkit-v1
build_flags =
${esp32_base.build_flags}
-D DIY_V1
-I variants/diy/hydra
; Promicro + E22(0)-xxxMM / RA-01SH modules board variant - DIY - without TCXO
[env:nrf52_promicro_diy_xtal]
extends = nrf52840_base
@ -122,35 +78,3 @@ build_src_filter = ${nrf52_base.build_src_filter} +<../variants/diy/seeed-xiao-n
lib_deps =
${nrf52840_base.lib_deps}
debug_tool = jlink
; NanoVHF T-Energy-S3 + E22(0)-xxxM - DIY
[env:t-energy-s3_e22]
extends = esp32s3_base
board = esp32-s3-devkitc-1
board_build.partitions = default_16MB.csv
board_level = extra
board_upload.flash_size = 16MB ;Specify the FLASH capacity as 16MB
board_build.arduino.memory_type = qio_opi ;Enable internal PSRAM
build_unflags =
${esp32s3_base.build_unflags}
-D ARDUINO_USB_MODE=1
build_flags =
${esp32s3_base.build_flags}
-D EBYTE_ESP32_S3
-D BOARD_HAS_PSRAM
-D ARDUINO_USB_MODE=0
-D ARDUINO_USB_CDC_ON_BOOT=1
-I variants/diy/t-energy-s3_e22
; ESP32 C3 Super Mini Development Board
; https://www.espboards.dev/esp32/esp32-c3-super-mini/
[env:esp32c3_super_mini]
extends = esp32c3_base
board = esp32-c3-devkitm-1
build_flags =
${esp32_base.build_flags}
-D PRIVATE_HW
-I variants/diy/esp32c3_super_mini
-D ARDUINO_USB_MODE=1
-D ARDUINO_USB_CDC_ON_BOOT=1
board_level = extra

View File

@ -8,11 +8,11 @@ build_flags =
-D VTABLES_IN_FLASH=1
-D CONFIG_DISABLE_HAL_LOCKS=1
-O2
-I variants/betafpv_2400_tx_micro
-I variants/esp32/betafpv_2400_tx_micro
board_build.f_cpu = 240000000L
upload_protocol = esptool
;upload_port = /dev/ttyUSB0
upload_speed = 460800
lib_deps =
${esp32_base.lib_deps}
adafruit/Adafruit NeoPixel @ ^1.12.0
adafruit/Adafruit NeoPixel @ ^1.12.0

View File

@ -8,10 +8,10 @@ build_flags =
-D VTABLES_IN_FLASH=1
-D CONFIG_DISABLE_HAL_LOCKS=1
-O2
-I variants/betafpv_900_tx_nano
-I variants/esp32/betafpv_900_tx_nano
board_build.f_cpu = 240000000L
upload_protocol = esptool
;upload_port = /dev/ttyUSB0
upload_speed = 460800
lib_deps =
${esp32_base.lib_deps}
${esp32_base.lib_deps}

View File

@ -5,7 +5,7 @@ board = esp32doit-devkit-v1
build_flags =
${esp32_base.build_flags}
-D CHATTER_2
-I variants/chatter2
-I variants/esp32/chatter2
lib_deps =
${esp32_base.lib_deps}

View File

@ -0,0 +1,11 @@
; Port to Disaster Radio's ESP32-v3 Dev Board
[env:meshtastic-dr-dev]
extends = esp32_base
board = esp32doit-devkit-v1
board_upload.maximum_size = 4194304
board_upload.maximum_ram_size = 532480
build_flags =
${esp32_base.build_flags}
-D DR_DEV
-D EBYTE_E22
-I variants/esp32/diy/dr-dev

View File

@ -0,0 +1,8 @@
; Hydra - Meshtastic DIY v1 hardware with some specific changes
[env:hydra]
extends = esp32_base
board = esp32doit-devkit-v1
build_flags =
${esp32_base.build_flags}
-D DIY_V1
-I variants/esp32/diy/hydra

View File

@ -0,0 +1,10 @@
; Meshtastic DIY v1 by Nano VHF Schematic based on ESP32-WROOM-32 (38 pins) devkit & EBYTE E22 SX1262/SX1268 module
[env:meshtastic-diy-v1]
extends = esp32_base
board = esp32doit-devkit-v1
board_check = true
build_flags =
${esp32_base.build_flags}
-D DIY_V1
-D EBYTE_E22
-I variants/esp32/diy/v1

View File

@ -0,0 +1,10 @@
; Meshtastic DIY v1.1 new schematic based on ESP32-WROOM-32 & SX1262/SX1268 modules
[env:meshtastic-diy-v1_1]
extends = esp32_base
board = esp32doit-devkit-v1
board_level = extra
build_flags =
${esp32_base.build_flags}
-D DIY_V1
-D EBYTE_E22
-I variants/esp32/diy/v1_1

View File

@ -5,7 +5,7 @@ board_level = extra
build_flags =
${esp32_base.build_flags}
-D PRIVATE_HW
-I variants/hackerboxes_esp32_io
-I variants/esp32/hackerboxes_esp32_io
monitor_speed = 115200
upload_protocol = esptool
;upload_port = /dev/ttyUSB0

View File

@ -4,4 +4,6 @@ extends = esp32_base
board_level = extra
board = heltec_wifi_lora_32
build_flags =
${esp32_base.build_flags} -D HELTEC_V1 -I variants/heltec_v1
${esp32_base.build_flags}
-D HELTEC_V1
-I variants/esp32/heltec_v1

View File

@ -4,5 +4,7 @@ board_level = extra
extends = esp32_base
board = heltec_wifi_lora_32_V2
build_flags =
${esp32_base.build_flags} -D HELTEC_V2_1 -I variants/heltec_v2.1
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
${esp32_base.build_flags}
-D HELTEC_V2_1
-I variants/esp32/heltec_v2.1
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.

View File

@ -4,4 +4,6 @@ board_level = extra
extends = esp32_base
board = heltec_wifi_lora_32_V2
build_flags =
${esp32_base.build_flags} -D HELTEC_V2_0 -I variants/heltec_v2
${esp32_base.build_flags}
-D HELTEC_V2_0
-I variants/esp32/heltec_v2

View File

@ -4,7 +4,7 @@ extends = esp32_base
board = heltec_wifi_lora_32
build_flags =
${esp32_base.build_flags}
-I variants/heltec_wireless_bridge
-I variants/esp32/heltec_wireless_bridge
-D HELTEC_WIRELESS_BRIDGE
-D BOARD_HAS_PSRAM
-D RADIOLIB_EXCLUDE_LR11X0=1

View File

@ -3,5 +3,7 @@ extends = esp32_base
board = heltec_wireless_stick_lite
board_level = extra
build_flags =
${esp32_base.build_flags} -D PRIVATE_HW -I variants/heltec_wsl_v2.1
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
${esp32_base.build_flags}
-D PRIVATE_HW
-I variants/esp32/heltec_wsl_v2.1
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.

View File

@ -5,7 +5,8 @@ monitor_filters = esp32_exception_decoder
build_src_filter =
${esp32_base.build_src_filter}
build_flags =
${esp32_base.build_flags} -I variants/m5stack_core
${esp32_base.build_flags}
-I variants/esp32/m5stack_core
-DILI9341_DRIVER
-DM5STACK
-DUSER_SETUP_LOADED

View File

@ -5,7 +5,8 @@ board_check = true
build_src_filter =
${esp32_base.build_src_filter}
build_flags =
${esp32_base.build_flags} -I variants/m5stack_coreink
${esp32_base.build_flags}
-I variants/esp32/m5stack_coreink
;-D RADIOLIB_VERBOSE
-Ofast
-D__MCUXPRESSO

View File

@ -5,4 +5,6 @@ board = ttgo-t-beam
lib_deps =
${esp32_base.lib_deps}
build_flags =
${esp32_base.build_flags} -D NANO_G1_EXPLORER -I variants/nano-g1-explorer
${esp32_base.build_flags}
-D NANO_G1_EXPLORER
-I variants/esp32/nano-g1-explorer

View File

@ -5,4 +5,6 @@ board = ttgo-t-beam
lib_deps =
${esp32_base.lib_deps}
build_flags =
${esp32_base.build_flags} -D NANO_G1 -I variants/nano-g1
${esp32_base.build_flags}
-D NANO_G1
-I variants/esp32/nano-g1

View File

@ -8,7 +8,7 @@ build_flags =
-DCONFIG_DISABLE_HAL_LOCKS=1
-DHAS_STK8XXX=1
-O2
-Ivariants/radiomaster_900_bandit
-I variants/esp32/radiomaster_900_bandit
board_build.f_cpu = 240000000L
upload_protocol = esptool
lib_deps =

View File

@ -12,8 +12,8 @@ build_flags =
-DVTABLES_IN_FLASH=1
-DCONFIG_DISABLE_HAL_LOCKS=1
-O2
-Ivariants/radiomaster_900_bandit_nano
-I variants/esp32/radiomaster_900_bandit_nano
board_build.f_cpu = 240000000L
upload_protocol = esptool
lib_deps =
${esp32_base.lib_deps}
${esp32_base.lib_deps}

View File

@ -7,8 +7,8 @@ build_flags =
-DVTABLES_IN_FLASH=1
-DCONFIG_DISABLE_HAL_LOCKS=1
-O2
-Ivariants/radiomaster_900_bandit_nano
-I variants/esp32/radiomaster_900_bandit_nano
board_build.f_cpu = 240000000L
upload_protocol = esptool
lib_deps =
${esp32_base.lib_deps}
${esp32_base.lib_deps}

View File

@ -3,5 +3,7 @@ extends = esp32_base
board = wiscore_rak11200
board_check = true
build_flags =
${esp32_base.build_flags} -D RAK_11200 -I variants/rak11200
upload_speed = 115200
${esp32_base.build_flags}
-D RAK_11200
-I variants/esp32/rak11200
upload_speed = 115200

View File

@ -5,4 +5,6 @@ board = ttgo-t-beam
lib_deps =
${esp32_base.lib_deps}
build_flags =
${esp32_base.build_flags} -D STATION_G1 -I variants/station-g1
${esp32_base.build_flags}
-D STATION_G1
-I variants/esp32/station-g1

View File

@ -6,8 +6,10 @@ board_check = true
lib_deps =
${esp32_base.lib_deps}
build_flags =
${esp32_base.build_flags} -D TBEAM_V10 -I variants/tbeam
${esp32_base.build_flags}
-D TBEAM_V10
-I variants/esp32/tbeam
-DGPS_POWER_TOGGLE ; comment this line to disable double press function on the user button to turn off gps entirely.
-DBOARD_HAS_PSRAM
-mfix-esp32-psram-cache-issue
upload_speed = 921600
upload_speed = 921600

View File

@ -4,4 +4,6 @@ board_level = extra
extends = esp32_base
board = ttgo-t-beam
build_flags =
${esp32_base.build_flags} -D TBEAM_V07 -I variants/tbeam_v07
${esp32_base.build_flags}
-D TBEAM_V07
-I variants/esp32/tbeam_v07

View File

@ -3,5 +3,7 @@ board_level = extra
extends = esp32_base
board = ttgo-lora32-v1
build_flags =
${esp32_base.build_flags} -D TLORA_V1 -I variants/tlora_v1
upload_speed = 115200
${esp32_base.build_flags}
-D TLORA_V1
-I variants/esp32/tlora_v1
upload_speed = 115200

View File

@ -3,5 +3,5 @@ board_level = extra
extends = esp32_base
board = ttgo-lora32-v1
build_flags =
${esp32_base.build_flags} -D TLORA_V1_3 -I variants/tlora_v1_3
upload_speed = 115200
${esp32_base.build_flags} -D TLORA_V1_3 -I variants/esp32/tlora_v1_3
upload_speed = 115200

View File

@ -3,4 +3,6 @@ board_level = extra
extends = esp32_base
board = ttgo-lora32-v1
build_flags =
${esp32_base.build_flags} -D TLORA_V2 -I variants/tlora_v2
${esp32_base.build_flags}
-D TLORA_V2
-I variants/esp32/tlora_v2

View File

@ -3,6 +3,6 @@ extends = esp32_base
board = ttgo-lora32-v21
board_check = true
build_flags =
${esp32_base.build_flags} -D TLORA_V2_1_16 -I variants/tlora_v2_1_16
${esp32_base.build_flags} -D TLORA_V2_1_16 -I variants/esp32/tlora_v2_1_16
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
upload_speed = 115200
upload_speed = 115200

View File

@ -5,7 +5,7 @@ board = ttgo-lora32-v21
build_flags =
${esp32_base.build_flags}
-D TLORA_V2_1_16
-I variants/tlora_v2_1_16
-I variants/esp32/tlora_v2_1_16
-D GPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
-D LORA_TCXO_GPIO=33
upload_speed = 115200

View File

@ -4,4 +4,6 @@ board_level = extra
board = ttgo-lora32-v21
build_flags =
${esp32_base.build_flags} -D TLORA_V2_1_18 -I variants/tlora_v2_1_18
${esp32_base.build_flags}
-D TLORA_V2_1_18
-I variants/esp32/tlora_v2_1_18

View File

@ -4,7 +4,7 @@ board = ttgo-lora32-v21
build_flags =
${esp32_base.build_flags}
-D TLORA_V2_1_16
-I variants/tlora_v2_1_16
-I variants/esp32/tlora_v2_1_16
-D GPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
-D LORA_TCXO_GPIO=12
-D BUTTON_PIN=0

Some files were not shown because too many files have changed in this diff Show More