mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-15 15:22:34 +00:00
Compare commits
40 Commits
revert-2m-
...
arduino-es
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b05f090dc | ||
|
|
e9b87f7a81 | ||
|
|
d47d249550 | ||
|
|
ff28355e16 | ||
|
|
351cbd723b | ||
|
|
be1a724ab4 | ||
|
|
04f98cf20e | ||
|
|
75a1a41d8c | ||
|
|
344efa6675 | ||
|
|
e919b3da9c | ||
|
|
155783c782 | ||
|
|
76bcd05259 | ||
|
|
2d29cbc34c | ||
|
|
2b77864192 | ||
|
|
10aa4cbfee | ||
|
|
c24a174490 | ||
|
|
3e5e19efec | ||
|
|
ea2c247024 | ||
|
|
0b463b6443 | ||
|
|
7d3c804279 | ||
|
|
1fa7d9f40e | ||
|
|
aa7abb1d3e | ||
|
|
effb454af0 | ||
|
|
27bb42ed3b | ||
|
|
05dc8caed8 | ||
|
|
f3734d407d | ||
|
|
bc8e509a8c | ||
|
|
74d0472834 | ||
|
|
5afc43ebc1 | ||
|
|
6cdb92b7a8 | ||
|
|
0e1872398a | ||
|
|
f25544c7e0 | ||
|
|
f40b2ba153 | ||
|
|
5033fd1f9f | ||
|
|
cd170fb011 | ||
|
|
fa169a5e43 | ||
|
|
c6e2a53a02 | ||
|
|
a286c06271 | ||
|
|
dda4b90e34 | ||
|
|
cc5dc5046c |
@@ -76,7 +76,7 @@ bool loopCanSleep()
|
||||
// Called just prior to starting Meshtastic. Allows for setting config values before startup.
|
||||
void lateInitVariant()
|
||||
{
|
||||
portduino_config.logoutputlevel = level_error;
|
||||
settingsMap[logoutputlevel] = level_error;
|
||||
channelFile.channels[0] = meshtastic_Channel{
|
||||
.has_settings = true,
|
||||
.settings =
|
||||
@@ -132,7 +132,7 @@ int portduino_main(int argc, char **argv); // Renamed "main" function from Mesht
|
||||
// Start Meshtastic in a thread and wait till it has reached the ON state.
|
||||
int LLVMFuzzerInitialize(int *argc, char ***argv)
|
||||
{
|
||||
portduino_config.maxtophone = 5;
|
||||
settingsMap[maxtophone] = 5;
|
||||
|
||||
meshtasticThread = std::thread([program = *argv[0]]() {
|
||||
char nodeIdStr[12];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# trunk-ignore-all(terrascan/AC_DOCKER_0002): Known terrascan issue
|
||||
# trunk-ignore-all(hadolint/DL3008): Do not pin apt package versions
|
||||
# trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions
|
||||
FROM mcr.microsoft.com/devcontainers/cpp:2-debian-13
|
||||
FROM mcr.microsoft.com/devcontainers/cpp:1-debian-12
|
||||
|
||||
USER root
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/python:1": {
|
||||
"installTools": true,
|
||||
"version": "3.14"
|
||||
"version": "latest"
|
||||
}
|
||||
},
|
||||
"customizations": {
|
||||
|
||||
2
.github/actions/build-variant/action.yml
vendored
2
.github/actions/build-variant/action.yml
vendored
@@ -100,7 +100,7 @@ runs:
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: firmware-${{ inputs.arch }}-${{ inputs.board }}-${{ steps.version.outputs.long }}.zip
|
||||
overwrite: true
|
||||
|
||||
2
.github/actions/setup-base/action.yml
vendored
2
.github/actions/setup-base/action.yml
vendored
@@ -5,7 +5,7 @@ runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: recursive
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
|
||||
4
.github/workflows/build_debian_src.yml
vendored
4
.github/workflows/build_debian_src.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: recursive
|
||||
path: meshtasticd
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
PKG_VERSION: ${{ steps.version.outputs.deb }}
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||
overwrite: true
|
||||
|
||||
7
.github/workflows/build_firmware.yml
vendored
7
.github/workflows/build_firmware.yml
vendored
@@ -19,10 +19,8 @@ jobs:
|
||||
pio-build:
|
||||
name: build-${{ inputs.platform }}
|
||||
runs-on: ubuntu-24.04
|
||||
outputs:
|
||||
artifact-id: ${{ steps.upload.outputs.artifact-id }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: recursive
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
@@ -56,8 +54,7 @@ jobs:
|
||||
ota_firmware_target: ${{ steps.ota_dir.outputs.tgt || '' }}
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
id: upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: firmware-${{ inputs.platform }}-${{ inputs.pio_env }}-${{ inputs.version }}.zip
|
||||
overwrite: true
|
||||
|
||||
161
.github/workflows/build_one_target.yml
vendored
161
.github/workflows/build_one_target.yml
vendored
@@ -1,161 +0,0 @@
|
||||
name: Build One Target
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
# trunk-ignore(checkov/CKV_GHA_7)
|
||||
arch:
|
||||
type: choice
|
||||
options:
|
||||
- esp32
|
||||
- esp32s3
|
||||
- esp32c3
|
||||
- esp32c6
|
||||
- nrf52840
|
||||
- rp2040
|
||||
- rp2350
|
||||
- stm32
|
||||
target:
|
||||
type: string
|
||||
required: false
|
||||
description: Choose the target board, e.g. nrf52_promicro_diy_tcxo. If blank, will find available targets.
|
||||
# find-target:
|
||||
# type: boolean
|
||||
# default: true
|
||||
# description: 'Find the available targets'
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
find-targets:
|
||||
if: ${{ inputs.target == '' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch:
|
||||
- esp32
|
||||
- esp32s3
|
||||
- esp32c3
|
||||
- esp32c6
|
||||
- nrf52840
|
||||
- rp2040
|
||||
- rp2350
|
||||
- stm32
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.x
|
||||
cache: pip
|
||||
- run: pip install -U platformio
|
||||
- name: Generate matrix
|
||||
id: jsonStep
|
||||
run: |
|
||||
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} --level extra)
|
||||
echo "Name: $GITHUB_REF_NAME" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Base: $GITHUB_BASE_REF" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Arch: ${{matrix.arch}}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Ref: $GITHUB_REF" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Targets:" >> $GITHUB_STEP_SUMMARY
|
||||
echo $TARGETS | jq -r 'sort_by(.board) |.[] | "- " + .board' >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
version:
|
||||
if: ${{ inputs.target != '' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Get release version string
|
||||
run: |
|
||||
echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
echo "deb=$(./bin/buildinfo.py deb)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
env:
|
||||
BUILD_LOCATION: local
|
||||
outputs:
|
||||
long: ${{ steps.version.outputs.long }}
|
||||
deb: ${{ steps.version.outputs.deb }}
|
||||
|
||||
build:
|
||||
if: ${{ inputs.target != '' && inputs.arch != 'native' }}
|
||||
needs: [version]
|
||||
uses: ./.github/workflows/build_firmware.yml
|
||||
with:
|
||||
version: ${{ needs.version.outputs.long }}
|
||||
pio_env: ${{ inputs.target }}
|
||||
platform: ${{ inputs.arch }}
|
||||
|
||||
gather-artifacts:
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
needs: [version, build]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
with:
|
||||
path: ./
|
||||
pattern: firmware-*-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Display structure of downloaded files
|
||||
run: ls -R
|
||||
|
||||
- name: Move files up
|
||||
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
|
||||
|
||||
- name: Repackage in single firmware zip
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: firmware-${{inputs.target}}-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
path: |
|
||||
./firmware-*.bin
|
||||
./firmware-*.uf2
|
||||
./firmware-*.hex
|
||||
./firmware-*-ota.zip
|
||||
./device-*.sh
|
||||
./device-*.bat
|
||||
./littlefs-*.bin
|
||||
./bleota*bin
|
||||
./Meshtastic_nRF52_factory_erase*.uf2
|
||||
retention-days: 30
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
with:
|
||||
pattern: firmware-*-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
path: ./output
|
||||
|
||||
# For diagnostics
|
||||
- name: Show artifacts
|
||||
run: ls -lR
|
||||
|
||||
- name: Device scripts permissions
|
||||
run: |
|
||||
chmod +x ./output/device-install.sh
|
||||
chmod +x ./output/device-update.sh
|
||||
|
||||
- name: Zip firmware
|
||||
run: zip -j -9 -r ./firmware-${{inputs.target}}-${{ needs.version.outputs.long }}.zip ./output
|
||||
|
||||
- name: Repackage in single elfs zip
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: debug-elfs-${{inputs.target}}-${{ needs.version.outputs.long }}.zip
|
||||
overwrite: true
|
||||
path: ./*.elf
|
||||
retention-days: 30
|
||||
|
||||
- uses: scruplelesswizard/comment-artifact@main
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
with:
|
||||
name: firmware-${{inputs.target}}-${{ needs.version.outputs.long }}
|
||||
description: "Download firmware-${{inputs.target}}-${{ needs.version.outputs.long }}.zip. This artifact will be available for 90 days from creation"
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
8
.github/workflows/daily_packaging.yml
vendored
8
.github/workflows/daily_packaging.yml
vendored
@@ -21,20 +21,18 @@ permissions:
|
||||
|
||||
jobs:
|
||||
docker-multiarch:
|
||||
if: github.repository == 'meshtastic/firmware'
|
||||
uses: ./.github/workflows/docker_manifest.yml
|
||||
with:
|
||||
release_channel: daily
|
||||
secrets: inherit
|
||||
|
||||
package-ppa:
|
||||
if: github.repository == 'meshtastic/firmware'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
series:
|
||||
- jammy # 22.04 LTS
|
||||
- noble # 24.04 LTS
|
||||
- jammy # 22.04
|
||||
- noble # 24.04
|
||||
- plucky # 25.04
|
||||
- questing # 25.10
|
||||
uses: ./.github/workflows/package_ppa.yml
|
||||
@@ -44,7 +42,6 @@ jobs:
|
||||
secrets: inherit
|
||||
|
||||
package-obs:
|
||||
if: github.repository == 'meshtastic/firmware'
|
||||
uses: ./.github/workflows/package_obs.yml
|
||||
with:
|
||||
obs_project: network:Meshtastic:daily
|
||||
@@ -52,7 +49,6 @@ jobs:
|
||||
secrets: inherit
|
||||
|
||||
hook-copr:
|
||||
if: github.repository == 'meshtastic/firmware'
|
||||
uses: ./.github/workflows/hook_copr.yml
|
||||
with:
|
||||
copr_project: daily
|
||||
|
||||
2
.github/workflows/docker_build.yml
vendored
2
.github/workflows/docker_build.yml
vendored
@@ -47,7 +47,7 @@ jobs:
|
||||
runs-on: ${{ inputs.runs-on }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: recursive
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
|
||||
2
.github/workflows/docker_manifest.yml
vendored
2
.github/workflows/docker_manifest.yml
vendored
@@ -83,7 +83,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: recursive
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
|
||||
2
.github/workflows/hook_copr.yml
vendored
2
.github/workflows/hook_copr.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: recursive
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
240
.github/workflows/main_matrix.yml
vendored
240
.github/workflows/main_matrix.yml
vendored
@@ -28,14 +28,21 @@ on:
|
||||
jobs:
|
||||
setup:
|
||||
strategy:
|
||||
fail-fast: true
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch:
|
||||
- all
|
||||
- esp32
|
||||
- esp32s3
|
||||
- esp32c3
|
||||
- esp32c6
|
||||
- nrf52840
|
||||
- rp2040
|
||||
- rp2350
|
||||
- stm32
|
||||
- check
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.x
|
||||
@@ -47,19 +54,25 @@ jobs:
|
||||
if [[ "$GITHUB_HEAD_REF" == "" ]]; then
|
||||
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}})
|
||||
else
|
||||
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} --level pr)
|
||||
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} pr)
|
||||
fi
|
||||
echo "Name: $GITHUB_REF_NAME Base: $GITHUB_BASE_REF Ref: $GITHUB_REF"
|
||||
echo "${{matrix.arch}}=$TARGETS" >> $GITHUB_OUTPUT
|
||||
echo "$TARGETS" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Name: $GITHUB_REF_NAME Base: $GITHUB_BASE_REF Ref: $GITHUB_REF Targets: $TARGETS"
|
||||
echo "${{matrix.arch}}=$(jq -cn --argjson environments "$TARGETS" '{board: $environments}')" >> $GITHUB_OUTPUT
|
||||
outputs:
|
||||
all: ${{ steps.jsonStep.outputs.all }}
|
||||
esp32: ${{ steps.jsonStep.outputs.esp32 }}
|
||||
esp32s3: ${{ steps.jsonStep.outputs.esp32s3 }}
|
||||
esp32c3: ${{ steps.jsonStep.outputs.esp32c3 }}
|
||||
esp32c6: ${{ steps.jsonStep.outputs.esp32c6 }}
|
||||
nrf52840: ${{ steps.jsonStep.outputs.nrf52840 }}
|
||||
rp2040: ${{ steps.jsonStep.outputs.rp2040 }}
|
||||
rp2350: ${{ steps.jsonStep.outputs.rp2350 }}
|
||||
stm32: ${{ steps.jsonStep.outputs.stm32 }}
|
||||
check: ${{ steps.jsonStep.outputs.check }}
|
||||
|
||||
version:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
- name: Get release version string
|
||||
run: |
|
||||
echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
@@ -75,30 +88,105 @@ jobs:
|
||||
needs: setup
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
check: ${{ fromJson(needs.setup.outputs.check) }}
|
||||
matrix: ${{ fromJson(needs.setup.outputs.check) }}
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name != 'workflow_dispatch' && github.repository == 'meshtastic/firmware' }}
|
||||
if: ${{ github.event_name != 'workflow_dispatch' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
- name: Build base
|
||||
id: base
|
||||
uses: ./.github/actions/setup-base
|
||||
- name: Check ${{ matrix.check.board }}
|
||||
run: bin/check-all.sh ${{ matrix.check.board }}
|
||||
- name: Check ${{ matrix.board }}
|
||||
run: bin/check-all.sh ${{ matrix.board }}
|
||||
|
||||
build:
|
||||
build-esp32:
|
||||
needs: [setup, version]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
build: ${{ fromJson(needs.setup.outputs.all) }}
|
||||
matrix: ${{ fromJson(needs.setup.outputs.esp32) }}
|
||||
uses: ./.github/workflows/build_firmware.yml
|
||||
with:
|
||||
version: ${{ needs.version.outputs.long }}
|
||||
pio_env: ${{ matrix.build.board }}
|
||||
platform: ${{ matrix.build.platform }}
|
||||
pio_env: ${{ matrix.board }}
|
||||
platform: esp32
|
||||
|
||||
build-esp32s3:
|
||||
needs: [setup, version]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix: ${{ fromJson(needs.setup.outputs.esp32s3) }}
|
||||
uses: ./.github/workflows/build_firmware.yml
|
||||
with:
|
||||
version: ${{ needs.version.outputs.long }}
|
||||
pio_env: ${{ matrix.board }}
|
||||
platform: esp32s3
|
||||
|
||||
build-esp32c3:
|
||||
needs: [setup, version]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix: ${{ fromJson(needs.setup.outputs.esp32c3) }}
|
||||
uses: ./.github/workflows/build_firmware.yml
|
||||
with:
|
||||
version: ${{ needs.version.outputs.long }}
|
||||
pio_env: ${{ matrix.board }}
|
||||
platform: esp32c3
|
||||
|
||||
build-esp32c6:
|
||||
needs: [setup, version]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix: ${{ fromJson(needs.setup.outputs.esp32c6) }}
|
||||
uses: ./.github/workflows/build_firmware.yml
|
||||
with:
|
||||
version: ${{ needs.version.outputs.long }}
|
||||
pio_env: ${{ matrix.board }}
|
||||
platform: esp32c6
|
||||
|
||||
build-nrf52840:
|
||||
needs: [setup, version]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix: ${{ fromJson(needs.setup.outputs.nrf52840) }}
|
||||
uses: ./.github/workflows/build_firmware.yml
|
||||
with:
|
||||
version: ${{ needs.version.outputs.long }}
|
||||
pio_env: ${{ matrix.board }}
|
||||
platform: nrf52840
|
||||
|
||||
build-rp2040:
|
||||
needs: [setup, version]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix: ${{ fromJson(needs.setup.outputs.rp2040) }}
|
||||
uses: ./.github/workflows/build_firmware.yml
|
||||
with:
|
||||
version: ${{ needs.version.outputs.long }}
|
||||
pio_env: ${{ matrix.board }}
|
||||
platform: rp2040
|
||||
|
||||
build-rp2350:
|
||||
needs: [setup, version]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix: ${{ fromJson(needs.setup.outputs.rp2350) }}
|
||||
uses: ./.github/workflows/build_firmware.yml
|
||||
with:
|
||||
version: ${{ needs.version.outputs.long }}
|
||||
pio_env: ${{ matrix.board }}
|
||||
platform: rp2350
|
||||
|
||||
build-stm32:
|
||||
needs: [setup, version]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix: ${{ fromJson(needs.setup.outputs.stm32) }}
|
||||
uses: ./.github/workflows/build_firmware.yml
|
||||
with:
|
||||
version: ${{ needs.version.outputs.long }}
|
||||
pio_env: ${{ matrix.board }}
|
||||
platform: stm32
|
||||
|
||||
build-debian-src:
|
||||
if: github.repository == 'meshtastic/firmware'
|
||||
@@ -109,41 +197,68 @@ jobs:
|
||||
secrets: inherit
|
||||
|
||||
package-pio-deps-native-tft:
|
||||
if: ${{ github.repository == 'meshtastic/firmware' && github.event_name == 'workflow_dispatch' }}
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
uses: ./.github/workflows/package_pio_deps.yml
|
||||
with:
|
||||
pio_env: native-tft
|
||||
secrets: inherit
|
||||
|
||||
test-native:
|
||||
if: ${{ !contains(github.ref_name, 'event/') && github.repository == 'meshtastic/firmware' }}
|
||||
if: ${{ !contains(github.ref_name, 'event/') }}
|
||||
uses: ./.github/workflows/test_native.yml
|
||||
|
||||
docker:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
distro: [debian, alpine]
|
||||
platform: [linux/amd64, linux/arm64, linux/arm/v7]
|
||||
pio_env: [native, native-tft]
|
||||
exclude:
|
||||
- distro: alpine
|
||||
platform: linux/arm/v7
|
||||
- pio_env: native-tft
|
||||
platform: linux/arm64
|
||||
- pio_env: native-tft
|
||||
platform: linux/arm/v7
|
||||
docker-deb-amd64:
|
||||
uses: ./.github/workflows/docker_build.yml
|
||||
with:
|
||||
distro: ${{ matrix.distro }}
|
||||
platform: ${{ matrix.platform }}
|
||||
runs-on: ${{ contains(matrix.platform, 'arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }}
|
||||
pio_env: ${{ matrix.pio_env }}
|
||||
distro: debian
|
||||
platform: linux/amd64
|
||||
runs-on: ubuntu-24.04
|
||||
push: false
|
||||
|
||||
docker-deb-amd64-tft:
|
||||
uses: ./.github/workflows/docker_build.yml
|
||||
with:
|
||||
distro: debian
|
||||
platform: linux/amd64
|
||||
runs-on: ubuntu-24.04
|
||||
push: false
|
||||
pio_env: native-tft
|
||||
|
||||
docker-alp-amd64:
|
||||
uses: ./.github/workflows/docker_build.yml
|
||||
with:
|
||||
distro: alpine
|
||||
platform: linux/amd64
|
||||
runs-on: ubuntu-24.04
|
||||
push: false
|
||||
|
||||
docker-alp-amd64-tft:
|
||||
uses: ./.github/workflows/docker_build.yml
|
||||
with:
|
||||
distro: alpine
|
||||
platform: linux/amd64
|
||||
runs-on: ubuntu-24.04
|
||||
push: false
|
||||
pio_env: native-tft
|
||||
|
||||
docker-deb-arm64:
|
||||
uses: ./.github/workflows/docker_build.yml
|
||||
with:
|
||||
distro: debian
|
||||
platform: linux/arm64
|
||||
runs-on: ubuntu-24.04-arm
|
||||
push: false
|
||||
|
||||
docker-deb-armv7:
|
||||
uses: ./.github/workflows/docker_build.yml
|
||||
with:
|
||||
distro: debian
|
||||
platform: linux/arm/v7
|
||||
runs-on: ubuntu-24.04-arm
|
||||
push: false
|
||||
|
||||
gather-artifacts:
|
||||
# trunk-ignore(checkov/CKV2_GHA_1)
|
||||
if: github.repository == 'meshtastic/firmware'
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
@@ -160,15 +275,26 @@ jobs:
|
||||
- rp2350
|
||||
- stm32
|
||||
runs-on: ubuntu-latest
|
||||
needs: [version, build]
|
||||
needs:
|
||||
[
|
||||
version,
|
||||
build-esp32,
|
||||
build-esp32s3,
|
||||
build-esp32c3,
|
||||
build-esp32c6,
|
||||
build-nrf52840,
|
||||
build-rp2040,
|
||||
build-rp2350,
|
||||
build-stm32,
|
||||
]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
path: ./
|
||||
pattern: firmware-${{matrix.arch}}-*
|
||||
@@ -181,7 +307,7 @@ jobs:
|
||||
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
|
||||
|
||||
- name: Repackage in single firmware zip
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
@@ -197,7 +323,7 @@ jobs:
|
||||
./Meshtastic_nRF52_factory_erase*.uf2
|
||||
retention-days: 30
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -216,7 +342,7 @@ jobs:
|
||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
||||
|
||||
- name: Repackage in single elfs zip
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip
|
||||
overwrite: true
|
||||
@@ -232,7 +358,7 @@ jobs:
|
||||
|
||||
release-artifacts:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.repository == 'meshtastic/firmware' }}
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
outputs:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
needs:
|
||||
@@ -242,7 +368,7 @@ jobs:
|
||||
- package-pio-deps-native-tft
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
@@ -261,14 +387,14 @@ jobs:
|
||||
Autogenerated by github action, developer should edit as required before publishing...
|
||||
|
||||
- name: Download source deb
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src
|
||||
merge-multiple: true
|
||||
path: ./output/debian-src
|
||||
|
||||
- name: Download `native-tft` pio deps
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -307,18 +433,18 @@ jobs:
|
||||
- rp2350
|
||||
- stm32
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.repository == 'meshtastic/firmware'}}
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
needs: [release-artifacts, version]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -335,7 +461,7 @@ jobs:
|
||||
- name: Zip firmware
|
||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip
|
||||
merge-multiple: true
|
||||
@@ -366,14 +492,14 @@ jobs:
|
||||
esp32,esp32s3,esp32c3,esp32c6,nrf52840,rp2040,rp2350,stm32
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
|
||||
238
.github/workflows/merge_queue.yml
vendored
238
.github/workflows/merge_queue.yml
vendored
@@ -7,18 +7,28 @@ on:
|
||||
# Merge group is a special trigger that is used to trigger the workflow when a merge group is created.
|
||||
merge_group:
|
||||
|
||||
env:
|
||||
FAIL_FAST_PER_ARCH: true
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
arch:
|
||||
- all
|
||||
- esp32
|
||||
- esp32s3
|
||||
- esp32c3
|
||||
- esp32c6
|
||||
- nrf52840
|
||||
- rp2040
|
||||
- rp2350
|
||||
- stm32
|
||||
- check
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-python@v6
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
cache: pip
|
||||
@@ -29,18 +39,25 @@ jobs:
|
||||
if [[ "$GITHUB_HEAD_REF" == "" ]]; then
|
||||
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}})
|
||||
else
|
||||
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} --level pr)
|
||||
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} pr)
|
||||
fi
|
||||
echo "Name: $GITHUB_REF_NAME Base: $GITHUB_BASE_REF Ref: $GITHUB_REF"
|
||||
echo "${{matrix.arch}}=$TARGETS" >> $GITHUB_OUTPUT
|
||||
echo "Name: $GITHUB_REF_NAME Base: $GITHUB_BASE_REF Ref: $GITHUB_REF Targets: $TARGETS"
|
||||
echo "${{matrix.arch}}=$(jq -cn --argjson environments "$TARGETS" '{board: $environments}')" >> $GITHUB_OUTPUT
|
||||
outputs:
|
||||
all: ${{ steps.jsonStep.outputs.all }}
|
||||
esp32: ${{ steps.jsonStep.outputs.esp32 }}
|
||||
esp32s3: ${{ steps.jsonStep.outputs.esp32s3 }}
|
||||
esp32c3: ${{ steps.jsonStep.outputs.esp32c3 }}
|
||||
esp32c6: ${{ steps.jsonStep.outputs.esp32c6 }}
|
||||
nrf52840: ${{ steps.jsonStep.outputs.nrf52840 }}
|
||||
rp2040: ${{ steps.jsonStep.outputs.rp2040 }}
|
||||
rp2350: ${{ steps.jsonStep.outputs.rp2350 }}
|
||||
stm32: ${{ steps.jsonStep.outputs.stm32 }}
|
||||
check: ${{ steps.jsonStep.outputs.check }}
|
||||
|
||||
version:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Get release version string
|
||||
run: |
|
||||
echo "long=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
@@ -56,29 +73,105 @@ jobs:
|
||||
needs: setup
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
check: ${{ fromJson(needs.setup.outputs.check) }}
|
||||
matrix: ${{ fromJson(needs.setup.outputs.check) }}
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name != 'workflow_dispatch' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build base
|
||||
id: base
|
||||
uses: ./.github/actions/setup-base
|
||||
- name: Check ${{ matrix.check.board }}
|
||||
run: bin/check-all.sh ${{ matrix.check.board }}
|
||||
- name: Check ${{ matrix.board }}
|
||||
run: bin/check-all.sh ${{ matrix.board }}
|
||||
|
||||
build:
|
||||
build-esp32:
|
||||
needs: [setup, version]
|
||||
strategy:
|
||||
matrix:
|
||||
build: ${{ fromJson(needs.setup.outputs.all) }}
|
||||
fail-fast: ${{ vars.FAIL_FAST_PER_ARCH == true }}
|
||||
matrix: ${{ fromJson(needs.setup.outputs.esp32) }}
|
||||
uses: ./.github/workflows/build_firmware.yml
|
||||
with:
|
||||
version: ${{ needs.version.outputs.long }}
|
||||
pio_env: ${{ matrix.build.board }}
|
||||
platform: ${{ matrix.build.platform }}
|
||||
pio_env: ${{ matrix.board }}
|
||||
platform: esp32
|
||||
|
||||
build-esp32s3:
|
||||
needs: [setup, version]
|
||||
strategy:
|
||||
fail-fast: ${{ vars.FAIL_FAST_PER_ARCH == true }}
|
||||
matrix: ${{ fromJson(needs.setup.outputs.esp32s3) }}
|
||||
uses: ./.github/workflows/build_firmware.yml
|
||||
with:
|
||||
version: ${{ needs.version.outputs.long }}
|
||||
pio_env: ${{ matrix.board }}
|
||||
platform: esp32s3
|
||||
|
||||
build-esp32c3:
|
||||
needs: [setup, version]
|
||||
strategy:
|
||||
fail-fast: ${{ vars.FAIL_FAST_PER_ARCH == true }}
|
||||
matrix: ${{ fromJson(needs.setup.outputs.esp32c3) }}
|
||||
uses: ./.github/workflows/build_firmware.yml
|
||||
with:
|
||||
version: ${{ needs.version.outputs.long }}
|
||||
pio_env: ${{ matrix.board }}
|
||||
platform: esp32c3
|
||||
|
||||
build-esp32c6:
|
||||
needs: [setup, version]
|
||||
strategy:
|
||||
fail-fast: ${{ vars.FAIL_FAST_PER_ARCH == true }}
|
||||
matrix: ${{ fromJson(needs.setup.outputs.esp32c6) }}
|
||||
uses: ./.github/workflows/build_firmware.yml
|
||||
with:
|
||||
version: ${{ needs.version.outputs.long }}
|
||||
pio_env: ${{ matrix.board }}
|
||||
platform: esp32c6
|
||||
|
||||
build-nrf52840:
|
||||
needs: [setup, version]
|
||||
strategy:
|
||||
fail-fast: ${{ vars.FAIL_FAST_PER_ARCH == true }}
|
||||
matrix: ${{ fromJson(needs.setup.outputs.nrf52840) }}
|
||||
uses: ./.github/workflows/build_firmware.yml
|
||||
with:
|
||||
version: ${{ needs.version.outputs.long }}
|
||||
pio_env: ${{ matrix.board }}
|
||||
platform: nrf52840
|
||||
|
||||
build-rp2040:
|
||||
needs: [setup, version]
|
||||
strategy:
|
||||
fail-fast: ${{ vars.FAIL_FAST_PER_ARCH == true }}
|
||||
matrix: ${{ fromJson(needs.setup.outputs.rp2040) }}
|
||||
uses: ./.github/workflows/build_firmware.yml
|
||||
with:
|
||||
version: ${{ needs.version.outputs.long }}
|
||||
pio_env: ${{ matrix.board }}
|
||||
platform: rp2040
|
||||
|
||||
build-rp2350:
|
||||
needs: [setup, version]
|
||||
strategy:
|
||||
fail-fast: ${{ vars.FAIL_FAST_PER_ARCH == true }}
|
||||
matrix: ${{ fromJson(needs.setup.outputs.rp2350) }}
|
||||
uses: ./.github/workflows/build_firmware.yml
|
||||
with:
|
||||
version: ${{ needs.version.outputs.long }}
|
||||
pio_env: ${{ matrix.board }}
|
||||
platform: rp2350
|
||||
|
||||
build-stm32:
|
||||
needs: [setup, version]
|
||||
strategy:
|
||||
fail-fast: ${{ vars.FAIL_FAST_PER_ARCH == true }}
|
||||
matrix: ${{ fromJson(needs.setup.outputs.stm32) }}
|
||||
uses: ./.github/workflows/build_firmware.yml
|
||||
with:
|
||||
version: ${{ needs.version.outputs.long }}
|
||||
pio_env: ${{ matrix.board }}
|
||||
platform: stm32
|
||||
|
||||
build-debian-src:
|
||||
if: github.repository == 'meshtastic/firmware'
|
||||
@@ -99,26 +192,54 @@ jobs:
|
||||
if: ${{ !contains(github.ref_name, 'event/') }}
|
||||
uses: ./.github/workflows/test_native.yml
|
||||
|
||||
docker:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
distro: [debian, alpine]
|
||||
platform: [linux/amd64, linux/arm64, linux/arm/v7]
|
||||
pio_env: [native, native-tft]
|
||||
exclude:
|
||||
- distro: alpine
|
||||
platform: linux/arm/v7
|
||||
- pio_env: native-tft
|
||||
platform: linux/arm64
|
||||
- pio_env: native-tft
|
||||
platform: linux/arm/v7
|
||||
docker-deb-amd64:
|
||||
uses: ./.github/workflows/docker_build.yml
|
||||
with:
|
||||
distro: ${{ matrix.distro }}
|
||||
platform: ${{ matrix.platform }}
|
||||
runs-on: ${{ contains(matrix.platform, 'arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }}
|
||||
pio_env: ${{ matrix.pio_env }}
|
||||
distro: debian
|
||||
platform: linux/amd64
|
||||
runs-on: ubuntu-24.04
|
||||
push: false
|
||||
|
||||
docker-deb-amd64-tft:
|
||||
uses: ./.github/workflows/docker_build.yml
|
||||
with:
|
||||
distro: debian
|
||||
platform: linux/amd64
|
||||
runs-on: ubuntu-24.04
|
||||
push: false
|
||||
pio_env: native-tft
|
||||
|
||||
docker-alp-amd64:
|
||||
uses: ./.github/workflows/docker_build.yml
|
||||
with:
|
||||
distro: alpine
|
||||
platform: linux/amd64
|
||||
runs-on: ubuntu-24.04
|
||||
push: false
|
||||
|
||||
docker-alp-amd64-tft:
|
||||
uses: ./.github/workflows/docker_build.yml
|
||||
with:
|
||||
distro: alpine
|
||||
platform: linux/amd64
|
||||
runs-on: ubuntu-24.04
|
||||
push: false
|
||||
pio_env: native-tft
|
||||
|
||||
docker-deb-arm64:
|
||||
uses: ./.github/workflows/docker_build.yml
|
||||
with:
|
||||
distro: debian
|
||||
platform: linux/arm64
|
||||
runs-on: ubuntu-24.04-arm
|
||||
push: false
|
||||
|
||||
docker-deb-armv7:
|
||||
uses: ./.github/workflows/docker_build.yml
|
||||
with:
|
||||
distro: debian
|
||||
platform: linux/arm/v7
|
||||
runs-on: ubuntu-24.04-arm
|
||||
push: false
|
||||
|
||||
gather-artifacts:
|
||||
@@ -139,15 +260,26 @@ jobs:
|
||||
- rp2350
|
||||
- stm32
|
||||
runs-on: ubuntu-latest
|
||||
needs: [version, build]
|
||||
needs:
|
||||
[
|
||||
version,
|
||||
build-esp32,
|
||||
build-esp32s3,
|
||||
build-esp32c3,
|
||||
build-esp32c6,
|
||||
build-nrf52840,
|
||||
build-rp2040,
|
||||
build-rp2350,
|
||||
build-stm32,
|
||||
]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: ./
|
||||
pattern: firmware-${{matrix.arch}}-*
|
||||
@@ -160,7 +292,7 @@ jobs:
|
||||
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
|
||||
|
||||
- name: Repackage in single firmware zip
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
overwrite: true
|
||||
@@ -176,7 +308,7 @@ jobs:
|
||||
./Meshtastic_nRF52_factory_erase*.uf2
|
||||
retention-days: 30
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -195,7 +327,7 @@ jobs:
|
||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
||||
|
||||
- name: Repackage in single elfs zip
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip
|
||||
overwrite: true
|
||||
@@ -221,10 +353,10 @@ jobs:
|
||||
- package-pio-deps-native-tft
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
@@ -240,14 +372,14 @@ jobs:
|
||||
Autogenerated by github action, developer should edit as required before publishing...
|
||||
|
||||
- name: Download source deb
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: firmware-debian-${{ needs.version.outputs.deb }}~UNRELEASED-src
|
||||
merge-multiple: true
|
||||
path: ./output/debian-src
|
||||
|
||||
- name: Download `native-tft` pio deps
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: platformio-deps-native-tft-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -290,14 +422,14 @@ jobs:
|
||||
needs: [release-artifacts, version]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
@@ -314,7 +446,7 @@ jobs:
|
||||
- name: Zip firmware
|
||||
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip ./output
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: debug-elfs-${{matrix.arch}}-${{ needs.version.outputs.long }}.zip
|
||||
merge-multiple: true
|
||||
@@ -345,14 +477,14 @@ jobs:
|
||||
esp32,esp32s3,esp32c3,esp32c6,nrf52840,rp2040,rp2350,stm32
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: firmware-{${{ env.targets }}}-${{ needs.version.outputs.long }}
|
||||
merge-multiple: true
|
||||
|
||||
4
.github/workflows/nightly.yml
vendored
4
.github/workflows/nightly.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Trunk Check
|
||||
uses: trunk-io/trunk-action@v1
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
pull-requests: write # For trunk to create PRs
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Trunk Upgrade
|
||||
uses: trunk-io/trunk-action/upgrade@v1
|
||||
|
||||
4
.github/workflows/package_obs.yml
vendored
4
.github/workflows/package_obs.yml
vendored
@@ -34,7 +34,7 @@ jobs:
|
||||
needs: build-debian-src
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: recursive
|
||||
path: meshtasticd
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
id: version
|
||||
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||
merge-multiple: true
|
||||
|
||||
4
.github/workflows/package_pio_deps.yml
vendored
4
.github/workflows/package_pio_deps.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: recursive
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
@@ -56,7 +56,7 @@ jobs:
|
||||
PLATFORMIO_CORE_DIR: pio/core
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: platformio-deps-${{ inputs.pio_env }}-${{ steps.version.outputs.long }}
|
||||
overwrite: true
|
||||
|
||||
4
.github/workflows/package_ppa.yml
vendored
4
.github/workflows/package_ppa.yml
vendored
@@ -32,7 +32,7 @@ jobs:
|
||||
needs: build-debian-src
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: recursive
|
||||
path: meshtasticd
|
||||
@@ -60,7 +60,7 @@ jobs:
|
||||
id: version
|
||||
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: firmware-debian-${{ steps.version.outputs.deb }}~${{ inputs.series }}-src
|
||||
merge-multiple: true
|
||||
|
||||
2
.github/workflows/pr_enforce_labels.yml
vendored
2
.github/workflows/pr_enforce_labels.yml
vendored
@@ -10,7 +10,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
check-label:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Check for PR labels
|
||||
uses: actions/github-script@v8
|
||||
|
||||
4
.github/workflows/pr_tests.yml
vendored
4
.github/workflows/pr_tests.yml
vendored
@@ -40,7 +40,7 @@ jobs:
|
||||
checks: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
|
||||
- name: Download test artifacts
|
||||
if: needs.native-tests.result != 'skipped'
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: platformio-test-report-${{ steps.version.outputs.long }}.zip
|
||||
merge-multiple: true
|
||||
|
||||
11
.github/workflows/release_channels.yml
vendored
11
.github/workflows/release_channels.yml
vendored
@@ -21,10 +21,10 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
series:
|
||||
- jammy # 22.04 LTS
|
||||
- noble # 24.04 LTS
|
||||
- jammy # 22.04
|
||||
- noble # 24.04
|
||||
- plucky # 25.04
|
||||
- questing # 25.10
|
||||
# - questing # 25.10
|
||||
uses: ./.github/workflows/package_ppa.yml
|
||||
with:
|
||||
ppa_repo: |-
|
||||
@@ -60,10 +60,7 @@ jobs:
|
||||
shell: bash
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
# Always use master branch for version bumps
|
||||
ref: master
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
|
||||
6
.github/workflows/sec_sast_semgrep_cron.yml
vendored
6
.github/workflows/sec_sast_semgrep_cron.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
steps:
|
||||
# step 1
|
||||
- name: clone application source code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
# step 2
|
||||
- name: full scan
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
|
||||
# step 3
|
||||
- name: save report as pipeline artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: report.sarif
|
||||
overwrite: true
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
|
||||
# step 4
|
||||
- name: publish code scanning alerts
|
||||
uses: github/codeql-action/upload-sarif@v4
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: report.sarif
|
||||
category: semgrep
|
||||
|
||||
2
.github/workflows/sec_sast_semgrep_pull.yml
vendored
2
.github/workflows/sec_sast_semgrep_pull.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
steps:
|
||||
# step 1
|
||||
- name: clone application source code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
8
.github/workflows/stale_bot.yml
vendored
8
.github/workflows/stale_bot.yml
vendored
@@ -17,10 +17,8 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Stale PR+Issues
|
||||
uses: actions/stale@v10.1.0
|
||||
uses: actions/stale@v10.0.0
|
||||
with:
|
||||
days-before-stale: 45
|
||||
stale-issue-message: This issue has not had any comment or update in the last month. If it is still relevant, please post update comments. If no comments are made, this issue will be closed automagically in 7 days.
|
||||
close-issue-message: This issue has not had any comment since the last notice. It has been closed automatically. If this is incorrect, or the issue becomes relevant again, please request that it is reopened.
|
||||
exempt-issue-labels: pinned,3.0,triaged,backlog
|
||||
exempt-pr-labels: pinned,3.0,triaged,backlog
|
||||
exempt-issue-labels: pinned,3.0
|
||||
exempt-pr-labels: pinned,3.0
|
||||
|
||||
22
.github/workflows/test_native.yml
vendored
22
.github/workflows/test_native.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
name: Native Simulator Tests
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
@@ -40,7 +40,7 @@ jobs:
|
||||
|
||||
- name: Integration test
|
||||
run: |
|
||||
.pio/build/coverage/program -s &
|
||||
.pio/build/coverage/program &
|
||||
PID=$!
|
||||
timeout 20 bash -c "until ls -al /proc/$PID/fd | grep socket; do sleep 1; done"
|
||||
echo "Simulator started, launching python test..."
|
||||
@@ -59,7 +59,7 @@ jobs:
|
||||
id: version
|
||||
|
||||
- name: Save coverage information
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always() # run this step even if previous step failed
|
||||
with:
|
||||
name: lcov-coverage-info-native-simulator-test-${{ steps.version.outputs.long }}.zip
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
name: Native PlatformIO Tests
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
@@ -94,7 +94,7 @@ jobs:
|
||||
|
||||
- name: Save test results
|
||||
if: always() # run this step even if previous step failed
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: platformio-test-report-${{ steps.version.outputs.long }}.zip
|
||||
overwrite: true
|
||||
@@ -108,7 +108,7 @@ jobs:
|
||||
sed -i -e "s#${PWD}#.#" coverage_tests.info # Make paths relative.
|
||||
|
||||
- name: Save coverage information
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always() # run this step even if previous step failed
|
||||
with:
|
||||
name: lcov-coverage-info-native-platformio-tests-${{ steps.version.outputs.long }}.zip
|
||||
@@ -127,7 +127,7 @@ jobs:
|
||||
- platformio-tests
|
||||
if: always()
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
@@ -137,20 +137,20 @@ jobs:
|
||||
id: version
|
||||
|
||||
- name: Download test artifacts
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: platformio-test-report-${{ steps.version.outputs.long }}.zip
|
||||
merge-multiple: true
|
||||
|
||||
- name: Test Report
|
||||
uses: dorny/test-reporter@v2.3.0
|
||||
uses: dorny/test-reporter@v2.1.1
|
||||
with:
|
||||
name: PlatformIO Tests
|
||||
path: testreport.xml
|
||||
reporter: java-junit
|
||||
|
||||
- name: Download coverage artifacts
|
||||
uses: actions/download-artifact@v6
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
pattern: lcov-coverage-info-native-*-${{ steps.version.outputs.long }}.zip
|
||||
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
|
||||
|
||||
- name: Save Code Coverage Report
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: code-coverage-report-${{ steps.version.outputs.long }}.zip
|
||||
path: code-coverage-report
|
||||
|
||||
6
.github/workflows/tests.yml
vendored
6
.github/workflows/tests.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
runs-on: test-runner
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
# - uses: actions/setup-python@v5
|
||||
# with:
|
||||
@@ -47,9 +47,9 @@ jobs:
|
||||
pio upgrade
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v6
|
||||
uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: 24
|
||||
node-version: 22
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
2
.github/workflows/trunk_annotate_pr.yml
vendored
2
.github/workflows/trunk_annotate_pr.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Trunk Check
|
||||
uses: trunk-io/trunk-action@v1
|
||||
|
||||
2
.github/workflows/trunk_check.yml
vendored
2
.github/workflows/trunk_check.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Trunk Check
|
||||
uses: trunk-io/trunk-action@v1
|
||||
|
||||
2
.github/workflows/trunk_format_pr.yml
vendored
2
.github/workflows/trunk_format_pr.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
2
.github/workflows/update_protobufs.yml
vendored
2
.github/workflows/update_protobufs.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -39,5 +39,14 @@ release/
|
||||
src/mesh/raspihttp/certificate.pem
|
||||
src/mesh/raspihttp/private_key.pem
|
||||
|
||||
# pioarduino platform
|
||||
managed_components/*
|
||||
arduino-lib-builder*
|
||||
dependencies.lock
|
||||
idf_component.yml
|
||||
CMakeLists.txt
|
||||
sdkconfig.*
|
||||
.dummy/*
|
||||
|
||||
# Ignore logo (set at build time with platformio-custom.py)
|
||||
data/boot/logo.*
|
||||
|
||||
@@ -4,31 +4,31 @@ cli:
|
||||
plugins:
|
||||
sources:
|
||||
- id: trunk
|
||||
ref: v1.7.4
|
||||
ref: v1.7.2
|
||||
uri: https://github.com/trunk-io/plugins
|
||||
lint:
|
||||
enabled:
|
||||
- checkov@3.2.495
|
||||
- renovate@42.27.1
|
||||
- prettier@3.7.3
|
||||
- trufflehog@3.91.1
|
||||
- checkov@3.2.471
|
||||
- renovate@41.115.2
|
||||
- prettier@3.6.2
|
||||
- trufflehog@3.90.6
|
||||
- yamllint@1.37.1
|
||||
- bandit@1.9.2
|
||||
- trivy@0.67.2
|
||||
- bandit@1.8.6
|
||||
- trivy@0.66.0
|
||||
- taplo@0.10.0
|
||||
- ruff@0.14.7
|
||||
- isort@7.0.0
|
||||
- markdownlint@0.46.0
|
||||
- ruff@0.13.0
|
||||
- isort@6.0.1
|
||||
- markdownlint@0.45.0
|
||||
- oxipng@9.1.5
|
||||
- svgo@4.0.0
|
||||
- actionlint@1.7.9
|
||||
- actionlint@1.7.7
|
||||
- flake8@7.3.0
|
||||
- hadolint@2.14.0
|
||||
- hadolint@2.13.1
|
||||
- shfmt@3.6.0
|
||||
- shellcheck@0.11.0
|
||||
- black@25.11.0
|
||||
- black@25.1.0
|
||||
- git-diff-check
|
||||
- gitleaks@8.30.0
|
||||
- gitleaks@8.28.0
|
||||
- clang-format@16.0.3
|
||||
ignore:
|
||||
- linters: [ALL]
|
||||
|
||||
6
8MB_no_ota.csv
Normal file
6
8MB_no_ota.csv
Normal file
@@ -0,0 +1,6 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
nvs, data, nvs, 0x9000, 0x5000,
|
||||
otadata, data, ota, 0xe000, 0x2000,
|
||||
app0, app, ota_0, 0x10000, 0x660000,
|
||||
spiffs, data, spiffs, 0x670000,0x180000,
|
||||
coredump, data, coredump,0x7F0000,0x10000,
|
||||
|
@@ -3,7 +3,7 @@
|
||||
# trunk-ignore-all(hadolint/DL3008): Do not pin apt package versions
|
||||
# trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions
|
||||
|
||||
FROM python:3.14-slim-trixie AS builder
|
||||
FROM python:3.13-slim-trixie AS builder
|
||||
ARG PIO_ENV=native
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV TZ=Etc/UTC
|
||||
|
||||
@@ -37,3 +37,4 @@ Join our community and help improve Meshtastic! 🚀
|
||||
## Stats
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -3,13 +3,12 @@
|
||||
# trunk-ignore-all(hadolint/DL3018): Do not pin apk package versions
|
||||
# trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions
|
||||
|
||||
FROM python:3.14-alpine3.22 AS builder
|
||||
FROM python:3.13-alpine3.22 AS builder
|
||||
ARG PIO_ENV=native
|
||||
ENV PIP_ROOT_USER_ACTION=ignore
|
||||
|
||||
RUN apk --no-cache add \
|
||||
bash g++ libstdc++-dev linux-headers zip git ca-certificates libbsd-dev \
|
||||
libgpiod-dev yaml-cpp-dev bluez-dev \
|
||||
bash g++ libstdc++-dev linux-headers zip git ca-certificates libgpiod-dev yaml-cpp-dev bluez-dev \
|
||||
libusb-dev i2c-tools-dev libuv-dev openssl-dev pkgconf argp-standalone \
|
||||
libx11-dev libinput-dev libxkbcommon-dev \
|
||||
&& rm -rf /var/cache/apk/* \
|
||||
@@ -41,8 +40,8 @@ LABEL org.opencontainers.image.title="Meshtastic" \
|
||||
USER root
|
||||
|
||||
RUN apk --no-cache add \
|
||||
shadow libstdc++ libbsd libgpiod yaml-cpp libusb \
|
||||
i2c-tools libuv libx11 libinput libxkbcommon \
|
||||
shadow libstdc++ libgpiod yaml-cpp libusb i2c-tools libuv \
|
||||
libx11 libinput libxkbcommon \
|
||||
&& rm -rf /var/cache/apk/* \
|
||||
&& mkdir -p /var/lib/meshtasticd \
|
||||
&& mkdir -p /etc/meshtasticd/config.d \
|
||||
|
||||
@@ -31,13 +31,11 @@ build_flags =
|
||||
-DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL
|
||||
-DAXP_DEBUG_PORT=Serial
|
||||
-DCONFIG_BT_NIMBLE_ENABLED
|
||||
-DCONFIG_BT_NIMBLE_MAX_BONDS=6 # default is 3
|
||||
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
|
||||
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
|
||||
-DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=8192
|
||||
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
|
||||
-DSERIAL_BUFFER_SIZE=4096
|
||||
-DSERIAL_HAS_ON_RECEIVE
|
||||
-DLIBPAX_ARDUINO
|
||||
-DLIBPAX_WIFI
|
||||
-DLIBPAX_BLE
|
||||
@@ -54,10 +52,10 @@ lib_deps =
|
||||
https://github.com/meshtastic/esp32_https_server/archive/3223704846752e6d545139204837bdb2a55459ca.zip
|
||||
# renovate: datasource=custom.pio depName=NimBLE-Arduino packageName=h2zero/library/NimBLE-Arduino
|
||||
h2zero/NimBLE-Arduino@^1.4.3
|
||||
# renovate: datasource=git-refs depName=libpax packageName=https://github.com/dbinfrago/libpax gitBranch=master
|
||||
https://github.com/dbinfrago/libpax/archive/3cdc0371c375676a97967547f4065607d4c53fd1.zip
|
||||
# renovate: datasource=git-refs depName=libpax packageName=https://github.com/mverch67/libpax gitBranch=master
|
||||
https://github.com/mverch67/libpax/archive/6f52ee989301cdabaeef00bcbf93bff55708ce2f.zip
|
||||
# renovate: datasource=github-tags depName=XPowersLib packageName=lewisxhe/XPowersLib
|
||||
https://github.com/lewisxhe/XPowersLib/archive/v0.3.2.zip
|
||||
https://github.com/lewisxhe/XPowersLib/archive/v0.3.0.zip
|
||||
# renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master
|
||||
https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip
|
||||
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto
|
||||
@@ -28,7 +28,7 @@ lib_deps =
|
||||
${environmental_extra.lib_deps}
|
||||
${radiolib_base.lib_deps}
|
||||
# renovate: datasource=custom.pio depName=XPowersLib packageName=lewisxhe/library/XPowersLib
|
||||
lewisxhe/XPowersLib@0.3.2
|
||||
lewisxhe/XPowersLib@0.3.0
|
||||
# renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master
|
||||
https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip
|
||||
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto
|
||||
@@ -7,13 +7,13 @@ extends = arduino_base
|
||||
platform_packages =
|
||||
; our custom Git version until they merge our PR
|
||||
# TODO renovate
|
||||
platformio/framework-arduinoadafruitnrf52 @ https://github.com/meshtastic/Adafruit_nRF52_Arduino#c770c8a16a351b55b86e347a3d9d7b74ad0bbf39
|
||||
platformio/framework-arduinoadafruitnrf52 @ https://github.com/meshtastic/Adafruit_nRF52_Arduino#e13f5820002a4fb2a5e6754b42ace185277e5adf
|
||||
; Don't renovate toolchain-gccarmnoneeabi
|
||||
platformio/toolchain-gccarmnoneeabi@~1.90301.0
|
||||
|
||||
build_type = release
|
||||
build_type = debug
|
||||
build_flags =
|
||||
-include variants/nrf52840/cpp_overrides/lfs_util.h
|
||||
-include arch/nrf52/cpp_overrides/lfs_util.h
|
||||
${arduino_base.build_flags}
|
||||
-DSERIAL_BUFFER_SIZE=1024
|
||||
-Wno-unused-variable
|
||||
@@ -21,17 +21,6 @@ build_flags =
|
||||
-DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818
|
||||
-DMESHTASTIC_EXCLUDE_AUDIO=1
|
||||
-DMESHTASTIC_EXCLUDE_PAXCOUNTER=1
|
||||
-Os
|
||||
build_unflags =
|
||||
-Ofast
|
||||
-Og
|
||||
-ggdb3
|
||||
-ggdb2
|
||||
-g3
|
||||
-g2
|
||||
-g
|
||||
-g1
|
||||
-g0
|
||||
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp> -<serialization/>
|
||||
@@ -8,7 +8,7 @@ lib_deps =
|
||||
${environmental_base.lib_deps}
|
||||
${environmental_extra.lib_deps}
|
||||
# renovate: datasource=git-refs depName=Kongduino-Adafruit_nRFCrypto packageName=https://github.com/Kongduino/Adafruit_nRFCrypto gitBranch=master
|
||||
https://github.com/Kongduino/Adafruit_nRFCrypto/archive/8cde7189b5ead9dcd49f72601b43b969c0bbc06e.zip
|
||||
https://github.com/Kongduino/Adafruit_nRFCrypto/archive/5f838d2709461a2c981f642917aa50254a25c14c.zip
|
||||
|
||||
; Common NRF52 debugging settings follow. See the Meshtastic developer docs for how to connect SWD debugging probes to your board.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
[portduino_base]
|
||||
platform =
|
||||
# renovate: datasource=git-refs depName=platform-native packageName=https://github.com/meshtastic/platform-native gitBranch=develop
|
||||
https://github.com/meshtastic/platform-native/archive/f566d364204416cdbf298e349213f7d551f793d9.zip
|
||||
https://github.com/meshtastic/platform-native/archive/c490bcd019e0658404088a61b96e653c9da22c45.zip
|
||||
framework = arduino
|
||||
|
||||
build_src_filter =
|
||||
@@ -2,7 +2,7 @@
|
||||
extends = arduino_base
|
||||
platform =
|
||||
# renovate: datasource=custom.pio depName=platformio/ststm32 packageName=platformio/platform/ststm32
|
||||
platformio/ststm32@19.4.0
|
||||
platformio/ststm32@19.3.0
|
||||
platform_packages =
|
||||
# TODO renovate
|
||||
platformio/framework-arduinoststm32@https://github.com/stm32duino/Arduino_Core_STM32/archive/2.10.1.zip
|
||||
@@ -37,9 +37,6 @@ build_flags =
|
||||
-DRADIOLIB_EXCLUDE_LR11X0=1
|
||||
-DHAL_DAC_MODULE_ONLY
|
||||
-DHAL_RNG_MODULE_ENABLED
|
||||
-Wl,--wrap=__assert_func
|
||||
-Wl,--wrap=strerror
|
||||
-Wl,--wrap=_tzset_unlocked_r
|
||||
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/RemoteHardwareModule.cpp> -<platform/nrf52> -<platform/portduino> -<platform/rp2xx0> -<mesh/raspihttp>
|
||||
@@ -1,165 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Summarise linker map output to highlight heavy object files and libraries.
|
||||
|
||||
Usage:
|
||||
python bin/analyze_map.py --map .pio/build/rak4631/output.map --top 20
|
||||
|
||||
The script parses GNU ld map files and aggregates section sizes per object file
|
||||
and per archive/library, then prints sortable tables that make it easy to spot
|
||||
modules worth trimming or hiding behind feature flags.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import collections
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from typing import DefaultDict, Dict, Tuple
|
||||
|
||||
|
||||
SECTION_LINE_RE = re.compile(r"^\s+(?P<section>\S+)\s+0x[0-9A-Fa-f]+\s+0x(?P<size>[0-9A-Fa-f]+)\s+(?P<object>.+)$")
|
||||
ARCHIVE_MEMBER_RE = re.compile(r"^(?P<archive>.+)\((?P<object>[^)]+)\)$")
|
||||
|
||||
|
||||
def human_size(num_bytes: int) -> str:
|
||||
"""Return a friendly size string with one decimal place."""
|
||||
if num_bytes < 1024:
|
||||
return f"{num_bytes:,} B"
|
||||
num = float(num_bytes)
|
||||
for unit in ("KB", "MB", "GB"):
|
||||
num /= 1024.0
|
||||
if num < 1024.0:
|
||||
return f"{num:.1f} {unit}"
|
||||
return f"{num:.1f} TB"
|
||||
|
||||
|
||||
def shorten_path(path: str, root: str) -> str:
|
||||
"""Prefer repository-relative paths for readability."""
|
||||
path = path.strip()
|
||||
if not path:
|
||||
return path
|
||||
|
||||
# Normalise Windows archives (backslashes) to POSIX style for consistency.
|
||||
path = path.replace("\\", "/")
|
||||
|
||||
# Attempt to strip the root when an absolute path lives inside the repo.
|
||||
if os.path.isabs(path):
|
||||
try:
|
||||
rel = os.path.relpath(path, root)
|
||||
if not rel.startswith(".."):
|
||||
return rel
|
||||
except ValueError:
|
||||
# relpath can fail on mixed drives on Windows; fall back to basename.
|
||||
pass
|
||||
return path
|
||||
|
||||
|
||||
def describe_object(raw_object: str, root: str) -> Tuple[str, str]:
|
||||
"""Return a human friendly object label and the library it belongs to."""
|
||||
raw_object = raw_object.strip()
|
||||
lib_label = "[app]"
|
||||
match = ARCHIVE_MEMBER_RE.match(raw_object)
|
||||
if match:
|
||||
archive = shorten_path(match.group("archive"), root)
|
||||
obj = match.group("object")
|
||||
lib_label = os.path.basename(archive) or archive
|
||||
label = f"{archive}:{obj}"
|
||||
else:
|
||||
label = shorten_path(raw_object, root)
|
||||
# If the object lives under libs, hint at the containing directory.
|
||||
parent = os.path.basename(os.path.dirname(label))
|
||||
if parent:
|
||||
lib_label = parent
|
||||
return label, lib_label
|
||||
|
||||
|
||||
def parse_map(map_path: str, repo_root: str) -> Tuple[Dict[str, int], Dict[str, int], Dict[str, Dict[str, int]]]:
|
||||
per_object: DefaultDict[str, int] = collections.defaultdict(int)
|
||||
per_library: DefaultDict[str, int] = collections.defaultdict(int)
|
||||
per_object_sections: DefaultDict[str, DefaultDict[str, int]] = collections.defaultdict(lambda: collections.defaultdict(int))
|
||||
|
||||
try:
|
||||
with open(map_path, "r", encoding="utf-8", errors="ignore") as handle:
|
||||
for line in handle:
|
||||
match = SECTION_LINE_RE.match(line)
|
||||
if not match:
|
||||
continue
|
||||
|
||||
section = match.group("section")
|
||||
if section.startswith("*") or section in {"LOAD", "ORIGIN"}:
|
||||
continue
|
||||
|
||||
size = int(match.group("size"), 16)
|
||||
if size == 0:
|
||||
continue
|
||||
|
||||
obj_token = match.group("object").strip()
|
||||
if not obj_token or obj_token.startswith("*") or "load address" in obj_token:
|
||||
continue
|
||||
|
||||
label, lib_label = describe_object(obj_token, repo_root)
|
||||
per_object[label] += size
|
||||
per_library[lib_label] += size
|
||||
per_object_sections[label][section] += size
|
||||
except FileNotFoundError:
|
||||
raise SystemExit(f"error: map file '{map_path}' not found. Run a build first.")
|
||||
|
||||
return per_object, per_library, per_object_sections
|
||||
|
||||
|
||||
def format_section_breakdown(section_sizes: Dict[str, int], total: int, limit: int = 3) -> str:
|
||||
items = sorted(section_sizes.items(), key=lambda kv: kv[1], reverse=True)
|
||||
parts = []
|
||||
for section, size in items[:limit]:
|
||||
pct = (size / total) * 100 if total else 0
|
||||
parts.append(f"{section} {pct:.1f}%")
|
||||
if len(items) > limit:
|
||||
remainder = total - sum(size for _, size in items[:limit])
|
||||
pct = (remainder / total) * 100 if total else 0
|
||||
parts.append(f"other {pct:.1f}%")
|
||||
return ", ".join(parts)
|
||||
|
||||
|
||||
def print_report(map_path: str, top_n: int, per_object: Dict[str, int], per_library: Dict[str, int], per_object_sections: Dict[str, Dict[str, int]]):
|
||||
total_bytes = sum(per_object.values())
|
||||
if total_bytes == 0:
|
||||
print("No section data found in map file.")
|
||||
return
|
||||
|
||||
print(f"Map file: {map_path}")
|
||||
print(f"Accounted size: {human_size(total_bytes)} across {len(per_object)} object files\n")
|
||||
|
||||
sorted_objects = sorted(per_object.items(), key=lambda kv: kv[1], reverse=True)
|
||||
print(f"Top {min(top_n, len(sorted_objects))} object files by linked size:")
|
||||
for idx, (obj, size) in enumerate(sorted_objects[:top_n], 1):
|
||||
pct = (size / total_bytes) * 100
|
||||
breakdown = format_section_breakdown(per_object_sections[obj], size)
|
||||
print(f"{idx:2}. {human_size(size):>9} ({size:,} B, {pct:5.2f}% of linked size)")
|
||||
print(f" {obj}")
|
||||
if breakdown:
|
||||
print(f" sections: {breakdown}")
|
||||
print()
|
||||
|
||||
sorted_libs = sorted(per_library.items(), key=lambda kv: kv[1], reverse=True)
|
||||
print(f"Top {min(top_n, len(sorted_libs))} libraries or source roots:")
|
||||
for idx, (lib, size) in enumerate(sorted_libs[:top_n], 1):
|
||||
pct = (size / total_bytes) * 100
|
||||
print(f"{idx:2}. {human_size(size):>9} ({size:,} B, {pct:5.2f}% of linked size) {lib}")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description="Highlight heavy object files from a GNU ld map file.")
|
||||
parser.add_argument("--map", default=".pio/build/rak4631/output.map", help="Path to the map file (default: %(default)s)")
|
||||
parser.add_argument("--top", type=int, default=20, help="Number of entries to display per table (default: %(default)s)")
|
||||
args = parser.parse_args()
|
||||
|
||||
map_path = os.path.abspath(args.map)
|
||||
repo_root = os.path.abspath(os.getcwd())
|
||||
|
||||
per_object, per_library, per_object_sections = parse_map(map_path, repo_root)
|
||||
print_report(os.path.relpath(map_path, repo_root), args.top, per_object, per_library, per_object_sections)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -15,12 +15,12 @@ SET "LOGCOUNTER=0"
|
||||
SET "BPS_RESET=0"
|
||||
|
||||
@REM FIXME: Determine mcu from PlatformIO variant, this is unmaintainable.
|
||||
SET "S3=s3 v3 t-deck wireless-paper wireless-tracker station-g2 unphone t-eth-elite tlora-pager mesh-tab dreamcatcher ESP32-S3-Pico seeed-sensecap-indicator heltec_capsule_sensor_v3 vision-master icarus tracksenger elecrow-adv heltec-v4"
|
||||
SET "S3=s3 v3 t-deck wireless-paper wireless-tracker station-g2 unphone t-eth-elite tlora-pager mesh-tab dreamcatcher ESP32-S3-Pico seeed-sensecap-indicator heltec_capsule_sensor_v3 vision-master icarus tracksenger elecrow-adv"
|
||||
SET "C3=esp32c3"
|
||||
@REM FIXME: Determine flash size from PlatformIO variant, this is unmaintainable.
|
||||
SET "BIGDB_8MB=crowpanel-esp32s3 heltec_capsule_sensor_v3 heltec-v3 heltec-vision-master-e213 heltec-vision-master-e290 heltec-vision-master-t190 heltec-wireless-paper heltec-wireless-tracker heltec-wsl-v3 icarus seeed-xiao-s3 tbeam-s3-core tracksenger"
|
||||
SET "MUIDB_8MB=picomputer-s3 unphone seeed-sensecap-indicator"
|
||||
SET "BIGDB_16MB=t-deck mesh-tab t-energy-s3 dreamcatcher ESP32-S3-Pico m5stack-cores3 station-g2 t-eth-elite tlora-pager t-watch-s3 elecrow-adv heltec-v4"
|
||||
SET "BIGDB_16MB=t-deck mesh-tab t-energy-s3 dreamcatcher ESP32-S3-Pico m5stack-cores3 station-g2 t-eth-elite tlora-pager t-watch-s3 elecrow-adv"
|
||||
|
||||
GOTO getopts
|
||||
:help
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/bin/bash
|
||||
|
||||
PYTHON=${PYTHON:-$(which python3 python | head -n 1)}
|
||||
BPS_RESET=false
|
||||
@@ -31,23 +31,21 @@ MUIDB_8MB=(
|
||||
"seeed-sensecap-indicator"
|
||||
)
|
||||
BIGDB_16MB=(
|
||||
"dreamcatcher"
|
||||
"elecrow-adv"
|
||||
"ESP32-S3-Pico"
|
||||
"heltec-v4"
|
||||
"m5stack-cores3"
|
||||
"mesh-tab"
|
||||
"station-g2"
|
||||
"t-deck"
|
||||
"mesh-tab"
|
||||
"t-energy-s3"
|
||||
"dreamcatcher"
|
||||
"ESP32-S3-Pico"
|
||||
"m5stack-cores3"
|
||||
"station-g2"
|
||||
"t-eth-elite"
|
||||
"t-watch-s3"
|
||||
"tlora-pager"
|
||||
"t-watch-s3"
|
||||
"elecrow-adv"
|
||||
)
|
||||
S3_VARIANTS=(
|
||||
"s3"
|
||||
"-v3"
|
||||
"-v4"
|
||||
"t-deck"
|
||||
"wireless-paper"
|
||||
"wireless-tracker"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/bin/bash
|
||||
|
||||
PYTHON=${PYTHON:-$(which python3 python|head -n 1)}
|
||||
CHANGE_MODE=false
|
||||
|
||||
@@ -1,32 +1,28 @@
|
||||
#!/usr/bin/env python3
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""Generate the CI matrix."""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
import random
|
||||
import re
|
||||
from platformio.project.config import ProjectConfig
|
||||
|
||||
parser = argparse.ArgumentParser(description="Generate the CI matrix")
|
||||
parser.add_argument("platform", help="Platform to build for")
|
||||
parser.add_argument(
|
||||
"--level",
|
||||
choices=["extra", "pr"],
|
||||
nargs="*",
|
||||
default=[],
|
||||
help="Board level to build for (omit for full release boards)",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
options = sys.argv[1:]
|
||||
|
||||
outlist = []
|
||||
|
||||
if len(options) < 1:
|
||||
print(json.dumps(outlist))
|
||||
exit(1)
|
||||
|
||||
cfg = ProjectConfig.get_instance()
|
||||
pio_envs = cfg.envs()
|
||||
|
||||
# Gather all PlatformIO environments for filtering later
|
||||
all_envs = []
|
||||
for pio_env in pio_envs:
|
||||
env_build_flags = cfg.get(f"env:{pio_env}", "build_flags")
|
||||
env_build_flags = cfg.get(f"env:{pio_env}", 'build_flags')
|
||||
env_platform = None
|
||||
for flag in env_build_flags:
|
||||
# Extract the platform from the build flags
|
||||
@@ -41,35 +37,36 @@ for pio_env in pio_envs:
|
||||
exit(1)
|
||||
# Store env details as a dictionary, and add to 'all_envs' list
|
||||
env = {
|
||||
"ci": {"board": pio_env, "platform": env_platform},
|
||||
"board_level": cfg.get(f"env:{pio_env}", "board_level", default=None),
|
||||
"board_check": bool(cfg.get(f"env:{pio_env}", "board_check", default=False)),
|
||||
'name': pio_env,
|
||||
'platform': env_platform,
|
||||
'board_level': cfg.get(f"env:{pio_env}", 'board_level', default=None),
|
||||
'board_check': bool(cfg.get(f"env:{pio_env}", 'board_check', default=False))
|
||||
}
|
||||
all_envs.append(env)
|
||||
|
||||
# Filter outputs based on options
|
||||
# Check is mutually exclusive with other options (except 'pr')
|
||||
if "check" in args.platform:
|
||||
if "check" in options:
|
||||
for env in all_envs:
|
||||
if env["board_check"]:
|
||||
if "pr" in args.level:
|
||||
if env["board_level"] == "pr":
|
||||
outlist.append(env["ci"])
|
||||
if env['board_check']:
|
||||
if "pr" in options:
|
||||
if env['board_level'] == 'pr':
|
||||
outlist.append(env['name'])
|
||||
else:
|
||||
outlist.append(env["ci"])
|
||||
outlist.append(env['name'])
|
||||
# Filter (non-check) builds by platform
|
||||
else:
|
||||
for env in all_envs:
|
||||
if args.platform == env["ci"]["platform"] or args.platform == "all":
|
||||
if options[0] == env['platform']:
|
||||
# Always include board_level = 'pr'
|
||||
if env["board_level"] == "pr":
|
||||
outlist.append(env["ci"])
|
||||
if env['board_level'] == 'pr':
|
||||
outlist.append(env['name'])
|
||||
# Include board_level = 'extra' when requested
|
||||
elif "extra" in args.level and env["board_level"] == "extra":
|
||||
outlist.append(env["ci"])
|
||||
elif "extra" in options and env['board_level'] == "extra":
|
||||
outlist.append(env['name'])
|
||||
# If no board level is specified, include in release builds (not PR)
|
||||
elif "pr" not in args.level and not env["board_level"]:
|
||||
outlist.append(env["ci"])
|
||||
elif "pr" not in options and not env['board_level']:
|
||||
outlist.append(env['name'])
|
||||
|
||||
# Return as a JSON list
|
||||
print(json.dumps(outlist))
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to cancel all running GitHub Actions workflows
|
||||
# Requires GitHub CLI (gh) to be installed and authenticated
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Function to print colored output
|
||||
print_status() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Check if gh CLI is installed
|
||||
if ! command -v gh &> /dev/null; then
|
||||
print_error "GitHub CLI (gh) is not installed. Please install it first:"
|
||||
echo " brew install gh"
|
||||
echo " Or visit: https://cli.github.com/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if authenticated
|
||||
if ! gh auth status &> /dev/null; then
|
||||
print_error "GitHub CLI is not authenticated. Please run:"
|
||||
echo " gh auth login"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get repository info
|
||||
REPO=$(gh repo view --json owner,name -q '.owner.login + "/" + .name')
|
||||
if [[ -z "$REPO" ]]; then
|
||||
print_error "Could not determine repository. Make sure you're in a GitHub repository."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_status "Working with repository: $REPO"
|
||||
|
||||
# Get all active workflows (both queued and in-progress)
|
||||
print_status "Fetching active workflows (queued and in-progress)..."
|
||||
QUEUED_WORKFLOWS=$(gh run list --status queued --json databaseId,displayTitle,headBranch,status --limit 100)
|
||||
IN_PROGRESS_WORKFLOWS=$(gh run list --status in_progress --json databaseId,displayTitle,headBranch,status --limit 100)
|
||||
|
||||
# Combine both lists
|
||||
ALL_WORKFLOWS=$(echo "$QUEUED_WORKFLOWS $IN_PROGRESS_WORKFLOWS" | jq -s 'add | unique_by(.databaseId)')
|
||||
|
||||
if [[ "$ALL_WORKFLOWS" == "[]" ]]; then
|
||||
print_status "No active workflows found."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Parse and display active workflows
|
||||
echo
|
||||
print_warning "Found active workflows:"
|
||||
echo "$ALL_WORKFLOWS" | jq -r '.[] | " - \(.displayTitle) (Branch: \(.headBranch), Status: \(.status), ID: \(.databaseId))"'
|
||||
|
||||
echo
|
||||
read -p "Do you want to cancel ALL these workflows? (y/N): " -n 1 -r
|
||||
echo
|
||||
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
print_status "Cancelled by user."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Cancel each workflow
|
||||
print_status "Cancelling workflows..."
|
||||
CANCELLED_COUNT=0
|
||||
FAILED_COUNT=0
|
||||
|
||||
while IFS= read -r WORKFLOW_ID; do
|
||||
if [[ -n "$WORKFLOW_ID" ]]; then
|
||||
print_status "Cancelling workflow ID: $WORKFLOW_ID"
|
||||
if gh run cancel "$WORKFLOW_ID" 2>/dev/null; then
|
||||
((CANCELLED_COUNT++))
|
||||
else
|
||||
print_error "Failed to cancel workflow ID: $WORKFLOW_ID"
|
||||
((FAILED_COUNT++))
|
||||
fi
|
||||
fi
|
||||
done < <(echo "$ALL_WORKFLOWS" | jq -r '.[].databaseId')
|
||||
|
||||
echo
|
||||
print_status "Summary:"
|
||||
echo " - Cancelled: $CANCELLED_COUNT workflows"
|
||||
if [[ $FAILED_COUNT -gt 0 ]]; then
|
||||
echo " - Failed: $FAILED_COUNT workflows"
|
||||
fi
|
||||
|
||||
print_status "Done!"
|
||||
|
||||
# Optional: Show remaining active workflows
|
||||
echo
|
||||
print_status "Checking for any remaining active workflows..."
|
||||
REMAINING_QUEUED=$(gh run list --status queued --json databaseId --limit 10)
|
||||
REMAINING_IN_PROGRESS=$(gh run list --status in_progress --json databaseId --limit 10)
|
||||
REMAINING_ALL=$(echo "$REMAINING_QUEUED $REMAINING_IN_PROGRESS" | jq -s 'add | unique_by(.databaseId)')
|
||||
|
||||
if [[ "$REMAINING_ALL" == "[]" ]]; then
|
||||
print_status "All workflows successfully cancelled."
|
||||
else
|
||||
REMAINING_COUNT=$(echo "$REMAINING_ALL" | jq '. | length')
|
||||
print_warning "Still $REMAINING_COUNT workflows active (may take a moment to update status)"
|
||||
fi
|
||||
@@ -87,30 +87,6 @@
|
||||
</screenshots>
|
||||
|
||||
<releases>
|
||||
<release version="2.7.17" date="2025-11-28">
|
||||
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.17</url>
|
||||
</release>
|
||||
<release version="2.7.16" date="2025-11-19">
|
||||
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.16</url>
|
||||
</release>
|
||||
<release version="2.7.15" date="2025-11-13">
|
||||
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.15</url>
|
||||
</release>
|
||||
<release version="2.7.14" date="2025-11-03">
|
||||
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.14</url>
|
||||
</release>
|
||||
<release version="2.7.13" date="2025-10-11">
|
||||
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.13</url>
|
||||
</release>
|
||||
<release version="2.7.12" date="2025-10-01">
|
||||
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.12</url>
|
||||
</release>
|
||||
<release version="2.7.11" date="2025-09-24">
|
||||
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.11</url>
|
||||
</release>
|
||||
<release version="2.7.10" date="2025-09-18">
|
||||
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.10</url>
|
||||
</release>
|
||||
<release version="2.7.9" date="2025-09-03">
|
||||
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.9</url>
|
||||
</release>
|
||||
|
||||
@@ -86,7 +86,7 @@ if platform.name == "espressif32":
|
||||
|
||||
if platform.name == "nordicnrf52":
|
||||
env.AddPostAction("$BUILD_DIR/${PROGNAME}.hex",
|
||||
env.VerboseAction(f"\"{sys.executable}\" ./bin/uf2conv.py \"$BUILD_DIR/firmware.hex\" -c -f 0xADA52840 -o \"$BUILD_DIR/firmware.uf2\"",
|
||||
env.VerboseAction(f"\"{sys.executable}\" ./bin/uf2conv.py $BUILD_DIR/firmware.hex -c -f 0xADA52840 -o $BUILD_DIR/firmware.uf2",
|
||||
"Generating UF2 file"))
|
||||
|
||||
Import("projenv")
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.6.7
|
||||
2.6.4
|
||||
@@ -1,53 +0,0 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "nrf52840_s140_v6.ld"
|
||||
},
|
||||
"core": "nRF5",
|
||||
"cpu": "cortex-m4",
|
||||
"extra_flags": "-DNRF52840_XXAA",
|
||||
"f_cpu": "64000000L",
|
||||
"hwids": [
|
||||
["0x239A", "0x4405"],
|
||||
["0x239A", "0x0029"],
|
||||
["0x239A", "0x002A"]
|
||||
],
|
||||
"usb_product": "elecrow_eink",
|
||||
"mcu": "nrf52840",
|
||||
"variant": "ELECROW-ThinkNode-M3",
|
||||
"variants_dir": "variants",
|
||||
"bsp": {
|
||||
"name": "adafruit"
|
||||
},
|
||||
"softdevice": {
|
||||
"sd_flags": "-DS140",
|
||||
"sd_name": "s140",
|
||||
"sd_version": "6.1.1",
|
||||
"sd_fwid": "0x00B6"
|
||||
},
|
||||
"bootloader": {
|
||||
"settings_addr": "0xFF000"
|
||||
}
|
||||
},
|
||||
"connectivity": ["bluetooth"],
|
||||
"debug": {
|
||||
"jlink_device": "nRF52840_xxAA",
|
||||
"onboard_tools": ["jlink"],
|
||||
"svd_path": "nrf52840.svd",
|
||||
"openocd_target": "nrf52840-mdk-rs"
|
||||
},
|
||||
"frameworks": ["arduino"],
|
||||
"name": "elecrow nrf",
|
||||
"upload": {
|
||||
"maximum_ram_size": 248832,
|
||||
"maximum_size": 815104,
|
||||
"speed": 115200,
|
||||
"protocol": "nrfutil",
|
||||
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
|
||||
"use_1200bps_touch": true,
|
||||
"require_upload_port": true,
|
||||
"wait_for_upload_port": true
|
||||
},
|
||||
"url": "",
|
||||
"vendor": "ELECROW"
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "nrf52840_s140_v6.ld"
|
||||
},
|
||||
"core": "nRF5",
|
||||
"cpu": "cortex-m4",
|
||||
"extra_flags": "-DARDUINO_NRF52840_ELECROW_M6 -DNRF52840_XXAA",
|
||||
"f_cpu": "64000000L",
|
||||
"hwids": [
|
||||
["0x239A", "0x4405"],
|
||||
["0x239A", "0x0029"],
|
||||
["0x239A", "0x002A"]
|
||||
],
|
||||
"usb_product": "elecrow_thinknode_m6",
|
||||
"mcu": "nrf52840",
|
||||
"variant": "ELECROW-ThinkNode-M6",
|
||||
"variants_dir": "variants",
|
||||
"bsp": {
|
||||
"name": "adafruit"
|
||||
},
|
||||
"softdevice": {
|
||||
"sd_flags": "-DS140",
|
||||
"sd_name": "s140",
|
||||
"sd_version": "6.1.1",
|
||||
"sd_fwid": "0x00B6"
|
||||
},
|
||||
"bootloader": {
|
||||
"settings_addr": "0xFF000"
|
||||
}
|
||||
},
|
||||
"connectivity": ["bluetooth"],
|
||||
"debug": {
|
||||
"jlink_device": "nRF52840_xxAA",
|
||||
"onboard_tools": ["jlink"],
|
||||
"svd_path": "nrf52840.svd",
|
||||
"openocd_target": "nrf52840-mdk-rs"
|
||||
},
|
||||
"frameworks": ["arduino"],
|
||||
"name": "ELECROW ThinkNode M6",
|
||||
"upload": {
|
||||
"maximum_ram_size": 248832,
|
||||
"maximum_size": 815104,
|
||||
"speed": 115200,
|
||||
"protocol": "nrfutil",
|
||||
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
|
||||
"use_1200bps_touch": true,
|
||||
"require_upload_port": true,
|
||||
"wait_for_upload_port": true
|
||||
},
|
||||
"url": "https://www.elecrow.com/thinknode-m6-outdoor-solar-power-for-lora-powered-by-nrf52840-supports-gps.html",
|
||||
"vendor": "ELECROW"
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32s3_out.ld",
|
||||
"memory_type": "qio_opi"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DBOARD_HAS_PSRAM",
|
||||
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||
"-DARDUINO_USB_MODE=0",
|
||||
"-DARDUINO_RUNNING_CORE=1",
|
||||
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "qio",
|
||||
"hwids": [["0x303A", "0x1001"]],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "hackaday-communicator"
|
||||
},
|
||||
"connectivity": ["wifi", "bluetooth", "lora"],
|
||||
"debug": {
|
||||
"default_tool": "esp-builtin",
|
||||
"onboard_tools": ["esp-builtin"],
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
"frameworks": ["arduino", "espidf"],
|
||||
"name": "hackaday-communicator (16 MB FLASH, 8 MB PSRAM)",
|
||||
"upload": {
|
||||
"flash_size": "16MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 16777216,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": true,
|
||||
"require_upload_port": true,
|
||||
"speed": 1500000
|
||||
},
|
||||
"url": "hackaday.com",
|
||||
"vendor": "hackaday"
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32s3_out.ld",
|
||||
"partitions": "default_16MB.csv",
|
||||
"memory_type": "qio_qspi"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DBOARD_HAS_PSRAM",
|
||||
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||
"-DARDUINO_USB_MODE=1",
|
||||
"-DARDUINO_RUNNING_CORE=1",
|
||||
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "qio",
|
||||
"psram_type": "qspi",
|
||||
"hwids": [["0x303A", "0x1001"]],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "heltec_v4"
|
||||
},
|
||||
"connectivity": ["wifi", "bluetooth", "lora"],
|
||||
"debug": {
|
||||
"default_tool": "esp-builtin",
|
||||
"onboard_tools": ["esp-builtin"],
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
"frameworks": ["arduino", "espidf"],
|
||||
"name": "heltec_wifi_lora_32 v4 (16 MB FLASH, 2 MB PSRAM)",
|
||||
"upload": {
|
||||
"flash_size": "16MB",
|
||||
"maximum_ram_size": 2097152,
|
||||
"maximum_size": 16777216,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": true,
|
||||
"require_upload_port": true,
|
||||
"speed": 921600
|
||||
},
|
||||
"url": "https://heltec.org/",
|
||||
"vendor": "heltec"
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32s3_out.ld",
|
||||
"partitions": "default_8MB.csv"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||
"-DARDUINO_USB_MODE=0",
|
||||
"-DARDUINO_RUNNING_CORE=1",
|
||||
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "qio",
|
||||
"hwids": [["0x303A", "0x1001"]],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "heltec_wireless_tracker_v2"
|
||||
},
|
||||
"connectivity": ["wifi", "bluetooth", "lora"],
|
||||
"debug": {
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
"frameworks": ["arduino", "espidf"],
|
||||
"name": "Heltec Wireless Tracker V2",
|
||||
"upload": {
|
||||
"flash_size": "8MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 8388608,
|
||||
"wait_for_upload_port": true,
|
||||
"require_upload_port": true,
|
||||
"speed": 921600
|
||||
},
|
||||
"url": "https://heltec.org",
|
||||
"vendor": "Heltec"
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "nrf52840_s140_v6.ld"
|
||||
},
|
||||
"core": "nRF5",
|
||||
"cpu": "cortex-m4",
|
||||
"extra_flags": "-DARDUINO_NRF52840_MUZI_BASE -DNRF52840_XXAA",
|
||||
"f_cpu": "64000000L",
|
||||
"hwids": [["0x239A", "0xcafe"]],
|
||||
"mcu": "nrf52840",
|
||||
"variant": "muzi-base",
|
||||
"variants_dir": "variants",
|
||||
"bsp": {
|
||||
"name": "adafruit"
|
||||
},
|
||||
"softdevice": {
|
||||
"sd_flags": "-DS140",
|
||||
"sd_name": "s140",
|
||||
"sd_version": "6.1.1",
|
||||
"sd_fwid": "0x00B6"
|
||||
},
|
||||
"bootloader": {
|
||||
"settings_addr": "0xFF000"
|
||||
}
|
||||
},
|
||||
"connectivity": ["bluetooth"],
|
||||
"debug": {
|
||||
"jlink_device": "nRF52840_xxAA",
|
||||
"onboard_tools": ["jlink"],
|
||||
"svd_path": "nrf52840.svd",
|
||||
"openocd_target": "nrf52840-mdk-rs"
|
||||
},
|
||||
"frameworks": ["arduino"],
|
||||
"name": "Muzi Base",
|
||||
"url": "https://muzi.works/",
|
||||
"vendor": "MuziWorks",
|
||||
"upload": {
|
||||
"maximum_ram_size": 248832,
|
||||
"maximum_size": 815104,
|
||||
"speed": 115200,
|
||||
"protocol": "nrfutil",
|
||||
"protocols": [
|
||||
"jlink",
|
||||
"nrfjprog",
|
||||
"nrfutil",
|
||||
"blackmagic",
|
||||
"cmsis-dap",
|
||||
"mbed",
|
||||
"stlink"
|
||||
],
|
||||
"use_1200bps_touch": true,
|
||||
"require_upload_port": true,
|
||||
"wait_for_upload_port": true
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "nrf52840_s140_v6.ld"
|
||||
},
|
||||
"core": "nRF5",
|
||||
"cpu": "cortex-m4",
|
||||
"extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
|
||||
"f_cpu": "64000000L",
|
||||
"hwids": [
|
||||
["0x239A", "0x8029"],
|
||||
["0x239A", "0x0029"],
|
||||
["0x239A", "0x002A"],
|
||||
["0x239A", "0x802A"]
|
||||
],
|
||||
"usb_product": "Muzi R1 Neo",
|
||||
"mcu": "nrf52840",
|
||||
"variant": "r1-neo",
|
||||
"bsp": {
|
||||
"name": "adafruit"
|
||||
},
|
||||
"softdevice": {
|
||||
"sd_flags": "-DS140",
|
||||
"sd_name": "s140",
|
||||
"sd_version": "6.1.1",
|
||||
"sd_fwid": "0x00B6"
|
||||
},
|
||||
"bootloader": {
|
||||
"settings_addr": "0xFF000"
|
||||
}
|
||||
},
|
||||
"connectivity": ["bluetooth"],
|
||||
"debug": {
|
||||
"jlink_device": "nRF52840_xxAA",
|
||||
"svd_path": "nrf52840.svd",
|
||||
"openocd_target": "nrf52840-mdk-rs"
|
||||
},
|
||||
"frameworks": ["arduino", "freertos"],
|
||||
"name": "WisCore RAK4631 Board",
|
||||
"upload": {
|
||||
"maximum_ram_size": 248832,
|
||||
"maximum_size": 815104,
|
||||
"speed": 115200,
|
||||
"protocol": "nrfutil",
|
||||
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
|
||||
"use_1200bps_touch": true,
|
||||
"require_upload_port": true,
|
||||
"wait_for_upload_port": true
|
||||
},
|
||||
"url": "https://muzi.works/",
|
||||
"vendor": "Muzi Works"
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"f_boot": "120000000L",
|
||||
"boot_freq": "120000000L",
|
||||
"boot": "qio",
|
||||
"flash_mode": "qio",
|
||||
"psram_type": "opi",
|
||||
|
||||
78
debian/changelog
vendored
78
debian/changelog
vendored
@@ -1,44 +1,50 @@
|
||||
meshtasticd (2.7.17.0) unstable; urgency=medium
|
||||
|
||||
* Version 2.7.17
|
||||
|
||||
-- GitHub Actions <github-actions[bot]@users.noreply.github.com> Fri, 28 Nov 2025 15:11:34 +0000
|
||||
|
||||
meshtasticd (2.7.16.0) unstable; urgency=medium
|
||||
|
||||
* Version 2.7.16
|
||||
|
||||
-- GitHub Actions <github-actions[bot]@users.noreply.github.com> Wed, 19 Nov 2025 16:12:32 +0000
|
||||
|
||||
|
||||
meshtasticd (2.7.15.0) unstable; urgency=medium
|
||||
|
||||
* Version 2.7.15
|
||||
|
||||
-- GitHub Actions <github-actions[bot]@users.noreply.github.com> Thu, 13 Nov 2025 12:31:57 +0000
|
||||
|
||||
meshtasticd (2.7.14.0) unstable; urgency=medium
|
||||
|
||||
* Version 2.7.14
|
||||
|
||||
-- GitHub Actions <github-actions[bot]@users.noreply.github.com> Mon, 03 Nov 2025 16:11:31 +0000
|
||||
|
||||
meshtasticd (2.7.13.0) unstable; urgency=medium
|
||||
|
||||
* Version 2.7.13
|
||||
|
||||
-- GitHub Actions <github-actions[bot]@users.noreply.github.com> Sat, 11 Oct 2025 15:27:28 +0000
|
||||
|
||||
meshtasticd (2.7.12.0) unstable; urgency=medium
|
||||
meshtasticd (2.7.9.0) UNRELEASED; urgency=medium
|
||||
|
||||
[ Austin Lane ]
|
||||
* Initial packaging
|
||||
* Version 2.5.19
|
||||
* GitHub Actions Automatic version bump
|
||||
* GitHub Actions Automatic version bump
|
||||
* GitHub Actions Automatic version bump
|
||||
* GitHub Actions Automatic version bump
|
||||
|
||||
[ ]
|
||||
* GitHub Actions Automatic version bump
|
||||
|
||||
[ GitHub Actions ]
|
||||
* Version 2.7.12
|
||||
[ ]
|
||||
* GitHub Actions Automatic version bump
|
||||
|
||||
-- GitHub Actions <github-actions[bot]@users.noreply.github.com> Wed, 01 Oct 2025 19:51:41 +0000
|
||||
[ ]
|
||||
* GitHub Actions Automatic version bump
|
||||
|
||||
[ ]
|
||||
* GitHub Actions Automatic version bump
|
||||
|
||||
[ ]
|
||||
* GitHub Actions Automatic version bump
|
||||
|
||||
[ ]
|
||||
* GitHub Actions Automatic version bump
|
||||
|
||||
[ ]
|
||||
* GitHub Actions Automatic version bump
|
||||
|
||||
[ Ubuntu ]
|
||||
* GitHub Actions Automatic version bump
|
||||
|
||||
[ ]
|
||||
* GitHub Actions Automatic version bump
|
||||
|
||||
[ ]
|
||||
* GitHub Actions Automatic version bump
|
||||
|
||||
[ ]
|
||||
* GitHub Actions Automatic version bump
|
||||
* GitHub Actions Automatic version bump
|
||||
|
||||
[ ]
|
||||
* GitHub Actions Automatic version bump
|
||||
|
||||
[ ]
|
||||
* GitHub Actions Automatic version bump
|
||||
|
||||
-- <github-actions[bot]@users.noreply.github.com> Wed, 03 Sep 2025 23:39:17 +0000
|
||||
|
||||
5
debian/ci_changelog.sh
vendored
5
debian/ci_changelog.sh
vendored
@@ -1,8 +1,7 @@
|
||||
#!/usr/bin/bash
|
||||
export DEBFULLNAME="GitHub Actions"
|
||||
export DEBEMAIL="github-actions[bot]@users.noreply.github.com"
|
||||
PKG_VERSION=$(python3 bin/buildinfo.py short)
|
||||
|
||||
dch --newversion "$PKG_VERSION.0" \
|
||||
--distribution unstable \
|
||||
"Version $PKG_VERSION"
|
||||
--distribution UNRELEASED \
|
||||
"GitHub Actions Automatic version bump"
|
||||
|
||||
1
debian/control
vendored
1
debian/control
vendored
@@ -3,7 +3,6 @@ Section: misc
|
||||
Priority: optional
|
||||
Maintainer: Austin Lane <vidplace7@gmail.com>
|
||||
Build-Depends: debhelper-compat (= 13),
|
||||
libc6-dev (>= 2.38) | libbsd-dev,
|
||||
lsb-release,
|
||||
tar,
|
||||
gzip,
|
||||
|
||||
2
debian/meshtasticd.postinst
vendored
2
debian/meshtasticd.postinst
vendored
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
# postinst script for meshtasticd
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
2
debian/meshtasticd.postrm
vendored
2
debian/meshtasticd.postrm
vendored
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
# postrm script for meshtasticd
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
@@ -49,13 +49,6 @@ BuildRequires: pkgconfig(x11)
|
||||
BuildRequires: pkgconfig(libinput)
|
||||
BuildRequires: pkgconfig(xkbcommon-x11)
|
||||
|
||||
# libbsd is needed on older Fedora/RHEL to provide 'strlcpy'
|
||||
%if 0%{?fedora} >= 39 || 0%{?rhel} >= 10
|
||||
BuildRequires: glibc-devel >= 2.38
|
||||
%else
|
||||
BuildRequires: pkgconfig(libbsd-overlay)
|
||||
%endif
|
||||
|
||||
Requires: systemd-udev
|
||||
|
||||
%description
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
default_envs = tbeam
|
||||
|
||||
extra_configs =
|
||||
variants/*/*.ini
|
||||
arch/*/*.ini
|
||||
variants/*/*/platformio.ini
|
||||
variants/*/diy/*/platformio.ini
|
||||
src/graphics/niche/InkHUD/PlatformioConfig.ini
|
||||
@@ -55,14 +55,12 @@ build_flags = -Wno-missing-field-initializers
|
||||
-D MAX_THREADS=40 ; As we've split modules, we have more threads to manage
|
||||
#-DBUILD_EPOCH=$UNIX_TIME ; set in platformio-custom.py now
|
||||
#-D OLED_PL=1
|
||||
#-D DEBUG_HEAP=1 ; uncomment to add free heap space / memory leak debugging logs
|
||||
#-D DEBUG_LOOP_TIMING=1 ; uncomment to add main loop timing logs
|
||||
|
||||
monitor_speed = 115200
|
||||
monitor_filters = direct
|
||||
lib_deps =
|
||||
# renovate: datasource=git-refs depName=meshtastic-esp8266-oled-ssd1306 packageName=https://github.com/meshtastic/esp8266-oled-ssd1306 gitBranch=master
|
||||
https://github.com/meshtastic/esp8266-oled-ssd1306/archive/2887bf4a19f64d92c984dcc8fd5ca7429e425e4a.zip
|
||||
https://github.com/meshtastic/esp8266-oled-ssd1306/archive/0cbc26b1f8f61957af0475f486b362eafe7cc4e2.zip
|
||||
# renovate: datasource=git-refs depName=meshtastic-OneButton packageName=https://github.com/meshtastic/OneButton gitBranch=master
|
||||
https://github.com/meshtastic/OneButton/archive/fa352d668c53f290cfa480a5f79ad422cd828c70.zip
|
||||
# renovate: datasource=git-refs depName=meshtastic-arduino-fsm packageName=https://github.com/meshtastic/arduino-fsm gitBranch=master
|
||||
@@ -70,7 +68,7 @@ lib_deps =
|
||||
# renovate: datasource=git-refs depName=meshtastic-TinyGPSPlus packageName=https://github.com/meshtastic/TinyGPSPlus gitBranch=master
|
||||
https://github.com/meshtastic/TinyGPSPlus/archive/71a82db35f3b973440044c476d4bcdc673b104f4.zip
|
||||
# renovate: datasource=git-refs depName=meshtastic-ArduinoThread packageName=https://github.com/meshtastic/ArduinoThread gitBranch=master
|
||||
https://github.com/meshtastic/ArduinoThread/archive/b841b0415721f1341ea41cccfb4adccfaf951567.zip
|
||||
https://github.com/meshtastic/ArduinoThread/archive/7c3ee9e1951551b949763b1f5280f8db1fa4068d.zip
|
||||
# renovate: datasource=custom.pio depName=Nanopb packageName=nanopb/library/Nanopb
|
||||
nanopb/Nanopb@0.4.91
|
||||
# renovate: datasource=custom.pio depName=ErriezCRC32 packageName=erriez/library/ErriezCRC32
|
||||
@@ -89,8 +87,9 @@ check_flags =
|
||||
framework = arduino
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
# renovate: datasource=custom.pio depName=NonBlockingRTTTL packageName=end2endzone/library/NonBlockingRTTTL
|
||||
end2endzone/NonBlockingRTTTL@1.4.0
|
||||
# renovate: datasource=custom.pio depName=NonBlockingRTTTL packageName=mverch67/library/NonBlockingRTTTL
|
||||
https://github.com/mverch67/NonBlockingRTTTL/archive/ad1c2fb12bc81db546c6a94e963acb3382d3689e.zip ; TODO
|
||||
|
||||
build_flags = ${env.build_flags} -Os
|
||||
build_src_filter = ${env.build_src_filter} -<platform/portduino/> -<graphics/niche/>
|
||||
|
||||
@@ -101,8 +100,6 @@ lib_deps =
|
||||
thingsboard/TBPubSubClient@2.12.1
|
||||
# renovate: datasource=custom.pio depName=NTPClient packageName=arduino-libraries/library/NTPClient
|
||||
arduino-libraries/NTPClient@3.2.1
|
||||
# renovate: datasource=custom.pio depName=Syslog packageName=arcao/library/Syslog
|
||||
arcao/Syslog@2.0.0
|
||||
|
||||
; Minimal networking libs for nrf52 (excludes Syslog to save flash)
|
||||
[nrf52_networking_base]
|
||||
@@ -115,19 +112,18 @@ lib_deps =
|
||||
[radiolib_base]
|
||||
lib_deps =
|
||||
# renovate: datasource=custom.pio depName=RadioLib packageName=jgromes/library/RadioLib
|
||||
# jgromes/RadioLib@7.4.0
|
||||
https://github.com/jgromes/RadioLib/archive/536c7267362e2c1345be7054ba45e503252975ff.zip
|
||||
jgromes/RadioLib@7.2.1
|
||||
|
||||
[device-ui_base]
|
||||
lib_deps =
|
||||
# renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master
|
||||
https://github.com/meshtastic/device-ui/archive/3bf332240416c5cb8c919fac2a0ec7260eb3be75.zip
|
||||
https://github.com/meshtastic/device-ui/archive/9ed5355a24059750e9b2eb5d669574d9ea42a37b.zip
|
||||
|
||||
; Common libs for environmental measurements in telemetry module
|
||||
[environmental_base]
|
||||
lib_deps =
|
||||
# renovate: datasource=custom.pio depName=Adafruit BusIO packageName=adafruit/library/Adafruit BusIO
|
||||
adafruit/Adafruit BusIO@1.17.4
|
||||
adafruit/Adafruit BusIO@1.17.2
|
||||
# renovate: datasource=custom.pio depName=Adafruit Unified Sensor packageName=adafruit/library/Adafruit Unified Sensor
|
||||
adafruit/Adafruit Unified Sensor@1.1.15
|
||||
# renovate: datasource=custom.pio depName=Adafruit BMP280 packageName=adafruit/library/Adafruit BMP280 Library
|
||||
@@ -165,11 +161,11 @@ lib_deps =
|
||||
# renovate: datasource=custom.pio depName=QMC5883L Compass packageName=mprograms/library/QMC5883LCompass
|
||||
mprograms/QMC5883LCompass@1.2.3
|
||||
# renovate: datasource=custom.pio depName=DFRobot_RTU packageName=dfrobot/library/DFRobot_RTU
|
||||
dfrobot/DFRobot_RTU@1.0.6
|
||||
dfrobot/DFRobot_RTU@1.0.3
|
||||
# renovate: datasource=git-refs depName=DFRobot_RainfallSensor packageName=https://github.com/DFRobot/DFRobot_RainfallSensor gitBranch=master
|
||||
https://github.com/DFRobot/DFRobot_RainfallSensor/archive/38fea5e02b40a5430be6dab39a99a6f6347d667e.zip
|
||||
# renovate: datasource=custom.pio depName=INA226 packageName=robtillaart/library/INA226
|
||||
robtillaart/INA226@0.6.5
|
||||
robtillaart/INA226@0.6.4
|
||||
# renovate: datasource=custom.pio depName=SparkFun MAX3010x packageName=sparkfun/library/SparkFun MAX3010x Pulse and Proximity Sensor Library
|
||||
sparkfun/SparkFun MAX3010x Pulse and Proximity Sensor Library@1.1.2
|
||||
# renovate: datasource=custom.pio depName=SparkFun 9DoF IMU Breakout ICM 20948 packageName=sparkfun/library/SparkFun 9DoF IMU Breakout - ICM 20948 - Arduino Library
|
||||
@@ -177,13 +173,11 @@ lib_deps =
|
||||
# renovate: datasource=custom.pio depName=Adafruit LTR390 Library packageName=adafruit/library/Adafruit LTR390 Library
|
||||
adafruit/Adafruit LTR390 Library@1.1.2
|
||||
# renovate: datasource=custom.pio depName=Adafruit PCT2075 packageName=adafruit/library/Adafruit PCT2075
|
||||
adafruit/Adafruit PCT2075@1.0.6
|
||||
adafruit/Adafruit PCT2075@1.0.5
|
||||
# renovate: datasource=custom.pio depName=DFRobot_BMM150 packageName=dfrobot/library/DFRobot_BMM150
|
||||
dfrobot/DFRobot_BMM150@1.0.0
|
||||
# renovate: datasource=custom.pio depName=Adafruit_TSL2561 packageName=adafruit/library/Adafruit TSL2561
|
||||
adafruit/Adafruit TSL2561@1.1.2
|
||||
# renovate: datasource=custom.pio depName=BH1750_WE packageName=wollewald/BH1750_WE@^1.1.10
|
||||
wollewald/BH1750_WE@^1.1.10
|
||||
|
||||
; (not included in native / portduino)
|
||||
[environmental_extra]
|
||||
@@ -213,6 +207,6 @@ lib_deps =
|
||||
# renovate: datasource=git-refs depName=meshtastic-DFRobot_LarkWeatherStation packageName=https://github.com/meshtastic/DFRobot_LarkWeatherStation gitBranch=master
|
||||
https://github.com/meshtastic/DFRobot_LarkWeatherStation/archive/4de3a9cadef0f6a5220a8a906cf9775b02b0040d.zip
|
||||
# renovate: datasource=custom.pio depName=Sensirion Core packageName=sensirion/library/Sensirion Core
|
||||
sensirion/Sensirion Core@0.7.2
|
||||
sensirion/Sensirion Core@0.7.1
|
||||
# renovate: datasource=custom.pio depName=Sensirion I2C SCD4x packageName=sensirion/library/Sensirion I2C SCD4x
|
||||
sensirion/Sensirion I2C SCD4x@1.1.0
|
||||
|
||||
Submodule protobufs updated: 52fa252f1e...945b796a98
@@ -8,7 +8,6 @@
|
||||
"replacements:all",
|
||||
"workarounds:all"
|
||||
],
|
||||
"baseBranchPatterns": ["master"],
|
||||
"forkProcessing": "enabled",
|
||||
"ignoreDeps": [
|
||||
"protobufs"
|
||||
|
||||
@@ -11,11 +11,6 @@
|
||||
#include <AudioOutputI2S.h>
|
||||
#include <ESP8266SAM.h>
|
||||
|
||||
#ifdef USE_XL9555
|
||||
#include "ExtensionIOXL9555.hpp"
|
||||
extern ExtensionIOXL9555 io;
|
||||
#endif
|
||||
|
||||
#define AUDIO_THREAD_INTERVAL_MS 100
|
||||
|
||||
class AudioThread : public concurrency::OSThread
|
||||
@@ -25,16 +20,12 @@ class AudioThread : public concurrency::OSThread
|
||||
|
||||
void beginRttl(const void *data, uint32_t len)
|
||||
{
|
||||
#ifdef T_LORA_PAGER
|
||||
io.digitalWrite(EXPANDS_AMP_EN, HIGH);
|
||||
#endif
|
||||
setCPUFast(true);
|
||||
rtttlFile = new AudioFileSourcePROGMEM(data, len);
|
||||
i2sRtttl = new AudioGeneratorRTTTL();
|
||||
i2sRtttl->begin(rtttlFile, audioOut);
|
||||
}
|
||||
|
||||
// Also handles actually playing the RTTTL, needs to be called in loop
|
||||
bool isPlaying()
|
||||
{
|
||||
if (i2sRtttl != nullptr) {
|
||||
@@ -50,16 +41,10 @@ class AudioThread : public concurrency::OSThread
|
||||
delete i2sRtttl;
|
||||
i2sRtttl = nullptr;
|
||||
}
|
||||
|
||||
if (rtttlFile != nullptr) {
|
||||
delete rtttlFile;
|
||||
rtttlFile = nullptr;
|
||||
}
|
||||
delete rtttlFile;
|
||||
rtttlFile = nullptr;
|
||||
|
||||
setCPUFast(false);
|
||||
#ifdef T_LORA_PAGER
|
||||
io.digitalWrite(EXPANDS_AMP_EN, LOW);
|
||||
#endif
|
||||
}
|
||||
|
||||
void readAloud(const char *text)
|
||||
@@ -70,16 +55,10 @@ class AudioThread : public concurrency::OSThread
|
||||
i2sRtttl = nullptr;
|
||||
}
|
||||
|
||||
#ifdef T_LORA_PAGER
|
||||
io.digitalWrite(EXPANDS_AMP_EN, HIGH);
|
||||
#endif
|
||||
ESP8266SAM *sam = new ESP8266SAM;
|
||||
sam->Say(audioOut, text);
|
||||
delete sam;
|
||||
setCPUFast(false);
|
||||
#ifdef T_LORA_PAGER
|
||||
io.digitalWrite(EXPANDS_AMP_EN, LOW);
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -102,9 +81,9 @@ class AudioThread : public concurrency::OSThread
|
||||
};
|
||||
|
||||
AudioGeneratorRTTTL *i2sRtttl = nullptr;
|
||||
AudioOutputI2S *audioOut = nullptr;
|
||||
AudioOutputI2S *audioOut;
|
||||
|
||||
AudioFileSourcePROGMEM *rtttlFile = nullptr;
|
||||
AudioFileSourcePROGMEM *rtttlFile;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -146,7 +146,7 @@ inline bool Syslog::_sendLog(uint16_t pri, const char *appName, const char *mess
|
||||
{
|
||||
int result;
|
||||
#ifdef ARCH_PORTDUINO
|
||||
bool utf = !portduino_config.ascii_logs;
|
||||
bool utf = !settingsMap[ascii_logs];
|
||||
#else
|
||||
bool utf = true;
|
||||
#endif
|
||||
|
||||
@@ -38,46 +38,4 @@ const char *DisplayFormatters::getModemPresetDisplayName(meshtastic_Config_LoRaC
|
||||
return useShortName ? "Custom" : "Invalid";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const char *DisplayFormatters::getDeviceRole(meshtastic_Config_DeviceConfig_Role role)
|
||||
{
|
||||
switch (role) {
|
||||
case meshtastic_Config_DeviceConfig_Role_CLIENT:
|
||||
return "Client";
|
||||
break;
|
||||
case meshtastic_Config_DeviceConfig_Role_CLIENT_MUTE:
|
||||
return "Client Mute";
|
||||
break;
|
||||
case meshtastic_Config_DeviceConfig_Role_CLIENT_HIDDEN:
|
||||
return "Client Hidden";
|
||||
break;
|
||||
case meshtastic_Config_DeviceConfig_Role_CLIENT_BASE:
|
||||
return "Client Base";
|
||||
break;
|
||||
case meshtastic_Config_DeviceConfig_Role_LOST_AND_FOUND:
|
||||
return "Lost and Found";
|
||||
break;
|
||||
case meshtastic_Config_DeviceConfig_Role_TRACKER:
|
||||
return "Tracker";
|
||||
break;
|
||||
case meshtastic_Config_DeviceConfig_Role_SENSOR:
|
||||
return "Sensor";
|
||||
break;
|
||||
case meshtastic_Config_DeviceConfig_Role_TAK:
|
||||
return "TAK";
|
||||
break;
|
||||
case meshtastic_Config_DeviceConfig_Role_TAK_TRACKER:
|
||||
return "TAK Tracker";
|
||||
break;
|
||||
case meshtastic_Config_DeviceConfig_Role_ROUTER:
|
||||
return "Router";
|
||||
break;
|
||||
case meshtastic_Config_DeviceConfig_Role_ROUTER_LATE:
|
||||
return "Router Late";
|
||||
break;
|
||||
default:
|
||||
return "Unknown";
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -6,5 +6,4 @@ class DisplayFormatters
|
||||
public:
|
||||
static const char *getModemPresetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset, bool useShortName,
|
||||
bool usePreset);
|
||||
static const char *getDeviceRole(meshtastic_Config_DeviceConfig_Role role);
|
||||
};
|
||||
|
||||
@@ -22,9 +22,6 @@ class GPSStatus : public Status
|
||||
|
||||
meshtastic_Position p = meshtastic_Position_init_default;
|
||||
|
||||
/// Time of last valid GPS fix (millis since boot)
|
||||
uint32_t lastFixMillis = 0;
|
||||
|
||||
public:
|
||||
GPSStatus() { statusType = STATUS_TYPE_GPS; }
|
||||
|
||||
@@ -86,9 +83,6 @@ class GPSStatus : public Status
|
||||
|
||||
uint32_t getNumSatellites() const { return p.sats_in_view; }
|
||||
|
||||
/// Return millis() when the last GPS fix occurred (0 = never)
|
||||
uint32_t getLastFixMillis() const { return lastFixMillis; }
|
||||
|
||||
bool matches(const GPSStatus *newStatus) const
|
||||
{
|
||||
#ifdef GPS_DEBUG
|
||||
@@ -120,9 +114,6 @@ class GPSStatus : public Status
|
||||
|
||||
if (isDirty) {
|
||||
if (hasLock) {
|
||||
// Record time of last valid GPS fix
|
||||
lastFixMillis = millis();
|
||||
|
||||
// In debug logs, identify position by @timestamp:stage (stage 3 = notify)
|
||||
LOG_DEBUG("New GPS pos@%x:3 lat=%f lon=%f alt=%d pdop=%.2f track=%.2f speed=%.2f sats=%d", p.timestamp,
|
||||
p.latitude_i * 1e-7, p.longitude_i * 1e-7, p.altitude, p.PDOP * 1e-2, p.ground_track * 1e-5,
|
||||
|
||||
@@ -14,16 +14,16 @@ class NodeStatus : public Status
|
||||
CallbackObserver<NodeStatus, const NodeStatus *> statusObserver =
|
||||
CallbackObserver<NodeStatus, const NodeStatus *>(this, &NodeStatus::updateStatus);
|
||||
|
||||
uint16_t numOnline = 0;
|
||||
uint16_t numTotal = 0;
|
||||
uint8_t numOnline = 0;
|
||||
uint8_t numTotal = 0;
|
||||
|
||||
uint16_t lastNumTotal = 0;
|
||||
uint8_t lastNumTotal = 0;
|
||||
|
||||
public:
|
||||
bool forceUpdate = false;
|
||||
|
||||
NodeStatus() { statusType = STATUS_TYPE_NODE; }
|
||||
NodeStatus(uint16_t numOnline, uint16_t numTotal, bool forceUpdate = false) : Status()
|
||||
NodeStatus(uint8_t numOnline, uint8_t numTotal, bool forceUpdate = false) : Status()
|
||||
{
|
||||
this->forceUpdate = forceUpdate;
|
||||
this->numOnline = numOnline;
|
||||
@@ -34,11 +34,11 @@ class NodeStatus : public Status
|
||||
|
||||
void observe(Observable<const NodeStatus *> *source) { statusObserver.observe(source); }
|
||||
|
||||
uint16_t getNumOnline() const { return numOnline; }
|
||||
uint8_t getNumOnline() const { return numOnline; }
|
||||
|
||||
uint16_t getNumTotal() const { return numTotal; }
|
||||
uint8_t getNumTotal() const { return numTotal; }
|
||||
|
||||
uint16_t getLastNumTotal() const { return lastNumTotal; }
|
||||
uint8_t getLastNumTotal() const { return lastNumTotal; }
|
||||
|
||||
bool matches(const NodeStatus *newStatus) const
|
||||
{
|
||||
@@ -56,7 +56,7 @@ class NodeStatus : public Status
|
||||
numTotal = newStatus->getNumTotal();
|
||||
}
|
||||
if (isDirty || newStatus->forceUpdate) {
|
||||
LOG_DEBUG("Node status update: %u online, %u total", numOnline, numTotal);
|
||||
LOG_DEBUG("Node status update: %d online, %d total", numOnline, numTotal);
|
||||
onNewStatus.notifyObservers(this);
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -194,7 +194,7 @@ static HasBatteryLevel *batteryLevel; // Default to NULL for no battery level se
|
||||
|
||||
#ifdef BATTERY_PIN
|
||||
|
||||
void battery_adcEnable()
|
||||
static void adcEnable()
|
||||
{
|
||||
#ifdef ADC_CTRL // enable adc voltage divider when we need to read
|
||||
#ifdef ADC_USE_PULLUP
|
||||
@@ -214,7 +214,7 @@ void battery_adcEnable()
|
||||
#endif
|
||||
}
|
||||
|
||||
static void battery_adcDisable()
|
||||
static void adcDisable()
|
||||
{
|
||||
#ifdef ADC_CTRL // disable adc voltage divider when we need to read
|
||||
#ifdef ADC_USE_PULLUP
|
||||
@@ -278,11 +278,6 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if defined(BATTERY_CHARGING_INV)
|
||||
// bit of trickery to show 99% up until the charge finishes
|
||||
if (!digitalRead(BATTERY_CHARGING_INV) && battery_SOC > 99)
|
||||
battery_SOC = 99;
|
||||
#endif
|
||||
return clamp((int)(battery_SOC), 0, 100);
|
||||
}
|
||||
|
||||
@@ -325,7 +320,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
uint32_t raw = 0;
|
||||
float scaled = 0;
|
||||
|
||||
battery_adcEnable();
|
||||
adcEnable();
|
||||
#ifdef ARCH_ESP32 // ADC block for espressif platforms
|
||||
raw = espAdcRead();
|
||||
scaled = esp_adc_cal_raw_to_voltage(raw, adc_characs);
|
||||
@@ -337,7 +332,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
raw = raw / BATTERY_SENSE_SAMPLES;
|
||||
scaled = operativeAdcMultiplier * ((1000 * AREF_VOLTAGE) / pow(2, BATTERY_SENSE_RESOLUTION_BITS)) * raw;
|
||||
#endif
|
||||
battery_adcDisable();
|
||||
adcDisable();
|
||||
|
||||
if (!initial_read_done) {
|
||||
// Flush the smoothing filter with an ADC reading, if the reading is plausibly correct
|
||||
@@ -460,8 +455,6 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
}
|
||||
// if it's not HIGH - check the battery
|
||||
#endif
|
||||
#elif defined(MUZI_BASE)
|
||||
return NRF_POWER->USBREGSTATUS & POWER_USBREGSTATUS_VBUSDETECT_Msk;
|
||||
#endif
|
||||
return getBattVoltage() > chargingVolt;
|
||||
}
|
||||
@@ -477,8 +470,6 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
#endif
|
||||
#ifdef EXT_CHRG_DETECT
|
||||
return digitalRead(EXT_CHRG_DETECT) == ext_chrg_detect_value;
|
||||
#elif defined(BATTERY_CHARGING_INV)
|
||||
return !digitalRead(BATTERY_CHARGING_INV);
|
||||
#else
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(DISABLE_INA_CHARGING_DETECTION)
|
||||
if (hasINA()) {
|
||||
@@ -571,7 +562,6 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
config.power.device_battery_ina_address) {
|
||||
if (!ina226Sensor.isInitialized())
|
||||
return ina226Sensor.runOnce() > 0;
|
||||
return ina226Sensor.isRunning();
|
||||
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260].first ==
|
||||
config.power.device_battery_ina_address) {
|
||||
if (!ina260Sensor.isInitialized())
|
||||
@@ -701,24 +691,7 @@ bool Power::setup()
|
||||
#ifdef NRF_APM
|
||||
found = true;
|
||||
#endif
|
||||
#ifdef EXT_PWR_DETECT
|
||||
attachInterrupt(
|
||||
EXT_PWR_DETECT,
|
||||
[]() {
|
||||
power->setIntervalFromNow(0);
|
||||
runASAP = true;
|
||||
},
|
||||
CHANGE);
|
||||
#endif
|
||||
#ifdef BATTERY_CHARGING_INV
|
||||
attachInterrupt(
|
||||
BATTERY_CHARGING_INV,
|
||||
[]() {
|
||||
power->setIntervalFromNow(0);
|
||||
runASAP = true;
|
||||
},
|
||||
CHANGE);
|
||||
#endif
|
||||
|
||||
enabled = found;
|
||||
low_voltage_counter = 0;
|
||||
|
||||
@@ -775,8 +748,6 @@ void Power::shutdown()
|
||||
if (screen) {
|
||||
#ifdef T_DECK_PRO
|
||||
screen->showSimpleBanner("Device is powered off.\nConnect USB to start!", 0); // T-Deck Pro has no power button
|
||||
#elif defined(USE_EINK)
|
||||
screen->showSimpleBanner("Shutting Down...", 2250); // dismiss after 3 seconds to avoid the banner on the sleep screen
|
||||
#else
|
||||
screen->showSimpleBanner("Shutting Down...", 0); // stays on screen
|
||||
#endif
|
||||
@@ -857,11 +828,8 @@ void Power::readPowerStatus()
|
||||
|
||||
// Notify any status instances that are observing us
|
||||
const PowerStatus powerStatus2 = PowerStatus(hasBattery, usbPowered, isChargingNow, batteryVoltageMv, batteryChargePercent);
|
||||
if (millis() > lastLogTime + 50 * 1000) {
|
||||
LOG_DEBUG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d", powerStatus2.getHasUSB(),
|
||||
powerStatus2.getIsCharging(), powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
|
||||
lastLogTime = millis();
|
||||
}
|
||||
LOG_DEBUG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d", powerStatus2.getHasUSB(), powerStatus2.getIsCharging(),
|
||||
powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
|
||||
newStatus.notifyObservers(&powerStatus2);
|
||||
#ifdef DEBUG_HEAP
|
||||
if (lastheap != memGet.getFreeHeap()) {
|
||||
@@ -924,8 +892,13 @@ void Power::readPowerStatus()
|
||||
low_voltage_counter++;
|
||||
LOG_DEBUG("Low voltage counter: %d/10", low_voltage_counter);
|
||||
if (low_voltage_counter > 10) {
|
||||
#ifdef ARCH_NRF52
|
||||
// We can't trigger deep sleep on NRF52, it's freezing the board
|
||||
LOG_DEBUG("Low voltage detected, but not trigger deep sleep");
|
||||
#else
|
||||
LOG_INFO("Low voltage detected, trigger deep sleep");
|
||||
powerFSM.trigger(EVENT_LOW_BATTERY);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
low_voltage_counter = 0;
|
||||
@@ -1453,7 +1426,7 @@ class LipoCharger : public HasBatteryLevel
|
||||
/**
|
||||
* return true if there is an external power source detected
|
||||
*/
|
||||
virtual bool isVbusIn() override { return PPM->isVbusIn(); }
|
||||
virtual bool isVbusIn() override { return PPM->getVbusVoltage() > 0; }
|
||||
|
||||
/**
|
||||
* return true if the battery is currently charging
|
||||
@@ -1565,4 +1538,4 @@ bool Power::meshSolarInit()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -57,21 +57,21 @@ static bool isPowered()
|
||||
|
||||
static void sdsEnter()
|
||||
{
|
||||
LOG_POWERFSM("State: SDS");
|
||||
LOG_DEBUG("State: SDS");
|
||||
// FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw
|
||||
doDeepSleep(Default::getConfiguredOrDefaultMs(config.power.sds_secs), false, false);
|
||||
}
|
||||
|
||||
static void lowBattSDSEnter()
|
||||
{
|
||||
LOG_POWERFSM("State: Lower batt SDS");
|
||||
LOG_DEBUG("State: Lower batt SDS");
|
||||
doDeepSleep(Default::getConfiguredOrDefaultMs(config.power.sds_secs), false, true);
|
||||
}
|
||||
extern Power *power;
|
||||
|
||||
static void shutdownEnter()
|
||||
{
|
||||
LOG_POWERFSM("State: SHUTDOWN");
|
||||
LOG_DEBUG("State: SHUTDOWN");
|
||||
shutdownAtMsec = millis();
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ static uint32_t secsSlept;
|
||||
|
||||
static void lsEnter()
|
||||
{
|
||||
LOG_POWERFSM("lsEnter begin, ls_secs=%u", config.power.ls_secs);
|
||||
LOG_INFO("lsEnter begin, ls_secs=%u", config.power.ls_secs);
|
||||
if (screen)
|
||||
screen->setOn(false);
|
||||
secsSlept = 0; // How long have we been sleeping this time
|
||||
@@ -155,12 +155,12 @@ static void lsIdle()
|
||||
|
||||
static void lsExit()
|
||||
{
|
||||
LOG_POWERFSM("State: lsExit");
|
||||
LOG_INFO("Exit state: LS");
|
||||
}
|
||||
|
||||
static void nbEnter()
|
||||
{
|
||||
LOG_POWERFSM("State: nbEnter");
|
||||
LOG_DEBUG("State: NB");
|
||||
if (screen)
|
||||
screen->setOn(false);
|
||||
#ifdef ARCH_ESP32
|
||||
@@ -173,7 +173,6 @@ static void nbEnter()
|
||||
|
||||
static void darkEnter()
|
||||
{
|
||||
LOG_POWERFSM("State: darkEnter");
|
||||
setBluetoothEnable(true);
|
||||
if (screen)
|
||||
screen->setOn(false);
|
||||
@@ -181,7 +180,7 @@ static void darkEnter()
|
||||
|
||||
static void serialEnter()
|
||||
{
|
||||
LOG_POWERFSM("State: serialEnter");
|
||||
LOG_DEBUG("State: SERIAL");
|
||||
setBluetoothEnable(false);
|
||||
if (screen) {
|
||||
screen->setOn(true);
|
||||
@@ -190,14 +189,13 @@ static void serialEnter()
|
||||
|
||||
static void serialExit()
|
||||
{
|
||||
LOG_POWERFSM("State: serialExit");
|
||||
// Turn bluetooth back on when we leave serial stream API
|
||||
setBluetoothEnable(true);
|
||||
}
|
||||
|
||||
static void powerEnter()
|
||||
{
|
||||
LOG_POWERFSM("State: powerEnter");
|
||||
// LOG_DEBUG("State: POWER");
|
||||
if (!isPowered()) {
|
||||
// If we got here, we are in the wrong state - we should be in powered, let that state handle things
|
||||
LOG_INFO("Loss of power in Powered");
|
||||
@@ -212,7 +210,6 @@ static void powerEnter()
|
||||
|
||||
static void powerIdle()
|
||||
{
|
||||
// LOG_POWERFSM("State: powerIdle"); // very chatty
|
||||
if (!isPowered()) {
|
||||
// If we got here, we are in the wrong state
|
||||
LOG_INFO("Loss of power in Powered");
|
||||
@@ -222,13 +219,14 @@ static void powerIdle()
|
||||
|
||||
static void powerExit()
|
||||
{
|
||||
LOG_POWERFSM("State: powerExit");
|
||||
if (screen)
|
||||
screen->setOn(true);
|
||||
setBluetoothEnable(true);
|
||||
}
|
||||
|
||||
static void onEnter()
|
||||
{
|
||||
LOG_POWERFSM("State: onEnter");
|
||||
LOG_DEBUG("State: ON");
|
||||
if (screen)
|
||||
screen->setOn(true);
|
||||
setBluetoothEnable(true);
|
||||
@@ -236,7 +234,6 @@ static void onEnter()
|
||||
|
||||
static void onIdle()
|
||||
{
|
||||
LOG_POWERFSM("State: onIdle");
|
||||
if (isPowered()) {
|
||||
// If we got here, we are in the wrong state - we should be in powered, let that state handle things
|
||||
powerFSM.trigger(EVENT_POWER_CONNECTED);
|
||||
@@ -245,7 +242,7 @@ static void onIdle()
|
||||
|
||||
static void bootEnter()
|
||||
{
|
||||
LOG_POWERFSM("State: bootEnter");
|
||||
LOG_DEBUG("State: BOOT");
|
||||
}
|
||||
|
||||
State stateSHUTDOWN(shutdownEnter, NULL, NULL, "SHUTDOWN");
|
||||
@@ -322,6 +319,11 @@ void PowerFSM_setup()
|
||||
// if any packet destined for phone arrives, turn on bluetooth at least
|
||||
powerFSM.add_transition(&stateNB, &stateDARK, EVENT_PACKET_FOR_PHONE, NULL, "Packet for phone");
|
||||
|
||||
// Removed 2.7: we don't show the nodes individually for every node on the screen anymore
|
||||
// powerFSM.add_transition(&stateNB, &stateON, EVENT_NODEDB_UPDATED, NULL, "NodeDB update");
|
||||
// powerFSM.add_transition(&stateDARK, &stateON, EVENT_NODEDB_UPDATED, NULL, "NodeDB update");
|
||||
// powerFSM.add_transition(&stateON, &stateON, EVENT_NODEDB_UPDATED, NULL, "NodeDB update");
|
||||
|
||||
// Show the received text message
|
||||
powerFSM.add_transition(&stateLS, &stateON, EVENT_RECEIVED_MSG, NULL, "Received text");
|
||||
powerFSM.add_transition(&stateNB, &stateON, EVENT_RECEIVED_MSG, NULL, "Received text");
|
||||
@@ -370,7 +372,7 @@ void PowerFSM_setup()
|
||||
// Don't add power saving transitions if we are a power saving tracker or sensor or have Wifi enabled. Sleep will be initiated
|
||||
// through the modules
|
||||
|
||||
#if HAS_WIFI && !defined(MESHTASTIC_EXCLUDE_WIFI)
|
||||
#if HAS_WIFI || !defined(MESHTASTIC_EXCLUDE_WIFI)
|
||||
bool isTrackerOrSensor = config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER ||
|
||||
config.device.role == meshtastic_Config_DeviceConfig_Role_TAK_TRACKER ||
|
||||
config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR;
|
||||
|
||||
@@ -2,12 +2,6 @@
|
||||
|
||||
#include "configuration.h"
|
||||
|
||||
#ifdef PowerFSMDebug
|
||||
#define LOG_POWERFSM(...) LOG_DEBUG(__VA_ARGS__)
|
||||
#else
|
||||
#define LOG_POWERFSM(...)
|
||||
#endif
|
||||
|
||||
// See sw-design.md for documentation
|
||||
|
||||
#define EVENT_PRESS 1
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "concurrency/OSThread.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include "memGet.h"
|
||||
#include "mesh/generated/meshtastic/mesh.pb.h"
|
||||
#include <assert.h>
|
||||
#include <cstring>
|
||||
@@ -58,7 +57,7 @@ size_t RedirectablePrint::vprintf(const char *logLevel, const char *format, va_l
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_PORTDUINO
|
||||
bool color = !portduino_config.ascii_logs;
|
||||
bool color = !settingsMap[ascii_logs];
|
||||
#else
|
||||
bool color = true;
|
||||
#endif
|
||||
@@ -100,7 +99,7 @@ void RedirectablePrint::log_to_serial(const char *logLevel, const char *format,
|
||||
size_t r = 0;
|
||||
|
||||
#ifdef ARCH_PORTDUINO
|
||||
bool color = !portduino_config.ascii_logs;
|
||||
bool color = !settingsMap[ascii_logs];
|
||||
#else
|
||||
bool color = true;
|
||||
#endif
|
||||
@@ -167,16 +166,6 @@ void RedirectablePrint::log_to_serial(const char *logLevel, const char *format,
|
||||
print(thread->ThreadName);
|
||||
print("] ");
|
||||
}
|
||||
|
||||
#ifdef DEBUG_HEAP
|
||||
// Add heap free space bytes prefix before every log message
|
||||
#ifdef ARCH_PORTDUINO
|
||||
::printf("[heap %u] ", memGet.getFreeHeap());
|
||||
#else
|
||||
printf("[heap %u] ", memGet.getFreeHeap());
|
||||
#endif
|
||||
#endif // DEBUG_HEAP
|
||||
|
||||
r += vprintf(logLevel, format, arg);
|
||||
}
|
||||
|
||||
@@ -299,7 +288,7 @@ void RedirectablePrint::log(const char *logLevel, const char *format, ...)
|
||||
#if ARCH_PORTDUINO
|
||||
// level trace is special, two possible ways to handle it.
|
||||
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0) {
|
||||
if (portduino_config.traceFilename != "") {
|
||||
if (settingsStrings[traceFilename] != "") {
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
try {
|
||||
@@ -308,18 +297,18 @@ void RedirectablePrint::log(const char *logLevel, const char *format, ...)
|
||||
}
|
||||
va_end(arg);
|
||||
}
|
||||
if (portduino_config.logoutputlevel < level_trace && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0) {
|
||||
if (settingsMap[logoutputlevel] < level_trace && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0) {
|
||||
delete[] newFormat;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (portduino_config.logoutputlevel < level_debug && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0) {
|
||||
if (settingsMap[logoutputlevel] < level_debug && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0) {
|
||||
delete[] newFormat;
|
||||
return;
|
||||
} else if (portduino_config.logoutputlevel < level_info && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0) {
|
||||
} else if (settingsMap[logoutputlevel] < level_info && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0) {
|
||||
delete[] newFormat;
|
||||
return;
|
||||
} else if (portduino_config.logoutputlevel < level_warn && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_WARN) == 0) {
|
||||
} else if (settingsMap[logoutputlevel] < level_warn && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_WARN) == 0) {
|
||||
delete[] newFormat;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6,14 +6,6 @@
|
||||
#include "configuration.h"
|
||||
#include "time.h"
|
||||
|
||||
#if defined(ARDUINO_USB_CDC_ON_BOOT) && ARDUINO_USB_CDC_ON_BOOT
|
||||
#define IS_USB_SERIAL
|
||||
#ifdef SERIAL_HAS_ON_RECEIVE
|
||||
#undef SERIAL_HAS_ON_RECEIVE
|
||||
#endif
|
||||
#include "HWCDC.h"
|
||||
#endif
|
||||
|
||||
#ifdef RP2040_SLOW_CLOCK
|
||||
#define Port Serial2
|
||||
#else
|
||||
@@ -30,12 +22,7 @@ SerialConsole *console;
|
||||
|
||||
void consoleInit()
|
||||
{
|
||||
auto sc = new SerialConsole(); // Must be dynamically allocated because we are now inheriting from thread
|
||||
|
||||
#if defined(SERIAL_HAS_ON_RECEIVE)
|
||||
// onReceive does only exist for HardwareSerial not for USB CDC serial
|
||||
Port.onReceive([sc]() { sc->rxInt(); });
|
||||
#endif
|
||||
new SerialConsole(); // Must be dynamically allocated because we are now inheriting from thread
|
||||
DEBUG_PORT.rpInit(); // Simply sets up semaphore
|
||||
}
|
||||
|
||||
@@ -50,7 +37,6 @@ void consolePrintf(const char *format, ...)
|
||||
|
||||
SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port), concurrency::OSThread("SerialConsole")
|
||||
{
|
||||
api_type = TYPE_SERIAL;
|
||||
assert(!console);
|
||||
console = this;
|
||||
canWrite = false; // We don't send packets to our port until it has talked to us first
|
||||
@@ -79,21 +65,14 @@ SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port), con
|
||||
int32_t SerialConsole::runOnce()
|
||||
{
|
||||
#ifdef HELTEC_MESH_SOLAR
|
||||
// After enabling the mesh solar serial port module configuration, command processing is handled by the serial port module.
|
||||
if (moduleConfig.serial.enabled && moduleConfig.serial.override_console_serial_port &&
|
||||
moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MS_CONFIG) {
|
||||
//After enabling the mesh solar serial port module configuration, command processing is handled by the serial port module.
|
||||
if(moduleConfig.serial.enabled && moduleConfig.serial.override_console_serial_port
|
||||
&& moduleConfig.serial.mode==meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MS_CONFIG)
|
||||
{
|
||||
return 250;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t delay = runOncePart();
|
||||
#if defined(SERIAL_HAS_ON_RECEIVE) || defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
return Port.available() ? delay : INT32_MAX;
|
||||
#elif defined(IS_USB_SERIAL)
|
||||
return HWCDC::isPlugged() ? delay : (1000 * 20);
|
||||
#else
|
||||
return delay;
|
||||
#endif
|
||||
return runOncePart();
|
||||
}
|
||||
|
||||
void SerialConsole::flush()
|
||||
@@ -101,18 +80,6 @@ void SerialConsole::flush()
|
||||
Port.flush();
|
||||
}
|
||||
|
||||
// trigger tx of serial data
|
||||
void SerialConsole::onNowHasData(uint32_t fromRadioNum)
|
||||
{
|
||||
setIntervalFromNow(0);
|
||||
}
|
||||
|
||||
// trigger rx of serial data
|
||||
void SerialConsole::rxInt()
|
||||
{
|
||||
setIntervalFromNow(0);
|
||||
}
|
||||
|
||||
// For the serial port we can't really detect if any client is on the other side, so instead just look for recent messages
|
||||
bool SerialConsole::checkIsConnected()
|
||||
{
|
||||
|
||||
@@ -32,14 +32,11 @@ class SerialConsole : public StreamAPI, public RedirectablePrint, private concur
|
||||
virtual int32_t runOnce() override;
|
||||
|
||||
void flush();
|
||||
void rxInt();
|
||||
|
||||
protected:
|
||||
/// Check the current underlying physical link to see if the client is currently connected
|
||||
virtual bool checkIsConnected() override;
|
||||
|
||||
virtual void onNowHasData(uint32_t fromRadioNum) override;
|
||||
|
||||
/// Possibly switch to protobufs if we see a valid protobuf message
|
||||
virtual void log_to_serial(const char *logLevel, const char *format, va_list arg);
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
BuzzerFeedbackThread *buzzerFeedbackThread;
|
||||
|
||||
BuzzerFeedbackThread::BuzzerFeedbackThread()
|
||||
BuzzerFeedbackThread::BuzzerFeedbackThread() : OSThread("BuzzerFeedback")
|
||||
{
|
||||
if (inputBroker)
|
||||
inputObserver.observe(inputBroker);
|
||||
@@ -15,24 +15,24 @@ int BuzzerFeedbackThread::handleInputEvent(const InputEvent *event)
|
||||
{
|
||||
// Only provide feedback if buzzer is enabled for notifications
|
||||
if (config.device.buzzer_mode == meshtastic_Config_DeviceConfig_BuzzerMode_DISABLED ||
|
||||
config.device.buzzer_mode == meshtastic_Config_DeviceConfig_BuzzerMode_NOTIFICATIONS_ONLY ||
|
||||
config.device.buzzer_mode == meshtastic_Config_DeviceConfig_BuzzerMode_DIRECT_MSG_ONLY) {
|
||||
config.device.buzzer_mode == meshtastic_Config_DeviceConfig_BuzzerMode_NOTIFICATIONS_ONLY) {
|
||||
return 0; // Let other handlers process the event
|
||||
}
|
||||
|
||||
// Track last event time for potential future use
|
||||
lastEventTime = millis();
|
||||
needsUpdate = true;
|
||||
|
||||
// Handle different input events with appropriate buzzer feedback
|
||||
switch (event->inputEvent) {
|
||||
case INPUT_BROKER_USER_PRESS:
|
||||
case INPUT_BROKER_ALT_PRESS:
|
||||
case INPUT_BROKER_SELECT:
|
||||
case INPUT_BROKER_SELECT_LONG:
|
||||
playBeep(); // Confirmation feedback
|
||||
break;
|
||||
|
||||
case INPUT_BROKER_UP:
|
||||
case INPUT_BROKER_UP_LONG:
|
||||
case INPUT_BROKER_DOWN:
|
||||
case INPUT_BROKER_DOWN_LONG:
|
||||
case INPUT_BROKER_LEFT:
|
||||
case INPUT_BROKER_RIGHT:
|
||||
playChirp(); // Navigation feedback
|
||||
@@ -58,4 +58,15 @@ int BuzzerFeedbackThread::handleInputEvent(const InputEvent *event)
|
||||
}
|
||||
|
||||
return 0; // Allow other handlers to process the event
|
||||
}
|
||||
}
|
||||
|
||||
int32_t BuzzerFeedbackThread::runOnce()
|
||||
{
|
||||
// This thread is primarily event-driven, but we can use runOnce
|
||||
// for any periodic tasks if needed in the future
|
||||
|
||||
needsUpdate = false;
|
||||
|
||||
// Run every 100ms when active, less frequently when idle
|
||||
return needsUpdate ? 100 : 1000;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "concurrency/OSThread.h"
|
||||
#include "input/InputBroker.h"
|
||||
|
||||
class BuzzerFeedbackThread
|
||||
class BuzzerFeedbackThread : public concurrency::OSThread
|
||||
{
|
||||
CallbackObserver<BuzzerFeedbackThread, const InputEvent *> inputObserver =
|
||||
CallbackObserver<BuzzerFeedbackThread, const InputEvent *>(this, &BuzzerFeedbackThread::handleInputEvent);
|
||||
@@ -12,6 +12,13 @@ class BuzzerFeedbackThread
|
||||
public:
|
||||
BuzzerFeedbackThread();
|
||||
int handleInputEvent(const InputEvent *event);
|
||||
|
||||
protected:
|
||||
virtual int32_t runOnce() override;
|
||||
|
||||
private:
|
||||
uint32_t lastEventTime = 0;
|
||||
bool needsUpdate = false;
|
||||
};
|
||||
|
||||
extern BuzzerFeedbackThread *buzzerFeedbackThread;
|
||||
|
||||
@@ -90,9 +90,7 @@ void OSThread::run()
|
||||
if (heap < newHeap)
|
||||
LOG_HEAP("++++++ Thread %s freed heap %d -> %d (%d) ++++++", ThreadName.c_str(), heap, newHeap, newHeap - heap);
|
||||
#endif
|
||||
#ifdef DEBUG_LOOP_TIMING
|
||||
LOG_DEBUG("====== Thread next run in: %d", newDelay);
|
||||
#endif
|
||||
|
||||
runned();
|
||||
|
||||
if (newDelay >= 0)
|
||||
|
||||
@@ -33,32 +33,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "pcf8563.h"
|
||||
#endif
|
||||
|
||||
/* Offer chance for variant-specific defines */
|
||||
#include "variant.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Display feature overrides
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Allow build environments to opt-in explicitly to the E-Ink UI stack while
|
||||
// keeping headless targets slim by default. Existing variants that already
|
||||
// define USE_EINK continue to work without additional flags.
|
||||
#ifndef MESHTASTIC_USE_EINK_UI
|
||||
#ifdef USE_EINK
|
||||
#define MESHTASTIC_USE_EINK_UI 1
|
||||
#else
|
||||
#define MESHTASTIC_USE_EINK_UI 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if MESHTASTIC_USE_EINK_UI
|
||||
#ifndef USE_EINK
|
||||
#define USE_EINK
|
||||
#endif
|
||||
#else
|
||||
#undef USE_EINK
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Version
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -143,17 +117,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define SX126X_MAX_POWER 22
|
||||
#endif
|
||||
|
||||
#ifdef USE_GC1109_PA
|
||||
// Power Amps are often non-linear, so we can use an array of values for the power curve
|
||||
#define NUM_PA_POINTS 22
|
||||
#define TX_GAIN_LORA 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 9, 8, 7
|
||||
#endif
|
||||
|
||||
#ifdef RAK13302
|
||||
#define NUM_PA_POINTS 22
|
||||
#define TX_GAIN_LORA 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8
|
||||
#endif
|
||||
|
||||
// Default system gain to 0 if not defined
|
||||
#ifndef TX_GAIN_LORA
|
||||
#define TX_GAIN_LORA 0
|
||||
@@ -251,7 +214,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define ICM20948_ADDR_ALT 0x68
|
||||
#define BHI260AP_ADDR 0x28
|
||||
#define BMM150_ADDR 0x13
|
||||
#define DA217_ADDR 0x26
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// LED
|
||||
@@ -273,9 +235,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// Touchscreen
|
||||
// -----------------------------------------------------------------------------
|
||||
#define FT6336U_ADDR 0x48
|
||||
#define CST328_ADDR 0x1A // same address as CST226SE
|
||||
#define CHSC6X_ADDR 0x2E
|
||||
#define CST226SE_ADDR_ALT 0x5A
|
||||
#define CST328_ADDR 0x1A
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// RAK12035VB Soil Monitor (using RAK12023 up to 3 RAK12035 monitors can be connected)
|
||||
@@ -294,18 +254,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// convert 24-bit color to 16-bit (56K)
|
||||
#define COLOR565(r, g, b) (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3))
|
||||
|
||||
/* Step #1: offer chance for variant-specific defines */
|
||||
#include "variant.h"
|
||||
|
||||
#if defined(VEXT_ENABLE) && !defined(VEXT_ON_VALUE)
|
||||
// Older variant.h files might not be defining this value, so stay with the old default
|
||||
#define VEXT_ON_VALUE LOW
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Rotary encoder
|
||||
// -----------------------------------------------------------------------------
|
||||
#ifndef ROTARY_DELAY
|
||||
#define ROTARY_DELAY 5
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// GPS
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -394,9 +350,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#ifndef HAS_BLUETOOTH
|
||||
#define HAS_BLUETOOTH 0
|
||||
#endif
|
||||
#ifndef USE_TFTDISPLAY
|
||||
#define USE_TFTDISPLAY 0
|
||||
#endif
|
||||
|
||||
#ifndef HW_VENDOR
|
||||
#error HW_VENDOR must be defined
|
||||
@@ -423,13 +376,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define HAS_RGB_LED
|
||||
#endif
|
||||
|
||||
#ifndef LED_STATE_OFF
|
||||
#define LED_STATE_OFF 0
|
||||
#endif
|
||||
#ifndef LED_STATE_ON
|
||||
#define LED_STATE_ON 1
|
||||
#endif
|
||||
|
||||
// default mapping of pins
|
||||
#if defined(PIN_BUTTON2) && !defined(CANCEL_BUTTON_PIN)
|
||||
#define ALT_BUTTON_PIN PIN_BUTTON2
|
||||
|
||||
@@ -25,8 +25,8 @@ ScanI2C::FoundDevice ScanI2C::firstScreen() const
|
||||
|
||||
ScanI2C::FoundDevice ScanI2C::firstRTC() const
|
||||
{
|
||||
ScanI2C::DeviceType types[] = {RTC_RV3028, RTC_PCF8563, RTC_RX8130CE};
|
||||
return firstOfOrNONE(3, types);
|
||||
ScanI2C::DeviceType types[] = {RTC_RV3028, RTC_PCF8563};
|
||||
return firstOfOrNONE(2, types);
|
||||
}
|
||||
|
||||
ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
|
||||
|
||||
@@ -14,7 +14,6 @@ class ScanI2C
|
||||
SCREEN_ST7567,
|
||||
RTC_RV3028,
|
||||
RTC_PCF8563,
|
||||
RTC_RX8130CE,
|
||||
CARDKB,
|
||||
TDECKKB,
|
||||
BBQ10KB,
|
||||
@@ -82,11 +81,7 @@ class ScanI2C
|
||||
BHI260AP,
|
||||
BMM150,
|
||||
TSL2561,
|
||||
DRV2605,
|
||||
BH1750,
|
||||
DA217,
|
||||
CHSC6X,
|
||||
CST226SE
|
||||
DRV2605
|
||||
} DeviceType;
|
||||
|
||||
// typedef uint8_t DeviceAddress;
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#include "ScanI2CConsumer.h"
|
||||
#include <forward_list>
|
||||
|
||||
static std::forward_list<ScanI2CConsumer *> ScanI2CConsumers;
|
||||
|
||||
ScanI2CConsumer::ScanI2CConsumer()
|
||||
{
|
||||
ScanI2CConsumers.push_front(this);
|
||||
}
|
||||
|
||||
void ScanI2CCompleted(ScanI2C *i2cScanner)
|
||||
{
|
||||
for (ScanI2CConsumer *consumer : ScanI2CConsumers) {
|
||||
consumer->i2cScanFinished(i2cScanner);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "ScanI2C.h"
|
||||
#include <stddef.h>
|
||||
|
||||
class ScanI2CConsumer
|
||||
{
|
||||
public:
|
||||
ScanI2CConsumer();
|
||||
virtual void i2cScanFinished(ScanI2C *i2cScanner) = 0;
|
||||
};
|
||||
|
||||
void ScanI2CCompleted(ScanI2C *i2cScanner);
|
||||
@@ -106,7 +106,6 @@ uint16_t ScanI2CTwoWire::getRegisterValue(const ScanI2CTwoWire::RegisterLocation
|
||||
if (i2cBus->available())
|
||||
i2cBus->read();
|
||||
}
|
||||
LOG_DEBUG("Register value: 0x%x", value);
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -198,9 +197,6 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
#ifdef PCF8563_RTC
|
||||
SCAN_SIMPLE_CASE(PCF8563_RTC, RTC_PCF8563, "PCF8563", (uint8_t)addr.address)
|
||||
#endif
|
||||
#ifdef RX8130CE_RTC
|
||||
SCAN_SIMPLE_CASE(RX8130CE_RTC, RTC_RX8130CE, "RX8130CE", (uint8_t)addr.address)
|
||||
#endif
|
||||
|
||||
case CARDKB_ADDR:
|
||||
// Do we have the RAK14006 instead?
|
||||
@@ -378,13 +374,13 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
}
|
||||
case SHT31_4x_ADDR: // same as OPT3001_ADDR_ALT
|
||||
case SHT31_4x_ADDR_ALT: // same as OPT3001_ADDR
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x7E), 2);
|
||||
if (registerValue == 0x5449) {
|
||||
type = OPT3001;
|
||||
logFoundDevice("OPT3001", (uint8_t)addr.address);
|
||||
} else if (getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x89), 2) != 0) { // unique SHT4x serial number
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x89), 2);
|
||||
if (registerValue == 0x11a2 || registerValue == 0x11da || registerValue == 0xe9c || registerValue == 0xc8d) {
|
||||
type = SHT4X;
|
||||
logFoundDevice("SHT4X", (uint8_t)addr.address);
|
||||
} else if (getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x7E), 2) == 0x5449) {
|
||||
type = OPT3001;
|
||||
logFoundDevice("OPT3001", (uint8_t)addr.address);
|
||||
} else {
|
||||
type = SHT31;
|
||||
logFoundDevice("SHT31", (uint8_t)addr.address);
|
||||
@@ -465,23 +461,8 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
break;
|
||||
|
||||
SCAN_SIMPLE_CASE(LSM6DS3_ADDR, LSM6DS3, "LSM6DS3", (uint8_t)addr.address);
|
||||
SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555", (uint8_t)addr.address);
|
||||
SCAN_SIMPLE_CASE(VEML7700_ADDR, VEML7700, "VEML7700", (uint8_t)addr.address);
|
||||
case TCA9555_ADDR:
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x01), 1);
|
||||
if (registerValue == 0x13) {
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1);
|
||||
if (registerValue == 0x81) {
|
||||
type = DA217;
|
||||
logFoundDevice("DA217", (uint8_t)addr.address);
|
||||
} else {
|
||||
type = TCA9555;
|
||||
logFoundDevice("TCA9555", (uint8_t)addr.address);
|
||||
}
|
||||
} else {
|
||||
type = TCA9555;
|
||||
logFoundDevice("TCA9555", (uint8_t)addr.address);
|
||||
}
|
||||
break;
|
||||
case TSL25911_ADDR:
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x12), 1);
|
||||
if (registerValue == 0x50) {
|
||||
@@ -499,38 +480,8 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
SCAN_SIMPLE_CASE(DFROBOT_RAIN_ADDR, DFROBOT_RAIN, "DFRobot Rain Gauge", (uint8_t)addr.address);
|
||||
SCAN_SIMPLE_CASE(LTR390UV_ADDR, LTR390UV, "LTR390UV", (uint8_t)addr.address);
|
||||
SCAN_SIMPLE_CASE(PCT2075_ADDR, PCT2075, "PCT2075", (uint8_t)addr.address);
|
||||
case CST328_ADDR:
|
||||
// Do we have the CST328 or the CST226SE
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xAB), 1);
|
||||
if (registerValue == 0xA9) {
|
||||
type = CST226SE;
|
||||
logFoundDevice("CST226SE", (uint8_t)addr.address);
|
||||
} else {
|
||||
type = CST328;
|
||||
logFoundDevice("CST328", (uint8_t)addr.address);
|
||||
}
|
||||
break;
|
||||
|
||||
SCAN_SIMPLE_CASE(CHSC6X_ADDR, CHSC6X, "CHSC6X", (uint8_t)addr.address);
|
||||
case LTR553ALS_ADDR:
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x86), 1); // Part ID register
|
||||
if (registerValue == 0x92) { // LTR553ALS Part ID
|
||||
type = LTR553ALS;
|
||||
logFoundDevice("LTR553ALS", (uint8_t)addr.address);
|
||||
} else {
|
||||
// Test BH1750 - send power on command
|
||||
i2cBus->beginTransmission(addr.address);
|
||||
i2cBus->write(0x01); // Power On command
|
||||
uint8_t bh1750_error = i2cBus->endTransmission();
|
||||
if (bh1750_error == 0) {
|
||||
type = BH1750;
|
||||
logFoundDevice("BH1750", (uint8_t)addr.address);
|
||||
} else {
|
||||
LOG_INFO("Device found at address 0x%x was not able to be enumerated", (uint8_t)addr.address);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
SCAN_SIMPLE_CASE(CST328_ADDR, CST328, "CST328", (uint8_t)addr.address);
|
||||
SCAN_SIMPLE_CASE(LTR553ALS_ADDR, LTR553ALS, "LTR553ALS", (uint8_t)addr.address);
|
||||
SCAN_SIMPLE_CASE(BHI260AP_ADDR, BHI260AP, "BHI260AP", (uint8_t)addr.address);
|
||||
SCAN_SIMPLE_CASE(SCD4X_ADDR, SCD4X, "SCD4X", (uint8_t)addr.address);
|
||||
SCAN_SIMPLE_CASE(BMM150_ADDR, BMM150, "BMM150", (uint8_t)addr.address);
|
||||
@@ -539,12 +490,8 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
#endif
|
||||
|
||||
case MLX90614_ADDR_DEF:
|
||||
// Do we have the MLX90614 or the MPR121KB or the CST226SE
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x06), 1);
|
||||
if (registerValue == 0xAB) {
|
||||
type = CST226SE;
|
||||
logFoundDevice("CST226SE", (uint8_t)addr.address);
|
||||
} else if (getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0e), 1) == 0x5a) {
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0e), 1);
|
||||
if (registerValue == 0x5a) {
|
||||
type = MLX90614;
|
||||
logFoundDevice("MLX90614", (uint8_t)addr.address);
|
||||
} else {
|
||||
@@ -562,11 +509,6 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
case ICM20948_ADDR: // same as BMX160_ADDR
|
||||
case ICM20948_ADDR_ALT: // same as MPU6050_ADDR
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1);
|
||||
#ifdef HAS_ICM20948
|
||||
type = ICM20948;
|
||||
logFoundDevice("ICM20948", (uint8_t)addr.address);
|
||||
break;
|
||||
#endif
|
||||
if (registerValue == 0xEA) {
|
||||
type = ICM20948;
|
||||
logFoundDevice("ICM20948", (uint8_t)addr.address);
|
||||
@@ -635,7 +577,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
|
||||
scanPort(port, nullptr, 0);
|
||||
}
|
||||
|
||||
TwoWire *ScanI2CTwoWire::fetchI2CBus(ScanI2C::DeviceAddress address)
|
||||
TwoWire *ScanI2CTwoWire::fetchI2CBus(ScanI2C::DeviceAddress address) const
|
||||
{
|
||||
if (address.port == ScanI2C::I2CPort::WIRE) {
|
||||
return &Wire;
|
||||
|
||||
@@ -23,12 +23,12 @@ class ScanI2CTwoWire : public ScanI2C
|
||||
|
||||
ScanI2C::FoundDevice find(ScanI2C::DeviceType) const override;
|
||||
|
||||
TwoWire *fetchI2CBus(ScanI2C::DeviceAddress) const;
|
||||
|
||||
bool exists(ScanI2C::DeviceType) const override;
|
||||
|
||||
size_t countDevices() const override;
|
||||
|
||||
static TwoWire *fetchI2CBus(ScanI2C::DeviceAddress);
|
||||
|
||||
protected:
|
||||
FoundDevice firstOfOrNONE(size_t, DeviceType[]) const override;
|
||||
|
||||
|
||||
539
src/gps/GPS.cpp
539
src/gps/GPS.cpp
@@ -38,16 +38,14 @@ template <typename T, std::size_t N> std::size_t array_count(const T (&)[N])
|
||||
return N;
|
||||
}
|
||||
|
||||
#ifndef GPS_SERIAL_PORT
|
||||
#define GPS_SERIAL_PORT Serial1
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_NRF52)
|
||||
Uart *GPS::_serial_gps = &GPS_SERIAL_PORT;
|
||||
#elif defined(ARCH_ESP32) || defined(ARCH_PORTDUINO) || defined(ARCH_STM32WL)
|
||||
#if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(ARCH_ESP32) || defined(ARCH_PORTDUINO) || defined(ARCH_STM32WL)
|
||||
#if defined(GPS_SERIAL_PORT)
|
||||
HardwareSerial *GPS::_serial_gps = &GPS_SERIAL_PORT;
|
||||
#else
|
||||
HardwareSerial *GPS::_serial_gps = &Serial1;
|
||||
#endif
|
||||
#elif defined(ARCH_RP2040)
|
||||
SerialUART *GPS::_serial_gps = &GPS_SERIAL_PORT;
|
||||
SerialUART *GPS::_serial_gps = &Serial1;
|
||||
#else
|
||||
HardwareSerial *GPS::_serial_gps = nullptr;
|
||||
#endif
|
||||
@@ -242,9 +240,6 @@ GPS_RESPONSE GPS::getACK(const char *message, uint32_t waitMillis)
|
||||
buffer[bytesRead] = b;
|
||||
bytesRead++;
|
||||
if ((bytesRead == 767) || (b == '\r')) {
|
||||
#ifdef GPS_DEBUG
|
||||
LOG_DEBUG(debugmsg.c_str());
|
||||
#endif
|
||||
if (strnstr((char *)buffer, message, bytesRead) != nullptr) {
|
||||
#ifdef GPS_DEBUG
|
||||
LOG_DEBUG("Found: %s", message); // Log the found message
|
||||
@@ -252,6 +247,9 @@ GPS_RESPONSE GPS::getACK(const char *message, uint32_t waitMillis)
|
||||
return GNSS_RESPONSE_OK;
|
||||
} else {
|
||||
bytesRead = 0;
|
||||
#ifdef GPS_DEBUG
|
||||
LOG_DEBUG(debugmsg.c_str());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -496,27 +494,38 @@ bool GPS::setup()
|
||||
if (!didSerialInit) {
|
||||
int msglen = 0;
|
||||
if (tx_gpio && gnssModel == GNSS_MODEL_UNKNOWN) {
|
||||
#ifdef TRACKER_T1000_E
|
||||
// add power up/down strategy, improve ag3335 detection success
|
||||
digitalWrite(PIN_GPS_EN, LOW);
|
||||
delay(500);
|
||||
digitalWrite(GPS_VRTC_EN, LOW);
|
||||
delay(1000);
|
||||
digitalWrite(GPS_VRTC_EN, HIGH);
|
||||
delay(500);
|
||||
digitalWrite(PIN_GPS_EN, HIGH);
|
||||
delay(1000);
|
||||
#endif
|
||||
if (probeTries < GPS_PROBETRIES) {
|
||||
LOG_DEBUG("Probe for GPS at %d", serialSpeeds[speedSelect]);
|
||||
gnssModel = probe(serialSpeeds[speedSelect]);
|
||||
if (gnssModel == GNSS_MODEL_UNKNOWN) {
|
||||
if (currentStep == 0 && ++speedSelect == array_count(serialSpeeds)) {
|
||||
if (++speedSelect == array_count(serialSpeeds)) {
|
||||
speedSelect = 0;
|
||||
++probeTries;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Rare Serial Speeds
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32C6
|
||||
if (probeTries == GPS_PROBETRIES) {
|
||||
LOG_DEBUG("Probe for GPS at %d", rareSerialSpeeds[speedSelect]);
|
||||
gnssModel = probe(rareSerialSpeeds[speedSelect]);
|
||||
if (gnssModel == GNSS_MODEL_UNKNOWN) {
|
||||
if (currentStep == 0 && ++speedSelect == array_count(rareSerialSpeeds)) {
|
||||
if (++speedSelect == array_count(rareSerialSpeeds)) {
|
||||
LOG_WARN("Give up on GPS probe and set to %d", GPS_BAUDRATE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (gnssModel != GNSS_MODEL_UNKNOWN) {
|
||||
@@ -798,14 +807,6 @@ bool GPS::setup()
|
||||
} else {
|
||||
LOG_INFO("GNSS module configuration saved!");
|
||||
}
|
||||
} else if (gnssModel == GNSS_MODEL_CM121) {
|
||||
// only ask for RMC and GGA
|
||||
// enable GGA
|
||||
_serial_gps->write("$CFGMSG,0,0,1,1*1B\r\n");
|
||||
delay(250);
|
||||
// enable RMC
|
||||
_serial_gps->write("$CFGMSG,0,4,1,1*1F\r\n");
|
||||
delay(250);
|
||||
}
|
||||
didSerialInit = true;
|
||||
}
|
||||
@@ -1022,7 +1023,7 @@ void GPS::down()
|
||||
LOG_DEBUG("%us until next search", sleepTime / 1000);
|
||||
|
||||
// If update interval less than 10 seconds, no attempt to sleep
|
||||
if (updateInterval <= GPS_UPDATE_ALWAYS_ON_THRESHOLD_MS || sleepTime == 0)
|
||||
if (updateInterval <= 10 * 1000UL || sleepTime == 0)
|
||||
setPowerState(GPS_IDLE);
|
||||
|
||||
else {
|
||||
@@ -1083,7 +1084,7 @@ int32_t GPS::runOnce()
|
||||
return disable();
|
||||
}
|
||||
if (!setup())
|
||||
return currentDelay; // Setup failed, re-run in two seconds
|
||||
return 2000; // Setup failed, re-run in two seconds
|
||||
|
||||
// We have now loaded our saved preferences from flash
|
||||
if (config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_ENABLED) {
|
||||
@@ -1093,29 +1094,11 @@ int32_t GPS::runOnce()
|
||||
publishUpdate();
|
||||
}
|
||||
|
||||
// ======================== GPS_ACTIVE state ========================
|
||||
// In GPS_ACTIVE state, GPS is powered on and we're receiving NMEA messages.
|
||||
// We use the following logic to determine when to update the local position
|
||||
// or time by running GPS::publishUpdate.
|
||||
// Note: Local position update is asynchronous to position broadcast. We
|
||||
// generally run this state every gps_update_interval seconds, and in most cases
|
||||
// gps_update_interval is faster than the position broadcast interval so there's a
|
||||
// fresh position ready when the device wants to broadcast one on the mesh.
|
||||
//
|
||||
// 1. Got a time for the first time --> set the time, don't publish.
|
||||
// 2. Got a lock for the first time
|
||||
// --> If gps_update_interval is <= 10s --> publishUpdate
|
||||
// --> Otherwise, hold for MIN(gps_update_interval - GPS_UPDATE_ALWAYS_ON_THRESHOLD_MS, 20s)
|
||||
// 3. Got a lock after turning back on
|
||||
// --> If gps_update_interval is <= 10s --> publishUpdate
|
||||
// --> Otherwise, hold for MIN(gps_update_interval - GPS_UPDATE_ALWAYS_ON_THRESHOLD_MS, 20s)
|
||||
// 4. Hold has expired
|
||||
// --> If we have a time and a location --> publishUpdate
|
||||
// --> down()
|
||||
// 5. Search time has expired
|
||||
// --> If we have a time and a location --> publishUpdate
|
||||
// --> If we had a location before but don't now --> publishUpdate
|
||||
// --> down()
|
||||
// Repeaters have no need for GPS
|
||||
if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
|
||||
return disable();
|
||||
}
|
||||
|
||||
if (whileActive()) {
|
||||
// if we have received valid NMEA claim we are connected
|
||||
setConnected();
|
||||
@@ -1125,81 +1108,55 @@ int32_t GPS::runOnce()
|
||||
if (!config.position.fixed_position && powerState != GPS_ACTIVE && scheduling.isUpdateDue())
|
||||
up();
|
||||
|
||||
// quality of the previous fix. We set it to 0 when we go down, so it's a way
|
||||
// to check if we're getting a lock after being GPS_OFF.
|
||||
// If we've already set time from the GPS, no need to ask the GPS
|
||||
bool gotTime = (getRTCQuality() >= RTCQualityGPS);
|
||||
if (!gotTime && lookForTime()) { // Note: we count on this && short-circuiting and not resetting the RTC time
|
||||
gotTime = true;
|
||||
shouldPublish = true;
|
||||
}
|
||||
|
||||
uint8_t prev_fixQual = fixQual;
|
||||
bool gotLoc = lookForLocation();
|
||||
if (gotLoc && !hasValidLocation) { // declare that we have location ASAP
|
||||
LOG_DEBUG("hasValidLocation RISING EDGE");
|
||||
hasValidLocation = true;
|
||||
shouldPublish = true;
|
||||
// Hold for 20secs after getting a lock to download ephemeris etc
|
||||
fixHoldEnds = millis() + 20000;
|
||||
}
|
||||
|
||||
if (powerState == GPS_ACTIVE) {
|
||||
// if gps_update_interval is <=10s, GPS never goes off, so we treat that differently
|
||||
uint32_t updateInterval = Default::getConfiguredOrDefaultMs(config.position.gps_update_interval);
|
||||
if (gotLoc && prev_fixQual == 0) { // just got a lock after turning back on.
|
||||
fixHoldEnds = millis() + 20000;
|
||||
shouldPublish = true; // Publish immediately, since next publish is at end of hold
|
||||
}
|
||||
|
||||
// 1. Got a time for the first time
|
||||
bool gotTime = (getRTCQuality() >= RTCQualityGPS);
|
||||
if (!gotTime && lookForTime()) { // Note: we count on this && short-circuiting and not resetting the RTC time
|
||||
gotTime = true;
|
||||
}
|
||||
bool tooLong = scheduling.searchedTooLong();
|
||||
if (tooLong)
|
||||
LOG_WARN("Couldn't publish a valid location: didn't get a GPS lock in time");
|
||||
|
||||
// 2. Got a lock for the first time, or 3. Got a lock after turning back on
|
||||
bool gotLoc = lookForLocation();
|
||||
if (gotLoc) {
|
||||
#ifdef GPS_DEBUG
|
||||
if (!hasValidLocation) { // declare that we have location ASAP
|
||||
LOG_DEBUG("hasValidLocation RISING EDGE");
|
||||
}
|
||||
#endif
|
||||
if (updateInterval <= GPS_UPDATE_ALWAYS_ON_THRESHOLD_MS) {
|
||||
hasValidLocation = true;
|
||||
shouldPublish = true;
|
||||
} else if (!hasValidLocation || prev_fixQual == 0 || (fixHoldEnds + GPS_THREAD_INTERVAL) < millis()) {
|
||||
hasValidLocation = true;
|
||||
// Hold for up to 20secs after getting a lock to download ephemeris etc
|
||||
uint32_t holdTime = updateInterval - GPS_UPDATE_ALWAYS_ON_THRESHOLD_MS;
|
||||
if (holdTime > GPS_FIX_HOLD_MAX_MS)
|
||||
holdTime = GPS_FIX_HOLD_MAX_MS;
|
||||
fixHoldEnds = millis() + holdTime;
|
||||
#ifdef GPS_DEBUG
|
||||
LOG_DEBUG("Holding for %ums after lock", holdTime);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool tooLong = scheduling.searchedTooLong();
|
||||
// Once we get a location we no longer desperately want an update
|
||||
if ((gotLoc && gotTime) || tooLong) {
|
||||
if (tooLong && !gotLoc) {
|
||||
LOG_WARN("Couldn't publish a valid location: didn't get a GPS lock in time");
|
||||
// we didn't get a location during this ack window, therefore declare loss of lock
|
||||
if (hasValidLocation) {
|
||||
p = meshtastic_Position_init_default;
|
||||
hasValidLocation = false;
|
||||
shouldPublish = true;
|
||||
#ifdef GPS_DEBUG
|
||||
LOG_DEBUG("hasValidLocation FALLING EDGE");
|
||||
#endif
|
||||
}
|
||||
p = meshtastic_Position_init_default;
|
||||
hasValidLocation = false;
|
||||
}
|
||||
|
||||
// Hold has expired , Search time has expired, we got a time only, or we never needed to hold.
|
||||
bool holdExpired = (fixHoldEnds != 0 && millis() > fixHoldEnds);
|
||||
if (shouldPublish || tooLong || holdExpired) {
|
||||
if (gotTime && hasValidLocation) {
|
||||
shouldPublish = true;
|
||||
}
|
||||
if (shouldPublish) {
|
||||
fixHoldEnds = 0;
|
||||
publishUpdate();
|
||||
}
|
||||
|
||||
// There's a chance we just got a time, so keep going to see if we can get a location too
|
||||
if (tooLong || holdExpired) {
|
||||
down();
|
||||
}
|
||||
|
||||
if (millis() > fixHoldEnds) {
|
||||
shouldPublish = true; // publish our update at the end of the lock hold
|
||||
publishUpdate();
|
||||
down();
|
||||
#ifdef GPS_DEBUG
|
||||
} else if (fixHoldEnds != 0) {
|
||||
} else {
|
||||
LOG_DEBUG("Holding for GPS data download: %d ms (numSats=%d)", fixHoldEnds - millis(), p.sats_in_view);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// ===================== end GPS_ACTIVE state ========================
|
||||
|
||||
// If state has changed do a publish
|
||||
publishUpdate();
|
||||
|
||||
if (config.position.fixed_position == true && hasValidLocation)
|
||||
return disable(); // This should trigger when we have a fixed position, and get that first position
|
||||
@@ -1256,215 +1213,157 @@ static const char *DETECTED_MESSAGE = "%s detected";
|
||||
|
||||
GnssModel_t GPS::probe(int serialSpeed)
|
||||
{
|
||||
uint8_t buffer[768] = {0};
|
||||
|
||||
switch (currentStep) {
|
||||
case 0: {
|
||||
#if defined(ARCH_NRF52) || defined(ARCH_PORTDUINO) || defined(ARCH_STM32WL)
|
||||
_serial_gps->end();
|
||||
_serial_gps->begin(serialSpeed);
|
||||
_serial_gps->end();
|
||||
_serial_gps->begin(serialSpeed);
|
||||
#elif defined(ARCH_RP2040)
|
||||
_serial_gps->end();
|
||||
_serial_gps->setFIFOSize(256);
|
||||
_serial_gps->begin(serialSpeed);
|
||||
_serial_gps->end();
|
||||
_serial_gps->setFIFOSize(256);
|
||||
_serial_gps->begin(serialSpeed);
|
||||
#else
|
||||
if (_serial_gps->baudRate() != serialSpeed) {
|
||||
LOG_DEBUG("Set GPS Baud to %i", serialSpeed);
|
||||
_serial_gps->updateBaudRate(serialSpeed);
|
||||
}
|
||||
if (_serial_gps->baudRate() != serialSpeed) {
|
||||
LOG_DEBUG("Set Baud to %i", serialSpeed);
|
||||
_serial_gps->updateBaudRate(serialSpeed);
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(&ublox_info, 0, sizeof(ublox_info));
|
||||
delay(100);
|
||||
memset(&ublox_info, 0, sizeof(ublox_info));
|
||||
uint8_t buffer[768] = {0};
|
||||
delay(100);
|
||||
|
||||
#if defined(PIN_GPS_RESET) && PIN_GPS_RESET != -1
|
||||
digitalWrite(PIN_GPS_RESET, GPS_RESET_MODE); // assert for 10ms
|
||||
delay(10);
|
||||
digitalWrite(PIN_GPS_RESET, !GPS_RESET_MODE);
|
||||
// Close all NMEA sentences, valid for L76K, ATGM336H (and likely other AT6558 devices)
|
||||
_serial_gps->write("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n");
|
||||
delay(20);
|
||||
// Close NMEA sequences on Ublox
|
||||
_serial_gps->write("$PUBX,40,GLL,0,0,0,0,0,0*5C\r\n");
|
||||
_serial_gps->write("$PUBX,40,GSV,0,0,0,0,0,0*59\r\n");
|
||||
_serial_gps->write("$PUBX,40,VTG,0,0,0,0,0,0*5E\r\n");
|
||||
delay(20);
|
||||
|
||||
// attempt to detect the chip based on boot messages
|
||||
std::vector<ChipInfo> passive_detect = {
|
||||
{"AG3335", "$PAIR021,AG3335", GNSS_MODEL_AG3335},
|
||||
{"AG3352", "$PAIR021,AG3352", GNSS_MODEL_AG3352},
|
||||
{"RYS3520", "$PAIR021,REYAX_RYS3520_V2", GNSS_MODEL_AG3352},
|
||||
{"UC6580", "UC6580", GNSS_MODEL_UC6580},
|
||||
// as L76K is sort of a last ditch effort, we won't attempt to detect it by startup messages for now.
|
||||
/*{"L76K", "SW=URANUS", GNSS_MODEL_MTK}*/};
|
||||
GnssModel_t detectedDriver = getProbeResponse(500, passive_detect, serialSpeed);
|
||||
if (detectedDriver != GNSS_MODEL_UNKNOWN) {
|
||||
return detectedDriver;
|
||||
// Unicore UFirebirdII Series: UC6580, UM620, UM621, UM670A, UM680A, or UM681A
|
||||
std::vector<ChipInfo> unicore = {{"UC6580", "UC6580", GNSS_MODEL_UC6580}, {"UM600", "UM600", GNSS_MODEL_UC6580}};
|
||||
PROBE_FAMILY("Unicore Family", "$PDTINFO", unicore, 500);
|
||||
|
||||
std::vector<ChipInfo> atgm = {
|
||||
{"ATGM336H", "$GPTXT,01,01,02,HW=ATGM336H", GNSS_MODEL_ATGM336H},
|
||||
/* ATGM332D series (-11(GPS), -21(BDS), -31(GPS+BDS), -51(GPS+GLONASS), -71-0(GPS+BDS+GLONASS)) based on AT6558 */
|
||||
{"ATGM332D", "$GPTXT,01,01,02,HW=ATGM332D", GNSS_MODEL_ATGM336H}};
|
||||
PROBE_FAMILY("ATGM33xx Family", "$PCAS06,1*1A", atgm, 500);
|
||||
|
||||
/* Airoha (Mediatek) AG3335A/M/S, A3352Q, Quectel L89 2.0, SimCom SIM65M */
|
||||
_serial_gps->write("$PAIR062,2,0*3C\r\n"); // GSA OFF to reduce volume
|
||||
_serial_gps->write("$PAIR062,3,0*3D\r\n"); // GSV OFF to reduce volume
|
||||
_serial_gps->write("$PAIR513*3D\r\n"); // save configuration
|
||||
std::vector<ChipInfo> airoha = {{"AG3335", "$PAIR021,AG3335", GNSS_MODEL_AG3335},
|
||||
{"AG3352", "$PAIR021,AG3352", GNSS_MODEL_AG3352},
|
||||
{"RYS3520", "$PAIR021,REYAX_RYS3520_V2", GNSS_MODEL_AG3352}};
|
||||
PROBE_FAMILY("Airoha Family", "$PAIR021*39", airoha, 1000);
|
||||
|
||||
PROBE_SIMPLE("LC86", "$PQTMVERNO*58", "$PQTMVERNO,LC86", GNSS_MODEL_AG3352, 500);
|
||||
PROBE_SIMPLE("L76K", "$PCAS06,0*1B", "$GPTXT,01,01,02,SW=", GNSS_MODEL_MTK, 500);
|
||||
|
||||
// Close all NMEA sentences, valid for MTK3333 and MTK3339 platforms
|
||||
_serial_gps->write("$PMTK514,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*2E\r\n");
|
||||
delay(20);
|
||||
std::vector<ChipInfo> mtk = {{"L76B", "Quectel-L76B", GNSS_MODEL_MTK_L76B}, {"PA1010D", "1010D", GNSS_MODEL_MTK_PA1010D},
|
||||
{"PA1616S", "1616S", GNSS_MODEL_MTK_PA1616S}, {"LS20031", "MC-1513", GNSS_MODEL_MTK_L76B},
|
||||
{"L96", "Quectel-L96", GNSS_MODEL_MTK_L76B}, {"L80-R", "_3337_", GNSS_MODEL_MTK_L76B},
|
||||
{"L80", "_3339_", GNSS_MODEL_MTK_L76B}};
|
||||
|
||||
PROBE_FAMILY("MTK Family", "$PMTK605*31", mtk, 500);
|
||||
|
||||
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00};
|
||||
UBXChecksum(cfg_rate, sizeof(cfg_rate));
|
||||
clearBuffer();
|
||||
_serial_gps->write(cfg_rate, sizeof(cfg_rate));
|
||||
// Check that the returned response class and message ID are correct
|
||||
GPS_RESPONSE response = getACK(0x06, 0x08, 750);
|
||||
if (response == GNSS_RESPONSE_NONE) {
|
||||
LOG_WARN("No GNSS Module (baudrate %d)", serialSpeed);
|
||||
return GNSS_MODEL_UNKNOWN;
|
||||
} else if (response == GNSS_RESPONSE_FRAME_ERRORS) {
|
||||
LOG_INFO("UBlox Frame Errors (baudrate %d)", serialSpeed);
|
||||
}
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
uint8_t _message_MONVER[8] = {
|
||||
0xB5, 0x62, // Sync message for UBX protocol
|
||||
0x0A, 0x04, // Message class and ID (UBX-MON-VER)
|
||||
0x00, 0x00, // Length of payload (we're asking for an answer, so no payload)
|
||||
0x00, 0x00 // Checksum
|
||||
};
|
||||
// Get Ublox gnss module hardware and software info
|
||||
UBXChecksum(_message_MONVER, sizeof(_message_MONVER));
|
||||
clearBuffer();
|
||||
_serial_gps->write(_message_MONVER, sizeof(_message_MONVER));
|
||||
|
||||
uint16_t len = getACK(buffer, sizeof(buffer), 0x0A, 0x04, 1200);
|
||||
if (len) {
|
||||
uint16_t position = 0;
|
||||
for (int i = 0; i < 30; i++) {
|
||||
ublox_info.swVersion[i] = buffer[position];
|
||||
position++;
|
||||
}
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ublox_info.hwVersion[i] = buffer[position];
|
||||
position++;
|
||||
}
|
||||
#endif
|
||||
// Close all NMEA sentences, valid for L76K, ATGM336H (and likely other AT6558 devices)
|
||||
_serial_gps->write("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n");
|
||||
delay(20);
|
||||
// Close NMEA sequences on Ublox
|
||||
_serial_gps->write("$PUBX,40,GLL,0,0,0,0,0,0*5C\r\n");
|
||||
_serial_gps->write("$PUBX,40,GSV,0,0,0,0,0,0*59\r\n");
|
||||
_serial_gps->write("$PUBX,40,VTG,0,0,0,0,0,0*5E\r\n");
|
||||
delay(20);
|
||||
// Close NMEA sequences on CM121
|
||||
_serial_gps->write("$CFGMSG,0,1,0,1*1B\r\n");
|
||||
_serial_gps->write("$CFGMSG,0,2,0,1*18\r\n");
|
||||
_serial_gps->write("$CFGMSG,0,3,0,1*19\r\n");
|
||||
currentDelay = 20;
|
||||
currentStep = 1;
|
||||
return GNSS_MODEL_UNKNOWN;
|
||||
}
|
||||
case 1: {
|
||||
|
||||
// Unicore UFirebirdII Series: UC6580, UM620, UM621, UM670A, UM680A, or UM681A,or CM121
|
||||
std::vector<ChipInfo> unicore = {
|
||||
{"UC6580", "UC6580", GNSS_MODEL_UC6580}, {"UM600", "UM600", GNSS_MODEL_UC6580}, {"CM121", "CM121", GNSS_MODEL_CM121}};
|
||||
PROBE_FAMILY("Unicore Family", "$PDTINFO", unicore, 500);
|
||||
currentDelay = 20;
|
||||
currentStep = 2;
|
||||
return GNSS_MODEL_UNKNOWN;
|
||||
}
|
||||
case 2: {
|
||||
std::vector<ChipInfo> atgm = {
|
||||
{"ATGM336H", "$GPTXT,01,01,02,HW=ATGM336H", GNSS_MODEL_ATGM336H},
|
||||
/* ATGM332D series (-11(GPS), -21(BDS), -31(GPS+BDS), -51(GPS+GLONASS), -71-0(GPS+BDS+GLONASS)) based on AT6558 */
|
||||
{"ATGM332D", "$GPTXT,01,01,02,HW=ATGM332D", GNSS_MODEL_ATGM336H}};
|
||||
PROBE_FAMILY("ATGM33xx Family", "$PCAS06,1*1A", atgm, 500);
|
||||
currentDelay = 20;
|
||||
currentStep = 3;
|
||||
return GNSS_MODEL_UNKNOWN;
|
||||
}
|
||||
case 3: {
|
||||
/* Airoha (Mediatek) AG3335A/M/S, A3352Q, Quectel L89 2.0, SimCom SIM65M */
|
||||
_serial_gps->write("$PAIR062,2,0*3C\r\n"); // GSA OFF to reduce volume
|
||||
_serial_gps->write("$PAIR062,3,0*3D\r\n"); // GSV OFF to reduce volume
|
||||
_serial_gps->write("$PAIR513*3D\r\n"); // save configuration
|
||||
std::vector<ChipInfo> airoha = {{"AG3335", "$PAIR021,AG3335", GNSS_MODEL_AG3335},
|
||||
{"AG3352", "$PAIR021,AG3352", GNSS_MODEL_AG3352},
|
||||
{"RYS3520", "$PAIR021,REYAX_RYS3520_V2", GNSS_MODEL_AG3352}};
|
||||
PROBE_FAMILY("Airoha Family", "$PAIR021*39", airoha, 1000);
|
||||
currentDelay = 20;
|
||||
currentStep = 4;
|
||||
return GNSS_MODEL_UNKNOWN;
|
||||
}
|
||||
case 4: {
|
||||
PROBE_SIMPLE("LC86", "$PQTMVERNO*58", "$PQTMVERNO,LC86", GNSS_MODEL_AG3352, 500);
|
||||
PROBE_SIMPLE("L76K", "$PCAS06,0*1B", "$GPTXT,01,01,02,SW=", GNSS_MODEL_MTK, 500);
|
||||
currentDelay = 20;
|
||||
currentStep = 5;
|
||||
return GNSS_MODEL_UNKNOWN;
|
||||
}
|
||||
case 5: {
|
||||
while (len >= position + 30) {
|
||||
for (int i = 0; i < 30; i++) {
|
||||
ublox_info.extension[ublox_info.extensionNo][i] = buffer[position];
|
||||
position++;
|
||||
}
|
||||
ublox_info.extensionNo++;
|
||||
if (ublox_info.extensionNo > 9)
|
||||
break;
|
||||
}
|
||||
|
||||
// Close all NMEA sentences, valid for MTK3333 and MTK3339 platforms
|
||||
_serial_gps->write("$PMTK514,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*2E\r\n");
|
||||
delay(20);
|
||||
std::vector<ChipInfo> mtk = {{"L76B", "Quectel-L76B", GNSS_MODEL_MTK_L76B}, {"PA1010D", "1010D", GNSS_MODEL_MTK_PA1010D},
|
||||
{"PA1616S", "1616S", GNSS_MODEL_MTK_PA1616S}, {"LS20031", "MC-1513", GNSS_MODEL_MTK_L76B},
|
||||
{"L96", "Quectel-L96", GNSS_MODEL_MTK_L76B}, {"L80-R", "_3337_", GNSS_MODEL_MTK_L76B},
|
||||
{"L80", "_3339_", GNSS_MODEL_MTK_L76B}};
|
||||
|
||||
PROBE_FAMILY("MTK Family", "$PMTK605*31", mtk, 500);
|
||||
currentDelay = 20;
|
||||
currentStep = 6;
|
||||
return GNSS_MODEL_UNKNOWN;
|
||||
}
|
||||
case 6: {
|
||||
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00};
|
||||
UBXChecksum(cfg_rate, sizeof(cfg_rate));
|
||||
clearBuffer();
|
||||
_serial_gps->write(cfg_rate, sizeof(cfg_rate));
|
||||
// Check that the returned response class and message ID are correct
|
||||
GPS_RESPONSE response = getACK(0x06, 0x08, 750);
|
||||
if (response == GNSS_RESPONSE_NONE) {
|
||||
LOG_WARN("No GNSS Module (baudrate %d)", serialSpeed);
|
||||
currentDelay = 2000;
|
||||
currentStep = 0;
|
||||
return GNSS_MODEL_UNKNOWN;
|
||||
} else if (response == GNSS_RESPONSE_FRAME_ERRORS) {
|
||||
LOG_INFO("UBlox Frame Errors (baudrate %d)", serialSpeed);
|
||||
LOG_DEBUG("Module Info : ");
|
||||
LOG_DEBUG("Soft version: %s", ublox_info.swVersion);
|
||||
LOG_DEBUG("Hard version: %s", ublox_info.hwVersion);
|
||||
LOG_DEBUG("Extensions:%d", ublox_info.extensionNo);
|
||||
for (int i = 0; i < ublox_info.extensionNo; i++) {
|
||||
LOG_DEBUG(" %s", ublox_info.extension[i]);
|
||||
}
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
uint8_t _message_MONVER[8] = {
|
||||
0xB5, 0x62, // Sync message for UBX protocol
|
||||
0x0A, 0x04, // Message class and ID (UBX-MON-VER)
|
||||
0x00, 0x00, // Length of payload (we're asking for an answer, so no payload)
|
||||
0x00, 0x00 // Checksum
|
||||
};
|
||||
// Get Ublox gnss module hardware and software info
|
||||
UBXChecksum(_message_MONVER, sizeof(_message_MONVER));
|
||||
clearBuffer();
|
||||
_serial_gps->write(_message_MONVER, sizeof(_message_MONVER));
|
||||
|
||||
uint16_t len = getACK(buffer, sizeof(buffer), 0x0A, 0x04, 1200);
|
||||
if (len) {
|
||||
uint16_t position = 0;
|
||||
for (int i = 0; i < 30; i++) {
|
||||
ublox_info.swVersion[i] = buffer[position];
|
||||
position++;
|
||||
}
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ublox_info.hwVersion[i] = buffer[position];
|
||||
position++;
|
||||
}
|
||||
|
||||
while (len >= position + 30) {
|
||||
for (int i = 0; i < 30; i++) {
|
||||
ublox_info.extension[ublox_info.extensionNo][i] = buffer[position];
|
||||
position++;
|
||||
// tips: extensionNo field is 0 on some 6M GNSS modules
|
||||
for (int i = 0; i < ublox_info.extensionNo; ++i) {
|
||||
if (!strncmp(ublox_info.extension[i], "MOD=", 4)) {
|
||||
strncpy((char *)buffer, &(ublox_info.extension[i][4]), sizeof(buffer));
|
||||
} else if (!strncmp(ublox_info.extension[i], "PROTVER", 7)) {
|
||||
char *ptr = nullptr;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
strncpy((char *)buffer, &(ublox_info.extension[i][8]), sizeof(buffer));
|
||||
LOG_DEBUG("Protocol Version:%s", (char *)buffer);
|
||||
if (strlen((char *)buffer)) {
|
||||
ublox_info.protocol_version = strtoul((char *)buffer, &ptr, 10);
|
||||
LOG_DEBUG("ProtVer=%d", ublox_info.protocol_version);
|
||||
} else {
|
||||
ublox_info.protocol_version = 0;
|
||||
}
|
||||
ublox_info.extensionNo++;
|
||||
if (ublox_info.extensionNo > 9)
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_DEBUG("Module Info : ");
|
||||
LOG_DEBUG("Soft version: %s", ublox_info.swVersion);
|
||||
LOG_DEBUG("Hard version: %s", ublox_info.hwVersion);
|
||||
LOG_DEBUG("Extensions:%d", ublox_info.extensionNo);
|
||||
for (int i = 0; i < ublox_info.extensionNo; i++) {
|
||||
LOG_DEBUG(" %s", ublox_info.extension[i]);
|
||||
}
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
// tips: extensionNo field is 0 on some 6M GNSS modules
|
||||
for (int i = 0; i < ublox_info.extensionNo; ++i) {
|
||||
if (!strncmp(ublox_info.extension[i], "MOD=", 4)) {
|
||||
strncpy((char *)buffer, &(ublox_info.extension[i][4]), sizeof(buffer));
|
||||
} else if (!strncmp(ublox_info.extension[i], "PROTVER", 7)) {
|
||||
char *ptr = nullptr;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
strncpy((char *)buffer, &(ublox_info.extension[i][8]), sizeof(buffer));
|
||||
LOG_DEBUG("Protocol Version:%s", (char *)buffer);
|
||||
if (strlen((char *)buffer)) {
|
||||
ublox_info.protocol_version = strtoul((char *)buffer, &ptr, 10);
|
||||
LOG_DEBUG("ProtVer=%d", ublox_info.protocol_version);
|
||||
} else {
|
||||
ublox_info.protocol_version = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (strncmp(ublox_info.hwVersion, "00040007", 8) == 0) {
|
||||
LOG_INFO(DETECTED_MESSAGE, "U-blox 6", "6");
|
||||
return GNSS_MODEL_UBLOX6;
|
||||
} else if (strncmp(ublox_info.hwVersion, "00070000", 8) == 0) {
|
||||
LOG_INFO(DETECTED_MESSAGE, "U-blox 7", "7");
|
||||
return GNSS_MODEL_UBLOX7;
|
||||
} else if (strncmp(ublox_info.hwVersion, "00080000", 8) == 0) {
|
||||
LOG_INFO(DETECTED_MESSAGE, "U-blox 8", "8");
|
||||
return GNSS_MODEL_UBLOX8;
|
||||
} else if (strncmp(ublox_info.hwVersion, "00190000", 8) == 0) {
|
||||
LOG_INFO(DETECTED_MESSAGE, "U-blox 9", "9");
|
||||
return GNSS_MODEL_UBLOX9;
|
||||
} else if (strncmp(ublox_info.hwVersion, "000A0000", 8) == 0) {
|
||||
LOG_INFO(DETECTED_MESSAGE, "U-blox 10", "10");
|
||||
return GNSS_MODEL_UBLOX10;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (strncmp(ublox_info.hwVersion, "00040007", 8) == 0) {
|
||||
LOG_INFO(DETECTED_MESSAGE, "U-blox 6", "6");
|
||||
return GNSS_MODEL_UBLOX6;
|
||||
} else if (strncmp(ublox_info.hwVersion, "00070000", 8) == 0) {
|
||||
LOG_INFO(DETECTED_MESSAGE, "U-blox 7", "7");
|
||||
return GNSS_MODEL_UBLOX7;
|
||||
} else if (strncmp(ublox_info.hwVersion, "00080000", 8) == 0) {
|
||||
LOG_INFO(DETECTED_MESSAGE, "U-blox 8", "8");
|
||||
return GNSS_MODEL_UBLOX8;
|
||||
} else if (strncmp(ublox_info.hwVersion, "00190000", 8) == 0) {
|
||||
LOG_INFO(DETECTED_MESSAGE, "U-blox 9", "9");
|
||||
return GNSS_MODEL_UBLOX9;
|
||||
} else if (strncmp(ublox_info.hwVersion, "000A0000", 8) == 0) {
|
||||
LOG_INFO(DETECTED_MESSAGE, "U-blox 10", "10");
|
||||
return GNSS_MODEL_UBLOX10;
|
||||
}
|
||||
}
|
||||
LOG_WARN("No GNSS Module (baudrate %d)", serialSpeed);
|
||||
currentDelay = 2000;
|
||||
currentStep = 0;
|
||||
return GNSS_MODEL_UNKNOWN;
|
||||
}
|
||||
|
||||
@@ -1493,12 +1392,12 @@ GnssModel_t GPS::getProbeResponse(unsigned long timeout, const std::vector<ChipI
|
||||
}
|
||||
|
||||
if (c == ',' || (responseLen >= 2 && response[responseLen - 2] == '\r' && response[responseLen - 1] == '\n')) {
|
||||
#ifdef GPS_DEBUG
|
||||
LOG_DEBUG(response);
|
||||
#endif
|
||||
// check if we can see our chips
|
||||
for (const auto &chipInfo : responseMap) {
|
||||
if (strstr(response, chipInfo.detectionString.c_str()) != nullptr) {
|
||||
#ifdef GPS_DEBUG
|
||||
LOG_DEBUG(response);
|
||||
#endif
|
||||
LOG_INFO("%s detected", chipInfo.chipName.c_str());
|
||||
delete[] response; // Cleanup before return
|
||||
return chipInfo.driver;
|
||||
@@ -1506,9 +1405,6 @@ GnssModel_t GPS::getProbeResponse(unsigned long timeout, const std::vector<ChipI
|
||||
}
|
||||
}
|
||||
if (responseLen >= 2 && response[responseLen - 2] == '\r' && response[responseLen - 1] == '\n') {
|
||||
#ifdef GPS_DEBUG
|
||||
LOG_DEBUG(response);
|
||||
#endif
|
||||
// Reset the response buffer for the next potential message
|
||||
responseLen = 0;
|
||||
response[0] = '\0';
|
||||
@@ -1527,7 +1423,10 @@ GPS *GPS::createGps()
|
||||
int8_t _rx_gpio = config.position.rx_gpio;
|
||||
int8_t _tx_gpio = config.position.tx_gpio;
|
||||
int8_t _en_gpio = config.position.gps_en_gpio;
|
||||
|
||||
#if HAS_GPS && !defined(ARCH_ESP32)
|
||||
_rx_gpio = 1; // We only specify GPS serial ports on ESP32. Otherwise, these are just flags.
|
||||
_tx_gpio = 1;
|
||||
#endif
|
||||
#if defined(GPS_RX_PIN)
|
||||
if (!_rx_gpio)
|
||||
_rx_gpio = GPS_RX_PIN;
|
||||
@@ -1541,7 +1440,7 @@ GPS *GPS::createGps()
|
||||
_en_gpio = PIN_GPS_EN;
|
||||
#endif
|
||||
#ifdef ARCH_PORTDUINO
|
||||
if (!portduino_config.has_gps)
|
||||
if (!settingsMap[has_gps])
|
||||
return nullptr;
|
||||
#endif
|
||||
if (!_rx_gpio || !_serial_gps) // Configured to have no GPS at all
|
||||
@@ -1592,6 +1491,8 @@ GPS *GPS::createGps()
|
||||
|
||||
#ifdef PIN_GPS_RESET
|
||||
pinMode(PIN_GPS_RESET, OUTPUT);
|
||||
digitalWrite(PIN_GPS_RESET, GPS_RESET_MODE); // assert for 10ms
|
||||
delay(10);
|
||||
digitalWrite(PIN_GPS_RESET, !GPS_RESET_MODE);
|
||||
#endif
|
||||
|
||||
@@ -1601,28 +1502,16 @@ GPS *GPS::createGps()
|
||||
_serial_gps->setRxBufferSize(SERIAL_BUFFER_SIZE); // the default is 256
|
||||
#endif
|
||||
|
||||
LOG_DEBUG("Use GPIO%d for GPS RX", new_gps->rx_gpio);
|
||||
LOG_DEBUG("Use GPIO%d for GPS TX", new_gps->tx_gpio);
|
||||
|
||||
// ESP32 has a special set of parameters vs other arduino ports
|
||||
#if defined(ARCH_ESP32)
|
||||
LOG_DEBUG("Use GPIO%d for GPS RX", new_gps->rx_gpio);
|
||||
LOG_DEBUG("Use GPIO%d for GPS TX", new_gps->tx_gpio);
|
||||
_serial_gps->begin(GPS_BAUDRATE, SERIAL_8N1, new_gps->rx_gpio, new_gps->tx_gpio);
|
||||
#elif defined(ARCH_RP2040)
|
||||
_serial_gps->setPinout(new_gps->tx_gpio, new_gps->rx_gpio);
|
||||
_serial_gps->setFIFOSize(256);
|
||||
_serial_gps->begin(GPS_BAUDRATE);
|
||||
#elif defined(ARCH_NRF52)
|
||||
_serial_gps->setPins(new_gps->rx_gpio, new_gps->tx_gpio);
|
||||
_serial_gps->begin(GPS_BAUDRATE);
|
||||
#elif defined(ARCH_STM32WL)
|
||||
_serial_gps->setTx(new_gps->tx_gpio);
|
||||
_serial_gps->setRx(new_gps->rx_gpio);
|
||||
_serial_gps->begin(GPS_BAUDRATE);
|
||||
#elif defined(ARCH_PORTDUINO)
|
||||
// Portduino can't set the GPS pins directly.
|
||||
_serial_gps->begin(GPS_BAUDRATE);
|
||||
#else
|
||||
#error Unsupported architecture!
|
||||
_serial_gps->begin(GPS_BAUDRATE);
|
||||
#endif
|
||||
}
|
||||
return new_gps;
|
||||
@@ -1689,12 +1578,8 @@ bool GPS::lookForLocation()
|
||||
|
||||
#ifndef TINYGPS_OPTION_NO_STATISTICS
|
||||
if (reader.failedChecksum() > lastChecksumFailCount) {
|
||||
// In a GPS_DEBUG build we want to log all of these. In production, we only care if there are many of them.
|
||||
#ifndef GPS_DEBUG
|
||||
if (reader.failedChecksum() > 4)
|
||||
#endif
|
||||
LOG_WARN("%u new GPS checksum failures, for a total of %u", reader.failedChecksum() - lastChecksumFailCount,
|
||||
reader.failedChecksum());
|
||||
LOG_WARN("%u new GPS checksum failures, for a total of %u", reader.failedChecksum() - lastChecksumFailCount,
|
||||
reader.failedChecksum());
|
||||
lastChecksumFailCount = reader.failedChecksum();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -16,9 +16,6 @@
|
||||
#define GPS_EN_ACTIVE 1
|
||||
#endif
|
||||
|
||||
static constexpr uint32_t GPS_UPDATE_ALWAYS_ON_THRESHOLD_MS = 10 * 1000UL;
|
||||
static constexpr uint32_t GPS_FIX_HOLD_MAX_MS = 20000;
|
||||
|
||||
typedef enum {
|
||||
GNSS_MODEL_ATGM336H,
|
||||
GNSS_MODEL_MTK,
|
||||
@@ -34,8 +31,7 @@ typedef enum {
|
||||
GNSS_MODEL_MTK_PA1616S,
|
||||
GNSS_MODEL_AG3335,
|
||||
GNSS_MODEL_AG3352,
|
||||
GNSS_MODEL_LS20031,
|
||||
GNSS_MODEL_CM121
|
||||
GNSS_MODEL_LS20031
|
||||
} GnssModel_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -154,8 +150,6 @@ class GPS : private concurrency::OSThread
|
||||
TinyGPSPlus reader;
|
||||
uint8_t fixQual = 0; // fix quality from GPGGA
|
||||
uint32_t lastChecksumFailCount = 0;
|
||||
uint8_t currentStep = 0;
|
||||
int32_t currentDelay = 2000;
|
||||
|
||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
||||
// (20210908) TinyGps++ can only read the GPGSA "FIX TYPE" field
|
||||
@@ -178,6 +172,8 @@ class GPS : private concurrency::OSThread
|
||||
*/
|
||||
bool hasValidLocation = false; // default to false, until we complete our first read
|
||||
|
||||
bool isInPowersave = false;
|
||||
|
||||
bool shouldPublish = false; // If we've changed GPS state, this will force a publish the next loop()
|
||||
|
||||
bool hasGPS = false; // Do we have a GPS we are talking to
|
||||
@@ -194,8 +190,6 @@ class GPS : private concurrency::OSThread
|
||||
/** If !NULL we will use this serial port to construct our GPS */
|
||||
#if defined(ARCH_RP2040)
|
||||
static SerialUART *_serial_gps;
|
||||
#elif defined(ARCH_NRF52)
|
||||
static Uart *_serial_gps;
|
||||
#else
|
||||
static HardwareSerial *_serial_gps;
|
||||
#endif
|
||||
|
||||
@@ -109,39 +109,6 @@ RTCSetResult readFromRTC()
|
||||
}
|
||||
return RTCSetResultSuccess;
|
||||
}
|
||||
#elif defined(RX8130CE_RTC)
|
||||
if (rtc_found.address == RX8130CE_RTC) {
|
||||
uint32_t now = millis();
|
||||
#ifdef MUZI_BASE
|
||||
ArtronShop_RX8130CE rtc(&Wire1);
|
||||
#else
|
||||
ArtronShop_RX8130CE rtc(&Wire);
|
||||
#endif
|
||||
tm t;
|
||||
if (rtc.getTime(&t)) {
|
||||
tv.tv_sec = gm_mktime(&t);
|
||||
tv.tv_usec = 0;
|
||||
|
||||
uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
|
||||
LOG_DEBUG("Read RTC time from RX8130CE getDateTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)", t.tm_year + 1900,
|
||||
t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, printableEpoch);
|
||||
#ifdef BUILD_EPOCH
|
||||
if (tv.tv_sec < BUILD_EPOCH) {
|
||||
if (Throttle::isWithinTimespanMs(lastTimeValidationWarning, TIME_VALIDATION_WARNING_INTERVAL_MS) == false) {
|
||||
LOG_WARN("Ignore time (%ld) before build epoch (%ld)!", printableEpoch, BUILD_EPOCH);
|
||||
lastTimeValidationWarning = millis();
|
||||
}
|
||||
return RTCSetResultInvalidTime;
|
||||
}
|
||||
#endif
|
||||
if (currentQuality == RTCQualityNone) {
|
||||
timeStartMsec = now;
|
||||
zeroOffsetSecs = tv.tv_sec;
|
||||
currentQuality = RTCQualityDevice;
|
||||
}
|
||||
return RTCSetResultSuccess;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (!gettimeofday(&tv, NULL)) {
|
||||
uint32_t now = millis();
|
||||
@@ -247,21 +214,6 @@ RTCSetResult perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpd
|
||||
LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d (%ld)", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
|
||||
t->tm_hour, t->tm_min, t->tm_sec, printableEpoch);
|
||||
}
|
||||
#elif defined(RX8130CE_RTC)
|
||||
if (rtc_found.address == RX8130CE_RTC) {
|
||||
#ifdef MUZI_BASE
|
||||
ArtronShop_RX8130CE rtc(&Wire1);
|
||||
#else
|
||||
ArtronShop_RX8130CE rtc(&Wire);
|
||||
#endif
|
||||
tm *t = gmtime(&tv->tv_sec);
|
||||
if (rtc.setTime(*t)) {
|
||||
LOG_DEBUG("RX8130CE setDateTime %02d-%02d-%02d %02d:%02d:%02d (%ld)", t->tm_year + 1900, t->tm_mon + 1,
|
||||
t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, printableEpoch);
|
||||
} else {
|
||||
LOG_WARN("Failed to set time for RX8130CE");
|
||||
}
|
||||
}
|
||||
#elif defined(ARCH_ESP32)
|
||||
settimeofday(tv, NULL);
|
||||
#endif
|
||||
@@ -318,7 +270,7 @@ RTCSetResult perhapsSetRTC(RTCQuality q, struct tm &t)
|
||||
#ifdef BUILD_EPOCH
|
||||
if (tv.tv_sec < BUILD_EPOCH) {
|
||||
if (Throttle::isWithinTimespanMs(lastTimeValidationWarning, TIME_VALIDATION_WARNING_INTERVAL_MS) == false) {
|
||||
LOG_WARN("Ignore time (%lu) before build epoch (%lu)!", printableEpoch, BUILD_EPOCH);
|
||||
LOG_WARN("Ignore time (%ld) before build epoch (%ld)!", printableEpoch, BUILD_EPOCH);
|
||||
lastTimeValidationWarning = millis();
|
||||
}
|
||||
return RTCSetResultInvalidTime;
|
||||
@@ -327,7 +279,7 @@ RTCSetResult perhapsSetRTC(RTCQuality q, struct tm &t)
|
||||
// Calculate max allowed time safely to avoid overflow in logging
|
||||
uint64_t maxAllowedTime = (uint64_t)BUILD_EPOCH + FORTY_YEARS;
|
||||
uint32_t maxAllowedPrintable = (maxAllowedTime > UINT32_MAX) ? UINT32_MAX : (uint32_t)maxAllowedTime;
|
||||
LOG_WARN("Ignore time (%lu) too far in the future (build epoch: %lu, max allowed: %lu)!", printableEpoch,
|
||||
LOG_WARN("Ignore time (%ld) too far in the future (build epoch: %ld, max allowed: %ld)!", printableEpoch,
|
||||
(uint32_t)BUILD_EPOCH, maxAllowedPrintable);
|
||||
lastTimeValidationWarning = millis();
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user