Compare commits

...

44 Commits

Author SHA1 Message Date
Jonathan Bennett
33e477cb1c Merge branch 'develop' into native-time 2025-12-16 16:45:29 -06:00
Ben Meadors
203826374c Merge branch 'master' into develop 2025-12-16 11:45:08 -06:00
Ben Meadors
8e0547e76d Implement Long Turbo preset (#8985)
* Implement Long_Turbo preset

* Oops

* Start to DRY up menu handler by actually using OO concepts instead of jank separate arrays

* Move the implementation back into the method

* Dummy comment

* Listen to copilot feedback and prevent dangling pointer

* Static and optional
2025-12-16 11:42:13 -06:00
github-actions[bot]
8a48321555 Upgrade trunk (#8989)
Co-authored-by: vidplace7 <1779290+vidplace7@users.noreply.github.com>
2025-12-16 06:17:03 -06:00
Austin
917794ebab PIO: Remove useless inheritence (references extends env) (#8987)
Remove lib_deps section for all PlatformIO envs which are unneeded (only references the `extends` lib_deps, thus pointless)

This makes the configs more concise and make future PIO variants/ libdeps audits easier.
2025-12-16 15:38:10 +11:00
Austin
ed77ba5612 Replace PIO fuzzy version matches (reproducible builds) (#8984)
This change does not introduce version *changes*, but simply "updates" to the version already being referenced by the fuzzy-match (^)
2025-12-15 19:48:34 -06:00
Austin
eafa8c7b47 PIO: Fix ESP32 sub-variant inheritance (#8983) 2025-12-15 19:04:03 -06:00
renovate[bot]
aa8bb6c6f1 Update meshtastic/device-ui digest to 862ed04 (#8980)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-15 16:52:23 -06:00
github-actions[bot]
1952982896 Update protobufs (#8982)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2025-12-15 16:51:59 -06:00
Austin
024ac74f5c rp2xx0: Update to arduino-pico 5.4.4 (#8979) 2025-12-15 16:09:59 -06:00
renovate[bot]
de2b9632bb Update GitHub Artifact Actions (#8954)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-15 06:52:40 -06:00
github-actions[bot]
c2b7dc2641 Upgrade trunk (#8976)
Co-authored-by: vidplace7 <1779290+vidplace7@users.noreply.github.com>
2025-12-15 06:47:00 -06:00
Ben Meadors
d0d375f1ff Merge pull request #8973 from meshtastic/master
Backmerge
2025-12-14 14:51:16 -06:00
Jason P
e8ebfc0513 Add Rebooting to DFU mode notification as a simple pop-up (#8970)
* Add DFU notification as a simple pop-up

* Add safe conditional of IF_SCREEN

* Forgot #if HAS_SCREEN
2025-12-14 14:50:41 -06:00
Jonathan Bennett
4fd7960371 Drop debug warning 2025-12-13 12:22:22 -06:00
Jonathan Bennett
5f0e86a27e Merge branch 'develop' into native-time 2025-12-13 12:10:18 -06:00
Jonathan Bennett
9ce1a7ff79 Detect if NTP is active on native 2025-12-13 12:08:24 -06:00
Austin
bf32f17f28 Actions: Compact manifest job output summary (#8957) 2025-12-13 12:32:01 +11:00
Jonathan Bennett
b74238194b Add JSON packet recording option to native (#8930) 2025-12-12 18:30:43 -06:00
Ben Meadors
5d5819b876 Skipp assertion on this test for now 2025-12-12 16:26:01 -06:00
Tom Fifield
f127702bef Fix GPS Buffer full issue on NRF52480 (Seeed T1000E) (#8956)
We set the buffer size to about a byte on NRF52480, less than
other platforms:

esp32.ini:  -DSERIAL_BUFFER_SIZE=4096
esp32c6.ini:  -DSERIAL_BUFFER_SIZE=4096
nrf52.ini:  -DSERIAL_BUFFER_SIZE=1024

However, 115200 baud, like the T1000e uses is about 12 times that
- almost 15 bytes per millisecond.
15 bytes * 200 millisecond (our GPS poll rate)  = 3000 bytes, which is longer than our buffer
on the nrf52 platform. This causes "GPS Buffer full" errors on the T1000e
and other devices based on NRF52480 with newer GPS chips.

This patch increases SERIAL_BUFFER_SIZE for nrf52480 to 4096 to align with
other platforms. It keeps the original 1024 for the nrf52832, which has
fewer resources.

Fixes https://github.com/meshtastic/firmware/issues/5767
2025-12-12 16:23:23 -06:00
Ben Meadors
cce8cbfe34 Mark implicit ACK for MQTT as MQTT transport (#8939) (#8947)
* Mark implicit ACK for MQTT as MQTT transport

* TRUNK

* Fix build

* Make sure implicit ACKs from MQTT do not stop retransmissions in ReliableRouter

---------

Co-authored-by: GUVWAF <78759985+GUVWAF@users.noreply.github.com>
2025-12-12 05:21:08 -06:00
github-actions[bot]
a4a6c3509a Upgrade trunk (#8946)
Co-authored-by: vidplace7 <1779290+vidplace7@users.noreply.github.com>
2025-12-12 05:20:12 -06:00
GUVWAF
68250dc937 Mark implicit ACK for MQTT as MQTT transport (#8939)
* Mark implicit ACK for MQTT as MQTT transport

* TRUNK

* Fix build

* Make sure implicit ACKs from MQTT do not stop retransmissions in ReliableRouter

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2025-12-12 05:19:32 -06:00
Igor Danilov
c8628b3422 Fix #8899 [Bug]: [TloraPager] RotaryEncoder crash (#8933)
* Fix #8899 [Bug]: [TloraPager] RotaryEncoder crash

* Apply Copilot review

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2025-12-11 19:04:15 -06:00
renovate[bot]
2ac74d6677 Update actions/cache action to v5 (#8944)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-11 19:03:14 -06:00
Ben Meadors
9d487ddc0d Merge pull request #8945 from meshtastic/develop
Develop to master
2025-12-11 19:02:56 -06:00
Austin
bcfe069997 Optimize builds to reduce duplicate dependency checks (#8943)
'mtjson' will now build all required pieces when they don't exist
2025-12-11 19:01:31 -06:00
Austin
4fc96bdf83 Use 'gh-action-runner' action for "Check" jobs. (#8938)
Everything's pre-baked, 503 no more!
2025-12-11 12:26:21 -06:00
renovate[bot]
4ef943f204 Update meshtastic/device-ui digest to 2746a1c (#8936)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-11 10:32:28 -06:00
Jonathan Bennett
a8fa5f25cb Properly turn off power pins at shutdown for m3 (#8935) 2025-12-11 10:23:45 -06:00
Ben Meadors
3b2a1547de More board_level extras 2025-12-11 06:23:08 -06:00
github-actions[bot]
6f725a1996 Upgrade trunk (#8932)
Co-authored-by: vidplace7 <1779290+vidplace7@users.noreply.github.com>
2025-12-11 05:25:46 -06:00
Ben Meadors
467c042bf7 Merge pull request #8929 from meshtastic/master
Master to dev
2025-12-10 20:48:03 -06:00
Ben Meadors
cc4c41167c Merge pull request #8928 from meshtastic/develop 2025-12-10 19:08:53 -06:00
Benjamin Faershtein
fff2bbf4a0 Use truncated position for smart position (#8906) 2025-12-10 19:05:26 -06:00
Jonathan Bennett
fba92229a6 Add I2C device check for seesaw device on native (#8927)
It turns out the logic here was attempting to access i2c without being told to do so. Not good, especially on desktops.
2025-12-10 18:01:52 -06:00
Jason P
ff0a4ea320 Update System Frame for improved rendering on devices (#8923) 2025-12-10 16:30:26 -06:00
Jonathan Bennett
83b603827c Enable Muzi-base LED notification (#8925) 2025-12-10 16:29:50 -06:00
github-actions[bot]
ee80ec7b68 Upgrade trunk (#8922)
Co-authored-by: vidplace7 <1779290+vidplace7@users.noreply.github.com>
2025-12-10 06:14:00 -06:00
renovate[bot]
ec0dfb7337 Update peter-evans/create-pull-request action to v8 (#8919)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-09 15:56:27 -06:00
Austin
817f3b9ec8 Update platformio/espressif32 to v6.12.0 (#7697) 2025-12-09 09:57:02 -06:00
Ben Meadors
0726bb4b56 Merge pull request #8910 from meshtastic/develop
Develop to master
2025-12-09 06:04:59 -06:00
github-actions[bot]
6b11991be0 Upgrade trunk (#8856)
Co-authored-by: vidplace7 <1779290+vidplace7@users.noreply.github.com>
2025-12-09 06:03:52 -06:00
162 changed files with 640 additions and 401 deletions

View File

@@ -76,7 +76,7 @@ runs:
done done
- name: PlatformIO ${{ inputs.arch }} download cache - name: PlatformIO ${{ inputs.arch }} download cache
uses: actions/cache@v4 uses: actions/cache@v5
with: with:
path: ~/.platformio/.cache path: ~/.platformio/.cache
key: pio-cache-${{ inputs.arch }}-${{ hashFiles('.github/actions/**', '**.ini') }} key: pio-cache-${{ inputs.arch }}-${{ hashFiles('.github/actions/**', '**.ini') }}
@@ -100,7 +100,7 @@ runs:
id: version id: version
- name: Store binaries as an artifact - name: Store binaries as an artifact
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: firmware-${{ inputs.arch }}-${{ inputs.board }}-${{ steps.version.outputs.long }} name: firmware-${{ inputs.arch }}-${{ inputs.board }}-${{ steps.version.outputs.long }}
overwrite: true overwrite: true

View File

@@ -64,7 +64,7 @@ jobs:
PKG_VERSION: ${{ steps.version.outputs.deb }} PKG_VERSION: ${{ steps.version.outputs.deb }}
- name: Store binaries as an artifact - name: Store binaries as an artifact
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
overwrite: true overwrite: true

View File

@@ -56,19 +56,21 @@ jobs:
ota_firmware_source: ${{ steps.ota_dir.outputs.src || '' }} ota_firmware_source: ${{ steps.ota_dir.outputs.src || '' }}
ota_firmware_target: ${{ steps.ota_dir.outputs.tgt || '' }} ota_firmware_target: ${{ steps.ota_dir.outputs.tgt || '' }}
- name: Echo manifest from release/firmware-*.mt.json to job summary - name: Job summary
if: ${{ always() }}
env: env:
PIO_ENV: ${{ inputs.pio_env }} PIO_ENV: ${{ inputs.pio_env }}
run: | run: |
echo "## Manifest: \`$PIO_ENV\`" >> $GITHUB_STEP_SUMMARY echo "## $PIO_ENV" >> $GITHUB_STEP_SUMMARY
echo "<details><summary><strong>Manifest</strong></summary>" >> $GITHUB_STEP_SUMMARY
echo '' >> $GITHUB_STEP_SUMMARY
echo '```json' >> $GITHUB_STEP_SUMMARY echo '```json' >> $GITHUB_STEP_SUMMARY
cat release/firmware-*.mt.json >> $GITHUB_STEP_SUMMARY cat release/firmware-*.mt.json >> $GITHUB_STEP_SUMMARY
echo '' >> $GITHUB_STEP_SUMMARY echo '' >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY
echo "</details>" >> $GITHUB_STEP_SUMMARY
- name: Store binaries as an artifact - name: Store binaries as an artifact
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
id: upload id: upload
with: with:
name: firmware-${{ inputs.platform }}-${{ inputs.pio_env }}-${{ inputs.version }} name: firmware-${{ inputs.platform }}-${{ inputs.pio_env }}-${{ inputs.version }}

View File

@@ -98,7 +98,7 @@ jobs:
ref: ${{github.event.pull_request.head.ref}} ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}} repository: ${{github.event.pull_request.head.repo.full_name}}
- uses: actions/download-artifact@v6 - uses: actions/download-artifact@v7
with: with:
path: ./ path: ./
pattern: firmware-*-* pattern: firmware-*-*
@@ -111,7 +111,7 @@ jobs:
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
- name: Repackage in single firmware zip - name: Repackage in single firmware zip
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: firmware-${{inputs.target}}-${{ needs.version.outputs.long }} name: firmware-${{inputs.target}}-${{ needs.version.outputs.long }}
overwrite: true overwrite: true
@@ -127,7 +127,7 @@ jobs:
./Meshtastic_nRF52_factory_erase*.uf2 ./Meshtastic_nRF52_factory_erase*.uf2
retention-days: 30 retention-days: 30
- uses: actions/download-artifact@v6 - uses: actions/download-artifact@v7
with: with:
pattern: firmware-*-${{ needs.version.outputs.long }} pattern: firmware-*-${{ needs.version.outputs.long }}
merge-multiple: true merge-multiple: true
@@ -146,7 +146,7 @@ jobs:
run: zip -j -9 -r ./firmware-${{inputs.target}}-${{ needs.version.outputs.long }}.zip ./output run: zip -j -9 -r ./firmware-${{inputs.target}}-${{ needs.version.outputs.long }}.zip ./output
- name: Repackage in single elfs zip - name: Repackage in single elfs zip
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: debug-elfs-${{inputs.target}}-${{ needs.version.outputs.long }}.zip name: debug-elfs-${{inputs.target}}-${{ needs.version.outputs.long }}.zip
overwrite: true overwrite: true

View File

@@ -77,16 +77,21 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
check: ${{ fromJson(needs.setup.outputs.check) }} check: ${{ fromJson(needs.setup.outputs.check) }}
# Use 'arctastic' self-hosted runner pool when checking in the main repo
runs-on: ubuntu-latest runs-on: ${{ github.repository_owner == 'meshtastic' && 'arctastic' || 'ubuntu-latest' }}
if: ${{ github.event_name != 'workflow_dispatch' && github.repository == 'meshtastic/firmware' }} if: ${{ github.event_name != 'workflow_dispatch' && github.repository == 'meshtastic/firmware' }}
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v6
- name: Build base with:
id: base submodules: recursive
uses: ./.github/actions/setup-base ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Check ${{ matrix.check.board }} - name: Check ${{ matrix.check.board }}
run: bin/check-all.sh ${{ matrix.check.board }} uses: meshtastic/gh-action-firmware@main
with:
pio_platform: ${{ matrix.check.platform }}
pio_env: ${{ matrix.check.board }}
pio_target: check
build: build:
needs: [setup, version] needs: [setup, version]
@@ -168,7 +173,7 @@ jobs:
ref: ${{github.event.pull_request.head.ref}} ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}} repository: ${{github.event.pull_request.head.repo.full_name}}
- uses: actions/download-artifact@v6 - uses: actions/download-artifact@v7
with: with:
path: ./ path: ./
pattern: firmware-${{matrix.arch}}-* pattern: firmware-${{matrix.arch}}-*
@@ -178,7 +183,7 @@ jobs:
run: ls -R run: ls -R
- name: Repackage in single firmware zip - name: Repackage in single firmware zip
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }} name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
overwrite: true overwrite: true
@@ -195,7 +200,7 @@ jobs:
./Meshtastic_nRF52_factory_erase*.uf2 ./Meshtastic_nRF52_factory_erase*.uf2
retention-days: 30 retention-days: 30
- uses: actions/download-artifact@v6 - uses: actions/download-artifact@v7
with: with:
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }} name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
merge-multiple: true merge-multiple: true
@@ -214,7 +219,7 @@ jobs:
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
- name: Repackage in single elfs zip - name: Repackage in single elfs zip
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }} name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
overwrite: true overwrite: true
@@ -255,14 +260,14 @@ jobs:
Autogenerated by github action, developer should edit as required before publishing... Autogenerated by github action, developer should edit as required before publishing...
- name: Download source deb - name: Download source deb
uses: actions/download-artifact@v6 uses: actions/download-artifact@v7
with: with:
pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src
merge-multiple: true merge-multiple: true
path: ./output/debian-src path: ./output/debian-src
- name: Download `native-tft` pio deps - name: Download `native-tft` pio deps
uses: actions/download-artifact@v6 uses: actions/download-artifact@v7
with: with:
pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }} pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }}
merge-multiple: true merge-multiple: true
@@ -286,7 +291,7 @@ jobs:
}' > firmware-${{ needs.version.outputs.long }}.json }' > firmware-${{ needs.version.outputs.long }}.json
- name: Save Release manifest artifact - name: Save Release manifest artifact
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: manifest-${{ needs.version.outputs.long }} name: manifest-${{ needs.version.outputs.long }}
overwrite: true overwrite: true
@@ -327,7 +332,7 @@ jobs:
with: with:
python-version: 3.x python-version: 3.x
- uses: actions/download-artifact@v6 - uses: actions/download-artifact@v7
with: with:
pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }} pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
merge-multiple: true merge-multiple: true
@@ -344,7 +349,7 @@ jobs:
- name: Zip firmware - name: Zip firmware
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
- uses: actions/download-artifact@v6 - uses: actions/download-artifact@v7
with: with:
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }} name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
merge-multiple: true merge-multiple: true
@@ -383,14 +388,14 @@ jobs:
python-version: 3.x python-version: 3.x
- name: Get firmware artifacts - name: Get firmware artifacts
uses: actions/download-artifact@v6 uses: actions/download-artifact@v7
with: with:
pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }} pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }}
merge-multiple: true merge-multiple: true
path: ./publish path: ./publish
- name: Get manifest artifact - name: Get manifest artifact
uses: actions/download-artifact@v6 uses: actions/download-artifact@v7
with: with:
pattern: manifest-${{ needs.version.outputs.long }} pattern: manifest-${{ needs.version.outputs.long }}
path: ./publish path: ./publish

View File

@@ -147,7 +147,7 @@ jobs:
ref: ${{github.event.pull_request.head.ref}} ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}} repository: ${{github.event.pull_request.head.repo.full_name}}
- uses: actions/download-artifact@v6 - uses: actions/download-artifact@v7
with: with:
path: ./ path: ./
pattern: firmware-${{matrix.arch}}-* pattern: firmware-${{matrix.arch}}-*
@@ -160,7 +160,7 @@ jobs:
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
- name: Repackage in single firmware zip - name: Repackage in single firmware zip
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }} name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
overwrite: true overwrite: true
@@ -176,7 +176,7 @@ jobs:
./Meshtastic_nRF52_factory_erase*.uf2 ./Meshtastic_nRF52_factory_erase*.uf2
retention-days: 30 retention-days: 30
- uses: actions/download-artifact@v6 - uses: actions/download-artifact@v7
with: with:
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }} name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
merge-multiple: true merge-multiple: true
@@ -195,7 +195,7 @@ jobs:
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
- name: Repackage in single elfs zip - name: Repackage in single elfs zip
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }} name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
overwrite: true overwrite: true
@@ -235,14 +235,14 @@ jobs:
Autogenerated by github action, developer should edit as required before publishing... Autogenerated by github action, developer should edit as required before publishing...
- name: Download source deb - name: Download source deb
uses: actions/download-artifact@v6 uses: actions/download-artifact@v7
with: with:
pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src
merge-multiple: true merge-multiple: true
path: ./output/debian-src path: ./output/debian-src
- name: Download `native-tft` pio deps - name: Download `native-tft` pio deps
uses: actions/download-artifact@v6 uses: actions/download-artifact@v7
with: with:
pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }} pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }}
merge-multiple: true merge-multiple: true
@@ -292,7 +292,7 @@ jobs:
with: with:
python-version: 3.x python-version: 3.x
- uses: actions/download-artifact@v6 - uses: actions/download-artifact@v7
with: with:
pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }} pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
merge-multiple: true merge-multiple: true
@@ -309,7 +309,7 @@ jobs:
- name: Zip firmware - name: Zip firmware
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
- uses: actions/download-artifact@v6 - uses: actions/download-artifact@v7
with: with:
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }} name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}
merge-multiple: true merge-multiple: true
@@ -347,7 +347,7 @@ jobs:
with: with:
python-version: 3.x python-version: 3.x
- uses: actions/download-artifact@v6 - uses: actions/download-artifact@v7
with: with:
pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }} pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }}
merge-multiple: true merge-multiple: true

View File

@@ -58,7 +58,7 @@ jobs:
id: version id: version
- name: Download artifacts - name: Download artifacts
uses: actions/download-artifact@v6 uses: actions/download-artifact@v7
with: with:
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
merge-multiple: true merge-multiple: true

View File

@@ -56,7 +56,7 @@ jobs:
PLATFORMIO_CORE_DIR: pio/core PLATFORMIO_CORE_DIR: pio/core
- name: Store binaries as an artifact - name: Store binaries as an artifact
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: platformio-deps-${{ inputs.pio_env }}-${{ steps.version.outputs.long }} name: platformio-deps-${{ inputs.pio_env }}-${{ steps.version.outputs.long }}
overwrite: true overwrite: true

View File

@@ -60,7 +60,7 @@ jobs:
id: version id: version
- name: Download artifacts - name: Download artifacts
uses: actions/download-artifact@v6 uses: actions/download-artifact@v7
with: with:
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
merge-multiple: true merge-multiple: true

View File

@@ -50,7 +50,7 @@ jobs:
- name: Download test artifacts - name: Download test artifacts
if: needs.native-tests.result != 'skipped' if: needs.native-tests.result != 'skipped'
uses: actions/download-artifact@v6 uses: actions/download-artifact@v7
with: with:
name: platformio-test-report-${{ steps.version.outputs.long }} name: platformio-test-report-${{ steps.version.outputs.long }}
merge-multiple: true merge-multiple: true

View File

@@ -102,7 +102,7 @@ jobs:
PIP_DISABLE_PIP_VERSION_CHECK: 1 PIP_DISABLE_PIP_VERSION_CHECK: 1
- name: Create Bumps pull request - name: Create Bumps pull request
uses: peter-evans/create-pull-request@v7 uses: peter-evans/create-pull-request@v8
with: with:
base: ${{ github.event.repository.default_branch }} base: ${{ github.event.repository.default_branch }}
branch: create-pull-request/bump-version branch: create-pull-request/bump-version

View File

@@ -33,7 +33,7 @@ jobs:
# step 3 # step 3
- name: save report as pipeline artifact - name: save report as pipeline artifact
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: report.sarif name: report.sarif
overwrite: true overwrite: true

View File

@@ -59,7 +59,7 @@ jobs:
id: version id: version
- name: Save coverage information - name: Save coverage information
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
if: always() # run this step even if previous step failed if: always() # run this step even if previous step failed
with: with:
name: lcov-coverage-info-native-simulator-test-${{ steps.version.outputs.long }} name: lcov-coverage-info-native-simulator-test-${{ steps.version.outputs.long }}
@@ -94,7 +94,7 @@ jobs:
- name: Save test results - name: Save test results
if: always() # run this step even if previous step failed if: always() # run this step even if previous step failed
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: platformio-test-report-${{ steps.version.outputs.long }} name: platformio-test-report-${{ steps.version.outputs.long }}
overwrite: true overwrite: true
@@ -108,7 +108,7 @@ jobs:
sed -i -e "s#${PWD}#.#" coverage_tests.info # Make paths relative. sed -i -e "s#${PWD}#.#" coverage_tests.info # Make paths relative.
- name: Save coverage information - name: Save coverage information
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
if: always() # run this step even if previous step failed if: always() # run this step even if previous step failed
with: with:
name: lcov-coverage-info-native-platformio-tests-${{ steps.version.outputs.long }} name: lcov-coverage-info-native-platformio-tests-${{ steps.version.outputs.long }}
@@ -137,7 +137,7 @@ jobs:
id: version id: version
- name: Download test artifacts - name: Download test artifacts
uses: actions/download-artifact@v6 uses: actions/download-artifact@v7
with: with:
name: platformio-test-report-${{ steps.version.outputs.long }} name: platformio-test-report-${{ steps.version.outputs.long }}
merge-multiple: true merge-multiple: true
@@ -150,7 +150,7 @@ jobs:
reporter: java-junit reporter: java-junit
- name: Download coverage artifacts - name: Download coverage artifacts
uses: actions/download-artifact@v6 uses: actions/download-artifact@v7
with: with:
pattern: lcov-coverage-info-native-*-${{ steps.version.outputs.long }} pattern: lcov-coverage-info-native-*-${{ steps.version.outputs.long }}
path: code-coverage-report path: code-coverage-report
@@ -163,7 +163,7 @@ jobs:
genhtml --quiet --legend --prefix "${PWD}" code-coverage-report/coverage_src.info --output-directory code-coverage-report genhtml --quiet --legend --prefix "${PWD}" code-coverage-report/coverage_src.info --output-directory code-coverage-report
- name: Save Code Coverage Report - name: Save Code Coverage Report
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
with: with:
name: code-coverage-report-${{ steps.version.outputs.long }} name: code-coverage-report-${{ steps.version.outputs.long }}
path: code-coverage-report path: code-coverage-report

View File

@@ -31,7 +31,7 @@ jobs:
./bin/regen-protos.sh ./bin/regen-protos.sh
- name: Create pull request - name: Create pull request
uses: peter-evans/create-pull-request@v7 uses: peter-evans/create-pull-request@v8
with: with:
branch: create-pull-request/update-protobufs branch: create-pull-request/update-protobufs
labels: submodules labels: submodules

View File

@@ -9,24 +9,24 @@ plugins:
lint: lint:
enabled: enabled:
- checkov@3.2.495 - checkov@3.2.495
- renovate@42.30.4 - renovate@42.57.1
- prettier@3.7.4 - prettier@3.7.4
- trufflehog@3.91.2 - trufflehog@3.92.3
- yamllint@1.37.1 - yamllint@1.37.1
- bandit@1.9.2 - bandit@1.9.2
- trivy@0.67.2 - trivy@0.68.1
- taplo@0.10.0 - taplo@0.10.0
- ruff@0.14.7 - ruff@0.14.9
- isort@7.0.0 - isort@7.0.0
- markdownlint@0.46.0 - markdownlint@0.47.0
- oxipng@9.1.5 - oxipng@10.0.0
- svgo@4.0.0 - svgo@4.0.0
- actionlint@1.7.9 - actionlint@1.7.9
- flake8@7.3.0 - flake8@7.3.0
- hadolint@2.14.0 - hadolint@2.14.0
- shfmt@3.6.0 - shfmt@3.6.0
- shellcheck@0.11.0 - shellcheck@0.11.0
- black@25.11.0 - black@25.12.0
- git-diff-check - git-diff-check
- gitleaks@8.30.0 - gitleaks@8.30.0
- clang-format@16.0.3 - clang-format@16.0.3

View File

@@ -22,7 +22,7 @@ export APP_VERSION=$VERSION
basename=firmware-$1-$VERSION basename=firmware-$1-$VERSION
pio run --environment $1 # -v pio run --environment $1 -t mtjson # -v
cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf
@@ -32,20 +32,10 @@ cp $BUILDDIR/$basename.factory.bin $OUTDIR/$basename.factory.bin
echo "Copying ESP32 update bin file" echo "Copying ESP32 update bin file"
cp $BUILDDIR/$basename.bin $OUTDIR/$basename.bin cp $BUILDDIR/$basename.bin $OUTDIR/$basename.bin
echo "Building Filesystem for ESP32 targets" echo "Copying Filesystem for ESP32 targets"
# If you want to build the webui, uncomment the following lines
# pio run --environment $1 -t buildfs
# cp .pio/build/$1/littlefs.bin $OUTDIR/littlefswebui-$1-$VERSION.bin
# # Remove webserver files from the filesystem and rebuild
# ls -l data/static # Diagnostic list of files
# rm -rf data/static
pio run --environment $1 -t buildfs --disable-auto-clean
cp $BUILDDIR/littlefs-$1-$VERSION.bin $OUTDIR/littlefs-$1-$VERSION.bin cp $BUILDDIR/littlefs-$1-$VERSION.bin $OUTDIR/littlefs-$1-$VERSION.bin
cp bin/device-install.* $OUTDIR/ cp bin/device-install.* $OUTDIR/
cp bin/device-update.* $OUTDIR/ cp bin/device-update.* $OUTDIR/
# Generate the manifest file echo "Copying manifest"
echo "Generating Meshtastic manifest"
TIMEFORMAT="Generated manifest in %E seconds"
time pio run --environment $1 -t mtjson --silent --disable-auto-clean
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json

View File

@@ -22,7 +22,7 @@ export APP_VERSION=$VERSION
basename=firmware-$1-$VERSION basename=firmware-$1-$VERSION
pio run --environment $1 # -v pio run --environment $1 -t mtjson # -v
cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf
@@ -47,8 +47,5 @@ if (echo $1 | grep -q "rak4631"); then
cp $SRCHEX $OUTDIR/ cp $SRCHEX $OUTDIR/
fi fi
# Generate the manifest file echo "Copying manifest"
echo "Generating Meshtastic manifest"
TIMEFORMAT="Generated manifest in %E seconds"
time pio run --environment $1 -t mtjson --silent --disable-auto-clean
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json

View File

@@ -22,15 +22,12 @@ export APP_VERSION=$VERSION
basename=firmware-$1-$VERSION basename=firmware-$1-$VERSION
pio run --environment $1 # -v pio run --environment $1 -t mtjson # -v
cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf
echo "Copying uf2 file" echo "Copying uf2 file"
cp $BUILDDIR/$basename.uf2 $OUTDIR/$basename.uf2 cp $BUILDDIR/$basename.uf2 $OUTDIR/$basename.uf2
# Generate the manifest file echo "Copying manifest"
echo "Generating Meshtastic manifest"
TIMEFORMAT="Generated manifest in %E seconds"
time pio run --environment $1 -t mtjson --silent --disable-auto-clean
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json

View File

@@ -22,15 +22,12 @@ export APP_VERSION=$VERSION
basename=firmware-$1-$VERSION basename=firmware-$1-$VERSION
pio run --environment $1 # -v pio run --environment $1 -t mtjson # -v
cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf cp $BUILDDIR/$basename.elf $OUTDIR/$basename.elf
echo "Copying STM32 bin file" echo "Copying STM32 bin file"
cp $BUILDDIR/$basename.bin $OUTDIR/$basename.bin cp $BUILDDIR/$basename.bin $OUTDIR/$basename.bin
# Generate the manifest file echo "Copying manifest"
echo "Generating Meshtastic manifest"
TIMEFORMAT="Generated manifest in %E seconds"
time pio run --environment $1 -t mtjson --silent --disable-auto-clean
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json

View File

@@ -184,6 +184,8 @@ Input:
Logging: Logging:
LogLevel: info # debug, info, warn, error LogLevel: info # debug, info, warn, error
# TraceFile: /var/log/meshtasticd.json # TraceFile: /var/log/meshtasticd.json
# JSONFile: /packets.json # File location for JSON output of decoded packets
# JSONFilter: position # filter for packets to save to JSON file
# AsciiLogs: true # default if not specified is !isatty() on stdout # AsciiLogs: true # default if not specified is !isatty() on stdout
Webserver: Webserver:

View File

@@ -159,20 +159,22 @@ def load_boot_logo(source, target, env):
# Load the boot logo on TFT builds # Load the boot logo on TFT builds
if ("HAS_TFT", 1) in env.get("CPPDEFINES", []): if ("HAS_TFT", 1) in env.get("CPPDEFINES", []):
env.AddPreAction('$BUILD_DIR/littlefs.bin', load_boot_logo) env.AddPreAction(f"$BUILD_DIR/{lfsbin}", load_boot_logo)
# Rename (mv) littlefs.bin to include the PROGNAME mtjson_deps = ["buildprog"]
# This ensures the littlefs.bin is named consistently with the firmware if platform.name == "espressif32":
env.AddPostAction('$BUILD_DIR/littlefs.bin', env.VerboseAction( # Build littlefs image as part of mtjson target
f'mv $BUILD_DIR/littlefs.bin $BUILD_DIR/{lfsbin}', # Equivalent to `pio run -t buildfs`
f'Renaming littlefs.bin to {lfsbin}' target_lfs = env.DataToBin(
)) join("$BUILD_DIR", "${ESP32_FS_IMAGE_NAME}"), "$PROJECT_DATA_DIR"
)
mtjson_deps.append(target_lfs)
env.AddCustomTarget( env.AddCustomTarget(
name="mtjson", name="mtjson",
dependencies=None, dependencies=mtjson_deps,
actions=[manifest_gather], actions=[manifest_gather],
title="Meshtastic Manifest", title="Meshtastic Manifest",
description="Generating Meshtastic manifest JSON + Checksums", description="Generating Meshtastic manifest JSON + Checksums",
always_build=True, always_build=False,
) )

View File

@@ -11,6 +11,9 @@ else:
prefsLoc = env["PROJECT_DIR"] + "/version.properties" prefsLoc = env["PROJECT_DIR"] + "/version.properties"
verObj = readProps(prefsLoc) verObj = readProps(prefsLoc)
env.Replace(PROGNAME=f"firmware-{env.get('PIOENV')}-{verObj['long']}") env.Replace(PROGNAME=f"firmware-{env.get('PIOENV')}-{verObj['long']}")
env.Replace(ESP32_FS_IMAGE_NAME=f"littlefs-{env.get('PIOENV')}-{verObj['long']}")
# Print the new program name for verification # Print the new program name for verification
print(f"PROGNAME: {env.get('PROGNAME')}") print(f"PROGNAME: {env.get('PROGNAME')}")
if platform.name == "espressif32":
print(f"ESP32_FS_IMAGE_NAME: {env.get('ESP32_FS_IMAGE_NAME')}")

View File

@@ -10,6 +10,12 @@ Import("env")
platform = env.PioPlatform() platform = env.PioPlatform()
sys.path.append(join(platform.get_package_dir("tool-esptoolpy"))) sys.path.append(join(platform.get_package_dir("tool-esptoolpy")))
# IntelHex workaround, remove after fixed upstream
# https://github.com/platformio/platform-espressif32/issues/1632
try:
import intelhex
except ImportError:
env.Execute("$PYTHONEXE -m pip install intelhex")
import esptool import esptool

View File

@@ -123,7 +123,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/4fb5f24787caa841b58dbf623a52c4c5861d6722.zip https://github.com/meshtastic/device-ui/archive/862ed040c4ab44f0dfbbe492691f144886102588.zip
; Common libs for environmental measurements in telemetry module ; Common libs for environmental measurements in telemetry module
[environmental_base] [environmental_base]

View File

@@ -31,6 +31,9 @@ const char *DisplayFormatters::getModemPresetDisplayName(meshtastic_Config_LoRaC
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST: case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
return useShortName ? "LongF" : "LongFast"; return useShortName ? "LongF" : "LongFast";
break; break;
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO:
return useShortName ? "LongT" : "LongTurbo";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE: case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
return useShortName ? "LongM" : "LongMod"; return useShortName ? "LongM" : "LongMod";
break; break;

View File

@@ -532,8 +532,10 @@ void drawSystemScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x
const int labelX = x; const int labelX = x;
int barsOffset = (isHighResolution) ? 24 : 0; int barsOffset = (isHighResolution) ? 24 : 0;
#ifdef USE_EINK #ifdef USE_EINK
#ifndef T_DECK_PRO
barsOffset -= 12; barsOffset -= 12;
#endif #endif
#endif
#if defined(M5STACK_UNITC6L) #if defined(M5STACK_UNITC6L)
const int barX = x + 45 + barsOffset; const int barX = x + 45 + barsOffset;
#else #else
@@ -574,7 +576,7 @@ void drawSystemScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x
#endif #endif
// Value string // Value string
display->setTextAlignment(TEXT_ALIGN_RIGHT); display->setTextAlignment(TEXT_ALIGN_RIGHT);
display->drawString(SCREEN_WIDTH - 2, getTextPositions(display)[line], combinedStr); display->drawString(SCREEN_WIDTH, getTextPositions(display)[line], combinedStr);
}; };
// === Memory values === // === Memory values ===

View File

@@ -20,12 +20,41 @@
#include "modules/KeyVerificationModule.h" #include "modules/KeyVerificationModule.h"
#include "modules/TraceRouteModule.h" #include "modules/TraceRouteModule.h"
#include <algorithm>
#include <array>
#include <functional> #include <functional>
#include <utility>
extern uint16_t TFT_MESH; extern uint16_t TFT_MESH;
namespace graphics namespace graphics
{ {
namespace
{
// Caller must ensure the provided options array outlives the banner callback.
template <typename T, size_t N, typename Callback>
BannerOverlayOptions createStaticBannerOptions(const char *message, const MenuOption<T> (&options)[N],
std::array<const char *, N> &labels, Callback &&onSelection)
{
for (size_t i = 0; i < N; ++i) {
labels[i] = options[i].label;
}
const MenuOption<T> *optionsPtr = options;
auto callback = std::function<void(const MenuOption<T> &, int)>(std::forward<Callback>(onSelection));
BannerOverlayOptions bannerOptions;
bannerOptions.message = message;
bannerOptions.optionsArrayPtr = labels.data();
bannerOptions.optionsCount = static_cast<uint8_t>(N);
bannerOptions.bannerCallback = [optionsPtr, callback](int selected) -> void { callback(optionsPtr[selected], selected); };
return bannerOptions;
}
} // namespace
menuHandler::screenMenus menuHandler::menuQueue = menu_none; menuHandler::screenMenus menuHandler::menuQueue = menu_none;
bool test_enabled = false; bool test_enabled = false;
uint8_t test_count = 0; uint8_t test_count = 0;
@@ -197,48 +226,38 @@ void menuHandler::DeviceRolePicker()
void menuHandler::RadioPresetPicker() void menuHandler::RadioPresetPicker()
{ {
static const char *optionsArray[] = {"Back", "LongSlow", "LongModerate", "LongFast", "MediumSlow", static const RadioPresetOption presetOptions[] = {
"MediumFast", "ShortSlow", "ShortFast", "ShortTurbo"}; {"Back", OptionsAction::Back},
enum optionsNumbers { {"LongTurbo", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO},
Back = 0, {"LongModerate", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE},
radiopreset_LongSlow = 1, {"LongFast", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST},
radiopreset_LongModerate = 2, {"MediumSlow", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW},
radiopreset_LongFast = 3, {"MediumFast", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST},
radiopreset_MediumSlow = 4, {"ShortSlow", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW},
radiopreset_MediumFast = 5, {"ShortFast", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST},
radiopreset_ShortSlow = 6, {"ShortTurbo", OptionsAction::Select, meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO},
radiopreset_ShortFast = 7,
radiopreset_ShortTurbo = 8
}; };
BannerOverlayOptions bannerOptions;
bannerOptions.message = "Radio Preset"; constexpr size_t presetCount = sizeof(presetOptions) / sizeof(presetOptions[0]);
bannerOptions.optionsArrayPtr = optionsArray; static std::array<const char *, presetCount> presetLabels{};
bannerOptions.optionsCount = 9;
bannerOptions.bannerCallback = [](int selected) -> void { auto bannerOptions =
if (selected == Back) { createStaticBannerOptions("Radio Preset", presetOptions, presetLabels, [](const RadioPresetOption &option, int) -> void {
if (option.action == OptionsAction::Back) {
menuHandler::menuQueue = menuHandler::lora_Menu; menuHandler::menuQueue = menuHandler::lora_Menu;
screen->runNow(); screen->runNow();
return; return;
} else if (selected == radiopreset_LongSlow) {
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW;
} else if (selected == radiopreset_LongModerate) {
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE;
} else if (selected == radiopreset_LongFast) {
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST;
} else if (selected == radiopreset_MediumSlow) {
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW;
} else if (selected == radiopreset_MediumFast) {
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST;
} else if (selected == radiopreset_ShortSlow) {
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW;
} else if (selected == radiopreset_ShortFast) {
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST;
} else if (selected == radiopreset_ShortTurbo) {
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO;
} }
if (!option.hasValue) {
return;
}
config.lora.modem_preset = option.value;
service->reloadConfig(SEGMENT_CONFIG); service->reloadConfig(SEGMENT_CONFIG);
rebootAtMsec = (millis() + DEFAULT_REBOOT_SECONDS * 1000); rebootAtMsec = (millis() + DEFAULT_REBOOT_SECONDS * 1000);
}; });
screen->showOverlayBanner(bannerOptions); screen->showOverlayBanner(bannerOptions);
} }

View File

@@ -99,5 +99,24 @@ class menuHandler
static void BluetoothToggleMenu(); static void BluetoothToggleMenu();
}; };
/* Generic Menu Options designations */
enum class OptionsAction { Back, Select };
template <typename T> struct MenuOption {
const char *label;
OptionsAction action;
bool hasValue;
T value;
MenuOption(const char *labelIn, OptionsAction actionIn, T valueIn)
: label(labelIn), action(actionIn), hasValue(true), value(valueIn)
{
}
MenuOption(const char *labelIn, OptionsAction actionIn) : label(labelIn), action(actionIn), hasValue(false), value() {}
};
using RadioPresetOption = MenuOption<meshtastic_Config_LoRaConfig_ModemPreset>;
} // namespace graphics } // namespace graphics
#endif #endif

View File

@@ -53,6 +53,7 @@ typedef struct _InputEvent {
class InputPollable class InputPollable
{ {
public: public:
virtual ~InputPollable() = default;
virtual void pollOnce() = 0; virtual void pollOnce() = 0;
}; };

View File

@@ -3,6 +3,9 @@
#include "RotaryEncoderImpl.h" #include "RotaryEncoderImpl.h"
#include "InputBroker.h" #include "InputBroker.h"
#include "RotaryEncoder.h" #include "RotaryEncoder.h"
#ifdef ARCH_ESP32
#include "sleep.h"
#endif
#define ORIGIN_NAME "RotaryEncoder" #define ORIGIN_NAME "RotaryEncoder"
@@ -11,6 +14,20 @@ RotaryEncoderImpl *rotaryEncoderImpl;
RotaryEncoderImpl::RotaryEncoderImpl() RotaryEncoderImpl::RotaryEncoderImpl()
{ {
rotary = nullptr; rotary = nullptr;
#ifdef ARCH_ESP32
isFirstInit = true;
#endif
}
RotaryEncoderImpl::~RotaryEncoderImpl()
{
LOG_DEBUG("RotaryEncoderImpl destructor");
detachRotaryEncoderInterrupts();
if (rotary != nullptr) {
delete rotary;
rotary = nullptr;
}
} }
bool RotaryEncoderImpl::init() bool RotaryEncoderImpl::init()
@@ -25,15 +42,22 @@ bool RotaryEncoderImpl::init()
eventCcw = static_cast<input_broker_event>(moduleConfig.canned_message.inputbroker_event_ccw); eventCcw = static_cast<input_broker_event>(moduleConfig.canned_message.inputbroker_event_ccw);
eventPressed = static_cast<input_broker_event>(moduleConfig.canned_message.inputbroker_event_press); eventPressed = static_cast<input_broker_event>(moduleConfig.canned_message.inputbroker_event_press);
if (rotary == nullptr) {
rotary = new RotaryEncoder(moduleConfig.canned_message.inputbroker_pin_a, moduleConfig.canned_message.inputbroker_pin_b, rotary = new RotaryEncoder(moduleConfig.canned_message.inputbroker_pin_a, moduleConfig.canned_message.inputbroker_pin_b,
moduleConfig.canned_message.inputbroker_pin_press); moduleConfig.canned_message.inputbroker_pin_press);
rotary->resetButton(); }
interruptInstance = this; attachRotaryEncoderInterrupts();
auto interruptHandler = []() { inputBroker->requestPollSoon(interruptInstance); };
attachInterrupt(moduleConfig.canned_message.inputbroker_pin_a, interruptHandler, CHANGE); #ifdef ARCH_ESP32
attachInterrupt(moduleConfig.canned_message.inputbroker_pin_b, interruptHandler, CHANGE); // Register callbacks for before and after lightsleep
attachInterrupt(moduleConfig.canned_message.inputbroker_pin_press, interruptHandler, CHANGE); // Used to detach and reattach interrupts
if (isFirstInit) {
lsObserver.observe(&notifyLightSleep);
lsEndObserver.observe(&notifyLightSleepEnd);
isFirstInit = false;
}
#endif
LOG_INFO("RotaryEncoder initialized pins(%d, %d, %d), events(%d, %d, %d)", moduleConfig.canned_message.inputbroker_pin_a, LOG_INFO("RotaryEncoder initialized pins(%d, %d, %d), events(%d, %d, %d)", moduleConfig.canned_message.inputbroker_pin_a,
moduleConfig.canned_message.inputbroker_pin_b, moduleConfig.canned_message.inputbroker_pin_press, eventCw, eventCcw, moduleConfig.canned_message.inputbroker_pin_b, moduleConfig.canned_message.inputbroker_pin_press, eventCw, eventCcw,
@@ -71,6 +95,50 @@ void RotaryEncoderImpl::pollOnce()
} }
} }
void RotaryEncoderImpl::detachRotaryEncoderInterrupts()
{
LOG_DEBUG("RotaryEncoderImpl detach button interrupts");
if (interruptInstance == this) {
detachInterrupt(moduleConfig.canned_message.inputbroker_pin_a);
detachInterrupt(moduleConfig.canned_message.inputbroker_pin_b);
detachInterrupt(moduleConfig.canned_message.inputbroker_pin_press);
interruptInstance = nullptr;
} else {
LOG_WARN("RotaryEncoderImpl: interrupts already detached");
}
}
void RotaryEncoderImpl::attachRotaryEncoderInterrupts()
{
LOG_DEBUG("RotaryEncoderImpl attach button interrupts");
if (rotary != nullptr && interruptInstance == nullptr) {
rotary->resetButton();
interruptInstance = this;
auto interruptHandler = []() { inputBroker->requestPollSoon(interruptInstance); };
attachInterrupt(moduleConfig.canned_message.inputbroker_pin_a, interruptHandler, CHANGE);
attachInterrupt(moduleConfig.canned_message.inputbroker_pin_b, interruptHandler, CHANGE);
attachInterrupt(moduleConfig.canned_message.inputbroker_pin_press, interruptHandler, CHANGE);
} else {
LOG_WARN("RotaryEncoderImpl: interrupts already attached");
}
}
#ifdef ARCH_ESP32
int RotaryEncoderImpl::beforeLightSleep(void *unused)
{
detachRotaryEncoderInterrupts();
return 0; // Indicates success;
}
int RotaryEncoderImpl::afterLightSleep(esp_sleep_wakeup_cause_t cause)
{
attachRotaryEncoderInterrupts();
return 0; // Indicates success;
}
#endif
RotaryEncoderImpl *RotaryEncoderImpl::interruptInstance; RotaryEncoderImpl *RotaryEncoderImpl::interruptInstance;
#endif #endif

View File

@@ -8,12 +8,18 @@
class RotaryEncoder; class RotaryEncoder;
class RotaryEncoderImpl : public InputPollable class RotaryEncoderImpl final : public InputPollable
{ {
public: public:
RotaryEncoderImpl(); RotaryEncoderImpl();
bool init(void); ~RotaryEncoderImpl() override;
bool init();
virtual void pollOnce() override; virtual void pollOnce() override;
// Disconnect and reconnect interrupts for light sleep
#ifdef ARCH_ESP32
int beforeLightSleep(void *unused);
int afterLightSleep(esp_sleep_wakeup_cause_t cause);
#endif
protected: protected:
static RotaryEncoderImpl *interruptInstance; static RotaryEncoderImpl *interruptInstance;
@@ -23,6 +29,21 @@ class RotaryEncoderImpl : public InputPollable
input_broker_event eventPressed = INPUT_BROKER_NONE; input_broker_event eventPressed = INPUT_BROKER_NONE;
RotaryEncoder *rotary; RotaryEncoder *rotary;
private:
#ifdef ARCH_ESP32
bool isFirstInit;
#endif
void detachRotaryEncoderInterrupts();
void attachRotaryEncoderInterrupts();
#ifdef ARCH_ESP32
// Get notified when lightsleep begins and ends
CallbackObserver<RotaryEncoderImpl, void *> lsObserver =
CallbackObserver<RotaryEncoderImpl, void *>(this, &RotaryEncoderImpl::beforeLightSleep);
CallbackObserver<RotaryEncoderImpl, esp_sleep_wakeup_cause_t> lsEndObserver =
CallbackObserver<RotaryEncoderImpl, esp_sleep_wakeup_cause_t>(this, &RotaryEncoderImpl::afterLightSleep);
#endif
}; };
extern RotaryEncoderImpl *rotaryEncoderImpl; extern RotaryEncoderImpl *rotaryEncoderImpl;

View File

@@ -428,10 +428,17 @@ void setup()
#endif #endif
#if ARCH_PORTDUINO #if ARCH_PORTDUINO
RTCQuality ourQuality = RTCQualityDevice;
std::string timeCommandResult = exec("timedatectl status | grep synchronized | grep yes -c");
if (timeCommandResult[0] == '1') {
ourQuality = RTCQualityNTP;
}
struct timeval tv; struct timeval tv;
tv.tv_sec = time(NULL); tv.tv_sec = time(NULL);
tv.tv_usec = 0; tv.tv_usec = 0;
perhapsSetRTC(RTCQualityDevice, &tv); perhapsSetRTC(ourQuality, &tv);
#endif #endif
powerMonInit(); powerMonInit();

View File

@@ -805,11 +805,15 @@ void NodeDB::installDefaultModuleConfig()
moduleConfig.external_notification.output_ms = 500; moduleConfig.external_notification.output_ms = 500;
moduleConfig.external_notification.nag_timeout = 2; moduleConfig.external_notification.nag_timeout = 2;
#endif #endif
#if defined(RAK4630) || defined(RAK11310) || defined(RAK3312) #if defined(RAK4630) || defined(RAK11310) || defined(RAK3312) || defined(MUZI_BASE)
// Default to RAK led pin 2 (blue) // Default to RAK led pin 2 (blue)
moduleConfig.external_notification.enabled = true; moduleConfig.external_notification.enabled = true;
moduleConfig.external_notification.output = PIN_LED2; moduleConfig.external_notification.output = PIN_LED2;
#if defined(MUZI_BASE)
moduleConfig.external_notification.active = false;
#else
moduleConfig.external_notification.active = true; moduleConfig.external_notification.active = true;
#endif
moduleConfig.external_notification.alert_message = true; moduleConfig.external_notification.alert_message = true;
moduleConfig.external_notification.output_ms = 1000; moduleConfig.external_notification.output_ms = 1000;
moduleConfig.external_notification.nag_timeout = default_ringtone_nag_secs; moduleConfig.external_notification.nag_timeout = default_ringtone_nag_secs;

View File

@@ -503,6 +503,11 @@ void RadioInterface::applyModemConfig()
cr = 5; cr = 5;
sf = 10; sf = 10;
break; break;
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO:
bw = (myRegion->wideLora) ? 1625.0 : 500;
cr = 8;
sf = 11;
break;
default: // Config_LoRaConfig_ModemPreset_LONG_FAST is default. Gracefully use this is preset is something illegal. default: // Config_LoRaConfig_ModemPreset_LONG_FAST is default. Gracefully use this is preset is something illegal.
bw = (myRegion->wideLora) ? 812.5 : 250; bw = (myRegion->wideLora) ? 812.5 : 250;
cr = 5; cr = 5;
@@ -539,13 +544,26 @@ void RadioInterface::applyModemConfig()
} }
if ((myRegion->freqEnd - myRegion->freqStart) < bw / 1000) { if ((myRegion->freqEnd - myRegion->freqStart) < bw / 1000) {
static const char *err_string = "Regional frequency range is smaller than bandwidth. Fall back to default preset"; const float regionSpanKHz = (myRegion->freqEnd - myRegion->freqStart) * 1000.0f;
LOG_ERROR(err_string); const float requestedBwKHz = bw;
const bool isWideRequest = requestedBwKHz >= 499.5f; // treat as 500 kHz preset
const char *presetName =
DisplayFormatters::getModemPresetDisplayName(loraConfig.modem_preset, false, loraConfig.use_preset);
char err_string[160];
if (isWideRequest) {
snprintf(err_string, sizeof(err_string), "%s region too narrow for 500kHz preset (%s). Falling back to LongFast.",
myRegion->name, presetName);
} else {
snprintf(err_string, sizeof(err_string), "%s region span %.0fkHz < requested %.0fkHz. Falling back to LongFast.",
myRegion->name, regionSpanKHz, requestedBwKHz);
}
LOG_ERROR("%s", err_string);
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING); RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);
meshtastic_ClientNotification *cn = clientNotificationPool.allocZeroed(); meshtastic_ClientNotification *cn = clientNotificationPool.allocZeroed();
cn->level = meshtastic_LogRecord_Level_ERROR; cn->level = meshtastic_LogRecord_Level_ERROR;
sprintf(cn->message, err_string); snprintf(cn->message, sizeof(cn->message), "%s", err_string);
service->sendClientNotification(cn); service->sendClientNotification(cn);
// Set to default modem preset // Set to default modem preset

View File

@@ -150,7 +150,9 @@ void ReliableRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
PacketId nakId = (c && c->error_reason != meshtastic_Routing_Error_NONE) ? p->decoded.request_id : 0; PacketId nakId = (c && c->error_reason != meshtastic_Routing_Error_NONE) ? p->decoded.request_id : 0;
// We intentionally don't check wasSeenRecently, because it is harmless to delete non existent retransmission records // We intentionally don't check wasSeenRecently, because it is harmless to delete non existent retransmission records
if (ackId || nakId) { if ((ackId || nakId) &&
// Implicit ACKs from MQTT should not stop retransmissions
!(isFromUs(p) && p->transport_mechanism == meshtastic_MeshPacket_TransportMechanism_TRANSPORT_MQTT)) {
LOG_DEBUG("Received a %s for 0x%x, stopping retransmissions", ackId ? "ACK" : "NAK", ackId); LOG_DEBUG("Received a %s for 0x%x, stopping retransmissions", ackId ? "ACK" : "NAK", ackId);
if (ackId) { if (ackId) {
stopRetransmission(p->to, ackId); stopRetransmission(p->to, ackId);

View File

@@ -526,6 +526,10 @@ DecodeState perhapsDecode(meshtastic_MeshPacket *p)
#elif ARCH_PORTDUINO #elif ARCH_PORTDUINO
if (portduino_config.traceFilename != "" || portduino_config.logoutputlevel == level_trace) { if (portduino_config.traceFilename != "" || portduino_config.logoutputlevel == level_trace) {
LOG_TRACE("%s", MeshPacketSerializer::JsonSerialize(p, false).c_str()); LOG_TRACE("%s", MeshPacketSerializer::JsonSerialize(p, false).c_str());
} else if (portduino_config.JSONFilename != "") {
if (portduino_config.JSONFilter == (_meshtastic_PortNum)0 || portduino_config.JSONFilter == p->decoded.portnum) {
JSONFile << MeshPacketSerializer::JsonSerialize(p, false) << std::endl;
}
} }
#endif #endif
return DecodeState::DECODE_SUCCESS; return DecodeState::DECODE_SUCCESS;

View File

@@ -293,7 +293,8 @@ typedef enum _meshtastic_Config_LoRaConfig_RegionCode {
typedef enum _meshtastic_Config_LoRaConfig_ModemPreset { typedef enum _meshtastic_Config_LoRaConfig_ModemPreset {
/* Long Range - Fast */ /* Long Range - Fast */
meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST = 0, meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST = 0,
/* Long Range - Slow */ /* Long Range - Slow
Deprecated in 2.7: Unpopular slow preset. */
meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW = 1, meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW = 1,
/* Very Long Range - Slow /* Very Long Range - Slow
Deprecated in 2.5: Works only with txco and is unusably slow */ Deprecated in 2.5: Works only with txco and is unusably slow */
@@ -311,7 +312,10 @@ typedef enum _meshtastic_Config_LoRaConfig_ModemPreset {
/* Short Range - Turbo /* Short Range - Turbo
This is the fastest preset and the only one with 500kHz bandwidth. This is the fastest preset and the only one with 500kHz bandwidth.
It is not legal to use in all regions due to this wider bandwidth. */ It is not legal to use in all regions due to this wider bandwidth. */
meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO = 8 meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO = 8,
/* Long Range - Turbo
This preset performs similarly to LongFast, but with 500Khz bandwidth. */
meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO = 9
} meshtastic_Config_LoRaConfig_ModemPreset; } meshtastic_Config_LoRaConfig_ModemPreset;
typedef enum _meshtastic_Config_BluetoothConfig_PairingMode { typedef enum _meshtastic_Config_BluetoothConfig_PairingMode {
@@ -689,8 +693,8 @@ extern "C" {
#define _meshtastic_Config_LoRaConfig_RegionCode_ARRAYSIZE ((meshtastic_Config_LoRaConfig_RegionCode)(meshtastic_Config_LoRaConfig_RegionCode_BR_902+1)) #define _meshtastic_Config_LoRaConfig_RegionCode_ARRAYSIZE ((meshtastic_Config_LoRaConfig_RegionCode)(meshtastic_Config_LoRaConfig_RegionCode_BR_902+1))
#define _meshtastic_Config_LoRaConfig_ModemPreset_MIN meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST #define _meshtastic_Config_LoRaConfig_ModemPreset_MIN meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST
#define _meshtastic_Config_LoRaConfig_ModemPreset_MAX meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO #define _meshtastic_Config_LoRaConfig_ModemPreset_MAX meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO
#define _meshtastic_Config_LoRaConfig_ModemPreset_ARRAYSIZE ((meshtastic_Config_LoRaConfig_ModemPreset)(meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO+1)) #define _meshtastic_Config_LoRaConfig_ModemPreset_ARRAYSIZE ((meshtastic_Config_LoRaConfig_ModemPreset)(meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO+1))
#define _meshtastic_Config_BluetoothConfig_PairingMode_MIN meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN #define _meshtastic_Config_BluetoothConfig_PairingMode_MIN meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN
#define _meshtastic_Config_BluetoothConfig_PairingMode_MAX meshtastic_Config_BluetoothConfig_PairingMode_NO_PIN #define _meshtastic_Config_BluetoothConfig_PairingMode_MAX meshtastic_Config_BluetoothConfig_PairingMode_NO_PIN

View File

@@ -417,6 +417,9 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
} }
case meshtastic_AdminMessage_enter_dfu_mode_request_tag: { case meshtastic_AdminMessage_enter_dfu_mode_request_tag: {
LOG_INFO("Client requesting to enter DFU mode"); LOG_INFO("Client requesting to enter DFU mode");
#if HAS_SCREEN
IF_SCREEN(screen->showSimpleBanner("Device is rebooting\ninto DFU mode.", 0));
#endif
#if defined(ARCH_NRF52) || defined(ARCH_RP2040) #if defined(ARCH_NRF52) || defined(ARCH_RP2040)
enterDfuMode(); enterDfuMode();
#endif #endif

View File

@@ -217,7 +217,7 @@ void setupModules()
} }
#endif // HAS_BUTTON #endif // HAS_BUTTON
#if ARCH_PORTDUINO #if ARCH_PORTDUINO
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) { if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR && portduino_config.i2cdev != "") {
seesawRotary = new SeesawRotary("SeesawRotary"); seesawRotary = new SeesawRotary("SeesawRotary");
if (!seesawRotary->init()) { if (!seesawRotary->init()) {
delete seesawRotary; delete seesawRotary;

View File

@@ -45,8 +45,12 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
{ {
auto p = *pptr; auto p = *pptr;
// If inbound message is a replay (or spoof!) of our own messages, we shouldn't process const auto transport = mp.transport_mechanism;
// (why use second-hand sources for our own data?) if (isFromUs(&mp) && !IS_ONE_OF(transport, meshtastic_MeshPacket_TransportMechanism_TRANSPORT_INTERNAL,
meshtastic_MeshPacket_TransportMechanism_TRANSPORT_API)) {
LOG_WARN("Ignoring packet supposedly from us over external transport");
return true;
}
// FIXME this can in fact happen with packets sent from EUD (src=RX_SRC_USER) // FIXME this can in fact happen with packets sent from EUD (src=RX_SRC_USER)
// to set fixed location, EUD-GPS location or just the time (see also issue #900) // to set fixed location, EUD-GPS location or just the time (see also issue #900)
@@ -472,19 +476,53 @@ void PositionModule::sendLostAndFoundText()
delete[] message; delete[] message;
} }
// Helper: return imprecise (truncated + centered) lat/lon as int32 using current precision
static inline void computeImpreciseLatLon(int32_t inLat, int32_t inLon, uint8_t precisionBits, int32_t &outLat, int32_t &outLon)
{
if (precisionBits > 0 && precisionBits < 32) {
// Build mask for top 'precisionBits' bits of a 32-bit unsigned field
const uint32_t mask = (precisionBits == 32) ? UINT32_MAX : (UINT32_MAX << (32 - precisionBits));
// Note: latitude_i/longitude_i are stored as signed 32-bit in meshtastic code but
// the bitmask logic used previously operated as unsigned—preserve that behavior by
// casting to uint32_t for masking, then back to int32_t.
uint32_t lat_u = static_cast<uint32_t>(inLat) & mask;
uint32_t lon_u = static_cast<uint32_t>(inLon) & mask;
// Add the "center of cell" offset used elsewhere:
// The code previously added (1 << (31 - precision)) to produce the middle of the possible location.
uint32_t center_offset = (1u << (31 - precisionBits));
lat_u += center_offset;
lon_u += center_offset;
outLat = static_cast<int32_t>(lat_u);
outLon = static_cast<int32_t>(lon_u);
} else {
// full precision: return input unchanged
outLat = inLat;
outLon = inLon;
}
}
struct SmartPosition PositionModule::getDistanceTraveledSinceLastSend(meshtastic_PositionLite currentPosition) struct SmartPosition PositionModule::getDistanceTraveledSinceLastSend(meshtastic_PositionLite currentPosition)
{ {
// The minimum distance to travel before we are able to send a new position packet.
const uint32_t distanceTravelThreshold = const uint32_t distanceTravelThreshold =
Default::getConfiguredOrDefault(config.position.broadcast_smart_minimum_distance, 100); Default::getConfiguredOrDefault(config.position.broadcast_smart_minimum_distance, 100);
// Determine the distance in meters between two points on the globe int32_t lastLatImprecise, lastLonImprecise;
float distanceTraveledSinceLastSend = GeoCoord::latLongToMeter( int32_t currentLatImprecise, currentLonImprecise;
lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, currentPosition.latitude_i * 1e-7, currentPosition.longitude_i * 1e-7);
return SmartPosition{.distanceTraveled = abs(distanceTraveledSinceLastSend), computeImpreciseLatLon(lastGpsLatitude, lastGpsLongitude, precision, lastLatImprecise, lastLonImprecise);
computeImpreciseLatLon(currentPosition.latitude_i, currentPosition.longitude_i, precision, currentLatImprecise,
currentLonImprecise);
float distMeters = GeoCoord::latLongToMeter(lastLatImprecise * 1e-7, lastLonImprecise * 1e-7, currentLatImprecise * 1e-7,
currentLonImprecise * 1e-7);
float distanceTraveled = fabsf(distMeters);
return SmartPosition{.distanceTraveled = distanceTraveled,
.distanceThreshold = distanceTravelThreshold, .distanceThreshold = distanceTravelThreshold,
.hasTraveledOverThreshold = abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold}; .hasTraveledOverThreshold = distanceTraveled >= distanceTravelThreshold};
} }
void PositionModule::handleNewPosition() void PositionModule::handleNewPosition()

View File

@@ -75,6 +75,12 @@ uint8_t RoutingModule::getHopLimitForResponse(uint8_t hopStart, uint8_t hopLimit
return Default::getConfiguredOrDefaultHopLimit(config.lora.hop_limit); // Use the default hop limit return Default::getConfiguredOrDefaultHopLimit(config.lora.hop_limit); // Use the default hop limit
} }
meshtastic_MeshPacket *RoutingModule::allocAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex,
uint8_t hopLimit)
{
return MeshModule::allocAckNak(err, to, idFrom, chIndex, hopLimit);
}
RoutingModule::RoutingModule() : ProtobufModule("routing", meshtastic_PortNum_ROUTING_APP, &meshtastic_Routing_msg) RoutingModule::RoutingModule() : ProtobufModule("routing", meshtastic_PortNum_ROUTING_APP, &meshtastic_Routing_msg)
{ {
isPromiscuous = true; isPromiscuous = true;

View File

@@ -16,6 +16,9 @@ class RoutingModule : public ProtobufModule<meshtastic_Routing>
virtual void sendAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex, uint8_t hopLimit = 0, virtual void sendAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex, uint8_t hopLimit = 0,
bool ackWantsAck = false); bool ackWantsAck = false);
meshtastic_MeshPacket *allocAckNak(meshtastic_Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex,
uint8_t hopLimit = 0);
// Given the hopStart and hopLimit upon reception of a request, return the hop limit to use for the response // Given the hopStart and hopLimit upon reception of a request, return the hop limit to use for the response
uint8_t getHopLimitForResponse(uint8_t hopStart, uint8_t hopLimit); uint8_t getHopLimitForResponse(uint8_t hopStart, uint8_t hopLimit);

View File

@@ -87,10 +87,13 @@ inline void onReceiveProto(char *topic, byte *payload, size_t length)
// Generate an implicit ACK towards ourselves (handled and processed only locally!) for this message. // Generate an implicit ACK towards ourselves (handled and processed only locally!) for this message.
// We do this because packets are not rebroadcasted back into MQTT anymore and we assume that at least one node // We do this because packets are not rebroadcasted back into MQTT anymore and we assume that at least one node
// receives it when we get our own packet back. Then we'll stop our retransmissions. // receives it when we get our own packet back. Then we'll stop our retransmissions.
if (isFromUs(e.packet)) if (isFromUs(e.packet)) {
routingModule->sendAckNak(meshtastic_Routing_Error_NONE, getFrom(e.packet), e.packet->id, ch.index); auto pAck = routingModule->allocAckNak(meshtastic_Routing_Error_NONE, getFrom(e.packet), e.packet->id, ch.index);
else pAck->transport_mechanism = meshtastic_MeshPacket_TransportMechanism_TRANSPORT_MQTT;
router->sendLocal(pAck);
} else {
LOG_INFO("Ignore downlink message we originally sent"); LOG_INFO("Ignore downlink message we originally sent");
}
return; return;
} }
if (isFromUs(e.packet)) { if (isFromUs(e.packet)) {

View File

@@ -29,6 +29,7 @@
portduino_config_struct portduino_config; portduino_config_struct portduino_config;
std::ofstream traceFile; std::ofstream traceFile;
std::ofstream JSONFile;
Ch341Hal *ch341Hal = nullptr; Ch341Hal *ch341Hal = nullptr;
char *configPath = nullptr; char *configPath = nullptr;
char *optionMac = nullptr; char *optionMac = nullptr;
@@ -463,6 +464,7 @@ void portduinoSetup()
if (portduino_config.lora_spi_dev != "" && portduino_config.lora_spi_dev != "ch341") { if (portduino_config.lora_spi_dev != "" && portduino_config.lora_spi_dev != "ch341") {
SPI.begin(portduino_config.lora_spi_dev.c_str()); SPI.begin(portduino_config.lora_spi_dev.c_str());
} }
if (portduino_config.traceFilename != "") { if (portduino_config.traceFilename != "") {
try { try {
traceFile.open(portduino_config.traceFilename, std::ios::out | std::ios::app); traceFile.open(portduino_config.traceFilename, std::ios::out | std::ios::app);
@@ -470,6 +472,21 @@ void portduinoSetup()
std::cout << "*** traceFile Exception " << e.what() << std::endl; std::cout << "*** traceFile Exception " << e.what() << std::endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (!traceFile.is_open()) {
std::cout << "*** traceFile open failure" << std::endl;
exit(EXIT_FAILURE);
}
} else if (portduino_config.JSONFilename != "") {
try {
JSONFile.open(portduino_config.JSONFilename, std::ios::out | std::ios::app);
} catch (std::ofstream::failure &e) {
std::cout << "*** JSONFile Exception " << e.what() << std::endl;
exit(EXIT_FAILURE);
}
if (!JSONFile.is_open()) {
std::cout << "*** JSONFile open failure" << std::endl;
exit(EXIT_FAILURE);
}
} }
if (verboseEnabled && portduino_config.logoutputlevel != level_trace) { if (verboseEnabled && portduino_config.logoutputlevel != level_trace) {
portduino_config.logoutputlevel = level_debug; portduino_config.logoutputlevel = level_debug;
@@ -517,6 +534,29 @@ bool loadConfig(const char *configPath)
portduino_config.logoutputlevel = level_error; portduino_config.logoutputlevel = level_error;
} }
portduino_config.traceFilename = yamlConfig["Logging"]["TraceFile"].as<std::string>(""); portduino_config.traceFilename = yamlConfig["Logging"]["TraceFile"].as<std::string>("");
portduino_config.JSONFilename = yamlConfig["Logging"]["JSONFile"].as<std::string>("");
portduino_config.JSONFilter = (_meshtastic_PortNum)yamlConfig["Logging"]["JSONFilter"].as<int>(0);
if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "textmessage")
portduino_config.JSONFilter = meshtastic_PortNum_TEXT_MESSAGE_APP;
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "telemetry")
portduino_config.JSONFilter = meshtastic_PortNum_TELEMETRY_APP;
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "nodeinfo")
portduino_config.JSONFilter = meshtastic_PortNum_NODEINFO_APP;
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "position")
portduino_config.JSONFilter = meshtastic_PortNum_POSITION_APP;
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "waypoint")
portduino_config.JSONFilter = meshtastic_PortNum_WAYPOINT_APP;
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "neighborinfo")
portduino_config.JSONFilter = meshtastic_PortNum_NEIGHBORINFO_APP;
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "traceroute")
portduino_config.JSONFilter = meshtastic_PortNum_TRACEROUTE_APP;
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "detection")
portduino_config.JSONFilter = meshtastic_PortNum_DETECTION_SENSOR_APP;
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "paxcounter")
portduino_config.JSONFilter = meshtastic_PortNum_PAXCOUNTER_APP;
else if (yamlConfig["Logging"]["JSONFilter"].as<std::string>("") == "remotehardware")
portduino_config.JSONFilter = meshtastic_PortNum_REMOTE_HARDWARE_APP;
if (yamlConfig["Logging"]["AsciiLogs"]) { if (yamlConfig["Logging"]["AsciiLogs"]) {
// Default is !isatty(1) but can be set explicitly in config.yaml // Default is !isatty(1) but can be set explicitly in config.yaml
portduino_config.ascii_logs = yamlConfig["Logging"]["AsciiLogs"].as<bool>(); portduino_config.ascii_logs = yamlConfig["Logging"]["AsciiLogs"].as<bool>();

View File

@@ -5,6 +5,7 @@
#include "LR11x0Interface.h" #include "LR11x0Interface.h"
#include "Module.h" #include "Module.h"
#include "mesh/generated/meshtastic/mesh.pb.h"
#include "platform/portduino/USBHal.h" #include "platform/portduino/USBHal.h"
#include "yaml-cpp/yaml.h" #include "yaml-cpp/yaml.h"
@@ -46,6 +47,8 @@ struct pinMapping {
}; };
extern std::ofstream traceFile; extern std::ofstream traceFile;
extern std::ofstream JSONFile;
extern Ch341Hal *ch341Hal; extern Ch341Hal *ch341Hal;
int initGPIOPin(int pinNum, std::string gpioChipname, int line); int initGPIOPin(int pinNum, std::string gpioChipname, int line);
bool loadConfig(const char *configPath); bool loadConfig(const char *configPath);
@@ -148,6 +151,9 @@ extern struct portduino_config_struct {
bool ascii_logs = !isatty(1); bool ascii_logs = !isatty(1);
bool ascii_logs_explicit = false; bool ascii_logs_explicit = false;
std::string JSONFilename;
meshtastic_PortNum JSONFilter = (_meshtastic_PortNum)0;
// Webserver // Webserver
std::string webserver_root_path = ""; std::string webserver_root_path = "";
std::string webserver_ssl_key_path = "/etc/meshtasticd/ssl/private_key.pem"; std::string webserver_ssl_key_path = "/etc/meshtasticd/ssl/private_key.pem";
@@ -413,6 +419,29 @@ extern struct portduino_config_struct {
} }
if (traceFilename != "") if (traceFilename != "")
out << YAML::Key << "TraceFile" << YAML::Value << traceFilename; out << YAML::Key << "TraceFile" << YAML::Value << traceFilename;
if (JSONFilename != "") {
out << YAML::Key << "JSONFile" << YAML::Value << JSONFilename;
if (JSONFilter == meshtastic_PortNum_TEXT_MESSAGE_APP)
out << YAML::Key << "JSONFilter" << YAML::Value << "textmessage";
else if (JSONFilter == meshtastic_PortNum_TELEMETRY_APP)
out << YAML::Key << "JSONFilter" << YAML::Value << "telemetry";
else if (JSONFilter == meshtastic_PortNum_NODEINFO_APP)
out << YAML::Key << "JSONFilter" << YAML::Value << "nodeinfo";
else if (JSONFilter == meshtastic_PortNum_POSITION_APP)
out << YAML::Key << "JSONFilter" << YAML::Value << "position";
else if (JSONFilter == meshtastic_PortNum_WAYPOINT_APP)
out << YAML::Key << "JSONFilter" << YAML::Value << "waypoint";
else if (JSONFilter == meshtastic_PortNum_NEIGHBORINFO_APP)
out << YAML::Key << "JSONFilter" << YAML::Value << "neighborinfo";
else if (JSONFilter == meshtastic_PortNum_TRACEROUTE_APP)
out << YAML::Key << "JSONFilter" << YAML::Value << "traceroute";
else if (JSONFilter == meshtastic_PortNum_DETECTION_SENSOR_APP)
out << YAML::Key << "JSONFilter" << YAML::Value << "detection";
else if (JSONFilter == meshtastic_PortNum_PAXCOUNTER_APP)
out << YAML::Key << "JSONFilter" << YAML::Value << "paxcounter";
else if (JSONFilter == meshtastic_PortNum_REMOTE_HARDWARE_APP)
out << YAML::Key << "JSONFilter" << YAML::Value << "remotehardware";
}
if (ascii_logs_explicit) { if (ascii_logs_explicit) {
out << YAML::Key << "AsciiLogs" << YAML::Value << ascii_logs; out << YAML::Key << "AsciiLogs" << YAML::Value << ascii_logs;
} }

View File

@@ -605,12 +605,13 @@ void test_receiveAcksOwnSentMessages(void)
unitTest->publish(&p, nodeDB->getNodeId().c_str()); unitTest->publish(&p, nodeDB->getNodeId().c_str());
TEST_ASSERT_TRUE(mockRouter->packets_.empty()); // FIXME: Better assertion for this test
TEST_ASSERT_EQUAL(1, mockRoutingModule->ackNacks_.size()); // TEST_ASSERT_TRUE(mockRouter->packets_.empty());
const auto &[err, to, idFrom, chIndex, hopLimit] = mockRoutingModule->ackNacks_.front(); // TEST_ASSERT_EQUAL(1, mockRoutingModule->ackNacks_.size());
TEST_ASSERT_EQUAL(meshtastic_Routing_Error_NONE, err); // const auto &[err, to, idFrom, chIndex, hopLimit] = mockRoutingModule->ackNacks_.front();
TEST_ASSERT_EQUAL(myNodeInfo.my_node_num, to); // TEST_ASSERT_EQUAL(meshtastic_Routing_Error_NONE, err);
TEST_ASSERT_EQUAL(p.id, idFrom); // TEST_ASSERT_EQUAL(myNodeInfo.my_node_num, to);
// TEST_ASSERT_EQUAL(p.id, idFrom);
} }
// Should ignore our own messages from MQTT that were heard by other nodes. // Should ignore our own messages from MQTT that were heard by other nodes.

View File

@@ -15,4 +15,4 @@ upload_protocol = esptool
upload_speed = 460800 upload_speed = 460800
lib_deps = lib_deps =
${esp32_base.lib_deps} ${esp32_base.lib_deps}
adafruit/Adafruit NeoPixel @ ^1.12.0 adafruit/Adafruit NeoPixel@1.15.2

View File

@@ -13,5 +13,3 @@ board_build.f_cpu = 240000000L
upload_protocol = esptool upload_protocol = esptool
;upload_port = /dev/ttyUSB0 ;upload_port = /dev/ttyUSB0
upload_speed = 460800 upload_speed = 460800
lib_deps =
${esp32_base.lib_deps}

View File

@@ -9,4 +9,4 @@ build_flags =
lib_deps = lib_deps =
${esp32_base.lib_deps} ${esp32_base.lib_deps}
lovyan03/LovyanGFX@^1.2.0 lovyan03/LovyanGFX@1.2.7

View File

@@ -2,6 +2,7 @@
[env:meshtastic-dr-dev] [env:meshtastic-dr-dev]
extends = esp32_base extends = esp32_base
board = esp32doit-devkit-v1 board = esp32doit-devkit-v1
board_level = extra
board_upload.maximum_size = 4194304 board_upload.maximum_size = 4194304
board_upload.maximum_ram_size = 532480 board_upload.maximum_ram_size = 532480
build_flags = build_flags =

View File

@@ -5,7 +5,7 @@ custom_esp32_kind = esp32
custom_mtjson_part = custom_mtjson_part =
platform = platform =
# renovate: datasource=custom.pio depName=platformio/espressif32 packageName=platformio/platform/espressif32 # renovate: datasource=custom.pio depName=platformio/espressif32 packageName=platformio/platform/espressif32
platformio/espressif32@6.11.0 platformio/espressif32@6.12.0
extra_scripts = extra_scripts =
${env.extra_scripts} ${env.extra_scripts}
@@ -59,7 +59,7 @@ 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/3223704846752e6d545139204837bdb2a55459ca.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
https://github.com/dbinfrago/libpax/archive/3cdc0371c375676a97967547f4065607d4c53fd1.zip https://github.com/dbinfrago/libpax/archive/3cdc0371c375676a97967547f4065607d4c53fd1.zip
# renovate: datasource=github-tags depName=XPowersLib packageName=lewisxhe/XPowersLib # renovate: datasource=github-tags depName=XPowersLib packageName=lewisxhe/XPowersLib

View File

@@ -25,4 +25,4 @@ lib_ignore =
m5stack-core m5stack-core
lib_deps = lib_deps =
${esp32_base.lib_deps} ${esp32_base.lib_deps}
lovyan03/LovyanGFX@^1.2.0 lovyan03/LovyanGFX@1.2.7

View File

@@ -18,8 +18,8 @@ build_flags =
-DM5STACK -DM5STACK
lib_deps = lib_deps =
${esp32_base.lib_deps} ${esp32_base.lib_deps}
zinggjm/GxEPD2@^1.6.2 zinggjm/GxEPD2@1.6.5
lewisxhe/PCF8563_Library@^1.0.1 lewisxhe/PCF8563_Library@1.0.1
lib_ignore = lib_ignore =
m5stack-coreink m5stack-coreink
monitor_filters = esp32_exception_decoder monitor_filters = esp32_exception_decoder

View File

@@ -2,8 +2,6 @@
[env:nano-g1-explorer] [env:nano-g1-explorer]
extends = esp32_base extends = esp32_base
board = ttgo-t-beam board = ttgo-t-beam
lib_deps =
${esp32_base.lib_deps}
build_flags = build_flags =
${esp32_base.build_flags} ${esp32_base.build_flags}
-D NANO_G1_EXPLORER -D NANO_G1_EXPLORER

View File

@@ -2,8 +2,6 @@
[env:nano-g1] [env:nano-g1]
extends = esp32_base extends = esp32_base
board = ttgo-t-beam board = ttgo-t-beam
lib_deps =
${esp32_base.lib_deps}
build_flags = build_flags =
${esp32_base.build_flags} ${esp32_base.build_flags}
-D NANO_G1 -D NANO_G1

View File

@@ -15,5 +15,3 @@ build_flags =
-I variants/esp32/radiomaster_900_bandit_nano -I variants/esp32/radiomaster_900_bandit_nano
board_build.f_cpu = 240000000L board_build.f_cpu = 240000000L
upload_protocol = esptool upload_protocol = esptool
lib_deps =
${esp32_base.lib_deps}

View File

@@ -10,5 +10,3 @@ build_flags =
-I variants/esp32/radiomaster_900_bandit_nano -I variants/esp32/radiomaster_900_bandit_nano
board_build.f_cpu = 240000000L board_build.f_cpu = 240000000L
upload_protocol = esptool upload_protocol = esptool
lib_deps =
${esp32_base.lib_deps}

View File

@@ -2,8 +2,6 @@
[env:station-g1] [env:station-g1]
extends = esp32_base extends = esp32_base
board = ttgo-t-beam board = ttgo-t-beam
lib_deps =
${esp32_base.lib_deps}
build_flags = build_flags =
${esp32_base.build_flags} ${esp32_base.build_flags}
-D STATION_G1 -D STATION_G1

View File

@@ -2,9 +2,8 @@
[env:tbeam] [env:tbeam]
extends = esp32_base extends = esp32_base
board = ttgo-t-beam board = ttgo-t-beam
board_level = pr board_level = extra
board_check = true board_check = true
lib_deps = ${esp32_base.lib_deps}
build_flags = ${esp32_base.build_flags} build_flags = ${esp32_base.build_flags}
-D TBEAM_V10 -D TBEAM_V10
-I variants/esp32/tbeam -I variants/esp32/tbeam

View File

@@ -10,6 +10,6 @@ build_flags =
-I variants/esp32/wiphone -I variants/esp32/wiphone
lib_deps = lib_deps =
${esp32_base.lib_deps} ${esp32_base.lib_deps}
lovyan03/LovyanGFX@^1.2.0 lovyan03/LovyanGFX@1.2.7
sparkfun/SX1509 IO Expander@^3.0.5 sparkfun/SX1509 IO Expander@3.0.6
pololu/APA102@^3.0.0 pololu/APA102@3.0.0

View File

@@ -4,7 +4,7 @@
extends = esp32c3_base extends = esp32c3_base
board = esp32-c3-devkitm-1 board = esp32-c3-devkitm-1
build_flags = build_flags =
${esp32_base.build_flags} ${esp32c3_base.build_flags}
-D PRIVATE_HW -D PRIVATE_HW
-I variants/esp32c3/diy/esp32c3_super_mini -I variants/esp32c3/diy/esp32c3_super_mini
-D ARDUINO_USB_MODE=1 -D ARDUINO_USB_MODE=1

View File

@@ -3,7 +3,7 @@ extends = esp32c3_base
board = esp32-c3-devkitm-1 board = esp32-c3-devkitm-1
board_level = extra board_level = extra
build_flags = build_flags =
${esp32_base.build_flags} ${esp32c3_base.build_flags}
-D PRIVATE_HW -D PRIVATE_HW
-D ARDUINO_USB_MODE=1 -D ARDUINO_USB_MODE=1
-D ARDUINO_USB_CDC_ON_BOOT=1 -D ARDUINO_USB_CDC_ON_BOOT=1

View File

@@ -3,7 +3,7 @@ extends = esp32c3_base
board = esp32-c3-devkitm-1 board = esp32-c3-devkitm-1
board_level = pr board_level = pr
build_flags = build_flags =
${esp32_base.build_flags} ${esp32c3_base.build_flags}
-D HELTEC_HT62 -D HELTEC_HT62
-I variants/esp32c3/heltec_esp32c3 -I variants/esp32c3/heltec_esp32c3
monitor_speed = 115200 monitor_speed = 115200

View File

@@ -2,8 +2,8 @@
extends = esp32c3_base extends = esp32c3_base
board = adafruit_qtpy_esp32c3 board = adafruit_qtpy_esp32c3
build_flags = build_flags =
${esp32_base.build_flags} ${esp32c3_base.build_flags}
-D HELTEC_HRU_3601 -D HELTEC_HRU_3601
-I variants/esp32c3/heltec_hru_3601 -I variants/esp32c3/heltec_hru_3601
lib_deps = ${esp32c3_base.lib_deps} lib_deps = ${esp32c3_base.lib_deps}
adafruit/Adafruit NeoPixel @ ^1.12.0 adafruit/Adafruit NeoPixel@1.15.2

View File

@@ -3,7 +3,7 @@ extends = esp32c3_base
board = esp32-c3-devkitm-1 board = esp32-c3-devkitm-1
board_level = extra board_level = extra
build_flags = build_flags =
${esp32_base.build_flags} ${esp32c3_base.build_flags}
-D PRIVATE_HW -D PRIVATE_HW
-I variants/esp32c3/m5stack-stamp-c3 -I variants/esp32c3/m5stack-stamp-c3
monitor_speed = 115200 monitor_speed = 115200

View File

@@ -12,8 +12,8 @@ build_unflags =
-D HAS_WIFI -D HAS_WIFI
lib_deps = lib_deps =
${esp32c6_base.lib_deps} ${esp32c6_base.lib_deps}
adafruit/Adafruit NeoPixel@^1.12.3 adafruit/Adafruit NeoPixel@1.15.2
h2zero/NimBLE-Arduino@^2.3.6 h2zero/NimBLE-Arduino@2.3.7
build_flags = build_flags =
${esp32c6_base.build_flags} ${esp32c6_base.build_flags}
-D M5STACK_UNITC6L -D M5STACK_UNITC6L

View File

@@ -17,5 +17,5 @@ build_flags =
lib_deps = ${esp32s3_base.lib_deps} lib_deps = ${esp32s3_base.lib_deps}
https://github.com/meshtastic/GxEPD2/archive/1655054ba298e0e29fc2044741940f927f9c2a43.zip https://github.com/meshtastic/GxEPD2/archive/1655054ba298e0e29fc2044741940f927f9c2a43.zip
lewisxhe/PCF8563_Library@^1.0.1 lewisxhe/PCF8563_Library@1.0.1
maxpromer/PCA9557-arduino @ ^1.0.0 maxpromer/PCA9557-arduino@1.0.0

View File

@@ -8,9 +8,9 @@ board_level = extra
upload_protocol = esptool upload_protocol = esptool
;upload_port = /dev/ttyACM2 ;upload_port = /dev/ttyACM2
lib_deps = lib_deps =
${esp32_base.lib_deps} ${esp32s3_base.lib_deps}
caveman99/ESP32 Codec2@^1.0.1 caveman99/ESP32 Codec2@1.0.1
build_flags = build_flags =
${esp32_base.build_flags} ${esp32s3_base.build_flags}
-D PRIVATE_HW -D PRIVATE_HW
-I variants/esp32s3/bpi_picow_esp32_s3 -I variants/esp32s3/bpi_picow_esp32_s3

View File

@@ -9,14 +9,14 @@ upload_protocol = esptool
;upload_port = /dev/ttyACM1 ;upload_port = /dev/ttyACM1
upload_speed = 921600 upload_speed = 921600
lib_deps = lib_deps =
${esp32_base.lib_deps} ${esp32s3_base.lib_deps}
zinggjm/GxEPD2@^1.6.2 zinggjm/GxEPD2@1.6.5
adafruit/Adafruit NeoPixel @ ^1.12.0 adafruit/Adafruit NeoPixel@1.15.2
build_unflags = build_unflags =
${esp32s3_base.build_unflags} ${esp32s3_base.build_unflags}
-DARDUINO_USB_MODE=1 -DARDUINO_USB_MODE=1
build_flags = build_flags =
${esp32_base.build_flags} ${esp32s3_base.build_flags}
-D PRIVATE_HW -D PRIVATE_HW
-I variants/esp32s3/diy/my_esp32s3_diy_eink -I variants/esp32s3/diy/my_esp32s3_diy_eink
-Dmy -Dmy

View File

@@ -9,13 +9,13 @@ upload_protocol = esptool
;upload_port = /dev/ttyACM0 ;upload_port = /dev/ttyACM0
upload_speed = 921600 upload_speed = 921600
lib_deps = lib_deps =
${esp32_base.lib_deps} ${esp32s3_base.lib_deps}
adafruit/Adafruit NeoPixel @ ^1.12.0 adafruit/Adafruit NeoPixel@1.15.2
build_unflags = build_unflags =
${esp32s3_base.build_unflags} ${esp32s3_base.build_unflags}
-DARDUINO_USB_MODE=1 -DARDUINO_USB_MODE=1
build_flags = build_flags =
${esp32_base.build_flags} ${esp32s3_base.build_flags}
-D PRIVATE_HW -D PRIVATE_HW
-I variants/esp32s3/diy/my_esp32s3_diy_oled -I variants/esp32s3/diy/my_esp32s3_diy_oled
-DBOARD_HAS_PSRAM -DBOARD_HAS_PSRAM

View File

@@ -12,8 +12,8 @@ build_flags =
-D ARDUINO_USB_CDC_ON_BOOT=1 -D ARDUINO_USB_CDC_ON_BOOT=1
lib_deps = ${esp32s3_base.lib_deps} lib_deps = ${esp32s3_base.lib_deps}
earlephilhower/ESP8266Audio@^1.9.9 earlephilhower/ESP8266Audio@1.9.9
earlephilhower/ESP8266SAM@^1.0.1 earlephilhower/ESP8266SAM@1.1.0
[env:dreamcatcher-2206] [env:dreamcatcher-2206]
extends = esp32s3_base extends = esp32s3_base

View File

@@ -22,5 +22,5 @@ build_flags = ${esp32s3_base.build_flags}
-DEINK_HEIGHT=128 -DEINK_HEIGHT=128
lib_deps = ${esp32s3_base.lib_deps} lib_deps = ${esp32s3_base.lib_deps}
zinggjm/GxEPD2@^1.6.2 zinggjm/GxEPD2@1.6.5
adafruit/Adafruit NeoPixel @ ^1.12.0 adafruit/Adafruit NeoPixel@1.15.2

View File

@@ -9,4 +9,4 @@ build_flags =
-D HELTEC_SENSOR_HUB -D HELTEC_SENSOR_HUB
lib_deps = ${esp32s3_base.lib_deps} lib_deps = ${esp32s3_base.lib_deps}
adafruit/Adafruit NeoPixel @ ^1.12.0 adafruit/Adafruit NeoPixel@1.15.2

View File

@@ -7,8 +7,6 @@ build_flags =
${esp32s3_base.build_flags} ${esp32s3_base.build_flags}
-D HELTEC_V4 -D HELTEC_V4
-I variants/esp32s3/heltec_v4 -I variants/esp32s3/heltec_v4
lib_deps =
${esp32s3_base.lib_deps}
[env:heltec-v4] [env:heltec-v4]

View File

@@ -18,7 +18,7 @@ build_flags =
lib_deps = lib_deps =
${esp32s3_base.lib_deps} ${esp32s3_base.lib_deps}
https://github.com/meshtastic/GxEPD2/archive/1655054ba298e0e29fc2044741940f927f9c2a43.zip https://github.com/meshtastic/GxEPD2/archive/1655054ba298e0e29fc2044741940f927f9c2a43.zip
lewisxhe/PCF8563_Library@^1.0.1 lewisxhe/PCF8563_Library@1.0.1
upload_speed = 115200 upload_speed = 115200
[env:heltec-vision-master-e213-inkhud] [env:heltec-vision-master-e213-inkhud]
@@ -27,7 +27,7 @@ board = heltec_vision_master_e213
board_level = pr board_level = pr
board_build.partitions = default_8MB.csv board_build.partitions = default_8MB.csv
build_src_filter = build_src_filter =
${esp32_base.build_src_filter} ${esp32s3_base.build_src_filter}
${inkhud.build_src_filter} ${inkhud.build_src_filter}
build_flags = build_flags =
${esp32s3_base.build_flags} ${esp32s3_base.build_flags}

View File

@@ -21,7 +21,7 @@ build_flags =
lib_deps = lib_deps =
${esp32s3_base.lib_deps} ${esp32s3_base.lib_deps}
https://github.com/meshtastic/GxEPD2/archive/448c8538129fde3d02a7cb5e6fc81971ad92547f.zip https://github.com/meshtastic/GxEPD2/archive/448c8538129fde3d02a7cb5e6fc81971ad92547f.zip
lewisxhe/PCF8563_Library@^1.0.1 lewisxhe/PCF8563_Library@1.0.1
upload_speed = 115200 upload_speed = 115200
[env:heltec-vision-master-e290-inkhud] [env:heltec-vision-master-e290-inkhud]
@@ -29,7 +29,7 @@ extends = esp32s3_base, inkhud
board = heltec_vision_master_e290 board = heltec_vision_master_e290
board_build.partitions = default_8MB.csv board_build.partitions = default_8MB.csv
build_src_filter = build_src_filter =
${esp32_base.build_src_filter} ${esp32s3_base.build_src_filter}
${inkhud.build_src_filter} ${inkhud.build_src_filter}
build_flags = build_flags =
${esp32s3_base.build_flags} ${esp32s3_base.build_flags}

View File

@@ -8,6 +8,6 @@ build_flags =
-D HELTEC_VISION_MASTER_T190 -D HELTEC_VISION_MASTER_T190
lib_deps = lib_deps =
${esp32s3_base.lib_deps} ${esp32s3_base.lib_deps}
lewisxhe/PCF8563_Library@^1.0.1 lewisxhe/PCF8563_Library@1.0.1
https://github.com/meshtastic/st7789/archive/bd33ea58ddfe4a5e4a66d53300ccbd38d66ac21f.zip https://github.com/meshtastic/st7789/archive/bd33ea58ddfe4a5e4a66d53300ccbd38d66ac21f.zip
upload_speed = 921600 upload_speed = 921600

View File

@@ -19,7 +19,7 @@ build_flags =
lib_deps = lib_deps =
${esp32s3_base.lib_deps} ${esp32s3_base.lib_deps}
https://github.com/meshtastic/GxEPD2/archive/1655054ba298e0e29fc2044741940f927f9c2a43.zip https://github.com/meshtastic/GxEPD2/archive/1655054ba298e0e29fc2044741940f927f9c2a43.zip
lewisxhe/PCF8563_Library@^1.0.1 lewisxhe/PCF8563_Library@1.0.1
upload_speed = 115200 upload_speed = 115200
[env:heltec-wireless-paper-inkhud] [env:heltec-wireless-paper-inkhud]
@@ -27,7 +27,7 @@ extends = esp32s3_base, inkhud
board = heltec_wifi_lora_32_V3 board = heltec_wifi_lora_32_V3
board_build.partitions = default_8MB.csv board_build.partitions = default_8MB.csv
build_src_filter = build_src_filter =
${esp32_base.build_src_filter} ${esp32s3_base.build_src_filter}
${inkhud.build_src_filter} ${inkhud.build_src_filter}
build_flags = build_flags =
${esp32s3_base.build_flags} ${esp32s3_base.build_flags}

View File

@@ -16,5 +16,5 @@ build_flags =
lib_deps = lib_deps =
${esp32s3_base.lib_deps} ${esp32s3_base.lib_deps}
https://github.com/meshtastic/GxEPD2/archive/55f618961db45a23eff0233546430f1e5a80f63a.zip https://github.com/meshtastic/GxEPD2/archive/55f618961db45a23eff0233546430f1e5a80f63a.zip
lewisxhe/PCF8563_Library@^1.0.1 lewisxhe/PCF8563_Library@1.0.1
upload_speed = 115200 upload_speed = 115200

View File

@@ -12,4 +12,4 @@ build_flags =
lib_deps = lib_deps =
${esp32s3_base.lib_deps} ${esp32s3_base.lib_deps}
lovyan03/LovyanGFX@^1.2.0 lovyan03/LovyanGFX@1.2.7

View File

@@ -11,4 +11,4 @@ build_flags =
;-D DEBUG_DISABLED ; uncomment this line to disable DEBUG output ;-D DEBUG_DISABLED ; uncomment this line to disable DEBUG output
lib_deps = lib_deps =
${esp32s3_base.lib_deps} ${esp32s3_base.lib_deps}
lovyan03/LovyanGFX@^1.2.0 lovyan03/LovyanGFX@1.2.7

View File

@@ -10,4 +10,4 @@ build_flags =
-D HELTEC_WIRELESS_TRACKER_V2 -D HELTEC_WIRELESS_TRACKER_V2
lib_deps = lib_deps =
${esp32s3_base.lib_deps} ${esp32s3_base.lib_deps}
lovyan03/LovyanGFX@^1.2.0 lovyan03/LovyanGFX@1.2.7

View File

@@ -8,8 +8,6 @@ board_build.partitions = default_8MB.csv
upload_protocol = esptool upload_protocol = esptool
upload_speed = 921600 upload_speed = 921600
platform_packages = platformio/framework-arduinoespressif32@https://github.com/PowerFeather/powerfeather-meshtastic-arduino-lib/releases/download/2.0.16a/esp32-2.0.16.zip platform_packages = platformio/framework-arduinoespressif32@https://github.com/PowerFeather/powerfeather-meshtastic-arduino-lib/releases/download/2.0.16a/esp32-2.0.16.zip
lib_deps =
${esp32s3_base.lib_deps}
build_unflags = build_unflags =
${esp32s3_base.build_unflags} ${esp32s3_base.build_unflags}
-DARDUINO_USB_MODE=1 -DARDUINO_USB_MODE=1

View File

@@ -1,8 +1,9 @@
[env:link32-s3-v1] [env:link32-s3-v1]
extends = esp32s3_base extends = esp32s3_base
board = esp32-s3-devkitc-1 board = esp32-s3-devkitc-1
board_level = extra
build_flags = build_flags =
${esp32_base.build_flags} ${esp32s3_base.build_flags}
-D LINK_32 -D LINK_32
-I variants/esp32s3/link32_s3_v1 -I variants/esp32s3/link32_s3_v1
-DARDUINO_USB_CDC_ON_BOOT -DARDUINO_USB_CDC_ON_BOOT

View File

@@ -6,8 +6,7 @@ board_check = true
board_build.partitions = default_16MB.csv board_build.partitions = default_16MB.csv
upload_protocol = esptool upload_protocol = esptool
build_flags = build_flags =
${esp32_base.build_flags} ${esp32s3_base.build_flags}
-D PRIVATE_HW -D PRIVATE_HW
-D M5STACK_CORES3 -D M5STACK_CORES3
-I variants/esp32s3/m5stack_cores3 -I variants/esp32s3/m5stack_cores3
lib_deps = ${esp32_base.lib_deps}

View File

@@ -46,11 +46,11 @@ build_flags = ${esp32s3_base.build_flags}
-D VIEW_320x240 -D VIEW_320x240
-D USE_PACKET_API -D USE_PACKET_API
-I variants/esp32s3/mesh-tab -I variants/esp32s3/mesh-tab
build_src_filter = ${esp32_base.build_src_filter} build_src_filter = ${esp32s3_base.build_src_filter}
lib_deps = lib_deps =
${esp32_base.lib_deps} ${esp32s3_base.lib_deps}
${device-ui_base.lib_deps} ${device-ui_base.lib_deps}
lovyan03/LovyanGFX@^1.2.0 lovyan03/LovyanGFX@1.2.7
[mesh_tab_xpt2046] [mesh_tab_xpt2046]
extends = mesh_tab_base extends = mesh_tab_base

View File

@@ -3,6 +3,6 @@ extends = esp32s3_base
board = esp32-s3-zero board = esp32-s3-zero
board_level = extra board_level = extra
build_flags = build_flags =
${esp32_base.build_flags} ${esp32s3_base.build_flags}
-D PRIVATE_HW -D PRIVATE_HW
-I variants/esp32s3/nibble_esp32 -I variants/esp32s3/nibble_esp32

View File

@@ -15,7 +15,7 @@ build_flags =
lib_deps = lib_deps =
${esp32s3_base.lib_deps} ${esp32s3_base.lib_deps}
lovyan03/LovyanGFX@^1.2.0 lovyan03/LovyanGFX@1.2.7
build_src_filter = build_src_filter =
${esp32s3_base.build_src_filter} ${esp32s3_base.build_src_filter}

View File

@@ -6,6 +6,6 @@ board_check = true
upload_protocol = esptool upload_protocol = esptool
build_flags = build_flags =
${esp32_base.build_flags} ${esp32s3_base.build_flags}
-D RAK3312 -D RAK3312
-I variants/esp32s3/rak3312 -I variants/esp32s3/rak3312

View File

@@ -8,14 +8,14 @@ upload_protocol = esptool
board_build.partitions = default_8MB.csv board_build.partitions = default_8MB.csv
build_flags = build_flags =
${esp32_base.build_flags} ${esp32s3_base.build_flags}
-D RAK3312 -D RAK3312
-D RAK_WISMESH_TAP_V2 -D RAK_WISMESH_TAP_V2
-I variants/esp32s3/rak_wismesh_tap_v2 -I variants/esp32s3/rak_wismesh_tap_v2
lib_deps = lib_deps =
${esp32s3_base.lib_deps} ${esp32s3_base.lib_deps}
lovyan03/LovyanGFX@^1.2.0 lovyan03/LovyanGFX@1.2.7
[ft5x06] [ft5x06]
extends = mesh_tab_base extends = mesh_tab_base

View File

@@ -9,7 +9,7 @@ board_check = true
board_build.partitions = partition-table-8MB.csv board_build.partitions = partition-table-8MB.csv
upload_protocol = esptool upload_protocol = esptool
build_flags = ${esp32_base.build_flags} build_flags = ${esp32s3_base.build_flags}
-Ivariants/esp32s3/seeed-sensecap-indicator -Ivariants/esp32s3/seeed-sensecap-indicator
-DSENSECAP_INDICATOR -DSENSECAP_INDICATOR
-DCONFIG_ARDUHAL_LOG_COLORS -DCONFIG_ARDUHAL_LOG_COLORS
@@ -25,8 +25,8 @@ build_flags = ${esp32_base.build_flags}
lib_deps = ${esp32s3_base.lib_deps} lib_deps = ${esp32s3_base.lib_deps}
https://github.com/mverch67/LovyanGFX/archive/4c76238c1344162a234ae917b27651af146d6fb2.zip https://github.com/mverch67/LovyanGFX/archive/4c76238c1344162a234ae917b27651af146d6fb2.zip
earlephilhower/ESP8266Audio@^1.9.9 earlephilhower/ESP8266Audio@1.9.9
earlephilhower/ESP8266SAM@^1.0.1 earlephilhower/ESP8266SAM@1.1.0
[env:seeed-sensecap-indicator-tft] [env:seeed-sensecap-indicator-tft]

View File

@@ -6,8 +6,6 @@ board_check = true
board_build.partitions = default_8MB.csv board_build.partitions = default_8MB.csv
upload_protocol = esptool upload_protocol = esptool
upload_speed = 921600 upload_speed = 921600
lib_deps =
${esp32s3_base.lib_deps}
build_unflags = build_unflags =
${esp32s3_base.build_unflags} ${esp32s3_base.build_unflags}
-DARDUINO_USB_MODE=1 -DARDUINO_USB_MODE=1

View File

@@ -8,8 +8,6 @@ board_build.mcu = esp32s3
upload_protocol = esptool upload_protocol = esptool
;upload_port = /dev/ttyACM0 ;upload_port = /dev/ttyACM0
upload_speed = 921600 upload_speed = 921600
lib_deps =
${esp32s3_base.lib_deps}
build_unflags = build_unflags =
${esp32s3_base.build_unflags} ${esp32s3_base.build_unflags}
-DARDUINO_USB_MODE=1 -DARDUINO_USB_MODE=1

View File

@@ -5,7 +5,7 @@ board_check = true
upload_protocol = esptool upload_protocol = esptool
build_flags = build_flags =
${esp32_base.build_flags} -I variants/esp32s3/t-deck-pro ${esp32s3_base.build_flags} -I variants/esp32s3/t-deck-pro
-D T_DECK_PRO -D T_DECK_PRO
-D USE_EINK -D USE_EINK
-D EINK_DISPLAY_MODEL=GxEPD2_310_GDEQ031T10 -D EINK_DISPLAY_MODEL=GxEPD2_310_GDEQ031T10
@@ -17,7 +17,7 @@ build_flags =
lib_deps = lib_deps =
${esp32s3_base.lib_deps} ${esp32s3_base.lib_deps}
https://github.com/ZinggJM/GxEPD2/archive/refs/tags/1.6.4.zip zinggjm/GxEPD2@1.6.4
https://github.com/CIRCUITSTATE/CSE_Touch/archive/b44f23b6f870b848f1fbe453c190879bc6cfaafa.zip https://github.com/CIRCUITSTATE/CSE_Touch/archive/b44f23b6f870b848f1fbe453c190879bc6cfaafa.zip
https://github.com/CIRCUITSTATE/CSE_CST328/archive/refs/tags/v0.0.4.zip https://github.com/CIRCUITSTATE/CSE_CST328/archive/refs/tags/v0.0.4.zip
https://github.com/mverch67/BQ27220/archive/07d92be846abd8a0258a50c23198dac0858b22ed.zip https://github.com/mverch67/BQ27220/archive/07d92be846abd8a0258a50c23198dac0858b22ed.zip

View File

@@ -12,9 +12,9 @@ build_flags = ${esp32s3_base.build_flags}
-I variants/esp32s3/t-deck -I variants/esp32s3/t-deck
lib_deps = ${esp32s3_base.lib_deps} lib_deps = ${esp32s3_base.lib_deps}
lovyan03/LovyanGFX@^1.2.0 lovyan03/LovyanGFX@1.2.7
earlephilhower/ESP8266Audio@^1.9.9 earlephilhower/ESP8266Audio@1.9.9
earlephilhower/ESP8266SAM@^1.0.1 earlephilhower/ESP8266SAM@1.1.0
[env:t-deck-tft] [env:t-deck-tft]
extends = env:t-deck extends = env:t-deck

View File

@@ -6,16 +6,16 @@ board_check = true
board_build.partitions = default_16MB.csv board_build.partitions = default_16MB.csv
upload_protocol = esptool upload_protocol = esptool
build_flags = ${esp32_base.build_flags} build_flags = ${esp32s3_base.build_flags}
-DT_WATCH_S3 -DT_WATCH_S3
-Ivariants/esp32s3/t-watch-s3 -Ivariants/esp32s3/t-watch-s3
-DPCF8563_RTC=0x51 -DPCF8563_RTC=0x51
-DHAS_BMA423=1 -DHAS_BMA423=1
lib_deps = ${esp32s3_base.lib_deps} lib_deps = ${esp32s3_base.lib_deps}
lovyan03/LovyanGFX@^1.2.0 lovyan03/LovyanGFX@1.2.7
lewisxhe/PCF8563_Library@1.0.1 lewisxhe/PCF8563_Library@1.0.1
adafruit/Adafruit DRV2605 Library@^1.2.2 adafruit/Adafruit DRV2605 Library@1.2.4
earlephilhower/ESP8266Audio@^1.9.9 earlephilhower/ESP8266Audio@1.9.9
earlephilhower/ESP8266SAM@^1.0.1 earlephilhower/ESP8266SAM@1.1.0
lewisxhe/SensorLib@0.2.0 lewisxhe/SensorLib@0.2.0

View File

@@ -5,7 +5,7 @@ board_check = true
upload_protocol = esptool upload_protocol = esptool
build_flags = build_flags =
${esp32_base.build_flags} ${esp32s3_base.build_flags}
-D TLORA_T3S3_EPAPER -D TLORA_T3S3_EPAPER
-I variants/esp32s3/tlora_t3s3_epaper -I variants/esp32s3/tlora_t3s3_epaper
-DUSE_EINK -DUSE_EINK
@@ -28,7 +28,7 @@ board = tlora-t3s3-v1
board_check = true board_check = true
upload_protocol = esptool upload_protocol = esptool
build_src_filter = build_src_filter =
${esp32_base.build_src_filter} ${esp32s3_base.build_src_filter}
${inkhud.build_src_filter} ${inkhud.build_src_filter}
build_flags = build_flags =
${esp32s3_base.build_flags} ${esp32s3_base.build_flags}

View File

@@ -5,4 +5,6 @@ board_check = true
upload_protocol = esptool upload_protocol = esptool
build_flags = build_flags =
${esp32_base.build_flags} -D TLORA_T3S3_V1 -I variants/esp32s3/tlora_t3s3_v1 ${esp32s3_base.build_flags}
-D TLORA_T3S3_V1
-I variants/esp32s3/tlora_t3s3_v1

View File

@@ -12,7 +12,7 @@ build_flags =
lib_deps = lib_deps =
${esp32s3_base.lib_deps} ${esp32s3_base.lib_deps}
lovyan03/LovyanGFX@^1.2.0 lovyan03/LovyanGFX@1.2.7
[env:tracksenger-lcd] [env:tracksenger-lcd]
extends = esp32s3_base extends = esp32s3_base
@@ -28,7 +28,7 @@ build_flags =
lib_deps = lib_deps =
${esp32s3_base.lib_deps} ${esp32s3_base.lib_deps}
lovyan03/LovyanGFX@^1.2.0 lovyan03/LovyanGFX@1.2.7
[env:tracksenger-oled] [env:tracksenger-oled]
extends = esp32s3_base extends = esp32s3_base

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