Compare commits

..

1 Commits

Author SHA1 Message Date
Kevin Hester
e5db458c6c fix release script 2021-05-25 08:06:59 +08:00
316 changed files with 4391 additions and 8229 deletions

View File

@@ -1,52 +1,21 @@
name: Continuous Integration (Legacy serial build) name: Continuous Integration
on: on:
# Triggers the workflow on push or pull request events but only for the master branch # Triggers the workflow on push or pull request events but only for the master branch
workflow_dispatch: push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs: jobs:
# setup:
ci-check: # runs-on: ubuntu-latest
runs-on: ubuntu-latest # steps:
steps:
# - name: Startup
- name: Checkout code # run: echo "No action setup currently needed, skipping..."
uses: actions/checkout@v2
with:
submodules: 'recursive'
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Install cppcheck
run: |
sudo apt-get install -y cppcheck
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Cache python libs
uses: actions/cache@v1
id: cache-pip # needed in if test
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip
- name: Upgrade python tools and install platformio
run: |
python -m pip install --upgrade pip
pip install -U platformio
- name: Upgrade platformio
run: |
pio upgrade
- name: Check everything
run: bin/check-all.sh
ci-build: ci-build:
# needs: setup
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@@ -54,8 +23,6 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
submodules: 'recursive' submodules: 'recursive'
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v2 uses: actions/setup-python@v2
@@ -69,6 +36,10 @@ jobs:
path: ~/.cache/pip path: ~/.cache/pip
key: ${{ runner.os }}-pip key: ${{ runner.os }}-pip
#- name: Install linux apt packages
# run: |
# sudo apt-get install -y libgpiod-dev
- name: Upgrade python tools - name: Upgrade python tools
# We actually want to run this every time # We actually want to run this every time
# if: steps.cache-pip.outputs.cache-hit != 'true' # if: steps.cache-pip.outputs.cache-hit != 'true'
@@ -87,19 +58,6 @@ jobs:
run: | run: |
pio upgrade pio upgrade
- name: Pull web ui
uses: dsaltares/fetch-gh-release-asset@master
with:
repo: "meshtastic/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
# We now run integration test before other build steps (to quickly see runtime failures) # We now run integration test before other build steps (to quickly see runtime failures)
- name: Build for native - name: Build for native
run: platformio run -e native run: platformio run -e native
@@ -110,42 +68,19 @@ jobs:
echo "Simulator started, launching python test..." echo "Simulator started, launching python test..."
python3 -c 'from meshtastic.test import testSimulator; testSimulator()' python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
- name: Cat bin/build-all.sh # - name: Build for tbeam
run: | # run: platformio run -e tbeam
cat bin/build-all.sh # - name: Build for heltec
# run: platformio run -e heltec
# - name: Build for wisblock RAK4631
# run: platformio run -e rak4631
- name: Build everything - name: Build everything
run: bin/build-all.sh run: bin/build-all.sh
- name: Get release version string - name: Store release zip as an artifact
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
id: version
- name: Store binaries as an artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
name: firmware-${{ steps.version.outputs.version }}.zip name: built
path: release/archive/firmware-${{ steps.version.outputs.version }}.zip path: release/archive/firmware-*.zip
retention-days: 90 retention-days: 30
- name: Store debugging elf files as an artifact
uses: actions/upload-artifact@v2
with:
name: debug-elfs
path: release/archive/elfs-*.zip
retention-days: 7
- name: Download firmware.zip
uses: actions/download-artifact@master
with:
name: firmware-${{ steps.version.outputs.version }}.zip
path: ./
- name: Pull request artifacts
if: ${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request' }}
uses: gavv/pull-request-artifacts@v1.0.0
with:
commit: ${{ (github.event.pull_request_target || github.event.pull_request).head.sha }}
repo-token: ${{ secrets.GITHUB_TOKEN }}
artifacts-branch: artifacts
artifacts: ./firmware-${{ steps.version.outputs.version }}.zip

View File

@@ -1,342 +0,0 @@
name: Continuous Integration PR Checks (1.2 Legacy)
on:
# # Triggers the workflow on push but only for the master branch
push:
branches: [ 1.2-legacy ]
paths-ignore:
- '**.md'
- '**.yml'
- 'version.properties'
# Note: This is different from "pull_request". Need to specify ref when doing checkouts.
pull_request_target:
branches: [ 1.2-legacy ]
paths-ignore:
- '**.md'
- '**.yml'
workflow_dispatch:
jobs:
check:
strategy:
fail-fast: false
matrix:
include:
- board: rak11200
- board: tlora-v2
- board: tlora-v1
- board: tlora_v1_3
- board: tlora-v2-1-1.6
- board: tbeam
- board: heltec-v1
- board: heltec-v2.0
- board: heltec-v2.1
- board: tbeam0.7
- board: meshtastic-diy-v1
- board: rak4631_5005
- board: rak4631_19003
- board: t-echo
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
submodules: 'recursive'
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Install cppcheck
run: |
sudo apt-get install -y cppcheck
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Cache python libs
uses: actions/cache@v1
id: cache-pip # needed in if test
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip
- name: Upgrade python tools and install platformio
run: |
python -m pip install --upgrade pip
pip install -U platformio
- name: Upgrade platformio
run: |
pio upgrade
- name: Check ${{ matrix.board }}
run: bin/check-all.sh ${{ matrix.board }}
after-checks:
runs-on: ubuntu-latest
needs: [check]
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
build-esp32:
strategy:
fail-fast: false
matrix:
include:
- board: rak11200
- board: tlora-v2
- board: tlora-v1
- board: tlora_v1_3
- board: tlora-v2-1-1.6
- board: tbeam
- board: heltec-v1
- board: heltec-v2.0
- board: heltec-v2.1
- board: tbeam0.7
- board: meshtastic-diy-v1
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
submodules: 'recursive'
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Cache python libs
uses: actions/cache@v1
id: cache-pip # needed in if test
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip
- name: Upgrade python tools
run: |
python -m pip install --upgrade pip
pip install -U platformio meshtastic adafruit-nrfutil
- name: Upgrade platformio
run: |
pio upgrade
- name: Pull web ui
uses: dsaltares/fetch-gh-release-asset@master
with:
repo: "meshtastic/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: Build ESP32
run: bin/build-esp32.sh ${{ matrix.board }}
- name: Get release version string
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
id: version
- name: Store binaries as an artifact
uses: actions/upload-artifact@v2
with:
name: firmware-${{ matrix.board }}-${{ steps.version.outputs.version }}.zip
path: |
release/*.bin
release/*.elf
retention-days: 90
build-nrf52:
strategy:
fail-fast: false
matrix:
include:
- board: rak4631_5005
- board: rak4631_19003
- board: t-echo
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
submodules: 'recursive'
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Cache python libs
uses: actions/cache@v1
id: cache-pip # needed in if test
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip
- name: Upgrade python tools
run: |
python -m pip install --upgrade pip
pip install -U platformio meshtastic adafruit-nrfutil
- name: Upgrade platformio
run: |
pio upgrade
- name: Build NRF52
run: bin/build-nrf52.sh ${{ matrix.board }}
- name: Get release version string
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
id: version
- name: Store binaries as an artifact
uses: actions/upload-artifact@v2
with:
name: firmware-${{ matrix.board }}-${{ steps.version.outputs.version }}.zip
path: |
release/*.uf2
release/*.elf
retention-days: 90
build-native:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
submodules: 'recursive'
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Cache python libs
uses: actions/cache@v1
id: cache-pip # needed in if test
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip
- name: Upgrade python tools
run: |
python -m pip install --upgrade pip
pip install -U platformio meshtastic adafruit-nrfutil
- name: Upgrade platformio
run: |
pio upgrade
# We now run integration test before other build steps (to quickly see runtime failures)
- name: Build for native
run: platformio run -e native
- name: Integration test
run: |
.pio/build/native/program &
sleep 20 # 5 seconds was not enough
echo "Simulator started, launching python test..."
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
- name: Build Native
run: bin/build-native.sh
- name: Get release version string
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
id: version
- name: Store binaries as an artifact
uses: actions/upload-artifact@v2
with:
name: firmware-native-${{ steps.version.outputs.version }}.zip
path: |
release/meshtasticd_linux_amd64
release/device-*.sh
release/device-*.bat
retention-days: 90
gather-artifacts:
runs-on: ubuntu-latest
needs: [build-esp32, build-nrf52, build-native]
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- uses: actions/download-artifact@v2
with:
path: ./
- name: Get release version string
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
id: version
- name: Move files up
run: mv -b -t ./ ./*tbeam-*/spiffs*.bin ./*tbeam-*/system-info.bin ./**/firmware*.bin ./**/*.uf2 ./**/*.elf ./**/meshtasticd_linux_amd64 ./*native*/*device-*.sh ./*native*/*device-*.bat
- name: Repackage in single firmware zip
uses: actions/upload-artifact@v2
with:
name: firmware-${{ steps.version.outputs.version }}
path: |
./*.bin
./*.uf2
./meshtasticd_linux_amd64
./device-*.sh
./device-*.bat
retention-days: 90
- uses: actions/download-artifact@v2
with:
name: firmware-${{ steps.version.outputs.version }}
path: ./output
# For diagnostics
- name: Show artifacts
run: ls -lR
- name: Zip firmware
run: zip -j -r ./firmware-${{ steps.version.outputs.version }}.zip ./output
- name: Repackage in single elfs zip
uses: actions/upload-artifact@v2
with:
name: debug-elfs-${{ steps.version.outputs.version }}.zip
path: ./*.elf
retention-days: 90
- name: Create request artifacts
if: ${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request' }}
uses: gavv/pull-request-artifacts@v1.0.0
with:
commit: ${{ (github.event.pull_request_target || github.event.pull_request).head.sha }}
repo-token: ${{ secrets.GITHUB_TOKEN }}
artifacts-branch: artifacts
artifacts: ./firmware-${{ steps.version.outputs.version }}.zip

View File

@@ -1,15 +1,15 @@
name: Make Release name: Make Release
on: on:
# Can optionally take parameters from the github UI, more info here https://github.blog/changelog/2020-07-06-github-actions-manual-triggers-with-workflow_dispatch/#:~:text=You%20can%20now%20create%20workflows,the%20workflow%20is%20run%20on. # Can optionally take parameters from the github UI, more info here https://github.blog/changelog/2020-07-06-github-actions-manual-triggers-with-workflow_dispatch/#:~:text=You%20can%20now%20create%20workflows,the%20workflow%20is%20run%20on.
#workflow_dispatch: # workflow_dispatch:
# inputs: # inputs:
# Only want to run if version.properties is bumped in master # Only want to be run if a new tag starting with v is pushed.
push: push:
branches: branches:
- 1.2-legacy - "!*"
paths: tags:
- 'version.properties' - "v1*"
jobs: jobs:
release-build: release-build:
@@ -21,15 +21,19 @@ jobs:
with: with:
submodules: 'recursive' submodules: 'recursive'
# get github branch and tag names as ${{ steps.branch_name.outputs.SOURCE_TAG }}
- name: Branch name
id: branch_name
run: |
echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/}
echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/}
echo ::set-output name=SOURCE_TAG::${GITHUB_REF#refs/tags/}
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v2 uses: actions/setup-python@v2
with: with:
python-version: 3.x python-version: 3.x
# Will be available in steps.version.outputs.version
- name: Get release version string
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
id: version
# Note: we don't use caches on release builds because we don't want to accidentally not have a virgin build machine # Note: we don't use caches on release builds because we don't want to accidentally not have a virgin build machine
- name: Upgrade python tools - name: Upgrade python tools
@@ -43,18 +47,10 @@ jobs:
run: | run: |
pio upgrade pio upgrade
- name: Pull web ui # Will be available in steps.version.outputs.version
uses: dsaltares/fetch-gh-release-asset@master - name: Get version string
with: run: echo "::set-output name=version::$(./bin/buildinfo.py)"
repo: "meshtastic/meshtastic-web" id: version
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: Build everything - name: Build everything
run: bin/build-all.sh run: bin/build-all.sh
@@ -66,13 +62,14 @@ jobs:
draft: true draft: true
prerelease: true prerelease: true
release_name: ${{ steps.version.outputs.version }} alpha release_name: ${{ steps.version.outputs.version }} alpha
tag_name: v${{ steps.version.outputs.version }} tag_name: ${{ steps.branch_name.outputs.SOURCE_TAG }}
# was ${{ github.ref }}
body: | body: |
Autogenerated by github action, developer should edit as required before publishing... Autogenerated by github action, developer should edit as required before publishing...
env: env:
GITHUB_TOKEN: ${{ github.token }} GITHUB_TOKEN: ${{ github.token }}
- name: Add bins to release - name: Add artifact to release
uses: actions/upload-release-asset@v1 uses: actions/upload-release-asset@v1
env: env:
GITHUB_TOKEN: ${{ github.token }} GITHUB_TOKEN: ${{ github.token }}
@@ -80,14 +77,4 @@ jobs:
upload_url: ${{ steps.create_release.outputs.upload_url }} upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: release/archive/firmware-${{ steps.version.outputs.version }}.zip asset_path: release/archive/firmware-${{ steps.version.outputs.version }}.zip
asset_name: firmware-${{ steps.version.outputs.version }}.zip asset_name: firmware-${{ steps.version.outputs.version }}.zip
asset_content_type: application/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: ${{ steps.create_release.outputs.upload_url }}
asset_path: release/archive/elfs-${{ steps.version.outputs.version }}.zip
asset_name: debug-elfs-${{ steps.version.outputs.version }}.zip
asset_content_type: application/zip

View File

@@ -1,33 +0,0 @@
name: "Update protobufs and regenerate classes"
on: workflow_dispatch
jobs:
update-protobufs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
submodules: true
- name: Update submodule
run: |
git submodule update --remote proto
- name: Download nanopb
run: |
wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.4-linux-x86.tar.gz
tar xvzf nanopb-0.4.4-linux-x86.tar.gz
mv nanopb-0.4.4-linux-x86 nanopb-0.4.4
- name: Re-generate protocol buffers
run: |
./bin/regen-protos.sh
- name: Create pull request
uses: peter-evans/create-pull-request@v3
with:
add-paths: |
proto
src/mesh

8
.gitignore vendored
View File

@@ -9,7 +9,7 @@ main/credentials.h
!.vscode/extensions.json !.vscode/extensions.json
*.code-workspace *.code-workspace
.idea .idea/workspace.xml
.DS_Store .DS_Store
Thumbs.db Thumbs.db
@@ -23,9 +23,3 @@ flash.uf2
cmake-build* cmake-build*
__pycache__ __pycache__
*.swp
*.swo
*~
venv/
release/

View File

@@ -1,50 +0,0 @@
image: python:latest
variables:
# make sure GitLab check out submodules
GIT_SUBMODULE_STRATEGY: recursive
stages:
- buildall
- upload
build:
stage: buildall
before_script:
# we need zip later for packaging
- "apt update;apt -y install zip"
- "pip install -U platformio"
script:
# clean up residues from previous run
- rm -rf release
- bin/build-all.sh
# This is for my local environment, if your runners are tagged differently, modify or remove
tags:
- dockerized
# The files which are to be made available in GitLab
artifacts:
paths:
- release/archive/firmware*.zip
upload:
image: curlimages/curl:latest
stage: upload
script:
- |
PACKAGE_REGISTRY_URL="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${CI_PROJECT_NAME}/master"
cd release/archive
for f in *.zip; do
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file ${f} ${PACKAGE_REGISTRY_URL}/${f}
done
echo 'Package uploaded!'
# This is for my local environment, if your runners are tagged differently, modify or remove
tags:
- dockerized

7
.idea/codeStyles/Project.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<clangFormatSettings>
<option name="ENABLED" value="true" />
</clangFormatSettings>
</code_scheme>
</component>

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

2
.idea/meshtastic-esp32.iml generated Normal file
View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" />

4
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
</project>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/meshtastic-esp32.iml" filepath="$PROJECT_DIR$/.idea/meshtastic-esp32.iml" />
</modules>
</component>
</project>

9
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/design" vcs="Git" />
<mapping directory="$PROJECT_DIR$/proto" vcs="Git" />
<mapping directory="$PROJECT_DIR$/sdk-nrfxlib" vcs="Git" />
</component>
</project>

View File

@@ -50,8 +50,7 @@
"cassert": "cpp", "cassert": "cpp",
"iterator": "cpp", "iterator": "cpp",
"shared_mutex": "cpp", "shared_mutex": "cpp",
"iostream": "cpp", "iostream": "cpp"
"esp_nimble_hci.h": "c"
}, },
"cSpell.words": [ "cSpell.words": [
"Blox", "Blox",

View File

@@ -1,16 +0,0 @@
FROM ubuntu
MAINTAINER Kevin Hester <kevinh@geeksville.com>
RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install wget python3 g++ zip python3-venv git vim
RUN wget https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py -O get-platformio.py; chmod +x get-platformio.py
RUN python3 get-platformio.py
RUN git clone https://github.com/meshtastic/Meshtastic-device.git
RUN cd Meshtastic-device; git submodule update --init --recursive
# only build the simulator
RUN sed -i 's/^BOARDS_ESP32.*/BOARDS_ESP32=""/' Meshtastic-device/bin/build-all.sh
RUN sed -i 's/^BOARDS_NRF52.*/BOARDS_NRF52=""/' Meshtastic-device/bin/build-all.sh
RUN sed -i 's/echo "Building SPIFFS.*/exit/' Meshtastic-device/bin/build-all.sh
RUN . ~/.platformio/penv/bin/activate; cd Meshtastic-device; ./bin/build-all.sh
CMD ["/Meshtastic-device/release/latest/bins/universal/meshtasticd_linux_amd64"]

215
README.md
View File

@@ -1,14 +1,213 @@
# Meshtastic-device # Meshtastic-device
[![Open in Visual Studio Code](https://open.vscode.dev/badges/open-in-vscode.svg)](https://open.vscode.dev/meshtastic/Meshtastic-device)
[![Continuous Integration](https://github.com/meshtastic/Meshtastic-device/actions/workflows/main.yml/badge.svg)](https://github.com/meshtastic/Meshtastic-device/actions/workflows/main.yml)
![GitHub all releases](https://img.shields.io/github/downloads/meshtastic/meshtastic-device/total)
## This repository contains the device firmware used in the [Meshtastic](https://meshtastic.org) project. This is the device side code for the [meshtastic.org](https://www.meshtastic.org) project.
Update Instructions ![Continuous Integration](https://github.com/meshtastic/Meshtastic-esp32/workflows/Continuous%20Integration/badge.svg)
[For ESP32 devices click here](https://meshtastic.org/docs/getting-started/flashing-esp32) Meshtastic® is a project that lets you use
inexpensive GPS mesh radios as an extensible, super long battery life mesh GPS communicator. These radios are great for hiking, skiing, paragliding -
essentially any hobby where you don't have reliable internet access. Each member of your private mesh can always see the location and distance of all other
members and any text messages sent to your group chat.
[For nRF52 devices click here](https://meshtastic.org/docs/getting-started/flashing-nrf52) The radios automatically create a mesh to forward packets as needed, so everyone in the group can receive messages from even the furthest member. The radios
will optionally work with your phone, but no phone is required.
For developer information and specific building instructions, please see the [developer doccumentation](https://meshtastic.org/docs/developers) Typical time between recharging the radios should be about eight days.
This project is is currently in beta-testing - if you have questions please [join our discussion forum](https://meshtastic.discourse.group/).
This software is 100% open source and developed by a group of hobbyist experimenters. No warranty is provided, if you'd like to improve it - we'd love your help. Please post in the chat.
## Supported hardware
We currently support three models of radios.
- TTGO T-Beam (usually the recommended choice)
- [T-Beam V1.1 w/ NEO-6M - special Meshtastic version](https://www.aliexpress.com/item/4001178678568.html) (Includes built-in OLED display and they have **preinstalled** the meshtastic software)
- [T-Beam V1.1 w/ NEO-M8N](https://www.aliexpress.com/item/33047631119.html) (slightly better GPS)
- [T-Beam V1.1 w/ NEO-M8N /w SX1262](https://www.aliexpress.com/item/4001287221970.html) (slightly better GPS + LoRa)
- board labels "TTGO T22_V1.1 20191212"
- [T-Beam V0.7 w/ NEO-6M](https://www.aliexpress.com/item/4000574335430.html) (will work but **you must use the tbeam0.7 firmware ** - but the T-Beam V1.0 or later are better!)
- board labels "TTGO T22_V07 20180711"
- 3D printable cases
- [T-Beam V0](https://www.thingiverse.com/thing:3773717) (GPS and LoRa antenna misaligned if GPS placed as pictured)
- [T-Beam V1 (SMA-antenna)](https://www.thingiverse.com/thing:3830711)
- [T-Beam V1 (SMA-antenna)](https://www.thingiverse.com/thing:4677388) (Mounting option for larger GPS antenna but LoRa antenna enclosed)
- [T-Beam V1 (IPEX-antenna)](https://www.thingiverse.com/thing:4587297) (GPS and LoRa antenna misaligned if GPS placed as pictured)
- [T-Beam V1 (IPEX-antenna)](https://www.thingiverse.com/thing:4589651)
- [T-Beam V1 (IPEX-antenna)](https://www.thingiverse.com/thing:4619981) (GPS and LoRa antenna misaligned if GPS placed as pictured)
- Laser-cut cases
- [T-Beam V1 (SMA-antenna)](https://www.thingiverse.com/thing:4552771)
- [TTGO LORA32](https://www.aliexpress.com/item/4000211331316.html) - No GPS
- version 2.1
- board labels "TTGO T3_V1.6 20180606"
- 3D printable case
- [TTGO LORA32 v1](https://www.thingiverse.com/thing:3385109)
- [Heltec LoRa 32](https://heltec.org/project/wifi-lora-32/) - No GPS
- [Official Heltec case](https://www.aliexpress.com/item/4001050707951.html)
- [3D Printable case](https://www.thingiverse.com/thing:3125854)
Note: The GPS and LoRa stock antennas should be placed in a way, that the GPS antenna faces the sky and the LoRa antenna radiates 360 degrees horizontally. For better GPS reception you might want to [upgrade the GPS antenna](https://meshtastic.discourse.group/t/the-importance-of-gps-antennas-and-request-to-3d-case-documentation-people/1505) and to properly align the antennas you might want to upgrade to a LoRa antenna that can be adjusted to radiate into the right directions.
**Make sure to get the frequency for your country**
- US/JP/AU/NZ/CA - 915MHz
- CN - 470MHz
- EU - 868MHz, 433MHz
- full list of LoRa frequencies per region is available [here](https://www.thethingsnetwork.org/docs/lorawan/frequencies-by-country.html)
Getting a version that includes a screen is optional, but highly recommended.
## Firmware Installation
Prebuilt binaries for the supported radios are available in our [releases](https://github.com/meshtastic/Meshtastic-esp32/releases). Your initial installation has to happen over USB from your Mac, Windows or Linux PC. Once our software is installed, all future software updates happen over bluetooth from your phone.
Be **very careful** to install the correct load for your board. In particular the popular 'T-BEAM' radio from TTGO is not called 'TTGO-Lora' (that is a different board). So don't install the 'TTGO-Lora' build on a TBEAM, it won't work correctly.
Please post comments on our [group chat](https://meshtastic.discourse.group/) if you have problems or successes.
### Installing from a GUI - Windows and Mac
1. Download and unzip the latest Meshtastic firmware [release](https://github.com/meshtastic/Meshtastic-esp32/releases).
2. Download [ESPHome Flasher](https://github.com/esphome/esphome-flasher/releases) (either x86-32bit Windows or x64-64 bit Windows).
3. Connect your radio to your USB port and open ESPHome Flasher.
4. If your board is not showing under Serial Port then you likely need to install the drivers for the CP210X serial chip. In Windows you can check by searching “Device Manager” and ensuring the device is shown under “Ports”.
5. If there is an error, download the drivers [here](https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers), then unzip and run the Installer application.
6. In ESPHome Flasher, refresh the serial ports and select your board.
7. Browse to the previously downloaded firmware and select the correct firmware based on the board type, country and frequency.
8. Select Flash ESP.
9. Once complete, “Done! Flashing is complete!” will be shown.
10. Debug messages sent from the Meshtastic device can be viewed with a terminal program such as [PuTTY](https://www.putty.org/) (Windows only). Within PuTTY, click “Serial”, enter the “Serial line” com port (can be found at step 4), enter “Speed” as 921600, then click “Open”.
### Installing from a commandline
These instructions currently require a few commmand lines, but it should be pretty straightforward.
1. Install "pip". Pip is the python package manager we use to get the esptool installer app. Instructions [here](https://www.makeuseof.com/tag/install-pip-for-python/). If you are using OS-X, see these [special instructions](docs/software/install-OSX.md).
2. Run "pip install --upgrade esptool" to get esptool installed on your machine.
3. Connect your radio to your USB port.
4. Confirm that your device is talking to your PC by running "esptool.py chip_id". The Heltec build also works on the TTGO LORA32 radio. You should see something like:
```
mydir$ esptool.py chip_id
esptool.py v2.6
Found 2 serial ports
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
MAC: 24:6f:28:b5:36:71
Uploading stub...
Running stub...
Stub running...
Warning: ESP32 has no Chip ID. Reading MAC instead.
MAC: 24:6f:28:b5:36:71
Hard resetting via RTS pin...
```
5. cd into the directory where the release zip file was expanded.
6. Install the correct firmware for your board with `device-install.sh -f firmware-_board_-_country_.bin`.
- Example: `./device-install.sh -f firmware-HELTEC-US-0.0.3.bin`.
7. To update run `device-update.sh -f firmware-_board_-_country_.bin`
- Example: `./device-update.sh -f firmware-HELTEC-US-0.0.3.bin`.
Note: If you have previously installed meshtastic, you don't need to run this full script instead just run `esptool.py --baud 921600 write_flash 0x10000 firmware-_board_-_country_-_version_.bin`. This will be faster, also all of your current preferences will be preserved.
You should see something like this:
```
kevinh@kevin-server:~/development/meshtastic/meshtastic-esp32/release/latest$ ./device-install.sh firmware-TBEAM-US-0.1.8.bin
Trying to flash firmware-TBEAM-US-0.1.8.bin, but first erasing and writing system information
esptool.py v2.6
Found 2 serial ports
Serial port /dev/ttyUSB0
Connecting........____
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
MAC: 24:6f:28:b2:01:6c
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Erasing flash (this may take a while)...
Chip erase completed successfully in 6.1s
Hard resetting via RTS pin...
esptool.py v2.6
Found 2 serial ports
Serial port /dev/ttyUSB0
Connecting.......
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
MAC: 24:6f:28:b2:01:6c
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...
Auto-detected Flash size: 4MB
Flash params set to 0x0220
Compressed 61440 bytes to 11950...
Wrote 61440 bytes (11950 compressed) at 0x00001000 in 0.2 seconds (effective 3092.4 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
esptool.py v2.6
Found 2 serial ports
Serial port /dev/ttyUSB0
Connecting.....
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
MAC: 24:6f:28:b2:01:6c
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 1223568 bytes to 678412...
Wrote 1223568 bytes (678412 compressed) at 0x00010000 in 10.7 seconds (effective 912.0 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
```
7. The board will boot and show the Meshtastic logo.
8. Please post a comment on our chat so we know if these instructions worked for you ;-). If you find bugs/have-questions post there also - we will be rapidly iterating over the next few weeks.
# Meshtastic Android app
The companion (optional) Meshtastic Android app is [here](https://play.google.com/store/apps/details?id=com.geeksville.mesh&referrer=utm_source%3Dgithub-dev-readme). You can also download it on Google Play.
# Python API
We offer a [python API](https://github.com/meshtastic/Meshtastic-python) that makes it easy to use these devices to provide mesh networking for your custom projects.
# Development
We'd love to have you join us on this merry little project. Please see our [development documents](https://meshtastic.org/docs/software/other/sw-design) and [join us in our discussion forum](https://meshtastic.discourse.group/).
# Credits
This project is run by volunteers. We are a friendly group and welcome any contribution (code fixes, documentation, features, bug reports etc...). We try to be good about listing contributor names in release notes, but it has become unwieldy for the main-devs to keep updating the list below and we've neglected it too long. If you'd like your name included in this list please send a pull request to edit this README and simply add your line yourself. Thank you very much for your help!
- @astro-arphid: Added support for 433MHz radios in europe.
- @claesg: Various documentation fixes and 3D print enclosures
- @girtsf: Lots of improvements
- @spattinson: Fixed interrupt handling for the AXP192 part
# IMPORTANT DISCLAIMERS AND FAQ
For a listing of currently missing features and a FAQ click [here](docs/faq.md).
Copyright 2019 Geeksville Industries, LLC. GPL V3 Licensed.

View File

@@ -1,16 +1,15 @@
#!/usr/bin/env bash #!/bin/bash
set -e set -e
VERSION=`bin/buildinfo.py long` VERSION=`bin/buildinfo.py long`
SHORT_VERSION=`bin/buildinfo.py short` SHORT_VERSION=`bin/buildinfo.py short`
BOARDS_ESP32="rak11200 tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1" BOARDS_ESP32="tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v2.0 heltec-v2.1 tbeam0.7"
#BOARDS_ESP32=tbeam #BOARDS_ESP32=tbeam
# FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine # FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine
BOARDS_NRF52="rak4631_5005 rak4631_19003 t-echo" BOARDS_NRF52="rak4631 t-echo"
#BOARDS_NRF52=""
OUTDIR=release/latest OUTDIR=release/latest
@@ -28,7 +27,7 @@ function do_build() {
BOARD=$1 BOARD=$1
isNrf=$3 isNrf=$3
echo "Building for $BOARD ($isNrf) with $PLATFORMIO_BUILD_FLAGS" echo "Building for $BOARD with $PLATFORMIO_BUILD_FLAGS"
rm -f .pio/build/$BOARD/firmware.* rm -f .pio/build/$BOARD/firmware.*
# The shell vars the build tool expects to find # The shell vars the build tool expects to find
@@ -59,7 +58,6 @@ function do_boards() {
declare isNrf=$2 declare isNrf=$2
for board in $boards; do for board in $boards; do
# Build universal # Build universal
echo "about to build $board $isNrf"
do_build $board "" "$isNrf" do_build $board "" "$isNrf"
done done
} }
@@ -73,9 +71,6 @@ platformio lib update
do_boards "$BOARDS_ESP32" "false" do_boards "$BOARDS_ESP32" "false"
do_boards "$BOARDS_NRF52" "true" do_boards "$BOARDS_NRF52" "true"
pio run --environment native
cp .pio/build/native/program $OUTDIR/bins/universal/meshtasticd_linux_amd64
echo "Building SPIFFS for ESP32 targets" echo "Building SPIFFS for ESP32 targets"
pio run --environment tbeam -t buildfs pio run --environment tbeam -t buildfs
cp .pio/build/tbeam/spiffs.bin $OUTDIR/bins/universal/spiffs-$VERSION.bin cp .pio/build/tbeam/spiffs.bin $OUTDIR/bins/universal/spiffs-$VERSION.bin
@@ -103,9 +98,6 @@ XML
echo Generating $ARCHIVEDIR/firmware-$VERSION.zip echo Generating $ARCHIVEDIR/firmware-$VERSION.zip
rm -f $ARCHIVEDIR/firmware-$VERSION.zip rm -f $ARCHIVEDIR/firmware-$VERSION.zip
zip --junk-paths $ARCHIVEDIR/firmware-$VERSION.zip $ARCHIVEDIR/spiffs-$VERSION.bin $OUTDIR/bins/universal/firmware-*-$VERSION.* $OUTDIR/bins/universal/meshtasticd* images/system-info.bin bin/device-install.* bin/device-update.* zip --junk-paths $ARCHIVEDIR/firmware-$VERSION.zip $ARCHIVEDIR/spiffs-$VERSION.bin $OUTDIR/bins/universal/firmware-*-$VERSION.* images/system-info.bin bin/device-install.sh bin/device-update.sh
echo Generating $ARCHIVEDIR/elfs-$VERSION.zip
rm -f $ARCHIVEDIR/elfs-$VERSION.zip
zip --junk-paths $ARCHIVEDIR/elfs-$VERSION.zip $OUTDIR/elfs/universal/firmware-*-$VERSION.*
echo BUILT ALL echo BUILT ALL

View File

@@ -1,43 +0,0 @@
#!/usr/bin/env bash
set -e
VERSION=`bin/buildinfo.py long`
SHORT_VERSION=`bin/buildinfo.py short`
OUTDIR=release/
rm -f $OUTDIR/firmware*
rm -r $OUTDIR/* || true
# Make sure our submodules are current
git submodule update
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
platformio lib update
echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS"
rm -f .pio/build/$1/firmware.*
# The shell vars the build tool expects to find
export APP_VERSION=$VERSION
# Are we building a universal/regionless rom?
export HW_VERSION="1.0"
basename=firmware-$1-$VERSION
pio run --environment $1 # -v
SRCELF=.pio/build/$1/firmware.elf
cp $SRCELF $OUTDIR/$basename.elf
echo "Copying ESP32 bin file"
SRCBIN=.pio/build/$1/firmware.bin
cp $SRCBIN $OUTDIR/$basename.bin
echo "Building SPIFFS for ESP32 targets"
pio run --environment tbeam -t buildfs
cp .pio/build/tbeam/spiffs.bin $OUTDIR/spiffs-$VERSION.bin
cp images/system-info.bin $OUTDIR/system-info.bin
cp bin/device-install.* $OUTDIR
cp bin/device-update.* $OUTDIR

View File

@@ -1,26 +0,0 @@
#!/usr/bin/env bash
set -e
VERSION=`bin/buildinfo.py long`
SHORT_VERSION=`bin/buildinfo.py short`
OUTDIR=release/
rm -f $OUTDIR/firmware*
mkdir -p $OUTDIR/
rm -r $OUTDIR/* || true
# Make sure our submodules are current
git submodule update
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
platformio lib update
pio run --environment native
cp .pio/build/native/program $OUTDIR/meshtasticd_linux_amd64
cp bin/device-install.* $OUTDIR
cp bin/device-update.* $OUTDIR

38
bin/build-nightly.sh Executable file
View File

@@ -0,0 +1,38 @@
#!/bin/bash
source ~/.bashrc
# Meshtastic Nightly Build Script.
# McHamster (jm@casler.org)
#
# This is the script that is used for the nightly build server.
#
# It's probably not useful for most people, but you may want to run your own
# nightly builds.
#
# The last line of ~/.bashrc contains an inclusion of platformio in the path.
# Without this, the build script won't run from the crontab:
#
# export PATH="$HOME/.platformio/penv/bin:$PATH"
#
# The crontab contains:
# 0 2 * * * cd ~/meshtastic/github/meshtastic && source "~/.bashrc"; ./build-nightly.sh > ~/cronout.txt 2> ~/cronout.txt
cd Meshtastic-device
git pull
bin/build-all.sh
date_stamp=$(date +'%Y-%m-%d')
cd ..
# TODO: Archive the same binaries used by the build-all script.
#zip -r meshtastic_device_nightly_${date_stamp} Meshtastic-device/release/latest/bins
cp Meshtastic-device/release/archive/`ls -t ./Meshtastic-device/release/archive/| head -1` meshtastic_device_nightly_${date_stamp}.zip
# Copy the file to the webserver
scp meshtastic_device_nightly_${date_stamp}.zip jm@10.11.12.20:/volume1/web/meshtastic/nightly_builds/
# Delete the local copy
rm meshtastic_device_nightly_${date_stamp}.zip

View File

@@ -1,37 +0,0 @@
#!/usr/bin/env bash
set -e
VERSION=`bin/buildinfo.py long`
SHORT_VERSION=`bin/buildinfo.py short`
OUTDIR=release/
rm -f $OUTDIR/firmware*
rm -r $OUTDIR/* || true
# Make sure our submodules are current
git submodule update
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
platformio lib update
echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS"
rm -f .pio/build/$1/firmware.*
# The shell vars the build tool expects to find
export APP_VERSION=$VERSION
export HW_VERSION="1.0"
basename=firmware-$1-$VERSION
pio run --environment $1 # -v
SRCELF=.pio/build/$1/firmware.elf
cp $SRCELF $OUTDIR/$basename.elf
echo "Generating NRF52 uf2 file"
SRCHEX=.pio/build/$1/firmware.hex
bin/uf2conv.py $SRCHEX -c -o $OUTDIR/$basename.uf2 -f 0xADA52840
cp bin/device-install.* $OUTDIR
cp bin/device-update.* $OUTDIR

View File

@@ -1,26 +0,0 @@
#!/usr/bin/env bash
# Note: This is a prototype for how we could add static code analysis to the CI.
set -e
VERSION=`bin/buildinfo.py long`
# The shell vars the build tool expects to find
export APP_VERSION=$VERSION
if [[ $# -gt 0 ]]; then
# can override which environment by passing arg
BOARDS="$@"
else
BOARDS="tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1 rak4631_5005 rak4631_19003 rak11200 t-echo"
fi
echo "BOARDS:${BOARDS}"
CHECK=""
for BOARD in $BOARDS; do
CHECK="${CHECK} -e ${BOARD}"
done
pio check --flags "-DAPP_VERSION=${APP_VERSION} --suppressions-list=suppressions.txt" $CHECK --skip-packages --pattern="src/" --fail-on-defect=low --fail-on-defect=medium --fail-on-defect=high

View File

@@ -11,7 +11,7 @@ Usage: $(basename $0) [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME|FILENAME]
Flash image file to device, but first erasing and writing system information" Flash image file to device, but first erasing and writing system information"
-h Display this help and exit -h Display this help and exit
-p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerous). -p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerrous).
-P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: "$PYTHON") -P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: "$PYTHON")
-f FILENAME The .bin file to flash. Custom to your device type and region. -f FILENAME The .bin file to flash. Custom to your device type and region.
EOF EOF
@@ -46,10 +46,10 @@ shift "$((OPTIND-1))"
if [ -f "${FILENAME}" ]; then if [ -f "${FILENAME}" ]; then
echo "Trying to flash ${FILENAME}, but first erasing and writing system information" echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
"$PYTHON" -m esptool erase_flash $PYTHON -m esptool --baud 921600 erase_flash
"$PYTHON" -m esptool write_flash 0x1000 system-info.bin $PYTHON -m esptool --baud 921600 write_flash 0x1000 system-info.bin
"$PYTHON" -m esptool write_flash 0x00390000 spiffs-*.bin $PYTHON -m esptool --baud 921600 write_flash 0x00390000 spiffs-*.bin
"$PYTHON" -m esptool write_flash 0x10000 ${FILENAME} $PYTHON -m esptool --baud 921600 write_flash 0x10000 ${FILENAME}
else else
echo "Invalid file: ${FILENAME}" echo "Invalid file: ${FILENAME}"
show_help show_help

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
arm-none-eabi-readelf -s -e .pio/build/nrf52dk/firmware.elf | head -80 arm-none-eabi-readelf -s -e .pio/build/nrf52dk/firmware.elf | head -80
nm -CSr --size-sort .pio/build/nrf52dk/firmware.elf | grep '^200' nm -CSr --size-sort .pio/build/nrf52dk/firmware.elf | grep '^200'

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env bash
set -e set -e

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/python2
# This is a layout for 4MB of flash # This is a layout for 4MB of flash
# Name, Type, SubType, Offset, Size, Flags # Name, Type, SubType, Offset, Size, Flags
@@ -38,4 +38,4 @@ app0, app, ota_0, , 0x{app:x},
app1, app, ota_1, , 0x{app:x}, app1, app, ota_1, , 0x{app:x},
spiffs, data, spiffs, , 0x{spi:x} """.format(**locals()) spiffs, data, spiffs, , 0x{spi:x} """.format(**locals())
print(table) print(table)

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
# You probably don't want to use this script, it programs a custom bootloader build onto a nrf52 board # You probably don't want to use this script, it programs a custom bootloader build onto a nrf52 board
set -e set -e

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
# You probably don't want to use this script, it programs a custom bootloader build onto a nrf52 board # You probably don't want to use this script, it programs a custom bootloader build onto a nrf52 board
set -e set -e

View File

@@ -1,4 +1,3 @@
#!/usr/bin/env bash
mosquitto_sub -h mqtt.meshtastic.org -v -t \$SYS/\# -t msh/+/stat/\# -t msh/+/json/\# mosquitto_sub -h mqtt.meshtastic.org -v -t \$SYS/\# -t msh/+/stat/\# -t msh/+/json/\#
# mosquitto_sub -h test.mosquitto.org -v -t mesh/\# -F "%j" # mosquitto_sub -h test.mosquitto.org -v -t mesh/\# -F "%j"

View File

@@ -1,3 +1 @@
#!/usr/bin/env bash
mosquitto_pub -h mqtt.meshtastic.org -u meshdev -P large4cats -t msh/1/stat/FakeNode -m online -d mosquitto_pub -h mqtt.meshtastic.org -u meshdev -P large4cats -t msh/1/stat/FakeNode -m online -d

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
set -e set -e
pio run --environment native pio run --environment native
gdbserver --once localhost:2345 .pio/build/native/program "$@" gdbserver --once localhost:2345 .pio/build/native/program "$@"

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
set -e set -e
pio run --environment native pio run --environment native
.pio/build/native/program "$@" .pio/build/native/program "$@"

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env bash
# JLinkRTTViewer # JLinkRTTViewer
JLinkRTTClient JLinkRTTClient

View File

@@ -1,3 +1,3 @@
#!/usr/bin/env bash
JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52832_XXAA JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52832_XXAA

View File

@@ -1,3 +1,3 @@
#!/usr/bin/env bash
JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52833_XXAA JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52833_XXAA

View File

@@ -1,3 +1,3 @@
#!/usr/bin/env bash
JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52840_XXAA -SuppressInfoUpdateFW -DisableAutoUpdateFW -rtos GDBServer/RTOSPlugin_FreeRTOS JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52840_XXAA -SuppressInfoUpdateFW -DisableAutoUpdateFW -rtos GDBServer/RTOSPlugin_FreeRTOS

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
esptool.py --baud 921600 write_flash 0x10000 release/archive/old/firmware-tbeam-EU865-1.0.0.bin esptool.py --baud 921600 write_flash 0x10000 release/archive/old/firmware-tbeam-EU865-1.0.0.bin
echo "Erasing the otadata partition, which will turn off flash flippy-flop and force the first image to be used" echo "Erasing the otadata partition, which will turn off flash flippy-flop and force the first image to be used"
esptool.py --baud 921600 erase_region 0xe000 0x2000 esptool.py --baud 921600 erase_region 0xe000 0x2000

View File

@@ -1,3 +1 @@
#!/usr/bin/env bash
esptool.py --baud 921600 write_flash 0x10000 release/archive/old/firmware-tbeam-1.1.50.bin esptool.py --baud 921600 write_flash 0x10000 release/archive/old/firmware-tbeam-1.1.50.bin

View File

@@ -1,4 +1,3 @@
#!/usr/bin/env bash
set -e set -e

View File

@@ -1,4 +1,3 @@
#!/usr/bin/env bash
set -e set -e

View File

@@ -1,4 +1,3 @@
#!/usr/bin/env bash
set -e set -e

View File

@@ -1,17 +1,11 @@
#!/usr/bin/env bash
set -e set -e
echo "This script is only for developers who are publishing new builds on github. Most users don't need it" echo "This script is only for developers who are publishing new builds on github. Most users don't need it"
VERSION=`bin/buildinfo.py long` VERSION=`bin/buildinfo.py short`
# Must have a V prefix to trigger github # Must have a V prefix to trigger github
git tag "v${VERSION}" git tag "v${VERSION}"
git push root "v${VERSION}" # push the tag
# Commented out per https://github.com/meshtastic/Meshtastic-device/issues/947
#git push root "v${VERSION}" # push the tag
git push origin "v${VERSION}" # push the tag
echo "Tag ${VERSION} pushed to github, github actions should now be building the draft release. If it seems good, click to publish it" echo "Tag ${VERSION} pushed to github, github actions should now be building the draft release. If it seems good, click to publish it"

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
# You probably don't need this - it is a basic test of the serial flash on the TTGO eink board # You probably don't need this - it is a basic test of the serial flash on the TTGO eink board
nrfjprog --qspiini nrf52/ttgo_eink_qpsi.ini --qspieraseall nrfjprog --qspiini nrf52/ttgo_eink_qpsi.ini --qspieraseall

View File

@@ -1,3 +1 @@
#!/usr/bin/env bash
esptool.py --baud 921600 read_flash 0x1000 0xf000 system-info.img esptool.py --baud 921600 read_flash 0x1000 0xf000 system-info.img

View File

@@ -1 +0,0 @@
cd proto && ..\nanopb-0.4.4\generator-bin\protoc.exe --nanopb_out=-v:..\src\mesh\generated -I=..\proto *.proto

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env bash #!/bin/bash
set -e set -e
@@ -12,4 +12,4 @@ cd proto
#echo "Regenerating protobuf documentation - if you see an error message" #echo "Regenerating protobuf documentation - if you see an error message"
#echo "you can ignore it unless doing a new protobuf release to github." #echo "you can ignore it unless doing a new protobuf release to github."
#bin/regen-docs.sh #bin/regen-docs.sh

View File

@@ -1,3 +1 @@
#!/usr/bin/env bash
pio run --upload-port /dev/ttyUSB0 -t upload -t monitor pio run --upload-port /dev/ttyUSB0 -t upload -t monitor

View File

@@ -1,3 +1 @@
#!/usr/bin/env bash
pio run --upload-port /dev/ttyUSB1 -t upload -t monitor pio run --upload-port /dev/ttyUSB1 -t upload -t monitor

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
set -e set -e
echo uploading to usb1 echo uploading to usb1

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
set -e set -e
TARG=tbeam TARG=tbeam

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env bash
# /home/kevinh/.platformio/packages/tool-openocd-esp32/bin/openocd -s /home/kevinh/.platformio/packages/tool-openocd-esp32 -c gdb_port pipe; tcl_port disabled; telnet_port disabled -s /home/kevinh/.platformio/packages/tool-openocd-esp32/share/openocd/scripts -f interface/jlink.cfg -f board/esp-wroom-32.cfg # /home/kevinh/.platformio/packages/tool-openocd-esp32/bin/openocd -s /home/kevinh/.platformio/packages/tool-openocd-esp32 -c gdb_port pipe; tcl_port disabled; telnet_port disabled -s /home/kevinh/.platformio/packages/tool-openocd-esp32/share/openocd/scripts -f interface/jlink.cfg -f board/esp-wroom-32.cfg
/home/kevinh/.platformio/packages/tool-openocd-esp32/bin/openocd -s /home/kevinh/.platformio/packages/tool-openocd-esp32 -s /home/kevinh/.platformio/packages/tool-openocd-esp32/share/openocd/scripts -f interface/jlink.cfg -f ./lora32-openocd.cfg /home/kevinh/.platformio/packages/tool-openocd-esp32/bin/openocd -s /home/kevinh/.platformio/packages/tool-openocd-esp32 -s /home/kevinh/.platformio/packages/tool-openocd-esp32/share/openocd/scripts -f interface/jlink.cfg -f ./lora32-openocd.cfg

View File

@@ -1,3 +1 @@
#!/usr/bin/env bash
pio device monitor -b 921600 pio device monitor -b 921600

View File

@@ -1,3 +1 @@
#!/usr/bin/env bash
pio device monitor -p /dev/ttyUSB1 -b 921600 pio device monitor -p /dev/ttyUSB1 -b 921600

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
set -e set -e
echo "Starting simulator" echo "Starting simulator"

View File

@@ -1,2 +0,0 @@
@echo off
if [%1]==[] (echo "Please specify a platformio NRF target (i.e. rak4631) as the first argument.") else (python3 .\bin\uf2conv.py .\.pio\build\%1\firmware.hex -c -o .\.pio\build\%1\firmware.uf2 -f 0xADA52840)

View File

@@ -1,10 +1,5 @@
#!/usr/bin/env bash
set -e set -e
echo "building for t-echo" echo "Converting to uf2 for NRF52 Adafruit bootloader"
pio run --environment t-echo
echo "Converting to uf2 for NRF52 Adafruit bootloader - double tap on the reset button to force bootloader entry"
bin/uf2conv.py .pio/build/t-echo/firmware.hex -f 0xADA52840 bin/uf2conv.py .pio/build/t-echo/firmware.hex -f 0xADA52840
cp flash.uf2 /media/kevinh/FTH*BOOT/ cp flash.uf2 /media/kevinh/FTH*BOOT/

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
set -e set -e
echo "Converting to uf2 for NRF52 Adafruit bootloader" echo "Converting to uf2 for NRF52 Adafruit bootloader"

View File

@@ -1,3 +1 @@
#!/usr/bin/env bash
pio run --upload-port /dev/ttyUSB1 -t upload pio run --upload-port /dev/ttyUSB1 -t upload

View File

@@ -1,4 +1,2 @@
#!/usr/bin/env bash
echo using amap tool to display memory map echo using amap tool to display memory map
amap .pio/build/output.map amap .pio/build/output.map

View File

@@ -16,9 +16,9 @@
"name": "adafruit" "name": "adafruit"
}, },
"softdevice": { "softdevice": {
"sd_flags": "-DS140", "sd_flags": "-DS113",
"sd_name": "s140", "sd_name": "s113",
"sd_version": "6.1.1", "sd_version": "7.2.0",
"sd_fwid": "0x00B6" "sd_fwid": "0x00B6"
}, },
"bootloader": { "bootloader": {

View File

@@ -1,39 +0,0 @@
{
"build": {
"arduino":{
"ldscript": "esp32_out.ld"
},
"core": "esp32",
"extra_flags": "-DARDUINO_ESP32_DEV",
"f_cpu": "240000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
"variant": "WisCore_RAK11200_Board"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"frameworks": [
"arduino",
"espidf"
],
"name": "WisCore RAK11200 Board",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"protocols": [
"esptool",
"espota",
"ftdi"
],
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.rakwireless.com",
"vendor": "RAKwireless"
}

View File

1
data/static/index.html Normal file
View File

@@ -0,0 +1 @@
not yet supported - soon will be included in build

BIN
deprecated/icon-18dp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 B

1
deprecated/icon-24px.svg Normal file
View File

@@ -0,0 +1 @@
<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="M12 5c-3.87 0-7 3.13-7 7h2c0-2.76 2.24-5 5-5s5 2.24 5 5h2c0-3.87-3.13-7-7-7zm1 9.29c.88-.39 1.5-1.26 1.5-2.29 0-1.38-1.12-2.5-2.5-2.5S9.5 10.62 9.5 12c0 1.02.62 1.9 1.5 2.29v3.3L7.59 21 9 22.41l3-3 3 3L16.41 21 13 17.59v-3.3zM12 1C5.93 1 1 5.93 1 12h2c0-4.97 4.03-9 9-9s9 4.03 9 9h2c0-6.07-4.93-11-11-11z"/></svg>

After

Width:  |  Height:  |  Size: 442 B

BIN
deprecated/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,17 +0,0 @@
To build:
docker build -t meshtastic/device .
To run:
docker run --rm -p 4403:4403 meshtastic/device
or, to get a shell on the docker image:
docker run -it meshtastic/device bash
To use python cli against it:
meshtastic --info --host localhost
To stop:
# run this to get id
docker ps
# tip: you can just use the first few characters of the id in the next command
docker kill <id>

View File

@@ -2,19 +2,23 @@
You probably don't care about this section - skip to the next one. You probably don't care about this section - skip to the next one.
* usb lora dongle from pine64, add end user instructions * DONE investigate TCP on ESP32 https://github.com/meshtastic/Meshtastic-device/issues/807
* measure rak4630 power draw and turn off power for GPS most of the time. We should be able to run on the small solar panel. * DONE fix python tool problem with windows and the heartbeat
* turn on watchdog reset if app hangs on nrf52 or esp32 * router mode dropping messages? https://meshtastic.discourse.group/t/router-mode-missing-messages/3329/3
* pine64 solar boards * fix ttgo eink screen
* for the matrix gateway? recommended by @sam-uk https://github.com/matrix-org/coap-proxy * list portduino on platformio
* DONE make native sim not touch hardware
* DONE reenable sim in CI builds
* figure our wss for mqtt.meshtastic - use cloudflare? 2052 ws, 2053 crypt * figure our wss for mqtt.meshtastic - use cloudflare? 2052 ws, 2053 crypt
* pine64 lora module
* @havealoha fixedposition not working
* ask for vercel access * ask for vercel access
* finish plan for riot.im * finish plan for riot.im
* turn on setTx(timeout) and state = setDioIrqParams(SX126X_IRQ_TX_DONE | SX126X_IRQ_TIMEOUT, SX126X_IRQ_TX_DONE | SX126X_IRQ_TIMEOUT); in sx1262 code * turn on setTx(timeout) and state = setDioIrqParams(SX126X_IRQ_TX_DONE | SX126X_IRQ_TIMEOUT, SX126X_IRQ_TX_DONE | SX126X_IRQ_TIMEOUT); in sx1262 code
* NO add rak4600 support (with rf95 radio and limited ram) * DONE fix this sleep problem: https://meshtastic.discourse.group/t/new-device-release-1-2-30-ready-for-alpha-testing/3272/13?u=geeksville
* store esp32 crashes to flash (and 64KB coredump partition) - https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/core_dump.html * add rak4600 support (with rf95 radio and limited ram)
* If more nodes appear than the nodedb can hold, delete oldest entries from DB
* send debug info 'in-band' * Switch to use https://github.com/adafruit/Adafruit_nRF52_Arduino.git when available (see arduino code for examples)
* DONE @luxonn reports that after a while the android app stops showing new messages * DONE @luxonn reports that after a while the android app stops showing new messages
* DONE release android APK - fix recent 1.2.28 crash report * DONE release android APK - fix recent 1.2.28 crash report
* DONE remote admin busted? * DONE remote admin busted?
@@ -27,6 +31,7 @@ You probably don't care about this section - skip to the next one.
* DONE tcp stream problem in python+pordtuino, server thinks client dropped when client DID NOT DROP * DONE tcp stream problem in python+pordtuino, server thinks client dropped when client DID NOT DROP
* DONE TCP mode for android, localhost is at 10.0.2.2 * DONE TCP mode for android, localhost is at 10.0.2.2
* DONE make sure USB still works in android * DONE make sure USB still works in android
* add portduino builds to zip
* add license to portduino and make announcement * add license to portduino and make announcement
* DONE naks are being dropped (though enqueuedLocal) sometimes before phone/PC gets them * DONE naks are being dropped (though enqueuedLocal) sometimes before phone/PC gets them
* DONE have android fill in if local GPS has poor signal * DONE have android fill in if local GPS has poor signal
@@ -325,7 +330,7 @@ Items after the first final candidate release.
- add "store and forward" support for messages, or move to the DB sync model. This would allow messages to be eventually delivered even if nodes are out of contact at the moment. - add "store and forward" support for messages, or move to the DB sync model. This would allow messages to be eventually delivered even if nodes are out of contact at the moment.
- use variable length Strings in protobufs (instead of current fixed buffers). This would save lots of RAM - use variable length Strings in protobufs (instead of current fixed buffers). This would save lots of RAM
- use BLEDevice::setPower to lower our BLE transmit power - extra range doesn't help us, it costs amps and it increases snoopability - use BLEDevice::setPower to lower our BLE transmit power - extra range doesn't help us, it costs amps and it increases snoopability
- make a Ham build: just a new frequency list, a bool to say 'never do encryption' and use the callsign as that node's unique id. -from Girts - make a HAM build: just a new frequency list, a bool to say 'never do encryption' and use hte callsign as that node's unique id. -from Girts
- don't forward redundant pings or ping responses to the phone, it just wastes phone battery - don't forward redundant pings or ping responses to the phone, it just wastes phone battery
- don't send location packets if we haven't moved significantly - don't send location packets if we haven't moved significantly
- scrub default radio config settings for bandwidth/range/speed - scrub default radio config settings for bandwidth/range/speed

View File

@@ -1,25 +0,0 @@
* nutcracker https://www.pine64.org/2020/10/28/nutcracker-challenge-blob-free-wifi-ble/
* https://github.com/pine64/bl_iot_sdk
* https://github.com/pine64/bl602-docs / https://pine64.github.io/bl602-docs/
* https://github.com/pine64/ArduinoCore-bouffalo
cd ~/packages
git clone --recursive https://github.com/pine64/bl_iot_sdk
https://github.com/spacemeowx2/blflash/releases
# FIXME or BL604
cd bl_iot_sdk
export BL60X_SDK_PATH=/home/kevinh/packages/bl_iot_sdk
export CONFIG_CHIP_NAME=BL602
cd customer_app/bl602_boot2
make
* todo run hello world on hardware (check for bl604 vs bl602 first)
* build/run in the crummy arduino environment
* build in platformio
https://lupyuen.github.io/articles/lorawan2

View File

@@ -11,26 +11,16 @@
[platformio] [platformio]
default_envs = tbeam default_envs = tbeam
;default_envs = tbeam0.7 ;default_envs = tbeam0.7
;default_envs = heltec-v1
;default_envs = heltec-v2.0 ;default_envs = heltec-v2.0
;default_envs = heltec-v2.1
;default_envs = tlora-v1
;default_envs = tlora-v1 ;default_envs = tlora-v1
;default_envs = tlora_v1_3 ;default_envs = tlora_v1_3
;default_envs = tlora-v2 ;default_envs = tlora-v2
;default_envs = tlora-v2-1-1.6
;default_envs = lora-relay-v1 # nrf board ;default_envs = lora-relay-v1 # nrf board
;default_envs = t-echo ;default_envs = t-echo
;default_envs = nrf52840dk-geeksville ;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 = 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 = rak4631 ;default_envs = rak4631
;default_envs = rak4630 ;default_envs = rak4630
;default_envs = meshtastic-diy-v1
;default_envs = meshtastic-diy-v1.1
; board specific config can be moved to the respective 'variants' file.
; See https://docs.platformio.org/en/latest/projectconf/section_platformio.html#extra-configs
extra_configs = variants/*/platformio.ini
[common] [common]
; common is not currently used ; common is not currently used
@@ -77,24 +67,20 @@ debug_tool = jlink
; monitor adapter_khz 10000 ; monitor adapter_khz 10000
lib_deps = lib_deps =
https://github.com/meshtastic/esp8266-oled-ssd1306.git#d90231dedbb2f52bd7a32fb8ed8edec52cf4a8cb ; ESP8266_SSD1306 https://github.com/meshtastic/esp8266-oled-ssd1306.git#35d796226b853b0c0ff818b2f1aa3d35e7296a96 ; ESP8266_SSD1306
https://github.com/meshtastic/OneButton.git#3bcba9492d01e2a8a86f46700ab16f96dd2cf1f5 ; OneButton library for non-blocking button debounce https://github.com/geeksville/OneButton.git ; OneButton library for non-blocking button debounce
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib 1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
https://github.com/meshtastic/arduino-fsm.git https://github.com/meshtastic/arduino-fsm.git#829e967b8a95c094f73c60ef8dacfe66eae38940
https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad
https://github.com/meshtastic/RadioLib.git#5582ac30578ff3f53f20630a00b2a8a4b8f92c74 https://github.com/meshtastic/RadioLib.git#80ed10d689a0568782c5bd152906b0f97d2bce93
https://github.com/meshtastic/TinyGPSPlus.git#f0f47067ef2f67c856475933188251c1ef615e79 https://github.com/meshtastic/TinyGPSPlus.git#f0f47067ef2f67c856475933188251c1ef615e79
https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460 https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460
Wire ; explicitly needed here because the AXP202 library forgets to add it Wire ; explicitly needed here because the AXP202 library forgets to add it
SPI SPI
https://github.com/geeksville/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3 https://github.com/geeksville/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
PubSubClient PubSubClient
; Used for the code analysis in PIO Home / Inspect ; Common settings for conventional (non Portduino) Ardino targets
check_tool = cppcheck
check_skip_packages = yes
; Common settings for conventional (non Portduino) Arduino targets
[arduino_base] [arduino_base]
framework = arduino framework = arduino
@@ -107,17 +93,6 @@ build_flags = ${env.build_flags} -Os
src_filter = ${env.src_filter} -<portduino/> src_filter = ${env.src_filter} -<portduino/>
; Common libs for environmental measurements (not included in native / portduino)
[environmental]
lib_deps =
adafruit/DHT sensor library@^1.4.1
adafruit/Adafruit Unified Sensor@^1.1.4
paulstoffregen/OneWire@^2.3.5
robtillaart/DS18B20@^0.1.11
adafruit/Adafruit BME280 Library@^2.2.2
adafruit/Adafruit BME680 Library@^2.0.1
adafruit/Adafruit MCP9808 Library@^2.0.0
; Common settings for ESP targes, mixin with extends = esp32_base ; Common settings for ESP targes, mixin with extends = esp32_base
[esp32_base] [esp32_base]
extends = arduino_base extends = arduino_base
@@ -126,33 +101,23 @@ src_filter =
${arduino_base.src_filter} -<nrf52/> ${arduino_base.src_filter} -<nrf52/>
upload_speed = 921600 upload_speed = 921600
debug_init_break = tbreak setup debug_init_break = tbreak setup
# Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging.
# See library directory for BLE logging possible values: .pio/libdeps/tbeam/NimBLE-Arduino/src/log_common/log_common.h
# This overrides the BLE logging default of LOG_LEVEL_INFO (1) from: .pio/libdeps/tbeam/NimBLE-Arduino/src/esp_nimble_cfg.h
build_flags = build_flags =
${arduino_base.build_flags} -Wall -Wextra -Isrc/esp32 -Isrc/esp32-mfix-esp32-psram-cache-issue -lnimble -std=c++11 ${arduino_base.build_flags} -Wall -Wextra -Isrc/esp32 -Isrc/esp32-mfix-esp32-psram-cache-issue -lnimble -std=c++11
-DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
-DAXP_DEBUG_PORT=Serial -DAXP_DEBUG_PORT=Serial
lib_deps = lib_deps =
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${environmental.lib_deps}
https://github.com/meshtastic/esp32_https_server.git https://github.com/meshtastic/esp32_https_server.git
h2zero/NimBLE-Arduino@1.3.6 adafruit/DHT sensor library@^1.4.1
tobozo/ESP32-targz@^1.1.4 adafruit/Adafruit Unified Sensor@^1.1.4
arduino-libraries/NTPClient#531eff39d9fbc831f3d03f706a161739203fbe2a
# Hmm - this doesn't work yet # Hmm - this doesn't work yet
# board_build.ldscript = linker/esp32.extram.bss.ld # board_build.ldscript = linker/esp32.extram.bss.ld
lib_ignore = lib_ignore = segger_rtt
segger_rtt
ESP32 BLE Arduino
platform_packages = platform_packages =
framework-arduinoespressif32@https://github.com/meshtastic/arduino-esp32.git#4cde0f5d412d2695184f32e8a47e9bea57b45276 framework-arduinoespressif32@https://github.com/meshtastic/arduino-esp32.git#4cde0f5d412d2695184f32e8a47e9bea57b45276
; leave this commented out to avoid breaking Windows ; leave this commented out to avoid breaking Windows
;upload_port = /dev/ttyUSB0 upload_port = /dev/ttyUSB0
;monitor_port = /dev/ttyUSB0 ;monitor_port = /dev/ttyUSB0
;upload_port = /dev/cu.SLAB_USBtoUART ;upload_port = /dev/cu.SLAB_USBtoUART
@@ -169,6 +134,62 @@ board_build.partitions = partition-table.csv
; -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG ; -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
; The 1.0 release of the TBEAM board
[env:tbeam]
extends = esp32_base
board = ttgo-t-beam
lib_deps =
${esp32_base.lib_deps}
build_flags =
${esp32_base.build_flags} -D TBEAM_V10
; The original TBEAM board without the AXP power chip and a few other changes
; Note: I've heard reports this didn't work. Disabled until someone with a 0.7 can test and debug.
[env:tbeam0.7]
extends = esp32_base
board = ttgo-t-beam
build_flags =
${esp32_base.build_flags} -D TBEAM_V07
[env:heltec-v2.0]
;build_type = debug ; to make it possible to step through our jtag debugger
extends = esp32_base
board = heltec_wifi_lora_32_V2
build_flags =
${esp32_base.build_flags} -D HELTEC_V2_0
[env:heltec-v2.1]
;build_type = debug ; to make it possible to step through our jtag debugger
extends = esp32_base
board = heltec_wifi_lora_32_V2
build_flags =
${esp32_base.build_flags} -D HELTEC_V2_1
[env:tlora-v1]
extends = esp32_base
board = ttgo-lora32-v1
build_flags =
${esp32_base.build_flags} -D TLORA_V1
; note: the platformio definition for lora32-v2 seems stale, it is missing a pins_arduino.h file, therefore I don't think it works
[env:tlora_v1_3]
extends = esp32_base
board = ttgo-lora32-v1
build_flags =
${esp32_base.build_flags} -D TLORA_V1_3
[env:tlora-v2]
extends = esp32_base
board = ttgo-lora32-v1
build_flags =
${esp32_base.build_flags} -D TLORA_V2
[env:tlora-v2-1-1.6]
extends = esp32_base
board = ttgo-lora32-v1
build_flags =
${esp32_base.build_flags} -D TLORA_V2_1_16
; The Heltec Cubecell plus ; The Heltec Cubecell plus
; IMPORTANT NOTE: This target doesn't yet work and probably won't ever work. I'm keeping it around for now. ; IMPORTANT NOTE: This target doesn't yet work and probably won't ever work. I'm keeping it around for now.
; For more details see my post in the forum. ; For more details see my post in the forum.
@@ -197,7 +218,7 @@ src_filter =
${arduino_base.src_filter} -<esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<plugins/esp32> -<mqtt/> ${arduino_base.src_filter} -<esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<plugins/esp32> -<mqtt/>
lib_ignore = lib_ignore =
BluetoothOTA BluetoothOTA
; monitor_port = /dev/ttyACM1 monitor_port = /dev/ttyACM1
# we pass in options to jlink so it can understand freertos (note: we don't use "jlink" as the tool) # we pass in options to jlink so it can understand freertos (note: we don't use "jlink" as the tool)
;debug_tool = jlink ;debug_tool = jlink
@@ -234,21 +255,43 @@ debug_init_break =
[nrf52840_base] [nrf52840_base]
; Common base class for all nrf52840 based targets ; Common base class for all nrf52840 based targets
extends = nrf52_base extends = nrf52_base
; was -DTINY_USB
build_flags = ${nrf52_base.build_flags}
lib_deps = lib_deps =
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${environmental.lib_deps}
Adafruit nRFCrypto Adafruit nRFCrypto
# Adafruit TinyUSB Arduino
# add Adafruit nRFCrypto platform IO automated scan is broken # add Adafruit nRFCrypto platform IO automated scan is broken
[env:lora_isp4520]
extends = nrf52_base
board = lora_isp4520
# add our variants files to the include and src paths
build_flags = ${nrf52_base.build_flags} -Ivariants/lora_isp4520
# No screen and GPS on the board. We still need RTC.cpp for the RTC clock.
src_filter = ${nrf52_base.src_filter} +<../variants/lora_isp4520> -<graphics> -<gps> +<gps/GPS.cpp> +<gps/RTC.cpp>
lib_ignore = ${nrf52_base.lib_ignore}
ESP8266_SSD1306
SparkFun Ublox Arduino Library
AXP202X_Library
TinyGPSPlus
upload_protocol = jlink
monitor_port = /dev/ttyUSB0
; The NRF52840-dk development board ; The NRF52840-dk development board
; Note: By default no lora device is created for this build - it uses a simulated interface ; Note: By default no lora device is created for this build - it uses a simulated interface
[env:nrf52840dk] [env:nrf52840dk]
extends = nrf52840_base extends = nrf52840_base
board = nrf52840_dk board = nrf52840_dk
; The NRF52840-dk development board, but @geeksville's board - which has a busted oscilliator
[env:nrf52840dk-geeksville]
extends = nrf52840_base
board = nrf52840_dk_modified
# add our variants files to the include and src paths
build_flags = ${nrf52_base.build_flags} -Ivariants/pca10056-rc-clock
src_filter = ${nrf52_base.src_filter} +<../variants/pca10056-rc-clock>
; Note: By default no lora device is created for this build - it uses a simulated interface ; Note: By default no lora device is created for this build - it uses a simulated interface
[env:feather_nrf52832] [env:feather_nrf52832]
extends = nrf52_base extends = nrf52_base
@@ -264,4 +307,150 @@ monitor_port = /dev/ttyUSB0
monitor_speed = 115200 monitor_speed = 115200
# For experimenting with RAM sizes # For experimenting with RAM sizes
# board_build.ldscript = linker/nrf52840_s140_sim832.ld # board_build.ldscript = linker/nrf52840_s140_sim832.ld
; The very slick RAK wireless RAK 4631 / 4630 board
[env:rak4631]
extends = nrf52840_base
board = wiscore_rak4631
# add our variants files to the include and src paths
# define build flags for the TFT_eSPI library
build_flags = ${nrf52_base.build_flags} -Ivariants/WisCore_RAK4631_Board
src_filter = ${nrf52_base.src_filter} +<../variants/WisCore_RAK4631_Board>
debug_tool = jlink
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
;upload_protocol = jlink
; Note, this board is not yet supported! It will not work without futher development.
; THIS IS UNTESTED (I don't have this board), but other developers can use it as a starting point
[env:rak4600]
extends = nrf52_base
board = wiscore_rak4600
# add our variants files to the include and src paths
# define build flags for the TFT_eSPI library
build_flags = ${nrf52_base.build_flags} -Ivariants/WisCore_RAK4600_Board
src_filter = ${nrf52_base.src_filter} +<../variants/WisCore_RAK4600_Board>
lib_deps =
${arduino_base.lib_deps}
; The PPR board
[env:ppr]
extends = nrf52_base
board = ppr
lib_deps =
${arduino_base.lib_deps}
UC1701
; The PPR board
[env:ppr1]
extends = nrf52_base
board = ppr1
build_flags = ${nrf52_base.build_flags} -Ivariants/ppr1
src_filter = ${nrf52_base.src_filter} +<../variants/ppr1>
lib_deps =
${arduino_base.lib_deps}
; First prototype eink/nrf52840/sx1262 device
[env:t-echo]
extends = nrf52840_base
board = t-echo
# add our variants files to the include and src paths
# define build flags for the TFT_eSPI library
build_flags = ${nrf52_base.build_flags} -Ivariants/t-echo
-DBUSY_PIN=3 -DRST_PIN=2 -DDC_PIN=28 -DCS_PIN=30
src_filter = ${nrf52_base.src_filter} +<../variants/t-echo>
lib_deps =
${nrf52840_base.lib_deps}
https://github.com/geeksville/EPD_Libraries.git
TFT_eSPI
;upload_protocol = fs
; First prototype eink/nrf52840/sx1262 device (removed from build because didn't ship in quantity)
;[env:eink0.1]
;extends = nrf52840_base
;board = eink0.1
;# add our variants files to the include and src paths
;# define build flags for the TFT_eSPI library
;build_flags = ${nrf52_base.build_flags} -Ivariants/eink0.1
; -DBUSY_PIN=3 -DRST_PIN=2 -DDC_PIN=28 -DCS_PIN=30
;src_filter = ${nrf52_base.src_filter} +<../variants/eink0.1>
;lib_deps =
; ${nrf52840_base.lib_deps}
; https://github.com/geeksville/EPD_Libraries.git
; TFT_eSPI
; The https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay board by @BigCorvus
[env:lora-relay-v1]
extends = nrf52840_base
board = lora-relay-v1
# add our variants files to the include and src paths
# define build flags for the TFT_eSPI library
build_flags = ${nrf52_base.build_flags} -Ivariants/lora_relay_v1
-DUSER_SETUP_LOADED
-DTFT_WIDTH=80
-DTFT_HEIGHT=160
-DST7735_GREENTAB160x80
-DST7735_DRIVER
-DTFT_CS=ST7735_CS
-DTFT_DC=ST7735_RS
-DTFT_RST=ST7735_RESET
-DSPI_FREQUENCY=27000000
src_filter = ${nrf52_base.src_filter} +<../variants/lora_relay_v1>
lib_deps =
${nrf52840_base.lib_deps}
SparkFun BQ27441 LiPo Fuel Gauge Arduino Library
TFT_eSPI
; The https://github.com/BigCorvus/LoRa-BLE-Relay-v2 board by @BigCorvus
[env:lora-relay-v2]
extends = nrf52840_base
board = lora-relay-v2
# add our variants files to the include and src paths
# define build flags for the TFT_eSPI library
build_flags = ${nrf52_base.build_flags} -Ivariants/lora_relay_v2
-DUSER_SETUP_LOADED
-DTFT_WIDTH=80
-DTFT_HEIGHT=160
-DST7735_GREENTAB160x80
-DST7735_DRIVER
-DTFT_CS=ST7735_CS
-DTFT_DC=ST7735_RS
-DTFT_RST=ST7735_RESET
-DSPI_FREQUENCY=27000000
-DTFT_WR=ST7735_SDA
-DTFT_SCLK=ST7735_SCK
src_filter = ${nrf52_base.src_filter} +<../variants/lora_relay_v2>
lib_deps =
${nrf52840_base.lib_deps}
SparkFun BQ27441 LiPo Fuel Gauge Arduino Library
TFT_eSPI
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
[env:native]
platform = https://github.com/geeksville/platform-native.git
src_filter = ${env.src_filter} -<esp32/> -<nimble/> -<nrf52/> -<mesh/http/> -<plugins/esp32>
build_flags = ${arduino_base.build_flags} -O0
framework = arduino
board = cross_platform
lib_deps =
${arduino_base.lib_deps}
rweather/Crypto
; The Portduino based sim environment on top of a linux OS and touching linux hardware devices
[env:linux]
platform = https://github.com/geeksville/platform-native.git
src_filter = ${env.src_filter} -<esp32/> -<nimble/> -<nrf52/> -<mesh/http/> -<plugins/esp32>
build_flags = ${arduino_base.build_flags} -O0 -lgpiod
framework = arduino
board = linux_hardware
lib_deps =
${arduino_base.lib_deps}
rweather/Crypto
; The GenieBlocks LORA prototype board
; note: @geeksville disabled because genieblocks_lora is not checked into the boards directory, please send in a PR to add it ;-)
;[env:genieblocks_lora]
;extends = esp32_base
;board = genieblocks_lora
;build_flags =
; ${esp32_base.build_flags} -D GENIEBLOCKS

2
proto

Submodule proto updated: 2930129e8e...dfcfba8d1a

1
src/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
main.ino.cpp

View File

@@ -1,4 +1,3 @@
#include "configuration.h"
#include "BluetoothCommon.h" #include "BluetoothCommon.h"
// NRF52 wants these constants as byte arrays // NRF52 wants these constants as byte arrays

View File

@@ -1,61 +0,0 @@
// DEBUG LED
#ifndef LED_INVERTED
#define LED_INVERTED 0 // define as 1 if LED is active low (on)
#endif
// -----------------------------------------------------------------------------
// DEBUG
// -----------------------------------------------------------------------------
#ifdef CONSOLE_MAX_BAUD
#define SERIAL_BAUD CONSOLE_MAX_BAUD
#else
#define SERIAL_BAUD 921600 // Serial debug baud rate
#endif
#include "SerialConsole.h"
#define DEBUG_PORT (*console) // Serial debug port
// What platforms should use SEGGER?
#ifdef NRF52_SERIES
// Always include the SEGGER code on NRF52 - because useful for debugging
#include "SEGGER_RTT.h"
// The channel we send stdout data to
#define SEGGER_STDOUT_CH 0
// Debug printing to segger console
#define SEGGER_MSG(...) SEGGER_RTT_printf(SEGGER_STDOUT_CH, __VA_ARGS__)
// If we are not on a NRF52840 (which has built in USB-ACM serial support) and we don't have serial pins hooked up, then we MUST
// use SEGGER for debug output
#if !defined(PIN_SERIAL_RX) && !defined(NRF52840_XXAA)
// No serial ports on this board - ONLY use segger in memory console
#define USE_SEGGER
#endif
#else
#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32
#endif
#ifdef USE_SEGGER
#define DEBUG_MSG(...) SEGGER_RTT_printf(0, __VA_ARGS__)
#else
#ifdef DEBUG_PORT
#define DEBUG_MSG(...) DEBUG_PORT.logDebug(__VA_ARGS__)
#else
#define DEBUG_MSG(...)
#endif
#endif
// -----------------------------------------------------------------------------
// AXP192 (Rev1-specific options)
// -----------------------------------------------------------------------------
#define GPS_POWER_CTRL_CH 3
#define LORA_POWER_CTRL_CH 2
// Default Bluetooth PIN
#define defaultBLEPin 123456

View File

@@ -1,4 +1,3 @@
#include "configuration.h"
#include "FSCommon.h" #include "FSCommon.h"
void fsInit() void fsInit()

View File

@@ -1,11 +1,8 @@
#pragma once #pragma once
#include "Status.h" #include "Status.h"
#include "configuration.h" #include "configuration.h"
#include "NodeDB.h"
#include <Arduino.h> #include <Arduino.h>
extern NodeDB nodeDB;
namespace meshtastic namespace meshtastic
{ {
@@ -19,39 +16,28 @@ class GPSStatus : public Status
bool hasLock = false; // default to false, until we complete our first read bool hasLock = false; // default to false, until we complete our first read
bool isConnected = false; // Do we have a GPS we are talking to bool isConnected = false; // Do we have a GPS we are talking to
int32_t latitude = 0, longitude = 0; // as an int mult by 1e-7 to get value as double
Position p = Position_init_default; int32_t altitude = 0;
uint32_t dop = 0; // Diminution of position; PDOP where possible (UBlox), HDOP otherwise (TinyGPS) in 10^2 units (needs
// scaling before use)
uint32_t heading = 0;
uint32_t numSatellites = 0;
public: public:
GPSStatus() { statusType = STATUS_TYPE_GPS; } GPSStatus() { statusType = STATUS_TYPE_GPS; }
// proposed for deprecation
GPSStatus(bool hasLock, bool isConnected, int32_t latitude, int32_t longitude, int32_t altitude, uint32_t dop, GPSStatus(bool hasLock, bool isConnected, int32_t latitude, int32_t longitude, int32_t altitude, uint32_t dop,
uint32_t heading, uint32_t numSatellites) uint32_t heading, uint32_t numSatellites)
: Status() : Status()
{ {
this->hasLock = hasLock; this->hasLock = hasLock;
this->isConnected = isConnected; this->isConnected = isConnected;
this->latitude = latitude;
this->p.latitude_i = latitude; this->longitude = longitude;
this->p.longitude_i = longitude; this->altitude = altitude;
this->p.altitude = altitude; this->dop = dop;
this->p.PDOP = dop; this->heading = heading;
this->p.ground_track = heading; this->numSatellites = numSatellites;
this->p.sats_in_view = numSatellites;
} }
// preferred method
GPSStatus(bool hasLock, bool isConnected, const Position& pos)
: Status()
{
this->hasLock = hasLock;
this->isConnected = isConnected;
// all-in-one struct copy
this->p = pos;
}
GPSStatus(const GPSStatus &); GPSStatus(const GPSStatus &);
GPSStatus &operator=(const GPSStatus &); GPSStatus &operator=(const GPSStatus &);
@@ -61,91 +47,45 @@ class GPSStatus : public Status
bool getIsConnected() const { return isConnected; } bool getIsConnected() const { return isConnected; }
int32_t getLatitude() const { int32_t getLatitude() const { return latitude; }
if (radioConfig.preferences.fixed_position){
#if GPS_EXTRAVERBOSE
DEBUG_MSG("WARNING: Using fixed latitude\n");
#endif
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
return node->position.latitude_i;
} else {
return p.latitude_i;
}
}
int32_t getLongitude() const { int32_t getLongitude() const { return longitude; }
if (radioConfig.preferences.fixed_position){
#if GPS_EXTRAVERBOSE
DEBUG_MSG("WARNING: Using fixed longitude\n");
#endif
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
return node->position.longitude_i;
} else {
return p.longitude_i;
}
}
int32_t getAltitude() const { int32_t getAltitude() const { return altitude; }
if (radioConfig.preferences.fixed_position){
#if GPS_EXTRAVERBOSE
DEBUG_MSG("WARNING: Using fixed altitude\n");
#endif
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
return node->position.altitude;
} else {
return p.altitude;
}
}
uint32_t getDOP() const { return p.PDOP; } uint32_t getDOP() const { return dop; }
uint32_t getHeading() const { return p.ground_track; } uint32_t getHeading() const { return heading; }
uint32_t getNumSatellites() const { return p.sats_in_view; } uint32_t getNumSatellites() const { return numSatellites; }
bool matches(const GPSStatus *newStatus) const bool matches(const GPSStatus *newStatus) const
{ {
#if GPS_EXTRAVERBOSE return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected || newStatus->latitude != latitude ||
DEBUG_MSG("GPSStatus.match() new pos@%x to old pos@%x\n", newStatus->longitude != longitude || newStatus->altitude != altitude || newStatus->dop != dop ||
newStatus->p.pos_timestamp, p.pos_timestamp); newStatus->heading != heading || newStatus->numSatellites != numSatellites);
#endif
return (newStatus->hasLock != hasLock ||
newStatus->isConnected != isConnected ||
newStatus->p.latitude_i != p.latitude_i ||
newStatus->p.longitude_i != p.longitude_i ||
newStatus->p.altitude != p.altitude ||
newStatus->p.altitude_hae != p.altitude_hae ||
newStatus->p.PDOP != p.PDOP ||
newStatus->p.ground_track != p.ground_track ||
newStatus->p.sats_in_view != p.sats_in_view);
} }
int updateStatus(const GPSStatus *newStatus) int updateStatus(const GPSStatus *newStatus)
{ {
// Only update the status if values have actually changed // Only update the status if values have actually changed
bool isDirty = matches(newStatus); bool isDirty;
{
if (isDirty && p.pos_timestamp && isDirty = matches(newStatus);
(newStatus->p.pos_timestamp == p.pos_timestamp)) { initialized = true;
// We can NEVER be in two locations at the same time! (also PR #886) hasLock = newStatus->hasLock;
DEBUG_MSG("BUG!! positional timestamp unchanged from prev solution\n"); isConnected = newStatus->isConnected;
latitude = newStatus->latitude;
longitude = newStatus->longitude;
altitude = newStatus->altitude;
dop = newStatus->dop;
heading = newStatus->heading;
numSatellites = newStatus->numSatellites;
} }
initialized = true;
hasLock = newStatus->hasLock;
isConnected = newStatus->isConnected;
p = newStatus->p;
if (isDirty) { if (isDirty) {
if (hasLock) { if (hasLock)
// In debug logs, identify position by @timestamp:stage (stage 3 = notify) DEBUG_MSG("New GPS pos lat=%f, lon=%f, alt=%d, pdop=%f, heading=%f, sats=%d\n", latitude * 1e-7, longitude * 1e-7,
DEBUG_MSG("New GPS pos@%x:3 lat=%f, lon=%f, alt=%d, pdop=%.2f, track=%.2f, sats=%d\n", altitude, dop * 1e-2, heading * 1e-5, numSatellites);
p.pos_timestamp, else
p.latitude_i * 1e-7, p.longitude_i * 1e-7,
p.altitude, p.PDOP * 1e-2, p.ground_track * 1e-5,
p.sats_in_view);
} else
DEBUG_MSG("No GPS lock\n"); DEBUG_MSG("No GPS lock\n");
onNewStatus.notifyObservers(this); onNewStatus.notifyObservers(this);
} }
@@ -155,4 +95,4 @@ class GPSStatus : public Status
} // namespace meshtastic } // namespace meshtastic
extern meshtastic::GPSStatus *gpsStatus; extern meshtastic::GPSStatus *gpsStatus;

View File

@@ -1,5 +1,5 @@
#include "configuration.h"
#include "OSTimer.h" #include "OSTimer.h"
#include "configuration.h"
/** /**
* Schedule a callback to run. The callback must _not_ block, though it is called from regular thread level (not ISR) * Schedule a callback to run. The callback must _not_ block, though it is called from regular thread level (not ISR)

View File

@@ -1,3 +1,2 @@
#include "configuration.h"
#include "Observer.h" #include "Observer.h"

View File

@@ -47,7 +47,7 @@ template <class Callback, class T> class CallbackObserver : public Observer<T>
CallbackObserver(Callback *_objPtr, ObserverCallback _method) : objPtr(_objPtr), method(_method) {} CallbackObserver(Callback *_objPtr, ObserverCallback _method) : objPtr(_objPtr), method(_method) {}
protected: protected:
virtual int onNotify(T arg) override { return (objPtr->*method)(arg); } virtual int onNotify(T arg) { return (objPtr->*method)(arg); }
}; };
/** /**
@@ -104,4 +104,4 @@ template <class T> void Observer<T>::observe(Observable<T> *o)
observed = o; observed = o;
o->addObserver(this); o->addObserver(this);
} }

View File

@@ -1,4 +1,3 @@
#include "configuration.h"
#include "power.h" #include "power.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "PowerFSM.h" #include "PowerFSM.h"
@@ -43,7 +42,6 @@ Power *power;
using namespace meshtastic; using namespace meshtastic;
#ifndef AREF_VOLTAGE
#if defined(NRF52_SERIES) #if defined(NRF52_SERIES)
/* /*
* Internal Reference is +/-0.6V, with an adjustable gain of 1/6, 1/5, 1/4, * Internal Reference is +/-0.6V, with an adjustable gain of 1/6, 1/5, 1/4,
@@ -58,7 +56,6 @@ using namespace meshtastic;
#else #else
#define AREF_VOLTAGE 3.3 #define AREF_VOLTAGE 3.3
#endif #endif
#endif
/** /**
* If this board has a battery level sensor, set this to a valid implementation * If this board has a battery level sensor, set this to a valid implementation
@@ -75,35 +72,28 @@ class AnalogBatteryLevel : public HasBatteryLevel
* *
* FIXME - use a lipo lookup table, the current % full is super wrong * FIXME - use a lipo lookup table, the current % full is super wrong
*/ */
virtual int getBattPercentage() override virtual int getBattPercentage()
{ {
float v = getBattVoltage(); float v = getBattVoltage();
if (v < noBatVolt) if (v < noBatVolt)
return -1; // If voltage is super low assume no battery installed return -1; // If voltage is super low assume no battery installed
#ifndef NRF52_SERIES
// This does not work on a RAK4631 with battery connected
if (v > chargingVolt) if (v > chargingVolt)
return 0; // While charging we can't report % full on the battery return 0; // While charging we can't report % full on the battery
#endif
return clamp((int)(100 * (v - emptyVolt) / (fullVolt - emptyVolt)), 0, 100); return 100 * (v - emptyVolt) / (fullVolt - emptyVolt);
} }
/** /**
* The raw voltage of the batteryin millivolts or NAN if unknown * The raw voltage of the batteryin millivolts or NAN if unknown
*/ */
virtual float getBattVoltage() override virtual float getBattVoltage()
{ {
#ifndef ADC_MULTIPLIER #ifndef ADC_MULTIPLIER
#define ADC_MULTIPLIER 2.0 #define ADC_MULTIPLIER 2.0
#endif #endif
// Override variant or default ADC_MULTIPLIER if we have the override pref
float operativeAdcMultiplier = radioConfig.preferences.adc_multiplier_override > 0 ?
radioConfig.preferences.adc_multiplier_override :
ADC_MULTIPLIER;
#ifdef BATTERY_PIN #ifdef BATTERY_PIN
// Do not call analogRead() often. // Do not call analogRead() often.
@@ -111,12 +101,8 @@ class AnalogBatteryLevel : public HasBatteryLevel
if (millis() - 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 = analogRead(BATTERY_PIN); uint32_t raw = analogRead(BATTERY_PIN);
float scaled; float scaled = 1000.0 * ADC_MULTIPLIER * (AREF_VOLTAGE / 1024.0) * raw;
#ifndef VBAT_RAW_TO_SCALED
scaled = 1000.0 * operativeAdcMultiplier * (AREF_VOLTAGE / 1024.0) * raw;
#else
scaled = VBAT_RAW_TO_SCALED(raw); //defined in variant.h
#endif
// DEBUG_MSG("battery gpio %d raw val=%u scaled=%u\n", BATTERY_PIN, raw, (uint32_t)(scaled)); // DEBUG_MSG("battery gpio %d raw val=%u scaled=%u\n", BATTERY_PIN, raw, (uint32_t)(scaled));
last_read_value = scaled; last_read_value = scaled;
return scaled; return scaled;
@@ -131,15 +117,15 @@ 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
*/ */
virtual bool isBatteryConnect() override { return getBattPercentage() != -1; } virtual bool isBatteryConnect() { return getBattPercentage() != -1; }
/// 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
virtual bool isVBUSPlug() override { return getBattVoltage() > chargingVolt; } virtual bool isVBUSPlug() { return getBattVoltage() > chargingVolt; }
/// Assume charging if we have a battery and external power is connected. /// Assume charging if we have a battery and external power is connected.
/// we can't be smart enough to say 'full'? /// we can't be smart enough to say 'full'?
virtual bool isChargeing() override { return isBatteryConnect() && isVBUSPlug(); } virtual bool isChargeing() { return isBatteryConnect() && isVBUSPlug(); }
private: private:
/// 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
@@ -149,14 +135,9 @@ class AnalogBatteryLevel : public HasBatteryLevel
const float fullVolt = 4200, emptyVolt = 3270, chargingVolt = 4210, noBatVolt = 2230; const float fullVolt = 4200, emptyVolt = 3270, chargingVolt = 4210, noBatVolt = 2230;
float last_read_value = 0.0; float last_read_value = 0.0;
uint32_t last_read_time_ms = 0; uint32_t last_read_time_ms = 0;
}; } analogLevel;
AnalogBatteryLevel analogLevel; Power::Power() : OSThread("Power") {}
Power::Power() : OSThread("Power") {
statusHandler = {};
low_voltage_counter = 0;
}
bool Power::analogInit() bool Power::analogInit()
{ {
@@ -171,19 +152,11 @@ bool Power::analogInit()
adcAttachPin(BATTERY_PIN); adcAttachPin(BATTERY_PIN);
#endif #endif
#ifdef NRF52_SERIES #ifdef NRF52_SERIES
#ifdef VBAT_AR_INTERNAL
analogReference(VBAT_AR_INTERNAL);
#else
analogReference(AR_INTERNAL); // 3.6V analogReference(AR_INTERNAL); // 3.6V
#endif #endif
#endif
#ifndef BATTERY_SENSE_RESOLUTION_BITS
#define BATTERY_SENSE_RESOLUTION_BITS 10
#endif
// adcStart(BATTERY_PIN); // adcStart(BATTERY_PIN);
analogReadResolution(BATTERY_SENSE_RESOLUTION_BITS); // Default of 12 is not very linear. Recommended to use 10 or 11 depending on needed resolution. analogReadResolution(10); // Default of 12 is not very linear. Recommended to use 10 or 11 depending on needed resolution.
batteryLevel = &analogLevel; batteryLevel = &analogLevel;
return true; return true;
#else #else
@@ -199,7 +172,6 @@ bool Power::setup()
found = analogInit(); found = analogInit();
} }
enabled = found; enabled = found;
low_voltage_counter = 0;
return found; return found;
} }
@@ -239,35 +211,20 @@ void Power::readPowerStatus()
} }
// Notify any status instances that are observing us // Notify any status instances that are observing us
const PowerStatus powerStatus2 = const PowerStatus powerStatus =
PowerStatus(hasBattery ? OptTrue : OptFalse, batteryLevel->isVBUSPlug() ? OptTrue : OptFalse, PowerStatus(hasBattery ? OptTrue : OptFalse, batteryLevel->isVBUSPlug() ? OptTrue : OptFalse,
batteryLevel->isChargeing() ? OptTrue : OptFalse, batteryVoltageMv, batteryChargePercent); batteryLevel->isChargeing() ? OptTrue : OptFalse, batteryVoltageMv, batteryChargePercent);
DEBUG_MSG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d\n", powerStatus2.getHasUSB(), DEBUG_MSG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d\n", powerStatus.getHasUSB(),
powerStatus2.getIsCharging(), powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent()); powerStatus.getIsCharging(), powerStatus.getBatteryVoltageMv(), powerStatus.getBatteryChargePercent());
newStatus.notifyObservers(&powerStatus2); newStatus.notifyObservers(&powerStatus);
// If we have a battery at all and it is less than 10% full, force deep sleep if we have more than 3 low readings in a row
// Supect fluctuating voltage on the RAK4631 to force it to deep sleep even if battery is at 85% after only a few days
#ifdef NRF52_SERIES
if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()){
if (batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS){
low_voltage_counter++;
if (low_voltage_counter>3)
powerFSM.trigger(EVENT_LOW_BATTERY);
} else {
low_voltage_counter = 0;
}
}
#else
// If we have a battery at all and it is less than 10% full, force deep sleep // If we have a battery at all and it is less than 10% full, force deep sleep
if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB() && batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS) if (powerStatus.getHasBattery() && !powerStatus.getHasUSB() && batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS)
powerFSM.trigger(EVENT_LOW_BATTERY); powerFSM.trigger(EVENT_LOW_BATTERY);
#endif
} else { } else {
// No power sensing on this board - tell everyone else we have no idea what is happening // No power sensing on this board - tell everyone else we have no idea what is happening
const PowerStatus powerStatus3 = PowerStatus(OptUnknown, OptUnknown, OptUnknown, -1, -1); const PowerStatus powerStatus = PowerStatus(OptUnknown, OptUnknown, OptUnknown, -1, -1);
newStatus.notifyObservers(&powerStatus3); newStatus.notifyObservers(&powerStatus);
} }
} }

View File

@@ -1,3 +1,4 @@
#include "PowerFSM.h" #include "PowerFSM.h"
#include "GPS.h" #include "GPS.h"
#include "MeshService.h" #include "MeshService.h"
@@ -11,11 +12,6 @@
/// Should we behave as if we have AC power now? /// Should we behave as if we have AC power now?
static bool isPowered() static bool isPowered()
{ {
// Completely circumvents the battery / power sensing logic and assumes constant power source
if (radioConfig.preferences.is_always_powered) {
return true;
}
bool isRouter = radioConfig.preferences.is_router; bool isRouter = radioConfig.preferences.is_router;
// If we are not a router and we already have AC power go to POWER state after init, otherwise go to ON // If we are not a router and we already have AC power go to POWER state after init, otherwise go to ON
@@ -32,19 +28,10 @@ static bool isPowered()
static void sdsEnter() static void sdsEnter()
{ {
DEBUG_MSG("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(getPref_sds_secs() * 1000LL); doDeepSleep(getPref_sds_secs() * 1000LL);
} }
extern Power *power;
static void shutdownEnter()
{
DEBUG_MSG("Enter state: SHUTDOWN\n");
power->shutdown();
}
#include "error.h" #include "error.h"
static uint32_t secsSlept; static uint32_t secsSlept;
@@ -55,7 +42,7 @@ static void lsEnter()
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
// DEBUG_MSG("lsEnter end\n"); DEBUG_MSG("lsEnter end\n");
} }
static void lsIdle() static void lsIdle()
@@ -63,6 +50,7 @@ static void lsIdle()
// DEBUG_MSG("lsIdle begin ls_secs=%u\n", getPref_ls_secs()); // DEBUG_MSG("lsIdle begin ls_secs=%u\n", getPref_ls_secs());
#ifndef NO_ESP32 #ifndef NO_ESP32
esp_sleep_source_t wakeCause = ESP_SLEEP_WAKEUP_UNDEFINED;
// Do we have more sleeping to do? // Do we have more sleeping to do?
if (secsSlept < getPref_ls_secs()) { if (secsSlept < getPref_ls_secs()) {
@@ -72,14 +60,14 @@ static void lsIdle()
// If some other service would stall sleep, don't let sleep happen yet // If some other service would stall sleep, don't let sleep happen yet
if (doPreflightSleep()) { if (doPreflightSleep()) {
setLed(false); // Never leave led on while in light sleep setLed(false); // Never leave led on while in light sleep
esp_sleep_source_t wakeCause2 = doLightSleep(sleepTime * 1000LL); wakeCause = doLightSleep(sleepTime * 1000LL);
switch (wakeCause2) { switch (wakeCause) {
case ESP_SLEEP_WAKEUP_TIMER: case ESP_SLEEP_WAKEUP_TIMER:
// Normal case: timer expired, we should just go back to sleep ASAP // Normal case: timer expired, we should just go back to sleep ASAP
setLed(true); // briefly turn on led setLed(true); // briefly turn on led
wakeCause2 = doLightSleep(1); // leave led on for 1ms wakeCause = doLightSleep(1); // leave led on for 1ms
secsSlept += sleepTime; secsSlept += sleepTime;
// DEBUG_MSG("sleeping, flash led!\n"); // DEBUG_MSG("sleeping, flash led!\n");
@@ -93,7 +81,7 @@ static void lsIdle()
default: default:
// We woke for some other reason (button press, device interrupt) // We woke for some other reason (button press, device interrupt)
// uint64_t status = esp_sleep_get_ext1_wakeup_status(); // uint64_t status = esp_sleep_get_ext1_wakeup_status();
DEBUG_MSG("wakeCause2 %d\n", wakeCause2); DEBUG_MSG("wakeCause %d\n", wakeCause);
#ifdef BUTTON_PIN #ifdef BUTTON_PIN
bool pressed = !digitalRead(BUTTON_PIN); bool pressed = !digitalRead(BUTTON_PIN);
@@ -125,7 +113,6 @@ static void lsIdle()
static void lsExit() static void lsExit()
{ {
DEBUG_MSG("Exit state: LS\n");
// setGPSPower(true); // restore GPS power // setGPSPower(true); // restore GPS power
if (gps) if (gps)
gps->forceWake(true); gps->forceWake(true);
@@ -133,7 +120,6 @@ static void lsExit()
static void nbEnter() static void nbEnter()
{ {
DEBUG_MSG("Enter state: NB\n");
screen->setOn(false); screen->setOn(false);
setBluetoothEnable(false); setBluetoothEnable(false);
@@ -148,7 +134,6 @@ static void darkEnter()
static void serialEnter() static void serialEnter()
{ {
DEBUG_MSG("Enter state: SERIAL\n");
setBluetoothEnable(false); setBluetoothEnable(false);
screen->setOn(true); screen->setOn(true);
screen->print("Serial connected\n"); screen->print("Serial connected\n");
@@ -161,7 +146,6 @@ static void serialExit()
static void powerEnter() static void powerEnter()
{ {
DEBUG_MSG("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
DEBUG_MSG("Loss of power in Powered\n"); DEBUG_MSG("Loss of power in Powered\n");
@@ -191,7 +175,6 @@ static void powerExit()
static void onEnter() static void onEnter()
{ {
DEBUG_MSG("Enter state: ON\n");
screen->setOn(true); screen->setOn(true);
setBluetoothEnable(true); setBluetoothEnable(true);
@@ -220,12 +203,8 @@ static void screenPress()
screen->onPress(); screen->onPress();
} }
static void bootEnter() static void bootEnter() {}
{
DEBUG_MSG("Enter state: BOOT\n");
}
State stateSHUTDOWN(shutdownEnter, NULL, NULL, "SHUTDOWN");
State stateSDS(sdsEnter, NULL, NULL, "SDS"); State stateSDS(sdsEnter, NULL, NULL, "SDS");
State stateLS(lsEnter, lsIdle, lsExit, "LS"); State stateLS(lsEnter, lsIdle, lsExit, "LS");
State stateNB(nbEnter, NULL, NULL, "NB"); State stateNB(nbEnter, NULL, NULL, "NB");
@@ -248,11 +227,10 @@ void PowerFSM_setup()
// if we are a router node, we go to NB (no need for bluetooth) otherwise we go to DARK (so we can send message to phone) // if we are a router node, we go to NB (no need for bluetooth) otherwise we go to DARK (so we can send message to phone)
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_WAKE_TIMER, NULL, "Wake timer"); powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_WAKE_TIMER, NULL, "Wake timer");
// We need this transition, because we might not transition if we were waiting to enter light-sleep, because when we wake from // Note we don't really use this transition, because when we wake from light sleep we _always_ transition to NB or dark and
// light sleep we _always_ transition to NB or dark and // then it handles things powerFSM.add_transition(&stateLS, &stateNB, EVENT_RECEIVED_PACKET, NULL, "Received packet");
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_PACKET_FOR_PHONE, NULL,
"Received packet, exiting light sleep"); powerFSM.add_transition(&stateNB, &stateNB, EVENT_RECEIVED_PACKET, NULL, "Received packet, resetting win wake");
powerFSM.add_transition(&stateNB, &stateNB, EVENT_PACKET_FOR_PHONE, NULL, "Received packet, resetting win wake");
// Handle press events - note: we ignore button presses when in API mode // Handle press events - note: we ignore button presses when in API mode
powerFSM.add_transition(&stateLS, &stateON, EVENT_PRESS, NULL, "Press"); powerFSM.add_transition(&stateLS, &stateON, EVENT_PRESS, NULL, "Press");
@@ -271,22 +249,11 @@ void PowerFSM_setup()
powerFSM.add_transition(&stateON, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat"); powerFSM.add_transition(&stateON, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
powerFSM.add_transition(&stateSERIAL, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat"); powerFSM.add_transition(&stateSERIAL, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
// Handle being told to power off
powerFSM.add_transition(&stateBOOT, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
powerFSM.add_transition(&stateLS, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
powerFSM.add_transition(&stateNB, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
powerFSM.add_transition(&stateDARK, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
powerFSM.add_transition(&stateON, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
powerFSM.add_transition(&stateSERIAL, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
powerFSM.add_transition(&stateDARK, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing"); powerFSM.add_transition(&stateDARK, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing");
powerFSM.add_transition(&stateON, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing"); powerFSM.add_transition(&stateON, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing");
// if we are a router we don't turn the screen on for these things // if we are a router we don't turn the screen on for these things
if (!isRouter) { if (!isRouter) {
// if any packet destined for phone arrives, turn on bluetooth at least
powerFSM.add_transition(&stateNB, &stateDARK, EVENT_PACKET_FOR_PHONE, NULL, "Packet for phone");
// show the latest node when we get a new node db update // show the latest node when we get a new node db update
powerFSM.add_transition(&stateNB, &stateON, EVENT_NODEDB_UPDATED, NULL, "NodeDB update"); powerFSM.add_transition(&stateNB, &stateON, EVENT_NODEDB_UPDATED, NULL, "NodeDB update");
powerFSM.add_transition(&stateDARK, &stateON, EVENT_NODEDB_UPDATED, NULL, "NodeDB update"); powerFSM.add_transition(&stateDARK, &stateON, EVENT_NODEDB_UPDATED, NULL, "NodeDB update");
@@ -326,35 +293,26 @@ void PowerFSM_setup()
powerFSM.add_transition(&stateDARK, &stateON, EVENT_FIRMWARE_UPDATE, NULL, "Got firmware update"); powerFSM.add_transition(&stateDARK, &stateON, EVENT_FIRMWARE_UPDATE, NULL, "Got firmware update");
powerFSM.add_transition(&stateON, &stateON, EVENT_FIRMWARE_UPDATE, NULL, "Got firmware update"); powerFSM.add_transition(&stateON, &stateON, EVENT_FIRMWARE_UPDATE, NULL, "Got firmware update");
powerFSM.add_transition(&stateNB, &stateDARK, EVENT_PACKET_FOR_PHONE, NULL, "Packet for phone");
powerFSM.add_timed_transition(&stateON, &stateDARK, getPref_screen_on_secs() * 1000, NULL, "Screen-on timeout"); powerFSM.add_timed_transition(&stateON, &stateDARK, getPref_screen_on_secs() * 1000, NULL, "Screen-on timeout");
// On most boards we use light-sleep to be our main state, but on NRF52 we just stay in DARK // On most boards we use light-sleep to be our main state, but on NRF52 we just stay in DARK
State *lowPowerState = &stateLS; State *lowPowerState = &stateLS;
uint32_t meshSds = 0;
#ifndef NRF52_SERIES #ifndef NRF52_SERIES
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally) // We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
// See: https://github.com/meshtastic/Meshtastic-device/issues/1071 // I don't think this transition is correct, turning off for now - @geeksville
if (isRouter || radioConfig.preferences.is_power_saving) { // powerFSM.add_timed_transition(&stateDARK, &stateNB, getPref_phone_timeout_secs() * 1000, NULL, "Phone timeout");
// I don't think this transition is correct, turning off for now - @geeksville
// powerFSM.add_timed_transition(&stateDARK, &stateNB, getPref_phone_timeout_secs() * 1000, NULL, "Phone timeout");
powerFSM.add_timed_transition(&stateNB, &stateLS, getPref_min_wake_secs() * 1000, NULL, "Min wake timeout");
powerFSM.add_timed_transition(&stateDARK, &stateLS, getPref_wait_bluetooth_secs() * 1000, NULL, "Bluetooth timeout");
meshSds = getPref_mesh_sds_timeout_secs();
} else {
meshSds = UINT32_MAX;
}
powerFSM.add_timed_transition(&stateNB, &stateLS, getPref_min_wake_secs() * 1000, NULL, "Min wake timeout");
powerFSM.add_timed_transition(&stateDARK, &stateLS, getPref_wait_bluetooth_secs() * 1000, NULL, "Bluetooth timeout");
#else #else
lowPowerState = &stateDARK; lowPowerState = &stateDARK;
meshSds = UINT32_MAX; // Workaround for now: Don't go into deep sleep on the RAK4631
#endif #endif
auto meshSds = getPref_mesh_sds_timeout_secs();
if (meshSds != UINT32_MAX) if (meshSds != UINT32_MAX)
powerFSM.add_timed_transition(lowPowerState, &stateSDS, meshSds * 1000, NULL, "mesh timeout"); powerFSM.add_timed_transition(lowPowerState, &stateSDS, meshSds * 1000, NULL, "mesh timeout");
// removing for now, because some users don't even have phones // removing for now, because some users don't even have phones

View File

@@ -6,7 +6,7 @@
#define EVENT_PRESS 1 #define EVENT_PRESS 1
#define EVENT_WAKE_TIMER 2 #define EVENT_WAKE_TIMER 2
// #define EVENT_RECEIVED_PACKET 3 #define EVENT_RECEIVED_PACKET 3
#define EVENT_PACKET_FOR_PHONE 4 #define EVENT_PACKET_FOR_PHONE 4
#define EVENT_RECEIVED_TEXT_MSG 5 #define EVENT_RECEIVED_TEXT_MSG 5
// #define EVENT_BOOT 6 // now done with a timed transition // #define EVENT_BOOT 6 // now done with a timed transition
@@ -19,7 +19,6 @@
#define EVENT_POWER_CONNECTED 13 #define EVENT_POWER_CONNECTED 13
#define EVENT_POWER_DISCONNECTED 14 #define EVENT_POWER_DISCONNECTED 14
#define EVENT_FIRMWARE_UPDATE 15 // We just received a new firmware update packet from the phone #define EVENT_FIRMWARE_UPDATE 15 // We just received a new firmware update packet from the phone
#define EVENT_SHUTDOWN 16 //force a full shutdown now (not just sleep)
extern Fsm powerFSM; extern Fsm powerFSM;
extern State statePOWER, stateSERIAL; extern State statePOWER, stateSERIAL;

View File

@@ -1,7 +0,0 @@
// TODO refactor this out with better radio configuration system
#ifdef USE_RF95
#define RF95_RESET LORA_RESET
#define RF95_IRQ LORA_DIO0 // on SX1262 version this is a no connect DIO0
#define RF95_DIO1 LORA_DIO1 // Note: not really used for RF95
#define RF95_DIO2 LORA_DIO2 // Note: not really used for RF95
#endif

View File

@@ -1,12 +1,10 @@
#include "configuration.h"
#include "RedirectablePrint.h" #include "RedirectablePrint.h"
#include "RTC.h" #include "RTC.h"
#include "concurrency/OSThread.h" #include "concurrency/OSThread.h"
// #include "wifi/WiFiServerAPI.h" #include "configuration.h"
#include <assert.h> #include <assert.h>
#include <sys/time.h> #include <sys/time.h>
#include <time.h> #include <time.h>
#include <cstring>
/** /**
* A printer that doesn't go anywhere * A printer that doesn't go anywhere
@@ -26,10 +24,6 @@ size_t RedirectablePrint::write(uint8_t c)
SEGGER_RTT_PutChar(SEGGER_STDOUT_CH, c); SEGGER_RTT_PutChar(SEGGER_STDOUT_CH, c);
#endif #endif
// FIXME - clean this up, the whole relationship of this class to SerialConsole to TCP/bluetooth debug log output is kinda messed up. But for now, just have this hack to
// optionally send chars to TCP also
//WiFiServerPort::debugOut(c);
dest->write(c); dest->write(c);
return 1; // We always claim one was written, rather than trusting what the return 1; // We always claim one was written, rather than trusting what the
// serial port said (which could be zero) // serial port said (which could be zero)

View File

@@ -22,7 +22,7 @@ class RedirectablePrint : public Print
volatile bool inDebugPrint = false; volatile bool inDebugPrint = false;
public: public:
explicit RedirectablePrint(Print *_dest) : dest(_dest) {} RedirectablePrint(Print *_dest) : dest(_dest) {}
/** /**
* Set a new destination * Set a new destination
@@ -56,4 +56,4 @@ class NoopPrint : public Print
/** /**
* A printer that doesn't go anywhere * A printer that doesn't go anywhere
*/ */
extern NoopPrint noopPrint; extern NoopPrint noopPrint;

View File

@@ -1,4 +1,3 @@
#include "configuration.h"
#include "SPILock.h" #include "SPILock.h"
#include <Arduino.h> #include <Arduino.h>
#include <assert.h> #include <assert.h>

View File

@@ -1,7 +1,8 @@
#include "configuration.h"
#include "SerialConsole.h" #include "SerialConsole.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "PowerFSM.h" #include "PowerFSM.h"
#include "configuration.h"
#include <Arduino.h>
#define Port Serial #define Port Serial

View File

@@ -15,9 +15,9 @@ class SerialConsole : public StreamAPI, public RedirectablePrint
* we override this to notice when we've received a protobuf over the serial stream. Then we shunt off * we override this to notice when we've received a protobuf over the serial stream. Then we shunt off
* debug serial output. * debug serial output.
*/ */
virtual bool handleToRadio(const uint8_t *buf, size_t len) override; virtual bool handleToRadio(const uint8_t *buf, size_t len);
virtual size_t write(uint8_t c) override virtual size_t write(uint8_t c)
{ {
if (c == '\n') // prefix any newlines with carriage return if (c == '\n') // prefix any newlines with carriage return
RedirectablePrint::write('\r'); RedirectablePrint::write('\r');
@@ -27,7 +27,7 @@ class SerialConsole : public StreamAPI, public RedirectablePrint
protected: protected:
/// Check the current underlying physical link to see if the client is currently connected /// Check the current underlying physical link to see if the client is currently connected
virtual bool checkIsConnected() override; virtual bool checkIsConnected();
}; };
// A simple wrapper to allow non class aware code write to the console // A simple wrapper to allow non class aware code write to the console

View File

@@ -1,187 +1,107 @@
#include "airtime.h" #include "airtime.h"
#include "NodeDB.h" #include <Arduino.h>
#include "configuration.h"
AirTime *airTime = NULL; #define periodsToLog 48
AirTime *airTime;
uint32_t secondsPerPeriod = 3600;
uint32_t lastMillis = 0;
uint32_t secSinceBoot = 0;
// AirTime at;
// Don't read out of this directly. Use the helper functions. // Don't read out of this directly. Use the helper functions.
struct airtimeStruct {
uint32_t periodTX[periodsToLog]; // AirTime transmitted
uint32_t periodRX[periodsToLog]; // AirTime received and repeated (Only valid mesh packets)
uint32_t periodRX_ALL[periodsToLog]; // AirTime received regardless of valid mesh packet. Could include noise.
uint8_t lastPeriodIndex;
} airtimes;
void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms) void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms)
{ {
if (reportType == TX_LOG) { if (reportType == TX_LOG) {
DEBUG_MSG("AirTime - Packet transmitted : %ums\n", airtime_ms); DEBUG_MSG("AirTime - Packet transmitted : %ums\n", airtime_ms);
this->airtimes.periodTX[0] = this->airtimes.periodTX[0] + airtime_ms; airtimes.periodTX[0] = airtimes.periodTX[0] + airtime_ms;
myNodeInfo.air_period_tx[0] = myNodeInfo.air_period_tx[0] + airtime_ms;
this->utilizationTX[this->getPeriodUtilHour()] = this->utilizationTX[this->getPeriodUtilHour()] + airtime_ms;
} else if (reportType == RX_LOG) { } else if (reportType == RX_LOG) {
DEBUG_MSG("AirTime - Packet received : %ums\n", airtime_ms); DEBUG_MSG("AirTime - Packet received : %ums\n", airtime_ms);
this->airtimes.periodRX[0] = this->airtimes.periodRX[0] + airtime_ms; airtimes.periodRX[0] = airtimes.periodRX[0] + airtime_ms;
myNodeInfo.air_period_rx[0] = myNodeInfo.air_period_rx[0] + airtime_ms;
} else if (reportType == RX_ALL_LOG) { } else if (reportType == RX_ALL_LOG) {
DEBUG_MSG("AirTime - Packet received (noise?) : %ums\n", airtime_ms); DEBUG_MSG("AirTime - Packet received (noise?) : %ums\n", airtime_ms);
this->airtimes.periodRX_ALL[0] = this->airtimes.periodRX_ALL[0] + airtime_ms; airtimes.periodRX_ALL[0] = airtimes.periodRX_ALL[0] + airtime_ms;
} else {
DEBUG_MSG("AirTime - Unknown report time. This should never happen!!\n");
} }
// Log all airtime type for channel utilization
this->channelUtilization[this->getPeriodUtilMinute()] = channelUtilization[this->getPeriodUtilMinute()] + airtime_ms;
} }
uint8_t AirTime::currentPeriodIndex() uint8_t currentPeriodIndex()
{ {
return ((getSecondsSinceBoot() / SECONDS_PER_PERIOD) % PERIODS_TO_LOG); return ((getSecondsSinceBoot() / secondsPerPeriod) % periodsToLog);
} }
uint8_t AirTime::getPeriodUtilMinute() { void airtimeRotatePeriod()
return (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS;
}
uint8_t AirTime::getPeriodUtilHour() {
return (getSecondsSinceBoot() / 60) % MINUTES_IN_HOUR;
}
void AirTime::airtimeRotatePeriod()
{ {
if (this->airtimes.lastPeriodIndex != this->currentPeriodIndex()) { if (airtimes.lastPeriodIndex != currentPeriodIndex()) {
DEBUG_MSG("Rotating airtimes to a new period = %u\n", this->currentPeriodIndex()); DEBUG_MSG("Rotating airtimes to a new period = %u\n", currentPeriodIndex());
for (int i = PERIODS_TO_LOG - 2; i >= 0; --i) { for (int i = periodsToLog - 2; i >= 0; --i) {
this->airtimes.periodTX[i + 1] = this->airtimes.periodTX[i]; airtimes.periodTX[i + 1] = airtimes.periodTX[i];
this->airtimes.periodRX[i + 1] = this->airtimes.periodRX[i]; airtimes.periodRX[i + 1] = airtimes.periodRX[i];
this->airtimes.periodRX_ALL[i + 1] = this->airtimes.periodRX_ALL[i]; airtimes.periodRX_ALL[i + 1] = airtimes.periodRX_ALL[i];
myNodeInfo.air_period_tx[i + 1] = this->airtimes.periodTX[i];
myNodeInfo.air_period_rx[i + 1] = this->airtimes.periodRX[i];
} }
airtimes.periodTX[0] = 0;
airtimes.periodRX[0] = 0;
airtimes.periodRX_ALL[0] = 0;
this->airtimes.periodTX[0] = 0; airtimes.lastPeriodIndex = currentPeriodIndex();
this->airtimes.periodRX[0] = 0;
this->airtimes.periodRX_ALL[0] = 0;
myNodeInfo.air_period_tx[0] = 0;
myNodeInfo.air_period_rx[0] = 0;
this->airtimes.lastPeriodIndex = this->currentPeriodIndex();
} }
} }
uint32_t *AirTime::airtimeReport(reportTypes reportType) uint32_t *airtimeReport(reportTypes reportType)
{ {
if (reportType == TX_LOG) { if (reportType == TX_LOG) {
return this->airtimes.periodTX; return airtimes.periodTX;
} else if (reportType == RX_LOG) { } else if (reportType == RX_LOG) {
return this->airtimes.periodRX; return airtimes.periodRX;
} else if (reportType == RX_ALL_LOG) { } else if (reportType == RX_ALL_LOG) {
return this->airtimes.periodRX_ALL; return airtimes.periodRX_ALL;
} }
return 0; return 0;
} }
uint8_t AirTime::getPeriodsToLog() uint8_t getPeriodsToLog()
{ {
return PERIODS_TO_LOG; return periodsToLog;
} }
uint32_t AirTime::getSecondsPerPeriod() uint32_t getSecondsPerPeriod()
{ {
return SECONDS_PER_PERIOD; return secondsPerPeriod;
} }
uint32_t AirTime::getSecondsSinceBoot() uint32_t getSecondsSinceBoot()
{ {
return this->secSinceBoot; return secSinceBoot;
} }
float AirTime::channelUtilizationPercent() AirTime::AirTime() : concurrency::OSThread("AirTime") {}
{
uint32_t sum = 0;
for (uint32_t i = 0; i < CHANNEL_UTILIZATION_PERIODS; i++) {
sum += this->channelUtilization[i];
// DEBUG_MSG("ChanUtilArray %u %u\n", i, this->channelUtilization[i]);
}
return (float(sum) / float(CHANNEL_UTILIZATION_PERIODS * 10 * 1000)) * 100;
}
float AirTime::utilizationTXPercent()
{
uint32_t sum = 0;
for (uint32_t i = 0; i < MINUTES_IN_HOUR; i++) {
sum += this->utilizationTX[i];
}
return (float(sum) / float(MS_IN_HOUR)) * 100;
}
AirTime::AirTime() : concurrency::OSThread("AirTime"),airtimes({}) {
}
int32_t AirTime::runOnce() int32_t AirTime::runOnce()
{ {
//DEBUG_MSG("AirTime::runOnce()\n");
airtimeRotatePeriod();
secSinceBoot++; secSinceBoot++;
uint8_t utilPeriod = this->getPeriodUtilMinute(); /*
uint8_t utilPeriodTX = this->getPeriodUtilHour(); This actually doesn't need to be run once per second but we currently use it for the
secSinceBoot counter.
if (firstTime) { If we have a better counter of how long the device has been online (and not millis())
then we can change this to something less frequent. Maybe once ever 5 seconds?
// Init utilizationTX window to all 0 */
for (uint32_t i = 0; i < MINUTES_IN_HOUR; i++) {
this->utilizationTX[i] = 0;
}
// Init channelUtilization window to all 0
for (uint32_t i = 0; i < CHANNEL_UTILIZATION_PERIODS; i++) {
this->channelUtilization[i] = 0;
}
// Init airtime windows to all 0
for (int i = 0; i < PERIODS_TO_LOG; i++) {
this->airtimes.periodTX[i] = 0;
this->airtimes.periodRX[i] = 0;
this->airtimes.periodRX_ALL[i] = 0;
// myNodeInfo.air_period_tx[i] = 0;
// myNodeInfo.air_period_rx[i] = 0;
}
firstTime = false;
lastUtilPeriod = utilPeriod;
} else {
this->airtimeRotatePeriod();
// Reset the channelUtilization window when we roll over
if (lastUtilPeriod != utilPeriod) {
lastUtilPeriod = utilPeriod;
this->channelUtilization[utilPeriod] = 0;
}
if (lastUtilPeriodTX != utilPeriodTX) {
lastUtilPeriodTX = utilPeriodTX;
this->utilizationTX[utilPeriodTX] = 0;
}
// Update channel_utilization every second.
myNodeInfo.channel_utilization = airTime->channelUtilizationPercent();
// Update channel_utilization every second.
myNodeInfo.air_util_tx = airTime->utilizationTXPercent();
}
/*
DEBUG_MSG("utilPeriodTX %d TX Airtime %3.2f%\n", utilPeriodTX, airTime->utilizationTXPercent());
for (uint32_t i = 0; i < MINUTES_IN_HOUR; i++) {
DEBUG_MSG(
"%d,", this->utilizationTX[i]
);
}
DEBUG_MSG("\n");
*/
return (1000 * 1); return (1000 * 1);
} }

View File

@@ -23,21 +23,21 @@
RX_ALL_LOG - RX_LOG = Other lora radios on our frequency channel. RX_ALL_LOG - RX_LOG = Other lora radios on our frequency channel.
*/ */
#define CHANNEL_UTILIZATION_PERIODS 6
#define SECONDS_PER_PERIOD 3600
#define PERIODS_TO_LOG 24
#define MINUTES_IN_HOUR 60
#define SECONDS_IN_MINUTE 60
#define MS_IN_HOUR (MINUTES_IN_HOUR * SECONDS_IN_MINUTE * 1000)
enum reportTypes { TX_LOG, RX_LOG, RX_ALL_LOG }; enum reportTypes { TX_LOG, RX_LOG, RX_ALL_LOG };
void logAirtime(reportTypes reportType, uint32_t airtime_ms); void logAirtime(reportTypes reportType, uint32_t airtime_ms);
void airtimeRotatePeriod();
uint8_t currentPeriodIndex();
uint8_t getPeriodsToLog();
uint32_t getSecondsSinceBoot();
uint32_t *airtimeReport(reportTypes reportType); uint32_t *airtimeReport(reportTypes reportType);
uint32_t getSecondsPerPeriod();
class AirTime : private concurrency::OSThread class AirTime : private concurrency::OSThread
{ {
@@ -45,38 +45,9 @@ class AirTime : private concurrency::OSThread
AirTime(); AirTime();
void logAirtime(reportTypes reportType, uint32_t airtime_ms); void logAirtime(reportTypes reportType, uint32_t airtime_ms);
float channelUtilizationPercent();
float utilizationTXPercent();
float UtilizationPercentTX();
uint32_t channelUtilization[CHANNEL_UTILIZATION_PERIODS] = {0};
uint32_t utilizationTX[MINUTES_IN_HOUR] = {0};
void airtimeRotatePeriod();
uint8_t getPeriodsToLog();
uint32_t getSecondsPerPeriod();
uint32_t getSecondsSinceBoot();
uint32_t *airtimeReport(reportTypes reportType);
private:
bool firstTime = true;
uint8_t lastUtilPeriod = 0;
uint8_t lastUtilPeriodTX = 0;
uint32_t secSinceBoot = 0;
struct airtimeStruct {
uint32_t periodTX[PERIODS_TO_LOG]; // AirTime transmitted
uint32_t periodRX[PERIODS_TO_LOG]; // AirTime received and repeated (Only valid mesh packets)
uint32_t periodRX_ALL[PERIODS_TO_LOG]; // AirTime received regardless of valid mesh packet. Could include noise.
uint8_t lastPeriodIndex;
} airtimes;
uint8_t getPeriodUtilMinute();
uint8_t getPeriodUtilHour();
uint8_t currentPeriodIndex();
protected: protected:
virtual int32_t runOnce() override; virtual int32_t runOnce() override;
}; };
extern AirTime *airTime; extern AirTime *airTime;

View File

@@ -13,5 +13,4 @@ enum class Cmd {
STOP_BLUETOOTH_PIN_SCREEN, STOP_BLUETOOTH_PIN_SCREEN,
STOP_BOOT_SCREEN, STOP_BOOT_SCREEN,
PRINT, PRINT,
START_SHUTDOWN_SCREEN,
}; };

View File

@@ -1,5 +1,5 @@
#include "configuration.h"
#include "concurrency/BinarySemaphoreFreeRTOS.h" #include "concurrency/BinarySemaphoreFreeRTOS.h"
#include "configuration.h"
#include <assert.h> #include <assert.h>
#ifdef HAS_FREE_RTOS #ifdef HAS_FREE_RTOS
@@ -7,8 +7,9 @@
namespace concurrency namespace concurrency
{ {
BinarySemaphoreFreeRTOS::BinarySemaphoreFreeRTOS() : semaphore(xSemaphoreCreateBinary()) BinarySemaphoreFreeRTOS::BinarySemaphoreFreeRTOS()
{ {
semaphore = xSemaphoreCreateBinary();
assert(semaphore); assert(semaphore);
} }
@@ -37,4 +38,4 @@ IRAM_ATTR void BinarySemaphoreFreeRTOS::giveFromISR(BaseType_t *pxHigherPriority
} // namespace concurrency } // namespace concurrency
#endif #endif

View File

@@ -1,5 +1,5 @@
#include "configuration.h"
#include "concurrency/BinarySemaphorePosix.h" #include "concurrency/BinarySemaphorePosix.h"
#include "configuration.h"
#ifndef HAS_FREE_RTOS #ifndef HAS_FREE_RTOS

View File

@@ -1,5 +1,5 @@
#include "configuration.h"
#include "concurrency/InterruptableDelay.h" #include "concurrency/InterruptableDelay.h"
#include "configuration.h"
namespace concurrency namespace concurrency
{ {

View File

@@ -1,4 +1,3 @@
#include "configuration.h"
#include "Lock.h" #include "Lock.h"
#include <cassert> #include <cassert>
@@ -6,8 +5,9 @@ namespace concurrency
{ {
#ifdef HAS_FREE_RTOS #ifdef HAS_FREE_RTOS
Lock::Lock() : handle(xSemaphoreCreateBinary()) Lock::Lock()
{ {
handle = xSemaphoreCreateBinary();
assert(handle); assert(handle);
assert(xSemaphoreGive(handle)); assert(xSemaphoreGive(handle));
} }

View File

@@ -1,4 +1,3 @@
#include "configuration.h"
#include "LockGuard.h" #include "LockGuard.h"
namespace concurrency { namespace concurrency {

View File

@@ -10,7 +10,7 @@ namespace concurrency {
class LockGuard class LockGuard
{ {
public: public:
explicit LockGuard(Lock *lock); LockGuard(Lock *lock);
~LockGuard(); ~LockGuard();
LockGuard(const LockGuard &) = delete; LockGuard(const LockGuard &) = delete;

View File

@@ -1,5 +1,5 @@
#include "configuration.h"
#include "NotifiedWorkerThread.h" #include "NotifiedWorkerThread.h"
#include "configuration.h"
#include "main.h" #include "main.h"
#include <assert.h> #include <assert.h>
@@ -72,21 +72,14 @@ bool NotifiedWorkerThread::notifyLater(uint32_t delay, uint32_t v, bool overwrit
return didIt; return didIt;
} }
void NotifiedWorkerThread::checkNotification() int32_t NotifiedWorkerThread::runOnce()
{ {
auto n = notification; auto n = notification;
enabled = false; // Only run once per notification
notification = 0; // clear notification notification = 0; // clear notification
if (n) { if (n) {
onNotify(n); onNotify(n);
} }
}
int32_t NotifiedWorkerThread::runOnce()
{
enabled = false; // Only run once per notification
checkNotification();
return RUN_SAME; return RUN_SAME;
} }

View File

@@ -38,13 +38,7 @@ class NotifiedWorkerThread : public OSThread
protected: protected:
virtual void onNotify(uint32_t notification) = 0; virtual void onNotify(uint32_t notification) = 0;
/// just calls checkNotification() virtual int32_t runOnce();
virtual int32_t runOnce() override;
/// Sometimes we might want to check notifications independently of when our thread was getting woken up (i.e. if we are about to change
/// radio transmit/receive modes we want to handle any pending interrupts first). You can call this method and if any notifications are currently
/// pending they will be handled immediately.
void checkNotification();
private: private:
/** /**

View File

@@ -1,5 +1,5 @@
#include "configuration.h"
#include "OSThread.h" #include "OSThread.h"
#include "configuration.h"
#include <assert.h> #include <assert.h>
namespace concurrency namespace concurrency

View File

@@ -18,7 +18,7 @@ class Periodic : public OSThread
Periodic(const char *name, int32_t (*_callback)()) : OSThread(name), callback(_callback) {} Periodic(const char *name, int32_t (*_callback)()) : OSThread(name), callback(_callback) {}
protected: protected:
int32_t runOnce() override { return callback(); } int32_t runOnce() { return callback(); }
}; };
} // namespace concurrency } // namespace concurrency

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