mirror of
https://github.com/meshtastic/firmware.git
synced 2025-04-23 00:58:14 +00:00
Merge branch 'master' into apollo
This commit is contained in:
commit
7d9b2ef3c4
3
.github/workflows/main_matrix.yml
vendored
3
.github/workflows/main_matrix.yml
vendored
@ -245,7 +245,8 @@ jobs:
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
outputs:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
needs: [
|
||||
needs:
|
||||
[
|
||||
gather-artifacts,
|
||||
package-raspbian,
|
||||
package-raspbian-armv7l,
|
||||
|
3
.github/workflows/package_amd64.yml
vendored
3
.github/workflows/package_amd64.yml
vendored
@ -50,11 +50,14 @@ jobs:
|
||||
mkdir -p .debpkg/usr/share/doc/meshtasticd/web
|
||||
mkdir -p .debpkg/usr/sbin
|
||||
mkdir -p .debpkg/etc/meshtasticd
|
||||
mkdir -p .debpkg/etc/meshtasticd/config.d
|
||||
mkdir -p .debpkg/etc/meshtasticd/available.d
|
||||
mkdir -p .debpkg/usr/lib/systemd/system/
|
||||
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
|
||||
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
|
||||
cp release/meshtasticd_linux_x86_64 .debpkg/usr/sbin/meshtasticd
|
||||
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
|
||||
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/
|
||||
chmod +x .debpkg/usr/sbin/meshtasticd
|
||||
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
|
||||
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles
|
||||
|
3
.github/workflows/package_raspbian.yml
vendored
3
.github/workflows/package_raspbian.yml
vendored
@ -50,11 +50,14 @@ jobs:
|
||||
mkdir -p .debpkg/usr/share/doc/meshtasticd/web
|
||||
mkdir -p .debpkg/usr/sbin
|
||||
mkdir -p .debpkg/etc/meshtasticd
|
||||
mkdir -p .debpkg/etc/meshtasticd/config.d
|
||||
mkdir -p .debpkg/etc/meshtasticd/available.d
|
||||
mkdir -p .debpkg/usr/lib/systemd/system/
|
||||
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
|
||||
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
|
||||
cp release/meshtasticd_linux_aarch64 .debpkg/usr/sbin/meshtasticd
|
||||
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
|
||||
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/
|
||||
chmod +x .debpkg/usr/sbin/meshtasticd
|
||||
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
|
||||
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles
|
||||
|
@ -50,11 +50,14 @@ jobs:
|
||||
mkdir -p .debpkg/usr/share/doc/meshtasticd/web
|
||||
mkdir -p .debpkg/usr/sbin
|
||||
mkdir -p .debpkg/etc/meshtasticd
|
||||
mkdir -p .debpkg/etc/meshtasticd/config.d
|
||||
mkdir -p .debpkg/etc/meshtasticd/available.d
|
||||
mkdir -p .debpkg/usr/lib/systemd/system/
|
||||
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
|
||||
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
|
||||
cp release/meshtasticd_linux_armv7l .debpkg/usr/sbin/meshtasticd
|
||||
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
|
||||
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/
|
||||
chmod +x .debpkg/usr/sbin/meshtasticd
|
||||
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
|
||||
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles
|
||||
|
21
.github/workflows/stale_bot.yml
vendored
Normal file
21
.github/workflows/stale_bot.yml
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
name: process stale Issues and PR's
|
||||
on:
|
||||
schedule:
|
||||
- cron: 0 6 * * *
|
||||
workflow_dispatch: {}
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
stale_issues:
|
||||
name: Close Stale Issues
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Stale PR+Issues
|
||||
uses: actions/stale@v9.0.0
|
||||
with:
|
||||
exempt-issue-labels: pinned,3.0
|
||||
exempt-pr-labels: pinned,3.0
|
43
.github/workflows/trunk_format_pr.yml
vendored
Normal file
43
.github/workflows/trunk_format_pr.yml
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
name: Run Trunk Fmt on PR Comment
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
trunk-fmt:
|
||||
if: github.event.issue.pull_request != null && contains(github.event.comment.body, 'trunk fmt')
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Install trunk
|
||||
run: curl https://get.trunk.io -fsSL | bash
|
||||
|
||||
- name: Run Trunk Fmt
|
||||
run: trunk fmt
|
||||
|
||||
- name: Commit and push changes
|
||||
run: |
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add .
|
||||
git commit -m "Add firmware version ${{ steps.version.outputs.version }}"
|
||||
git push
|
||||
|
||||
- name: Comment on PR
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
github.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: '`trunk fmt` has been run on this PR.'
|
||||
})
|
@ -1,22 +1,22 @@
|
||||
version: 0.1
|
||||
cli:
|
||||
version: 1.22.6
|
||||
version: 1.22.7
|
||||
plugins:
|
||||
sources:
|
||||
- id: trunk
|
||||
ref: v1.6.3
|
||||
ref: v1.6.4
|
||||
uri: https://github.com/trunk-io/plugins
|
||||
lint:
|
||||
enabled:
|
||||
- trufflehog@3.82.6
|
||||
- trufflehog@3.83.2
|
||||
- yamllint@1.35.1
|
||||
- bandit@1.7.10
|
||||
- checkov@3.2.256
|
||||
- terrascan@1.19.1
|
||||
- trivy@0.55.2
|
||||
- checkov@3.2.276
|
||||
- terrascan@1.19.9
|
||||
- trivy@0.56.2
|
||||
#- trufflehog@3.63.2-rc0
|
||||
- taplo@0.9.3
|
||||
- ruff@0.6.8
|
||||
- ruff@0.7.1
|
||||
- isort@5.13.2
|
||||
- markdownlint@0.42.0
|
||||
- oxipng@9.1.2
|
||||
@ -26,9 +26,9 @@ lint:
|
||||
- hadolint@2.12.0
|
||||
- shfmt@3.6.0
|
||||
- shellcheck@0.10.0
|
||||
- black@24.8.0
|
||||
- black@24.10.0
|
||||
- git-diff-check
|
||||
- gitleaks@8.20.0
|
||||
- gitleaks@8.21.1
|
||||
- clang-format@16.0.3
|
||||
- prettier@3.3.3
|
||||
ignore:
|
||||
|
4
CODE_OF_CONDUCT.md
Normal file
4
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,4 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
The Meshtastic Firmware project is subject to the code of conduct for the parent project, which can be found here:
|
||||
https://meshtastic.org/docs/legal/conduct/
|
@ -37,7 +37,7 @@ build_flags =
|
||||
-DCONFIG_BT_NIMBLE_ENABLED
|
||||
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
|
||||
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
|
||||
-DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5120
|
||||
-DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=8192
|
||||
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
|
||||
-DSERIAL_BUFFER_SIZE=4096
|
||||
-DLIBPAX_ARDUINO
|
||||
|
@ -34,4 +34,5 @@ lib_deps=
|
||||
rweather/Crypto@^0.4.0
|
||||
|
||||
lib_ignore =
|
||||
BluetoothOTA
|
||||
BluetoothOTA
|
||||
lvgl
|
||||
|
@ -25,7 +25,7 @@ lib_deps =
|
||||
${env.lib_deps}
|
||||
${networking_base.lib_deps}
|
||||
rweather/Crypto@^0.4.0
|
||||
lovyan03/LovyanGFX@^1.1.16
|
||||
https://github.com/lovyan03/LovyanGFX.git#1401c28a47646fe00538d487adcb2eb3c72de805
|
||||
|
||||
build_flags =
|
||||
${arduino_base.build_flags}
|
||||
|
@ -26,8 +26,9 @@ build_src_filter =
|
||||
|
||||
lib_ignore =
|
||||
BluetoothOTA
|
||||
lvgl
|
||||
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
${environmental_base.lib_deps}
|
||||
rweather/Crypto
|
||||
rweather/Crypto
|
||||
|
@ -1,15 +1,11 @@
|
||||
### Many device configs have been moved to /etc/meshtasticd/available.d
|
||||
### To activate, simply copy or link the appropriate file into /etc/meshtasticd/config.d
|
||||
|
||||
### Define your devices here using Broadcom pin numbering
|
||||
### Uncomment the block that corresponds to your hardware
|
||||
### Including the "Module:" line!
|
||||
---
|
||||
Lora:
|
||||
# Module: sx1262 # Waveshare SX126X XXXM
|
||||
# DIO2_AS_RF_SWITCH: true
|
||||
# CS: 21
|
||||
# IRQ: 16
|
||||
# Busy: 20
|
||||
# Reset: 18
|
||||
# SX126X_ANT_SW: 6
|
||||
|
||||
# Module: sx1262 # Waveshare SX1302 LISTEN ONLY AT THIS TIME!
|
||||
# CS: 7
|
||||
@ -115,6 +111,29 @@ Display:
|
||||
# Height: 320
|
||||
# Rotate: true
|
||||
|
||||
### SHCHV 3.5 RPi TFT+Touchscreen
|
||||
# Panel: ILI9486
|
||||
# spidev: spidev0.0
|
||||
# BusFrequency: 30000000
|
||||
# DC: 24
|
||||
# Reset: 25
|
||||
# Width: 320
|
||||
# Height: 480
|
||||
# OffsetRotate: 2
|
||||
|
||||
### TZT 2.0 Inch TFT Display ST7789V 240RGBx320
|
||||
# Panel: ST7789
|
||||
# spidev: spidev0.0
|
||||
# # CS: 8 # can be freely chosen
|
||||
# BusFrequency: 80000000
|
||||
# DC: 24 # can be freely chosen
|
||||
# Width: 320
|
||||
# Height: 240
|
||||
# Reset: 25 # can be freely chosen
|
||||
# Rotate: true
|
||||
# OffsetRotate: 1
|
||||
# Invert: true
|
||||
|
||||
### You can also specify the spi device for the display to use
|
||||
# spidev: spidev0.0
|
||||
|
||||
@ -156,3 +175,4 @@ Webserver:
|
||||
General:
|
||||
MaxNodes: 200
|
||||
MaxMessageQueue: 100
|
||||
ConfigDirectory: /etc/meshtasticd/config.d/
|
18
bin/config.d/display-waveshare-2.8.yaml
Normal file
18
bin/config.d/display-waveshare-2.8.yaml
Normal file
@ -0,0 +1,18 @@
|
||||
Display:
|
||||
|
||||
### Waveshare 2.8inch RPi LCD
|
||||
Panel: ST7789
|
||||
CS: 8
|
||||
DC: 22 # Data/Command pin
|
||||
Backlight: 18
|
||||
Width: 240
|
||||
Height: 320
|
||||
Reset: 27
|
||||
Rotate: true
|
||||
Invert: true
|
||||
|
||||
Touchscreen:
|
||||
### Note, at least for now, the touchscreen must have a CS pin defined, even if you let Linux manage the CS switching.
|
||||
Module: XPT2046 # Waveshare 2.8inch
|
||||
CS: 7
|
||||
IRQ: 17
|
8
bin/config.d/lora-waveshare-sxxx.yaml
Normal file
8
bin/config.d/lora-waveshare-sxxx.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
Lora:
|
||||
Module: sx1262 # Waveshare SX126X XXXM
|
||||
DIO2_AS_RF_SWITCH: true
|
||||
CS: 21
|
||||
IRQ: 16
|
||||
Busy: 20
|
||||
Reset: 18
|
||||
SX126X_ANT_SW: 6
|
@ -28,6 +28,8 @@
|
||||
"flash_size": "8MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 8388608,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": true,
|
||||
"require_upload_port": true,
|
||||
"speed": 921600
|
||||
},
|
||||
|
41
boards/icarus.json
Normal file
41
boards/icarus.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32s3_out.ld",
|
||||
"memory_type": "qio_opi"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DBOARD_HAS_PSRAM",
|
||||
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||
"-DARDUINO_USB_MODE=0",
|
||||
"-DARDUINO_RUNNING_CORE=1",
|
||||
"-DARDUINO_EVENT_RUNNING_CORE=0"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "qio",
|
||||
"hwids": [["0x2886", "0x0059"]],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "icarus"
|
||||
},
|
||||
"connectivity": ["wifi", "bluetooth", "lora"],
|
||||
"debug": {
|
||||
"default_tool": "esp-builtin",
|
||||
"onboard_tools": ["esp-builtin"],
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
"frameworks": ["arduino", "espidf"],
|
||||
"name": "icarus",
|
||||
"upload": {
|
||||
"flash_size": "8MB",
|
||||
"maximum_ram_size": 8388608,
|
||||
"maximum_size": 8388608,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": true,
|
||||
"require_upload_port": true,
|
||||
"speed": 921600
|
||||
},
|
||||
"url": "https://icarus.azlan.works",
|
||||
"vendor": "Muhammad Shah"
|
||||
}
|
46
boards/unphone.json
Normal file
46
boards/unphone.json
Normal file
@ -0,0 +1,46 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32s3_out.ld",
|
||||
"memory_type": "qio_opi",
|
||||
"partitions": "default_8MB.csv"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DBOARD_HAS_PSRAM",
|
||||
"-DUNPHONE_SPIN=9",
|
||||
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||
"-DARDUINO_USB_MODE=0",
|
||||
"-DARDUINO_RUNNING_CORE=1",
|
||||
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "qio",
|
||||
"hwids": [
|
||||
["0x16D0", "0x1178"],
|
||||
["0x303a", "0x1001"]
|
||||
],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "unphone"
|
||||
},
|
||||
"connectivity": ["wifi", "bluetooth", "lora"],
|
||||
"debug": {
|
||||
"default_tool": "esp-builtin",
|
||||
"onboard_tools": ["esp-builtin"],
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
"frameworks": ["arduino", "espidf"],
|
||||
"name": "unPhone",
|
||||
"upload": {
|
||||
"flash_size": "8MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 8323072,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": true,
|
||||
"require_upload_port": true,
|
||||
"speed": 921600
|
||||
},
|
||||
"url": "https://unphone.net/",
|
||||
"vendor": "University of Sheffield"
|
||||
}
|
@ -1 +1 @@
|
||||
Subproject commit 7960241ccdd6b262a11b79523857037f755ab847
|
||||
Subproject commit 015202aead5f6807d63537c58f4cb6525f19e56f
|
@ -154,9 +154,16 @@ static void adcEnable()
|
||||
#ifdef ADC_CTRL // enable adc voltage divider when we need to read
|
||||
#ifdef ADC_USE_PULLUP
|
||||
pinMode(ADC_CTRL, INPUT_PULLUP);
|
||||
#else
|
||||
#ifdef HELTEC_V3
|
||||
pinMode(ADC_CTRL, INPUT);
|
||||
uint8_t adc_ctl_enable_value = !(digitalRead(ADC_CTRL));
|
||||
pinMode(ADC_CTRL, OUTPUT);
|
||||
digitalWrite(ADC_CTRL, adc_ctl_enable_value);
|
||||
#else
|
||||
pinMode(ADC_CTRL, OUTPUT);
|
||||
digitalWrite(ADC_CTRL, ADC_CTRL_ENABLED);
|
||||
#endif
|
||||
#endif
|
||||
delay(10);
|
||||
#endif
|
||||
@ -167,10 +174,14 @@ static void adcDisable()
|
||||
#ifdef ADC_CTRL // disable adc voltage divider when we need to read
|
||||
#ifdef ADC_USE_PULLUP
|
||||
pinMode(ADC_CTRL, INPUT_PULLDOWN);
|
||||
#else
|
||||
#ifdef HELTEC_V3
|
||||
pinMode(ADC_CTRL, ANALOG);
|
||||
#else
|
||||
digitalWrite(ADC_CTRL, !ADC_CTRL_ENABLED);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -207,6 +207,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef GPS_BAUDRATE
|
||||
#define GPS_BAUDRATE 9600
|
||||
#define GPS_BAUDRATE_FIXED 0
|
||||
#else
|
||||
#define GPS_BAUDRATE_FIXED 1
|
||||
#endif
|
||||
|
||||
/* Step #2: follow with defines common to the architecture;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#ifdef ARCH_PORTDUINO
|
||||
#include "PortduinoGlue.h"
|
||||
#include "meshUtils.h"
|
||||
#include <algorithm>
|
||||
#include <ctime>
|
||||
#endif
|
||||
|
||||
@ -412,30 +413,42 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Setup the GPS based on the model detected.
|
||||
* We detect the GPS by cycling through a set of baud rates, first common then rare.
|
||||
* For each baud rate, we run GPS::Probe to send commands and match the responses
|
||||
* to known GPS responses.
|
||||
* @retval Whether setup reached the end of its potential to configure the GPS.
|
||||
*/
|
||||
bool GPS::setup()
|
||||
{
|
||||
|
||||
if (!didSerialInit) {
|
||||
int msglen = 0;
|
||||
if (tx_gpio && gnssModel == GNSS_MODEL_UNKNOWN) {
|
||||
|
||||
// if GPS_BAUDRATE is specified in variant (i.e. not 9600), skip to the specified rate.
|
||||
if (speedSelect == 0 && GPS_BAUDRATE != serialSpeeds[speedSelect]) {
|
||||
speedSelect = std::find(serialSpeeds, std::end(serialSpeeds), GPS_BAUDRATE) - serialSpeeds;
|
||||
if (probeTries < 2) {
|
||||
LOG_DEBUG("Probing for GPS at %d", serialSpeeds[speedSelect]);
|
||||
gnssModel = probe(serialSpeeds[speedSelect]);
|
||||
if (gnssModel == GNSS_MODEL_UNKNOWN) {
|
||||
if (++speedSelect == sizeof(serialSpeeds) / sizeof(int)) {
|
||||
speedSelect = 0;
|
||||
++probeTries;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG("Probing for GPS at %d", serialSpeeds[speedSelect]);
|
||||
gnssModel = probe(serialSpeeds[speedSelect]);
|
||||
if (gnssModel == GNSS_MODEL_UNKNOWN) {
|
||||
if (++speedSelect == sizeof(serialSpeeds) / sizeof(int)) {
|
||||
speedSelect = 0;
|
||||
if (--probeTries == 0) {
|
||||
LOG_WARN("Giving up on GPS probe and setting to 9600.");
|
||||
// Rare Serial Speeds
|
||||
if (probeTries == 2) {
|
||||
LOG_DEBUG("Probing for GPS at %d", rareSerialSpeeds[speedSelect]);
|
||||
gnssModel = probe(rareSerialSpeeds[speedSelect]);
|
||||
if (gnssModel == GNSS_MODEL_UNKNOWN) {
|
||||
if (++speedSelect == sizeof(rareSerialSpeeds) / sizeof(int)) {
|
||||
LOG_WARN("Giving up on GPS probe and setting to %d", GPS_BAUDRATE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
} else {
|
||||
gnssModel = GNSS_MODEL_UNKNOWN;
|
||||
}
|
||||
@ -475,6 +488,18 @@ bool GPS::setup()
|
||||
// Switch to Fitness Mode, for running and walking purpose with low speed (<5 m/s)
|
||||
_serial_gps->write("$PMTK886,1*29\r\n");
|
||||
delay(250);
|
||||
} else if (gnssModel == GNSS_MODEL_MTK_PA1616S) {
|
||||
// PA1616S is used in some GPS breakout boards from Adafruit
|
||||
// PA1616S does not have GLONASS capability. PA1616D does, but is not implemented here.
|
||||
_serial_gps->write("$PMTK353,1,0,0,0,0*2A\r\n");
|
||||
// Above command will reset the GPS and takes longer before it will accept new commands
|
||||
delay(1000);
|
||||
// Only ask for RMC and GGA (GNRMC and GNGGA)
|
||||
_serial_gps->write("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n");
|
||||
delay(250);
|
||||
// Enable SBAS / WAAS
|
||||
_serial_gps->write("$PMTK301,2*2E\r\n");
|
||||
delay(250);
|
||||
} else if (gnssModel == GNSS_MODEL_ATGM336H) {
|
||||
// Set the intial configuration of the device - these _should_ work for most AT6558 devices
|
||||
msglen = makeCASPacket(0x06, 0x07, sizeof(_message_CAS_CFG_NAVX_CONF), _message_CAS_CFG_NAVX_CONF);
|
||||
@ -662,7 +687,8 @@ bool GPS::setup()
|
||||
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_SBAS_BBR, "disable SBAS M10 GPS BBR", 300);
|
||||
delay(750); // will cause a receiver restart so wait a bit
|
||||
|
||||
// Done with initialization, Now enable wanted NMEA messages in BBR layer so they will survive a periodic sleep.
|
||||
// Done with initialization, Now enable wanted NMEA messages in BBR layer so they will survive a periodic
|
||||
// sleep.
|
||||
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ENABLE_NMEA_BBR, "enable messages for M10 GPS BBR", 300);
|
||||
delay(750);
|
||||
// Next enable wanted NMEA messages in RAM layer
|
||||
@ -924,10 +950,10 @@ void GPS::down()
|
||||
#endif
|
||||
|
||||
if (softsleepSupported) {
|
||||
// How long does gps_update_interval need to be, for GPS_HARDSLEEP to become more efficient than GPS_SOFTSLEEP?
|
||||
// Heuristic equation. A compromise manually fitted to power observations from U-blox NEO-6M and M10050
|
||||
// https://www.desmos.com/calculator/6gvjghoumr
|
||||
// This is not particularly accurate, but probably an impromevement over a single, fixed threshold
|
||||
// How long does gps_update_interval need to be, for GPS_HARDSLEEP to become more efficient than
|
||||
// GPS_SOFTSLEEP? Heuristic equation. A compromise manually fitted to power observations from U-blox NEO-6M
|
||||
// and M10050 https://www.desmos.com/calculator/6gvjghoumr This is not particularly accurate, but probably an
|
||||
// improvement over a single, fixed threshold
|
||||
uint32_t hardsleepThreshold = (2750 * pow(predictedSearchDuration / 1000, 1.22));
|
||||
LOG_DEBUG("gps_update_interval >= %us needed to justify hardsleep", hardsleepThreshold / 1000);
|
||||
|
||||
@ -1143,6 +1169,7 @@ GnssModel_t GPS::probe(int serialSpeed)
|
||||
delay(20);
|
||||
|
||||
PROBE_SIMPLE("L76B", "$PMTK605*31", "Quectel-L76B", GNSS_MODEL_MTK_L76B, 500);
|
||||
PROBE_SIMPLE("PA1616S", "$PMTK605*31", "1616S", GNSS_MODEL_MTK_PA1616S, 500);
|
||||
|
||||
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00};
|
||||
UBXChecksum(cfg_rate, sizeof(cfg_rate));
|
||||
@ -1279,10 +1306,12 @@ GPS *GPS::createGps()
|
||||
|
||||
if (!GPS_EN_ACTIVE) { // Need to invert the pin before hardware
|
||||
new GpioNotTransformer(
|
||||
virtPin, p); // We just leave this created object on the heap so it can stay watching virtPin and driving en_gpio
|
||||
virtPin,
|
||||
p); // We just leave this created object on the heap so it can stay watching virtPin and driving en_gpio
|
||||
} else {
|
||||
new GpioUnaryTransformer(
|
||||
virtPin, p); // We just leave this created object on the heap so it can stay watching virtPin and driving en_gpio
|
||||
virtPin,
|
||||
p); // We just leave this created object on the heap so it can stay watching virtPin and driving en_gpio
|
||||
}
|
||||
}
|
||||
|
||||
@ -1390,8 +1419,8 @@ bool GPS::factoryReset()
|
||||
_serial_gps->write("$PMTK104*37\r\n");
|
||||
// No PMTK_ACK for this command.
|
||||
delay(100);
|
||||
// send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's UBLOX.
|
||||
// Factory Reset
|
||||
// send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's
|
||||
// UBLOX. Factory Reset
|
||||
byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFB, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
|
||||
_serial_gps->write(_message_reset, sizeof(_message_reset));
|
||||
@ -1430,8 +1459,8 @@ bool GPS::lookForTime()
|
||||
auto d = reader.date;
|
||||
if (ti.isValid() && d.isValid()) { // Note: we don't check for updated, because we'll only be called if needed
|
||||
/* Convert to unix time
|
||||
The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970
|
||||
(midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
|
||||
The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1,
|
||||
1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
|
||||
*/
|
||||
struct tm t;
|
||||
t.tm_sec = ti.second() + round(ti.age() / 1000);
|
||||
@ -1664,7 +1693,9 @@ bool GPS::whileActive()
|
||||
}
|
||||
}
|
||||
#ifdef GPS_DEBUG
|
||||
LOG_DEBUG(debugmsg.c_str());
|
||||
if (debugmsg != "") {
|
||||
LOG_DEBUG(debugmsg.c_str());
|
||||
}
|
||||
#endif
|
||||
return isValid;
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ typedef enum {
|
||||
GNSS_MODEL_UC6580,
|
||||
GNSS_MODEL_UNKNOWN,
|
||||
GNSS_MODEL_MTK_L76B,
|
||||
GNSS_MODEL_MTK_PA1616S,
|
||||
GNSS_MODEL_AG3335,
|
||||
GNSS_MODEL_AG3352
|
||||
} GnssModel_t;
|
||||
@ -75,13 +76,21 @@ class GPS : private concurrency::OSThread
|
||||
uint8_t fixType = 0; // fix type from GPGSA
|
||||
#endif
|
||||
private:
|
||||
const int serialSpeeds[6] = {9600, 115200, 38400, 4800, 57600, 9600};
|
||||
#if GPS_BAUDRATE_FIXED
|
||||
// if GPS_BAUDRATE is specified in variant, only try that.
|
||||
const int serialSpeeds[1] = {GPS_BAUDRATE};
|
||||
const int rareSerialSpeeds[1] = {GPS_BAUDRATE};
|
||||
#else
|
||||
const int serialSpeeds[3] = {9600, 115200, 38400};
|
||||
const int rareSerialSpeeds[3] = {4800, 57600, GPS_BAUDRATE};
|
||||
#endif
|
||||
|
||||
uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0, lastFixStartMsec = 0;
|
||||
uint32_t rx_gpio = 0;
|
||||
uint32_t tx_gpio = 0;
|
||||
|
||||
int speedSelect = 0;
|
||||
int probeTries = 2;
|
||||
int probeTries = 0;
|
||||
|
||||
/**
|
||||
* hasValidLocation - indicates that the position variables contain a complete
|
||||
|
@ -70,9 +70,9 @@ bool GPSUpdateScheduling::isUpdateDue()
|
||||
// Have we been searching for a GPS position for too long?
|
||||
bool GPSUpdateScheduling::searchedTooLong()
|
||||
{
|
||||
uint32_t maxSearchMs =
|
||||
Default::getConfiguredOrDefaultMs(config.position.position_broadcast_secs, default_broadcast_interval_secs);
|
||||
|
||||
uint32_t minimumOrConfiguredSecs =
|
||||
Default::getConfiguredOrMinimumValue(config.position.position_broadcast_secs, default_broadcast_interval_secs);
|
||||
uint32_t maxSearchMs = Default::getConfiguredOrDefaultMs(minimumOrConfiguredSecs, default_broadcast_interval_secs);
|
||||
// If broadcast interval set to max, no such thing as "too long"
|
||||
if (maxSearchMs == UINT32_MAX)
|
||||
return false;
|
||||
@ -115,4 +115,4 @@ void GPSUpdateScheduling::updateLockTimePrediction()
|
||||
uint32_t GPSUpdateScheduling::predictedSearchDurationMs()
|
||||
{
|
||||
return GPSUpdateScheduling::predictedMsToGetLock;
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ int32_t ScanAndSelectInput::runOnce()
|
||||
// If: "no messages added" alert screen currently shown
|
||||
if (alertingNoMessage) {
|
||||
// Dismiss the alert screen several seconds after it appears
|
||||
if (now > alertingSinceMs + durationAlertMs) {
|
||||
if (!Throttle::isWithinTimespanMs(alertingSinceMs, durationAlertMs)) {
|
||||
alertingNoMessage = false;
|
||||
screen->endAlert();
|
||||
}
|
||||
@ -74,9 +74,9 @@ int32_t ScanAndSelectInput::runOnce()
|
||||
|
||||
// Existing press
|
||||
else {
|
||||
// Duration enough for long press
|
||||
// Longer than shortpress window
|
||||
// Long press not yet fired (prevent repeat firing while held)
|
||||
if (!longPressFired && Throttle::isWithinTimespanMs(downSinceMs, durationLongMs)) {
|
||||
if (!longPressFired && !Throttle::isWithinTimespanMs(downSinceMs, durationLongMs)) {
|
||||
longPressFired = true;
|
||||
longPress();
|
||||
}
|
||||
@ -91,7 +91,9 @@ int32_t ScanAndSelectInput::runOnce()
|
||||
// Button newly released
|
||||
// Long press event didn't already fire
|
||||
if (held && !longPressFired) {
|
||||
// Duration enough for short press
|
||||
// Duration within shortpress window
|
||||
// - longer than durationShortPress (debounce)
|
||||
// - shorter than durationLongPress
|
||||
if (!Throttle::isWithinTimespanMs(downSinceMs, durationShortMs)) {
|
||||
shortPress();
|
||||
}
|
||||
|
12
src/main.cpp
12
src/main.cpp
@ -267,14 +267,19 @@ void setup()
|
||||
#ifdef DEBUG_PORT
|
||||
consoleInit(); // Set serial baud rate and init our mesh console
|
||||
#endif
|
||||
|
||||
#ifdef UNPHONE
|
||||
unphone.printStore();
|
||||
#endif
|
||||
|
||||
#if ARCH_PORTDUINO
|
||||
struct timeval tv;
|
||||
tv.tv_sec = time(NULL);
|
||||
tv.tv_usec = 0;
|
||||
perhapsSetRTC(RTCQualityNTP, &tv);
|
||||
#endif
|
||||
powerMonInit();
|
||||
|
||||
powerMonInit();
|
||||
serialSinceMsec = millis();
|
||||
|
||||
LOG_INFO("\n\n//\\ E S H T /\\ S T / C\n");
|
||||
@ -643,6 +648,8 @@ void setup()
|
||||
rp2040Setup();
|
||||
#endif
|
||||
|
||||
initSPI(); // needed here before reading from littleFS
|
||||
|
||||
// We do this as early as possible because this loads preferences from flash
|
||||
// but we need to do this after main cpu init (esp32setup), because we need the random seed set
|
||||
nodeDB = new NodeDB;
|
||||
@ -706,7 +713,6 @@ void setup()
|
||||
#endif
|
||||
|
||||
// Init our SPI controller (must be before screen and lora)
|
||||
initSPI();
|
||||
#ifdef ARCH_RP2040
|
||||
#ifdef HW_SPI1_DEVICE
|
||||
SPI1.setSCK(LORA_SCK);
|
||||
@ -1190,4 +1196,4 @@ void loop()
|
||||
mainDelay.delay(delayMsec);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -32,6 +32,7 @@
|
||||
#if HAS_WIFI
|
||||
#include "mesh/wifi/WiFiAPClient.h"
|
||||
#endif
|
||||
#include "SPILock.h"
|
||||
#include "modules/StoreForwardModule.h"
|
||||
#include <Preferences.h>
|
||||
#include <esp_efuse.h>
|
||||
@ -136,11 +137,12 @@ NodeDB::NodeDB()
|
||||
memcpy(myNodeInfo.device_id.bytes, &device_id_start, sizeof(device_id_start));
|
||||
memcpy(myNodeInfo.device_id.bytes + sizeof(device_id_start), &device_id_end, sizeof(device_id_end));
|
||||
myNodeInfo.device_id.size = 16;
|
||||
hasUniqueId = true;
|
||||
// Uncomment below to print the device id
|
||||
// hasUniqueId = true;
|
||||
#else
|
||||
// FIXME - implement for other platforms
|
||||
#endif
|
||||
// Uncomment below to print the device id
|
||||
|
||||
// if (hasUniqueId) {
|
||||
// std::string deviceIdHex;
|
||||
// for (size_t i = 0; i < myNodeInfo.device_id.size; ++i) {
|
||||
@ -173,21 +175,23 @@ NodeDB::NodeDB()
|
||||
}
|
||||
|
||||
#if !(MESHTASTIC_EXCLUDE_PKI_KEYGEN || MESHTASTIC_EXCLUDE_PKI)
|
||||
bool keygenSuccess = false;
|
||||
if (config.security.private_key.size == 32) {
|
||||
if (crypto->regeneratePublicKey(config.security.public_key.bytes, config.security.private_key.bytes)) {
|
||||
if (!owner.is_licensed) {
|
||||
bool keygenSuccess = false;
|
||||
if (config.security.private_key.size == 32) {
|
||||
if (crypto->regeneratePublicKey(config.security.public_key.bytes, config.security.private_key.bytes)) {
|
||||
keygenSuccess = true;
|
||||
}
|
||||
} else {
|
||||
LOG_INFO("Generating new PKI keys");
|
||||
crypto->generateKeyPair(config.security.public_key.bytes, config.security.private_key.bytes);
|
||||
keygenSuccess = true;
|
||||
}
|
||||
} else {
|
||||
LOG_INFO("Generating new PKI keys");
|
||||
crypto->generateKeyPair(config.security.public_key.bytes, config.security.private_key.bytes);
|
||||
keygenSuccess = true;
|
||||
}
|
||||
if (keygenSuccess) {
|
||||
config.security.public_key.size = 32;
|
||||
config.security.private_key.size = 32;
|
||||
owner.public_key.size = 32;
|
||||
memcpy(owner.public_key.bytes, config.security.public_key.bytes, 32);
|
||||
if (keygenSuccess) {
|
||||
config.security.public_key.size = 32;
|
||||
config.security.private_key.size = 32;
|
||||
owner.public_key.size = 32;
|
||||
memcpy(owner.public_key.bytes, config.security.public_key.bytes, 32);
|
||||
}
|
||||
}
|
||||
#elif !(MESHTASTIC_EXCLUDE_PKI)
|
||||
// Calculate Curve25519 public and private keys
|
||||
@ -556,8 +560,10 @@ void NodeDB::installRoleDefaults(meshtastic_Config_DeviceConfig_Role role)
|
||||
if (role == meshtastic_Config_DeviceConfig_Role_ROUTER) {
|
||||
initConfigIntervals();
|
||||
initModuleConfigIntervals();
|
||||
config.device.rebroadcast_mode = meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY;
|
||||
} else if (role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
|
||||
config.display.screen_on_secs = 1;
|
||||
config.device.rebroadcast_mode = meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY;
|
||||
} else if (role == meshtastic_Config_DeviceConfig_Role_SENSOR) {
|
||||
moduleConfig.telemetry.environment_measurement_enabled = true;
|
||||
moduleConfig.telemetry.environment_update_interval = 300;
|
||||
@ -870,6 +876,9 @@ void NodeDB::loadFromDisk()
|
||||
bool NodeDB::saveProto(const char *filename, size_t protoSize, const pb_msgdesc_t *fields, const void *dest_struct,
|
||||
bool fullAtomic)
|
||||
{
|
||||
#ifdef ARCH_ESP32
|
||||
concurrency::LockGuard g(spiLock);
|
||||
#endif
|
||||
bool okay = false;
|
||||
#ifdef FSCom
|
||||
auto f = SafeFile(filename, fullAtomic);
|
||||
@ -1270,4 +1279,4 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co
|
||||
LOG_ERROR("A critical failure occurred, portduino is exiting...");
|
||||
exit(2);
|
||||
#endif
|
||||
}
|
||||
}
|
@ -271,7 +271,7 @@ uint32_t RadioInterface::getTxDelayMsecWeighted(float snr)
|
||||
if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ||
|
||||
config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
|
||||
delay = random(0, 2 * CWsize) * slotTimeMsec;
|
||||
LOG_DEBUG("rx_snr found in packet. As a router, setting tx delay:%d", delay);
|
||||
LOG_DEBUG("rx_snr found in packet. Router: setting tx delay:%d", delay);
|
||||
} else {
|
||||
// offset the maximum delay for routers: (2 * CWmax * slotTimeMsec)
|
||||
delay = (2 * CWmax * slotTimeMsec) + random(0, pow(2, CWsize)) * slotTimeMsec;
|
||||
|
@ -11,6 +11,10 @@
|
||||
#include <pb_decode.h>
|
||||
#include <pb_encode.h>
|
||||
|
||||
#if ARCH_PORTDUINO
|
||||
#include "PortduinoGlue.h"
|
||||
#include "meshUtils.h"
|
||||
#endif
|
||||
void LockingArduinoHal::spiBeginTransaction()
|
||||
{
|
||||
spiLock->lock();
|
||||
@ -20,9 +24,9 @@ void LockingArduinoHal::spiBeginTransaction()
|
||||
|
||||
void LockingArduinoHal::spiEndTransaction()
|
||||
{
|
||||
spiLock->unlock();
|
||||
|
||||
ArduinoHal::spiEndTransaction();
|
||||
|
||||
spiLock->unlock();
|
||||
}
|
||||
#if ARCH_PORTDUINO
|
||||
void LockingArduinoHal::spiTransfer(uint8_t *out, size_t len, uint8_t *in)
|
||||
@ -278,11 +282,14 @@ void RadioLibInterface::onNotify(uint32_t notification)
|
||||
// Send any outgoing packets we have ready
|
||||
meshtastic_MeshPacket *txp = txQueue.dequeue();
|
||||
assert(txp);
|
||||
bool isLoraTx = txp->to != NODENUM_BROADCAST_NO_LORA;
|
||||
startSend(txp);
|
||||
|
||||
// Packet has been sent, count it toward our TX airtime utilization.
|
||||
uint32_t xmitMsec = getPacketTime(txp);
|
||||
airTime->logAirtime(TX_LOG, xmitMsec);
|
||||
if (isLoraTx) {
|
||||
// Packet has been sent, count it toward our TX airtime utilization.
|
||||
uint32_t xmitMsec = getPacketTime(txp);
|
||||
airTime->logAirtime(TX_LOG, xmitMsec);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -390,6 +397,11 @@ void RadioLibInterface::handleReceiveInterrupt()
|
||||
#endif
|
||||
|
||||
int state = iface->readData((uint8_t *)&radioBuffer, length);
|
||||
#if ARCH_PORTDUINO
|
||||
if (settingsMap[logoutputlevel] == level_trace) {
|
||||
printBytes("Raw incoming packet: ", (uint8_t *)&radioBuffer, length);
|
||||
}
|
||||
#endif
|
||||
if (state != RADIOLIB_ERR_NONE) {
|
||||
LOG_ERROR("ignoring received packet due to error=%d", state);
|
||||
rxBad++;
|
||||
|
@ -81,14 +81,17 @@ int32_t Router::runOnce()
|
||||
*/
|
||||
void Router::enqueueReceivedMessage(meshtastic_MeshPacket *p)
|
||||
{
|
||||
if (fromRadioQueue.enqueue(p, 0)) { // NOWAIT - fixme, if queue is full, delete older messages
|
||||
|
||||
// Nasty hack because our threading is primitive. interfaces shouldn't need to know about routers FIXME
|
||||
setReceivedMessage();
|
||||
} else {
|
||||
printPacket("BUG! fromRadioQueue is full! Discarding!", p);
|
||||
packetPool.release(p);
|
||||
// Try enqueue until successful
|
||||
while (!fromRadioQueue.enqueue(p, 0)) {
|
||||
meshtastic_MeshPacket *old_p;
|
||||
old_p = fromRadioQueue.dequeuePtr(0); // Dequeue and discard the oldest packet
|
||||
if (old_p) {
|
||||
printPacket("fromRadioQ full, drop oldest!", old_p);
|
||||
packetPool.release(old_p);
|
||||
}
|
||||
}
|
||||
// Nasty hack because our threading is primitive. interfaces shouldn't need to know about routers FIXME
|
||||
setReceivedMessage();
|
||||
}
|
||||
|
||||
/// Generate a unique packet id
|
||||
@ -591,19 +594,20 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
|
||||
skipHandle = true;
|
||||
}
|
||||
|
||||
bool shouldIgnoreNonstandardPorts =
|
||||
config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY;
|
||||
#if USERPREFS_EVENT_MODE
|
||||
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
|
||||
(p->decoded.portnum == meshtastic_PortNum_ATAK_FORWARDER || p->decoded.portnum == meshtastic_PortNum_ATAK_PLUGIN ||
|
||||
p->decoded.portnum == meshtastic_PortNum_PAXCOUNTER_APP || p->decoded.portnum == meshtastic_PortNum_IP_TUNNEL_APP ||
|
||||
p->decoded.portnum == meshtastic_PortNum_AUDIO_APP || p->decoded.portnum == meshtastic_PortNum_PRIVATE_APP ||
|
||||
p->decoded.portnum == meshtastic_PortNum_DETECTION_SENSOR_APP ||
|
||||
p->decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP ||
|
||||
p->decoded.portnum == meshtastic_PortNum_REMOTE_HARDWARE_APP)) {
|
||||
LOG_DEBUG("Ignoring packet on blacklisted portnum during event");
|
||||
shouldIgnoreNonstandardPorts = true;
|
||||
#endif
|
||||
if (shouldIgnoreNonstandardPorts && p->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
|
||||
IS_ONE_OF(p->decoded.portnum, meshtastic_PortNum_ATAK_FORWARDER, meshtastic_PortNum_ATAK_PLUGIN,
|
||||
meshtastic_PortNum_PAXCOUNTER_APP, meshtastic_PortNum_IP_TUNNEL_APP, meshtastic_PortNum_AUDIO_APP,
|
||||
meshtastic_PortNum_PRIVATE_APP, meshtastic_PortNum_DETECTION_SENSOR_APP, meshtastic_PortNum_RANGE_TEST_APP,
|
||||
meshtastic_PortNum_REMOTE_HARDWARE_APP)) {
|
||||
LOG_DEBUG("Ignoring packet on blacklisted portnum for CORE_PORTNUMS_ONLY");
|
||||
cancelSending(p->from, p->id);
|
||||
skipHandle = true;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
printPacket("packet decoding failed or skipped (no PSK?)", p);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#ifndef PB_MESHTASTIC_MESHTASTIC_CONFIG_PB_H_INCLUDED
|
||||
#define PB_MESHTASTIC_MESHTASTIC_CONFIG_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
#include "meshtastic/device_ui.pb.h"
|
||||
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
@ -576,6 +577,7 @@ typedef struct _meshtastic_Config {
|
||||
meshtastic_Config_BluetoothConfig bluetooth;
|
||||
meshtastic_Config_SecurityConfig security;
|
||||
meshtastic_Config_SessionkeyConfig sessionkey;
|
||||
meshtastic_DeviceUIConfig device_ui;
|
||||
} payload_variant;
|
||||
} meshtastic_Config;
|
||||
|
||||
@ -779,6 +781,7 @@ extern "C" {
|
||||
#define meshtastic_Config_bluetooth_tag 7
|
||||
#define meshtastic_Config_security_tag 8
|
||||
#define meshtastic_Config_sessionkey_tag 9
|
||||
#define meshtastic_Config_device_ui_tag 10
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define meshtastic_Config_FIELDLIST(X, a) \
|
||||
@ -790,7 +793,8 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,display,payload_variant.disp
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,lora,payload_variant.lora), 6) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,bluetooth,payload_variant.bluetooth), 7) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,security,payload_variant.security), 8) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,sessionkey,payload_variant.sessionkey), 9)
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,sessionkey,payload_variant.sessionkey), 9) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,device_ui,payload_variant.device_ui), 10)
|
||||
#define meshtastic_Config_CALLBACK NULL
|
||||
#define meshtastic_Config_DEFAULT NULL
|
||||
#define meshtastic_Config_payload_variant_device_MSGTYPE meshtastic_Config_DeviceConfig
|
||||
@ -802,6 +806,7 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,sessionkey,payload_variant.s
|
||||
#define meshtastic_Config_payload_variant_bluetooth_MSGTYPE meshtastic_Config_BluetoothConfig
|
||||
#define meshtastic_Config_payload_variant_security_MSGTYPE meshtastic_Config_SecurityConfig
|
||||
#define meshtastic_Config_payload_variant_sessionkey_MSGTYPE meshtastic_Config_SessionkeyConfig
|
||||
#define meshtastic_Config_payload_variant_device_ui_MSGTYPE meshtastic_DeviceUIConfig
|
||||
|
||||
#define meshtastic_Config_DeviceConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UENUM, role, 1) \
|
||||
|
@ -40,7 +40,19 @@ typedef enum _meshtastic_Language {
|
||||
/* Polish */
|
||||
meshtastic_Language_POLISH = 8,
|
||||
/* Turkish */
|
||||
meshtastic_Language_TURKISH = 9
|
||||
meshtastic_Language_TURKISH = 9,
|
||||
/* Serbian */
|
||||
meshtastic_Language_SERBIAN = 10,
|
||||
/* Russian */
|
||||
meshtastic_Language_RUSSIAN = 11,
|
||||
/* Dutch */
|
||||
meshtastic_Language_DUTCH = 12,
|
||||
/* Greek */
|
||||
meshtastic_Language_GREEK = 13,
|
||||
/* Simplified Chinese (experimental) */
|
||||
meshtastic_Language_SIMPLIFIED_CHINESE = 30,
|
||||
/* Traditional Chinese (experimental) */
|
||||
meshtastic_Language_TRADITIONAL_CHINESE = 31
|
||||
} meshtastic_Language;
|
||||
|
||||
/* Struct definitions */
|
||||
@ -73,16 +85,22 @@ typedef struct _meshtastic_NodeHighlight {
|
||||
} meshtastic_NodeHighlight;
|
||||
|
||||
typedef struct _meshtastic_DeviceUIConfig {
|
||||
/* A version integer used to invalidate saved files when we make incompatible changes. */
|
||||
uint32_t version;
|
||||
/* TFT display brightness 1..255 */
|
||||
uint8_t screen_brightness;
|
||||
/* Screen timeout 0..900 */
|
||||
uint16_t screen_timeout;
|
||||
/* Screen lock enabled */
|
||||
/* Screen/Settings lock enabled */
|
||||
bool screen_lock;
|
||||
bool settings_lock;
|
||||
uint32_t pin_code;
|
||||
/* Color theme */
|
||||
meshtastic_Theme theme;
|
||||
/* Audible message alert enabled */
|
||||
/* Audible message, banner and ring tone */
|
||||
bool alert_enabled;
|
||||
bool banner_enabled;
|
||||
uint8_t ring_tone_id;
|
||||
/* Localization */
|
||||
meshtastic_Language language;
|
||||
/* Node list filter */
|
||||
@ -104,8 +122,8 @@ extern "C" {
|
||||
#define _meshtastic_Theme_ARRAYSIZE ((meshtastic_Theme)(meshtastic_Theme_RED+1))
|
||||
|
||||
#define _meshtastic_Language_MIN meshtastic_Language_ENGLISH
|
||||
#define _meshtastic_Language_MAX meshtastic_Language_TURKISH
|
||||
#define _meshtastic_Language_ARRAYSIZE ((meshtastic_Language)(meshtastic_Language_TURKISH+1))
|
||||
#define _meshtastic_Language_MAX meshtastic_Language_TRADITIONAL_CHINESE
|
||||
#define _meshtastic_Language_ARRAYSIZE ((meshtastic_Language)(meshtastic_Language_TRADITIONAL_CHINESE+1))
|
||||
|
||||
#define meshtastic_DeviceUIConfig_theme_ENUMTYPE meshtastic_Theme
|
||||
#define meshtastic_DeviceUIConfig_language_ENUMTYPE meshtastic_Language
|
||||
@ -114,10 +132,10 @@ extern "C" {
|
||||
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define meshtastic_DeviceUIConfig_init_default {0, 0, 0, _meshtastic_Theme_MIN, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_default, false, meshtastic_NodeHighlight_init_default}
|
||||
#define meshtastic_DeviceUIConfig_init_default {0, 0, 0, 0, 0, 0, _meshtastic_Theme_MIN, 0, 0, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_default, false, meshtastic_NodeHighlight_init_default}
|
||||
#define meshtastic_NodeFilter_init_default {0, 0, 0, 0, 0, ""}
|
||||
#define meshtastic_NodeHighlight_init_default {0, 0, 0, 0, ""}
|
||||
#define meshtastic_DeviceUIConfig_init_zero {0, 0, 0, _meshtastic_Theme_MIN, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_zero, false, meshtastic_NodeHighlight_init_zero}
|
||||
#define meshtastic_DeviceUIConfig_init_zero {0, 0, 0, 0, 0, 0, _meshtastic_Theme_MIN, 0, 0, 0, _meshtastic_Language_MIN, false, meshtastic_NodeFilter_init_zero, false, meshtastic_NodeHighlight_init_zero}
|
||||
#define meshtastic_NodeFilter_init_zero {0, 0, 0, 0, 0, ""}
|
||||
#define meshtastic_NodeHighlight_init_zero {0, 0, 0, 0, ""}
|
||||
|
||||
@ -133,25 +151,35 @@ extern "C" {
|
||||
#define meshtastic_NodeHighlight_telemetry_switch_tag 3
|
||||
#define meshtastic_NodeHighlight_iaq_switch_tag 4
|
||||
#define meshtastic_NodeHighlight_node_name_tag 5
|
||||
#define meshtastic_DeviceUIConfig_screen_brightness_tag 1
|
||||
#define meshtastic_DeviceUIConfig_screen_timeout_tag 2
|
||||
#define meshtastic_DeviceUIConfig_screen_lock_tag 3
|
||||
#define meshtastic_DeviceUIConfig_theme_tag 4
|
||||
#define meshtastic_DeviceUIConfig_alert_enabled_tag 5
|
||||
#define meshtastic_DeviceUIConfig_language_tag 6
|
||||
#define meshtastic_DeviceUIConfig_node_filter_tag 7
|
||||
#define meshtastic_DeviceUIConfig_node_highlight_tag 8
|
||||
#define meshtastic_DeviceUIConfig_version_tag 1
|
||||
#define meshtastic_DeviceUIConfig_screen_brightness_tag 2
|
||||
#define meshtastic_DeviceUIConfig_screen_timeout_tag 3
|
||||
#define meshtastic_DeviceUIConfig_screen_lock_tag 4
|
||||
#define meshtastic_DeviceUIConfig_settings_lock_tag 5
|
||||
#define meshtastic_DeviceUIConfig_pin_code_tag 6
|
||||
#define meshtastic_DeviceUIConfig_theme_tag 7
|
||||
#define meshtastic_DeviceUIConfig_alert_enabled_tag 8
|
||||
#define meshtastic_DeviceUIConfig_banner_enabled_tag 9
|
||||
#define meshtastic_DeviceUIConfig_ring_tone_id_tag 10
|
||||
#define meshtastic_DeviceUIConfig_language_tag 11
|
||||
#define meshtastic_DeviceUIConfig_node_filter_tag 12
|
||||
#define meshtastic_DeviceUIConfig_node_highlight_tag 13
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define meshtastic_DeviceUIConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, screen_brightness, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, screen_timeout, 2) \
|
||||
X(a, STATIC, SINGULAR, BOOL, screen_lock, 3) \
|
||||
X(a, STATIC, SINGULAR, UENUM, theme, 4) \
|
||||
X(a, STATIC, SINGULAR, BOOL, alert_enabled, 5) \
|
||||
X(a, STATIC, SINGULAR, UENUM, language, 6) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, node_filter, 7) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, node_highlight, 8)
|
||||
X(a, STATIC, SINGULAR, UINT32, version, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, screen_brightness, 2) \
|
||||
X(a, STATIC, SINGULAR, UINT32, screen_timeout, 3) \
|
||||
X(a, STATIC, SINGULAR, BOOL, screen_lock, 4) \
|
||||
X(a, STATIC, SINGULAR, BOOL, settings_lock, 5) \
|
||||
X(a, STATIC, SINGULAR, UINT32, pin_code, 6) \
|
||||
X(a, STATIC, SINGULAR, UENUM, theme, 7) \
|
||||
X(a, STATIC, SINGULAR, BOOL, alert_enabled, 8) \
|
||||
X(a, STATIC, SINGULAR, BOOL, banner_enabled, 9) \
|
||||
X(a, STATIC, SINGULAR, UINT32, ring_tone_id, 10) \
|
||||
X(a, STATIC, SINGULAR, UENUM, language, 11) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, node_filter, 12) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, node_highlight, 13)
|
||||
#define meshtastic_DeviceUIConfig_CALLBACK NULL
|
||||
#define meshtastic_DeviceUIConfig_DEFAULT NULL
|
||||
#define meshtastic_DeviceUIConfig_node_filter_MSGTYPE meshtastic_NodeFilter
|
||||
@ -187,7 +215,7 @@ extern const pb_msgdesc_t meshtastic_NodeHighlight_msg;
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define MESHTASTIC_MESHTASTIC_DEVICE_UI_PB_H_MAX_SIZE meshtastic_DeviceUIConfig_size
|
||||
#define meshtastic_DeviceUIConfig_size 80
|
||||
#define meshtastic_DeviceUIConfig_size 99
|
||||
#define meshtastic_NodeFilter_size 36
|
||||
#define meshtastic_NodeHighlight_size 25
|
||||
|
||||
|
@ -408,7 +408,7 @@ typedef enum _meshtastic_LogRecord_Level {
|
||||
} meshtastic_LogRecord_Level;
|
||||
|
||||
/* Struct definitions */
|
||||
/* a gps position */
|
||||
/* A GPS Position */
|
||||
typedef struct _meshtastic_Position {
|
||||
/* The new preferred location encoding, multiply by 1e-7 to get degrees
|
||||
in floating point */
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include "FSCommon.h"
|
||||
#include "mesh-pb-constants.h"
|
||||
#include <Arduino.h>
|
||||
#include <assert.h>
|
||||
#include <pb_decode.h>
|
||||
#include <pb_encode.h>
|
||||
|
||||
@ -14,8 +13,6 @@ size_t pb_encode_to_bytes(uint8_t *destbuf, size_t destbufsize, const pb_msgdesc
|
||||
pb_ostream_t stream = pb_ostream_from_buffer(destbuf, destbufsize);
|
||||
if (!pb_encode(&stream, fields, src_struct)) {
|
||||
LOG_ERROR("Panic: can't encode protobuf reason='%s'", PB_GET_ERROR(&stream));
|
||||
assert(
|
||||
0); // If this assert fails it probably means you made a field too large for the max limits specified in mesh.options
|
||||
return 0;
|
||||
} else {
|
||||
return stream.bytes_written;
|
||||
@ -71,4 +68,4 @@ bool is_in_helper(uint32_t n, const uint32_t *array, pb_size_t count)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -61,15 +61,13 @@ char *strnstr(const char *s, const char *find, size_t slen)
|
||||
void printBytes(const char *label, const uint8_t *p, size_t numbytes)
|
||||
{
|
||||
int labelSize = strlen(label);
|
||||
if (labelSize < 100 && numbytes < 64) {
|
||||
char *messageBuffer = new char[labelSize + (numbytes * 3) + 2];
|
||||
strncpy(messageBuffer, label, labelSize);
|
||||
for (size_t i = 0; i < numbytes; i++)
|
||||
snprintf(messageBuffer + labelSize + i * 3, 4, " %02x", p[i]);
|
||||
strcpy(messageBuffer + labelSize + numbytes * 3, "\n");
|
||||
LOG_DEBUG(messageBuffer);
|
||||
delete[] messageBuffer;
|
||||
}
|
||||
char *messageBuffer = new char[labelSize + (numbytes * 3) + 2];
|
||||
strncpy(messageBuffer, label, labelSize);
|
||||
for (size_t i = 0; i < numbytes; i++)
|
||||
snprintf(messageBuffer + labelSize + i * 3, 4, " %02x", p[i]);
|
||||
strcpy(messageBuffer + labelSize + numbytes * 3, "\n");
|
||||
LOG_DEBUG(messageBuffer);
|
||||
delete[] messageBuffer;
|
||||
}
|
||||
|
||||
bool memfll(const uint8_t *mem, uint8_t find, size_t numbytes)
|
||||
|
@ -900,7 +900,7 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r
|
||||
#ifdef ARCH_PORTDUINO
|
||||
conn.wifi.status.is_connected = true;
|
||||
#else
|
||||
conn.wifi.status.is_connected = WiFi.status() != WL_CONNECTED;
|
||||
conn.wifi.status.is_connected = WiFi.status() == WL_CONNECTED;
|
||||
#endif
|
||||
strncpy(conn.wifi.ssid, config.network.wifi_ssid, 33);
|
||||
if (conn.wifi.status.is_connected) {
|
||||
@ -932,10 +932,14 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r
|
||||
conn.has_bluetooth = true;
|
||||
conn.bluetooth.pin = config.bluetooth.fixed_pin;
|
||||
#ifdef ARCH_ESP32
|
||||
conn.bluetooth.is_connected = nimbleBluetooth->isConnected();
|
||||
conn.bluetooth.rssi = nimbleBluetooth->getRssi();
|
||||
if (config.bluetooth.enabled && nimbleBluetooth) {
|
||||
conn.bluetooth.is_connected = nimbleBluetooth->isConnected();
|
||||
conn.bluetooth.rssi = nimbleBluetooth->getRssi();
|
||||
}
|
||||
#elif defined(ARCH_NRF52)
|
||||
conn.bluetooth.is_connected = nrf52Bluetooth->isConnected();
|
||||
if (config.bluetooth.enabled && nrf52Bluetooth) {
|
||||
conn.bluetooth.is_connected = nrf52Bluetooth->isConnected();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
conn.has_serial = true; // No serial-less devices
|
||||
|
@ -93,7 +93,7 @@ int32_t ExternalNotificationModule::runOnce()
|
||||
nagCycleCutoff = UINT32_MAX;
|
||||
LOG_INFO("Turning off external notification: ");
|
||||
for (int i = 0; i < 3; i++) {
|
||||
setExternalOff(i);
|
||||
setExternalState(i, false);
|
||||
externalTurnedOn[i] = 0;
|
||||
LOG_INFO("%d ", i);
|
||||
}
|
||||
@ -114,17 +114,17 @@ int32_t ExternalNotificationModule::runOnce()
|
||||
if (externalTurnedOn[0] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms
|
||||
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) <
|
||||
millis()) {
|
||||
getExternal(0) ? setExternalOff(0) : setExternalOn(0);
|
||||
setExternalState(0, !getExternal(0));
|
||||
}
|
||||
if (externalTurnedOn[1] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms
|
||||
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) <
|
||||
millis()) {
|
||||
getExternal(1) ? setExternalOff(1) : setExternalOn(1);
|
||||
setExternalState(0, !getExternal(1));
|
||||
}
|
||||
if (externalTurnedOn[2] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms
|
||||
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) <
|
||||
millis()) {
|
||||
getExternal(2) ? setExternalOff(2) : setExternalOn(2);
|
||||
setExternalState(0, !getExternal(2));
|
||||
}
|
||||
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
|
||||
red = (colorState & 4) ? brightnessValues[brightnessIndex] : 0; // Red enabled on colorState = 4,5,6,7
|
||||
@ -184,7 +184,7 @@ int32_t ExternalNotificationModule::runOnce()
|
||||
}
|
||||
#endif
|
||||
// now let the PWM buzzer play
|
||||
if (moduleConfig.external_notification.use_pwm) {
|
||||
if (moduleConfig.external_notification.use_pwm && config.device.buzzer_gpio) {
|
||||
if (rtttl::isPlaying()) {
|
||||
rtttl::play();
|
||||
} else if (isNagging && (nagCycleCutoff >= millis())) {
|
||||
@ -203,86 +203,42 @@ bool ExternalNotificationModule::wantPacket(const meshtastic_MeshPacket *p)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the external notification on for the specified index.
|
||||
* Sets the external notification for the specified index.
|
||||
*
|
||||
* @param index The index of the external notification to turn on.
|
||||
* @param index The index of the external notification to change state.
|
||||
* @param on Whether we are turning things on (true) or off (false).
|
||||
*/
|
||||
void ExternalNotificationModule::setExternalOn(uint8_t index)
|
||||
void ExternalNotificationModule::setExternalState(uint8_t index, bool on)
|
||||
{
|
||||
externalCurrentState[index] = 1;
|
||||
externalCurrentState[index] = on;
|
||||
externalTurnedOn[index] = millis();
|
||||
|
||||
switch (index) {
|
||||
case 1:
|
||||
#ifdef UNPHONE
|
||||
unphone.vibe(true); // the unPhone's vibration motor is on a i2c GPIO expander
|
||||
unphone.vibe(on); // the unPhone's vibration motor is on a i2c GPIO expander
|
||||
#endif
|
||||
if (moduleConfig.external_notification.output_vibra)
|
||||
digitalWrite(moduleConfig.external_notification.output_vibra, true);
|
||||
digitalWrite(moduleConfig.external_notification.output_vibra, on);
|
||||
break;
|
||||
case 2:
|
||||
if (moduleConfig.external_notification.output_buzzer)
|
||||
digitalWrite(moduleConfig.external_notification.output_buzzer, true);
|
||||
digitalWrite(moduleConfig.external_notification.output_buzzer, on);
|
||||
break;
|
||||
default:
|
||||
if (output > 0)
|
||||
digitalWrite(output, (moduleConfig.external_notification.active ? true : false));
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef HAS_NCP5623
|
||||
if (rgb_found.type == ScanI2C::NCP5623) {
|
||||
rgb.setColor(red, green, blue);
|
||||
}
|
||||
#endif
|
||||
#ifdef RGBLED_CA
|
||||
analogWrite(RGBLED_RED, 255 - red); // CA type needs reverse logic
|
||||
analogWrite(RGBLED_GREEN, 255 - green);
|
||||
analogWrite(RGBLED_BLUE, 255 - blue);
|
||||
#elif defined(RGBLED_RED)
|
||||
analogWrite(RGBLED_RED, red);
|
||||
analogWrite(RGBLED_GREEN, green);
|
||||
analogWrite(RGBLED_BLUE, blue);
|
||||
#endif
|
||||
#ifdef HAS_NEOPIXEL
|
||||
pixels.fill(pixels.Color(red, green, blue), 0, NEOPIXEL_COUNT);
|
||||
pixels.show();
|
||||
#endif
|
||||
#ifdef UNPHONE
|
||||
unphone.rgb(red, green, blue);
|
||||
#endif
|
||||
#ifdef T_WATCH_S3
|
||||
drv.go();
|
||||
#endif
|
||||
}
|
||||
|
||||
void ExternalNotificationModule::setExternalOff(uint8_t index)
|
||||
{
|
||||
externalCurrentState[index] = 0;
|
||||
externalTurnedOn[index] = millis();
|
||||
|
||||
switch (index) {
|
||||
case 1:
|
||||
#ifdef UNPHONE
|
||||
unphone.vibe(false); // the unPhone's vibration motor is on a i2c GPIO expander
|
||||
#endif
|
||||
if (moduleConfig.external_notification.output_vibra)
|
||||
digitalWrite(moduleConfig.external_notification.output_vibra, false);
|
||||
break;
|
||||
case 2:
|
||||
if (moduleConfig.external_notification.output_buzzer)
|
||||
digitalWrite(moduleConfig.external_notification.output_buzzer, false);
|
||||
break;
|
||||
default:
|
||||
if (output > 0)
|
||||
digitalWrite(output, (moduleConfig.external_notification.active ? false : true));
|
||||
digitalWrite(output, (moduleConfig.external_notification.active ? on : !on));
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
|
||||
red = 0;
|
||||
green = 0;
|
||||
blue = 0;
|
||||
if (!on) {
|
||||
red = 0;
|
||||
green = 0;
|
||||
blue = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_NCP5623
|
||||
if (rgb_found.type == ScanI2C::NCP5623) {
|
||||
rgb.setColor(red, green, blue);
|
||||
@ -304,10 +260,12 @@ void ExternalNotificationModule::setExternalOff(uint8_t index)
|
||||
#ifdef UNPHONE
|
||||
unphone.rgb(red, green, blue);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef T_WATCH_S3
|
||||
drv.stop();
|
||||
if (on) {
|
||||
drv.go();
|
||||
} else {
|
||||
drv.stop();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -379,19 +337,19 @@ ExternalNotificationModule::ExternalNotificationModule()
|
||||
LOG_INFO("Using Pin %i in digital mode", output);
|
||||
pinMode(output, OUTPUT);
|
||||
}
|
||||
setExternalOff(0);
|
||||
setExternalState(0, false);
|
||||
externalTurnedOn[0] = 0;
|
||||
if (moduleConfig.external_notification.output_vibra) {
|
||||
LOG_INFO("Using Pin %i for vibra motor", moduleConfig.external_notification.output_vibra);
|
||||
pinMode(moduleConfig.external_notification.output_vibra, OUTPUT);
|
||||
setExternalOff(1);
|
||||
setExternalState(1, false);
|
||||
externalTurnedOn[1] = 0;
|
||||
}
|
||||
if (moduleConfig.external_notification.output_buzzer) {
|
||||
if (!moduleConfig.external_notification.use_pwm) {
|
||||
LOG_INFO("Using Pin %i for buzzer", moduleConfig.external_notification.output_buzzer);
|
||||
pinMode(moduleConfig.external_notification.output_buzzer, OUTPUT);
|
||||
setExternalOff(2);
|
||||
setExternalState(2, false);
|
||||
externalTurnedOn[2] = 0;
|
||||
} else {
|
||||
config.device.buzzer_gpio = config.device.buzzer_gpio ? config.device.buzzer_gpio : PIN_BUZZER;
|
||||
@ -449,7 +407,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
|
||||
if (containsBell) {
|
||||
LOG_INFO("externalNotificationModule - Notification Bell");
|
||||
isNagging = true;
|
||||
setExternalOn(0);
|
||||
setExternalState(0, true);
|
||||
if (moduleConfig.external_notification.nag_timeout) {
|
||||
nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000;
|
||||
} else {
|
||||
@ -462,7 +420,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
|
||||
if (containsBell) {
|
||||
LOG_INFO("externalNotificationModule - Notification Bell (Vibra)");
|
||||
isNagging = true;
|
||||
setExternalOn(1);
|
||||
setExternalState(1, true);
|
||||
if (moduleConfig.external_notification.nag_timeout) {
|
||||
nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000;
|
||||
} else {
|
||||
@ -476,7 +434,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
|
||||
LOG_INFO("externalNotificationModule - Notification Bell (Buzzer)");
|
||||
isNagging = true;
|
||||
if (!moduleConfig.external_notification.use_pwm) {
|
||||
setExternalOn(2);
|
||||
setExternalState(2, true);
|
||||
} else {
|
||||
#ifdef HAS_I2S
|
||||
audioThread->beginRttl(rtttlConfig.ringtone, strlen_P(rtttlConfig.ringtone));
|
||||
@ -495,7 +453,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
|
||||
if (moduleConfig.external_notification.alert_message) {
|
||||
LOG_INFO("externalNotificationModule - Notification Module");
|
||||
isNagging = true;
|
||||
setExternalOn(0);
|
||||
setExternalState(0, true);
|
||||
if (moduleConfig.external_notification.nag_timeout) {
|
||||
nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000;
|
||||
} else {
|
||||
@ -506,7 +464,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
|
||||
if (moduleConfig.external_notification.alert_message_vibra) {
|
||||
LOG_INFO("externalNotificationModule - Notification Module (Vibra)");
|
||||
isNagging = true;
|
||||
setExternalOn(1);
|
||||
setExternalState(1, true);
|
||||
if (moduleConfig.external_notification.nag_timeout) {
|
||||
nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000;
|
||||
} else {
|
||||
@ -518,7 +476,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
|
||||
LOG_INFO("externalNotificationModule - Notification Module (Buzzer)");
|
||||
isNagging = true;
|
||||
if (!moduleConfig.external_notification.use_pwm && !moduleConfig.external_notification.use_i2s_as_buzzer) {
|
||||
setExternalOn(2);
|
||||
setExternalState(2, true);
|
||||
} else {
|
||||
#ifdef HAS_I2S
|
||||
if (moduleConfig.external_notification.use_i2s_as_buzzer) {
|
||||
|
@ -32,10 +32,9 @@ class ExternalNotificationModule : public SinglePortModule, private concurrency:
|
||||
public:
|
||||
ExternalNotificationModule();
|
||||
|
||||
uint32_t nagCycleCutoff = UINT32_MAX;
|
||||
uint32_t nagCycleCutoff = 1;
|
||||
|
||||
void setExternalOn(uint8_t index = 0);
|
||||
void setExternalOff(uint8_t index = 0);
|
||||
void setExternalState(uint8_t index = 0, bool on = false);
|
||||
bool getExternal(uint8_t index = 0);
|
||||
|
||||
void setMute(bool mute) { isMuted = mute; }
|
||||
|
@ -121,9 +121,7 @@ Will be used for broadcast.
|
||||
*/
|
||||
int32_t NeighborInfoModule::runOnce()
|
||||
{
|
||||
if (airTime->isTxAllowedChannelUtil(true) && airTime->isTxAllowedAirUtil()) {
|
||||
sendNeighborInfo(NODENUM_BROADCAST_NO_LORA, false);
|
||||
}
|
||||
sendNeighborInfo(NODENUM_BROADCAST_NO_LORA, false);
|
||||
return Default::getConfiguredOrDefaultMs(moduleConfig.neighbor_info.update_interval, default_neighbor_info_broadcast_secs);
|
||||
}
|
||||
|
||||
|
@ -81,6 +81,12 @@ meshtastic_MeshPacket *NodeInfoModule::allocReply()
|
||||
ignoreRequest = false; // Don't ignore requests anymore
|
||||
meshtastic_User &u = owner;
|
||||
|
||||
// Strip the public key if the user is licensed
|
||||
if (u.is_licensed && u.public_key.size > 0) {
|
||||
u.public_key.bytes[0] = 0;
|
||||
u.public_key.size = 0;
|
||||
}
|
||||
|
||||
LOG_INFO("sending owner %s/%s/%s", u.id, u.long_name, u.short_name);
|
||||
lastSentToMesh = millis();
|
||||
return allocDataProtobuf(u);
|
||||
|
@ -315,7 +315,7 @@ ProcessMessage SerialModuleRadio::handleReceived(const meshtastic_MeshPacket &mp
|
||||
// LOG_DEBUG("Received text msg self=0x%0x, from=0x%0x, to=0x%0x, id=%d, msg=%.*s",
|
||||
// nodeDB->getNodeNum(), mp.from, mp.to, mp.id, p.payload.size, p.payload.bytes);
|
||||
|
||||
if (!isFromUs(&mp)) {
|
||||
if (isFromUs(&mp)) {
|
||||
|
||||
/*
|
||||
* If moduleConfig.serial.echo is true, then echo the packets that are sent out
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "QMA6100PSensor.h"
|
||||
|
||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && HAS_QMA6100P
|
||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && defined(HAS_QMA6100P)
|
||||
|
||||
// Flag when an interrupt has been detected
|
||||
volatile static bool QMA6100P_IRQ = false;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include "MotionSensor.h"
|
||||
|
||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && HAS_QMA6100P
|
||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && defined(HAS_QMA6100P)
|
||||
|
||||
#include <QMA6100P.h>
|
||||
|
||||
|
@ -51,7 +51,11 @@ void updateBatteryLevel(uint8_t level) {}
|
||||
|
||||
void getMacAddr(uint8_t *dmac)
|
||||
{
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32C6) && defined(CONFIG_SOC_IEEE802154_SUPPORTED)
|
||||
assert(esp_base_mac_addr_get(dmac) == ESP_OK);
|
||||
#else
|
||||
assert(esp_efuse_mac_get_default(dmac) == ESP_OK);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAS_32768HZ
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "PortduinoGlue.h"
|
||||
#include "linux/gpio/LinuxGPIOPin.h"
|
||||
#include "yaml-cpp/yaml.h"
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <unistd.h>
|
||||
@ -100,33 +101,22 @@ void portduinoSetup()
|
||||
settingsStrings[displayspidev] = "";
|
||||
settingsMap[spiSpeed] = 2000000;
|
||||
settingsMap[ascii_logs] = !isatty(1);
|
||||
settingsMap[displayPanel] = no_screen;
|
||||
settingsMap[touchscreenModule] = no_touchscreen;
|
||||
|
||||
YAML::Node yamlConfig;
|
||||
|
||||
if (configPath != nullptr) {
|
||||
std::cout << "Using " << configPath << " as config file" << std::endl;
|
||||
try {
|
||||
yamlConfig = YAML::LoadFile(configPath);
|
||||
} catch (YAML::Exception &e) {
|
||||
std::cout << "Could not open " << configPath << " because of error: " << e.what() << std::endl;
|
||||
if (loadConfig(configPath)) {
|
||||
std::cout << "Using " << configPath << " as config file" << std::endl;
|
||||
} else {
|
||||
std::cout << "Unable to use " << configPath << " as config file" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else if (access("config.yaml", R_OK) == 0) {
|
||||
} else if (access("config.yaml", R_OK) == 0 && loadConfig("config.yaml")) {
|
||||
std::cout << "Using local config.yaml as config file" << std::endl;
|
||||
try {
|
||||
yamlConfig = YAML::LoadFile("config.yaml");
|
||||
} catch (YAML::Exception &e) {
|
||||
std::cout << "*** Exception " << e.what() << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else if (access("/etc/meshtasticd/config.yaml", R_OK) == 0) {
|
||||
} else if (access("/etc/meshtasticd/config.yaml", R_OK) == 0 && loadConfig("/etc/meshtasticd/config.yaml")) {
|
||||
std::cout << "Using /etc/meshtasticd/config.yaml as config file" << std::endl;
|
||||
try {
|
||||
yamlConfig = YAML::LoadFile("/etc/meshtasticd/config.yaml");
|
||||
} catch (YAML::Exception &e) {
|
||||
std::cout << "*** Exception " << e.what() << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
std::cout << "No 'config.yaml' found, running simulated." << std::endl;
|
||||
settingsMap[maxnodes] = 200; // Default to 200 nodes
|
||||
@ -136,170 +126,21 @@ void portduinoSetup()
|
||||
return;
|
||||
}
|
||||
|
||||
if (settingsStrings[config_directory] != "") {
|
||||
std::string filetype = ".yaml";
|
||||
for (const std::filesystem::directory_entry &entry :
|
||||
std::filesystem::directory_iterator{settingsStrings[config_directory]}) {
|
||||
if (ends_with(entry.path().string(), ".yaml")) {
|
||||
std::cout << "Also using " << entry << " as additional config file" << std::endl;
|
||||
loadConfig(entry.path().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Rather important to set this, if not running simulated.
|
||||
randomSeed(time(NULL));
|
||||
|
||||
try {
|
||||
if (yamlConfig["Logging"]) {
|
||||
if (yamlConfig["Logging"]["LogLevel"].as<std::string>("info") == "trace") {
|
||||
settingsMap[logoutputlevel] = level_trace;
|
||||
} else if (yamlConfig["Logging"]["LogLevel"].as<std::string>("info") == "debug") {
|
||||
settingsMap[logoutputlevel] = level_debug;
|
||||
} else if (yamlConfig["Logging"]["LogLevel"].as<std::string>("info") == "info") {
|
||||
settingsMap[logoutputlevel] = level_info;
|
||||
} else if (yamlConfig["Logging"]["LogLevel"].as<std::string>("info") == "warn") {
|
||||
settingsMap[logoutputlevel] = level_warn;
|
||||
} else if (yamlConfig["Logging"]["LogLevel"].as<std::string>("info") == "error") {
|
||||
settingsMap[logoutputlevel] = level_error;
|
||||
}
|
||||
settingsStrings[traceFilename] = yamlConfig["Logging"]["TraceFile"].as<std::string>("");
|
||||
if (yamlConfig["Logging"]["AsciiLogs"]) {
|
||||
// Default is !isatty(1) but can be set explicitly in config.yaml
|
||||
settingsMap[ascii_logs] = yamlConfig["Logging"]["AsciiLogs"].as<bool>();
|
||||
}
|
||||
}
|
||||
if (yamlConfig["Lora"]) {
|
||||
settingsMap[use_sx1262] = false;
|
||||
settingsMap[use_rf95] = false;
|
||||
settingsMap[use_sx1280] = false;
|
||||
settingsMap[use_sx1268] = false;
|
||||
|
||||
if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "sx1262") {
|
||||
settingsMap[use_sx1262] = true;
|
||||
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "RF95") {
|
||||
settingsMap[use_rf95] = true;
|
||||
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "sx1280") {
|
||||
settingsMap[use_sx1280] = true;
|
||||
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "sx1268") {
|
||||
settingsMap[use_sx1268] = true;
|
||||
}
|
||||
settingsMap[dio2_as_rf_switch] = yamlConfig["Lora"]["DIO2_AS_RF_SWITCH"].as<bool>(false);
|
||||
settingsMap[dio3_tcxo_voltage] = yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].as<bool>(false);
|
||||
settingsMap[cs] = yamlConfig["Lora"]["CS"].as<int>(RADIOLIB_NC);
|
||||
settingsMap[irq] = yamlConfig["Lora"]["IRQ"].as<int>(RADIOLIB_NC);
|
||||
settingsMap[busy] = yamlConfig["Lora"]["Busy"].as<int>(RADIOLIB_NC);
|
||||
settingsMap[reset] = yamlConfig["Lora"]["Reset"].as<int>(RADIOLIB_NC);
|
||||
settingsMap[txen] = yamlConfig["Lora"]["TXen"].as<int>(RADIOLIB_NC);
|
||||
settingsMap[rxen] = yamlConfig["Lora"]["RXen"].as<int>(RADIOLIB_NC);
|
||||
settingsMap[sx126x_ant_sw] = yamlConfig["Lora"]["SX126X_ANT_SW"].as<int>(RADIOLIB_NC);
|
||||
settingsMap[gpiochip] = yamlConfig["Lora"]["gpiochip"].as<int>(0);
|
||||
settingsMap[ch341Quirk] = yamlConfig["Lora"]["ch341_quirk"].as<bool>(false);
|
||||
settingsMap[spiSpeed] = yamlConfig["Lora"]["spiSpeed"].as<int>(2000000);
|
||||
gpioChipName += std::to_string(settingsMap[gpiochip]);
|
||||
|
||||
settingsStrings[spidev] = "/dev/" + yamlConfig["Lora"]["spidev"].as<std::string>("spidev0.0");
|
||||
if (settingsStrings[spidev].length() == 14) {
|
||||
int x = settingsStrings[spidev].at(11) - '0';
|
||||
int y = settingsStrings[spidev].at(13) - '0';
|
||||
if (x >= 0 && x < 10 && y >= 0 && y < 10) {
|
||||
settingsMap[spidev] = x + y << 4;
|
||||
settingsMap[displayspidev] = settingsMap[spidev];
|
||||
settingsMap[touchscreenspidev] = settingsMap[spidev];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (yamlConfig["GPIO"]) {
|
||||
settingsMap[user] = yamlConfig["GPIO"]["User"].as<int>(RADIOLIB_NC);
|
||||
}
|
||||
if (yamlConfig["GPS"]) {
|
||||
std::string serialPath = yamlConfig["GPS"]["SerialPath"].as<std::string>("");
|
||||
if (serialPath != "") {
|
||||
Serial1.setPath(serialPath);
|
||||
settingsMap[has_gps] = 1;
|
||||
}
|
||||
}
|
||||
if (yamlConfig["I2C"]) {
|
||||
settingsStrings[i2cdev] = yamlConfig["I2C"]["I2CDevice"].as<std::string>("");
|
||||
}
|
||||
settingsMap[displayPanel] = no_screen;
|
||||
if (yamlConfig["Display"]) {
|
||||
if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ST7789")
|
||||
settingsMap[displayPanel] = st7789;
|
||||
else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ST7735")
|
||||
settingsMap[displayPanel] = st7735;
|
||||
else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ST7735S")
|
||||
settingsMap[displayPanel] = st7735s;
|
||||
else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ST7796")
|
||||
settingsMap[displayPanel] = st7796;
|
||||
else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ILI9341")
|
||||
settingsMap[displayPanel] = ili9341;
|
||||
else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ILI9342")
|
||||
settingsMap[displayPanel] = ili9342;
|
||||
else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ILI9488")
|
||||
settingsMap[displayPanel] = ili9488;
|
||||
else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "HX8357D")
|
||||
settingsMap[displayPanel] = hx8357d;
|
||||
else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "X11")
|
||||
settingsMap[displayPanel] = x11;
|
||||
settingsMap[displayHeight] = yamlConfig["Display"]["Height"].as<int>(0);
|
||||
settingsMap[displayWidth] = yamlConfig["Display"]["Width"].as<int>(0);
|
||||
settingsMap[displayDC] = yamlConfig["Display"]["DC"].as<int>(-1);
|
||||
settingsMap[displayCS] = yamlConfig["Display"]["CS"].as<int>(-1);
|
||||
settingsMap[displayRGBOrder] = yamlConfig["Display"]["RGBOrder"].as<bool>(false);
|
||||
settingsMap[displayBacklight] = yamlConfig["Display"]["Backlight"].as<int>(-1);
|
||||
settingsMap[displayBacklightInvert] = yamlConfig["Display"]["BacklightInvert"].as<bool>(false);
|
||||
settingsMap[displayBacklightPWMChannel] = yamlConfig["Display"]["BacklightPWMChannel"].as<int>(-1);
|
||||
settingsMap[displayReset] = yamlConfig["Display"]["Reset"].as<int>(-1);
|
||||
settingsMap[displayOffsetX] = yamlConfig["Display"]["OffsetX"].as<int>(0);
|
||||
settingsMap[displayOffsetY] = yamlConfig["Display"]["OffsetY"].as<int>(0);
|
||||
settingsMap[displayRotate] = yamlConfig["Display"]["Rotate"].as<bool>(false);
|
||||
settingsMap[displayOffsetRotate] = yamlConfig["Display"]["OffsetRotate"].as<int>(1);
|
||||
settingsMap[displayInvert] = yamlConfig["Display"]["Invert"].as<bool>(false);
|
||||
settingsMap[displayBusFrequency] = yamlConfig["Display"]["BusFrequency"].as<int>(40000000);
|
||||
if (yamlConfig["Display"]["spidev"]) {
|
||||
settingsStrings[displayspidev] = "/dev/" + yamlConfig["Display"]["spidev"].as<std::string>("spidev0.1");
|
||||
if (settingsStrings[displayspidev].length() == 14) {
|
||||
int x = settingsStrings[displayspidev].at(11) - '0';
|
||||
int y = settingsStrings[displayspidev].at(13) - '0';
|
||||
if (x >= 0 && x < 10 && y >= 0 && y < 10) {
|
||||
settingsMap[displayspidev] = x + y << 4;
|
||||
settingsMap[touchscreenspidev] = settingsMap[displayspidev];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
settingsMap[touchscreenModule] = no_touchscreen;
|
||||
if (yamlConfig["Touchscreen"]) {
|
||||
if (yamlConfig["Touchscreen"]["Module"].as<std::string>("") == "XPT2046")
|
||||
settingsMap[touchscreenModule] = xpt2046;
|
||||
else if (yamlConfig["Touchscreen"]["Module"].as<std::string>("") == "STMPE610")
|
||||
settingsMap[touchscreenModule] = stmpe610;
|
||||
else if (yamlConfig["Touchscreen"]["Module"].as<std::string>("") == "GT911")
|
||||
settingsMap[touchscreenModule] = gt911;
|
||||
else if (yamlConfig["Touchscreen"]["Module"].as<std::string>("") == "FT5x06")
|
||||
settingsMap[touchscreenModule] = ft5x06;
|
||||
settingsMap[touchscreenCS] = yamlConfig["Touchscreen"]["CS"].as<int>(-1);
|
||||
settingsMap[touchscreenIRQ] = yamlConfig["Touchscreen"]["IRQ"].as<int>(-1);
|
||||
settingsMap[touchscreenBusFrequency] = yamlConfig["Touchscreen"]["BusFrequency"].as<int>(1000000);
|
||||
settingsMap[touchscreenRotate] = yamlConfig["Touchscreen"]["Rotate"].as<int>(-1);
|
||||
settingsMap[touchscreenI2CAddr] = yamlConfig["Touchscreen"]["I2CAddr"].as<int>(-1);
|
||||
if (yamlConfig["Touchscreen"]["spidev"]) {
|
||||
settingsStrings[touchscreenspidev] = "/dev/" + yamlConfig["Touchscreen"]["spidev"].as<std::string>("");
|
||||
if (settingsStrings[touchscreenspidev].length() == 14) {
|
||||
int x = settingsStrings[touchscreenspidev].at(11) - '0';
|
||||
int y = settingsStrings[touchscreenspidev].at(13) - '0';
|
||||
if (x >= 0 && x < 10 && y >= 0 && y < 10) {
|
||||
settingsMap[touchscreenspidev] = x + y << 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (yamlConfig["Input"]) {
|
||||
settingsStrings[keyboardDevice] = (yamlConfig["Input"]["KeyboardDevice"]).as<std::string>("");
|
||||
}
|
||||
|
||||
if (yamlConfig["Webserver"]) {
|
||||
settingsMap[webserverport] = (yamlConfig["Webserver"]["Port"]).as<int>(-1);
|
||||
settingsStrings[webserverrootpath] = (yamlConfig["Webserver"]["RootPath"]).as<std::string>("");
|
||||
}
|
||||
|
||||
settingsMap[maxnodes] = (yamlConfig["General"]["MaxNodes"]).as<int>(200);
|
||||
settingsMap[maxtophone] = (yamlConfig["General"]["MaxMessageQueue"]).as<int>(100);
|
||||
|
||||
} catch (YAML::Exception &e) {
|
||||
std::cout << "*** Exception " << e.what() << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
gpioChipName += std::to_string(settingsMap[gpiochip]);
|
||||
|
||||
for (configNames i : GPIO_lines) {
|
||||
if (settingsMap.count(i) && settingsMap[i] > max_GPIO)
|
||||
@ -402,4 +243,178 @@ int initGPIOPin(int pinNum, const std::string gpioChipName)
|
||||
#else
|
||||
return ERRNO_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool loadConfig(const char *configPath)
|
||||
{
|
||||
YAML::Node yamlConfig;
|
||||
try {
|
||||
yamlConfig = YAML::LoadFile(configPath);
|
||||
if (yamlConfig["Logging"]) {
|
||||
if (yamlConfig["Logging"]["LogLevel"].as<std::string>("info") == "trace") {
|
||||
settingsMap[logoutputlevel] = level_trace;
|
||||
} else if (yamlConfig["Logging"]["LogLevel"].as<std::string>("info") == "debug") {
|
||||
settingsMap[logoutputlevel] = level_debug;
|
||||
} else if (yamlConfig["Logging"]["LogLevel"].as<std::string>("info") == "info") {
|
||||
settingsMap[logoutputlevel] = level_info;
|
||||
} else if (yamlConfig["Logging"]["LogLevel"].as<std::string>("info") == "warn") {
|
||||
settingsMap[logoutputlevel] = level_warn;
|
||||
} else if (yamlConfig["Logging"]["LogLevel"].as<std::string>("info") == "error") {
|
||||
settingsMap[logoutputlevel] = level_error;
|
||||
}
|
||||
settingsStrings[traceFilename] = yamlConfig["Logging"]["TraceFile"].as<std::string>("");
|
||||
if (yamlConfig["Logging"]["AsciiLogs"]) {
|
||||
// Default is !isatty(1) but can be set explicitly in config.yaml
|
||||
settingsMap[ascii_logs] = yamlConfig["Logging"]["AsciiLogs"].as<bool>();
|
||||
}
|
||||
}
|
||||
if (yamlConfig["Lora"]) {
|
||||
settingsMap[use_sx1262] = false;
|
||||
settingsMap[use_rf95] = false;
|
||||
settingsMap[use_sx1280] = false;
|
||||
settingsMap[use_sx1268] = false;
|
||||
|
||||
if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "sx1262") {
|
||||
settingsMap[use_sx1262] = true;
|
||||
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "RF95") {
|
||||
settingsMap[use_rf95] = true;
|
||||
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "sx1280") {
|
||||
settingsMap[use_sx1280] = true;
|
||||
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "sx1268") {
|
||||
settingsMap[use_sx1268] = true;
|
||||
}
|
||||
settingsMap[dio2_as_rf_switch] = yamlConfig["Lora"]["DIO2_AS_RF_SWITCH"].as<bool>(false);
|
||||
settingsMap[dio3_tcxo_voltage] = yamlConfig["Lora"]["DIO3_TCXO_VOLTAGE"].as<bool>(false);
|
||||
settingsMap[cs] = yamlConfig["Lora"]["CS"].as<int>(RADIOLIB_NC);
|
||||
settingsMap[irq] = yamlConfig["Lora"]["IRQ"].as<int>(RADIOLIB_NC);
|
||||
settingsMap[busy] = yamlConfig["Lora"]["Busy"].as<int>(RADIOLIB_NC);
|
||||
settingsMap[reset] = yamlConfig["Lora"]["Reset"].as<int>(RADIOLIB_NC);
|
||||
settingsMap[txen] = yamlConfig["Lora"]["TXen"].as<int>(RADIOLIB_NC);
|
||||
settingsMap[rxen] = yamlConfig["Lora"]["RXen"].as<int>(RADIOLIB_NC);
|
||||
settingsMap[sx126x_ant_sw] = yamlConfig["Lora"]["SX126X_ANT_SW"].as<int>(RADIOLIB_NC);
|
||||
settingsMap[gpiochip] = yamlConfig["Lora"]["gpiochip"].as<int>(0);
|
||||
settingsMap[ch341Quirk] = yamlConfig["Lora"]["ch341_quirk"].as<bool>(false);
|
||||
settingsMap[spiSpeed] = yamlConfig["Lora"]["spiSpeed"].as<int>(2000000);
|
||||
|
||||
settingsStrings[spidev] = "/dev/" + yamlConfig["Lora"]["spidev"].as<std::string>("spidev0.0");
|
||||
if (settingsStrings[spidev].length() == 14) {
|
||||
int x = settingsStrings[spidev].at(11) - '0';
|
||||
int y = settingsStrings[spidev].at(13) - '0';
|
||||
if (x >= 0 && x < 10 && y >= 0 && y < 10) {
|
||||
settingsMap[spidev] = x + y << 4;
|
||||
settingsMap[displayspidev] = settingsMap[spidev];
|
||||
settingsMap[touchscreenspidev] = settingsMap[spidev];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (yamlConfig["GPIO"]) {
|
||||
settingsMap[user] = yamlConfig["GPIO"]["User"].as<int>(RADIOLIB_NC);
|
||||
}
|
||||
if (yamlConfig["GPS"]) {
|
||||
std::string serialPath = yamlConfig["GPS"]["SerialPath"].as<std::string>("");
|
||||
if (serialPath != "") {
|
||||
Serial1.setPath(serialPath);
|
||||
settingsMap[has_gps] = 1;
|
||||
}
|
||||
}
|
||||
if (yamlConfig["I2C"]) {
|
||||
settingsStrings[i2cdev] = yamlConfig["I2C"]["I2CDevice"].as<std::string>("");
|
||||
}
|
||||
if (yamlConfig["Display"]) {
|
||||
if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ST7789")
|
||||
settingsMap[displayPanel] = st7789;
|
||||
else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ST7735")
|
||||
settingsMap[displayPanel] = st7735;
|
||||
else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ST7735S")
|
||||
settingsMap[displayPanel] = st7735s;
|
||||
else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ST7796")
|
||||
settingsMap[displayPanel] = st7796;
|
||||
else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ILI9341")
|
||||
settingsMap[displayPanel] = ili9341;
|
||||
else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ILI9342")
|
||||
settingsMap[displayPanel] = ili9342;
|
||||
else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "ILI9488")
|
||||
settingsMap[displayPanel] = ili9488;
|
||||
else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "HX8357D")
|
||||
settingsMap[displayPanel] = hx8357d;
|
||||
else if (yamlConfig["Display"]["Panel"].as<std::string>("") == "X11")
|
||||
settingsMap[displayPanel] = x11;
|
||||
settingsMap[displayHeight] = yamlConfig["Display"]["Height"].as<int>(0);
|
||||
settingsMap[displayWidth] = yamlConfig["Display"]["Width"].as<int>(0);
|
||||
settingsMap[displayDC] = yamlConfig["Display"]["DC"].as<int>(-1);
|
||||
settingsMap[displayCS] = yamlConfig["Display"]["CS"].as<int>(-1);
|
||||
settingsMap[displayRGBOrder] = yamlConfig["Display"]["RGBOrder"].as<bool>(false);
|
||||
settingsMap[displayBacklight] = yamlConfig["Display"]["Backlight"].as<int>(-1);
|
||||
settingsMap[displayBacklightInvert] = yamlConfig["Display"]["BacklightInvert"].as<bool>(false);
|
||||
settingsMap[displayBacklightPWMChannel] = yamlConfig["Display"]["BacklightPWMChannel"].as<int>(-1);
|
||||
settingsMap[displayReset] = yamlConfig["Display"]["Reset"].as<int>(-1);
|
||||
settingsMap[displayOffsetX] = yamlConfig["Display"]["OffsetX"].as<int>(0);
|
||||
settingsMap[displayOffsetY] = yamlConfig["Display"]["OffsetY"].as<int>(0);
|
||||
settingsMap[displayRotate] = yamlConfig["Display"]["Rotate"].as<bool>(false);
|
||||
settingsMap[displayOffsetRotate] = yamlConfig["Display"]["OffsetRotate"].as<int>(1);
|
||||
settingsMap[displayInvert] = yamlConfig["Display"]["Invert"].as<bool>(false);
|
||||
settingsMap[displayBusFrequency] = yamlConfig["Display"]["BusFrequency"].as<int>(40000000);
|
||||
if (yamlConfig["Display"]["spidev"]) {
|
||||
settingsStrings[displayspidev] = "/dev/" + yamlConfig["Display"]["spidev"].as<std::string>("spidev0.1");
|
||||
if (settingsStrings[displayspidev].length() == 14) {
|
||||
int x = settingsStrings[displayspidev].at(11) - '0';
|
||||
int y = settingsStrings[displayspidev].at(13) - '0';
|
||||
if (x >= 0 && x < 10 && y >= 0 && y < 10) {
|
||||
settingsMap[displayspidev] = x + y << 4;
|
||||
settingsMap[touchscreenspidev] = settingsMap[displayspidev];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (yamlConfig["Touchscreen"]) {
|
||||
if (yamlConfig["Touchscreen"]["Module"].as<std::string>("") == "XPT2046")
|
||||
settingsMap[touchscreenModule] = xpt2046;
|
||||
else if (yamlConfig["Touchscreen"]["Module"].as<std::string>("") == "STMPE610")
|
||||
settingsMap[touchscreenModule] = stmpe610;
|
||||
else if (yamlConfig["Touchscreen"]["Module"].as<std::string>("") == "GT911")
|
||||
settingsMap[touchscreenModule] = gt911;
|
||||
else if (yamlConfig["Touchscreen"]["Module"].as<std::string>("") == "FT5x06")
|
||||
settingsMap[touchscreenModule] = ft5x06;
|
||||
settingsMap[touchscreenCS] = yamlConfig["Touchscreen"]["CS"].as<int>(-1);
|
||||
settingsMap[touchscreenIRQ] = yamlConfig["Touchscreen"]["IRQ"].as<int>(-1);
|
||||
settingsMap[touchscreenBusFrequency] = yamlConfig["Touchscreen"]["BusFrequency"].as<int>(1000000);
|
||||
settingsMap[touchscreenRotate] = yamlConfig["Touchscreen"]["Rotate"].as<int>(-1);
|
||||
settingsMap[touchscreenI2CAddr] = yamlConfig["Touchscreen"]["I2CAddr"].as<int>(-1);
|
||||
if (yamlConfig["Touchscreen"]["spidev"]) {
|
||||
settingsStrings[touchscreenspidev] = "/dev/" + yamlConfig["Touchscreen"]["spidev"].as<std::string>("");
|
||||
if (settingsStrings[touchscreenspidev].length() == 14) {
|
||||
int x = settingsStrings[touchscreenspidev].at(11) - '0';
|
||||
int y = settingsStrings[touchscreenspidev].at(13) - '0';
|
||||
if (x >= 0 && x < 10 && y >= 0 && y < 10) {
|
||||
settingsMap[touchscreenspidev] = x + y << 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (yamlConfig["Input"]) {
|
||||
settingsStrings[keyboardDevice] = (yamlConfig["Input"]["KeyboardDevice"]).as<std::string>("");
|
||||
}
|
||||
|
||||
if (yamlConfig["Webserver"]) {
|
||||
settingsMap[webserverport] = (yamlConfig["Webserver"]["Port"]).as<int>(-1);
|
||||
settingsStrings[webserverrootpath] = (yamlConfig["Webserver"]["RootPath"]).as<std::string>("");
|
||||
}
|
||||
|
||||
if (yamlConfig["General"]) {
|
||||
settingsMap[maxnodes] = (yamlConfig["General"]["MaxNodes"]).as<int>(200);
|
||||
settingsMap[maxtophone] = (yamlConfig["General"]["MaxMessageQueue"]).as<int>(100);
|
||||
settingsStrings[config_directory] = (yamlConfig["General"]["ConfigDirectory"]).as<std::string>("");
|
||||
}
|
||||
|
||||
} catch (YAML::Exception &e) {
|
||||
std::cout << "*** Exception " << e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/874134/find-out-if-string-ends-with-another-string-in-c
|
||||
static bool ends_with(std::string_view str, std::string_view suffix)
|
||||
{
|
||||
return str.size() >= suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
|
||||
}
|
@ -55,7 +55,8 @@ enum configNames {
|
||||
webserverrootpath,
|
||||
maxtophone,
|
||||
maxnodes,
|
||||
ascii_logs
|
||||
ascii_logs,
|
||||
config_directory
|
||||
};
|
||||
enum { no_screen, x11, st7789, st7735, st7735s, st7796, ili9341, ili9342, ili9488, hx8357d };
|
||||
enum { no_touchscreen, xpt2046, stmpe610, gt911, ft5x06 };
|
||||
@ -64,4 +65,6 @@ enum { level_error, level_warn, level_info, level_debug, level_trace };
|
||||
extern std::map<configNames, int> settingsMap;
|
||||
extern std::map<configNames, std::string> settingsStrings;
|
||||
extern std::ofstream traceFile;
|
||||
int initGPIOPin(int pinNum, std::string gpioChipname);
|
||||
int initGPIOPin(int pinNum, std::string gpioChipname);
|
||||
bool loadConfig(const char *configPath);
|
||||
static bool ends_with(std::string_view str, std::string_view suffix);
|
49
variants/diy/mesh-tab/variant.h
Normal file
49
variants/diy/mesh-tab/variant.h
Normal file
@ -0,0 +1,49 @@
|
||||
#ifndef _VARIANT_MESHTAB_DIY_
|
||||
#define _VARIANT_MESHTAB_DIY_
|
||||
|
||||
#define HAS_TOUCHSCREEN 1
|
||||
|
||||
#define SLEEP_TIME 120
|
||||
|
||||
// Analog pins
|
||||
#define BATTERY_PIN 4 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||
// ratio of voltage divider = 2.0
|
||||
#define ADC_MULTIPLIER 2.11 // 2.0 + 10% for correction of display undervoltage.
|
||||
#define ADC_CHANNEL ADC1_GPIO4_CHANNEL
|
||||
|
||||
// LED
|
||||
#define LED_PIN 21
|
||||
|
||||
// Button
|
||||
#define BUTTON_PIN 0
|
||||
|
||||
// GPS
|
||||
#define GPS_RX_PIN 18
|
||||
#define GPS_TX_PIN 17
|
||||
|
||||
// #define HAS_SDCARD 1
|
||||
#define SPI_MOSI 13
|
||||
#define SPI_SCK 12
|
||||
#define SPI_MISO 11
|
||||
#define SPI_CS 10
|
||||
#define SDCARD_CS 6
|
||||
|
||||
// LORA SPI
|
||||
#define LORA_SCK 36
|
||||
#define LORA_MISO 37
|
||||
#define LORA_MOSI 35
|
||||
#define LORA_CS 39
|
||||
|
||||
// LORA MODULES
|
||||
#define USE_SX1262
|
||||
|
||||
// LORA CONFIG
|
||||
#define SX126X_CS LORA_CS
|
||||
#define SX126X_DIO1 15
|
||||
#define SX126X_DIO2_AS_RF_SWITCH
|
||||
#define SX126X_BUSY 40
|
||||
#define SX126X_RESET 14
|
||||
#define SX126X_RXEN 47
|
||||
#define SX126X_TXEN RADIOLIB_NC // Assuming that DIO2 is connected to TXEN pin
|
||||
|
||||
#endif
|
@ -88,3 +88,73 @@ build_flags =
|
||||
-D ARDUINO_USB_MODE=0
|
||||
-D ARDUINO_USB_CDC_ON_BOOT=1
|
||||
-I variants/diy/t-energy-s3_e22
|
||||
|
||||
; esp32-s3 + ra-sh01 lora + 3.2" ILI9143
|
||||
[env:mesh-tab]
|
||||
extends = esp32s3_base
|
||||
board = um_feathers3
|
||||
board_level = extra
|
||||
board_upload.flash_size = 16MB
|
||||
board_build.partitions = default_16MB.csv
|
||||
upload_protocol = esptool
|
||||
build_flags = ${esp32s3_base.build_flags}
|
||||
-D MESH_TAB
|
||||
-D PRIVATE_HW
|
||||
-D CONFIG_ARDUHAL_ESP_LOG
|
||||
-D CONFIG_ARDUHAL_LOG_COLORS=1
|
||||
-D CONFIG_DISABLE_HAL_LOCKS=1 ; "feels" to be a bit more stable without locks
|
||||
-D MESHTASTIC_EXCLUDE_CANNEDMESSAGES=1
|
||||
-D MESHTASTIC_EXCLUDE_INPUTBROKER=1
|
||||
-D MESHTASTIC_EXCLUDE_BLUETOOTH=1
|
||||
-D MESHTASTIC_EXCLUDE_WEBSERVER=1
|
||||
-D LV_LVGL_H_INCLUDE_SIMPLE
|
||||
-D LV_CONF_INCLUDE_SIMPLE
|
||||
-D LV_COMP_CONF_INCLUDE_SIMPLE
|
||||
-D LV_USE_SYSMON=0
|
||||
-D LV_USE_PROFILER=0
|
||||
-D LV_USE_PERF_MONITOR=0
|
||||
-D LV_USE_MEM_MONITOR=0
|
||||
-D LV_USE_LOG=0
|
||||
-D LV_BUILD_TEST=0
|
||||
-D USE_LOG_DEBUG
|
||||
-D LOG_DEBUG_INC=\"DebugConfiguration.h\"
|
||||
-D RADIOLIB_SPI_PARANOID=0
|
||||
-D MAX_NUM_NODES=250
|
||||
-D MAX_THREADS=40
|
||||
-D HAS_SCREEN=0
|
||||
-D HAS_TFT=1
|
||||
-D RAM_SIZE=1024
|
||||
-D LGFX_DRIVER_TEMPLATE
|
||||
-D LGFX_DRIVER=LGFX_GENERIC
|
||||
-D LGFX_PANEL=ILI9341
|
||||
-D LGFX_OFFSET_ROTATION=1
|
||||
-D LGFX_TOUCH=XPT2046
|
||||
-D LGFX_PIN_SCK=12
|
||||
-D LGFX_PIN_MOSI=13
|
||||
-D LGFX_PIN_MISO=11
|
||||
-D LGFX_PIN_DC=16
|
||||
-D LGFX_PIN_CS=10
|
||||
-D LGFX_PIN_RST=-1
|
||||
-D LGFX_PIN_BL=42
|
||||
-D LGFX_TOUCH_INT=41
|
||||
-D LGFX_TOUCH_CS=7
|
||||
-D LGFX_TOUCH_CLK=12
|
||||
-D LGFX_TOUCH_DO=11
|
||||
-D LGFX_TOUCH_DIN=13
|
||||
-D LGFX_TOUCH_X_MIN=300
|
||||
-D LGFX_TOUCH_X_MAX=3900
|
||||
-D LGFX_TOUCH_Y_MIN=400
|
||||
-D LGFX_TOUCH_Y_MAX=3900
|
||||
-D VIEW_320x240
|
||||
-D USE_PACKET_API
|
||||
-I lib/device-ui/generated/ui_320x240
|
||||
-I variants/diy/mesh-tab
|
||||
build_src_filter = ${esp32_base.build_src_filter}
|
||||
+<../lib/device-ui/generated/ui_320x240>
|
||||
+<../lib/device-ui/resources>
|
||||
+<../lib/device-ui/locale>
|
||||
+<../lib/device-ui/source>
|
||||
lib_deps = ${esp32_base.lib_deps}
|
||||
lovyan03/LovyanGFX@^1.1.16
|
||||
earlephilhower/ESP8266Audio@^1.9.7
|
||||
earlephilhower/ESP8266SAM@^1.0.1
|
||||
|
21
variants/icarus/pins_arduino.h
Normal file
21
variants/icarus/pins_arduino.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef Pins_Arduino_h
|
||||
#define Pins_Arduino_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define USB_VID 0x2886
|
||||
#define USB_PID 0x0059
|
||||
|
||||
// GPIO48 Reference: https://github.com/espressif/arduino-esp32/pull/8600
|
||||
|
||||
// The default Wire will be mapped to Screen and Sensors
|
||||
static const uint8_t SDA = 8;
|
||||
static const uint8_t SCL = 9;
|
||||
|
||||
// Default SPI will be mapped to Radio
|
||||
static const uint8_t MISO = 39;
|
||||
static const uint8_t SCK = 21;
|
||||
static const uint8_t MOSI = 38;
|
||||
static const uint8_t SS = 17;
|
||||
|
||||
#endif /* Pins_Arduino_h */
|
19
variants/icarus/platformio.ini
Normal file
19
variants/icarus/platformio.ini
Normal file
@ -0,0 +1,19 @@
|
||||
[env:icarus]
|
||||
extends = esp32s3_base
|
||||
board = icarus
|
||||
board_level = extra
|
||||
board_check = true
|
||||
board_build.mcu = esp32s3
|
||||
upload_protocol = esptool
|
||||
upload_speed = 921600
|
||||
platform_packages = framework-arduinoespressif32@https://github.com/PowerFeather/powerfeather-meshtastic-arduino-lib/releases/download/2.0.16a/esp32-2.0.16.zip
|
||||
lib_deps =
|
||||
${esp32s3_base.lib_deps}
|
||||
build_unflags =
|
||||
${esp32s3_base.build_unflags}
|
||||
-DARDUINO_USB_MODE=1
|
||||
build_flags =
|
||||
${esp32s3_base.build_flags} -D PRIVATE_HW -I variants/icarus
|
||||
-DBOARD_HAS_PSRAM
|
||||
|
||||
-DARDUINO_USB_MODE=0
|
31
variants/icarus/variant.h
Normal file
31
variants/icarus/variant.h
Normal file
@ -0,0 +1,31 @@
|
||||
// Icarus has a 1.3 inch OLED Screen
|
||||
#define SCREEN_SSD106
|
||||
|
||||
#define I2C_SDA 8
|
||||
#define I2C_SCL 9
|
||||
|
||||
#define I2C_SDA1 18
|
||||
#define I2C_SCL1 6
|
||||
|
||||
#define BUTTON_PIN 7 // Selection button
|
||||
|
||||
// RA-01SH/HT-RA62 LORA module
|
||||
#define USE_SX1262
|
||||
|
||||
#define LORA_MISO 39
|
||||
#define LORA_SCK 21
|
||||
#define LORA_MOSI 38
|
||||
#define LORA_CS 17
|
||||
|
||||
#define LORA_RESET 42
|
||||
#define LORA_DIO1 5
|
||||
|
||||
#ifdef USE_SX1262
|
||||
#define SX126X_CS LORA_CS
|
||||
#define SX126X_DIO1 LORA_DIO1
|
||||
#define SX126X_BUSY 47
|
||||
#define SX126X_RESET LORA_RESET
|
||||
|
||||
// DIO2 controlls an antenna switch
|
||||
#define SX126X_DIO2_AS_RF_SWITCH
|
||||
#endif
|
@ -12,4 +12,4 @@ lib_deps =
|
||||
https://github.com/RAKWireless/RAK13800-W5100S.git#1.0.2
|
||||
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
|
||||
;upload_protocol = jlink
|
||||
|
67
variants/unphone/pins_arduino.h
Normal file
67
variants/unphone/pins_arduino.h
Normal file
@ -0,0 +1,67 @@
|
||||
#ifndef Pins_Arduino_h
|
||||
#define Pins_Arduino_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define USB_VID 0x16D0
|
||||
#define USB_PID 0x1178
|
||||
|
||||
#define EXTERNAL_NUM_INTERRUPTS 46
|
||||
#define NUM_DIGITAL_PINS 48
|
||||
#define NUM_ANALOG_INPUTS 20
|
||||
|
||||
#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1)
|
||||
#define digitalPinToInterrupt(p) (((p) < 48) ? (p) : -1)
|
||||
#define digitalPinHasPWM(p) (p < 46)
|
||||
|
||||
#define LED_BUILTIN 13
|
||||
#define BUILTIN_LED LED_BUILTIN // backward compatibility
|
||||
|
||||
static const uint8_t TX = 43;
|
||||
static const uint8_t RX = 44;
|
||||
|
||||
static const uint8_t SDA = 3;
|
||||
static const uint8_t SCL = 4;
|
||||
|
||||
static const uint8_t SS = 13;
|
||||
static const uint8_t MOSI = 40;
|
||||
static const uint8_t MISO = 41;
|
||||
static const uint8_t SCK = 39;
|
||||
|
||||
static const uint8_t A0 = 1;
|
||||
static const uint8_t A1 = 2;
|
||||
static const uint8_t A2 = 8;
|
||||
static const uint8_t A3 = 9;
|
||||
static const uint8_t A4 = 5;
|
||||
static const uint8_t A5 = 6;
|
||||
static const uint8_t A6 = 14;
|
||||
static const uint8_t A7 = 7;
|
||||
static const uint8_t A8 = 15;
|
||||
static const uint8_t A9 = 33;
|
||||
static const uint8_t A10 = 27;
|
||||
static const uint8_t A11 = 12;
|
||||
static const uint8_t A12 = 13;
|
||||
static const uint8_t A13 = 14;
|
||||
static const uint8_t A14 = 15;
|
||||
static const uint8_t A15 = 16;
|
||||
static const uint8_t A16 = 17;
|
||||
static const uint8_t A17 = 18;
|
||||
static const uint8_t A18 = 19;
|
||||
static const uint8_t A19 = 20;
|
||||
|
||||
static const uint8_t T1 = 2;
|
||||
static const uint8_t T2 = 8;
|
||||
static const uint8_t T3 = 9;
|
||||
static const uint8_t T4 = 5;
|
||||
static const uint8_t T5 = 6;
|
||||
static const uint8_t T6 = 14;
|
||||
static const uint8_t T7 = 7;
|
||||
static const uint8_t T8 = 15;
|
||||
static const uint8_t T9 = 33;
|
||||
static const uint8_t T10 = 27;
|
||||
static const uint8_t T11 = 12;
|
||||
static const uint8_t T12 = 13;
|
||||
static const uint8_t T13 = 14;
|
||||
static const uint8_t T14 = 15;
|
||||
|
||||
#endif /* Pins_Arduino_h */
|
@ -13,7 +13,6 @@ build_unflags =
|
||||
-D ARDUINO_USB_MODE
|
||||
|
||||
build_flags = ${esp32_base.build_flags}
|
||||
;-D BOARD_HAS_PSRAM // what's up with this - doesn't seem to be recognised at boot
|
||||
-D UNPHONE
|
||||
-I variants/unphone
|
||||
-D ARDUINO_USB_MODE=0
|
||||
@ -27,6 +26,52 @@ build_flags = ${esp32_base.build_flags}
|
||||
build_src_filter = ${esp32_base.build_src_filter} +<../variants/unphone>
|
||||
|
||||
lib_deps = ${esp32s3_base.lib_deps}
|
||||
lovyan03/LovyanGFX @ ^1.1.8
|
||||
https://gitlab.com/hamishcunningham/unphonelibrary#meshtastic @ ^9.0.0
|
||||
adafruit/Adafruit NeoPixel @ ^1.12.0
|
||||
lovyan03/LovyanGFX@ 1.1.12
|
||||
https://gitlab.com/hamishcunningham/unphonelibrary#meshtastic@9.0.0
|
||||
adafruit/Adafruit NeoPixel @ ^1.12.0
|
||||
|
||||
|
||||
[env:unphone-tft]
|
||||
extends = esp32s3_base
|
||||
board_level = extra
|
||||
board = unphone
|
||||
board_build.partitions = default_8MB.csv
|
||||
monitor_speed = 115200
|
||||
monitor_filters = esp32_exception_decoder
|
||||
build_flags = ${esp32_base.build_flags}
|
||||
-D UNPHONE
|
||||
-D UNPHONE_ACCEL=0
|
||||
-D UNPHONE_TOUCHS=0
|
||||
-D UNPHONE_SDCARD=0
|
||||
-D UNPHONE_UI0=0
|
||||
-D UNPHONE_LORA=0
|
||||
-D UNPHONE_FACTORY_MODE=0
|
||||
-D MAX_THREADS=40
|
||||
-D HAS_SCREEN=0
|
||||
-D HAS_TFT=1
|
||||
-D RAM_SIZE=512
|
||||
-D LV_LVGL_H_INCLUDE_SIMPLE
|
||||
-D LV_CONF_INCLUDE_SIMPLE
|
||||
-D LV_COMP_CONF_INCLUDE_SIMPLE
|
||||
-D LV_BUILD_TEST=0
|
||||
-D LV_USE_PERF_MONITOR=0
|
||||
-D LV_USE_MEM_MONITOR=0
|
||||
-D USE_LOG_DEBUG
|
||||
-D LOG_DEBUG_INC=\"DebugConfiguration.h\"
|
||||
; -D CALIBRATE_TOUCH=0
|
||||
-D LGFX_DRIVER=LGFX_UNPHONE_V9
|
||||
-D VIEW_320x240
|
||||
; -D USE_DOUBLE_BUFFER
|
||||
-D USE_PACKET_API
|
||||
-I lib/device-ui/generated/ui_320x240
|
||||
-I variants/unphone
|
||||
|
||||
build_src_filter = ${esp32_base.build_src_filter} +<../variants/unphone>
|
||||
+<../lib/device-ui/generated/ui_320x240>
|
||||
+<../lib/device-ui/resources>
|
||||
+<../lib/device-ui/source>
|
||||
|
||||
lib_deps = ${esp32s3_base.lib_deps}
|
||||
lovyan03/LovyanGFX@^1.1.12
|
||||
https://gitlab.com/hamishcunningham/unphonelibrary#meshtastic@9.0.0
|
||||
adafruit/Adafruit NeoPixel@1.12.0
|
@ -1,4 +1,4 @@
|
||||
[VERSION]
|
||||
major = 2
|
||||
minor = 5
|
||||
build = 9
|
||||
build = 11
|
||||
|
Loading…
Reference in New Issue
Block a user