Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
645b647
Move PMSA003I to separate class and update AQ telemetry
oscgonfer Jul 1, 2025
a359f06
AirQualityTelemetry module not depend on PM sensor presence
oscgonfer Jul 1, 2025
abc13a2
Remove commented line
oscgonfer Jul 2, 2025
292a3b4
Fixes on PMS class
oscgonfer Jul 2, 2025
98efc6d
Add missing warmup period to wakeUp function
oscgonfer Jul 2, 2025
4a34a0f
Fixes on compilation for different variants
oscgonfer Jul 6, 2025
7c9b131
Add functions to check for I2C bus speed and set it
oscgonfer Jul 11, 2025
1f8b510
Add ScreenFonts.h
oscgonfer Jul 12, 2025
854a562
PMSA003I 1st round test
peterzqx Jul 22, 2025
fe74b83
feat: add support for RAK Wismesh Tag hardware platform (#6853)
DanielCao0 Jul 14, 2025
5fa685a
[create-pull-request] automated change (#7338)
github-actions[bot] Jul 14, 2025
e636118
STM32 PlatformIO cleanup (#7339)
vidplace7 Jul 14, 2025
c3a99e4
Map report should work over devices which do not have network hardwar…
thebentern Jul 15, 2025
d728c30
Message frame New Message Options and Clock / TDeck / Brightness Refi…
Xaositek Jul 15, 2025
1d41e1f
Fix L1 EInk HWModel (#7346)
thebentern Jul 15, 2025
6be4290
Drop NodeInfo packets if the is_licensed bit doesn't match owner (#7361)
jp-bennett Jul 16, 2025
4ad3d0f
clean up double i2c init/scan code (#7359)
caveman99 Jul 16, 2025
eea07e7
BaseUI Updates (#7358)
Xaositek Jul 17, 2025
b9b21b3
Add additional Epoch check for time set (#7375)
fifieldt Jul 18, 2025
36f6dd4
Fix build
thebentern Jul 18, 2025
2c48c1e
automated bumps (#7383)
github-actions[bot] Jul 19, 2025
fb43cad
Actions: Enforce PR labels (#7379)
vidplace7 Jul 19, 2025
540981e
ESP32: Initial sort variants by platform (#7340)
vidplace7 Jul 19, 2025
73694f3
ESP32c3: Migrate variants to new structure (#7342)
vidplace7 Jul 20, 2025
96391df
Misc cppcheck fixes (#7370)
jp-bennett Jul 20, 2025
a40d2a6
Upgrade trunk (#7349)
github-actions[bot] Jul 20, 2025
f8e3733
RP2040/RP2350: Migrate variants to new structure (#7345)
vidplace7 Jul 20, 2025
cc01d23
STM32: Migrate variants to new structure (#7389)
vidplace7 Jul 20, 2025
1c6ff6d
UDP for RAK4631 Eth Gw and the t-eth-elite. Solves #7149 (#7385)
caveman99 Jul 20, 2025
db05992
Restore High Resolution Hour Hand (#7392)
Xaositek Jul 20, 2025
ffe95b8
Update protobufs (#7395)
github-actions[bot] Jul 20, 2025
bac2f33
fix UDP builds on nRF (#7394)
caveman99 Jul 20, 2025
6401502
ESP32s3: Migrate variants to new structure (#7343)
vidplace7 Jul 20, 2025
7bd53dc
Unify the shutdown proceedure (#7393)
jp-bennett Jul 20, 2025
08e94fe
STM32 doesn't play
thebentern Jul 21, 2025
34c02d7
Text message rate limiting should return routing error instead (#7365)
thebentern Jul 21, 2025
81e0fd1
ARCH_STM32*WL* macro fix (#7397)
vidplace7 Jul 21, 2025
0d41244
Initial integration of ADS1X15 ADC
oscgonfer Jun 23, 2025
d6b5ac1
Fixes on imports of Adafruit library, and ADS1x15 integration
oscgonfer Jun 25, 2025
504e188
Add additional ADS1X15 to support daisy chaining
oscgonfer Jun 28, 2025
0723c10
Fix in screen functions
oscgonfer Jul 7, 2025
14a7f8b
Changes on bus speed for ADS1X15
oscgonfer Jul 21, 2025
ec0b1e9
Change I2C bus speed only once
oscgonfer Jul 22, 2025
34035d4
Minor changes for logging of I2C bus changes
oscgonfer Jul 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
24 changes: 24 additions & 0 deletions .github/workflows/pr_enforce_labels.yml
Original file line number Diff line number Diff line change
@@ -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(', ')}.`);
}
3 changes: 2 additions & 1 deletion .github/workflows/release_channels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/update_protobufs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
8 changes: 4 additions & 4 deletions .trunk/trunk.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion arch/portduino/portduino.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions arch/stm32/stm32.ini
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,17 @@ build_flags =
-DMESHTASTIC_EXCLUDE_WIFI=1
-DMESHTASTIC_EXCLUDE_TZ=1 ; Exclude TZ to save some flash space.
-DSERIAL_RX_BUFFER_SIZE=256 ; For GPS - the default of 64 is too small.
-DHAS_SCREEN=0 ; Always disable screen for STM32, it is not supported.
-DPIO_FRAMEWORK_ARDUINO_NANOLIB_FLOAT_PRINTF ; This is REQUIRED for at least traceroute debug prints - without it the length ends up uninitialized.
-DDEBUG_MUTE ; You can #undef DEBUG_MUTE in certain source files if you need the logs.
-fmerge-all-constants
-ffunction-sections
-fdata-sections
-DRADIOLIB_EXCLUDE_SX128X=1
-DRADIOLIB_EXCLUDE_SX127X=1
-DRADIOLIB_EXCLUDE_LR11X0=1
-DHAL_DAC_MODULE_ONLY
-DHAL_RNG_MODULE_ENABLED

build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/RemoteHardwareModule.cpp> -<platform/nrf52> -<platform/portduino> -<platform/rp2xx0> -<mesh/raspihttp>
Expand Down
3 changes: 3 additions & 0 deletions bin/org.meshtastic.meshtasticd.metainfo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
7 changes: 5 additions & 2 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
meshtasticd (2.7.3.0) UNRELEASED; urgency=medium
meshtasticd (2.7.4.0) UNRELEASED; urgency=medium

[ Austin Lane ]
* Initial packaging
Expand Down Expand Up @@ -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
6 changes: 5 additions & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -200,3 +202,5 @@ lib_deps =
sensirion/Sensirion Core@0.7.1
# renovate: datasource=custom.pio depName=Sensirion I2C SCD4x packageName=sensirion/library/Sensirion I2C SCD4x
sensirion/Sensirion I2C SCD4x@1.1.0
# renovate: datasource=custom.pio depName=Adafruit ADS1X15 packageName=adafruit/library/Adafruit ADS1X15 Library
adafruit/Adafruit ADS1X15@2.5.0
17 changes: 15 additions & 2 deletions src/Power.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
}

Expand Down
9 changes: 1 addition & 8 deletions src/buzz/BuzzerFeedbackThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions src/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define LTR390UV_ADDR 0x53
#define XPOWERS_AXP192_AXP2101_ADDRESS 0x34 // same adress as TCA8418
#define PCT2075_ADDR 0x37
#define ADS1X15_ADDR 0x48 // same address as FT6336U
#define ADS1X15_ADDR_ALT1 0x49
#define ADS1X15_ADDR_ALT2 0x4A
#define ADS1X15_ADDR_ALT3 0x4B

// -----------------------------------------------------------------------------
// ACCELEROMETER
Expand Down
2 changes: 2 additions & 0 deletions src/detect/ScanI2C.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ class ScanI2C
TCA8418KB,
PCT2075,
BMM150,
ADS1X15,
ADS1X15_ALT,
} DeviceType;

// typedef uint8_t DeviceAddress;
Expand Down
91 changes: 90 additions & 1 deletion src/detect/ScanI2CTwoWire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,75 @@ uint16_t ScanI2CTwoWire::getRegisterValue(const ScanI2CTwoWire::RegisterLocation
return value;
}

bool ScanI2CTwoWire::setClockSpeed(I2CPort port, uint32_t speed) {

DeviceAddress addr(port, 0x00);
TwoWire *i2cBus;

#if WIRE_INTERFACES_COUNT == 2
if (port == I2CPort::WIRE1) {
i2cBus = &Wire1;
} else {
#endif
i2cBus = &Wire;
#if WIRE_INTERFACES_COUNT == 2
}
#endif

return i2cBus->setClock(speed);
}

uint32_t ScanI2CTwoWire::getClockSpeed(I2CPort port) {

DeviceAddress addr(port, 0x00);
TwoWire *i2cBus;

#if WIRE_INTERFACES_COUNT == 2
if (port == I2CPort::WIRE1) {
i2cBus = &Wire1;
} else {
#endif
i2cBus = &Wire;
#if WIRE_INTERFACES_COUNT == 2
}
#endif

return i2cBus->getClock();
}

/// for SEN5X detection
String readSEN5xProductName(TwoWire* i2cBus, uint8_t address) {
uint8_t cmd[] = { 0xD0, 0x14 };
uint8_t response[48] = {0};

i2cBus->beginTransmission(address);
i2cBus->write(cmd, 2);
if (i2cBus->endTransmission() != 0) return "";

delay(20);
if (i2cBus->requestFrom(address, (uint8_t)48) != 48) return "";

for (int i = 0; i < 48 && i2cBus->available(); ++i) {
response[i] = i2cBus->read();
}

char productName[33] = {0};
int j = 0;
for (int i = 0; i < 48 && j < 32; i += 3) {
if (response[i] >= 32 && response[i] <= 126)
productName[j++] = response[i];
else
break;

if (response[i + 1] >= 32 && response[i + 1] <= 126)
productName[j++] = response[i + 1];
else
break;
}

return String(productName);
}

#define SCAN_SIMPLE_CASE(ADDR, T, ...) \
case ADDR: \
logFoundDevice(__VA_ARGS__); \
Expand Down Expand Up @@ -495,7 +564,16 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
}
break;

case 0x48: {
case 0x48: { // same as ADS1X15 main address

// ADS1X15 default config register is 8583h
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x01), 2);
if (registerValue == 0x8583) {
type = ADS1X15;
logFoundDevice("ADS1X15", (uint8_t)addr.address);
break;
}

i2cBus->beginTransmission(addr.address);
uint8_t getInfo[] = {0x5A, 0xC0, 0x00, 0xFF, 0xFC};
uint8_t expectedInfo[] = {0xa5, 0xE0, 0x00, 0x3F, 0x19};
Expand All @@ -515,6 +593,17 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
break;
}

case ADS1X15_ADDR_ALT1:
case ADS1X15_ADDR_ALT2:
case ADS1X15_ADDR_ALT3:
// ADS1X15 default config register is 8583h
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x01), 2);
if (registerValue == 0x8583) {
type = ADS1X15_ALT;
logFoundDevice("ADS1X15_ALT", (uint8_t)addr.address);
break;
}

default:
LOG_INFO("Device found at address 0x%x was not able to be enumerated", (uint8_t)addr.address);
}
Expand Down
3 changes: 3 additions & 0 deletions src/detect/ScanI2CTwoWire.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ class ScanI2CTwoWire : public ScanI2C

size_t countDevices() const override;

bool setClockSpeed(ScanI2C::I2CPort, uint32_t);
uint32_t getClockSpeed(ScanI2C::I2CPort);

protected:
FoundDevice firstOfOrNONE(size_t, DeviceType[]) const override;

Expand Down
9 changes: 8 additions & 1 deletion src/gps/RTC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,14 @@ RTCSetResult perhapsSetRTC(RTCQuality q, struct tm &t)
time_t res = gm_mktime(&t);
struct timeval tv;
tv.tv_sec = res;
tv.tv_usec = 0; // time.centisecond() * (10 / 1000);
tv.tv_usec = 0; // time.centisecond() * (10 / 1000);
uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
#ifdef BUILD_EPOCH
if (tv.tv_sec < BUILD_EPOCH) {
LOG_WARN("Ignore time (%ld) before build epoch (%ld)!", printableEpoch, BUILD_EPOCH);
return RTCSetResultInvalidTime;
}
#endif

// LOG_DEBUG("Got time from GPS month=%d, year=%d, unixtime=%ld", t.tm_mon, t.tm_year, tv.tv_sec);
if (t.tm_year < 0 || t.tm_year >= 300) {
Expand Down
13 changes: 9 additions & 4 deletions src/graphics/Screen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,8 @@ void Screen::setFrames(FrameFocus focus)
uint8_t previousFrameCount = framesetInfo.frameCount;
FramesetInfo fsi; // Location of specific frames, for applying focus parameter

graphics::UIRenderer::rebuildFavoritedNodes();

LOG_DEBUG("Show standard frames");
showingNormalScreen = true;

Expand Down Expand Up @@ -999,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);
}
Expand Down Expand Up @@ -1374,9 +1376,12 @@ int Screen::handleInputEvent(const InputEvent *event)
menuHandler::clockMenu();
} else if (this->ui->getUiState()->currentFrame == framesetInfo.positions.lora) {
menuHandler::LoraRegionPicker();
} else if (this->ui->getUiState()->currentFrame == framesetInfo.positions.textMessage &&
devicestate.rx_text_message.from) {
menuHandler::messageResponseMenu();
} else if (this->ui->getUiState()->currentFrame == framesetInfo.positions.textMessage) {
if (devicestate.rx_text_message.from) {
menuHandler::messageResponseMenu();
} else {
menuHandler::textMessageBaseMenu();
}
} else if (framesetInfo.positions.firstFavorite != 255 &&
this->ui->getUiState()->currentFrame >= framesetInfo.positions.firstFavorite &&
this->ui->getUiState()->currentFrame <= framesetInfo.positions.lastFavorite) {
Expand Down
2 changes: 1 addition & 1 deletion src/graphics/SharedUIDisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const char *ti
timeX = screenW - xOffset - timeStrWidth + 3;

// === Show Mail or Mute Icon to the Left of Time ===
int iconRightEdge = timeX - 1;
int iconRightEdge = timeX - 2;

bool showMail = false;

Expand Down
Loading
Loading