Merge branch 'master' into usbhost

This commit is contained in:
Thomas Göttgens 2024-11-02 16:44:29 +01:00 committed by GitHub
commit c4644936bb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
55 changed files with 1034 additions and 415 deletions

View File

@ -245,7 +245,8 @@ jobs:
if: ${{ github.event_name == 'workflow_dispatch' }} if: ${{ github.event_name == 'workflow_dispatch' }}
outputs: outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }} upload_url: ${{ steps.create_release.outputs.upload_url }}
needs: [ needs:
[
gather-artifacts, gather-artifacts,
package-raspbian, package-raspbian,
package-raspbian-armv7l, package-raspbian-armv7l,

View File

@ -50,11 +50,14 @@ jobs:
mkdir -p .debpkg/usr/share/doc/meshtasticd/web mkdir -p .debpkg/usr/share/doc/meshtasticd/web
mkdir -p .debpkg/usr/sbin mkdir -p .debpkg/usr/sbin
mkdir -p .debpkg/etc/meshtasticd mkdir -p .debpkg/etc/meshtasticd
mkdir -p .debpkg/etc/meshtasticd/config.d
mkdir -p .debpkg/etc/meshtasticd/available.d
mkdir -p .debpkg/usr/lib/systemd/system/ mkdir -p .debpkg/usr/lib/systemd/system/
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
cp release/meshtasticd_linux_x86_64 .debpkg/usr/sbin/meshtasticd cp release/meshtasticd_linux_x86_64 .debpkg/usr/sbin/meshtasticd
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/
chmod +x .debpkg/usr/sbin/meshtasticd chmod +x .debpkg/usr/sbin/meshtasticd
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles

View File

@ -50,11 +50,14 @@ jobs:
mkdir -p .debpkg/usr/share/doc/meshtasticd/web mkdir -p .debpkg/usr/share/doc/meshtasticd/web
mkdir -p .debpkg/usr/sbin mkdir -p .debpkg/usr/sbin
mkdir -p .debpkg/etc/meshtasticd mkdir -p .debpkg/etc/meshtasticd
mkdir -p .debpkg/etc/meshtasticd/config.d
mkdir -p .debpkg/etc/meshtasticd/available.d
mkdir -p .debpkg/usr/lib/systemd/system/ mkdir -p .debpkg/usr/lib/systemd/system/
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
cp release/meshtasticd_linux_aarch64 .debpkg/usr/sbin/meshtasticd cp release/meshtasticd_linux_aarch64 .debpkg/usr/sbin/meshtasticd
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/
chmod +x .debpkg/usr/sbin/meshtasticd chmod +x .debpkg/usr/sbin/meshtasticd
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles

View File

@ -50,11 +50,14 @@ jobs:
mkdir -p .debpkg/usr/share/doc/meshtasticd/web mkdir -p .debpkg/usr/share/doc/meshtasticd/web
mkdir -p .debpkg/usr/sbin mkdir -p .debpkg/usr/sbin
mkdir -p .debpkg/etc/meshtasticd mkdir -p .debpkg/etc/meshtasticd
mkdir -p .debpkg/etc/meshtasticd/config.d
mkdir -p .debpkg/etc/meshtasticd/available.d
mkdir -p .debpkg/usr/lib/systemd/system/ mkdir -p .debpkg/usr/lib/systemd/system/
tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web
gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz
cp release/meshtasticd_linux_armv7l .debpkg/usr/sbin/meshtasticd cp release/meshtasticd_linux_armv7l .debpkg/usr/sbin/meshtasticd
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
cp bin/config.d/* .debpkg/etc/meshtasticd/available.d/
chmod +x .debpkg/usr/sbin/meshtasticd chmod +x .debpkg/usr/sbin/meshtasticd
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles

21
.github/workflows/stale_bot.yml vendored Normal file
View 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
View 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.'
})

View File

@ -1,22 +1,22 @@
version: 0.1 version: 0.1
cli: cli:
version: 1.22.6 version: 1.22.7
plugins: plugins:
sources: sources:
- id: trunk - id: trunk
ref: v1.6.3 ref: v1.6.4
uri: https://github.com/trunk-io/plugins uri: https://github.com/trunk-io/plugins
lint: lint:
enabled: enabled:
- trufflehog@3.82.6 - trufflehog@3.83.2
- yamllint@1.35.1 - yamllint@1.35.1
- bandit@1.7.10 - bandit@1.7.10
- checkov@3.2.256 - checkov@3.2.276
- terrascan@1.19.1 - terrascan@1.19.9
- trivy@0.55.2 - trivy@0.56.2
#- trufflehog@3.63.2-rc0 #- trufflehog@3.63.2-rc0
- taplo@0.9.3 - taplo@0.9.3
- ruff@0.6.8 - ruff@0.7.1
- isort@5.13.2 - isort@5.13.2
- markdownlint@0.42.0 - markdownlint@0.42.0
- oxipng@9.1.2 - oxipng@9.1.2
@ -26,9 +26,9 @@ lint:
- hadolint@2.12.0 - hadolint@2.12.0
- shfmt@3.6.0 - shfmt@3.6.0
- shellcheck@0.10.0 - shellcheck@0.10.0
- black@24.8.0 - black@24.10.0
- git-diff-check - git-diff-check
- gitleaks@8.20.0 - gitleaks@8.21.1
- clang-format@16.0.3 - clang-format@16.0.3
- prettier@3.3.3 - prettier@3.3.3
ignore: ignore:

4
CODE_OF_CONDUCT.md Normal file
View 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/

View File

@ -31,7 +31,7 @@ build_flags =
-DCONFIG_BT_NIMBLE_ENABLED -DCONFIG_BT_NIMBLE_ENABLED
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2 -DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20 -DCONFIG_BT_NIMBLE_MAX_CCCDS=20
-DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5120 -DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=8192
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
-DSERIAL_BUFFER_SIZE=4096 -DSERIAL_BUFFER_SIZE=4096
-DLIBPAX_ARDUINO -DLIBPAX_ARDUINO

View File

@ -23,4 +23,5 @@ lib_deps=
rweather/Crypto@^0.4.0 rweather/Crypto@^0.4.0
lib_ignore = lib_ignore =
BluetoothOTA BluetoothOTA
lvgl

View File

@ -24,7 +24,7 @@ lib_deps =
${env.lib_deps} ${env.lib_deps}
${networking_base.lib_deps} ${networking_base.lib_deps}
rweather/Crypto@^0.4.0 rweather/Crypto@^0.4.0
lovyan03/LovyanGFX@^1.1.16 https://github.com/lovyan03/LovyanGFX.git#1401c28a47646fe00538d487adcb2eb3c72de805
build_flags = build_flags =
${arduino_base.build_flags} ${arduino_base.build_flags}

View File

@ -16,8 +16,9 @@ build_src_filter =
lib_ignore = lib_ignore =
BluetoothOTA BluetoothOTA
lvgl
lib_deps = lib_deps =
${arduino_base.lib_deps} ${arduino_base.lib_deps}
${environmental_base.lib_deps} ${environmental_base.lib_deps}
rweather/Crypto rweather/Crypto

View File

@ -1,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 ### Define your devices here using Broadcom pin numbering
### Uncomment the block that corresponds to your hardware ### Uncomment the block that corresponds to your hardware
### Including the "Module:" line! ### Including the "Module:" line!
--- ---
Lora: Lora:
# Module: sx1262 # Waveshare SX126X XXXM
# DIO2_AS_RF_SWITCH: true
# CS: 21
# IRQ: 16
# Busy: 20
# Reset: 18
# SX126X_ANT_SW: 6
# Module: sx1262 # Waveshare SX1302 LISTEN ONLY AT THIS TIME! # Module: sx1262 # Waveshare SX1302 LISTEN ONLY AT THIS TIME!
# CS: 7 # CS: 7
@ -115,6 +111,29 @@ Display:
# Height: 320 # Height: 320
# Rotate: true # Rotate: true
### SHCHV 3.5 RPi TFT+Touchscreen
# Panel: ILI9486
# spidev: spidev0.0
# BusFrequency: 30000000
# DC: 24
# Reset: 25
# Width: 320
# Height: 480
# OffsetRotate: 2
### TZT 2.0 Inch TFT Display ST7789V 240RGBx320
# Panel: ST7789
# spidev: spidev0.0
# # CS: 8 # can be freely chosen
# BusFrequency: 80000000
# DC: 24 # can be freely chosen
# Width: 320
# Height: 240
# Reset: 25 # can be freely chosen
# Rotate: true
# OffsetRotate: 1
# Invert: true
### You can also specify the spi device for the display to use ### You can also specify the spi device for the display to use
# spidev: spidev0.0 # spidev: spidev0.0
@ -156,3 +175,4 @@ Webserver:
General: General:
MaxNodes: 200 MaxNodes: 200
MaxMessageQueue: 100 MaxMessageQueue: 100
ConfigDirectory: /etc/meshtasticd/config.d/

View 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

View 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

View File

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

41
boards/icarus.json Normal file
View 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
View 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

View File

@ -154,9 +154,16 @@ static void adcEnable()
#ifdef ADC_CTRL // enable adc voltage divider when we need to read #ifdef ADC_CTRL // enable adc voltage divider when we need to read
#ifdef ADC_USE_PULLUP #ifdef ADC_USE_PULLUP
pinMode(ADC_CTRL, INPUT_PULLUP); pinMode(ADC_CTRL, INPUT_PULLUP);
#else
#ifdef HELTEC_V3
pinMode(ADC_CTRL, INPUT);
uint8_t adc_ctl_enable_value = !(digitalRead(ADC_CTRL));
pinMode(ADC_CTRL, OUTPUT);
digitalWrite(ADC_CTRL, adc_ctl_enable_value);
#else #else
pinMode(ADC_CTRL, OUTPUT); pinMode(ADC_CTRL, OUTPUT);
digitalWrite(ADC_CTRL, ADC_CTRL_ENABLED); digitalWrite(ADC_CTRL, ADC_CTRL_ENABLED);
#endif
#endif #endif
delay(10); delay(10);
#endif #endif
@ -167,10 +174,14 @@ static void adcDisable()
#ifdef ADC_CTRL // disable adc voltage divider when we need to read #ifdef ADC_CTRL // disable adc voltage divider when we need to read
#ifdef ADC_USE_PULLUP #ifdef ADC_USE_PULLUP
pinMode(ADC_CTRL, INPUT_PULLDOWN); pinMode(ADC_CTRL, INPUT_PULLDOWN);
#else
#ifdef HELTEC_V3
pinMode(ADC_CTRL, ANALOG);
#else #else
digitalWrite(ADC_CTRL, !ADC_CTRL_ENABLED); digitalWrite(ADC_CTRL, !ADC_CTRL_ENABLED);
#endif #endif
#endif #endif
#endif
} }
#endif #endif

View File

@ -207,6 +207,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef GPS_BAUDRATE #ifndef GPS_BAUDRATE
#define GPS_BAUDRATE 9600 #define GPS_BAUDRATE 9600
#define GPS_BAUDRATE_FIXED 0
#else
#define GPS_BAUDRATE_FIXED 1
#endif #endif
/* Step #2: follow with defines common to the architecture; /* Step #2: follow with defines common to the architecture;

View File

@ -20,6 +20,7 @@
#ifdef ARCH_PORTDUINO #ifdef ARCH_PORTDUINO
#include "PortduinoGlue.h" #include "PortduinoGlue.h"
#include "meshUtils.h" #include "meshUtils.h"
#include <algorithm>
#include <ctime> #include <ctime>
#endif #endif
@ -412,30 +413,42 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
return 0; 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() bool GPS::setup()
{ {
if (!didSerialInit) { if (!didSerialInit) {
int msglen = 0; int msglen = 0;
if (tx_gpio && gnssModel == GNSS_MODEL_UNKNOWN) { if (tx_gpio && gnssModel == GNSS_MODEL_UNKNOWN) {
if (probeTries < 2) {
// if GPS_BAUDRATE is specified in variant (i.e. not 9600), skip to the specified rate. LOG_DEBUG("Probing for GPS at %d", serialSpeeds[speedSelect]);
if (speedSelect == 0 && GPS_BAUDRATE != serialSpeeds[speedSelect]) { gnssModel = probe(serialSpeeds[speedSelect]);
speedSelect = std::find(serialSpeeds, std::end(serialSpeeds), GPS_BAUDRATE) - serialSpeeds; if (gnssModel == GNSS_MODEL_UNKNOWN) {
if (++speedSelect == sizeof(serialSpeeds) / sizeof(int)) {
speedSelect = 0;
++probeTries;
}
}
} }
// Rare Serial Speeds
LOG_DEBUG("Probing for GPS at %d", serialSpeeds[speedSelect]); if (probeTries == 2) {
gnssModel = probe(serialSpeeds[speedSelect]); LOG_DEBUG("Probing for GPS at %d", rareSerialSpeeds[speedSelect]);
if (gnssModel == GNSS_MODEL_UNKNOWN) { gnssModel = probe(rareSerialSpeeds[speedSelect]);
if (++speedSelect == sizeof(serialSpeeds) / sizeof(int)) { if (gnssModel == GNSS_MODEL_UNKNOWN) {
speedSelect = 0; if (++speedSelect == sizeof(rareSerialSpeeds) / sizeof(int)) {
if (--probeTries == 0) { LOG_WARN("Giving up on GPS probe and setting to %d", GPS_BAUDRATE);
LOG_WARN("Giving up on GPS probe and setting to 9600.");
return true; return true;
} }
} }
return false;
} }
return false;
} else { } else {
gnssModel = GNSS_MODEL_UNKNOWN; 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) // Switch to Fitness Mode, for running and walking purpose with low speed (<5 m/s)
_serial_gps->write("$PMTK886,1*29\r\n"); _serial_gps->write("$PMTK886,1*29\r\n");
delay(250); 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) { } else if (gnssModel == GNSS_MODEL_ATGM336H) {
// Set the intial configuration of the device - these _should_ work for most AT6558 devices // 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); 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); 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 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); SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ENABLE_NMEA_BBR, "enable messages for M10 GPS BBR", 300);
delay(750); delay(750);
// Next enable wanted NMEA messages in RAM layer // Next enable wanted NMEA messages in RAM layer
@ -924,10 +950,10 @@ void GPS::down()
#endif #endif
if (softsleepSupported) { if (softsleepSupported) {
// How long does gps_update_interval need to be, for GPS_HARDSLEEP to become more efficient than GPS_SOFTSLEEP? // How long does gps_update_interval need to be, for GPS_HARDSLEEP to become more efficient than
// Heuristic equation. A compromise manually fitted to power observations from U-blox NEO-6M and M10050 // GPS_SOFTSLEEP? Heuristic equation. A compromise manually fitted to power observations from U-blox NEO-6M
// https://www.desmos.com/calculator/6gvjghoumr // and M10050 https://www.desmos.com/calculator/6gvjghoumr This is not particularly accurate, but probably an
// This is not particularly accurate, but probably an impromevement over a single, fixed threshold // improvement over a single, fixed threshold
uint32_t hardsleepThreshold = (2750 * pow(predictedSearchDuration / 1000, 1.22)); uint32_t hardsleepThreshold = (2750 * pow(predictedSearchDuration / 1000, 1.22));
LOG_DEBUG("gps_update_interval >= %us needed to justify hardsleep", hardsleepThreshold / 1000); LOG_DEBUG("gps_update_interval >= %us needed to justify hardsleep", hardsleepThreshold / 1000);
@ -1143,6 +1169,7 @@ GnssModel_t GPS::probe(int serialSpeed)
delay(20); delay(20);
PROBE_SIMPLE("L76B", "$PMTK605*31", "Quectel-L76B", GNSS_MODEL_MTK_L76B, 500); 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}; uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00};
UBXChecksum(cfg_rate, sizeof(cfg_rate)); UBXChecksum(cfg_rate, sizeof(cfg_rate));
@ -1279,10 +1306,12 @@ GPS *GPS::createGps()
if (!GPS_EN_ACTIVE) { // Need to invert the pin before hardware if (!GPS_EN_ACTIVE) { // Need to invert the pin before hardware
new GpioNotTransformer( 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 { } else {
new GpioUnaryTransformer( 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"); _serial_gps->write("$PMTK104*37\r\n");
// No PMTK_ACK for this command. // No PMTK_ACK for this command.
delay(100); delay(100);
// send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's UBLOX. // send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's
// Factory Reset // UBLOX. Factory Reset
byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFB, 0x00, 0x00, 0x00, byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFB, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E}; 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
_serial_gps->write(_message_reset, sizeof(_message_reset)); _serial_gps->write(_message_reset, sizeof(_message_reset));
@ -1430,8 +1459,8 @@ bool GPS::lookForTime()
auto d = reader.date; auto d = reader.date;
if (ti.isValid() && d.isValid()) { // Note: we don't check for updated, because we'll only be called if needed if (ti.isValid() && d.isValid()) { // Note: we don't check for updated, because we'll only be called if needed
/* Convert to unix time /* 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 The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1,
(midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z). 1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
*/ */
struct tm t; struct tm t;
t.tm_sec = ti.second() + round(ti.age() / 1000); t.tm_sec = ti.second() + round(ti.age() / 1000);
@ -1664,7 +1693,9 @@ bool GPS::whileActive()
} }
} }
#ifdef GPS_DEBUG #ifdef GPS_DEBUG
LOG_DEBUG(debugmsg.c_str()); if (debugmsg != "") {
LOG_DEBUG(debugmsg.c_str());
}
#endif #endif
return isValid; return isValid;
} }

View File

@ -34,6 +34,7 @@ typedef enum {
GNSS_MODEL_UC6580, GNSS_MODEL_UC6580,
GNSS_MODEL_UNKNOWN, GNSS_MODEL_UNKNOWN,
GNSS_MODEL_MTK_L76B, GNSS_MODEL_MTK_L76B,
GNSS_MODEL_MTK_PA1616S,
GNSS_MODEL_AG3335, GNSS_MODEL_AG3335,
GNSS_MODEL_AG3352 GNSS_MODEL_AG3352
} GnssModel_t; } GnssModel_t;
@ -75,13 +76,21 @@ class GPS : private concurrency::OSThread
uint8_t fixType = 0; // fix type from GPGSA uint8_t fixType = 0; // fix type from GPGSA
#endif #endif
private: 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 lastWakeStartMsec = 0, lastSleepStartMsec = 0, lastFixStartMsec = 0;
uint32_t rx_gpio = 0; uint32_t rx_gpio = 0;
uint32_t tx_gpio = 0; uint32_t tx_gpio = 0;
int speedSelect = 0; int speedSelect = 0;
int probeTries = 2; int probeTries = 0;
/** /**
* hasValidLocation - indicates that the position variables contain a complete * hasValidLocation - indicates that the position variables contain a complete

View File

@ -70,9 +70,9 @@ bool GPSUpdateScheduling::isUpdateDue()
// Have we been searching for a GPS position for too long? // Have we been searching for a GPS position for too long?
bool GPSUpdateScheduling::searchedTooLong() bool GPSUpdateScheduling::searchedTooLong()
{ {
uint32_t maxSearchMs = uint32_t minimumOrConfiguredSecs =
Default::getConfiguredOrDefaultMs(config.position.position_broadcast_secs, default_broadcast_interval_secs); 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 broadcast interval set to max, no such thing as "too long"
if (maxSearchMs == UINT32_MAX) if (maxSearchMs == UINT32_MAX)
return false; return false;
@ -115,4 +115,4 @@ void GPSUpdateScheduling::updateLockTimePrediction()
uint32_t GPSUpdateScheduling::predictedSearchDurationMs() uint32_t GPSUpdateScheduling::predictedSearchDurationMs()
{ {
return GPSUpdateScheduling::predictedMsToGetLock; return GPSUpdateScheduling::predictedMsToGetLock;
} }

View File

@ -59,7 +59,7 @@ int32_t ScanAndSelectInput::runOnce()
// If: "no messages added" alert screen currently shown // If: "no messages added" alert screen currently shown
if (alertingNoMessage) { if (alertingNoMessage) {
// Dismiss the alert screen several seconds after it appears // Dismiss the alert screen several seconds after it appears
if (now > alertingSinceMs + durationAlertMs) { if (!Throttle::isWithinTimespanMs(alertingSinceMs, durationAlertMs)) {
alertingNoMessage = false; alertingNoMessage = false;
screen->endAlert(); screen->endAlert();
} }
@ -74,9 +74,9 @@ int32_t ScanAndSelectInput::runOnce()
// Existing press // Existing press
else { else {
// Duration enough for long press // Longer than shortpress window
// Long press not yet fired (prevent repeat firing while held) // Long press not yet fired (prevent repeat firing while held)
if (!longPressFired && Throttle::isWithinTimespanMs(downSinceMs, durationLongMs)) { if (!longPressFired && !Throttle::isWithinTimespanMs(downSinceMs, durationLongMs)) {
longPressFired = true; longPressFired = true;
longPress(); longPress();
} }
@ -91,7 +91,9 @@ int32_t ScanAndSelectInput::runOnce()
// Button newly released // Button newly released
// Long press event didn't already fire // Long press event didn't already fire
if (held && !longPressFired) { if (held && !longPressFired) {
// Duration enough for short press // Duration within shortpress window
// - longer than durationShortPress (debounce)
// - shorter than durationLongPress
if (!Throttle::isWithinTimespanMs(downSinceMs, durationShortMs)) { if (!Throttle::isWithinTimespanMs(downSinceMs, durationShortMs)) {
shortPress(); shortPress();
} }

View File

@ -266,14 +266,19 @@ void setup()
#ifdef DEBUG_PORT #ifdef DEBUG_PORT
consoleInit(); // Set serial baud rate and init our mesh console consoleInit(); // Set serial baud rate and init our mesh console
#endif #endif
#ifdef UNPHONE
unphone.printStore();
#endif
#if ARCH_PORTDUINO #if ARCH_PORTDUINO
struct timeval tv; struct timeval tv;
tv.tv_sec = time(NULL); tv.tv_sec = time(NULL);
tv.tv_usec = 0; tv.tv_usec = 0;
perhapsSetRTC(RTCQualityNTP, &tv); perhapsSetRTC(RTCQualityNTP, &tv);
#endif #endif
powerMonInit();
powerMonInit();
serialSinceMsec = millis(); serialSinceMsec = millis();
LOG_INFO("\n\n//\\ E S H T /\\ S T / C\n"); LOG_INFO("\n\n//\\ E S H T /\\ S T / C\n");
@ -642,6 +647,8 @@ void setup()
rp2040Setup(); rp2040Setup();
#endif #endif
initSPI(); // needed here before reading from littleFS
// We do this as early as possible because this loads preferences from flash // 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 // but we need to do this after main cpu init (esp32setup), because we need the random seed set
nodeDB = new NodeDB; nodeDB = new NodeDB;
@ -705,7 +712,6 @@ void setup()
#endif #endif
// Init our SPI controller (must be before screen and lora) // Init our SPI controller (must be before screen and lora)
initSPI();
#ifdef ARCH_RP2040 #ifdef ARCH_RP2040
#ifdef HW_SPI1_DEVICE #ifdef HW_SPI1_DEVICE
SPI1.setSCK(LORA_SCK); SPI1.setSCK(LORA_SCK);
@ -1189,4 +1195,4 @@ void loop()
mainDelay.delay(delayMsec); mainDelay.delay(delayMsec);
} }
} }
#endif #endif

View File

@ -32,6 +32,7 @@
#if HAS_WIFI #if HAS_WIFI
#include "mesh/wifi/WiFiAPClient.h" #include "mesh/wifi/WiFiAPClient.h"
#endif #endif
#include "SPILock.h"
#include "modules/StoreForwardModule.h" #include "modules/StoreForwardModule.h"
#include <Preferences.h> #include <Preferences.h>
#include <esp_efuse.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, &device_id_start, sizeof(device_id_start));
memcpy(myNodeInfo.device_id.bytes + sizeof(device_id_start), &device_id_end, sizeof(device_id_end)); memcpy(myNodeInfo.device_id.bytes + sizeof(device_id_start), &device_id_end, sizeof(device_id_end));
myNodeInfo.device_id.size = 16; myNodeInfo.device_id.size = 16;
hasUniqueId = true; // Uncomment below to print the device id
// hasUniqueId = true;
#else #else
// FIXME - implement for other platforms // FIXME - implement for other platforms
#endif #endif
// Uncomment below to print the device id
// if (hasUniqueId) { // if (hasUniqueId) {
// std::string deviceIdHex; // std::string deviceIdHex;
// for (size_t i = 0; i < myNodeInfo.device_id.size; ++i) { // 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) #if !(MESHTASTIC_EXCLUDE_PKI_KEYGEN || MESHTASTIC_EXCLUDE_PKI)
bool keygenSuccess = false; if (!owner.is_licensed) {
if (config.security.private_key.size == 32) { bool keygenSuccess = false;
if (crypto->regeneratePublicKey(config.security.public_key.bytes, config.security.private_key.bytes)) { 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; keygenSuccess = true;
} }
} else { if (keygenSuccess) {
LOG_INFO("Generating new PKI keys"); config.security.public_key.size = 32;
crypto->generateKeyPair(config.security.public_key.bytes, config.security.private_key.bytes); config.security.private_key.size = 32;
keygenSuccess = true; 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) #elif !(MESHTASTIC_EXCLUDE_PKI)
// Calculate Curve25519 public and private keys // 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) { if (role == meshtastic_Config_DeviceConfig_Role_ROUTER) {
initConfigIntervals(); initConfigIntervals();
initModuleConfigIntervals(); initModuleConfigIntervals();
config.device.rebroadcast_mode = meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY;
} else if (role == meshtastic_Config_DeviceConfig_Role_REPEATER) { } else if (role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
config.display.screen_on_secs = 1; 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) { } else if (role == meshtastic_Config_DeviceConfig_Role_SENSOR) {
moduleConfig.telemetry.environment_measurement_enabled = true; moduleConfig.telemetry.environment_measurement_enabled = true;
moduleConfig.telemetry.environment_update_interval = 300; 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 NodeDB::saveProto(const char *filename, size_t protoSize, const pb_msgdesc_t *fields, const void *dest_struct,
bool fullAtomic) bool fullAtomic)
{ {
#ifdef ARCH_ESP32
concurrency::LockGuard g(spiLock);
#endif
bool okay = false; bool okay = false;
#ifdef FSCom #ifdef FSCom
auto f = SafeFile(filename, fullAtomic); 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..."); LOG_ERROR("A critical failure occurred, portduino is exiting...");
exit(2); exit(2);
#endif #endif
} }

View File

@ -271,7 +271,7 @@ uint32_t RadioInterface::getTxDelayMsecWeighted(float snr)
if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER || if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ||
config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) { config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
delay = random(0, 2 * CWsize) * slotTimeMsec; 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 { } else {
// offset the maximum delay for routers: (2 * CWmax * slotTimeMsec) // offset the maximum delay for routers: (2 * CWmax * slotTimeMsec)
delay = (2 * CWmax * slotTimeMsec) + random(0, pow(2, CWsize)) * slotTimeMsec; delay = (2 * CWmax * slotTimeMsec) + random(0, pow(2, CWsize)) * slotTimeMsec;

View File

@ -11,6 +11,10 @@
#include <pb_decode.h> #include <pb_decode.h>
#include <pb_encode.h> #include <pb_encode.h>
#if ARCH_PORTDUINO
#include "PortduinoGlue.h"
#include "meshUtils.h"
#endif
void LockingArduinoHal::spiBeginTransaction() void LockingArduinoHal::spiBeginTransaction()
{ {
spiLock->lock(); spiLock->lock();
@ -20,9 +24,9 @@ void LockingArduinoHal::spiBeginTransaction()
void LockingArduinoHal::spiEndTransaction() void LockingArduinoHal::spiEndTransaction()
{ {
spiLock->unlock();
ArduinoHal::spiEndTransaction(); ArduinoHal::spiEndTransaction();
spiLock->unlock();
} }
#if ARCH_PORTDUINO #if ARCH_PORTDUINO
void LockingArduinoHal::spiTransfer(uint8_t *out, size_t len, uint8_t *in) 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 // Send any outgoing packets we have ready
meshtastic_MeshPacket *txp = txQueue.dequeue(); meshtastic_MeshPacket *txp = txQueue.dequeue();
assert(txp); assert(txp);
bool isLoraTx = txp->to != NODENUM_BROADCAST_NO_LORA;
startSend(txp); startSend(txp);
// Packet has been sent, count it toward our TX airtime utilization. if (isLoraTx) {
uint32_t xmitMsec = getPacketTime(txp); // Packet has been sent, count it toward our TX airtime utilization.
airTime->logAirtime(TX_LOG, xmitMsec); uint32_t xmitMsec = getPacketTime(txp);
airTime->logAirtime(TX_LOG, xmitMsec);
}
} }
} }
} else { } else {
@ -390,6 +397,11 @@ void RadioLibInterface::handleReceiveInterrupt()
#endif #endif
int state = iface->readData((uint8_t *)&radioBuffer, length); 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) { if (state != RADIOLIB_ERR_NONE) {
LOG_ERROR("ignoring received packet due to error=%d", state); LOG_ERROR("ignoring received packet due to error=%d", state);
rxBad++; rxBad++;

View File

@ -81,14 +81,17 @@ int32_t Router::runOnce()
*/ */
void Router::enqueueReceivedMessage(meshtastic_MeshPacket *p) void Router::enqueueReceivedMessage(meshtastic_MeshPacket *p)
{ {
if (fromRadioQueue.enqueue(p, 0)) { // NOWAIT - fixme, if queue is full, delete older messages // Try enqueue until successful
while (!fromRadioQueue.enqueue(p, 0)) {
// Nasty hack because our threading is primitive. interfaces shouldn't need to know about routers FIXME meshtastic_MeshPacket *old_p;
setReceivedMessage(); old_p = fromRadioQueue.dequeuePtr(0); // Dequeue and discard the oldest packet
} else { if (old_p) {
printPacket("BUG! fromRadioQueue is full! Discarding!", p); printPacket("fromRadioQ full, drop oldest!", old_p);
packetPool.release(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 /// Generate a unique packet id
@ -591,19 +594,20 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
skipHandle = true; skipHandle = true;
} }
bool shouldIgnoreNonstandardPorts =
config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY;
#if USERPREFS_EVENT_MODE #if USERPREFS_EVENT_MODE
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag && shouldIgnoreNonstandardPorts = true;
(p->decoded.portnum == meshtastic_PortNum_ATAK_FORWARDER || p->decoded.portnum == meshtastic_PortNum_ATAK_PLUGIN || #endif
p->decoded.portnum == meshtastic_PortNum_PAXCOUNTER_APP || p->decoded.portnum == meshtastic_PortNum_IP_TUNNEL_APP || if (shouldIgnoreNonstandardPorts && p->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
p->decoded.portnum == meshtastic_PortNum_AUDIO_APP || p->decoded.portnum == meshtastic_PortNum_PRIVATE_APP || IS_ONE_OF(p->decoded.portnum, meshtastic_PortNum_ATAK_FORWARDER, meshtastic_PortNum_ATAK_PLUGIN,
p->decoded.portnum == meshtastic_PortNum_DETECTION_SENSOR_APP || meshtastic_PortNum_PAXCOUNTER_APP, meshtastic_PortNum_IP_TUNNEL_APP, meshtastic_PortNum_AUDIO_APP,
p->decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP || meshtastic_PortNum_PRIVATE_APP, meshtastic_PortNum_DETECTION_SENSOR_APP, meshtastic_PortNum_RANGE_TEST_APP,
p->decoded.portnum == meshtastic_PortNum_REMOTE_HARDWARE_APP)) { meshtastic_PortNum_REMOTE_HARDWARE_APP)) {
LOG_DEBUG("Ignoring packet on blacklisted portnum during event"); LOG_DEBUG("Ignoring packet on blacklisted portnum for CORE_PORTNUMS_ONLY");
cancelSending(p->from, p->id); cancelSending(p->from, p->id);
skipHandle = true; skipHandle = true;
} }
#endif
} else { } else {
printPacket("packet decoding failed or skipped (no PSK?)", p); printPacket("packet decoding failed or skipped (no PSK?)", p);
} }

View File

@ -4,6 +4,7 @@
#ifndef PB_MESHTASTIC_MESHTASTIC_CONFIG_PB_H_INCLUDED #ifndef PB_MESHTASTIC_MESHTASTIC_CONFIG_PB_H_INCLUDED
#define PB_MESHTASTIC_MESHTASTIC_CONFIG_PB_H_INCLUDED #define PB_MESHTASTIC_MESHTASTIC_CONFIG_PB_H_INCLUDED
#include <pb.h> #include <pb.h>
#include "meshtastic/device_ui.pb.h"
#if PB_PROTO_HEADER_VERSION != 40 #if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator. #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_BluetoothConfig bluetooth;
meshtastic_Config_SecurityConfig security; meshtastic_Config_SecurityConfig security;
meshtastic_Config_SessionkeyConfig sessionkey; meshtastic_Config_SessionkeyConfig sessionkey;
meshtastic_DeviceUIConfig device_ui;
} payload_variant; } payload_variant;
} meshtastic_Config; } meshtastic_Config;
@ -779,6 +781,7 @@ extern "C" {
#define meshtastic_Config_bluetooth_tag 7 #define meshtastic_Config_bluetooth_tag 7
#define meshtastic_Config_security_tag 8 #define meshtastic_Config_security_tag 8
#define meshtastic_Config_sessionkey_tag 9 #define meshtastic_Config_sessionkey_tag 9
#define meshtastic_Config_device_ui_tag 10
/* Struct field encoding specification for nanopb */ /* Struct field encoding specification for nanopb */
#define meshtastic_Config_FIELDLIST(X, a) \ #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,lora,payload_variant.lora), 6) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,bluetooth,payload_variant.bluetooth), 7) \ 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,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_CALLBACK NULL
#define meshtastic_Config_DEFAULT NULL #define meshtastic_Config_DEFAULT NULL
#define meshtastic_Config_payload_variant_device_MSGTYPE meshtastic_Config_DeviceConfig #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_bluetooth_MSGTYPE meshtastic_Config_BluetoothConfig
#define meshtastic_Config_payload_variant_security_MSGTYPE meshtastic_Config_SecurityConfig #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_sessionkey_MSGTYPE meshtastic_Config_SessionkeyConfig
#define meshtastic_Config_payload_variant_device_ui_MSGTYPE meshtastic_DeviceUIConfig
#define meshtastic_Config_DeviceConfig_FIELDLIST(X, a) \ #define meshtastic_Config_DeviceConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UENUM, role, 1) \ X(a, STATIC, SINGULAR, UENUM, role, 1) \

View File

@ -40,7 +40,19 @@ typedef enum _meshtastic_Language {
/* Polish */ /* Polish */
meshtastic_Language_POLISH = 8, meshtastic_Language_POLISH = 8,
/* Turkish */ /* 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; } meshtastic_Language;
/* Struct definitions */ /* Struct definitions */
@ -73,16 +85,22 @@ typedef struct _meshtastic_NodeHighlight {
} meshtastic_NodeHighlight; } meshtastic_NodeHighlight;
typedef struct _meshtastic_DeviceUIConfig { 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 */ /* TFT display brightness 1..255 */
uint8_t screen_brightness; uint8_t screen_brightness;
/* Screen timeout 0..900 */ /* Screen timeout 0..900 */
uint16_t screen_timeout; uint16_t screen_timeout;
/* Screen lock enabled */ /* Screen/Settings lock enabled */
bool screen_lock; bool screen_lock;
bool settings_lock;
uint32_t pin_code;
/* Color theme */ /* Color theme */
meshtastic_Theme theme; meshtastic_Theme theme;
/* Audible message alert enabled */ /* Audible message, banner and ring tone */
bool alert_enabled; bool alert_enabled;
bool banner_enabled;
uint8_t ring_tone_id;
/* Localization */ /* Localization */
meshtastic_Language language; meshtastic_Language language;
/* Node list filter */ /* Node list filter */
@ -104,8 +122,8 @@ extern "C" {
#define _meshtastic_Theme_ARRAYSIZE ((meshtastic_Theme)(meshtastic_Theme_RED+1)) #define _meshtastic_Theme_ARRAYSIZE ((meshtastic_Theme)(meshtastic_Theme_RED+1))
#define _meshtastic_Language_MIN meshtastic_Language_ENGLISH #define _meshtastic_Language_MIN meshtastic_Language_ENGLISH
#define _meshtastic_Language_MAX meshtastic_Language_TURKISH #define _meshtastic_Language_MAX meshtastic_Language_TRADITIONAL_CHINESE
#define _meshtastic_Language_ARRAYSIZE ((meshtastic_Language)(meshtastic_Language_TURKISH+1)) #define _meshtastic_Language_ARRAYSIZE ((meshtastic_Language)(meshtastic_Language_TRADITIONAL_CHINESE+1))
#define meshtastic_DeviceUIConfig_theme_ENUMTYPE meshtastic_Theme #define meshtastic_DeviceUIConfig_theme_ENUMTYPE meshtastic_Theme
#define meshtastic_DeviceUIConfig_language_ENUMTYPE meshtastic_Language #define meshtastic_DeviceUIConfig_language_ENUMTYPE meshtastic_Language
@ -114,10 +132,10 @@ extern "C" {
/* Initializer values for message structs */ /* 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_NodeFilter_init_default {0, 0, 0, 0, 0, ""}
#define meshtastic_NodeHighlight_init_default {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_NodeFilter_init_zero {0, 0, 0, 0, 0, ""}
#define meshtastic_NodeHighlight_init_zero {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_telemetry_switch_tag 3
#define meshtastic_NodeHighlight_iaq_switch_tag 4 #define meshtastic_NodeHighlight_iaq_switch_tag 4
#define meshtastic_NodeHighlight_node_name_tag 5 #define meshtastic_NodeHighlight_node_name_tag 5
#define meshtastic_DeviceUIConfig_screen_brightness_tag 1 #define meshtastic_DeviceUIConfig_version_tag 1
#define meshtastic_DeviceUIConfig_screen_timeout_tag 2 #define meshtastic_DeviceUIConfig_screen_brightness_tag 2
#define meshtastic_DeviceUIConfig_screen_lock_tag 3 #define meshtastic_DeviceUIConfig_screen_timeout_tag 3
#define meshtastic_DeviceUIConfig_theme_tag 4 #define meshtastic_DeviceUIConfig_screen_lock_tag 4
#define meshtastic_DeviceUIConfig_alert_enabled_tag 5 #define meshtastic_DeviceUIConfig_settings_lock_tag 5
#define meshtastic_DeviceUIConfig_language_tag 6 #define meshtastic_DeviceUIConfig_pin_code_tag 6
#define meshtastic_DeviceUIConfig_node_filter_tag 7 #define meshtastic_DeviceUIConfig_theme_tag 7
#define meshtastic_DeviceUIConfig_node_highlight_tag 8 #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 */ /* Struct field encoding specification for nanopb */
#define meshtastic_DeviceUIConfig_FIELDLIST(X, a) \ #define meshtastic_DeviceUIConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, screen_brightness, 1) \ X(a, STATIC, SINGULAR, UINT32, version, 1) \
X(a, STATIC, SINGULAR, UINT32, screen_timeout, 2) \ X(a, STATIC, SINGULAR, UINT32, screen_brightness, 2) \
X(a, STATIC, SINGULAR, BOOL, screen_lock, 3) \ X(a, STATIC, SINGULAR, UINT32, screen_timeout, 3) \
X(a, STATIC, SINGULAR, UENUM, theme, 4) \ X(a, STATIC, SINGULAR, BOOL, screen_lock, 4) \
X(a, STATIC, SINGULAR, BOOL, alert_enabled, 5) \ X(a, STATIC, SINGULAR, BOOL, settings_lock, 5) \
X(a, STATIC, SINGULAR, UENUM, language, 6) \ X(a, STATIC, SINGULAR, UINT32, pin_code, 6) \
X(a, STATIC, OPTIONAL, MESSAGE, node_filter, 7) \ X(a, STATIC, SINGULAR, UENUM, theme, 7) \
X(a, STATIC, OPTIONAL, MESSAGE, node_highlight, 8) 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_CALLBACK NULL
#define meshtastic_DeviceUIConfig_DEFAULT NULL #define meshtastic_DeviceUIConfig_DEFAULT NULL
#define meshtastic_DeviceUIConfig_node_filter_MSGTYPE meshtastic_NodeFilter #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) */ /* Maximum encoded size of messages (where known) */
#define MESHTASTIC_MESHTASTIC_DEVICE_UI_PB_H_MAX_SIZE meshtastic_DeviceUIConfig_size #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_NodeFilter_size 36
#define meshtastic_NodeHighlight_size 25 #define meshtastic_NodeHighlight_size 25

View File

@ -408,7 +408,7 @@ typedef enum _meshtastic_LogRecord_Level {
} meshtastic_LogRecord_Level; } meshtastic_LogRecord_Level;
/* Struct definitions */ /* Struct definitions */
/* a gps position */ /* A GPS Position */
typedef struct _meshtastic_Position { typedef struct _meshtastic_Position {
/* The new preferred location encoding, multiply by 1e-7 to get degrees /* The new preferred location encoding, multiply by 1e-7 to get degrees
in floating point */ in floating point */

View File

@ -3,7 +3,6 @@
#include "FSCommon.h" #include "FSCommon.h"
#include "mesh-pb-constants.h" #include "mesh-pb-constants.h"
#include <Arduino.h> #include <Arduino.h>
#include <assert.h>
#include <pb_decode.h> #include <pb_decode.h>
#include <pb_encode.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); pb_ostream_t stream = pb_ostream_from_buffer(destbuf, destbufsize);
if (!pb_encode(&stream, fields, src_struct)) { if (!pb_encode(&stream, fields, src_struct)) {
LOG_ERROR("Panic: can't encode protobuf reason='%s'", PB_GET_ERROR(&stream)); 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; return 0;
} else { } else {
return stream.bytes_written; 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 true;
return false; return false;
} }

View File

@ -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) void printBytes(const char *label, const uint8_t *p, size_t numbytes)
{ {
int labelSize = strlen(label); int labelSize = strlen(label);
if (labelSize < 100 && numbytes < 64) { char *messageBuffer = new char[labelSize + (numbytes * 3) + 2];
char *messageBuffer = new char[labelSize + (numbytes * 3) + 2]; strncpy(messageBuffer, label, labelSize);
strncpy(messageBuffer, label, labelSize); for (size_t i = 0; i < numbytes; i++)
for (size_t i = 0; i < numbytes; i++) snprintf(messageBuffer + labelSize + i * 3, 4, " %02x", p[i]);
snprintf(messageBuffer + labelSize + i * 3, 4, " %02x", p[i]); strcpy(messageBuffer + labelSize + numbytes * 3, "\n");
strcpy(messageBuffer + labelSize + numbytes * 3, "\n"); LOG_DEBUG(messageBuffer);
LOG_DEBUG(messageBuffer); delete[] messageBuffer;
delete[] messageBuffer;
}
} }
bool memfll(const uint8_t *mem, uint8_t find, size_t numbytes) bool memfll(const uint8_t *mem, uint8_t find, size_t numbytes)

View File

@ -900,7 +900,7 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r
#ifdef ARCH_PORTDUINO #ifdef ARCH_PORTDUINO
conn.wifi.status.is_connected = true; conn.wifi.status.is_connected = true;
#else #else
conn.wifi.status.is_connected = WiFi.status() != WL_CONNECTED; conn.wifi.status.is_connected = WiFi.status() == WL_CONNECTED;
#endif #endif
strncpy(conn.wifi.ssid, config.network.wifi_ssid, 33); strncpy(conn.wifi.ssid, config.network.wifi_ssid, 33);
if (conn.wifi.status.is_connected) { if (conn.wifi.status.is_connected) {
@ -932,10 +932,14 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r
conn.has_bluetooth = true; conn.has_bluetooth = true;
conn.bluetooth.pin = config.bluetooth.fixed_pin; conn.bluetooth.pin = config.bluetooth.fixed_pin;
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
conn.bluetooth.is_connected = nimbleBluetooth->isConnected(); if (config.bluetooth.enabled && nimbleBluetooth) {
conn.bluetooth.rssi = nimbleBluetooth->getRssi(); conn.bluetooth.is_connected = nimbleBluetooth->isConnected();
conn.bluetooth.rssi = nimbleBluetooth->getRssi();
}
#elif defined(ARCH_NRF52) #elif defined(ARCH_NRF52)
conn.bluetooth.is_connected = nrf52Bluetooth->isConnected(); if (config.bluetooth.enabled && nrf52Bluetooth) {
conn.bluetooth.is_connected = nrf52Bluetooth->isConnected();
}
#endif #endif
#endif #endif
conn.has_serial = true; // No serial-less devices conn.has_serial = true; // No serial-less devices

View File

@ -93,7 +93,7 @@ int32_t ExternalNotificationModule::runOnce()
nagCycleCutoff = UINT32_MAX; nagCycleCutoff = UINT32_MAX;
LOG_INFO("Turning off external notification: "); LOG_INFO("Turning off external notification: ");
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
setExternalOff(i); setExternalState(i, false);
externalTurnedOn[i] = 0; externalTurnedOn[i] = 0;
LOG_INFO("%d ", i); 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 if (externalTurnedOn[0] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) < : EXT_NOTIFICATION_MODULE_OUTPUT_MS) <
millis()) { millis()) {
getExternal(0) ? setExternalOff(0) : setExternalOn(0); setExternalState(0, !getExternal(0));
} }
if (externalTurnedOn[1] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms if (externalTurnedOn[1] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) < : EXT_NOTIFICATION_MODULE_OUTPUT_MS) <
millis()) { millis()) {
getExternal(1) ? setExternalOff(1) : setExternalOn(1); setExternalState(0, !getExternal(1));
} }
if (externalTurnedOn[2] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms if (externalTurnedOn[2] + (moduleConfig.external_notification.output_ms ? moduleConfig.external_notification.output_ms
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) < : EXT_NOTIFICATION_MODULE_OUTPUT_MS) <
millis()) { millis()) {
getExternal(2) ? setExternalOff(2) : setExternalOn(2); setExternalState(0, !getExternal(2));
} }
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE) #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 red = (colorState & 4) ? brightnessValues[brightnessIndex] : 0; // Red enabled on colorState = 4,5,6,7
@ -184,7 +184,7 @@ int32_t ExternalNotificationModule::runOnce()
} }
#endif #endif
// now let the PWM buzzer play // 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()) { if (rtttl::isPlaying()) {
rtttl::play(); rtttl::play();
} else if (isNagging && (nagCycleCutoff >= millis())) { } 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(); externalTurnedOn[index] = millis();
switch (index) { switch (index) {
case 1: case 1:
#ifdef UNPHONE #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 #endif
if (moduleConfig.external_notification.output_vibra) if (moduleConfig.external_notification.output_vibra)
digitalWrite(moduleConfig.external_notification.output_vibra, true); digitalWrite(moduleConfig.external_notification.output_vibra, on);
break; break;
case 2: case 2:
if (moduleConfig.external_notification.output_buzzer) if (moduleConfig.external_notification.output_buzzer)
digitalWrite(moduleConfig.external_notification.output_buzzer, true); digitalWrite(moduleConfig.external_notification.output_buzzer, on);
break; break;
default: default:
if (output > 0) if (output > 0)
digitalWrite(output, (moduleConfig.external_notification.active ? true : false)); digitalWrite(output, (moduleConfig.external_notification.active ? on : !on));
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));
break; break;
} }
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE) #if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
red = 0; if (!on) {
green = 0; red = 0;
blue = 0; green = 0;
blue = 0;
}
#endif
#ifdef HAS_NCP5623 #ifdef HAS_NCP5623
if (rgb_found.type == ScanI2C::NCP5623) { if (rgb_found.type == ScanI2C::NCP5623) {
rgb.setColor(red, green, blue); rgb.setColor(red, green, blue);
@ -304,10 +260,12 @@ void ExternalNotificationModule::setExternalOff(uint8_t index)
#ifdef UNPHONE #ifdef UNPHONE
unphone.rgb(red, green, blue); unphone.rgb(red, green, blue);
#endif #endif
#endif
#ifdef T_WATCH_S3 #ifdef T_WATCH_S3
drv.stop(); if (on) {
drv.go();
} else {
drv.stop();
}
#endif #endif
} }
@ -379,19 +337,19 @@ ExternalNotificationModule::ExternalNotificationModule()
LOG_INFO("Using Pin %i in digital mode", output); LOG_INFO("Using Pin %i in digital mode", output);
pinMode(output, OUTPUT); pinMode(output, OUTPUT);
} }
setExternalOff(0); setExternalState(0, false);
externalTurnedOn[0] = 0; externalTurnedOn[0] = 0;
if (moduleConfig.external_notification.output_vibra) { if (moduleConfig.external_notification.output_vibra) {
LOG_INFO("Using Pin %i for vibra motor", 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); pinMode(moduleConfig.external_notification.output_vibra, OUTPUT);
setExternalOff(1); setExternalState(1, false);
externalTurnedOn[1] = 0; externalTurnedOn[1] = 0;
} }
if (moduleConfig.external_notification.output_buzzer) { if (moduleConfig.external_notification.output_buzzer) {
if (!moduleConfig.external_notification.use_pwm) { if (!moduleConfig.external_notification.use_pwm) {
LOG_INFO("Using Pin %i for buzzer", moduleConfig.external_notification.output_buzzer); LOG_INFO("Using Pin %i for buzzer", moduleConfig.external_notification.output_buzzer);
pinMode(moduleConfig.external_notification.output_buzzer, OUTPUT); pinMode(moduleConfig.external_notification.output_buzzer, OUTPUT);
setExternalOff(2); setExternalState(2, false);
externalTurnedOn[2] = 0; externalTurnedOn[2] = 0;
} else { } else {
config.device.buzzer_gpio = config.device.buzzer_gpio ? config.device.buzzer_gpio : PIN_BUZZER; 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) { if (containsBell) {
LOG_INFO("externalNotificationModule - Notification Bell"); LOG_INFO("externalNotificationModule - Notification Bell");
isNagging = true; isNagging = true;
setExternalOn(0); setExternalState(0, true);
if (moduleConfig.external_notification.nag_timeout) { if (moduleConfig.external_notification.nag_timeout) {
nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000; nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000;
} else { } else {
@ -462,7 +420,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
if (containsBell) { if (containsBell) {
LOG_INFO("externalNotificationModule - Notification Bell (Vibra)"); LOG_INFO("externalNotificationModule - Notification Bell (Vibra)");
isNagging = true; isNagging = true;
setExternalOn(1); setExternalState(1, true);
if (moduleConfig.external_notification.nag_timeout) { if (moduleConfig.external_notification.nag_timeout) {
nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000; nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000;
} else { } else {
@ -476,7 +434,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
LOG_INFO("externalNotificationModule - Notification Bell (Buzzer)"); LOG_INFO("externalNotificationModule - Notification Bell (Buzzer)");
isNagging = true; isNagging = true;
if (!moduleConfig.external_notification.use_pwm) { if (!moduleConfig.external_notification.use_pwm) {
setExternalOn(2); setExternalState(2, true);
} else { } else {
#ifdef HAS_I2S #ifdef HAS_I2S
audioThread->beginRttl(rtttlConfig.ringtone, strlen_P(rtttlConfig.ringtone)); audioThread->beginRttl(rtttlConfig.ringtone, strlen_P(rtttlConfig.ringtone));
@ -495,7 +453,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
if (moduleConfig.external_notification.alert_message) { if (moduleConfig.external_notification.alert_message) {
LOG_INFO("externalNotificationModule - Notification Module"); LOG_INFO("externalNotificationModule - Notification Module");
isNagging = true; isNagging = true;
setExternalOn(0); setExternalState(0, true);
if (moduleConfig.external_notification.nag_timeout) { if (moduleConfig.external_notification.nag_timeout) {
nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000; nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000;
} else { } else {
@ -506,7 +464,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
if (moduleConfig.external_notification.alert_message_vibra) { if (moduleConfig.external_notification.alert_message_vibra) {
LOG_INFO("externalNotificationModule - Notification Module (Vibra)"); LOG_INFO("externalNotificationModule - Notification Module (Vibra)");
isNagging = true; isNagging = true;
setExternalOn(1); setExternalState(1, true);
if (moduleConfig.external_notification.nag_timeout) { if (moduleConfig.external_notification.nag_timeout) {
nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000; nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000;
} else { } else {
@ -518,7 +476,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
LOG_INFO("externalNotificationModule - Notification Module (Buzzer)"); LOG_INFO("externalNotificationModule - Notification Module (Buzzer)");
isNagging = true; isNagging = true;
if (!moduleConfig.external_notification.use_pwm && !moduleConfig.external_notification.use_i2s_as_buzzer) { if (!moduleConfig.external_notification.use_pwm && !moduleConfig.external_notification.use_i2s_as_buzzer) {
setExternalOn(2); setExternalState(2, true);
} else { } else {
#ifdef HAS_I2S #ifdef HAS_I2S
if (moduleConfig.external_notification.use_i2s_as_buzzer) { if (moduleConfig.external_notification.use_i2s_as_buzzer) {

View File

@ -32,10 +32,9 @@ class ExternalNotificationModule : public SinglePortModule, private concurrency:
public: public:
ExternalNotificationModule(); ExternalNotificationModule();
uint32_t nagCycleCutoff = UINT32_MAX; uint32_t nagCycleCutoff = 1;
void setExternalOn(uint8_t index = 0); void setExternalState(uint8_t index = 0, bool on = false);
void setExternalOff(uint8_t index = 0);
bool getExternal(uint8_t index = 0); bool getExternal(uint8_t index = 0);
void setMute(bool mute) { isMuted = mute; } void setMute(bool mute) { isMuted = mute; }

View File

@ -121,9 +121,7 @@ Will be used for broadcast.
*/ */
int32_t NeighborInfoModule::runOnce() 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); return Default::getConfiguredOrDefaultMs(moduleConfig.neighbor_info.update_interval, default_neighbor_info_broadcast_secs);
} }

View File

@ -81,6 +81,12 @@ meshtastic_MeshPacket *NodeInfoModule::allocReply()
ignoreRequest = false; // Don't ignore requests anymore ignoreRequest = false; // Don't ignore requests anymore
meshtastic_User &u = owner; 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); LOG_INFO("sending owner %s/%s/%s", u.id, u.long_name, u.short_name);
lastSentToMesh = millis(); lastSentToMesh = millis();
return allocDataProtobuf(u); return allocDataProtobuf(u);

View File

@ -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", // 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); // 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 * If moduleConfig.serial.echo is true, then echo the packets that are sent out

View File

@ -1,6 +1,6 @@
#include "QMA6100PSensor.h" #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 // Flag when an interrupt has been detected
volatile static bool QMA6100P_IRQ = false; volatile static bool QMA6100P_IRQ = false;

View File

@ -4,7 +4,7 @@
#include "MotionSensor.h" #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> #include <QMA6100P.h>

View File

@ -51,7 +51,11 @@ void updateBatteryLevel(uint8_t level) {}
void getMacAddr(uint8_t *dmac) 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); assert(esp_efuse_mac_get_default(dmac) == ESP_OK);
#endif
} }
#ifdef HAS_32768HZ #ifdef HAS_32768HZ

View File

@ -11,6 +11,7 @@
#include "PortduinoGlue.h" #include "PortduinoGlue.h"
#include "linux/gpio/LinuxGPIOPin.h" #include "linux/gpio/LinuxGPIOPin.h"
#include "yaml-cpp/yaml.h" #include "yaml-cpp/yaml.h"
#include <filesystem>
#include <iostream> #include <iostream>
#include <map> #include <map>
#include <unistd.h> #include <unistd.h>
@ -100,33 +101,22 @@ void portduinoSetup()
settingsStrings[displayspidev] = ""; settingsStrings[displayspidev] = "";
settingsMap[spiSpeed] = 2000000; settingsMap[spiSpeed] = 2000000;
settingsMap[ascii_logs] = !isatty(1); settingsMap[ascii_logs] = !isatty(1);
settingsMap[displayPanel] = no_screen;
settingsMap[touchscreenModule] = no_touchscreen;
YAML::Node yamlConfig; YAML::Node yamlConfig;
if (configPath != nullptr) { if (configPath != nullptr) {
std::cout << "Using " << configPath << " as config file" << std::endl; if (loadConfig(configPath)) {
try { std::cout << "Using " << configPath << " as config file" << std::endl;
yamlConfig = YAML::LoadFile(configPath); } else {
} catch (YAML::Exception &e) { std::cout << "Unable to use " << configPath << " as config file" << std::endl;
std::cout << "Could not open " << configPath << " because of error: " << e.what() << std::endl;
exit(EXIT_FAILURE); 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; std::cout << "Using local config.yaml as config file" << std::endl;
try { } else if (access("/etc/meshtasticd/config.yaml", R_OK) == 0 && loadConfig("/etc/meshtasticd/config.yaml")) {
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) {
std::cout << "Using /etc/meshtasticd/config.yaml as config file" << std::endl; 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 { } else {
std::cout << "No 'config.yaml' found, running simulated." << std::endl; std::cout << "No 'config.yaml' found, running simulated." << std::endl;
settingsMap[maxnodes] = 200; // Default to 200 nodes settingsMap[maxnodes] = 200; // Default to 200 nodes
@ -136,170 +126,21 @@ void portduinoSetup()
return; 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. // Rather important to set this, if not running simulated.
randomSeed(time(NULL)); randomSeed(time(NULL));
try { gpioChipName += std::to_string(settingsMap[gpiochip]);
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);
}
for (configNames i : GPIO_lines) { for (configNames i : GPIO_lines) {
if (settingsMap.count(i) && settingsMap[i] > max_GPIO) if (settingsMap.count(i) && settingsMap[i] > max_GPIO)
@ -402,4 +243,178 @@ int initGPIOPin(int pinNum, const std::string gpioChipName)
#else #else
return ERRNO_OK; return ERRNO_OK;
#endif #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;
} }

View File

@ -55,7 +55,8 @@ enum configNames {
webserverrootpath, webserverrootpath,
maxtophone, maxtophone,
maxnodes, maxnodes,
ascii_logs ascii_logs,
config_directory
}; };
enum { no_screen, x11, st7789, st7735, st7735s, st7796, ili9341, ili9342, ili9488, hx8357d }; enum { no_screen, x11, st7789, st7735, st7735s, st7796, ili9341, ili9342, ili9488, hx8357d };
enum { no_touchscreen, xpt2046, stmpe610, gt911, ft5x06 }; 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, int> settingsMap;
extern std::map<configNames, std::string> settingsStrings; extern std::map<configNames, std::string> settingsStrings;
extern std::ofstream traceFile; 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);

View 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

View File

@ -88,3 +88,73 @@ build_flags =
-D ARDUINO_USB_MODE=0 -D ARDUINO_USB_MODE=0
-D ARDUINO_USB_CDC_ON_BOOT=1 -D ARDUINO_USB_CDC_ON_BOOT=1
-I variants/diy/t-energy-s3_e22 -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

View 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 */

View 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
View 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

View File

@ -12,4 +12,4 @@ lib_deps =
https://github.com/RAKWireless/RAK13800-W5100S.git#1.0.2 https://github.com/RAKWireless/RAK13800-W5100S.git#1.0.2
debug_tool = jlink debug_tool = jlink
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ; 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

View 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 */

View File

@ -13,7 +13,6 @@ build_unflags =
-D ARDUINO_USB_MODE -D ARDUINO_USB_MODE
build_flags = ${esp32_base.build_flags} 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 -D UNPHONE
-I variants/unphone -I variants/unphone
-D ARDUINO_USB_MODE=0 -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> build_src_filter = ${esp32_base.build_src_filter} +<../variants/unphone>
lib_deps = ${esp32s3_base.lib_deps} lib_deps = ${esp32s3_base.lib_deps}
lovyan03/LovyanGFX @ ^1.1.8 lovyan03/LovyanGFX@ 1.1.12
https://gitlab.com/hamishcunningham/unphonelibrary#meshtastic @ ^9.0.0 https://gitlab.com/hamishcunningham/unphonelibrary#meshtastic@9.0.0
adafruit/Adafruit NeoPixel @ ^1.12.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

View File

@ -1,4 +1,4 @@
[VERSION] [VERSION]
major = 2 major = 2
minor = 5 minor = 5
build = 9 build = 11