Compare commits

..

1 Commits

Author SHA1 Message Date
Ben Meadors
c0d8602e7c WIP 2024-09-10 18:25:39 -05:00
466 changed files with 7264 additions and 11508 deletions

View File

@@ -13,13 +13,16 @@
}, },
"customizations": { "customizations": {
"vscode": { "vscode": {
"extensions": ["ms-vscode.cpptools", "platformio.platformio-ide"] "extensions": [
"ms-vscode.cpptools",
"platformio.platformio-ide",
]
} }
}, },
// Use 'forwardPorts' to make a list of ports inside the container available locally. // Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [4403], "forwardPorts": [ 4403 ],
// Run commands to prepare the container for use // Run commands to prepare the container for use
"postCreateCommand": ".devcontainer/setup.sh" "postCreateCommand": ".devcontainer/setup.sh",
} }

View File

@@ -1,3 +1,3 @@
#!/usr/bin/env sh #!/usr/bin/env sh
git submodule update --init git submodule update --init

View File

@@ -49,24 +49,10 @@ body:
- Heltec V3 - Heltec V3
- Heltec Wireless Paper - Heltec Wireless Paper
- Heltec Wireless Tracker - Heltec Wireless Tracker
- Heltec Mesh Node T114
- Heltec Vision Master E213
- Heltec Vision Master E290
- Heltec Vision Master T190
- Nano G1
- Nano G1 Explorer
- Nano G2 Ultra
- Raspberry Pi Pico (W) - Raspberry Pi Pico (W)
- Relay v1 - Relay v1
- Relay v2 - Relay v2
- Seeed Wio Tracker 1110 - Seeed Wio Tracker 1110
- Seeed Card Tracker T1000-E
- Station G1
- Station G2
- unPhone
- CanaryOne
- Chatter
- Linux Native
- DIY - DIY
- Other - Other
validations: validations:

View File

@@ -18,7 +18,6 @@ body:
- ESP32 - ESP32
- RP2040 - RP2040
- Linux Native - Linux Native
- Cross-Platform
- other - other
validations: validations:
required: true required: true

View File

@@ -1,94 +0,0 @@
name: Setup Build Variant Composite Action
description: Variant build actions for Meshtastic Platform IO steps
inputs:
board:
description: The board to build for
required: true
github_token:
description: GitHub token
required: true
build-script-path:
description: Path to the build script
required: true
remove-debug-flags:
description: A space separated list of files to remove debug flags from
required: false
default: ""
ota-firmware-source:
description: The OTA firmware file to pull
required: false
default: ""
ota-firmware-target:
description: The target path to store the OTA firmware file
required: false
default: ""
artifact-paths:
description: A newline separated list of paths to store as artifacts
required: false
default: ""
include-web-ui:
description: Include the web UI in the build
required: false
default: "false"
arch:
description: Processor arch name
required: true
default: "esp32"
runs:
using: composite
steps:
- name: Build base
id: base
uses: ./.github/actions/setup-base
- name: Pull web ui
if: inputs.include-web-ui == 'true'
uses: dsaltares/fetch-gh-release-asset@master
with:
repo: meshtastic/web
file: build.tar
target: build.tar
token: ${{ inputs.github_token }}
- name: Unpack web ui
if: inputs.include-web-ui == 'true'
shell: bash
run: |
tar -xf build.tar -C data/static
rm build.tar
- name: Remove debug flags for release
shell: bash
if: inputs.remove-debug-flags != ''
run: |
for INI_FILE in ${{ inputs.remove-debug-flags }}; do
sed -i '/DDEBUG_HEAP/d' ${INI_FILE}
done
- name: Build ${{ inputs.board }}
shell: bash
run: ${{ inputs.build-script-path }} ${{ inputs.board }}
- name: Pull OTA Firmware
if: inputs.ota-firmware-source != '' && inputs.ota-firmware-target != ''
uses: dsaltares/fetch-gh-release-asset@master
with:
repo: meshtastic/firmware-ota
file: ${{ inputs.ota-firmware-source }}
target: ${{ inputs.ota-firmware-target }}
token: ${{ inputs.github_token }}
- name: Get release version string
shell: bash
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Store binaries as an artifact
uses: actions/upload-artifact@v4
with:
name: firmware-${{ inputs.arch }}-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
overwrite: true
path: |
${{ inputs.artifact-paths }}

View File

@@ -11,11 +11,6 @@ runs:
ref: ${{github.event.pull_request.head.ref}} ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}} repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Uncomment build epoch
shell: bash
run: |
sed -i 's/#-DBUILD_EPOCH=$UNIX_TIME/-DBUILD_EPOCH=$UNIX_TIME/' platformio.ini
- name: Install dependencies - name: Install dependencies
shell: bash shell: bash
run: | run: |

View File

@@ -1,26 +0,0 @@
version: 2
updates:
- package-ecosystem: docker
directory: devcontainer
schedule:
interval: daily
time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
timezone: US/Pacific
- package-ecosystem: docker
directory: /
schedule:
interval: daily
time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
timezone: US/Pacific
- package-ecosystem: gitsubmodule
directory: /
schedule:
interval: daily
time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
timezone: US/Pacific
- package-ecosystem: github-actions
directory: /.github/workflows
schedule:
interval: daily
time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
timezone: US/Pacific

View File

@@ -12,23 +12,52 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Build base
id: base
uses: ./.github/actions/setup-base
- name: Pull web ui
uses: dsaltares/fetch-gh-release-asset@master
with:
repo: meshtastic/web
file: build.tar
target: build.tar
token: ${{ secrets.GITHUB_TOKEN }}
- name: Unpack web ui
run: |
tar -xf build.tar -C data/static
rm build.tar
- name: Remove debug flags for release
if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32c3.ini
- name: Build ESP32 - name: Build ESP32
id: build run: bin/build-esp32.sh ${{ inputs.board }}
uses: ./.github/actions/build-variant
- name: Pull OTA Firmware
uses: dsaltares/fetch-gh-release-asset@master
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} repo: meshtastic/firmware-ota
board: ${{ inputs.board }} file: firmware.bin
remove-debug-flags: >- target: release/bleota.bin
./arch/esp32/esp32.ini token: ${{ secrets.GITHUB_TOKEN }}
./arch/esp32/esp32s2.ini
./arch/esp32/esp32s3.ini - name: Get release version string
./arch/esp32/esp32c3.ini shell: bash
build-script-path: bin/build-esp32.sh run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
ota-firmware-source: firmware.bin id: version
ota-firmware-target: release/bleota.bin
artifact-paths: | - name: Store binaries as an artifact
uses: actions/upload-artifact@v4
with:
name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
overwrite: true
path: |
release/*.bin release/*.bin
release/*.elf release/*.elf
include-web-ui: true
arch: esp32

View File

@@ -14,22 +14,50 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Build base
id: base
uses: ./.github/actions/setup-base
- name: Build ESP32-C3 - name: Pull web ui
id: build uses: dsaltares/fetch-gh-release-asset@master
uses: ./.github/actions/build-variant
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} repo: meshtastic/web
board: ${{ inputs.board }} file: build.tar
remove-debug-flags: >- target: build.tar
./arch/esp32/esp32.ini token: ${{ secrets.GITHUB_TOKEN }}
./arch/esp32/esp32s2.ini
./arch/esp32/esp32s3.ini - name: Unpack web ui
./arch/esp32/esp32c3.ini run: |
build-script-path: bin/build-esp32.sh tar -xf build.tar -C data/static
ota-firmware-source: firmware-c3.bin rm build.tar
ota-firmware-target: release/bleota-c3.bin - name: Remove debug flags for release
artifact-paths: | if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32c3.ini
- name: Build ESP32
run: bin/build-esp32.sh ${{ inputs.board }}
- name: Pull OTA Firmware
uses: dsaltares/fetch-gh-release-asset@master
with:
repo: meshtastic/firmware-ota
file: firmware-c3.bin
target: release/bleota-c3.bin
token: ${{ secrets.GITHUB_TOKEN }}
- name: Get release version string
shell: bash
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Store binaries as an artifact
uses: actions/upload-artifact@v4
with:
name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
overwrite: true
path: |
release/*.bin release/*.bin
release/*.elf release/*.elf
arch: esp32c3

View File

@@ -1,36 +0,0 @@
name: Build ESP32-C6
on:
workflow_call:
inputs:
board:
required: true
type: string
permissions: read-all
jobs:
build-esp32-c6:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build ESP32-C6
id: build
uses: ./.github/actions/build-variant
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
board: ${{ inputs.board }}
remove-debug-flags: >-
./arch/esp32/esp32.ini
./arch/esp32/esp32s2.ini
./arch/esp32/esp32s3.ini
./arch/esp32/esp32c3.ini
./arch/esp32/esp32c6.ini
build-script-path: bin/build-esp32.sh
ota-firmware-source: firmware-c3.bin
ota-firmware-target: release/bleota-c3.bin
artifact-paths: |
release/*.bin
release/*.elf
arch: esp32c6

View File

@@ -12,23 +12,50 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Build base
id: base
uses: ./.github/actions/setup-base
- name: Build ESP32-S3 - name: Pull web ui
id: build uses: dsaltares/fetch-gh-release-asset@master
uses: ./.github/actions/build-variant
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} repo: meshtastic/web
board: ${{ inputs.board }} file: build.tar
remove-debug-flags: >- target: build.tar
./arch/esp32/esp32.ini token: ${{ secrets.GITHUB_TOKEN }}
./arch/esp32/esp32s2.ini
./arch/esp32/esp32s3.ini - name: Unpack web ui
./arch/esp32/esp32c3.ini run: |
build-script-path: bin/build-esp32.sh tar -xf build.tar -C data/static
ota-firmware-source: firmware-s3.bin rm build.tar
ota-firmware-target: release/bleota-s3.bin - name: Remove debug flags for release
artifact-paths: | if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32c3.ini
- name: Build ESP32
run: bin/build-esp32.sh ${{ inputs.board }}
- name: Pull OTA Firmware
uses: dsaltares/fetch-gh-release-asset@master
with:
repo: meshtastic/firmware-ota
file: firmware-s3.bin
target: release/bleota-s3.bin
token: ${{ secrets.GITHUB_TOKEN }}
- name: Get release version string
shell: bash
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Store binaries as an artifact
uses: actions/upload-artifact@v4
with:
name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
overwrite: true
path: |
release/*.bin release/*.bin
release/*.elf release/*.elf
include-web-ui: true
arch: esp32s3

View File

@@ -67,7 +67,7 @@ jobs:
- name: Docker build and push tagged versions - name: Docker build and push tagged versions
if: ${{ github.event_name == 'workflow_dispatch' }} if: ${{ github.event_name == 'workflow_dispatch' }}
continue-on-error: true # FIXME: Failing docker login auth continue-on-error: true # FIXME: Failing docker login auth
uses: docker/build-push-action@v6 uses: docker/build-push-action@v5
with: with:
context: . context: .
file: ./Dockerfile file: ./Dockerfile
@@ -77,7 +77,7 @@ jobs:
- name: Docker build and push - name: Docker build and push
if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
continue-on-error: true # FIXME: Failing docker login auth continue-on-error: true # FIXME: Failing docker login auth
uses: docker/build-push-action@v6 uses: docker/build-push-action@v5
with: with:
context: . context: .
file: ./Dockerfile file: ./Dockerfile

View File

@@ -12,17 +12,24 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Build base
id: base
uses: ./.github/actions/setup-base
- name: Build NRF52 - name: Build NRF52
id: build run: bin/build-nrf52.sh ${{ inputs.board }}
uses: ./.github/actions/build-variant
- name: Get release version string
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Store binaries as an artifact
uses: actions/upload-artifact@v4
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
board: ${{ inputs.board }} overwrite: true
build-script-path: bin/build-nrf52.sh path: |
artifact-paths: |
release/*.hex release/*.hex
release/*.uf2 release/*.uf2
release/*.elf release/*.elf
release/*.zip release/*.zip
arch: nrf52840

View File

@@ -12,15 +12,22 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Build base
id: base
uses: ./.github/actions/setup-base
- name: Build Raspberry Pi 2040 - name: Build Raspberry Pi 2040
id: build run: ./bin/build-rpi2040.sh ${{ inputs.board }}
uses: ./.github/actions/build-variant
- name: Get release version string
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Store binaries as an artifact
uses: actions/upload-artifact@v4
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
board: ${{ inputs.board }} overwrite: true
build-script-path: bin/build-rpi2040.sh path: |
artifact-paths: |
release/*.uf2 release/*.uf2
release/*.elf release/*.elf
arch: rp2040

View File

@@ -12,16 +12,22 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Build base
id: base
uses: ./.github/actions/setup-base
- name: Build STM32WL - name: Build STM32
id: build run: bin/build-stm32.sh ${{ inputs.board }}
uses: ./.github/actions/build-variant
- name: Get release version string
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- name: Store binaries as an artifact
uses: actions/upload-artifact@v4
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
board: ${{ inputs.board }} overwrite: true
build-script-path: bin/build-stm32.sh path: |
artifact-paths: |
release/*.hex release/*.hex
release/*.bin release/*.bin
release/*.elf
arch: stm32

View File

@@ -1,35 +0,0 @@
name: Generate UsersPrefs JSON manifest
on:
push:
paths:
- userPrefs.h
branches:
- master
jobs:
generate-userprefs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Clang
run: sudo apt-get install -y clang
- name: Install trunk
run: curl https://get.trunk.io -fsSL | bash
- name: Generate userPrefs.jsom
run: python3 ./bin/build-userprefs-json.py
- name: Trunk format json
run: trunk format userPrefs.json
- name: Commit userPrefs.json
run: |
git config --global user.email "actions@github.com"
git config --global user.name "GitHub Actions"
git add userPrefs.json
git commit -m "Update userPrefs.json"
git push

View File

@@ -1,7 +1,7 @@
name: CI name: CI
concurrency: #concurrency:
group: ci-${{ github.head_ref || github.run_id }} # group: ${{ github.ref }}
cancel-in-progress: true # cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
on: on:
# # Triggers the workflow on push but only for the master branch # # Triggers the workflow on push but only for the master branch
push: push:
@@ -24,7 +24,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
arch: [esp32, esp32s3, esp32c3, esp32c6, nrf52840, rp2040, stm32, check] arch: [esp32, esp32s3, esp32c3, nrf52840, rp2040, stm32, check]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- id: checkout - id: checkout
@@ -32,18 +32,13 @@ jobs:
name: Checkout base name: Checkout base
- id: jsonStep - id: jsonStep
run: | run: |
if [[ "${{ github.head_ref }}" == "" ]]; then TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}})
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}}) echo "$TARGETS"
else
TARGETS=$(./bin/generate_ci_matrix.py ${{matrix.arch}} quick)
fi
echo "Name: ${{ github.ref_name }} Base: ${{ github.base_ref }} Head: ${{ github.head_ref }} Ref: ${{ github.ref }} Targets: $TARGETS"
echo "${{matrix.arch}}=$(jq -cn --argjson environments "$TARGETS" '{board: $environments}')" >> $GITHUB_OUTPUT echo "${{matrix.arch}}=$(jq -cn --argjson environments "$TARGETS" '{board: $environments}')" >> $GITHUB_OUTPUT
outputs: outputs:
esp32: ${{ steps.jsonStep.outputs.esp32 }} esp32: ${{ steps.jsonStep.outputs.esp32 }}
esp32s3: ${{ steps.jsonStep.outputs.esp32s3 }} esp32s3: ${{ steps.jsonStep.outputs.esp32s3 }}
esp32c3: ${{ steps.jsonStep.outputs.esp32c3 }} esp32c3: ${{ steps.jsonStep.outputs.esp32c3 }}
esp32c6: ${{ steps.jsonStep.outputs.esp32c6 }}
nrf52840: ${{ steps.jsonStep.outputs.nrf52840 }} nrf52840: ${{ steps.jsonStep.outputs.nrf52840 }}
rp2040: ${{ steps.jsonStep.outputs.rp2040 }} rp2040: ${{ steps.jsonStep.outputs.rp2040 }}
stm32: ${{ steps.jsonStep.outputs.stm32 }} stm32: ${{ steps.jsonStep.outputs.stm32 }}
@@ -56,7 +51,6 @@ jobs:
matrix: ${{ fromJson(needs.setup.outputs.check) }} matrix: ${{ fromJson(needs.setup.outputs.check) }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ github.event_name != 'workflow_dispatch' }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Build base - name: Build base
@@ -92,15 +86,6 @@ jobs:
with: with:
board: ${{ matrix.board }} board: ${{ matrix.board }}
build-esp32-c6:
needs: setup
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup.outputs.esp32c6) }}
uses: ./.github/workflows/build_esp32_c6.yml
with:
board: ${{ matrix.board }}
build-nrf52: build-nrf52:
needs: setup needs: setup
strategy: strategy:
@@ -139,7 +124,6 @@ jobs:
after-checks: after-checks:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ github.event_name != 'workflow_dispatch' }}
needs: [check] needs: [check]
steps: steps:
- name: Checkout code - name: Checkout code
@@ -152,20 +136,18 @@ jobs:
permissions: permissions:
contents: write contents: write
pull-requests: write pull-requests: write
strategy:
fail-fast: false
matrix:
arch: [esp32, esp32s3, esp32c3, esp32c6, nrf52840, rp2040, stm32]
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: needs:
[ [
build-esp32, build-esp32,
build-esp32-s3, build-esp32-s3,
build-esp32-c3, build-esp32-c3,
build-esp32-c6,
build-nrf52, build-nrf52,
build-rpi2040, build-rpi2040,
build-stm32, build-stm32,
package-raspbian,
package-raspbian-armv7l,
package-native,
] ]
steps: steps:
- name: Checkout code - name: Checkout code
@@ -177,7 +159,6 @@ jobs:
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
path: ./ path: ./
pattern: firmware-${{matrix.arch}}-*
merge-multiple: true merge-multiple: true
- name: Display structure of downloaded files - name: Display structure of downloaded files
@@ -188,12 +169,12 @@ jobs:
id: version id: version
- name: Move files up - name: Move files up
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat run: mv -b -t ./ ./release/meshtasticd_linux_* ./bin/config-dist.yaml ./bin/device-*.sh ./bin/device-*.bat
- name: Repackage in single firmware zip - name: Repackage in single firmware zip
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }} name: firmware-${{ steps.version.outputs.version }}
overwrite: true overwrite: true
path: | path: |
./firmware-*.bin ./firmware-*.bin
@@ -202,14 +183,16 @@ jobs:
./firmware-*-ota.zip ./firmware-*-ota.zip
./device-*.sh ./device-*.sh
./device-*.bat ./device-*.bat
./meshtasticd_linux_*
./config-dist.yaml
./littlefs-*.bin ./littlefs-*.bin
./bleota*bin ./bleota*bin
./Meshtastic_nRF52_factory_erase*.uf2 ./Meshtastic_nRF52_factory_erase*.uf2
retention-days: 30 retention-days: 90
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }} name: firmware-${{ steps.version.outputs.version }}
merge-multiple: true merge-multiple: true
path: ./output path: ./output
@@ -223,35 +206,32 @@ jobs:
chmod +x ./output/device-update.sh chmod +x ./output/device-update.sh
- name: Zip firmware - name: Zip firmware
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip ./output run: zip -j -9 -r ./firmware-${{ steps.version.outputs.version }}.zip ./output
- name: Repackage in single elfs zip - name: Repackage in single elfs zip
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip name: debug-elfs-${{ steps.version.outputs.version }}.zip
overwrite: true overwrite: true
path: ./*.elf path: ./*.elf
retention-days: 30 retention-days: 30
- uses: scruplelesswizard/comment-artifact@main - name: Create request artifacts
if: ${{ github.event_name == 'pull_request' }} continue-on-error: true # FIXME: Why are we getting 502, but things still work?
if: ${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request' }}
uses: gavv/pull-request-artifacts@v2.1.0
with: with:
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }} commit: ${{ (github.event.pull_request_target || github.event.pull_request).head.sha }}
description: "Download firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip. This artifact will be available for 90 days from creation" repo-token: ${{ secrets.GITHUB_TOKEN }}
github-token: ${{ secrets.GITHUB_TOKEN }} artifacts-token: ${{ secrets.ARTIFACTS_TOKEN }}
artifacts-repo: meshtastic/artifacts
artifacts-branch: device
artifacts: ./firmware-${{ steps.version.outputs.version }}.zip
release-artifacts: release-artifacts:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' }} if: ${{ github.event_name == 'workflow_dispatch' }}
outputs: needs: [gather-artifacts, after-checks]
upload_url: ${{ steps.create_release.outputs.upload_url }}
needs:
[
gather-artifacts,
package-raspbian,
package-raspbian-armv7l,
package-native,
]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -265,6 +245,42 @@ jobs:
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version id: version
- uses: actions/download-artifact@v4
with:
name: firmware-${{ steps.version.outputs.version }}
merge-multiple: true
path: ./output
- uses: actions/download-artifact@v4
with:
pattern: meshtasticd_${{ steps.version.outputs.version }}_*.deb
merge-multiple: true
path: ./output
- name: Display structure of downloaded files
run: ls -R
- 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-${{ steps.version.outputs.version }}.zip ./output -x *.deb
- uses: actions/download-artifact@v4
with:
name: debug-elfs-${{ steps.version.outputs.version }}.zip
merge-multiple: true
path: ./elfs
- name: Zip Elfs
run: zip -j -9 -r ./debug-elfs-${{ steps.version.outputs.version }}.zip ./elfs
# For diagnostics
- name: Show artifacts
run: ls -lR
- name: Create release - name: Create release
uses: actions/create-release@v1 uses: actions/create-release@v1
id: create_release id: create_release
@@ -278,16 +294,25 @@ jobs:
env: env:
GITHUB_TOKEN: ${{ github.token }} GITHUB_TOKEN: ${{ github.token }}
- name: Download deb files - name: Add bins to release
uses: actions/download-artifact@v4 uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with: with:
pattern: meshtasticd_${{ steps.version.outputs.version }}_*.deb upload_url: ${{ steps.create_release.outputs.upload_url }}
merge-multiple: true asset_path: ./firmware-${{ steps.version.outputs.version }}.zip
path: ./output asset_name: firmware-${{ steps.version.outputs.version }}.zip
asset_content_type: application/zip
# For diagnostics - name: Add debug elfs to release
- name: Display structure of downloaded files uses: actions/upload-release-asset@v1
run: ls -lR env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./debug-elfs-${{ steps.version.outputs.version }}.zip
asset_name: debug-elfs-${{ steps.version.outputs.version }}.zip
asset_content_type: application/zip
- name: Add raspbian aarch64 .deb - name: Add raspbian aarch64 .deb
uses: actions/upload-release-asset@v1 uses: actions/upload-release-asset@v1
@@ -324,79 +349,7 @@ jobs:
bin/bump_version.py bin/bump_version.py
- name: Create version.properties pull request - name: Create version.properties pull request
uses: peter-evans/create-pull-request@v7 uses: peter-evans/create-pull-request@v6
with: with:
title: Bump version.properties
add-paths: | add-paths: |
version.properties version.properties
release-firmware:
strategy:
fail-fast: false
matrix:
arch: [esp32, esp32s3, esp32c3, esp32c6, nrf52840, rp2040, stm32]
runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' }}
needs: [release-artifacts]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.x
- name: Get release version string
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
id: version
- uses: actions/download-artifact@v4
with:
pattern: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
merge-multiple: true
path: ./output
- name: Display structure of downloaded files
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-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip ./output
- uses: actions/download-artifact@v4
with:
name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
merge-multiple: true
path: ./elfs
- name: Zip firmware
run: zip -j -9 -r ./debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip ./elfs
# For diagnostics
- name: Display structure of downloaded files
run: ls -lR
- name: Add bins to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{needs.release-artifacts.outputs.upload_url}}
asset_path: ./firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
asset_name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
asset_content_type: application/zip
- name: Add debug elfs to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
upload_url: ${{needs.release-artifacts.outputs.upload_url}}
asset_path: ./debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
asset_name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
asset_content_type: application/zip

View File

@@ -13,7 +13,7 @@ jobs:
uses: ./.github/workflows/build_native.yml uses: ./.github/workflows/build_native.yml
package-native: package-native:
runs-on: ubuntu-22.04 runs-on: ubuntu-latest
needs: build-native needs: build-native
steps: steps:
- name: Checkout code - name: Checkout code
@@ -50,14 +50,11 @@ jobs:
mkdir -p .debpkg/usr/share/doc/meshtasticd/web mkdir -p .debpkg/usr/share/doc/meshtasticd/web
mkdir -p .debpkg/usr/sbin mkdir -p .debpkg/usr/sbin
mkdir -p .debpkg/etc/meshtasticd mkdir -p .debpkg/etc/meshtasticd
mkdir -p .debpkg/etc/meshtasticd/config.d
mkdir -p .debpkg/etc/meshtasticd/available.d
mkdir -p .debpkg/usr/lib/systemd/system/ mkdir -p .debpkg/usr/lib/systemd/system/
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
cp release/meshtasticd_linux_x86_64 .debpkg/usr/sbin/meshtasticd cp release/meshtasticd_linux_x86_64 .debpkg/usr/sbin/meshtasticd
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/
chmod +x .debpkg/usr/sbin/meshtasticd chmod +x .debpkg/usr/sbin/meshtasticd
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles

View File

@@ -13,7 +13,7 @@ jobs:
uses: ./.github/workflows/build_raspbian.yml uses: ./.github/workflows/build_raspbian.yml
package-raspbian: package-raspbian:
runs-on: ubuntu-22.04 runs-on: ubuntu-latest
needs: build-raspbian needs: build-raspbian
steps: steps:
- name: Checkout code - name: Checkout code
@@ -50,14 +50,11 @@ jobs:
mkdir -p .debpkg/usr/share/doc/meshtasticd/web mkdir -p .debpkg/usr/share/doc/meshtasticd/web
mkdir -p .debpkg/usr/sbin mkdir -p .debpkg/usr/sbin
mkdir -p .debpkg/etc/meshtasticd mkdir -p .debpkg/etc/meshtasticd
mkdir -p .debpkg/etc/meshtasticd/config.d
mkdir -p .debpkg/etc/meshtasticd/available.d
mkdir -p .debpkg/usr/lib/systemd/system/ mkdir -p .debpkg/usr/lib/systemd/system/
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
cp release/meshtasticd_linux_aarch64 .debpkg/usr/sbin/meshtasticd cp release/meshtasticd_linux_aarch64 .debpkg/usr/sbin/meshtasticd
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/
chmod +x .debpkg/usr/sbin/meshtasticd chmod +x .debpkg/usr/sbin/meshtasticd
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles

View File

@@ -13,7 +13,7 @@ jobs:
uses: ./.github/workflows/build_raspbian_armv7l.yml uses: ./.github/workflows/build_raspbian_armv7l.yml
package-raspbian_armv7l: package-raspbian_armv7l:
runs-on: ubuntu-22.04 runs-on: ubuntu-latest
needs: build-raspbian_armv7l needs: build-raspbian_armv7l
steps: steps:
- name: Checkout code - name: Checkout code
@@ -50,14 +50,11 @@ jobs:
mkdir -p .debpkg/usr/share/doc/meshtasticd/web mkdir -p .debpkg/usr/share/doc/meshtasticd/web
mkdir -p .debpkg/usr/sbin mkdir -p .debpkg/usr/sbin
mkdir -p .debpkg/etc/meshtasticd mkdir -p .debpkg/etc/meshtasticd
mkdir -p .debpkg/etc/meshtasticd/config.d
mkdir -p .debpkg/etc/meshtasticd/available.d
mkdir -p .debpkg/usr/lib/systemd/system/ mkdir -p .debpkg/usr/lib/systemd/system/
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
cp release/meshtasticd_linux_armv7l .debpkg/usr/sbin/meshtasticd cp release/meshtasticd_linux_armv7l .debpkg/usr/sbin/meshtasticd
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/
chmod +x .debpkg/usr/sbin/meshtasticd chmod +x .debpkg/usr/sbin/meshtasticd
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles

View File

@@ -12,7 +12,7 @@ jobs:
semgrep-full: semgrep-full:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
image: semgrep/semgrep image: returntocorp/semgrep
steps: steps:
# step 1 # step 1

View File

@@ -4,9 +4,9 @@ on: pull_request
jobs: jobs:
semgrep-diff: semgrep-diff:
runs-on: ubuntu-22.04 runs-on: ubuntu-latest
container: container:
image: semgrep/semgrep image: returntocorp/semgrep
steps: steps:
# step 1 # step 1

View File

@@ -1,21 +0,0 @@
name: process stale Issues and PR's
on:
schedule:
- cron: 0 6 * * *
workflow_dispatch: {}
permissions:
issues: write
pull-requests: write
jobs:
stale_issues:
name: Close Stale Issues
runs-on: ubuntu-latest
steps:
- name: Stale PR+Issues
uses: actions/stale@v9.0.0
with:
exempt-issue-labels: pinned,3.0
exempt-pr-labels: pinned,3.0

View File

@@ -57,50 +57,35 @@ jobs:
reporter: java-junit reporter: java-junit
hardware-tests: hardware-tests:
runs-on: test-runner runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
# - uses: actions/setup-python@v5
# with:
# python-version: '3.10'
# pipx install "setuptools<72"
- name: Upgrade python tools - name: Upgrade python tools
shell: bash shell: bash
run: | run: |
pipx install adafruit-nrfutil python -m pip install --upgrade pip
pipx install poetry pip install -U --no-build-isolation --no-cache-dir "setuptools<72"
pipx install meshtastic --pip-args=--pre pip install -U platformio adafruit-nrfutil --no-build-isolation
pip install -U poetry --no-build-isolation
- name: Install PlatformIO from script pip install -U meshtastic --pre --no-build-isolation
shell: bash
run: |
curl -fsSL -o get-platformio.py https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py
python3 get-platformio.py
- name: Upgrade platformio - name: Upgrade platformio
shell: bash shell: bash
run: | run: |
export PATH=$PATH:$HOME/.local/bin
pio upgrade pio upgrade
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 18
- name: Setup pnpm - name: Setup pnpm
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v2
with: with:
version: latest version: latest
- name: Install dependencies, setup devices and run - name: Install Dependencies
shell: bash run: pnpm install
run: |
git submodule update --init --recursive - name: Setup devices
cd meshtestic/ run: pnpm run setup
pnpm install
pnpm run setup - name: Execute end to end tests on connected hardware
pnpm run test run: pnpm run test

View File

@@ -1,43 +0,0 @@
name: Run Trunk Fmt on PR Comment
on:
issue_comment:
types: [created]
jobs:
trunk-fmt:
if: github.event.issue.pull_request != null && contains(github.event.comment.body, 'trunk fmt')
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Install trunk
run: curl https://get.trunk.io -fsSL | bash
- name: Run Trunk Fmt
run: trunk fmt
- name: Commit and push changes
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git add .
git commit -m "Add firmware version ${{ steps.version.outputs.version }}"
git push
- name: Comment on PR
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '`trunk fmt` has been run on this PR.'
})

View File

@@ -1,4 +1,4 @@
name: Update protobufs and regenerate classes name: "Update protobufs and regenerate classes"
on: workflow_dispatch on: workflow_dispatch
jobs: jobs:
@@ -17,18 +17,17 @@ jobs:
- name: Download nanopb - name: Download nanopb
run: | run: |
wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.9-linux-x86.tar.gz wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8-linux-x86.tar.gz
tar xvzf nanopb-0.4.9-linux-x86.tar.gz tar xvzf nanopb-0.4.8-linux-x86.tar.gz
mv nanopb-0.4.9-linux-x86 nanopb-0.4.9 mv nanopb-0.4.8-linux-x86 nanopb-0.4.8
- name: Re-generate protocol buffers - name: Re-generate protocol buffers
run: | run: |
./bin/regen-protos.sh ./bin/regen-protos.sh
- name: Create pull request - name: Create pull request
uses: peter-evans/create-pull-request@v7 uses: peter-evans/create-pull-request@v6
with: with:
title: Update protobufs and classes
add-paths: | add-paths: |
protobufs protobufs
src/mesh src/mesh

4
.gitignore vendored
View File

@@ -1,4 +1,6 @@
.pio .pio
main/configuration.h
main/credentials.h
# ignore vscode IDE settings files # ignore vscode IDE settings files
.vscode/* .vscode/*
@@ -30,4 +32,4 @@ release/
.vscode/extensions.json .vscode/extensions.json
/compile_commands.json /compile_commands.json
src/mesh/raspihttp/certificate.pem src/mesh/raspihttp/certificate.pem
src/mesh/raspihttp/private_key.pem src/mesh/raspihttp/private_key.pem

View File

@@ -1,34 +1,34 @@
version: 0.1 version: 0.1
cli: cli:
version: 1.22.7 version: 1.22.3
plugins: plugins:
sources: sources:
- id: trunk - id: trunk
ref: v1.6.4 ref: v1.6.2
uri: https://github.com/trunk-io/plugins uri: https://github.com/trunk-io/plugins
lint: lint:
enabled: enabled:
- trufflehog@3.83.2 - trufflehog@3.81.9
- yamllint@1.35.1 - yamllint@1.35.1
- bandit@1.7.10 - bandit@1.7.9
- checkov@3.2.276 - checkov@3.2.238
- terrascan@1.19.9 - terrascan@1.19.1
- trivy@0.56.2 - trivy@0.54.1
#- trufflehog@3.63.2-rc0 #- trufflehog@3.63.2-rc0
- taplo@0.9.3 - taplo@0.9.3
- ruff@0.7.1 - ruff@0.6.2
- isort@5.13.2 - isort@5.13.2
- markdownlint@0.42.0 - markdownlint@0.41.0
- oxipng@9.1.2 - oxipng@9.1.2
- svgo@3.3.2 - svgo@3.3.2
- actionlint@1.7.3 - actionlint@1.7.1
- flake8@7.1.1 - flake8@7.1.1
- hadolint@2.12.0 - hadolint@2.12.0
- shfmt@3.6.0 - shfmt@3.6.0
- shellcheck@0.10.0 - shellcheck@0.10.0
- black@24.10.0 - black@24.8.0
- git-diff-check - git-diff-check
- gitleaks@8.21.1 - gitleaks@8.18.4
- clang-format@16.0.3 - clang-format@16.0.3
- prettier@3.3.3 - prettier@3.3.3
ignore: ignore:

View File

@@ -1,4 +0,0 @@
# Contributor Covenant Code of Conduct
The Meshtastic Firmware project is subject to the code of conduct for the parent project, which can be found here:
https://meshtastic.org/docs/legal/conduct/

View File

@@ -1,12 +0,0 @@
# Security Policy
## Supported Versions
| Firmware Version | Supported |
| ---------------- | ------------------ |
| 2.5.x | :white_check_mark: |
| <= 2.4.x | :x: |
## Reporting a Vulnerability
We support the private reporting of potential security vulnerabilities. Please go to the Security tab to file a report with a description of the potential vulnerability and reproduction scripts (preferred) or steps, and our developers will review.

View File

@@ -2,10 +2,10 @@
[esp32_base] [esp32_base]
extends = arduino_base extends = arduino_base
custom_esp32_kind = esp32 custom_esp32_kind = esp32
platform = platformio/espressif32@6.9.0 platform = platformio/espressif32@6.7.0
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp> ${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/> -<mesh/raspihttp>
upload_speed = 921600 upload_speed = 921600
debug_init_break = tbreak setup debug_init_break = tbreak setup
@@ -31,7 +31,7 @@ build_flags =
-DCONFIG_BT_NIMBLE_ENABLED -DCONFIG_BT_NIMBLE_ENABLED
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2 -DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20 -DCONFIG_BT_NIMBLE_MAX_CCCDS=20
-DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=8192 -DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5120
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
-DSERIAL_BUFFER_SIZE=4096 -DSERIAL_BUFFER_SIZE=4096
-DLIBPAX_ARDUINO -DLIBPAX_ARDUINO
@@ -46,7 +46,7 @@ lib_deps =
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2 https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
h2zero/NimBLE-Arduino@^1.4.2 h2zero/NimBLE-Arduino@^1.4.2
https://github.com/dbSuS/libpax.git#7bcd3fcab75037505be9b122ab2b24cc5176b587 https://github.com/dbSuS/libpax.git#7bcd3fcab75037505be9b122ab2b24cc5176b587
lewisxhe/XPowersLib@^0.2.6 https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
rweather/Crypto@^0.4.0 rweather/Crypto@^0.4.0

View File

@@ -1,40 +0,0 @@
[esp32c6_base]
extends = esp32_base
platform = https://github.com/Jason2866/platform-espressif32.git#22faa566df8c789000f8136cd8d0aca49617af55
build_flags =
${arduino_base.build_flags}
-Wall
-Wextra
-Isrc/platform/esp32
-std=c++11
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
-DSERIAL_BUFFER_SIZE=4096
-DLIBPAX_ARDUINO
-DLIBPAX_WIFI
-DLIBPAX_BLE
-DMESHTASTIC_EXCLUDE_WEBSERVER
;-DDEBUG_HEAP
; TEMP
-DHAS_BLUETOOTH=0
-DMESHTASTIC_EXCLUDE_PAXCOUNTER
-DMESHTASTIC_EXCLUDE_BLUETOOTH
lib_deps =
${arduino_base.lib_deps}
${networking_base.lib_deps}
${environmental_base.lib_deps}
lewisxhe/XPowersLib@^0.2.6
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
rweather/Crypto@^0.4.0
build_src_filter =
${esp32_base.build_src_filter} -<mesh/http>
monitor_speed = 460800
monitor_filters = esp32_c3_exception_decoder
lib_ignore =
NonBlockingRTTTL
NimBLE-Arduino
libpax

View File

@@ -16,12 +16,11 @@ build_flags =
-DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818 -DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818
build_src_filter = 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> ${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2040> -<mesh/eth/> -<mesh/raspihttp>
lib_deps= lib_deps=
${arduino_base.lib_deps} ${arduino_base.lib_deps}
rweather/Crypto@^0.4.0 rweather/Crypto@^0.4.0
lib_ignore = lib_ignore =
BluetoothOTA BluetoothOTA
lvgl

View File

@@ -1,6 +1,6 @@
; The Portduino based sim environment on top of any host OS, all hardware will be simulated ; The Portduino based sim environment on top of any host OS, all hardware will be simulated
[portduino_base] [portduino_base]
platform = https://github.com/meshtastic/platform-native.git#6b3796d697481c8f6e3f4aa5c111bd9979f29e64 platform = https://github.com/meshtastic/platform-native.git#ad8112adf82ce1f5b917092cf32be07a077801a0
framework = arduino framework = arduino
build_src_filter = build_src_filter =
@@ -9,7 +9,7 @@ build_src_filter =
-<nimble/> -<nimble/>
-<platform/nrf52/> -<platform/nrf52/>
-<platform/stm32wl/> -<platform/stm32wl/>
-<platform/rp2xx0> -<platform/rp2040>
-<mesh/wifi/> -<mesh/wifi/>
-<mesh/http/> -<mesh/http/>
+<mesh/raspihttp/> +<mesh/raspihttp/>
@@ -24,7 +24,7 @@ lib_deps =
${env.lib_deps} ${env.lib_deps}
${networking_base.lib_deps} ${networking_base.lib_deps}
rweather/Crypto@^0.4.0 rweather/Crypto@^0.4.0
https://github.com/lovyan03/LovyanGFX.git#1401c28a47646fe00538d487adcb2eb3c72de805 https://github.com/lovyan03/LovyanGFX.git#5a39989aa2c9492572255b22f033843ec8900233
build_flags = build_flags =
${arduino_base.build_flags} ${arduino_base.build_flags}

View File

@@ -1,14 +1,14 @@
; Common settings for rp2040 Processor based targets ; Common settings for rp2040 Processor based targets
[rp2350_base] [rp2040_base]
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#9e55f6db5c56b9867c69fe473f388beea4546672 platform = https://github.com/maxgerhardt/platform-raspberrypi.git#60d6ae81fcc73c34b1493ca9e261695e471bc0c2
extends = arduino_base extends = arduino_base
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#a6ab6e1f95bc1428d667d55ea7173c0744acc03c ; 4.0.2+ platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#3.7.2
board_build.core = earlephilhower board_build.core = earlephilhower
board_build.filesystem_size = 0.5m board_build.filesystem_size = 0.5m
build_flags = build_flags =
${arduino_base.build_flags} -Wno-unused-variable ${arduino_base.build_flags} -Wno-unused-variable
-Isrc/platform/rp2xx0 -Isrc/platform/rp2040
-D__PLAT_RP2040__ -D__PLAT_RP2040__
# -D _POSIX_THREADS # -D _POSIX_THREADS
build_src_filter = build_src_filter =
@@ -16,9 +16,8 @@ build_src_filter =
lib_ignore = lib_ignore =
BluetoothOTA BluetoothOTA
lvgl
lib_deps = lib_deps =
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${environmental_base.lib_deps} ${environmental_base.lib_deps}
rweather/Crypto rweather/Crypto

View File

@@ -1,25 +0,0 @@
; Common settings for rp2040 Processor based targets
[rp2040_base]
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#v1.2.0-gcc12
extends = arduino_base
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#4.0.3
board_build.core = earlephilhower
board_build.filesystem_size = 0.5m
build_flags =
${arduino_base.build_flags} -Wno-unused-variable -Wcast-align
-Isrc/platform/rp2xx0
-Isrc/platform/rp2xx0/hardware_rosc/include
-Isrc/platform/rp2xx0/pico_sleep/include
-D__PLAT_RP2040__
# -D _POSIX_THREADS
build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<modules/esp32> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/> -<mesh/wifi/> -<mesh/http/> -<mesh/raspihttp>
lib_ignore =
BluetoothOTA
lib_deps =
${arduino_base.lib_deps}
${environmental_base.lib_deps}
rweather/Crypto

View File

@@ -1,7 +1,7 @@
[stm32_base] [stm32_base]
extends = arduino_base extends = arduino_base
platform = ststm32 platform = ststm32
platform_packages = platformio/framework-arduinoststm32@https://github.com/stm32duino/Arduino_Core_STM32.git#ea74156acd823b6d14739f389e6cdc648f8ee36e platform_packages = platformio/framework-arduinoststm32@https://github.com/stm32duino/Arduino_Core_STM32.git#361a7fdb67e2a7104e99b4f42a802469eef8b129
build_type = release build_type = release
@@ -22,7 +22,7 @@ build_flags =
-fdata-sections -fdata-sections
build_src_filter = 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> ${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/rp2040> -<mesh/raspihttp>
board_upload.offset_address = 0x08000000 board_upload.offset_address = 0x08000000
upload_protocol = stlink upload_protocol = stlink
@@ -33,5 +33,5 @@ lib_deps =
https://github.com/caveman99/Crypto.git#f61ae26a53f7a2d0ba5511625b8bf8eff3a35d5e https://github.com/caveman99/Crypto.git#f61ae26a53f7a2d0ba5511625b8bf8eff3a35d5e
lib_ignore = lib_ignore =
mathertel/OneButton@~2.6.1 https://github.com/mathertel/OneButton@~2.6.1
Wire Wire

View File

@@ -1,48 +0,0 @@
import json
import subprocess
import re
def get_macros_from_header(header_file):
# Run clang to preprocess the header file and capture the output
result = subprocess.run(['clang', '-E', '-dM', header_file], capture_output=True, text=True)
if result.returncode != 0:
raise RuntimeError(f"Clang preprocessing failed: {result.stderr}")
# Extract macros from the output
macros = {}
macro_pattern = re.compile(r'#define\s+(\w+)\s+(.*)')
for line in result.stdout.splitlines():
match = macro_pattern.match(line)
if match and 'USERPREFS_' in line and '_USERPREFS_' not in line:
macros[match.group(1)] = match.group(2)
return macros
def write_macros_to_json(macros, output_file):
with open(output_file, 'w') as f:
json.dump(macros, f, indent=4)
def main():
header_file = 'userPrefs.h'
output_file = 'userPrefs.json'
# Uncomment all macros in the header file
with open(header_file, 'r') as file:
lines = file.readlines()
uncommented_lines = []
for line in lines:
stripped_line = line.strip().replace('/*', '').replace('*/', '')
if stripped_line.startswith('//') and 'USERPREFS_' in stripped_line:
# Replace "//"
stripped_line = stripped_line.replace('//', '')
uncommented_lines.append(stripped_line + '\n')
with open(header_file, 'w') as file:
for line in uncommented_lines:
file.write(line)
macros = get_macros_from_header(header_file)
write_macros_to_json(macros, output_file)
print(f"Macros have been written to {output_file}")
if __name__ == "__main__":
main()

View File

@@ -1,11 +1,14 @@
### Many device configs have been moved to /etc/meshtasticd/available.d
### To activate, simply copy or link the appropriate file into /etc/meshtasticd/config.d
### Define your devices here using Broadcom pin numbering ### Define your devices here using Broadcom pin numbering
### Uncomment the block that corresponds to your hardware ### Uncomment the block that corresponds to your hardware
### Including the "Module:" line! ### Including the "Module:" line!
--- ---
Lora: Lora:
# Module: sx1262 # Waveshare SX126X XXXM
# DIO2_AS_RF_SWITCH: true
# CS: 21
# IRQ: 16
# Busy: 20
# Reset: 18
# Module: sx1262 # Waveshare SX1302 LISTEN ONLY AT THIS TIME! # Module: sx1262 # Waveshare SX1302 LISTEN ONLY AT THIS TIME!
# CS: 7 # CS: 7
@@ -16,7 +19,6 @@ Lora:
# CS: 0 # CS: 0
# IRQ: 10 # IRQ: 10
# Busy: 11 # Busy: 11
# DIO2_AS_RF_SWITCH: true
# spidev: spidev0.1 # spidev: spidev0.1
# Module: RF95 # Adafruit RFM9x # Module: RF95 # Adafruit RFM9x
@@ -111,29 +113,6 @@ Display:
# Height: 320 # Height: 320
# Rotate: true # Rotate: true
### SHCHV 3.5 RPi TFT+Touchscreen
# Panel: ILI9486
# spidev: spidev0.0
# BusFrequency: 30000000
# DC: 24
# Reset: 25
# Width: 320
# Height: 480
# OffsetRotate: 2
### TZT 2.0 Inch TFT Display ST7789V 240RGBx320
# Panel: ST7789
# spidev: spidev0.0
# # CS: 8 # can be freely chosen
# BusFrequency: 80000000
# DC: 24 # can be freely chosen
# Width: 320
# Height: 240
# Reset: 25 # can be freely chosen
# Rotate: true
# OffsetRotate: 1
# Invert: true
### You can also specify the spi device for the display to use ### You can also specify the spi device for the display to use
# spidev: spidev0.0 # spidev: spidev0.0
@@ -175,4 +154,3 @@ Webserver:
General: General:
MaxNodes: 200 MaxNodes: 200
MaxMessageQueue: 100 MaxMessageQueue: 100
ConfigDirectory: /etc/meshtasticd/config.d/

View File

@@ -1,18 +0,0 @@
Display:
### Waveshare 2.8inch RPi LCD
Panel: ST7789
CS: 8
DC: 22 # Data/Command pin
Backlight: 18
Width: 240
Height: 320
Reset: 27
Rotate: true
Invert: true
Touchscreen:
### Note, at least for now, the touchscreen must have a CS pin defined, even if you let Linux manage the CS switching.
Module: XPT2046 # Waveshare 2.8inch
CS: 7
IRQ: 17

View File

@@ -1,8 +0,0 @@
Lora:
Module: sx1262 # Waveshare SX126X XXXM
DIO2_AS_RF_SWITCH: true
CS: 21
IRQ: 16
Busy: 20
Reset: 18
SX126X_ANT_SW: 6

View File

@@ -6,7 +6,6 @@ import configparser
import json import json
import os import os
import sys import sys
import random
rootdir = "variants/" rootdir = "variants/"
@@ -40,7 +39,5 @@ for subdir, dirs, files in os.walk(rootdir):
"check" in options "check" in options
): ):
outlist.append(section) outlist.append(section)
if ("quick" in options) & (len(outlist) > 3):
print(json.dumps(random.sample(outlist, 3))) print(json.dumps(outlist))
else:
print(json.dumps(outlist))

View File

@@ -1,16 +1,12 @@
[Unit] [Unit]
Description=Meshtastic Native Daemon Description=Meshtastic Native Daemon
After=network-online.target After=network-online.target
StartLimitInterval=200
StartLimitBurst=5
[Service] [Service]
User=root User=root
Group=root Group=root
Type=simple Type=simple
ExecStart=/usr/sbin/meshtasticd ExecStart=/usr/sbin/meshtasticd
Restart=always
RestartSec=3
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
cp "release/meshtasticd_linux_$(uname -m)" /usr/sbin/meshtasticd cp "release/meshtasticd_linux_$(uname -m)" /usr/sbin/meshtasticd
mkdir -p /etc/meshtasticd mkdir /etc/meshtasticd
if [[ -f "/etc/meshtasticd/config.yaml" ]]; then if [[ -f "/etc/meshtasticd/config.yaml" ]]; then
cp bin/config-dist.yaml /etc/meshtasticd/config-upgrade.yaml cp bin/config-dist.yaml /etc/meshtasticd/config-upgrade.yaml
else else

View File

@@ -1 +1 @@
cd protobufs && ..\nanopb-0.4.9\generator-bin\protoc.exe --experimental_allow_proto3_optional "--nanopb_out=-S.cpp -v:..\src\mesh\generated" -I=..\protobufs\ ..\protobufs\meshtastic\*.proto cd protobufs && ..\nanopb-0.4.8\generator-bin\protoc.exe --experimental_allow_proto3_optional "--nanopb_out=-S.cpp -v:..\src\mesh\generated" -I=..\protobufs\ ..\protobufs\meshtastic\*.proto

View File

@@ -2,10 +2,10 @@
set -e set -e
echo "This script requires https://jpa.kapsi.fi/nanopb/download/ version 0.4.9 to be located in the" echo "This script requires https://jpa.kapsi.fi/nanopb/download/ version 0.4.8 to be located in the"
echo "firmware root directory if the following step fails, you should download the correct" echo "firmware root directory if the following step fails, you should download the correct"
echo "prebuilt binaries for your computer into nanopb-0.4.9" echo "prebuilt binaries for your computer into nanopb-0.4.8"
# the nanopb tool seems to require that the .options file be in the current directory! # the nanopb tool seems to require that the .options file be in the current directory!
cd protobufs cd protobufs
../nanopb-0.4.9/generator-bin/protoc --experimental_allow_proto3_optional "--nanopb_out=-S.cpp -v:../src/mesh/generated/" -I=../protobufs meshtastic/*.proto ../nanopb-0.4.8/generator-bin/protoc --experimental_allow_proto3_optional "--nanopb_out=-S.cpp -v:../src/mesh/generated/" -I=../protobufs meshtastic/*.proto

View File

@@ -28,8 +28,6 @@
"flash_size": "8MB", "flash_size": "8MB",
"maximum_ram_size": 327680, "maximum_ram_size": 327680,
"maximum_size": 8388608, "maximum_size": 8388608,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"require_upload_port": true, "require_upload_port": true,
"speed": 921600 "speed": 921600
}, },

View File

@@ -5,7 +5,7 @@
}, },
"core": "nRF5", "core": "nRF5",
"cpu": "cortex-m4", "cpu": "cortex-m4",
"extra_flags": "-DHELTEC_T114 -DNRF52840_XXAA", "extra_flags": "-DARDUINO_NRF52840_PCA10056 -DNRF52840_XXAA",
"f_cpu": "64000000L", "f_cpu": "64000000L",
"hwids": [ "hwids": [
["0x239A", "0x4405"], ["0x239A", "0x4405"],

View File

@@ -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=0"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [["0x2886", "0x0059"]],
"mcu": "esp32s3",
"variant": "icarus"
},
"connectivity": ["wifi", "bluetooth", "lora"],
"debug": {
"default_tool": "esp-builtin",
"onboard_tools": ["esp-builtin"],
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "icarus",
"upload": {
"flash_size": "8MB",
"maximum_ram_size": 8388608,
"maximum_size": 8388608,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 921600
},
"url": "https://icarus.azlan.works",
"vendor": "Muhammad Shah"
}

47
boards/lora-relay-v1.json Normal file
View File

@@ -0,0 +1,47 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_LORA_RELAY_V1 -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [["0x239A", "0x4404"]],
"usb_product": "LORA_RELAY",
"mcu": "nrf52840",
"variant": "lora_relay_v1",
"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": "Meshtastic Lora Relay V1 (Adafruit BSP)",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"require_upload_port": true,
"speed": 115200,
"protocol": "jlink",
"protocols": ["jlink", "nrfjprog", "stlink"]
},
"url": "https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay",
"vendor": "BigCorvus"
}

47
boards/lora-relay-v2.json Normal file
View File

@@ -0,0 +1,47 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_LORA_RELAY_V2 -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [["0x239A", "0x4406"]],
"usb_product": "LORA_RELAY",
"mcu": "nrf52840",
"variant": "lora_relay_v2",
"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": "Meshtastic Lora Relay V1 (Adafruit BSP)",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"require_upload_port": true,
"speed": 115200,
"protocol": "jlink",
"protocols": ["jlink", "nrfjprog", "stlink"]
},
"url": "https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay",
"vendor": "BigCorvus"
}

40
boards/lora_isp4520.json Normal file
View File

@@ -0,0 +1,40 @@
{
"build": {
"arduino": {
"ldscript": "nrf52832_s132_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DNRF52832_XXAA -DNRF52",
"f_cpu": "64000000L",
"mcu": "nrf52832",
"variant": "lora_isp4520",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_flags": "-DS132",
"sd_name": "s132",
"sd_version": "6.1.1",
"sd_fwid": "0x00B7"
}
},
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52832_xxAA",
"svd_path": "nrf52.svd",
"openocd_target": "nrf52840-mdk-rs"
},
"frameworks": ["arduino"],
"name": "lora ISP4520",
"upload": {
"maximum_ram_size": 65536,
"maximum_size": 524288,
"require_upload_port": true,
"speed": 115200,
"protocol": "nrfutil",
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"]
},
"url": "",
"vendor": "PsiSoft"
}

View File

@@ -5,7 +5,7 @@
}, },
"core": "nRF5", "core": "nRF5",
"cpu": "cortex-m4", "cpu": "cortex-m4",
"extra_flags": "-DME25LS01_4Y10TD -DNRF52840_XXAA", "extra_flags": "-DARDUINO_WIO_WM1110 -DNRF52840_XXAA",
"f_cpu": "64000000L", "f_cpu": "64000000L",
"hwids": [ "hwids": [
["0x239A", "0x8029"], ["0x239A", "0x8029"],

View File

@@ -5,7 +5,7 @@
}, },
"core": "nRF5", "core": "nRF5",
"cpu": "cortex-m4", "cpu": "cortex-m4",
"extra_flags": "-DMS24SF1 -DNRF52840_XXAA", "extra_flags": "-DARDUINO_WIO_WM1110 -DNRF52840_XXAA",
"f_cpu": "64000000L", "f_cpu": "64000000L",
"hwids": [ "hwids": [
["0x239A", "0x8029"], ["0x239A", "0x8029"],

View File

@@ -5,7 +5,7 @@
}, },
"core": "nRF5", "core": "nRF5",
"cpu": "cortex-m4", "cpu": "cortex-m4",
"extra_flags": "-DNORDIC_PCA10059 -DNRF52840_XXAA", "extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
"f_cpu": "64000000L", "f_cpu": "64000000L",
"hwids": [ "hwids": [
["0x239A", "0x8029"], ["0x239A", "0x8029"],

View File

@@ -0,0 +1,47 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s113_v7.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_PCA10056 -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [["0x239A", "0x4404"]],
"usb_product": "nrf52840dk",
"mcu": "nrf52840",
"variant": "pca10056-rc-clock",
"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": "A modified NRF52840-DK devboard (Adafruit BSP)",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"require_upload_port": true,
"speed": 115200,
"protocol": "jlink",
"protocols": ["jlink", "nrfjprog", "stlink"]
},
"url": "https://meshtastic.org/",
"vendor": "Nordic Semi"
}

47
boards/ppr.json Normal file
View File

@@ -0,0 +1,47 @@
{
"build": {
"arduino": {
"ldscript": "nrf52840_s140_v6.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_PPR -DNRF52840_XXAA",
"f_cpu": "64000000L",
"hwids": [["0x239A", "0x4403"]],
"usb_product": "PPR",
"mcu": "nrf52840",
"variant": "ppr",
"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": "Meshtastic PPR (Adafruit BSP)",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"require_upload_port": true,
"speed": 115200,
"protocol": "jlink",
"protocols": ["jlink", "nrfjprog", "stlink"]
},
"url": "https://meshtastic.org/",
"vendor": "Othernet"
}

47
boards/ppr1.json Normal file
View File

@@ -0,0 +1,47 @@
{
"build": {
"arduino": {
"ldscript": "nrf52833_s113_v7.ld"
},
"core": "nRF5",
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52833_PPR -DNRF52833_XXAA",
"f_cpu": "64000000L",
"hwids": [["0x239A", "0x4406"]],
"usb_product": "PPR",
"mcu": "nrf52833",
"variant": "ppr",
"variants_dir": "variants",
"bsp": {
"name": "adafruit"
},
"softdevice": {
"sd_flags": "-DS113",
"sd_name": "s113",
"sd_version": "7.2.0",
"sd_fwid": "0x00b6"
},
"bootloader": {
"settings_addr": "0xFF000"
}
},
"connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52833_xxAA",
"onboard_tools": ["jlink"],
"svd_path": "nrf52833.svd",
"openocd_target": "nrf52840-mdk-rs"
},
"frameworks": ["arduino"],
"name": "Meshtastic PPR1 (Adafruit BSP)",
"upload": {
"maximum_ram_size": 248832,
"maximum_size": 815104,
"require_upload_port": true,
"speed": 115200,
"protocol": "jlink",
"protocols": ["jlink", "nrfjprog", "stlink"]
},
"url": "https://meshtastic.org/",
"vendor": "Othernet"
}

View File

@@ -1,42 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"partitions": "default_8MB.csv",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DARDUINO_USB_CDC_ON_BOOT=0",
"-DARDUINO_USB_MODE=1",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=1"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [["0x1A86", "0x7523"]],
"mcu": "esp32s3",
"variant": "esp32s3r8"
},
"connectivity": ["wifi", "bluetooth", "lora"],
"debug": {
"default_tool": "esp-builtin",
"onboard_tools": ["esp-builtin"],
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino"],
"name": "Seeed Studio SenseCAP Indicator",
"upload": {
"flash_size": "8MB",
"maximum_ram_size": 327680,
"maximum_size": 8388608,
"require_upload_port": true,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"speed": 921600
},
"url": "https://www.seeedstudio.com/Indicator-for-Meshtastic.html",
"vendor": "Seeed Studio"
}

View File

@@ -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=0"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [["0x2886", "0x0059"]],
"mcu": "esp32s3",
"variant": "seeed-xiao-s3"
},
"connectivity": ["wifi", "bluetooth", "lora"],
"debug": {
"default_tool": "esp-builtin",
"onboard_tools": ["esp-builtin"],
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "seeed-xiao-s3",
"upload": {
"flash_size": "8MB",
"maximum_ram_size": 8388608,
"maximum_size": 8388608,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 921600
},
"url": "https://www.seeedstudio.com/XIAO-ESP32S3-Sense-p-5639.html",
"vendor": "Seeed Studio"
}

View File

@@ -1,46 +0,0 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_opi",
"partitions": "default_8MB.csv"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DUNPHONE_SPIN=9",
"-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": [
["0x16D0", "0x1178"],
["0x303a", "0x1001"]
],
"mcu": "esp32s3",
"variant": "unphone"
},
"connectivity": ["wifi", "bluetooth", "lora"],
"debug": {
"default_tool": "esp-builtin",
"onboard_tools": ["esp-builtin"],
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "unPhone",
"upload": {
"flash_size": "8MB",
"maximum_ram_size": 327680,
"maximum_size": 8323072,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 921600
},
"url": "https://unphone.net/",
"vendor": "University of Sheffield"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 594 B

After

Width:  |  Height:  |  Size: 845 B

View File

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M9 11.75a1.25 1.25 0 1 0 0 2.5 1.25 1.25 0 0 0 0-2.5m6 0a1.25 1.25 0 1 0 0 2.5 1.25 1.25 0 0 0 0-2.5M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2m0 18c-4.41 0-8-3.59-8-8 0-.29.02-.58.05-.86 2.36-1.05 4.23-2.98 5.21-5.37a9.97 9.97 0 0 0 10.41 3.97c.21.71.33 1.47.33 2.26 0 4.41-3.59 8-8 8"/><path fill="none" d="M0 0h24v24H0z"/></svg> <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M9 11.75c-.69 0-1.25.56-1.25 1.25s.56 1.25 1.25 1.25 1.25-.56 1.25-1.25-.56-1.25-1.25-1.25zm6 0c-.69 0-1.25.56-1.25 1.25s.56 1.25 1.25 1.25 1.25-.56 1.25-1.25-.56-1.25-1.25-1.25zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8 0-.29.02-.58.05-.86 2.36-1.05 4.23-2.98 5.21-5.37C11.07 8.33 14.05 10 17.42 10c.78 0 1.53-.09 2.25-.26.21.71.33 1.47.33 2.26 0 4.41-3.59 8-8 8z"/><path d="M0 0h24v24H0z" fill="none"/></svg>

Before

Width:  |  Height:  |  Size: 445 B

After

Width:  |  Height:  |  Size: 550 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 225 B

After

Width:  |  Height:  |  Size: 329 B

View File

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M20.94 11A8.994 8.994 0 0 0 13 3.06V1h-2v2.06A8.994 8.994 0 0 0 3.06 11H1v2h2.06A8.994 8.994 0 0 0 11 20.94V23h2v-2.06A8.994 8.994 0 0 0 20.94 13H23v-2zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7"/></svg> <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M20.94 11c-.46-4.17-3.77-7.48-7.94-7.94V1h-2v2.06C6.83 3.52 3.52 6.83 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c4.17-.46 7.48-3.77 7.94-7.94H23v-2h-2.06zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/></svg>

Before

Width:  |  Height:  |  Size: 348 B

After

Width:  |  Height:  |  Size: 365 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 B

After

Width:  |  Height:  |  Size: 288 B

View File

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7m0 9.5a2.5 2.5 0 0 1 0-5 2.5 2.5 0 0 1 0 5"/><path fill="none" d="M0 0h24v24H0z"/></svg> <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>

Before

Width:  |  Height:  |  Size: 250 B

After

Width:  |  Height:  |  Size: 292 B

View File

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2M9 11H7V9h2zm4 0h-2V9h2zm4 0h-2V9h2z"/><path fill="none" d="M0 0h24v24H0z"/></svg> <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM9 11H7V9h2v2zm4 0h-2V9h2v2zm4 0h-2V9h2v2z"/><path d="M0 0h24v24H0z" fill="none"/></svg>

Before

Width:  |  Height:  |  Size: 246 B

After

Width:  |  Height:  |  Size: 253 B

View File

@@ -17,9 +17,11 @@ default_envs = tbeam
;default_envs = tlora-v2-1-1_6 ;default_envs = tlora-v2-1-1_6
;default_envs = tlora-v2-1-1_6-tcxo ;default_envs = tlora-v2-1-1_6-tcxo
;default_envs = tlora-t3s3-v1 ;default_envs = tlora-t3s3-v1
;default_envs = lora-relay-v1 # nrf board
;default_envs = t-echo ;default_envs = t-echo
;default_envs = canaryone ;default_envs = canaryone
;default_envs = native ;default_envs = nrf52840dk-geeksville
;default_envs = native # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here
;default_envs = nano-g1 ;default_envs = nano-g1
;default_envs = pca10059_diy_eink ;default_envs = pca10059_diy_eink
;default_envs = meshtastic-diy-v1 ;default_envs = meshtastic-diy-v1
@@ -27,7 +29,6 @@ default_envs = tbeam
;default_envs = meshtastic-dr-dev ;default_envs = meshtastic-dr-dev
;default_envs = m5stack-coreink ;default_envs = m5stack-coreink
;default_envs = rak4631 ;default_envs = rak4631
;default_envs = rak4631_eth_gw
;default_envs = rak2560 ;default_envs = rak2560
;default_envs = rak10701 ;default_envs = rak10701
;default_envs = wio-e5 ;default_envs = wio-e5
@@ -59,44 +60,43 @@ build_flags = -Wno-missing-field-initializers
-DUSE_THREAD_NAMES -DUSE_THREAD_NAMES
-DTINYGPS_OPTION_NO_CUSTOM_FIELDS -DTINYGPS_OPTION_NO_CUSTOM_FIELDS
-DPB_ENABLE_MALLOC=1 -DPB_ENABLE_MALLOC=1
-DRADIOLIB_EXCLUDE_CC1101=1 -DRADIOLIB_EXCLUDE_CC1101
-DRADIOLIB_EXCLUDE_NRF24=1 -DRADIOLIB_EXCLUDE_NRF24
-DRADIOLIB_EXCLUDE_RF69=1 -DRADIOLIB_EXCLUDE_RF69
-DRADIOLIB_EXCLUDE_SX1231=1 -DRADIOLIB_EXCLUDE_SX1231
-DRADIOLIB_EXCLUDE_SX1233=1 -DRADIOLIB_EXCLUDE_SX1233
-DRADIOLIB_EXCLUDE_SI443X=1 -DRADIOLIB_EXCLUDE_SI443X
-DRADIOLIB_EXCLUDE_RFM2X=1 -DRADIOLIB_EXCLUDE_RFM2X
-DRADIOLIB_EXCLUDE_AFSK=1 -DRADIOLIB_EXCLUDE_AFSK
-DRADIOLIB_EXCLUDE_BELL=1 -DRADIOLIB_EXCLUDE_BELL
-DRADIOLIB_EXCLUDE_HELLSCHREIBER=1 -DRADIOLIB_EXCLUDE_HELLSCHREIBER
-DRADIOLIB_EXCLUDE_MORSE=1 -DRADIOLIB_EXCLUDE_MORSE
-DRADIOLIB_EXCLUDE_RTTY=1 -DRADIOLIB_EXCLUDE_RTTY
-DRADIOLIB_EXCLUDE_SSTV=1 -DRADIOLIB_EXCLUDE_SSTV
-DRADIOLIB_EXCLUDE_AX25=1 -DRADIOLIB_EXCLUDE_AX25
-DRADIOLIB_EXCLUDE_DIRECT_RECEIVE=1 -DRADIOLIB_EXCLUDE_DIRECT_RECEIVE
-DRADIOLIB_EXCLUDE_BELL=1 -DRADIOLIB_EXCLUDE_BELL
-DRADIOLIB_EXCLUDE_PAGER=1 -DRADIOLIB_EXCLUDE_PAGER
-DRADIOLIB_EXCLUDE_FSK4=1 -DRADIOLIB_EXCLUDE_FSK4
-DRADIOLIB_EXCLUDE_APRS=1 -DRADIOLIB_EXCLUDE_APRS
-DRADIOLIB_EXCLUDE_LORAWAN=1 -DRADIOLIB_EXCLUDE_LORAWAN
-DMESHTASTIC_EXCLUDE_DROPZONE=1 -DMESHTASTIC_EXCLUDE_DROPZONE=1
-DMESHTASTIC_EXCLUDE_REMOTEHARDWARE=1
#-DBUILD_EPOCH=$UNIX_TIME
;-D OLED_PL ;-D OLED_PL
monitor_speed = 115200 monitor_speed = 115200
monitor_filters = direct monitor_filters = direct
lib_deps = lib_deps =
jgromes/RadioLib@~7.0.2 ; jgromes/RadioLib@~6.6.0
https://github.com/jgromes/RadioLib.git#3115fc2d6700a9aee05888791ac930a910f2628f
https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95 ; ESP8266_SSD1306 https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95 ; ESP8266_SSD1306
mathertel/OneButton@~2.6.1 ; OneButton library for non-blocking button debounce https://github.com/mathertel/OneButton@~2.6.1 ; OneButton library for non-blocking button debounce
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159 https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
https://github.com/meshtastic/TinyGPSPlus.git#71a82db35f3b973440044c476d4bcdc673b104f4 https://github.com/meshtastic/TinyGPSPlus.git#71a82db35f3b973440044c476d4bcdc673b104f4
https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0 https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0
nanopb/Nanopb@^0.4.9 nanopb/Nanopb@^0.4.8
erriez/ErriezCRC32@^1.0.1 erriez/ErriezCRC32@^1.0.1
; Used for the code analysis in PIO Home / Inspect ; Used for the code analysis in PIO Home / Inspect
check_tool = cppcheck check_tool = cppcheck
check_skip_packages = yes check_skip_packages = yes
@@ -127,7 +127,7 @@ lib_deps =
; (not included in native / portduino) ; (not included in native / portduino)
[environmental_base] [environmental_base]
lib_deps = lib_deps =
adafruit/Adafruit BusIO@^1.16.1 adafruit/Adafruit BusIO@^1.15.0
adafruit/Adafruit Unified Sensor@^1.1.11 adafruit/Adafruit Unified Sensor@^1.1.11
adafruit/Adafruit BMP280 Library@^2.6.8 adafruit/Adafruit BMP280 Library@^2.6.8
adafruit/Adafruit BMP085 Library@^1.2.4 adafruit/Adafruit BMP085 Library@^1.2.4
@@ -136,31 +136,25 @@ lib_deps =
adafruit/Adafruit MCP9808 Library@^2.0.0 adafruit/Adafruit MCP9808 Library@^2.0.0
adafruit/Adafruit INA260 Library@^1.5.0 adafruit/Adafruit INA260 Library@^1.5.0
adafruit/Adafruit INA219@^1.2.0 adafruit/Adafruit INA219@^1.2.0
adafruit/Adafruit MAX1704X@^1.0.3
adafruit/Adafruit SHTC3 Library@^1.0.0 adafruit/Adafruit SHTC3 Library@^1.0.0
adafruit/Adafruit LPS2X@^2.0.4 adafruit/Adafruit LPS2X@^2.0.4
adafruit/Adafruit SHT31 Library@^2.2.2 adafruit/Adafruit SHT31 Library@^2.2.2
adafruit/Adafruit PM25 AQI Sensor@^1.1.1 adafruit/Adafruit PM25 AQI Sensor@^1.0.6
adafruit/Adafruit MPU6050@^2.2.4 adafruit/Adafruit MPU6050@^2.2.4
adafruit/Adafruit LIS3DH@^1.3.0 adafruit/Adafruit LIS3DH@^1.2.4
adafruit/Adafruit AHTX0@^2.0.5 adafruit/Adafruit AHTX0@^2.0.5
adafruit/Adafruit LSM6DS@^4.7.2 adafruit/Adafruit LSM6DS@^4.7.2
adafruit/Adafruit VEML7700 Library@^2.1.6 adafruit/Adafruit VEML7700 Library@^2.1.6
adafruit/Adafruit SHT4x Library@^1.0.4 adafruit/Adafruit SHT4x Library@^1.0.4
adafruit/Adafruit TSL2591 Library@^1.4.5 adafruit/Adafruit TSL2591 Library@^1.4.5
sparkfun/SparkFun Qwiic Scale NAU7802 Arduino Library@^1.0.5 sparkfun/SparkFun Qwiic Scale NAU7802 Arduino Library@^1.0.5
sparkfun/SparkFun 9DoF IMU Breakout - ICM 20948 - Arduino Library@^1.2.13
ClosedCube OPT3001@^1.1.2 ClosedCube OPT3001@^1.1.2
emotibit/EmotiBit MLX90632@^1.0.8 emotibit/EmotiBit MLX90632@^1.0.8
dfrobot/DFRobot_RTU@^1.0.3 dfrobot/DFRobot_RTU@^1.0.3
sparkfun/SparkFun MAX3010x Pulse and Proximity Sensor Library@^1.1.2
adafruit/Adafruit MLX90614 Library@^2.1.5
https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502 https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502
boschsensortec/BME68x Sensor Library@^1.1.40407 boschsensortec/BME68x Sensor Library@^1.1.40407
https://github.com/KodinLanewave/INA3221@^1.0.1 https://github.com/KodinLanewave/INA3221@^1.0.0
lewisxhe/SensorLib@0.2.0 lewisxhe/SensorLib@^0.2.0
mprograms/QMC5883LCompass@^1.2.0 mprograms/QMC5883LCompass@^1.2.0
https://github.com/meshtastic/DFRobot_LarkWeatherStation#dee914270dc7cb3e43fbf034edd85a63a16a12ee
https://github.com/meshtastic/DFRobot_LarkWeatherStation#4de3a9cadef0f6a5220a8a906cf9775b02b0040d https://github.com/meshtastic/i2c-sensor#8e97122268960593c8c279df1a84a29970136a8f
https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1

297
src/AccelerometerThread.h Normal file
View File

@@ -0,0 +1,297 @@
#pragma once
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "PowerFSM.h"
#include "concurrency/OSThread.h"
#include "main.h"
#include "power.h"
#include <Adafruit_LIS3DH.h>
#include <Adafruit_LSM6DS3TRC.h>
#include <Adafruit_MPU6050.h>
#include <Arduino.h>
#include <SensorBMA423.hpp>
#include <Wire.h>
#ifdef RAK_4631
#include "Fusion/Fusion.h"
#include "graphics/Screen.h"
#include "graphics/ScreenFonts.h"
#include <Rak_BMX160.h>
#endif
#define ACCELEROMETER_CHECK_INTERVAL_MS 100
#define ACCELEROMETER_CLICK_THRESHOLD 40
static inline int readRegister(uint8_t address, uint8_t reg, uint8_t *data, uint8_t len)
{
Wire.beginTransmission(address);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom((uint8_t)address, (uint8_t)len);
uint8_t i = 0;
while (Wire.available()) {
data[i++] = Wire.read();
}
return 0; // Pass
}
static inline int writeRegister(uint8_t address, uint8_t reg, uint8_t *data, uint8_t len)
{
Wire.beginTransmission(address);
Wire.write(reg);
Wire.write(data, len);
return (0 != Wire.endTransmission());
}
class AccelerometerThread : public concurrency::OSThread
{
public:
explicit AccelerometerThread(ScanI2C::DeviceType type) : OSThread("AccelerometerThread")
{
if (accelerometer_found.port == ScanI2C::I2CPort::NO_I2C) {
LOG_DEBUG("AccelerometerThread disabling due to no sensors found\n");
disable();
return;
}
acceleremoter_type = type;
#ifndef RAK_4631
if (!config.display.wake_on_tap_or_motion && !config.device.double_tap_as_button_press) {
LOG_DEBUG("AccelerometerThread disabling due to no interested configurations\n");
disable();
return;
}
#endif
init();
}
void start()
{
init();
setIntervalFromNow(0);
};
protected:
int32_t runOnce() override
{
canSleep = true; // Assume we should not keep the board awake
if (acceleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.getMotionInterruptStatus()) {
wakeScreen();
} else if (acceleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.getClick() > 0) {
uint8_t click = lis.getClick();
if (!config.device.double_tap_as_button_press) {
wakeScreen();
}
if (config.device.double_tap_as_button_press && (click & 0x20)) {
buttonPress();
return 500;
}
} else if (acceleremoter_type == ScanI2C::DeviceType::BMA423 && bmaSensor.readIrqStatus() != DEV_WIRE_NONE) {
if (bmaSensor.isTilt() || bmaSensor.isDoubleTap()) {
wakeScreen();
return 500;
}
#ifdef RAK_4631
} else if (acceleremoter_type == ScanI2C::DeviceType::BMX160) {
sBmx160SensorData_t magAccel;
sBmx160SensorData_t gAccel;
/* Get a new sensor event */
bmx160.getAllData(&magAccel, NULL, &gAccel);
// expirimental calibrate routine. Limited to between 10 and 30 seconds after boot
if (millis() > 12 * 1000 && millis() < 30 * 1000) {
if (!showingScreen) {
showingScreen = true;
screen->startAlert((FrameCallback)drawFrameCalibration);
}
if (magAccel.x > highestX)
highestX = magAccel.x;
if (magAccel.x < lowestX)
lowestX = magAccel.x;
if (magAccel.y > highestY)
highestY = magAccel.y;
if (magAccel.y < lowestY)
lowestY = magAccel.y;
if (magAccel.z > highestZ)
highestZ = magAccel.z;
if (magAccel.z < lowestZ)
lowestZ = magAccel.z;
} else if (showingScreen && millis() >= 30 * 1000) {
showingScreen = false;
screen->endAlert();
}
int highestRealX = highestX - (highestX + lowestX) / 2;
magAccel.x -= (highestX + lowestX) / 2;
magAccel.y -= (highestY + lowestY) / 2;
magAccel.z -= (highestZ + lowestZ) / 2;
FusionVector ga, ma;
ga.axis.x = -gAccel.x; // default location for the BMX160 is on the rear of the board
ga.axis.y = -gAccel.y;
ga.axis.z = gAccel.z;
ma.axis.x = -magAccel.x;
ma.axis.y = -magAccel.y;
ma.axis.z = magAccel.z * 3;
// If we're set to one of the inverted positions
if (config.display.compass_orientation > meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270) {
ma = FusionAxesSwap(ma, FusionAxesAlignmentNXNYPZ);
ga = FusionAxesSwap(ga, FusionAxesAlignmentNXNYPZ);
}
float heading = FusionCompassCalculateHeading(FusionConventionNed, ga, ma);
switch (config.display.compass_orientation) {
case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_0_INVERTED:
case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_0:
break;
case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_90:
case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_90_INVERTED:
heading += 90;
break;
case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_180:
case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_180_INVERTED:
heading += 180;
break;
case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270:
case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270_INVERTED:
heading += 270;
break;
}
screen->setHeading(heading);
#endif
} else if (acceleremoter_type == ScanI2C::DeviceType::LSM6DS3 && lsm.shake()) {
wakeScreen();
return 500;
}
return ACCELEROMETER_CHECK_INTERVAL_MS;
}
private:
void init()
{
LOG_DEBUG("AccelerometerThread initializing\n");
if (acceleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.begin(accelerometer_found.address)) {
LOG_DEBUG("MPU6050 initializing\n");
// setup motion detection
mpu.setHighPassFilter(MPU6050_HIGHPASS_0_63_HZ);
mpu.setMotionDetectionThreshold(1);
mpu.setMotionDetectionDuration(20);
mpu.setInterruptPinLatch(true); // Keep it latched. Will turn off when reinitialized.
mpu.setInterruptPinPolarity(true);
} else if (acceleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.begin(accelerometer_found.address)) {
LOG_DEBUG("LIS3DH initializing\n");
lis.setRange(LIS3DH_RANGE_2_G);
// Adjust threshold, higher numbers are less sensitive
lis.setClick(config.device.double_tap_as_button_press ? 2 : 1, ACCELEROMETER_CLICK_THRESHOLD);
} else if (acceleremoter_type == ScanI2C::DeviceType::BMA423 &&
bmaSensor.begin(accelerometer_found.address, &readRegister, &writeRegister)) {
LOG_DEBUG("BMA423 initializing\n");
bmaSensor.configAccelerometer(bmaSensor.RANGE_2G, bmaSensor.ODR_100HZ, bmaSensor.BW_NORMAL_AVG4,
bmaSensor.PERF_CONTINUOUS_MODE);
bmaSensor.enableAccelerometer();
bmaSensor.configInterrupt(BMA4_LEVEL_TRIGGER, BMA4_ACTIVE_HIGH, BMA4_PUSH_PULL, BMA4_OUTPUT_ENABLE,
BMA4_INPUT_DISABLE);
#ifdef BMA423_INT
pinMode(BMA4XX_INT, INPUT);
attachInterrupt(
BMA4XX_INT,
[] {
// Set interrupt to set irq value to true
BMA_IRQ = true;
},
RISING); // Select the interrupt mode according to the actual circuit
#endif
#ifdef T_WATCH_S3
// Need to raise the wrist function, need to set the correct axis
bmaSensor.setReampAxes(bmaSensor.REMAP_TOP_LAYER_RIGHT_CORNER);
#else
bmaSensor.setReampAxes(bmaSensor.REMAP_BOTTOM_LAYER_BOTTOM_LEFT_CORNER);
#endif
// bmaSensor.enableFeature(bmaSensor.FEATURE_STEP_CNTR, true);
bmaSensor.enableFeature(bmaSensor.FEATURE_TILT, true);
bmaSensor.enableFeature(bmaSensor.FEATURE_WAKEUP, true);
// bmaSensor.resetPedometer();
// Turn on feature interrupt
bmaSensor.enablePedometerIRQ();
bmaSensor.enableTiltIRQ();
// It corresponds to isDoubleClick interrupt
bmaSensor.enableWakeupIRQ();
#ifdef RAK_4631
} else if (acceleremoter_type == ScanI2C::DeviceType::BMX160 && bmx160.begin()) {
bmx160.ODR_Config(BMX160_ACCEL_ODR_100HZ, BMX160_GYRO_ODR_100HZ); // set output data rate
#endif
} else if (acceleremoter_type == ScanI2C::DeviceType::LSM6DS3 && lsm.begin_I2C(accelerometer_found.address)) {
LOG_DEBUG("LSM6DS3 initializing\n");
// Default threshold of 2G, less sensitive options are 4, 8 or 16G
lsm.setAccelRange(LSM6DS_ACCEL_RANGE_2_G);
#ifndef LSM6DS3_WAKE_THRESH
#define LSM6DS3_WAKE_THRESH 20
#endif
lsm.enableWakeup(config.display.wake_on_tap_or_motion, 1, LSM6DS3_WAKE_THRESH);
// Duration is number of occurances needed to trigger, higher threshold is less sensitive
}
}
void wakeScreen()
{
if (powerFSM.getState() == &stateDARK) {
LOG_INFO("Tap or motion detected. Turning on screen\n");
powerFSM.trigger(EVENT_INPUT);
}
}
void buttonPress()
{
LOG_DEBUG("Double-tap detected. Firing button press\n");
powerFSM.trigger(EVENT_PRESS);
}
ScanI2C::DeviceType acceleremoter_type;
Adafruit_MPU6050 mpu;
Adafruit_LIS3DH lis;
Adafruit_LSM6DS3TRC lsm;
SensorBMA423 bmaSensor;
bool BMA_IRQ = false;
#ifdef RAK_4631
bool showingScreen = false;
RAK_BMX160 bmx160;
float highestX = 0, lowestX = 0, highestY = 0, lowestY = 0, highestZ = 0, lowestZ = 0;
static void drawFrameCalibration(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
int x_offset = display->width() / 2;
int y_offset = display->height() <= 80 ? 0 : 32;
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_MEDIUM);
display->drawString(x, y, "Calibrating\nCompass");
int16_t compassX = 0, compassY = 0;
uint16_t compassDiam = graphics::Screen::getCompassDiam(display->getWidth(), display->getHeight());
// coordinates for the center of the compass/circle
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
compassX = x + display->getWidth() - compassDiam / 2 - 5;
compassY = y + display->getHeight() / 2;
} else {
compassX = x + display->getWidth() - compassDiam / 2 - 5;
compassY = y + FONT_HEIGHT_SMALL + (display->getHeight() - FONT_HEIGHT_SMALL) / 2;
}
display->drawCircle(compassX, compassY, compassDiam / 2);
screen->drawCompassNorth(display, compassX, compassY, screen->getHeading() * PI / 180);
}
#endif
};
#endif

View File

@@ -42,18 +42,18 @@ class AmbientLightingThread : public concurrency::OSThread
#ifdef HAS_NCP5623 #ifdef HAS_NCP5623
_type = type; _type = type;
if (_type == ScanI2C::DeviceType::NONE) { if (_type == ScanI2C::DeviceType::NONE) {
LOG_DEBUG("AmbientLightingThread disabling due to no RGB leds found on I2C bus"); LOG_DEBUG("AmbientLightingThread disabling due to no RGB leds found on I2C bus\n");
disable(); disable();
return; return;
} }
#endif #endif
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE) #if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
if (!moduleConfig.ambient_lighting.led_state) { if (!moduleConfig.ambient_lighting.led_state) {
LOG_DEBUG("AmbientLightingThread disabling due to moduleConfig.ambient_lighting.led_state OFF"); LOG_DEBUG("AmbientLightingThread disabling due to moduleConfig.ambient_lighting.led_state OFF\n");
disable(); disable();
return; return;
} }
LOG_DEBUG("AmbientLightingThread initializing"); LOG_DEBUG("AmbientLightingThread initializing\n");
#ifdef HAS_NCP5623 #ifdef HAS_NCP5623
if (_type == ScanI2C::NCP5623) { if (_type == ScanI2C::NCP5623) {
rgb.begin(); rgb.begin();
@@ -106,27 +106,27 @@ class AmbientLightingThread : public concurrency::OSThread
rgb.setRed(0); rgb.setRed(0);
rgb.setGreen(0); rgb.setGreen(0);
rgb.setBlue(0); rgb.setBlue(0);
LOG_INFO("Turn Off NCP5623 Ambient lighting."); LOG_INFO("Turn Off NCP5623 Ambient lighting.\n");
#endif #endif
#ifdef HAS_NEOPIXEL #ifdef HAS_NEOPIXEL
pixels.clear(); pixels.clear();
pixels.show(); pixels.show();
LOG_INFO("Turn Off NeoPixel Ambient lighting."); LOG_INFO("Turn Off NeoPixel Ambient lighting.\n");
#endif #endif
#ifdef RGBLED_CA #ifdef RGBLED_CA
analogWrite(RGBLED_RED, 255 - 0); analogWrite(RGBLED_RED, 255 - 0);
analogWrite(RGBLED_GREEN, 255 - 0); analogWrite(RGBLED_GREEN, 255 - 0);
analogWrite(RGBLED_BLUE, 255 - 0); analogWrite(RGBLED_BLUE, 255 - 0);
LOG_INFO("Turn Off Ambient lighting RGB Common Anode."); LOG_INFO("Turn Off Ambient lighting RGB Common Anode.\n");
#elif defined(RGBLED_RED) #elif defined(RGBLED_RED)
analogWrite(RGBLED_RED, 0); analogWrite(RGBLED_RED, 0);
analogWrite(RGBLED_GREEN, 0); analogWrite(RGBLED_GREEN, 0);
analogWrite(RGBLED_BLUE, 0); analogWrite(RGBLED_BLUE, 0);
LOG_INFO("Turn Off Ambient lighting RGB Common Cathode."); LOG_INFO("Turn Off Ambient lighting RGB Common Cathode.\n");
#endif #endif
#ifdef UNPHONE #ifdef UNPHONE
unphone.rgb(0, 0, 0); unphone.rgb(0, 0, 0);
LOG_INFO("Turn Off unPhone Ambient lighting."); LOG_INFO("Turn Off unPhone Ambient lighting.\n");
#endif #endif
return 0; return 0;
} }
@@ -138,7 +138,7 @@ class AmbientLightingThread : public concurrency::OSThread
rgb.setRed(moduleConfig.ambient_lighting.red); rgb.setRed(moduleConfig.ambient_lighting.red);
rgb.setGreen(moduleConfig.ambient_lighting.green); rgb.setGreen(moduleConfig.ambient_lighting.green);
rgb.setBlue(moduleConfig.ambient_lighting.blue); rgb.setBlue(moduleConfig.ambient_lighting.blue);
LOG_DEBUG("Initializing NCP5623 Ambient lighting w/ current=%d, red=%d, green=%d, blue=%d", LOG_DEBUG("Initializing NCP5623 Ambient lighting w/ current=%d, red=%d, green=%d, blue=%d\n",
moduleConfig.ambient_lighting.current, moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.current, moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
moduleConfig.ambient_lighting.blue); moduleConfig.ambient_lighting.blue);
#endif #endif
@@ -158,7 +158,7 @@ class AmbientLightingThread : public concurrency::OSThread
#endif #endif
#endif #endif
pixels.show(); pixels.show();
LOG_DEBUG("Initializing NeoPixel Ambient lighting w/ brightness(current)=%d, red=%d, green=%d, blue=%d", LOG_DEBUG("Initializing NeoPixel Ambient lighting w/ brightness(current)=%d, red=%d, green=%d, blue=%d\n",
moduleConfig.ambient_lighting.current, moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.current, moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
moduleConfig.ambient_lighting.blue); moduleConfig.ambient_lighting.blue);
#endif #endif
@@ -166,18 +166,18 @@ class AmbientLightingThread : public concurrency::OSThread
analogWrite(RGBLED_RED, 255 - moduleConfig.ambient_lighting.red); analogWrite(RGBLED_RED, 255 - moduleConfig.ambient_lighting.red);
analogWrite(RGBLED_GREEN, 255 - moduleConfig.ambient_lighting.green); analogWrite(RGBLED_GREEN, 255 - moduleConfig.ambient_lighting.green);
analogWrite(RGBLED_BLUE, 255 - moduleConfig.ambient_lighting.blue); analogWrite(RGBLED_BLUE, 255 - moduleConfig.ambient_lighting.blue);
LOG_DEBUG("Initializing Ambient lighting RGB Common Anode w/ red=%d, green=%d, blue=%d", LOG_DEBUG("Initializing Ambient lighting RGB Common Anode w/ red=%d, green=%d, blue=%d\n",
moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue); moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
#elif defined(RGBLED_RED) #elif defined(RGBLED_RED)
analogWrite(RGBLED_RED, moduleConfig.ambient_lighting.red); analogWrite(RGBLED_RED, moduleConfig.ambient_lighting.red);
analogWrite(RGBLED_GREEN, moduleConfig.ambient_lighting.green); analogWrite(RGBLED_GREEN, moduleConfig.ambient_lighting.green);
analogWrite(RGBLED_BLUE, moduleConfig.ambient_lighting.blue); analogWrite(RGBLED_BLUE, moduleConfig.ambient_lighting.blue);
LOG_DEBUG("Initializing Ambient lighting RGB Common Cathode w/ red=%d, green=%d, blue=%d", LOG_DEBUG("Initializing Ambient lighting RGB Common Cathode w/ red=%d, green=%d, blue=%d\n",
moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue); moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
#endif #endif
#ifdef UNPHONE #ifdef UNPHONE
unphone.rgb(moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue); unphone.rgb(moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
LOG_DEBUG("Initializing unPhone Ambient lighting w/ red=%d, green=%d, blue=%d", moduleConfig.ambient_lighting.red, LOG_DEBUG("Initializing unPhone Ambient lighting w/ red=%d, green=%d, blue=%d\n", moduleConfig.ambient_lighting.red,
moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue); moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
#endif #endif
} }

View File

@@ -36,7 +36,7 @@ ButtonThread::ButtonThread() : OSThread("Button")
#if defined(ARCH_PORTDUINO) #if defined(ARCH_PORTDUINO)
if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) { if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) {
this->userButton = OneButton(settingsMap[user], true, true); this->userButton = OneButton(settingsMap[user], true, true);
LOG_DEBUG("Using GPIO%02d for button", settingsMap[user]); LOG_DEBUG("Using GPIO%02d for button\n", settingsMap[user]);
} }
#elif defined(BUTTON_PIN) #elif defined(BUTTON_PIN)
int pin = config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN; // Resolved button pin int pin = config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN; // Resolved button pin
@@ -47,7 +47,7 @@ ButtonThread::ButtonThread() : OSThread("Button")
#else #else
this->userButton = OneButton(pin, true, true); this->userButton = OneButton(pin, true, true);
#endif #endif
LOG_DEBUG("Using GPIO%02d for button", pin); LOG_DEBUG("Using GPIO%02d for button\n", pin);
#endif #endif
#ifdef INPUT_PULLUP_SENSE #ifdef INPUT_PULLUP_SENSE
@@ -123,12 +123,7 @@ int32_t ButtonThread::runOnce()
if (btnEvent != BUTTON_EVENT_NONE) { if (btnEvent != BUTTON_EVENT_NONE) {
switch (btnEvent) { switch (btnEvent) {
case BUTTON_EVENT_PRESSED: { case BUTTON_EVENT_PRESSED: {
LOG_BUTTON("press!"); LOG_BUTTON("press!\n");
// If a nag notification is running, stop it and prevent other actions
if (moduleConfig.external_notification.enabled && (externalNotificationModule->nagCycleCutoff != UINT32_MAX)) {
externalNotificationModule->stopNow();
return 50;
}
#ifdef BUTTON_PIN #ifdef BUTTON_PIN
if (((config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN) != if (((config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN) !=
moduleConfig.canned_message.inputbroker_pin_press) || moduleConfig.canned_message.inputbroker_pin_press) ||
@@ -148,7 +143,7 @@ int32_t ButtonThread::runOnce()
} }
case BUTTON_EVENT_DOUBLE_PRESSED: { case BUTTON_EVENT_DOUBLE_PRESSED: {
LOG_BUTTON("Double press!"); LOG_BUTTON("Double press!\n");
service->refreshLocalMeshNode(); service->refreshLocalMeshNode();
auto sentPosition = service->trySendPosition(NODENUM_BROADCAST, true); auto sentPosition = service->trySendPosition(NODENUM_BROADCAST, true);
if (screen) { if (screen) {
@@ -162,7 +157,7 @@ int32_t ButtonThread::runOnce()
} }
case BUTTON_EVENT_MULTI_PRESSED: { case BUTTON_EVENT_MULTI_PRESSED: {
LOG_BUTTON("Mulitipress! %hux", multipressClickCount); LOG_BUTTON("Mulitipress! %hux\n", multipressClickCount);
switch (multipressClickCount) { switch (multipressClickCount) {
#if HAS_GPS #if HAS_GPS
// 3 clicks: toggle GPS // 3 clicks: toggle GPS
@@ -189,7 +184,7 @@ int32_t ButtonThread::runOnce()
} // end multipress event } // end multipress event
case BUTTON_EVENT_LONG_PRESSED: { case BUTTON_EVENT_LONG_PRESSED: {
LOG_BUTTON("Long press!"); LOG_BUTTON("Long press!\n");
powerFSM.trigger(EVENT_PRESS); powerFSM.trigger(EVENT_PRESS);
if (screen) { if (screen) {
screen->startAlert("Shutting down..."); screen->startAlert("Shutting down...");
@@ -201,7 +196,7 @@ int32_t ButtonThread::runOnce()
// Do actual shutdown when button released, otherwise the button release // Do actual shutdown when button released, otherwise the button release
// may wake the board immediatedly. // may wake the board immediatedly.
case BUTTON_EVENT_LONG_RELEASED: { case BUTTON_EVENT_LONG_RELEASED: {
LOG_INFO("Shutdown from long press"); LOG_INFO("Shutdown from long press\n");
playShutdownMelody(); playShutdownMelody();
delay(3000); delay(3000);
power->shutdown(); power->shutdown();
@@ -210,7 +205,7 @@ int32_t ButtonThread::runOnce()
#ifdef BUTTON_PIN_TOUCH #ifdef BUTTON_PIN_TOUCH
case BUTTON_EVENT_TOUCH_LONG_PRESSED: { case BUTTON_EVENT_TOUCH_LONG_PRESSED: {
LOG_BUTTON("Touch press!"); LOG_BUTTON("Touch press!\n");
if (screen) { if (screen) {
// Wake if asleep // Wake if asleep
if (powerFSM.getState() == &stateDARK) if (powerFSM.getState() == &stateDARK)

View File

@@ -53,7 +53,7 @@ bool lfs_assert_failed =
extern "C" void lfs_assert(const char *reason) extern "C" void lfs_assert(const char *reason)
{ {
LOG_ERROR("LFS assert: %s", reason); LOG_ERROR("LFS assert: %s\n", reason);
lfs_assert_failed = true; lfs_assert_failed = true;
} }
@@ -75,19 +75,19 @@ bool copyFile(const char *from, const char *to)
r = OSFS::getFile(from, cbuffer); r = OSFS::getFile(from, cbuffer);
if (r == notfound) { if (r == notfound) {
LOG_ERROR("Failed to open source file %s", from); LOG_ERROR("Failed to open source file %s\n", from);
return false; return false;
} else if (r == noerr) { } else if (r == noerr) {
r = OSFS::newFile(to, cbuffer, true); r = OSFS::newFile(to, cbuffer, true);
if (r == noerr) { if (r == noerr) {
return true; return true;
} else { } else {
LOG_ERROR("OSFS Error %d", r); LOG_ERROR("OSFS Error %d\n", r);
return false; return false;
} }
} else { } else {
LOG_ERROR("OSFS Error %d", r); LOG_ERROR("OSFS Error %d\n", r);
return false; return false;
} }
return true; return true;
@@ -97,13 +97,13 @@ bool copyFile(const char *from, const char *to)
File f1 = FSCom.open(from, FILE_O_READ); File f1 = FSCom.open(from, FILE_O_READ);
if (!f1) { if (!f1) {
LOG_ERROR("Failed to open source file %s", from); LOG_ERROR("Failed to open source file %s\n", from);
return false; return false;
} }
File f2 = FSCom.open(to, FILE_O_WRITE); File f2 = FSCom.open(to, FILE_O_WRITE);
if (!f2) { if (!f2) {
LOG_ERROR("Failed to open destination file %s", to); LOG_ERROR("Failed to open destination file %s\n", to);
return false; return false;
} }
@@ -231,7 +231,7 @@ void listDir(const char *dirname, uint8_t levels, bool del)
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
listDir(file.path(), levels - 1, del); listDir(file.path(), levels - 1, del);
if (del) { if (del) {
LOG_DEBUG("Removing %s", file.path()); LOG_DEBUG("Removing %s\n", file.path());
strncpy(buffer, file.path(), sizeof(buffer)); strncpy(buffer, file.path(), sizeof(buffer));
file.close(); file.close();
FSCom.rmdir(buffer); FSCom.rmdir(buffer);
@@ -241,7 +241,7 @@ void listDir(const char *dirname, uint8_t levels, bool del)
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO)) #elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
listDir(file.name(), levels - 1, del); listDir(file.name(), levels - 1, del);
if (del) { if (del) {
LOG_DEBUG("Removing %s", file.name()); LOG_DEBUG("Removing %s\n", file.name());
strncpy(buffer, file.name(), sizeof(buffer)); strncpy(buffer, file.name(), sizeof(buffer));
file.close(); file.close();
FSCom.rmdir(buffer); FSCom.rmdir(buffer);
@@ -249,7 +249,7 @@ void listDir(const char *dirname, uint8_t levels, bool del)
file.close(); file.close();
} }
#else #else
LOG_DEBUG(" %s (directory)", file.name()); LOG_DEBUG(" %s (directory)\n", file.name());
listDir(file.name(), levels - 1, del); listDir(file.name(), levels - 1, del);
file.close(); file.close();
#endif #endif
@@ -257,26 +257,26 @@ void listDir(const char *dirname, uint8_t levels, bool del)
} else { } else {
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
if (del) { if (del) {
LOG_DEBUG("Deleting %s", file.path()); LOG_DEBUG("Deleting %s\n", file.path());
strncpy(buffer, file.path(), sizeof(buffer)); strncpy(buffer, file.path(), sizeof(buffer));
file.close(); file.close();
FSCom.remove(buffer); FSCom.remove(buffer);
} else { } else {
LOG_DEBUG(" %s (%i Bytes)", file.path(), file.size()); LOG_DEBUG(" %s (%i Bytes)\n", file.path(), file.size());
file.close(); file.close();
} }
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO)) #elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
if (del) { if (del) {
LOG_DEBUG("Deleting %s", file.name()); LOG_DEBUG("Deleting %s\n", file.name());
strncpy(buffer, file.name(), sizeof(buffer)); strncpy(buffer, file.name(), sizeof(buffer));
file.close(); file.close();
FSCom.remove(buffer); FSCom.remove(buffer);
} else { } else {
LOG_DEBUG(" %s (%i Bytes)", file.name(), file.size()); LOG_DEBUG(" %s (%i Bytes)\n", file.name(), file.size());
file.close(); file.close();
} }
#else #else
LOG_DEBUG(" %s (%i Bytes)", file.name(), file.size()); LOG_DEBUG(" %s (%i Bytes)\n", file.name(), file.size());
file.close(); file.close();
#endif #endif
} }
@@ -284,7 +284,7 @@ void listDir(const char *dirname, uint8_t levels, bool del)
} }
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
if (del) { if (del) {
LOG_DEBUG("Removing %s", root.path()); LOG_DEBUG("Removing %s\n", root.path());
strncpy(buffer, root.path(), sizeof(buffer)); strncpy(buffer, root.path(), sizeof(buffer));
root.close(); root.close();
FSCom.rmdir(buffer); FSCom.rmdir(buffer);
@@ -293,7 +293,7 @@ void listDir(const char *dirname, uint8_t levels, bool del)
} }
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO)) #elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
if (del) { if (del) {
LOG_DEBUG("Removing %s", root.name()); LOG_DEBUG("Removing %s\n", root.name());
strncpy(buffer, root.name(), sizeof(buffer)); strncpy(buffer, root.name(), sizeof(buffer));
root.close(); root.close();
FSCom.rmdir(buffer); FSCom.rmdir(buffer);
@@ -329,13 +329,13 @@ void fsInit()
{ {
#ifdef FSCom #ifdef FSCom
if (!FSBegin()) { if (!FSBegin()) {
LOG_ERROR("Filesystem mount Failed."); LOG_ERROR("Filesystem mount Failed.\n");
// assert(0); This auto-formats the partition, so no need to fail here. // assert(0); This auto-formats the partition, so no need to fail here.
} }
#if defined(ARCH_ESP32) #if defined(ARCH_ESP32)
LOG_DEBUG("Filesystem files (%d/%d Bytes):", FSCom.usedBytes(), FSCom.totalBytes()); LOG_DEBUG("Filesystem files (%d/%d Bytes):\n", FSCom.usedBytes(), FSCom.totalBytes());
#else #else
LOG_DEBUG("Filesystem files:"); LOG_DEBUG("Filesystem files:\n");
#endif #endif
listDir("/", 10); listDir("/", 10);
#endif #endif
@@ -350,28 +350,28 @@ void setupSDCard()
SDHandler.begin(SPI_SCK, SPI_MISO, SPI_MOSI); SDHandler.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
if (!SD.begin(SDCARD_CS, SDHandler)) { if (!SD.begin(SDCARD_CS, SDHandler)) {
LOG_DEBUG("No SD_MMC card detected"); LOG_DEBUG("No SD_MMC card detected\n");
return; return;
} }
uint8_t cardType = SD.cardType(); uint8_t cardType = SD.cardType();
if (cardType == CARD_NONE) { if (cardType == CARD_NONE) {
LOG_DEBUG("No SD_MMC card attached"); LOG_DEBUG("No SD_MMC card attached\n");
return; return;
} }
LOG_DEBUG("SD_MMC Card Type: "); LOG_DEBUG("SD_MMC Card Type: ");
if (cardType == CARD_MMC) { if (cardType == CARD_MMC) {
LOG_DEBUG("MMC"); LOG_DEBUG("MMC\n");
} else if (cardType == CARD_SD) { } else if (cardType == CARD_SD) {
LOG_DEBUG("SDSC"); LOG_DEBUG("SDSC\n");
} else if (cardType == CARD_SDHC) { } else if (cardType == CARD_SDHC) {
LOG_DEBUG("SDHC"); LOG_DEBUG("SDHC\n");
} else { } else {
LOG_DEBUG("UNKNOWN"); LOG_DEBUG("UNKNOWN\n");
} }
uint64_t cardSize = SD.cardSize() / (1024 * 1024); uint64_t cardSize = SD.cardSize() / (1024 * 1024);
LOG_DEBUG("SD Card Size: %lu MB", (uint32_t)cardSize); LOG_DEBUG("SD Card Size: %lluMB\n", cardSize);
LOG_DEBUG("Total space: %lu MB", (uint32_t)(SD.totalBytes() / (1024 * 1024))); LOG_DEBUG("Total space: %llu MB\n", SD.totalBytes() / (1024 * 1024));
LOG_DEBUG("Used space: %lu MB", (uint32_t)(SD.usedBytes() / (1024 * 1024))); LOG_DEBUG("Used space: %llu MB\n", SD.usedBytes() / (1024 * 1024));
#endif #endif
} }

View File

@@ -51,7 +51,7 @@ class GPSStatus : public Status
{ {
if (config.position.fixed_position) { if (config.position.fixed_position) {
#ifdef GPS_EXTRAVERBOSE #ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed latitude"); LOG_WARN("Using fixed latitude\n");
#endif #endif
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum()); meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());
return node->position.latitude_i; return node->position.latitude_i;
@@ -64,7 +64,7 @@ class GPSStatus : public Status
{ {
if (config.position.fixed_position) { if (config.position.fixed_position) {
#ifdef GPS_EXTRAVERBOSE #ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed longitude"); LOG_WARN("Using fixed longitude\n");
#endif #endif
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum()); meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());
return node->position.longitude_i; return node->position.longitude_i;
@@ -77,7 +77,7 @@ class GPSStatus : public Status
{ {
if (config.position.fixed_position) { if (config.position.fixed_position) {
#ifdef GPS_EXTRAVERBOSE #ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed altitude"); LOG_WARN("Using fixed altitude\n");
#endif #endif
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum()); meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());
return node->position.altitude; return node->position.altitude;
@@ -95,7 +95,7 @@ class GPSStatus : public Status
bool matches(const GPSStatus *newStatus) const bool matches(const GPSStatus *newStatus) const
{ {
#ifdef GPS_EXTRAVERBOSE #ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("GPSStatus.match() new pos@%x to old pos@%x", newStatus->p.timestamp, p.timestamp); LOG_DEBUG("GPSStatus.match() new pos@%x to old pos@%x\n", newStatus->p.timestamp, p.timestamp);
#endif #endif
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected || return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected ||
newStatus->isPowerSaving != isPowerSaving || newStatus->p.latitude_i != p.latitude_i || newStatus->isPowerSaving != isPowerSaving || newStatus->p.latitude_i != p.latitude_i ||
@@ -112,7 +112,7 @@ class GPSStatus : public Status
if (isDirty && p.timestamp && (newStatus->p.timestamp == p.timestamp)) { if (isDirty && p.timestamp && (newStatus->p.timestamp == p.timestamp)) {
// We can NEVER be in two locations at the same time! (also PR #886) // We can NEVER be in two locations at the same time! (also PR #886)
LOG_ERROR("BUG: Positional timestamp unchanged from prev solution"); LOG_ERROR("BUG: Positional timestamp unchanged from prev solution\n");
} }
initialized = true; initialized = true;
@@ -124,11 +124,11 @@ class GPSStatus : public Status
if (isDirty) { if (isDirty) {
if (hasLock) { if (hasLock) {
// In debug logs, identify position by @timestamp:stage (stage 3 = notify) // 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, LOG_DEBUG("New GPS pos@%x:3 lat=%f lon=%f alt=%d pdop=%.2f track=%.2f speed=%.2f sats=%d\n", p.timestamp,
p.latitude_i * 1e-7, p.longitude_i * 1e-7, p.altitude, p.PDOP * 1e-2, p.ground_track * 1e-5, p.latitude_i * 1e-7, p.longitude_i * 1e-7, p.altitude, p.PDOP * 1e-2, p.ground_track * 1e-5,
p.ground_speed * 1e-2, p.sats_in_view); p.ground_speed * 1e-2, p.sats_in_view);
} else { } else {
LOG_DEBUG("No GPS lock"); LOG_DEBUG("No GPS lock\n");
} }
onNewStatus.notifyObservers(this); onNewStatus.notifyObservers(this);
} }

View File

@@ -12,7 +12,7 @@ void GpioVirtPin::set(bool value)
void GpioHwPin::set(bool value) void GpioHwPin::set(bool value)
{ {
// if (num == 3) LOG_DEBUG("Setting pin %d to %d", num, value); // if (num == 3) LOG_DEBUG("Setting pin %d to %d\n", num, value);
pinMode(num, OUTPUT); pinMode(num, OUTPUT);
digitalWrite(num, value); digitalWrite(num, value);
} }
@@ -88,7 +88,7 @@ void GpioBinaryTransformer::update()
newValue = (GpioVirtPin::PinState)(p1 && p2); newValue = (GpioVirtPin::PinState)(p1 && p2);
break; break;
case Or: case Or:
// LOG_DEBUG("Doing GPIO OR"); // LOG_DEBUG("Doing GPIO OR\n");
newValue = (GpioVirtPin::PinState)(p1 || p2); newValue = (GpioVirtPin::PinState)(p1 || p2);
break; break;
case Xor: case Xor:

View File

@@ -56,7 +56,7 @@ class NodeStatus : public Status
numTotal = newStatus->getNumTotal(); numTotal = newStatus->getNumTotal();
} }
if (isDirty || newStatus->forceUpdate) { if (isDirty || newStatus->forceUpdate) {
LOG_DEBUG("Node status update: %d online, %d total", numOnline, numTotal); LOG_DEBUG("Node status update: %d online, %d total\n", numOnline, numTotal);
onNewStatus.notifyObservers(this); onNewStatus.notifyObservers(this);
} }
return 0; return 0;

View File

@@ -13,7 +13,6 @@
#include "power.h" #include "power.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "PowerFSM.h" #include "PowerFSM.h"
#include "Throttle.h"
#include "buzz/buzz.h" #include "buzz/buzz.h"
#include "configuration.h" #include "configuration.h"
#include "main.h" #include "main.h"
@@ -31,7 +30,6 @@
#if HAS_WIFI #if HAS_WIFI
#include <WiFi.h> #include <WiFi.h>
#endif #endif
#endif #endif
#ifndef DELAY_FOREVER #ifndef DELAY_FOREVER
@@ -77,15 +75,6 @@ INA219Sensor ina219Sensor;
INA3221Sensor ina3221Sensor; INA3221Sensor ina3221Sensor;
#endif #endif
#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
#include "modules/Telemetry/Sensor/MAX17048Sensor.h"
#include <utility>
extern std::pair<uint8_t, TwoWire *> nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1];
#if HAS_TELEMETRY && (!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR || !MESHTASTIC_EXCLUDE_POWER_TELEMETRY)
MAX17048Sensor max17048Sensor;
#endif
#endif
#if HAS_RAKPROT && !defined(ARCH_PORTDUINO) #if HAS_RAKPROT && !defined(ARCH_PORTDUINO)
RAK9154Sensor rak9154Sensor; RAK9154Sensor rak9154Sensor;
#endif #endif
@@ -147,23 +136,14 @@ using namespace meshtastic;
*/ */
static HasBatteryLevel *batteryLevel; // Default to NULL for no battery level sensor static HasBatteryLevel *batteryLevel; // Default to NULL for no battery level sensor
#ifdef BATTERY_PIN
static void adcEnable() static void adcEnable()
{ {
#ifdef ADC_CTRL // enable adc voltage divider when we need to read #ifdef ADC_CTRL // enable adc voltage divider when we need to read
#ifdef ADC_USE_PULLUP #ifdef ADC_USE_PULLUP
pinMode(ADC_CTRL, INPUT_PULLUP); pinMode(ADC_CTRL, INPUT_PULLUP);
#else
#ifdef HELTEC_V3
pinMode(ADC_CTRL, INPUT);
uint8_t adc_ctl_enable_value = !(digitalRead(ADC_CTRL));
pinMode(ADC_CTRL, OUTPUT);
digitalWrite(ADC_CTRL, adc_ctl_enable_value);
#else #else
pinMode(ADC_CTRL, OUTPUT); pinMode(ADC_CTRL, OUTPUT);
digitalWrite(ADC_CTRL, ADC_CTRL_ENABLED); digitalWrite(ADC_CTRL, ADC_CTRL_ENABLED);
#endif
#endif #endif
delay(10); delay(10);
#endif #endif
@@ -174,24 +154,17 @@ static void adcDisable()
#ifdef ADC_CTRL // disable adc voltage divider when we need to read #ifdef ADC_CTRL // disable adc voltage divider when we need to read
#ifdef ADC_USE_PULLUP #ifdef ADC_USE_PULLUP
pinMode(ADC_CTRL, INPUT_PULLDOWN); pinMode(ADC_CTRL, INPUT_PULLDOWN);
#else
#ifdef HELTEC_V3
pinMode(ADC_CTRL, ANALOG);
#else #else
digitalWrite(ADC_CTRL, !ADC_CTRL_ENABLED); digitalWrite(ADC_CTRL, !ADC_CTRL_ENABLED);
#endif #endif
#endif #endif
#endif
} }
#endif
/** /**
* A simple battery level sensor that assumes the battery voltage is attached via a voltage-divider to an analog input * A simple battery level sensor that assumes the battery voltage is attached via a voltage-divider to an analog input
*/ */
class AnalogBatteryLevel : public HasBatteryLevel class AnalogBatteryLevel : public HasBatteryLevel
{ {
public:
/** /**
* Battery state of charge, from 0 to 100 or -1 for unknown * Battery state of charge, from 0 to 100 or -1 for unknown
*/ */
@@ -251,7 +224,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(HAS_PMU) && \ #if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(HAS_PMU) && \
!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
if (hasINA()) { if (hasINA()) {
LOG_DEBUG("Using INA on I2C addr 0x%x for device battery voltage", config.power.device_battery_ina_address); LOG_DEBUG("Using INA on I2C addr 0x%x for device battery voltage\n", config.power.device_battery_ina_address);
return getINAVoltage(); return getINAVoltage();
} }
#endif #endif
@@ -271,7 +244,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
config.power.adc_multiplier_override > 0 ? config.power.adc_multiplier_override : ADC_MULTIPLIER; config.power.adc_multiplier_override > 0 ? config.power.adc_multiplier_override : ADC_MULTIPLIER;
// Do not call analogRead() often. // Do not call analogRead() often.
const uint32_t min_read_interval = 5000; const uint32_t min_read_interval = 5000;
if (!Throttle::isWithinTimespanMs(last_read_time_ms, min_read_interval)) { if (millis() - last_read_time_ms > min_read_interval) {
last_read_time_ms = millis(); last_read_time_ms = millis();
uint32_t raw = 0; uint32_t raw = 0;
@@ -301,7 +274,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
last_read_value += (scaled - last_read_value) * 0.5; // Virtual LPF last_read_value += (scaled - last_read_value) * 0.5; // Virtual LPF
} }
// LOG_DEBUG("battery gpio %d raw val=%u scaled=%u filtered=%u", BATTERY_PIN, raw, (uint32_t)(scaled), (uint32_t) // LOG_DEBUG("battery gpio %d raw val=%u scaled=%u filtered=%u\n", BATTERY_PIN, raw, (uint32_t)(scaled), (uint32_t)
// (last_read_value)); // (last_read_value));
} }
return last_read_value; return last_read_value;
@@ -346,7 +319,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
raw += adc_buf; raw += adc_buf;
raw_c++; // Count valid samples raw_c++; // Count valid samples
} else { } else {
LOG_DEBUG("An attempt to sample ADC2 failed"); LOG_DEBUG("An attempt to sample ADC2 failed\n");
} }
} }
@@ -371,12 +344,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
/** /**
* return true if there is a battery installed in this unit * return true if there is a battery installed in this unit
*/ */
// if we have a integrated device with a battery, we can assume that the battery is always connected
#ifdef BATTERY_IMMUTABLE
virtual bool isBatteryConnect() override { return true; }
#else
virtual bool isBatteryConnect() override { return getBatteryPercent() != -1; } virtual bool isBatteryConnect() override { return getBatteryPercent() != -1; }
#endif
/// If we see a battery voltage higher than physics allows - assume charger is pumping /// If we see a battery voltage higher than physics allows - assume charger is pumping
/// in power /// in power
@@ -511,7 +479,7 @@ bool Power::analogInit()
#endif #endif
#ifdef BATTERY_PIN #ifdef BATTERY_PIN
LOG_DEBUG("Using analog input %d for battery level", BATTERY_PIN); LOG_DEBUG("Using analog input %d for battery level\n", BATTERY_PIN);
// disable any internal pullups // disable any internal pullups
pinMode(BATTERY_PIN, INPUT); pinMode(BATTERY_PIN, INPUT);
@@ -542,18 +510,18 @@ bool Power::analogInit()
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_characs); esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_characs);
// show ADC characterization base // show ADC characterization base
if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) { if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
LOG_INFO("ADCmod: ADC characterization based on Two Point values stored in eFuse"); LOG_INFO("ADCmod: ADC characterization based on Two Point values stored in eFuse\n");
} else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) { } else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
LOG_INFO("ADCmod: ADC characterization based on reference voltage stored in eFuse"); LOG_INFO("ADCmod: ADC characterization based on reference voltage stored in eFuse\n");
} }
#ifdef CONFIG_IDF_TARGET_ESP32S3 #ifdef CONFIG_IDF_TARGET_ESP32S3
// ESP32S3 // ESP32S3
else if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP_FIT) { else if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP_FIT) {
LOG_INFO("ADCmod: ADC Characterization based on Two Point values and fitting curve coefficients stored in eFuse"); LOG_INFO("ADCmod: ADC Characterization based on Two Point values and fitting curve coefficients stored in eFuse\n");
} }
#endif #endif
else { else {
LOG_INFO("ADCmod: ADC characterization based on default reference voltage"); LOG_INFO("ADCmod: ADC characterization based on default reference voltage\n");
} }
#endif // ARCH_ESP32 #endif // ARCH_ESP32
@@ -583,12 +551,7 @@ bool Power::analogInit()
*/ */
bool Power::setup() bool Power::setup()
{ {
// initialise one power sensor (only) bool found = axpChipInit() || analogInit();
bool found = axpChipInit();
if (!found)
found = lipoInit();
if (!found)
found = analogInit();
#ifdef NRF_APM #ifdef NRF_APM
found = true; found = true;
@@ -602,9 +565,9 @@ bool Power::setup()
void Power::shutdown() void Power::shutdown()
{ {
LOG_INFO("Shutting down"); LOG_INFO("Shutting down\n");
#if defined(ARCH_NRF52) || defined(ARCH_ESP32) || defined(ARCH_RP2040) #if defined(ARCH_NRF52) || defined(ARCH_ESP32)
#ifdef PIN_LED1 #ifdef PIN_LED1
ledOff(PIN_LED1); ledOff(PIN_LED1);
#endif #endif
@@ -657,7 +620,7 @@ void Power::readPowerStatus()
// changes. // changes.
nrfx_power_usb_state_t nrf_usb_state = nrfx_power_usbstatus_get(); nrfx_power_usb_state_t nrf_usb_state = nrfx_power_usbstatus_get();
// LOG_DEBUG("NRF Power %d", nrf_usb_state); // LOG_DEBUG("NRF Power %d\n", nrf_usb_state);
// If changed to DISCONNECTED // If changed to DISCONNECTED
if (nrf_usb_state == NRFX_POWER_USB_STATE_DISCONNECTED) if (nrf_usb_state == NRFX_POWER_USB_STATE_DISCONNECTED)
@@ -670,22 +633,22 @@ void Power::readPowerStatus()
// Notify any status instances that are observing us // Notify any status instances that are observing us
const PowerStatus powerStatus2 = PowerStatus(hasBattery, usbPowered, isCharging, batteryVoltageMv, batteryChargePercent); const PowerStatus powerStatus2 = PowerStatus(hasBattery, usbPowered, isCharging, batteryVoltageMv, batteryChargePercent);
LOG_DEBUG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d", powerStatus2.getHasUSB(), powerStatus2.getIsCharging(), LOG_DEBUG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d\n", powerStatus2.getHasUSB(),
powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent()); powerStatus2.getIsCharging(), powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
newStatus.notifyObservers(&powerStatus2); newStatus.notifyObservers(&powerStatus2);
#ifdef DEBUG_HEAP #ifdef DEBUG_HEAP
if (lastheap != memGet.getFreeHeap()) { if (lastheap != memGet.getFreeHeap()) {
std::string threadlist = "Threads running:"; LOG_DEBUG("Threads running:");
int running = 0; int running = 0;
for (int i = 0; i < MAX_THREADS; i++) { for (int i = 0; i < MAX_THREADS; i++) {
auto thread = concurrency::mainController.get(i); auto thread = concurrency::mainController.get(i);
if ((thread != nullptr) && (thread->enabled)) { if ((thread != nullptr) && (thread->enabled)) {
threadlist += vformat(" %s", thread->ThreadName.c_str()); LOG_DEBUG(" %s", thread->ThreadName.c_str());
running++; running++;
} }
} }
LOG_DEBUG(threadlist.c_str()); LOG_DEBUG("\n");
LOG_DEBUG("Heap status: %d/%d bytes free (%d), running %d/%d threads", memGet.getFreeHeap(), memGet.getHeapSize(), LOG_DEBUG("Heap status: %d/%d bytes free (%d), running %d/%d threads\n", memGet.getFreeHeap(), memGet.getHeapSize(),
memGet.getFreeHeap() - lastheap, running, concurrency::mainController.size(false)); memGet.getFreeHeap() - lastheap, running, concurrency::mainController.size(false));
lastheap = memGet.getFreeHeap(); lastheap = memGet.getFreeHeap();
} }
@@ -718,13 +681,13 @@ void Power::readPowerStatus()
if (batteryLevel && powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()) { if (batteryLevel && powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()) {
if (batteryLevel->getBattVoltage() < OCV[NUM_OCV_POINTS - 1]) { if (batteryLevel->getBattVoltage() < OCV[NUM_OCV_POINTS - 1]) {
low_voltage_counter++; low_voltage_counter++;
LOG_DEBUG("Low voltage counter: %d/10", low_voltage_counter); LOG_DEBUG("Low voltage counter: %d/10\n", low_voltage_counter);
if (low_voltage_counter > 10) { if (low_voltage_counter > 10) {
#ifdef ARCH_NRF52 #ifdef ARCH_NRF52
// We can't trigger deep sleep on NRF52, it's freezing the board // We can't trigger deep sleep on NRF52, it's freezing the board
LOG_DEBUG("Low voltage detected, but not triggering deep sleep"); LOG_DEBUG("Low voltage detected, but not triggering deep sleep\n");
#else #else
LOG_INFO("Low voltage detected, triggering deep sleep"); LOG_INFO("Low voltage detected, triggering deep sleep\n");
powerFSM.trigger(EVENT_LOW_BATTERY); powerFSM.trigger(EVENT_LOW_BATTERY);
#endif #endif
} }
@@ -746,12 +709,12 @@ int32_t Power::runOnce()
PMU->getIrqStatus(); PMU->getIrqStatus();
if (PMU->isVbusRemoveIrq()) { if (PMU->isVbusRemoveIrq()) {
LOG_INFO("USB unplugged"); LOG_INFO("USB unplugged\n");
powerFSM.trigger(EVENT_POWER_DISCONNECTED); powerFSM.trigger(EVENT_POWER_DISCONNECTED);
} }
if (PMU->isVbusInsertIrq()) { if (PMU->isVbusInsertIrq()) {
LOG_INFO("USB plugged In"); LOG_INFO("USB plugged In\n");
powerFSM.trigger(EVENT_POWER_CONNECTED); powerFSM.trigger(EVENT_POWER_CONNECTED);
} }
@@ -759,21 +722,21 @@ int32_t Power::runOnce()
Other things we could check if we cared... Other things we could check if we cared...
if (PMU->isBatChagerStartIrq()) { if (PMU->isBatChagerStartIrq()) {
LOG_DEBUG("Battery start charging"); LOG_DEBUG("Battery start charging\n");
} }
if (PMU->isBatChagerDoneIrq()) { if (PMU->isBatChagerDoneIrq()) {
LOG_DEBUG("Battery fully charged"); LOG_DEBUG("Battery fully charged\n");
} }
if (PMU->isBatInsertIrq()) { if (PMU->isBatInsertIrq()) {
LOG_DEBUG("Battery inserted"); LOG_DEBUG("Battery inserted\n");
} }
if (PMU->isBatRemoveIrq()) { if (PMU->isBatRemoveIrq()) {
LOG_DEBUG("Battery removed"); LOG_DEBUG("Battery removed\n");
} }
*/ */
#ifndef T_WATCH_S3 // FIXME - why is this triggering on the T-Watch S3? #ifndef T_WATCH_S3 // FIXME - why is this triggering on the T-Watch S3?
if (PMU->isPekeyLongPressIrq()) { if (PMU->isPekeyLongPressIrq()) {
LOG_DEBUG("PEK long button press"); LOG_DEBUG("PEK long button press\n");
screen->setOn(false); screen->setOn(false);
} }
#endif #endif
@@ -816,22 +779,22 @@ bool Power::axpChipInit()
if (!PMU) { if (!PMU) {
PMU = new XPowersAXP2101(*w); PMU = new XPowersAXP2101(*w);
if (!PMU->init()) { if (!PMU->init()) {
LOG_WARN("Failed to find AXP2101 power management"); LOG_WARN("Failed to find AXP2101 power management\n");
delete PMU; delete PMU;
PMU = NULL; PMU = NULL;
} else { } else {
LOG_INFO("AXP2101 PMU init succeeded, using AXP2101 PMU"); LOG_INFO("AXP2101 PMU init succeeded, using AXP2101 PMU\n");
} }
} }
if (!PMU) { if (!PMU) {
PMU = new XPowersAXP192(*w); PMU = new XPowersAXP192(*w);
if (!PMU->init()) { if (!PMU->init()) {
LOG_WARN("Failed to find AXP192 power management"); LOG_WARN("Failed to find AXP192 power management\n");
delete PMU; delete PMU;
PMU = NULL; PMU = NULL;
} else { } else {
LOG_INFO("AXP192 PMU init succeeded, using AXP192 PMU"); LOG_INFO("AXP192 PMU init succeeded, using AXP192 PMU\n");
} }
} }
@@ -987,54 +950,56 @@ bool Power::axpChipInit()
PMU->enableVbusVoltageMeasure(); PMU->enableVbusVoltageMeasure();
PMU->enableBattVoltageMeasure(); PMU->enableBattVoltageMeasure();
LOG_DEBUG("=======================================================================\n");
if (PMU->isChannelAvailable(XPOWERS_DCDC1)) { if (PMU->isChannelAvailable(XPOWERS_DCDC1)) {
LOG_DEBUG("DC1 : %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-", LOG_DEBUG("DC1 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_DCDC1)); PMU->getPowerChannelVoltage(XPOWERS_DCDC1));
} }
if (PMU->isChannelAvailable(XPOWERS_DCDC2)) { if (PMU->isChannelAvailable(XPOWERS_DCDC2)) {
LOG_DEBUG("DC2 : %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-", LOG_DEBUG("DC2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_DCDC2)); PMU->getPowerChannelVoltage(XPOWERS_DCDC2));
} }
if (PMU->isChannelAvailable(XPOWERS_DCDC3)) { if (PMU->isChannelAvailable(XPOWERS_DCDC3)) {
LOG_DEBUG("DC3 : %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-", LOG_DEBUG("DC3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_DCDC3)); PMU->getPowerChannelVoltage(XPOWERS_DCDC3));
} }
if (PMU->isChannelAvailable(XPOWERS_DCDC4)) { if (PMU->isChannelAvailable(XPOWERS_DCDC4)) {
LOG_DEBUG("DC4 : %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-", LOG_DEBUG("DC4 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_DCDC4)); PMU->getPowerChannelVoltage(XPOWERS_DCDC4));
} }
if (PMU->isChannelAvailable(XPOWERS_LDO2)) { if (PMU->isChannelAvailable(XPOWERS_LDO2)) {
LOG_DEBUG("LDO2 : %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-", LOG_DEBUG("LDO2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_LDO2)); PMU->getPowerChannelVoltage(XPOWERS_LDO2));
} }
if (PMU->isChannelAvailable(XPOWERS_LDO3)) { if (PMU->isChannelAvailable(XPOWERS_LDO3)) {
LOG_DEBUG("LDO3 : %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-", LOG_DEBUG("LDO3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_LDO3)); PMU->getPowerChannelVoltage(XPOWERS_LDO3));
} }
if (PMU->isChannelAvailable(XPOWERS_ALDO1)) { if (PMU->isChannelAvailable(XPOWERS_ALDO1)) {
LOG_DEBUG("ALDO1: %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-", LOG_DEBUG("ALDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_ALDO1)); PMU->getPowerChannelVoltage(XPOWERS_ALDO1));
} }
if (PMU->isChannelAvailable(XPOWERS_ALDO2)) { if (PMU->isChannelAvailable(XPOWERS_ALDO2)) {
LOG_DEBUG("ALDO2: %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-", LOG_DEBUG("ALDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_ALDO2)); PMU->getPowerChannelVoltage(XPOWERS_ALDO2));
} }
if (PMU->isChannelAvailable(XPOWERS_ALDO3)) { if (PMU->isChannelAvailable(XPOWERS_ALDO3)) {
LOG_DEBUG("ALDO3: %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-", LOG_DEBUG("ALDO3: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_ALDO3)); PMU->getPowerChannelVoltage(XPOWERS_ALDO3));
} }
if (PMU->isChannelAvailable(XPOWERS_ALDO4)) { if (PMU->isChannelAvailable(XPOWERS_ALDO4)) {
LOG_DEBUG("ALDO4: %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-", LOG_DEBUG("ALDO4: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_ALDO4)); PMU->getPowerChannelVoltage(XPOWERS_ALDO4));
} }
if (PMU->isChannelAvailable(XPOWERS_BLDO1)) { if (PMU->isChannelAvailable(XPOWERS_BLDO1)) {
LOG_DEBUG("BLDO1: %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-", LOG_DEBUG("BLDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_BLDO1)); PMU->getPowerChannelVoltage(XPOWERS_BLDO1));
} }
if (PMU->isChannelAvailable(XPOWERS_BLDO2)) { if (PMU->isChannelAvailable(XPOWERS_BLDO2)) {
LOG_DEBUG("BLDO2: %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-", LOG_DEBUG("BLDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-",
PMU->getPowerChannelVoltage(XPOWERS_BLDO2)); PMU->getPowerChannelVoltage(XPOWERS_BLDO2));
} }
LOG_DEBUG("=======================================================================\n");
// We can safely ignore this approach for most (or all) boards because MCU turned off // We can safely ignore this approach for most (or all) boards because MCU turned off
// earlier than battery discharged to 2.6V. // earlier than battery discharged to 2.6V.
@@ -1077,82 +1042,4 @@ bool Power::axpChipInit()
#else #else
return false; return false;
#endif #endif
} }
#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
/**
* Wrapper class for an I2C MAX17048 Lipo battery sensor.
*/
class LipoBatteryLevel : public HasBatteryLevel
{
private:
MAX17048Singleton *max17048 = nullptr;
public:
/**
* Init the I2C MAX17048 Lipo battery level sensor
*/
bool runOnce()
{
if (max17048 == nullptr) {
max17048 = MAX17048Singleton::GetInstance();
}
// try to start if the sensor has been detected
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_MAX17048].first != 0) {
return max17048->runOnce(nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_MAX17048].second);
}
return false;
}
/**
* Battery state of charge, from 0 to 100 or -1 for unknown
*/
virtual int getBatteryPercent() override { return max17048->getBusBatteryPercent(); }
/**
* The raw voltage of the battery in millivolts, or NAN if unknown
*/
virtual uint16_t getBattVoltage() override { return max17048->getBusVoltageMv(); }
/**
* return true if there is a battery installed in this unit
*/
virtual bool isBatteryConnect() override { return max17048->isBatteryConnected(); }
/**
* return true if there is an external power source detected
*/
virtual bool isVbusIn() override { return max17048->isExternallyPowered(); }
/**
* return true if the battery is currently charging
*/
virtual bool isCharging() override { return max17048->isBatteryCharging(); }
};
LipoBatteryLevel lipoLevel;
/**
* Init the Lipo battery level sensor
*/
bool Power::lipoInit()
{
bool result = lipoLevel.runOnce();
LOG_DEBUG("Power::lipoInit lipo sensor is %s", result ? "ready" : "not ready yet");
if (!result)
return false;
batteryLevel = &lipoLevel;
return true;
}
#else
/**
* The Lipo battery level sensor is unavailable - default to AnalogBatteryLevel
*/
bool Power::lipoInit()
{
return false;
}
#endif

View File

@@ -53,7 +53,7 @@ static bool isPowered()
static void sdsEnter() static void sdsEnter()
{ {
LOG_DEBUG("Enter state: SDS"); LOG_DEBUG("Enter state: SDS\n");
// FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw // 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); doDeepSleep(Default::getConfiguredOrDefaultMs(config.power.sds_secs), false);
} }
@@ -62,7 +62,7 @@ extern Power *power;
static void shutdownEnter() static void shutdownEnter()
{ {
LOG_DEBUG("Enter state: SHUTDOWN"); LOG_DEBUG("Enter state: SHUTDOWN\n");
power->shutdown(); power->shutdown();
} }
@@ -72,16 +72,16 @@ static uint32_t secsSlept;
static void lsEnter() static void lsEnter()
{ {
LOG_INFO("lsEnter begin, ls_secs=%u", config.power.ls_secs); LOG_INFO("lsEnter begin, ls_secs=%u\n", config.power.ls_secs);
screen->setOn(false); screen->setOn(false);
secsSlept = 0; // How long have we been sleeping this time secsSlept = 0; // How long have we been sleeping this time
// LOG_INFO("lsEnter end"); // LOG_INFO("lsEnter end\n");
} }
static void lsIdle() static void lsIdle()
{ {
// LOG_INFO("lsIdle begin ls_secs=%u", getPref_ls_secs()); // LOG_INFO("lsIdle begin ls_secs=%u\n", getPref_ls_secs());
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
@@ -105,7 +105,7 @@ static void lsIdle()
wakeCause2 = doLightSleep(100); // leave led on for 1ms wakeCause2 = doLightSleep(100); // leave led on for 1ms
secsSlept += sleepTime; secsSlept += sleepTime;
// LOG_INFO("sleeping, flash led!"); // LOG_INFO("sleeping, flash led!\n");
break; break;
case ESP_SLEEP_WAKEUP_UART: case ESP_SLEEP_WAKEUP_UART:
@@ -137,7 +137,7 @@ static void lsIdle()
} else { } else {
// Time to stop sleeping! // Time to stop sleeping!
ledBlink.set(false); ledBlink.set(false);
LOG_INFO("Reached ls_secs, servicing loop()"); LOG_INFO("Reached ls_secs, servicing loop()\n");
powerFSM.trigger(EVENT_WAKE_TIMER); powerFSM.trigger(EVENT_WAKE_TIMER);
} }
#endif #endif
@@ -145,12 +145,12 @@ static void lsIdle()
static void lsExit() static void lsExit()
{ {
LOG_INFO("Exit state: LS"); LOG_INFO("Exit state: LS\n");
} }
static void nbEnter() static void nbEnter()
{ {
LOG_DEBUG("Enter state: NB"); LOG_DEBUG("Enter state: NB\n");
screen->setOn(false); screen->setOn(false);
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
// Only ESP32 should turn off bluetooth // Only ESP32 should turn off bluetooth
@@ -168,7 +168,7 @@ static void darkEnter()
static void serialEnter() static void serialEnter()
{ {
LOG_DEBUG("Enter state: SERIAL"); LOG_DEBUG("Enter state: SERIAL\n");
setBluetoothEnable(false); setBluetoothEnable(false);
screen->setOn(true); screen->setOn(true);
screen->print("Serial connected\n"); screen->print("Serial connected\n");
@@ -183,10 +183,10 @@ static void serialExit()
static void powerEnter() static void powerEnter()
{ {
// LOG_DEBUG("Enter state: POWER"); // LOG_DEBUG("Enter state: POWER\n");
if (!isPowered()) { if (!isPowered()) {
// If we got here, we are in the wrong state - we should be in powered, let that state ahndle things // If we got here, we are in the wrong state - we should be in powered, let that state ahndle things
LOG_INFO("Loss of power in Powered"); LOG_INFO("Loss of power in Powered\n");
powerFSM.trigger(EVENT_POWER_DISCONNECTED); powerFSM.trigger(EVENT_POWER_DISCONNECTED);
} else { } else {
screen->setOn(true); screen->setOn(true);
@@ -205,7 +205,7 @@ static void powerIdle()
{ {
if (!isPowered()) { if (!isPowered()) {
// If we got here, we are in the wrong state // If we got here, we are in the wrong state
LOG_INFO("Loss of power in Powered"); LOG_INFO("Loss of power in Powered\n");
powerFSM.trigger(EVENT_POWER_DISCONNECTED); powerFSM.trigger(EVENT_POWER_DISCONNECTED);
} }
} }
@@ -222,7 +222,7 @@ static void powerExit()
static void onEnter() static void onEnter()
{ {
LOG_DEBUG("Enter state: ON"); LOG_DEBUG("Enter state: ON\n");
screen->setOn(true); screen->setOn(true);
setBluetoothEnable(true); setBluetoothEnable(true);
} }
@@ -242,7 +242,7 @@ static void screenPress()
static void bootEnter() static void bootEnter()
{ {
LOG_DEBUG("Enter state: BOOT"); LOG_DEBUG("Enter state: BOOT\n");
} }
State stateSHUTDOWN(shutdownEnter, NULL, NULL, "SHUTDOWN"); State stateSHUTDOWN(shutdownEnter, NULL, NULL, "SHUTDOWN");
@@ -264,7 +264,7 @@ void PowerFSM_setup()
config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR; config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR;
bool hasPower = isPowered(); bool hasPower = isPowered();
LOG_INFO("PowerFSM init, USB power=%d", hasPower ? 1 : 0); LOG_INFO("PowerFSM init, USB power=%d\n", hasPower ? 1 : 0);
powerFSM.add_timed_transition(&stateBOOT, hasPower ? &statePOWER : &stateON, 3 * 1000, NULL, "boot timeout"); powerFSM.add_timed_transition(&stateBOOT, hasPower ? &statePOWER : &stateON, 3 * 1000, NULL, "boot timeout");
// wake timer expired or a packet arrived // wake timer expired or a packet arrived

View File

@@ -35,7 +35,7 @@ void PowerMon::emitLog(const char *reason)
{ {
#ifdef USE_POWERMON #ifdef USE_POWERMON
// The nrf52 printf doesn't understand 64 bit ints, so if we ever reach that point this function will need to change. // The nrf52 printf doesn't understand 64 bit ints, so if we ever reach that point this function will need to change.
LOG_INFO("S:PM:0x%08lx,%s", (uint32_t)states, reason); LOG_INFO("S:PM:0x%08lx,%s\n", (uint32_t)states, reason);
#endif #endif
} }

View File

@@ -91,7 +91,7 @@ class PowerStatus : public Status
isCharging = newStatus->isCharging; isCharging = newStatus->isCharging;
} }
if (isDirty) { if (isDirty) {
// LOG_DEBUG("Battery %dmV %d%%", batteryVoltageMv, batteryChargePercent); // LOG_DEBUG("Battery %dmV %d%%\n", batteryVoltageMv, batteryChargePercent);
onNewStatus.notifyObservers(this); onNewStatus.notifyObservers(this);
} }
return 0; return 0;

View File

@@ -98,75 +98,81 @@ void RedirectablePrint::log_to_serial(const char *logLevel, const char *format,
{ {
size_t r = 0; size_t r = 0;
// Cope with 0 len format strings, but look for new line terminator
bool hasNewline = *format && format[strlen(format) - 1] == '\n';
#ifdef ARCH_PORTDUINO #ifdef ARCH_PORTDUINO
bool color = !settingsMap[ascii_logs]; bool color = !settingsMap[ascii_logs];
#else #else
bool color = true; bool color = true;
#endif #endif
// include the header // If we are the first message on a report, include the header
if (color) { if (!isContinuationMessage) {
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0) if (color) {
Print::write("\u001b[34m", 6); if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0)
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0) Print::write("\u001b[34m", 6);
Print::write("\u001b[32m", 6); if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0)
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_WARN) == 0) Print::write("\u001b[32m", 6);
Print::write("\u001b[33m", 6); if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_WARN) == 0)
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_ERROR) == 0) Print::write("\u001b[33m", 6);
Print::write("\u001b[31m", 6); if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_ERROR) == 0)
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0) Print::write("\u001b[31m", 6);
Print::write("\u001b[35m", 6); if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0)
} Print::write("\u001b[35m", 6);
}
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true); // display local time on logfile uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true); // display local time on logfile
if (rtc_sec > 0) { if (rtc_sec > 0) {
long hms = rtc_sec % SEC_PER_DAY; long hms = rtc_sec % SEC_PER_DAY;
// hms += tz.tz_dsttime * SEC_PER_HOUR; // hms += tz.tz_dsttime * SEC_PER_HOUR;
// hms -= tz.tz_minuteswest * SEC_PER_MIN; // hms -= tz.tz_minuteswest * SEC_PER_MIN;
// mod `hms` to ensure in positive range of [0...SEC_PER_DAY) // mod `hms` to ensure in positive range of [0...SEC_PER_DAY)
hms = (hms + SEC_PER_DAY) % SEC_PER_DAY; hms = (hms + SEC_PER_DAY) % SEC_PER_DAY;
// Tear apart hms into h:m:s // Tear apart hms into h:m:s
int hour = hms / SEC_PER_HOUR; int hour = hms / SEC_PER_HOUR;
int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN; int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN;
int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN
#ifdef ARCH_PORTDUINO #ifdef ARCH_PORTDUINO
::printf("%s ", logLevel); ::printf("%s ", logLevel);
if (color) { if (color) {
::printf("\u001b[0m"); ::printf("\u001b[0m");
} }
::printf("| %02d:%02d:%02d %u ", hour, min, sec, millis() / 1000); ::printf("| %02d:%02d:%02d %u ", hour, min, sec, millis() / 1000);
#else #else
printf("%s ", logLevel); printf("%s ", logLevel);
if (color) { if (color) {
printf("\u001b[0m"); printf("\u001b[0m");
} }
printf("| %02d:%02d:%02d %u ", hour, min, sec, millis() / 1000); printf("| %02d:%02d:%02d %u ", hour, min, sec, millis() / 1000);
#endif #endif
} else { } else {
#ifdef ARCH_PORTDUINO #ifdef ARCH_PORTDUINO
::printf("%s ", logLevel); ::printf("%s ", logLevel);
if (color) { if (color) {
::printf("\u001b[0m"); ::printf("\u001b[0m");
} }
::printf("| ??:??:?? %u ", millis() / 1000); ::printf("| ??:??:?? %u ", millis() / 1000);
#else #else
printf("%s ", logLevel); printf("%s ", logLevel);
if (color) { if (color) {
printf("\u001b[0m"); printf("\u001b[0m");
} }
printf("| ??:??:?? %u ", millis() / 1000); printf("| ??:??:?? %u ", millis() / 1000);
#endif #endif
} }
auto thread = concurrency::OSThread::currentThread; auto thread = concurrency::OSThread::currentThread;
if (thread) { if (thread) {
print("["); print("[");
// printf("%p ", thread); // printf("%p ", thread);
// assert(thread->ThreadName.length()); // assert(thread->ThreadName.length());
print(thread->ThreadName); print(thread->ThreadName);
print("] "); print("] ");
}
} }
r += vprintf(logLevel, format, arg); r += vprintf(logLevel, format, arg);
isContinuationMessage = !hasNewline;
} }
void RedirectablePrint::log_to_syslog(const char *logLevel, const char *format, va_list arg) void RedirectablePrint::log_to_syslog(const char *logLevel, const char *format, va_list arg)
@@ -277,14 +283,6 @@ meshtastic_LogRecord_Level RedirectablePrint::getLogLevel(const char *logLevel)
void RedirectablePrint::log(const char *logLevel, const char *format, ...) void RedirectablePrint::log(const char *logLevel, const char *format, ...)
{ {
// append \n to format
size_t len = strlen(format);
char *newFormat = new char[len + 2];
strcpy(newFormat, format);
newFormat[len] = '\n';
newFormat[len + 1] = '\0';
#if ARCH_PORTDUINO #if ARCH_PORTDUINO
// level trace is special, two possible ways to handle it. // level trace is special, two possible ways to handle it.
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0) { if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0) {
@@ -297,24 +295,17 @@ void RedirectablePrint::log(const char *logLevel, const char *format, ...)
} }
va_end(arg); va_end(arg);
} }
if (settingsMap[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; return;
}
} }
if (settingsMap[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; return;
} else if (settingsMap[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; return;
} else if (settingsMap[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; return;
}
#endif #endif
if (moduleConfig.serial.override_console_serial_port && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0) { if (moduleConfig.serial.override_console_serial_port && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0) {
delete[] newFormat;
return; return;
} }
@@ -328,9 +319,9 @@ void RedirectablePrint::log(const char *logLevel, const char *format, ...)
va_list arg; va_list arg;
va_start(arg, format); va_start(arg, format);
log_to_serial(logLevel, newFormat, arg); log_to_serial(logLevel, format, arg);
log_to_syslog(logLevel, newFormat, arg); log_to_syslog(logLevel, format, arg);
log_to_ble(logLevel, newFormat, arg); log_to_ble(logLevel, format, arg);
va_end(arg); va_end(arg);
#ifdef HAS_FREE_RTOS #ifdef HAS_FREE_RTOS
@@ -340,18 +331,17 @@ void RedirectablePrint::log(const char *logLevel, const char *format, ...)
#endif #endif
} }
delete[] newFormat;
return; return;
} }
void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16_t len) void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16_t len)
{ {
const char alphabet[17] = "0123456789abcdef"; const char alphabet[17] = "0123456789abcdef";
log(logLevel, " +------------------------------------------------+ +----------------+"); log(logLevel, " +------------------------------------------------+ +----------------+\n");
log(logLevel, " |.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f | | ASCII |"); log(logLevel, " |.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f | | ASCII |\n");
for (uint16_t i = 0; i < len; i += 16) { for (uint16_t i = 0; i < len; i += 16) {
if (i % 128 == 0) if (i % 128 == 0)
log(logLevel, " +------------------------------------------------+ +----------------+"); log(logLevel, " +------------------------------------------------+ +----------------+\n");
char s[] = "| | | |\n"; char s[] = "| | | |\n";
uint8_t ix = 1, iy = 52; uint8_t ix = 1, iy = 52;
for (uint8_t j = 0; j < 16; j++) { for (uint8_t j = 0; j < 16; j++) {
@@ -373,7 +363,7 @@ void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16
log(logLevel, "."); log(logLevel, ".");
log(logLevel, s); log(logLevel, s);
} }
log(logLevel, " +------------------------------------------------+ +----------------+"); log(logLevel, " +------------------------------------------------+ +----------------+\n");
} }
std::string RedirectablePrint::mt_sprintf(const std::string fmt_str, ...) std::string RedirectablePrint::mt_sprintf(const std::string fmt_str, ...)

View File

@@ -15,6 +15,9 @@ class RedirectablePrint : public Print
{ {
Print *dest; Print *dest;
/// Used to allow multiple logDebug messages to appear on a single log line
bool isContinuationMessage = false;
#ifdef HAS_FREE_RTOS #ifdef HAS_FREE_RTOS
SemaphoreHandle_t inDebugPrint = nullptr; SemaphoreHandle_t inDebugPrint = nullptr;
StaticSemaphore_t _MutexStorageSpace; StaticSemaphore_t _MutexStorageSpace;
@@ -51,9 +54,9 @@ class RedirectablePrint : public Print
protected: protected:
/// Subclasses can override if they need to change how we format over the serial port /// Subclasses can override if they need to change how we format over the serial port
virtual void log_to_serial(const char *logLevel, const char *format, va_list arg); virtual void log_to_serial(const char *logLevel, const char *format, va_list arg);
meshtastic_LogRecord_Level getLogLevel(const char *logLevel);
private: private:
void log_to_syslog(const char *logLevel, const char *format, va_list arg); void log_to_syslog(const char *logLevel, const char *format, va_list arg);
void log_to_ble(const char *logLevel, const char *format, va_list arg); void log_to_ble(const char *logLevel, const char *format, va_list arg);
meshtastic_LogRecord_Level getLogLevel(const char *logLevel);
}; };

View File

@@ -59,14 +59,14 @@ bool SafeFile::close()
// brief window of risk here ;-) // brief window of risk here ;-)
if (fullAtomic && FSCom.exists(filename.c_str()) && !FSCom.remove(filename.c_str())) { if (fullAtomic && FSCom.exists(filename.c_str()) && !FSCom.remove(filename.c_str())) {
LOG_ERROR("Can't remove old pref file"); LOG_ERROR("Can't remove old pref file\n");
return false; return false;
} }
String filenameTmp = filename; String filenameTmp = filename;
filenameTmp += ".tmp"; filenameTmp += ".tmp";
if (!renameFile(filenameTmp.c_str(), filename.c_str())) { if (!renameFile(filenameTmp.c_str(), filename.c_str())) {
LOG_ERROR("Error: can't rename new pref file"); LOG_ERROR("Error: can't rename new pref file\n");
return false; return false;
} }
@@ -83,7 +83,7 @@ bool SafeFile::testReadback()
filenameTmp += ".tmp"; filenameTmp += ".tmp";
auto f2 = FSCom.open(filenameTmp.c_str(), FILE_O_READ); auto f2 = FSCom.open(filenameTmp.c_str(), FILE_O_READ);
if (!f2) { if (!f2) {
LOG_ERROR("Can't open tmp file for readback"); LOG_ERROR("Can't open tmp file for readback\n");
return false; return false;
} }
@@ -95,7 +95,7 @@ bool SafeFile::testReadback()
f2.close(); f2.close();
if (test_hash != hash) { if (test_hash != hash) {
LOG_ERROR("Readback failed hash mismatch"); LOG_ERROR("Readback failed hash mismatch\n");
return false; return false;
} }

View File

@@ -24,7 +24,7 @@
class SafeFile : public Print class SafeFile : public Print
{ {
public: public:
explicit SafeFile(char const *filepath, bool fullAtomic = false); SafeFile(char const *filepath, bool fullAtomic = false);
virtual size_t write(uint8_t); virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *buffer, size_t size); virtual size_t write(const uint8_t *buffer, size_t size);

View File

@@ -1,8 +1,6 @@
#include "SerialConsole.h" #include "SerialConsole.h"
#include "Default.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "PowerFSM.h" #include "PowerFSM.h"
#include "Throttle.h"
#include "configuration.h" #include "configuration.h"
#include "time.h" #include "time.h"
@@ -46,11 +44,10 @@ SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port), con
Port.setRX(SERIAL2_RX); Port.setRX(SERIAL2_RX);
#endif #endif
Port.begin(SERIAL_BAUD); Port.begin(SERIAL_BAUD);
#if defined(ARCH_NRF52) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(ARCH_RP2040) || \ #if defined(ARCH_NRF52) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(ARCH_RP2040)
defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6)
time_t timeout = millis(); time_t timeout = millis();
while (!Port) { while (!Port) {
if (Throttle::isWithinTimespanMs(timeout, FIVE_SECONDS_MS)) { if ((millis() - timeout) < 5000) {
delay(100); delay(100);
} else { } else {
break; break;
@@ -75,7 +72,8 @@ void SerialConsole::flush()
// For the serial port we can't really detect if any client is on the other side, so instead just look for recent messages // 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() bool SerialConsole::checkIsConnected()
{ {
return Throttle::isWithinTimespanMs(lastContactMsec, SERIAL_CONNECTION_TIMEOUT); uint32_t now = millis();
return (now - lastContactMsec) < SERIAL_CONNECTION_TIMEOUT;
} }
/** /**
@@ -99,9 +97,27 @@ bool SerialConsole::handleToRadio(const uint8_t *buf, size_t len)
void SerialConsole::log_to_serial(const char *logLevel, const char *format, va_list arg) void SerialConsole::log_to_serial(const char *logLevel, const char *format, va_list arg)
{ {
if (usingProtobufs && config.security.debug_log_api_enabled) { if (usingProtobufs && config.security.debug_log_api_enabled) {
meshtastic_LogRecord_Level ll = RedirectablePrint::getLogLevel(logLevel); meshtastic_LogRecord_Level ll = meshtastic_LogRecord_Level_UNSET; // default to unset
switch (logLevel[0]) {
case 'D':
ll = meshtastic_LogRecord_Level_DEBUG;
break;
case 'I':
ll = meshtastic_LogRecord_Level_INFO;
break;
case 'W':
ll = meshtastic_LogRecord_Level_WARNING;
break;
case 'E':
ll = meshtastic_LogRecord_Level_ERROR;
break;
case 'C':
ll = meshtastic_LogRecord_Level_CRITICAL;
break;
}
auto thread = concurrency::OSThread::currentThread; auto thread = concurrency::OSThread::currentThread;
emitLogRecord(ll, thread ? thread->ThreadName.c_str() : "", format, arg); emitLogRecord(ll, thread ? thread->ThreadName.c_str() : "", format, arg);
} else } else
RedirectablePrint::log_to_serial(logLevel, format, arg); RedirectablePrint::log_to_serial(logLevel, format, arg);
} }

View File

@@ -13,17 +13,17 @@ void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms)
{ {
if (reportType == TX_LOG) { if (reportType == TX_LOG) {
LOG_DEBUG("Packet transmitted : %ums", airtime_ms); LOG_DEBUG("AirTime - Packet transmitted : %ums\n", airtime_ms);
this->airtimes.periodTX[0] = this->airtimes.periodTX[0] + airtime_ms; this->airtimes.periodTX[0] = this->airtimes.periodTX[0] + airtime_ms;
air_period_tx[0] = air_period_tx[0] + airtime_ms; air_period_tx[0] = air_period_tx[0] + airtime_ms;
this->utilizationTX[this->getPeriodUtilHour()] = this->utilizationTX[this->getPeriodUtilHour()] + airtime_ms; this->utilizationTX[this->getPeriodUtilHour()] = this->utilizationTX[this->getPeriodUtilHour()] + airtime_ms;
} else if (reportType == RX_LOG) { } else if (reportType == RX_LOG) {
LOG_DEBUG("Packet received : %ums", airtime_ms); LOG_DEBUG("AirTime - Packet received : %ums\n", airtime_ms);
this->airtimes.periodRX[0] = this->airtimes.periodRX[0] + airtime_ms; this->airtimes.periodRX[0] = this->airtimes.periodRX[0] + airtime_ms;
air_period_rx[0] = air_period_rx[0] + airtime_ms; air_period_rx[0] = air_period_rx[0] + airtime_ms;
} else if (reportType == RX_ALL_LOG) { } else if (reportType == RX_ALL_LOG) {
LOG_DEBUG("Packet received (noise?) : %ums", airtime_ms); LOG_DEBUG("AirTime - Packet received (noise?) : %ums\n", airtime_ms);
this->airtimes.periodRX_ALL[0] = this->airtimes.periodRX_ALL[0] + airtime_ms; this->airtimes.periodRX_ALL[0] = this->airtimes.periodRX_ALL[0] + airtime_ms;
} }
@@ -50,7 +50,7 @@ void AirTime::airtimeRotatePeriod()
{ {
if (this->airtimes.lastPeriodIndex != this->currentPeriodIndex()) { if (this->airtimes.lastPeriodIndex != this->currentPeriodIndex()) {
LOG_DEBUG("Rotating airtimes to a new period = %u", this->currentPeriodIndex()); LOG_DEBUG("Rotating airtimes to a new period = %u\n", this->currentPeriodIndex());
for (int i = PERIODS_TO_LOG - 2; i >= 0; --i) { for (int i = PERIODS_TO_LOG - 2; i >= 0; --i) {
this->airtimes.periodTX[i + 1] = this->airtimes.periodTX[i]; this->airtimes.periodTX[i + 1] = this->airtimes.periodTX[i];
@@ -105,7 +105,7 @@ float AirTime::channelUtilizationPercent()
uint32_t sum = 0; uint32_t sum = 0;
for (uint32_t i = 0; i < CHANNEL_UTILIZATION_PERIODS; i++) { for (uint32_t i = 0; i < CHANNEL_UTILIZATION_PERIODS; i++) {
sum += this->channelUtilization[i]; sum += this->channelUtilization[i];
// LOG_DEBUG("ChanUtilArray %u %u", i, this->channelUtilization[i]); // LOG_DEBUG("ChanUtilArray %u %u\n", i, this->channelUtilization[i]);
} }
return (float(sum) / float(CHANNEL_UTILIZATION_PERIODS * 10 * 1000)) * 100; return (float(sum) / float(CHANNEL_UTILIZATION_PERIODS * 10 * 1000)) * 100;
@@ -127,7 +127,7 @@ bool AirTime::isTxAllowedChannelUtil(bool polite)
if (channelUtilizationPercent() < percentage) { if (channelUtilizationPercent() < percentage) {
return true; return true;
} else { } else {
LOG_WARN("Channel utilization is >%d percent. Skipping this opportunity to send.", percentage); LOG_WARN("Channel utilization is >%d percent. Skipping this opportunity to send.\n", percentage);
return false; return false;
} }
} }
@@ -138,7 +138,7 @@ bool AirTime::isTxAllowedAirUtil()
if (utilizationTXPercent() < myRegion->dutyCycle * polite_duty_cycle_percent / 100) { if (utilizationTXPercent() < myRegion->dutyCycle * polite_duty_cycle_percent / 100) {
return true; return true;
} else { } else {
LOG_WARN("Tx air utilization is >%f percent. Skipping this opportunity to send.", LOG_WARN("Tx air utilization is >%f percent. Skipping this opportunity to send.\n",
myRegion->dutyCycle * polite_duty_cycle_percent / 100); myRegion->dutyCycle * polite_duty_cycle_percent / 100);
return false; return false;
} }
@@ -209,13 +209,13 @@ int32_t AirTime::runOnce()
} }
} }
/* /*
LOG_DEBUG("utilPeriodTX %d TX Airtime %3.2f%", utilPeriodTX, airTime->utilizationTXPercent()); LOG_DEBUG("utilPeriodTX %d TX Airtime %3.2f%\n", utilPeriodTX, airTime->utilizationTXPercent());
for (uint32_t i = 0; i < MINUTES_IN_HOUR; i++) { for (uint32_t i = 0; i < MINUTES_IN_HOUR; i++) {
LOG_DEBUG( LOG_DEBUG(
"%d,", this->utilizationTX[i] "%d,", this->utilizationTX[i]
); );
} }
LOG_DEBUG(""); LOG_DEBUG("\n");
*/ */
return (1000 * 1); return (1000 * 1);
} }

View File

@@ -55,18 +55,6 @@ void playBeep()
playTones(melody, sizeof(melody) / sizeof(ToneDuration)); playTones(melody, sizeof(melody) / sizeof(ToneDuration));
} }
void playGPSEnableBeep()
{
ToneDuration melody[] = {{NOTE_C3, DURATION_1_8}, {NOTE_FS3, DURATION_1_4}, {NOTE_CS4, DURATION_1_4}};
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
}
void playGPSDisableBeep()
{
ToneDuration melody[] = {{NOTE_CS4, DURATION_1_8}, {NOTE_FS3, DURATION_1_4}, {NOTE_C3, DURATION_1_4}};
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
}
void playStartMelody() void playStartMelody()
{ {
ToneDuration melody[] = {{NOTE_FS3, DURATION_1_8}, {NOTE_AS3, DURATION_1_8}, {NOTE_CS4, DURATION_1_4}}; ToneDuration melody[] = {{NOTE_FS3, DURATION_1_8}, {NOTE_AS3, DURATION_1_8}, {NOTE_CS4, DURATION_1_4}};

View File

@@ -3,5 +3,3 @@
void playBeep(); void playBeep();
void playStartMelody(); void playStartMelody();
void playShutdownMelody(); void playShutdownMelody();
void playGPSEnableBeep();
void playGPSDisableBeep();

View File

@@ -18,7 +18,7 @@ bool InterruptableDelay::delay(uint32_t msec)
// sem take will return false if we timed out (i.e. were not interrupted) // sem take will return false if we timed out (i.e. were not interrupted)
bool r = semaphore.take(msec); bool r = semaphore.take(msec);
// LOG_DEBUG("interrupt=%d", r); // LOG_DEBUG("interrupt=%d\n", r);
return !r; return !r;
} }

View File

@@ -32,12 +32,12 @@ IRAM_ATTR bool NotifiedWorkerThread::notifyCommon(uint32_t v, bool overwrite)
notification = v; notification = v;
if (debugNotification) { if (debugNotification) {
LOG_DEBUG("setting notification %d", v); LOG_DEBUG("setting notification %d\n", v);
} }
return true; return true;
} else { } else {
if (debugNotification) { if (debugNotification) {
LOG_DEBUG("dropping notification %d", v); LOG_DEBUG("dropping notification %d\n", v);
} }
return false; return false;
} }
@@ -67,7 +67,7 @@ bool NotifiedWorkerThread::notifyLater(uint32_t delay, uint32_t v, bool overwrit
if (didIt) { // If we didn't already have something queued, override the delay to be larger if (didIt) { // If we didn't already have something queued, override the delay to be larger
setIntervalFromNow(delay); // a new version of setInterval relative to the current time setIntervalFromNow(delay); // a new version of setInterval relative to the current time
if (debugNotification) { if (debugNotification) {
LOG_DEBUG("delaying notification %u", delay); LOG_DEBUG("delaying notification %u\n", delay);
} }
} }

View File

@@ -62,15 +62,15 @@ bool OSThread::shouldRun(unsigned long time)
bool r = Thread::shouldRun(time); bool r = Thread::shouldRun(time);
if (showRun && r) { if (showRun && r) {
LOG_DEBUG("Thread %s: run", ThreadName.c_str()); LOG_DEBUG("Thread %s: run\n", ThreadName.c_str());
} }
if (showWaiting && enabled && !r) { if (showWaiting && enabled && !r) {
LOG_DEBUG("Thread %s: wait %lu", ThreadName.c_str(), interval); LOG_DEBUG("Thread %s: wait %lu\n", ThreadName.c_str(), interval);
} }
if (showDisabled && !enabled) { if (showDisabled && !enabled) {
LOG_DEBUG("Thread %s: disabled", ThreadName.c_str()); LOG_DEBUG("Thread %s: disabled\n", ThreadName.c_str());
} }
return r; return r;
@@ -86,9 +86,9 @@ void OSThread::run()
#ifdef DEBUG_HEAP #ifdef DEBUG_HEAP
auto newHeap = memGet.getFreeHeap(); auto newHeap = memGet.getFreeHeap();
if (newHeap < heap) if (newHeap < heap)
LOG_DEBUG("------ Thread %s leaked heap %d -> %d (%d) ------", ThreadName.c_str(), heap, newHeap, newHeap - heap); LOG_DEBUG("------ Thread %s leaked heap %d -> %d (%d) ------\n", ThreadName.c_str(), heap, newHeap, newHeap - heap);
if (heap < newHeap) if (heap < newHeap)
LOG_DEBUG("++++++ Thread %s freed heap %d -> %d (%d) ++++++", ThreadName.c_str(), heap, newHeap, newHeap - heap); LOG_DEBUG("++++++ Thread %s freed heap %d -> %d (%d) ++++++\n", ThreadName.c_str(), heap, newHeap, newHeap - heap);
#endif #endif
runned(); runned();

View File

@@ -69,9 +69,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef RTC_DATA_ATTR #ifndef RTC_DATA_ATTR
#define RTC_DATA_ATTR #define RTC_DATA_ATTR
#endif #endif
#ifndef EXT_RAM_BSS_ATTR
#define EXT_RAM_BSS_ATTR EXT_RAM_ATTR
#endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Regulatory overrides // Regulatory overrides
@@ -114,7 +111,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define CARDKB_ADDR 0x5F #define CARDKB_ADDR 0x5F
#define TDECK_KB_ADDR 0x55 #define TDECK_KB_ADDR 0x55
#define BBQ10_KB_ADDR 0x1F #define BBQ10_KB_ADDR 0x1F
#define MPR121_KB_ADDR 0x5A
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// SENSOR // SENSOR
@@ -126,17 +122,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define INA_ADDR_ALTERNATE 0x41 #define INA_ADDR_ALTERNATE 0x41
#define INA_ADDR_WAVESHARE_UPS 0x43 #define INA_ADDR_WAVESHARE_UPS 0x43
#define INA3221_ADDR 0x42 #define INA3221_ADDR 0x42
#define MAX1704X_ADDR 0x36
#define QMC6310_ADDR 0x1C #define QMC6310_ADDR 0x1C
#define QMI8658_ADDR 0x6B #define QMI8658_ADDR 0x6B
#define QMC5883L_ADDR 0x0D #define QMC5883L_ADDR 0x1E
#define HMC5883L_ADDR 0x1E
#define SHTC3_ADDR 0x70 #define SHTC3_ADDR 0x70
#define LPS22HB_ADDR 0x5C #define LPS22HB_ADDR 0x5C
#define LPS22HB_ADDR_ALT 0x5D #define LPS22HB_ADDR_ALT 0x5D
#define SHT31_4x_ADDR 0x44 #define SHT31_4x_ADDR 0x44
#define PMSA0031_ADDR 0x12 #define PMSA0031_ADDR 0x12
#define QMA6100P_ADDR 0x12
#define AHT10_ADDR 0x38 #define AHT10_ADDR 0x38
#define RCWL9620_ADDR 0x57 #define RCWL9620_ADDR 0x57
#define VEML7700_ADDR 0x10 #define VEML7700_ADDR 0x10
@@ -146,20 +139,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define MLX90632_ADDR 0x3A #define MLX90632_ADDR 0x3A
#define DFROBOT_LARK_ADDR 0x42 #define DFROBOT_LARK_ADDR 0x42
#define NAU7802_ADDR 0x2A #define NAU7802_ADDR 0x2A
#define MAX30102_ADDR 0x57
#define MLX90614_ADDR_DEF 0x5A
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// ACCELEROMETER // ACCELEROMETER
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#define MPU6050_ADDR 0x68 #define MPU6050_ADDR 0x68
#define STK8BXX_ADR 0x18
#define LIS3DH_ADR 0x18 #define LIS3DH_ADR 0x18
#define BMA423_ADDR 0x19 #define BMA423_ADDR 0x19
#define LSM6DS3_ADDR 0x6A #define LSM6DS3_ADDR 0x6A
#define BMX160_ADDR 0x69 #define BMX160_ADDR 0x69
#define ICM20948_ADDR 0x69
#define ICM20948_ADDR_ALT 0x68
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// LED // LED
@@ -174,7 +162,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// IO Expander // IO Expander
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#define TCA9535_ADDR 0x20
#define TCA9555_ADDR 0x26 #define TCA9555_ADDR 0x26
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@@ -184,16 +171,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define GPS_THREAD_INTERVAL 200 #define GPS_THREAD_INTERVAL 200
#endif #endif
// -----------------------------------------------------------------------------
// Touchscreen
// -----------------------------------------------------------------------------
#define FT6336U_ADDR 0x48
// -----------------------------------------------------------------------------
// BIAS-T Generator
// -----------------------------------------------------------------------------
#define TPS65233_ADDR 0x60
// convert 24-bit color to 16-bit (56K) // convert 24-bit color to 16-bit (56K)
#define COLOR565(r, g, b) (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3)) #define COLOR565(r, g, b) (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3))
@@ -207,9 +184,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef GPS_BAUDRATE #ifndef GPS_BAUDRATE
#define GPS_BAUDRATE 9600 #define GPS_BAUDRATE 9600
#define GPS_BAUDRATE_FIXED 0
#else
#define GPS_BAUDRATE_FIXED 1
#endif #endif
/* Step #2: follow with defines common to the architecture; /* Step #2: follow with defines common to the architecture;
@@ -228,16 +202,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define MINIMUM_SAFE_FREE_HEAP 1500 #define MINIMUM_SAFE_FREE_HEAP 1500
#endif #endif
#ifndef WIRE_INTERFACES_COUNT
// Officially an NRF52 macro
// Repurposed cross-platform to identify devices using Wire1
#if defined(I2C_SDA1) || defined(PIN_WIRE1_SDA)
#define WIRE_INTERFACES_COUNT 2
#elif HAS_WIRE
#define WIRE_INTERFACES_COUNT 1
#endif
#endif
/* Step #3: mop up with disabled values for HAS_ options not handled by the above two */ /* Step #3: mop up with disabled values for HAS_ options not handled by the above two */
#ifndef HAS_WIFI #ifndef HAS_WIFI
@@ -360,4 +324,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#endif #endif
#include "DebugConfiguration.h" #include "DebugConfiguration.h"
#include "RF95Configuration.h" #include "RF95Configuration.h"

View File

@@ -10,8 +10,7 @@ enum LoRaRadioType {
LLCC68_RADIO, LLCC68_RADIO,
SX1280_RADIO, SX1280_RADIO,
LR1110_RADIO, LR1110_RADIO,
LR1120_RADIO, LR1120_RADIO
LR1121_RADIO
}; };
extern LoRaRadioType radioType; extern LoRaRadioType radioType;

View File

@@ -31,14 +31,14 @@ ScanI2C::FoundDevice ScanI2C::firstRTC() const
ScanI2C::FoundDevice ScanI2C::firstKeyboard() const ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
{ {
ScanI2C::DeviceType types[] = {CARDKB, TDECKKB, BBQ10KB, RAK14004, MPR121KB}; ScanI2C::DeviceType types[] = {CARDKB, TDECKKB, BBQ10KB, RAK14004};
return firstOfOrNONE(5, types); return firstOfOrNONE(4, types);
} }
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
{ {
ScanI2C::DeviceType types[] = {MPU6050, LIS3DH, BMA423, LSM6DS3, BMX160, STK8BAXX, ICM20948, QMA6100P}; ScanI2C::DeviceType types[] = {MPU6050, LIS3DH, BMA423, LSM6DS3, BMX160};
return firstOfOrNONE(8, types); return firstOfOrNONE(5, types);
} }
ScanI2C::FoundDevice ScanI2C::find(ScanI2C::DeviceType) const ScanI2C::FoundDevice ScanI2C::find(ScanI2C::DeviceType) const

View File

@@ -28,7 +28,6 @@ class ScanI2C
INA260, INA260,
INA219, INA219,
INA3221, INA3221,
MAX17048,
MCP9808, MCP9808,
SHT31, SHT31,
SHT4X, SHT4X,
@@ -37,15 +36,12 @@ class ScanI2C
QMC6310, QMC6310,
QMI8658, QMI8658,
QMC5883L, QMC5883L,
HMC5883L,
PMSA0031, PMSA0031,
QMA6100P,
MPU6050, MPU6050,
LIS3DH, LIS3DH,
BMA423, BMA423,
BQ24295, BQ24295,
LSM6DS3, LSM6DS3,
TCA9535,
TCA9555, TCA9555,
VEML7700, VEML7700,
RCWL9620, RCWL9620,
@@ -53,17 +49,11 @@ class ScanI2C
TSL2591, TSL2591,
OPT3001, OPT3001,
MLX90632, MLX90632,
MLX90614,
AHT10, AHT10,
BMX160, BMX160,
DFROBOT_LARK, DFROBOT_LARK,
NAU7802, NAU7802,
FT6336U, CUSTOM_SENSOR,
STK8BAXX,
ICM20948,
MAX30102,
TPS65233,
MPR121KB
} DeviceType; } DeviceType;
// typedef uint8_t DeviceAddress; // typedef uint8_t DeviceAddress;
@@ -74,9 +64,8 @@ class ScanI2C
} I2CPort; } I2CPort;
typedef struct DeviceAddress { typedef struct DeviceAddress {
// set default values for ADDRESS_NONE I2CPort port;
I2CPort port = I2CPort::NO_I2C; uint8_t address;
uint8_t address = 0;
explicit DeviceAddress(I2CPort port, uint8_t address); explicit DeviceAddress(I2CPort port, uint8_t address);
DeviceAddress(); DeviceAddress();

View File

@@ -7,8 +7,8 @@
#include "linux/LinuxHardwareI2C.h" #include "linux/LinuxHardwareI2C.h"
#endif #endif
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
#include "main.h" // atecc #include "I2CDefinitions.h"
#include "meshUtils.h" // vformat #include "main.h" // atecc
#endif #endif
// AXP192 and AXP2101 have the same device address, we just need to identify it in Power.cpp // AXP192 and AXP2101 have the same device address, we just need to identify it in Power.cpp
@@ -72,15 +72,15 @@ ScanI2C::DeviceType ScanI2CTwoWire::probeOLED(ScanI2C::DeviceAddress addr) const
r &= 0x0f; r &= 0x0f;
if (r == 0x08 || r == 0x00) { if (r == 0x08 || r == 0x00) {
LOG_INFO("sh1106 display found"); LOG_INFO("sh1106 display found\n");
o_probe = SCREEN_SH1106; // SH1106 o_probe = SCREEN_SH1106; // SH1106
} else if (r == 0x03 || r == 0x04 || r == 0x06 || r == 0x07) { } else if (r == 0x03 || r == 0x04 || r == 0x06 || r == 0x07) {
LOG_INFO("ssd1306 display found"); LOG_INFO("ssd1306 display found\n");
o_probe = SCREEN_SSD1306; // SSD1306 o_probe = SCREEN_SSD1306; // SSD1306
} }
c++; c++;
} while ((r != r_prev) && (c < 4)); } while ((r != r_prev) && (c < 4));
LOG_DEBUG("0x%x subtype probed in %i tries ", r, c); LOG_DEBUG("0x%x subtype probed in %i tries \n", r, c);
return o_probe; return o_probe;
} }
@@ -89,31 +89,31 @@ void ScanI2CTwoWire::printATECCInfo() const
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
atecc.readConfigZone(false); atecc.readConfigZone(false);
std::string atecc_numbers = "ATECC608B Serial Number: "; LOG_DEBUG("ATECC608B Serial Number: ");
for (int i = 0; i < 9; i++) { for (int i = 0; i < 9; i++) {
atecc_numbers += vformat("%02x", atecc.serialNumber[i]); LOG_DEBUG("%02x", atecc.serialNumber[i]);
} }
atecc_numbers += ", Rev Number: "; LOG_DEBUG(", Rev Number: ");
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
atecc_numbers += vformat("%02x", atecc.revisionNumber[i]); LOG_DEBUG("%02x", atecc.revisionNumber[i]);
} }
LOG_DEBUG(atecc_numbers.c_str()); LOG_DEBUG("\n");
LOG_DEBUG("ATECC608B Config %s, Data %s, Slot 0 %s", atecc.configLockStatus ? "Locked" : "Unlocked", LOG_DEBUG("ATECC608B Config %s", atecc.configLockStatus ? "Locked" : "Unlocked");
atecc.dataOTPLockStatus ? "Locked" : "Unlocked", atecc.slot0LockStatus ? "Locked" : "Unlocked"); LOG_DEBUG(", Data %s", atecc.dataOTPLockStatus ? "Locked" : "Unlocked");
LOG_DEBUG(", Slot 0 %s\n", atecc.slot0LockStatus ? "Locked" : "Unlocked");
std::string atecc_publickey = "";
if (atecc.configLockStatus && atecc.dataOTPLockStatus && atecc.slot0LockStatus) { if (atecc.configLockStatus && atecc.dataOTPLockStatus && atecc.slot0LockStatus) {
if (atecc.generatePublicKey() == false) { if (atecc.generatePublicKey() == false) {
atecc_publickey += "ATECC608B Error generating public key"; LOG_DEBUG("ATECC608B Error generating public key\n");
} else { } else {
atecc_publickey += "ATECC608B Public Key: "; LOG_DEBUG("ATECC608B Public Key: ");
for (int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
atecc_publickey += vformat("%02x", atecc.publicKey64Bytes[i]); LOG_DEBUG("%02x", atecc.publicKey64Bytes[i]);
} }
LOG_DEBUG("\n");
} }
LOG_DEBUG(atecc_publickey.c_str());
} }
#endif #endif
} }
@@ -129,7 +129,7 @@ uint16_t ScanI2CTwoWire::getRegisterValue(const ScanI2CTwoWire::RegisterLocation
i2cBus->endTransmission(); i2cBus->endTransmission();
delay(20); delay(20);
i2cBus->requestFrom(registerLocation.i2cAddress.address, responseWidth); i2cBus->requestFrom(registerLocation.i2cAddress.address, responseWidth);
LOG_DEBUG("Wire.available() = %d", i2cBus->available()); LOG_DEBUG("Wire.available() = %d\n", i2cBus->available());
if (i2cBus->available() == 2) { if (i2cBus->available() == 2) {
// Read MSB, then LSB // Read MSB, then LSB
value = (uint16_t)i2cBus->read() << 8; value = (uint16_t)i2cBus->read() << 8;
@@ -150,7 +150,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
{ {
concurrency::LockGuard guard((concurrency::Lock *)&lock); concurrency::LockGuard guard((concurrency::Lock *)&lock);
LOG_DEBUG("Scanning for I2C devices on port %d", port); LOG_DEBUG("Scanning for I2C devices on port %d\n", port);
uint8_t err; uint8_t err;
@@ -163,30 +163,21 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
Melopero_RV3028 rtc; Melopero_RV3028 rtc;
#endif #endif
#if WIRE_INTERFACES_COUNT == 2 #ifdef I2C_SDA1
if (port == I2CPort::WIRE1) { if (port == I2CPort::WIRE1) {
i2cBus = &Wire1; i2cBus = &Wire1;
} else { } else {
#endif #endif
i2cBus = &Wire; i2cBus = &Wire;
#if WIRE_INTERFACES_COUNT == 2 #ifdef I2C_SDA1
} }
#endif #endif
// We only need to scan 112 addresses, the rest is reserved for special purposes for (addr.address = 1; addr.address < 127; addr.address++) {
// 0x00 General Call
// 0x01 CBUS addresses
// 0x02 Reserved for different bus formats
// 0x03 Reserved for future purposes
// 0x04-0x07 High Speed Master Code
// 0x78-0x7B 10-bit slave addressing
// 0x7C-0x7F Reserved for future purposes
for (addr.address = 8; addr.address < 120; addr.address++) {
if (asize != 0) { if (asize != 0) {
if (!in_array(address, asize, addr.address)) if (!in_array(address, asize, addr.address))
continue; continue;
LOG_DEBUG("Scanning address 0x%x", addr.address); LOG_DEBUG("Scanning address 0x%x\n", addr.address);
} }
i2cBus->beginTransmission(addr.address); i2cBus->beginTransmission(addr.address);
#ifdef ARCH_PORTDUINO #ifdef ARCH_PORTDUINO
@@ -199,7 +190,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
#endif #endif
type = NONE; type = NONE;
if (err == 0) { if (err == 0) {
LOG_DEBUG("I2C device found at address 0x%x", addr.address); LOG_DEBUG("I2C device found at address 0x%x\n", addr.address);
switch (addr.address) { switch (addr.address) {
case SSD1306_ADDRESS: case SSD1306_ADDRESS:
@@ -215,9 +206,9 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
#endif #endif
{ {
LOG_INFO("ATECC608B initialized"); LOG_INFO("ATECC608B initialized\n");
} else { } else {
LOG_WARN("ATECC608B initialization failed"); LOG_WARN("ATECC608B initialization failed\n");
} }
printATECCInfo(); printATECCInfo();
break; break;
@@ -227,7 +218,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
case RV3028_RTC: case RV3028_RTC:
// foundDevices[addr] = RTC_RV3028; // foundDevices[addr] = RTC_RV3028;
type = RTC_RV3028; type = RTC_RV3028;
LOG_INFO("RV3028 RTC found"); LOG_INFO("RV3028 RTC found\n");
rtc.initI2C(*i2cBus); rtc.initI2C(*i2cBus);
rtc.writeToRegister(0x35, 0x07); // no Clkout rtc.writeToRegister(0x35, 0x07); // no Clkout
rtc.writeToRegister(0x37, 0xB4); rtc.writeToRegister(0x37, 0xB4);
@@ -235,7 +226,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
#endif #endif
#ifdef PCF8563_RTC #ifdef PCF8563_RTC
SCAN_SIMPLE_CASE(PCF8563_RTC, RTC_PCF8563, "PCF8563 RTC found") SCAN_SIMPLE_CASE(PCF8563_RTC, RTC_PCF8563, "PCF8563 RTC found\n")
#endif #endif
case CARDKB_ADDR: case CARDKB_ADDR:
@@ -243,50 +234,49 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x04), 1); registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x04), 1);
if (registerValue == 0x02) { if (registerValue == 0x02) {
// KEYPAD_VERSION // KEYPAD_VERSION
LOG_INFO("RAK14004 found"); LOG_INFO("RAK14004 found\n");
type = RAK14004; type = RAK14004;
} else { } else {
LOG_INFO("m5 cardKB found"); LOG_INFO("m5 cardKB found\n");
type = CARDKB; type = CARDKB;
} }
break; break;
SCAN_SIMPLE_CASE(TDECK_KB_ADDR, TDECKKB, "T-Deck keyboard found"); SCAN_SIMPLE_CASE(TDECK_KB_ADDR, TDECKKB, "T-Deck keyboard found\n");
SCAN_SIMPLE_CASE(BBQ10_KB_ADDR, BBQ10KB, "BB Q10 keyboard found"); SCAN_SIMPLE_CASE(BBQ10_KB_ADDR, BBQ10KB, "BB Q10 keyboard found\n");
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found\n");
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found");
#ifdef HAS_NCP5623 #ifdef HAS_NCP5623
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623 RGB LED found"); SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623 RGB LED found\n");
#endif #endif
#ifdef HAS_PMU #ifdef HAS_PMU
SCAN_SIMPLE_CASE(XPOWERS_AXP192_AXP2101_ADDRESS, PMU_AXP192_AXP2101, "axp192/axp2101 PMU found") SCAN_SIMPLE_CASE(XPOWERS_AXP192_AXP2101_ADDRESS, PMU_AXP192_AXP2101, "axp192/axp2101 PMU found\n")
#endif #endif
case BME_ADDR: case BME_ADDR:
case BME_ADDR_ALTERNATE: case BME_ADDR_ALTERNATE:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xD0), 1); // GET_ID registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xD0), 1); // GET_ID
switch (registerValue) { switch (registerValue) {
case 0x61: case 0x61:
LOG_INFO("BME-680 sensor found at address 0x%x", (uint8_t)addr.address); LOG_INFO("BME-680 sensor found at address 0x%x\n", (uint8_t)addr.address);
type = BME_680; type = BME_680;
break; break;
case 0x60: case 0x60:
LOG_INFO("BME-280 sensor found at address 0x%x", (uint8_t)addr.address); LOG_INFO("BME-280 sensor found at address 0x%x\n", (uint8_t)addr.address);
type = BME_280; type = BME_280;
break; break;
case 0x55: case 0x55:
LOG_INFO("BMP-085 or BMP-180 sensor found at address 0x%x", (uint8_t)addr.address); LOG_INFO("BMP-085 or BMP-180 sensor found at address 0x%x\n", (uint8_t)addr.address);
type = BMP_085; type = BMP_085;
break; break;
default: default:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1); // GET_ID registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1); // GET_ID
switch (registerValue) { switch (registerValue) {
case 0x50: // BMP-388 should be 0x50 case 0x50: // BMP-388 should be 0x50
LOG_INFO("BMP-388 sensor found at address 0x%x", (uint8_t)addr.address); LOG_INFO("BMP-388 sensor found at address 0x%x\n", (uint8_t)addr.address);
type = BMP_3XX; type = BMP_3XX;
break; break;
case 0x58: // BMP-280 should be 0x58 case 0x58: // BMP-280 should be 0x58
default: default:
LOG_INFO("BMP-280 sensor found at address 0x%x", (uint8_t)addr.address); LOG_INFO("BMP-280 sensor found at address 0x%x\n", (uint8_t)addr.address);
type = BMP_280; type = BMP_280;
break; break;
} }
@@ -295,7 +285,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
break; break;
#ifndef HAS_NCP5623 #ifndef HAS_NCP5623
case AHT10_ADDR: case AHT10_ADDR:
LOG_INFO("AHT10 sensor found at address 0x%x", (uint8_t)addr.address); LOG_INFO("AHT10 sensor found at address 0x%x\n", (uint8_t)addr.address);
type = AHT10; type = AHT10;
break; break;
#endif #endif
@@ -303,161 +293,98 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
case INA_ADDR_ALTERNATE: case INA_ADDR_ALTERNATE:
case INA_ADDR_WAVESHARE_UPS: case INA_ADDR_WAVESHARE_UPS:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2); registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
LOG_DEBUG("Register MFG_UID: 0x%x", registerValue); LOG_DEBUG("Register MFG_UID: 0x%x\n", registerValue);
if (registerValue == 0x5449) { if (registerValue == 0x5449) {
LOG_INFO("INA260 sensor found at address 0x%x", (uint8_t)addr.address); LOG_INFO("INA260 sensor found at address 0x%x\n", (uint8_t)addr.address);
type = INA260; type = INA260;
} else { // Assume INA219 if INA260 ID is not found } else { // Assume INA219 if INA260 ID is not found
LOG_INFO("INA219 sensor found at address 0x%x", (uint8_t)addr.address); LOG_INFO("INA219 sensor found at address 0x%x\n", (uint8_t)addr.address);
type = INA219; type = INA219;
} }
break; break;
case INA3221_ADDR: case INA3221_ADDR:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2); registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
LOG_DEBUG("Register MFG_UID: 0x%x", registerValue); LOG_DEBUG("Register MFG_UID: 0x%x\n", registerValue);
if (registerValue == 0x5449) { if (registerValue == 0x5449) {
LOG_INFO("INA3221 sensor found at address 0x%x", (uint8_t)addr.address); LOG_INFO("INA3221 sensor found at address 0x%x\n", (uint8_t)addr.address);
type = INA3221; type = INA3221;
} else { } else {
LOG_INFO("DFRobot Lark weather station found at address 0x%x", (uint8_t)addr.address); LOG_INFO("DFRobot Lark weather station found at address 0x%x\n", (uint8_t)addr.address);
type = DFROBOT_LARK; type = DFROBOT_LARK;
} }
break; break;
case MCP9808_ADDR: case MCP9808_ADDR:
// We need to check for STK8BAXX first, since register 0x07 is new data flag for the z-axis and can produce some registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2);
// weird result. and register 0x00 doesn't seems to be colliding with MCP9808 and LIS3DH chips. if (registerValue == 0x0400) {
{ type = MCP9808;
// Check register 0x00 for 0x8700 response to ID STK8BA53 chip. LOG_INFO("MCP9808 sensor found\n");
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 2); } else {
if (registerValue == 0x8700) { type = LIS3DH;
type = STK8BAXX; LOG_INFO("LIS3DH accelerometer found\n");
LOG_INFO("STK8BAXX accelerometer found");
break;
}
// Check register 0x07 for 0x0400 response to ID MCP9808 chip.
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2);
if (registerValue == 0x0400) {
type = MCP9808;
LOG_INFO("MCP9808 sensor found");
break;
}
// Check register 0x0F for 0x3300 response to ID LIS3DH chip.
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 2);
if (registerValue == 0x3300 || registerValue == 0x3333) { // RAK4631 WisBlock has LIS3DH register at 0x3333
type = LIS3DH;
LOG_INFO("LIS3DH accelerometer found");
}
break;
} }
break;
case SHT31_4x_ADDR: case SHT31_4x_ADDR:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x89), 2); registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x89), 2);
if (registerValue == 0x11a2 || registerValue == 0x11da || registerValue == 0xe9c) { if (registerValue == 0x11a2 || registerValue == 0x11da || registerValue == 0xe9c) {
type = SHT4X; type = SHT4X;
LOG_INFO("SHT4X sensor found"); LOG_INFO("SHT4X sensor found\n");
} else if (getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x7E), 2) == 0x5449) { } else if (getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x7E), 2) == 0x5449) {
type = OPT3001; type = OPT3001;
LOG_INFO("OPT3001 light sensor found"); LOG_INFO("OPT3001 light sensor found\n");
} else { } else {
type = SHT31; type = SHT31;
LOG_INFO("SHT31 sensor found"); LOG_INFO("SHT31 sensor found\n");
} }
break; break;
SCAN_SIMPLE_CASE(SHTC3_ADDR, SHTC3, "SHTC3 sensor found") SCAN_SIMPLE_CASE(SHTC3_ADDR, SHTC3, "SHTC3 sensor found\n")
case RCWL9620_ADDR: SCAN_SIMPLE_CASE(RCWL9620_ADDR, RCWL9620, "RCWL9620 sensor found\n")
// get MAX30102 PARTID
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFF), 1);
if (registerValue == 0x15) {
type = MAX30102;
LOG_INFO("MAX30102 Health sensor found");
break;
} else {
type = RCWL9620;
LOG_INFO("RCWL9620 sensor found");
}
break;
case LPS22HB_ADDR_ALT: case LPS22HB_ADDR_ALT:
SCAN_SIMPLE_CASE(LPS22HB_ADDR, LPS22HB, "LPS22HB sensor found") SCAN_SIMPLE_CASE(LPS22HB_ADDR, LPS22HB, "LPS22HB sensor found\n")
SCAN_SIMPLE_CASE(QMC6310_ADDR, QMC6310, "QMC6310 Highrate 3-Axis magnetic sensor found") SCAN_SIMPLE_CASE(QMC6310_ADDR, QMC6310, "QMC6310 Highrate 3-Axis magnetic sensor found\n")
case QMI8658_ADDR: case QMI8658_ADDR:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0A), 1); // get ID registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0A), 1); // get ID
if (registerValue == 0xC0) { if (registerValue == 0xC0) {
type = BQ24295; type = BQ24295;
LOG_INFO("BQ24295 PMU found"); LOG_INFO("BQ24295 PMU found\n");
break; break;
} }
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 1); // get ID registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 1); // get ID
if (registerValue == 0x6A) { if (registerValue == 0x6A) {
type = LSM6DS3; type = LSM6DS3;
LOG_INFO("LSM6DS3 accelerometer found at address 0x%x", (uint8_t)addr.address); LOG_INFO("LSM6DS3 accelerometer found at address 0x%x\n", (uint8_t)addr.address);
} else { } else {
type = QMI8658; type = QMI8658;
LOG_INFO("QMI8658 Highrate 6-Axis inertial measurement sensor found"); LOG_INFO("QMI8658 Highrate 6-Axis inertial measurement sensor found\n");
} }
break; break;
SCAN_SIMPLE_CASE(QMC5883L_ADDR, QMC5883L, "QMC5883L Highrate 3-Axis magnetic sensor found") SCAN_SIMPLE_CASE(QMC5883L_ADDR, QMC5883L, "QMC5883L Highrate 3-Axis magnetic sensor found\n")
SCAN_SIMPLE_CASE(HMC5883L_ADDR, HMC5883L, "HMC5883L 3-Axis digital compass found")
#ifdef HAS_QMA6100P
SCAN_SIMPLE_CASE(QMA6100P_ADDR, QMA6100P, "QMA6100P accelerometer found")
#else
SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031 air quality sensor found")
#endif
SCAN_SIMPLE_CASE(BMA423_ADDR, BMA423, "BMA423 accelerometer found");
SCAN_SIMPLE_CASE(LSM6DS3_ADDR, LSM6DS3, "LSM6DS3 accelerometer found at address 0x%x", (uint8_t)addr.address);
SCAN_SIMPLE_CASE(TCA9535_ADDR, TCA9535, "TCA9535 I2C expander found");
SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555 I2C expander found");
SCAN_SIMPLE_CASE(VEML7700_ADDR, VEML7700, "VEML7700 light sensor found");
SCAN_SIMPLE_CASE(TSL25911_ADDR, TSL2591, "TSL2591 light sensor found");
SCAN_SIMPLE_CASE(OPT3001_ADDR, OPT3001, "OPT3001 light sensor found");
SCAN_SIMPLE_CASE(MLX90632_ADDR, MLX90632, "MLX90632 IR temp sensor found");
SCAN_SIMPLE_CASE(NAU7802_ADDR, NAU7802, "NAU7802 based scale found");
SCAN_SIMPLE_CASE(FT6336U_ADDR, FT6336U, "FT6336U touchscreen found");
SCAN_SIMPLE_CASE(MAX1704X_ADDR, MAX17048, "MAX17048 lipo fuel gauge found");
#ifdef HAS_TPS65233
SCAN_SIMPLE_CASE(TPS65233_ADDR, TPS65233, "TPS65233 BIAS-T found");
#endif
case MLX90614_ADDR_DEF: SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031 air quality sensor found\n")
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0e), 1); SCAN_SIMPLE_CASE(MPU6050_ADDR, MPU6050, "MPU6050 accelerometer found\n");
if (registerValue == 0x5a) { SCAN_SIMPLE_CASE(BMX160_ADDR, BMX160, "BMX160 accelerometer found\n");
type = MLX90614; SCAN_SIMPLE_CASE(BMA423_ADDR, BMA423, "BMA423 accelerometer found\n");
LOG_INFO("MLX90614 IR temp sensor found"); SCAN_SIMPLE_CASE(LSM6DS3_ADDR, LSM6DS3, "LSM6DS3 accelerometer found at address 0x%x\n", (uint8_t)addr.address);
} else { SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555 I2C expander found\n");
type = MPR121KB; SCAN_SIMPLE_CASE(VEML7700_ADDR, VEML7700, "VEML7700 light sensor found\n");
LOG_INFO("MPR121KB keyboard found"); SCAN_SIMPLE_CASE(TSL25911_ADDR, TSL2591, "TSL2591 light sensor found\n");
} SCAN_SIMPLE_CASE(OPT3001_ADDR, OPT3001, "OPT3001 light sensor found\n");
break; SCAN_SIMPLE_CASE(MLX90632_ADDR, MLX90632, "MLX90632 IR temp sensor found\n");
SCAN_SIMPLE_CASE(NAU7802_ADDR, NAU7802, "NAU7802 based scale found\n");
case ICM20948_ADDR: // same as BMX160_ADDR SCAN_SIMPLE_CASE(MT_I2C_ADDRESS, CUSTOM_SENSOR, "Meshtastic custom I2C sensor found\n");
case ICM20948_ADDR_ALT: // same as MPU6050_ADDR
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1);
if (registerValue == 0xEA) {
type = ICM20948;
LOG_INFO("ICM20948 9-dof motion processor found");
break;
} else if (addr.address == BMX160_ADDR) {
type = BMX160;
LOG_INFO("BMX160 accelerometer found");
break;
} else {
type = MPU6050;
LOG_INFO("MPU6050 accelerometer found");
break;
}
break;
default: default:
LOG_INFO("Device found at address 0x%x was not able to be enumerated", addr.address); LOG_INFO("Device found at address 0x%x was not able to be enumerated\n", addr.address);
} }
} else if (err == 4) { } else if (err == 4) {
LOG_ERROR("Unknown error at address 0x%x", addr.address); LOG_ERROR("Unknown error at address 0x%x\n", addr.address);
} }
// Check if a type was found for the enumerated device - save, if so // Check if a type was found for the enumerated device - save, if so
@@ -478,7 +405,7 @@ TwoWire *ScanI2CTwoWire::fetchI2CBus(ScanI2C::DeviceAddress address) const
if (address.port == ScanI2C::I2CPort::WIRE) { if (address.port == ScanI2C::I2CPort::WIRE) {
return &Wire; return &Wire;
} else { } else {
#if WIRE_INTERFACES_COUNT == 2 #ifdef I2C_SDA1
return &Wire1; return &Wire1;
#else #else
return &Wire; return &Wire;
@@ -490,4 +417,4 @@ size_t ScanI2CTwoWire::countDevices() const
{ {
return foundDevices.size(); return foundDevices.size();
} }
#endif #endif

19
src/detect/axpDebug.h Normal file
View File

@@ -0,0 +1,19 @@
#if 0
// Turn off for now
uint32_t axpDebugRead()
{
axp.debugCharging();
LOG_DEBUG("vbus current %f\n", axp.getVbusCurrent());
LOG_DEBUG("charge current %f\n", axp.getBattChargeCurrent());
LOG_DEBUG("bat voltage %f\n", axp.getBattVoltage());
LOG_DEBUG("batt pct %d\n", axp.getBattPercentage());
LOG_DEBUG("is battery connected %d\n", axp.isBatteryConnect());
LOG_DEBUG("is USB connected %d\n", axp.isVBUSPlug());
LOG_DEBUG("is charging %d\n", axp.isChargeing());
return 30 * 1000;
}
Periodic axpDebugOutput(axpDebugRead);
axpDebugOutput.setup();
#endif

View File

@@ -59,9 +59,9 @@ void scanEInkDevice(void)
d_writeCommand(0x20); d_writeCommand(0x20);
eink_found = (d_waitWhileBusy(150) > 0) ? true : false; eink_found = (d_waitWhileBusy(150) > 0) ? true : false;
if (eink_found) if (eink_found)
LOG_DEBUG("EInk display found"); LOG_DEBUG("EInk display found\n");
else else
LOG_DEBUG("EInk display not found"); LOG_DEBUG("EInk display not found\n");
SPI1.end(); SPI1.end();
} }
#endif #endif

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