mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-20 08:47:31 +00:00
Compare commits
36 Commits
v2.3.3.818
...
v2.3.4.ea6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea61808fd9 | ||
|
|
b14ac777f1 | ||
|
|
65e5bdc212 | ||
|
|
aa3280c18c | ||
|
|
68e657fd07 | ||
|
|
47b8f7b6c6 | ||
|
|
fde20db95f | ||
|
|
40a7fd145a | ||
|
|
33842b67e8 | ||
|
|
2db061ded9 | ||
|
|
1baad2875a | ||
|
|
0e9f1beb40 | ||
|
|
03f60dcb49 | ||
|
|
5b5f9c62b5 | ||
|
|
577de1e517 | ||
|
|
f6e6f975c0 | ||
|
|
902f38238d | ||
|
|
9b2d862b7d | ||
|
|
4cdfae71cf | ||
|
|
be889015f7 | ||
|
|
f0b6ff9b2d | ||
|
|
30ebb6ae46 | ||
|
|
d1db51830b | ||
|
|
eb0e705ba9 | ||
|
|
46ad4bf0e5 | ||
|
|
a570e50aca | ||
|
|
2caed6d29c | ||
|
|
f2ed0f7c8c | ||
|
|
8bb562c5fa | ||
|
|
15501e84dd | ||
|
|
a4c22321fc | ||
|
|
46a63bf293 | ||
|
|
279464f96d | ||
|
|
3cf6c47bab | ||
|
|
64fd866494 | ||
|
|
7b391d1a9f |
60
Dockerfile
60
Dockerfile
@@ -1,4 +1,4 @@
|
|||||||
FROM debian:bullseye-slim AS builder
|
FROM debian:bookworm-slim AS builder
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
ENV TZ=Etc/UTC
|
ENV TZ=Etc/UTC
|
||||||
@@ -11,31 +11,45 @@ SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
|||||||
|
|
||||||
# Install build deps
|
# Install build deps
|
||||||
USER root
|
USER root
|
||||||
RUN apt-get update && \
|
|
||||||
apt-get -y install wget python3 g++ zip python3-venv git vim ca-certificates libgpiod-dev libyaml-cpp-dev libbluetooth-dev
|
|
||||||
|
|
||||||
# create a non-priveleged user & group
|
# trunk-ignore(terrascan/AC_DOCKER_0002): Known terrascan issue
|
||||||
|
# trunk-ignore(hadolint/DL3008): Use latest version of packages for buildchain
|
||||||
|
RUN apt-get update && apt-get install --no-install-recommends -y wget python3 python3-pip python3-wheel python3-venv g++ zip git \
|
||||||
|
ca-certificates libgpiod-dev libyaml-cpp-dev libbluetooth-dev \
|
||||||
|
libulfius-dev liborcania-dev libssl-dev pkg-config && \
|
||||||
|
apt-get clean && rm -rf /var/lib/apt/lists/* && mkdir /tmp/firmware
|
||||||
|
|
||||||
|
RUN groupadd -g 1000 mesh && useradd -ml -u 1000 -g 1000 mesh && chown mesh:mesh /tmp/firmware
|
||||||
|
USER mesh
|
||||||
|
|
||||||
|
WORKDIR /tmp/firmware
|
||||||
|
RUN python3 -m venv /tmp/firmware
|
||||||
|
RUN source ./bin/activate && pip3 install --no-cache-dir -U platformio==6.1.14
|
||||||
|
# trunk-ignore(terrascan/AC_DOCKER_00024): We would actually like these files to be owned by mesh tyvm
|
||||||
|
COPY --chown=mesh:mesh . /tmp/firmware
|
||||||
|
RUN source ./bin/activate && chmod +x /tmp/firmware/bin/build-native.sh && ./bin/build-native.sh
|
||||||
|
RUN cp "/tmp/firmware/release/meshtasticd_linux_$(uname -m)" "/tmp/firmware/release/meshtasticd"
|
||||||
|
|
||||||
|
|
||||||
|
##### PRODUCTION BUILD #############
|
||||||
|
|
||||||
|
FROM debian:bookworm-slim
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
ENV TZ=Etc/UTC
|
||||||
|
|
||||||
|
# trunk-ignore(terrascan/AC_DOCKER_0002): Known terrascan issue
|
||||||
|
# trunk-ignore(hadolint/DL3008): Use latest version of packages for buildchain
|
||||||
|
RUN apt-get update && apt-get --no-install-recommends -y install libc-bin libc6 libgpiod2 libyaml-cpp0.7 libulfius2.7 liborcania2.3 libssl3 && \
|
||||||
|
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
RUN groupadd -g 1000 mesh && useradd -ml -u 1000 -g 1000 mesh
|
RUN groupadd -g 1000 mesh && useradd -ml -u 1000 -g 1000 mesh
|
||||||
|
|
||||||
USER mesh
|
USER mesh
|
||||||
RUN wget https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py -qO /tmp/get-platformio.py && \
|
|
||||||
chmod +x /tmp/get-platformio.py && \
|
|
||||||
python3 /tmp/get-platformio.py && \
|
|
||||||
git clone https://github.com/meshtastic/firmware --recurse-submodules /tmp/firmware && \
|
|
||||||
cd /tmp/firmware && \
|
|
||||||
chmod +x /tmp/firmware/bin/build-native.sh && \
|
|
||||||
source ~/.platformio/penv/bin/activate && \
|
|
||||||
./bin/build-native.sh
|
|
||||||
|
|
||||||
FROM frolvlad/alpine-glibc:glibc-2.31
|
|
||||||
|
|
||||||
RUN apk --update add --no-cache g++ shadow && \
|
|
||||||
groupadd -g 1000 mesh && useradd -ml -u 1000 -g 1000 mesh
|
|
||||||
|
|
||||||
COPY --from=builder /tmp/firmware/release/meshtasticd_linux_x86_64 /home/mesh/
|
|
||||||
|
|
||||||
USER mesh
|
|
||||||
WORKDIR /home/mesh
|
WORKDIR /home/mesh
|
||||||
CMD sh -cx "./meshtasticd_linux_x86_64 --hwid '${HWID:-$RANDOM}'"
|
COPY --from=builder /tmp/firmware/release/meshtasticd /home/mesh/
|
||||||
|
|
||||||
HEALTHCHECK NONE
|
VOLUME /home/mesh/data
|
||||||
|
|
||||||
|
CMD [ "sh", "-cx", "./meshtasticd -d /home/mesh/data --hwid=${HWID:-$RANDOM}" ]
|
||||||
|
|
||||||
|
HEALTHCHECK NONE
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
|
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
|
||||||
[portduino_base]
|
[portduino_base]
|
||||||
platform = https://github.com/meshtastic/platform-native.git#1b8a32c60ab7495026033858d53c737f7d1cb34a
|
platform = https://github.com/meshtastic/platform-native.git#117acc5e7fcc2047e9ba1dc11789daea26fc36d2
|
||||||
framework = arduino
|
framework = arduino
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
@@ -34,4 +34,4 @@ build_flags =
|
|||||||
-DPORTDUINO_LINUX_HARDWARE
|
-DPORTDUINO_LINUX_HARDWARE
|
||||||
-lbluetooth
|
-lbluetooth
|
||||||
-lgpiod
|
-lgpiod
|
||||||
-lyaml-cpp
|
-lyaml-cpp
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ mkdir -p $OUTDIR/
|
|||||||
rm -r $OUTDIR/* || true
|
rm -r $OUTDIR/* || true
|
||||||
|
|
||||||
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
||||||
platformio pkg update
|
platformio pkg update --environment native
|
||||||
pio run --environment native
|
pio run --environment native
|
||||||
cp .pio/build/native/program "$OUTDIR/meshtasticd_linux_$(arch)"
|
cp .pio/build/native/program "$OUTDIR/meshtasticd_linux_$(uname -m)"
|
||||||
cp bin/device-install.* $OUTDIR
|
cp bin/device-install.* $OUTDIR
|
||||||
cp bin/device-update.* $OUTDIR
|
cp bin/device-update.* $OUTDIR
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
### 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!
|
||||||
---
|
---
|
||||||
Lora:
|
Lora:
|
||||||
# Module: sx1262 # Waveshare SX126X XXXM
|
# Module: sx1262 # Waveshare SX126X XXXM
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ IF EXIST %FILENAME% IF x%FILENAME:update=%==x%FILENAME% (
|
|||||||
%PYTHON% -m esptool --baud 115200 write_flash 0x00 %FILENAME%
|
%PYTHON% -m esptool --baud 115200 write_flash 0x00 %FILENAME%
|
||||||
|
|
||||||
@REM Account for S3 and C3 board's different OTA partition
|
@REM Account for S3 and C3 board's different OTA partition
|
||||||
IF x%FILENAME:s3=%==x%FILENAME% IF x%FILENAME:v3=%==x%FILENAME% IF x%FILENAME:t-deck=%==x%FILENAME% IF x%FILENAME:wireless-paper=%==x%FILENAME% IF x%FILENAME:wireless-tracker=%==x%FILENAME% (
|
IF x%FILENAME:s3=%==x%FILENAME% IF x%FILENAME:v3=%==x%FILENAME% IF x%FILENAME:t-deck=%==x%FILENAME% IF x%FILENAME:wireless-paper=%==x%FILENAME% IF x%FILENAME:wireless-tracker=%==x%FILENAME% IF x%FILENAME:station-g2=%==x%FILENAME% (
|
||||||
IF x%FILENAME:esp32c3=%==x%FILENAME% (
|
IF x%FILENAME:esp32c3=%==x%FILENAME% (
|
||||||
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota.bin
|
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota.bin
|
||||||
) else (
|
) else (
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ if [ -f "${FILENAME}" ] && [ -n "${FILENAME##*"update"*}" ]; then
|
|||||||
"$PYTHON" -m esptool erase_flash
|
"$PYTHON" -m esptool erase_flash
|
||||||
"$PYTHON" -m esptool write_flash 0x00 ${FILENAME}
|
"$PYTHON" -m esptool write_flash 0x00 ${FILENAME}
|
||||||
# Account for S3 board's different OTA partition
|
# Account for S3 board's different OTA partition
|
||||||
if [ -n "${FILENAME##*"s3"*}" ] && [ -n "${FILENAME##*"-v3"*}" ] && [ -n "${FILENAME##*"t-deck"*}" ] && [ -n "${FILENAME##*"wireless-paper"*}" ] && [ -n "${FILENAME##*"wireless-tracker"*}" ]; then
|
if [ -n "${FILENAME##*"s3"*}" ] && [ -n "${FILENAME##*"-v3"*}" ] && [ -n "${FILENAME##*"t-deck"*}" ] && [ -n "${FILENAME##*"wireless-paper"*}" ] && [ -n "${FILENAME##*"wireless-tracker"*}" ] && [ -n "${FILENAME##*"station-g2"*}" ]; then
|
||||||
if [ -n "${FILENAME##*"esp32c3"*}" ]; then
|
if [ -n "${FILENAME##*"esp32c3"*}" ]; then
|
||||||
"$PYTHON" -m esptool write_flash 0x260000 bleota.bin
|
"$PYTHON" -m esptool write_flash 0x260000 bleota.bin
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
cp "release/meshtasticd_linux_$(arch)" /usr/sbin/meshtasticd
|
cp "release/meshtasticd_linux_$(uname -m)" /usr/sbin/meshtasticd
|
||||||
mkdir /etc/meshtasticd
|
mkdir /etc/meshtasticd
|
||||||
if [[ -f "/etc/meshtasticd/config.yaml" ]]; then
|
if [[ -f "/etc/meshtasticd/config.yaml" ]]; then
|
||||||
cp bin/config-dist.yaml /etc/meshtasticd/config-upgrade.yaml
|
cp bin/config-dist.yaml /etc/meshtasticd/config-upgrade.yaml
|
||||||
|
|||||||
Submodule protobufs updated: dea3a82ef2...68720ed8db
@@ -48,7 +48,7 @@ ButtonThread::ButtonThread() : OSThread("Button")
|
|||||||
userButton.setPressMs(c_longPressTime);
|
userButton.setPressMs(c_longPressTime);
|
||||||
userButton.setDebounceMs(1);
|
userButton.setDebounceMs(1);
|
||||||
userButton.attachDoubleClick(userButtonDoublePressed);
|
userButton.attachDoubleClick(userButtonDoublePressed);
|
||||||
userButton.attachMultiClick(userButtonMultiPressed);
|
userButton.attachMultiClick(userButtonMultiPressed, this); // Reference to instance: get click count from non-static OneButton
|
||||||
#ifndef T_DECK // T-Deck immediately wakes up after shutdown, so disable this function
|
#ifndef T_DECK // T-Deck immediately wakes up after shutdown, so disable this function
|
||||||
userButton.attachLongPressStart(userButtonPressedLongStart);
|
userButton.attachLongPressStart(userButtonPressedLongStart);
|
||||||
userButton.attachLongPressStop(userButtonPressedLongStop);
|
userButton.attachLongPressStop(userButtonPressedLongStop);
|
||||||
@@ -86,7 +86,8 @@ ButtonThread::ButtonThread() : OSThread("Button")
|
|||||||
|
|
||||||
#ifdef BUTTON_PIN_TOUCH
|
#ifdef BUTTON_PIN_TOUCH
|
||||||
userButtonTouch = OneButton(BUTTON_PIN_TOUCH, true, true);
|
userButtonTouch = OneButton(BUTTON_PIN_TOUCH, true, true);
|
||||||
userButtonTouch.attachClick(touchPressed);
|
userButtonTouch.setPressMs(400);
|
||||||
|
userButtonTouch.attachLongPressStart(touchPressedLongStart); // Better handling with longpress than click?
|
||||||
wakeOnIrq(BUTTON_PIN_TOUCH, FALLING);
|
wakeOnIrq(BUTTON_PIN_TOUCH, FALLING);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -138,26 +139,42 @@ int32_t ButtonThread::runOnce()
|
|||||||
|
|
||||||
case BUTTON_EVENT_DOUBLE_PRESSED: {
|
case BUTTON_EVENT_DOUBLE_PRESSED: {
|
||||||
LOG_BUTTON("Double press!\n");
|
LOG_BUTTON("Double press!\n");
|
||||||
#if defined(USE_EINK) && defined(PIN_EINK_EN)
|
|
||||||
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
|
|
||||||
#endif
|
|
||||||
service.refreshLocalMeshNode();
|
service.refreshLocalMeshNode();
|
||||||
service.sendNetworkPing(NODENUM_BROADCAST, true);
|
service.sendNetworkPing(NODENUM_BROADCAST, true);
|
||||||
if (screen)
|
if (screen) {
|
||||||
screen->print("Sent ad-hoc ping\n");
|
screen->print("Sent ad-hoc ping\n");
|
||||||
break;
|
screen->forceDisplay(true); // Force a new UI frame, then force an EInk update
|
||||||
}
|
|
||||||
#if HAS_GPS
|
|
||||||
case BUTTON_EVENT_MULTI_PRESSED: {
|
|
||||||
LOG_BUTTON("Multi press!\n");
|
|
||||||
if (!config.device.disable_triple_click && (gps != nullptr)) {
|
|
||||||
gps->toggleGpsMode();
|
|
||||||
if (screen)
|
|
||||||
screen->forceDisplay();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case BUTTON_EVENT_MULTI_PRESSED: {
|
||||||
|
LOG_BUTTON("Mulitipress! %hux\n", multipressClickCount);
|
||||||
|
switch (multipressClickCount) {
|
||||||
|
#if HAS_GPS
|
||||||
|
// 3 clicks: toggle GPS
|
||||||
|
case 3:
|
||||||
|
if (!config.device.disable_triple_click && (gps != nullptr)) {
|
||||||
|
gps->toggleGpsMode();
|
||||||
|
if (screen)
|
||||||
|
screen->forceDisplay(true); // Force a new UI frame, then force an EInk update
|
||||||
|
}
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(USE_EINK) && defined(PIN_EINK_EN) // i.e. T-Echo
|
||||||
|
// 4 clicks: toggle backlight
|
||||||
|
case 4:
|
||||||
|
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
// No valid multipress action
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
} // end switch: click count
|
||||||
|
|
||||||
|
break;
|
||||||
|
} // end multipress event
|
||||||
|
|
||||||
case BUTTON_EVENT_LONG_PRESSED: {
|
case BUTTON_EVENT_LONG_PRESSED: {
|
||||||
LOG_BUTTON("Long press!\n");
|
LOG_BUTTON("Long press!\n");
|
||||||
powerFSM.trigger(EVENT_PRESS);
|
powerFSM.trigger(EVENT_PRESS);
|
||||||
@@ -176,12 +193,24 @@ int32_t ButtonThread::runOnce()
|
|||||||
power->shutdown();
|
power->shutdown();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BUTTON_EVENT_TOUCH_PRESSED: {
|
|
||||||
|
#ifdef BUTTON_PIN_TOUCH
|
||||||
|
case BUTTON_EVENT_TOUCH_LONG_PRESSED: {
|
||||||
LOG_BUTTON("Touch press!\n");
|
LOG_BUTTON("Touch press!\n");
|
||||||
if (screen)
|
if (config.display.wake_on_tap_or_motion) {
|
||||||
screen->forceDisplay();
|
if (screen) {
|
||||||
|
// Wake if asleep
|
||||||
|
if (powerFSM.getState() == &stateDARK)
|
||||||
|
powerFSM.trigger(EVENT_PRESS);
|
||||||
|
|
||||||
|
// Update display (legacy behaviour)
|
||||||
|
screen->forceDisplay();
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif // BUTTON_PIN_TOUCH
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -206,6 +235,25 @@ void ButtonThread::wakeOnIrq(int irq, int mode)
|
|||||||
FALLING);
|
FALLING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Static callback
|
||||||
|
void ButtonThread::userButtonMultiPressed(void *callerThread)
|
||||||
|
{
|
||||||
|
// Grab click count from non-static button, while the info is still valid
|
||||||
|
ButtonThread *thread = (ButtonThread *)callerThread;
|
||||||
|
thread->storeClickCount();
|
||||||
|
|
||||||
|
// Then handle later, in the usual way
|
||||||
|
btnEvent = BUTTON_EVENT_MULTI_PRESSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-static method, runs during callback. Grabs info while still valid
|
||||||
|
void ButtonThread::storeClickCount()
|
||||||
|
{
|
||||||
|
#ifdef BUTTON_PIN
|
||||||
|
multipressClickCount = userButton.getNumberClicks();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void ButtonThread::userButtonPressedLongStart()
|
void ButtonThread::userButtonPressedLongStart()
|
||||||
{
|
{
|
||||||
if (millis() > c_holdOffTime) {
|
if (millis() > c_holdOffTime) {
|
||||||
|
|||||||
@@ -17,11 +17,12 @@ class ButtonThread : public concurrency::OSThread
|
|||||||
BUTTON_EVENT_MULTI_PRESSED,
|
BUTTON_EVENT_MULTI_PRESSED,
|
||||||
BUTTON_EVENT_LONG_PRESSED,
|
BUTTON_EVENT_LONG_PRESSED,
|
||||||
BUTTON_EVENT_LONG_RELEASED,
|
BUTTON_EVENT_LONG_RELEASED,
|
||||||
BUTTON_EVENT_TOUCH_PRESSED
|
BUTTON_EVENT_TOUCH_LONG_PRESSED,
|
||||||
};
|
};
|
||||||
|
|
||||||
ButtonThread();
|
ButtonThread();
|
||||||
int32_t runOnce() override;
|
int32_t runOnce() override;
|
||||||
|
void storeClickCount();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef BUTTON_PIN
|
#ifdef BUTTON_PIN
|
||||||
@@ -40,13 +41,16 @@ class ButtonThread : public concurrency::OSThread
|
|||||||
// set during IRQ
|
// set during IRQ
|
||||||
static volatile ButtonEventType btnEvent;
|
static volatile ButtonEventType btnEvent;
|
||||||
|
|
||||||
|
// Store click count during callback, for later use
|
||||||
|
volatile int multipressClickCount = 0;
|
||||||
|
|
||||||
static void wakeOnIrq(int irq, int mode);
|
static void wakeOnIrq(int irq, int mode);
|
||||||
|
|
||||||
// IRQ callbacks
|
// IRQ callbacks
|
||||||
static void touchPressed() { btnEvent = BUTTON_EVENT_TOUCH_PRESSED; }
|
|
||||||
static void userButtonPressed() { btnEvent = BUTTON_EVENT_PRESSED; }
|
static void userButtonPressed() { btnEvent = BUTTON_EVENT_PRESSED; }
|
||||||
static void userButtonDoublePressed() { btnEvent = BUTTON_EVENT_DOUBLE_PRESSED; }
|
static void userButtonDoublePressed() { btnEvent = BUTTON_EVENT_DOUBLE_PRESSED; }
|
||||||
static void userButtonMultiPressed() { btnEvent = BUTTON_EVENT_MULTI_PRESSED; }
|
static void userButtonMultiPressed(void *callerThread); // Retrieve click count from non-static Onebutton while still valid
|
||||||
static void userButtonPressedLongStart();
|
static void userButtonPressedLongStart();
|
||||||
static void userButtonPressedLongStop();
|
static void userButtonPressedLongStop();
|
||||||
|
static void touchPressedLongStart() { btnEvent = BUTTON_EVENT_TOUCH_LONG_PRESSED; }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -102,23 +102,18 @@ static void lsIdle()
|
|||||||
powerFSM.trigger(EVENT_SERIAL_CONNECTED);
|
powerFSM.trigger(EVENT_SERIAL_CONNECTED);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ESP_SLEEP_WAKEUP_GPIO:
|
||||||
|
// GPIO wakeup is now used for all ESP32 devices during light sleep
|
||||||
|
powerFSM.trigger(EVENT_PRESS);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// We woke for some other reason (button press, device interrupt)
|
// We woke for some other reason (device interrupt?)
|
||||||
// uint64_t status = esp_sleep_get_ext1_wakeup_status();
|
|
||||||
LOG_INFO("wakeCause2 %d\n", wakeCause2);
|
LOG_INFO("wakeCause2 %d\n", wakeCause2);
|
||||||
|
|
||||||
#ifdef BUTTON_PIN
|
// Let the NB state handle the IRQ (and that state will handle stuff like IRQs etc)
|
||||||
bool pressed = !digitalRead(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN);
|
// we lie and say "wake timer" because the interrupt will be handled by the regular IRQ code
|
||||||
#else
|
powerFSM.trigger(EVENT_WAKE_TIMER);
|
||||||
bool pressed = false;
|
|
||||||
#endif
|
|
||||||
if (pressed) { // If we woke because of press, instead generate a PRESS event.
|
|
||||||
powerFSM.trigger(EVENT_PRESS);
|
|
||||||
} else {
|
|
||||||
// Otherwise let the NB state handle the IRQ (and that state will handle stuff like IRQs etc)
|
|
||||||
// we lie and say "wake timer" because the interrupt will be handled by the regular IRQ code
|
|
||||||
powerFSM.trigger(EVENT_WAKE_TIMER);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -348,9 +343,6 @@ void PowerFSM_setup()
|
|||||||
powerFSM.add_timed_transition(&statePOWER, &stateDARK,
|
powerFSM.add_timed_transition(&statePOWER, &stateDARK,
|
||||||
Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
|
Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
|
||||||
"Screen-on timeout");
|
"Screen-on timeout");
|
||||||
powerFSM.add_timed_transition(&stateDARK, &stateDARK,
|
|
||||||
Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
|
|
||||||
"Screen-on timeout");
|
|
||||||
|
|
||||||
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
|
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
@@ -361,11 +353,24 @@ void PowerFSM_setup()
|
|||||||
powerFSM.add_timed_transition(&stateNB, &stateLS,
|
powerFSM.add_timed_transition(&stateNB, &stateLS,
|
||||||
Default::getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL,
|
Default::getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL,
|
||||||
"Min wake timeout");
|
"Min wake timeout");
|
||||||
|
|
||||||
|
// If ESP32 and using power-saving, timer mover from DARK to light-sleep
|
||||||
|
// Also serves purpose of the old DARK to DARK transition(?) See https://github.com/meshtastic/firmware/issues/3517
|
||||||
powerFSM.add_timed_transition(
|
powerFSM.add_timed_transition(
|
||||||
&stateDARK, &stateLS,
|
&stateDARK, &stateLS,
|
||||||
Default::getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs), NULL,
|
Default::getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs), NULL,
|
||||||
"Bluetooth timeout");
|
"Bluetooth timeout");
|
||||||
|
} else {
|
||||||
|
// If ESP32, but not using power-saving, check periodically if config has drifted out of stateDark
|
||||||
|
powerFSM.add_timed_transition(&stateDARK, &stateDARK,
|
||||||
|
Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs),
|
||||||
|
NULL, "Screen-on timeout");
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// If not ESP32, light-sleep not used. Check periodically if config has drifted out of stateDark
|
||||||
|
powerFSM.add_timed_transition(&stateDARK, &stateDARK,
|
||||||
|
Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
|
||||||
|
"Screen-on timeout");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
powerFSM.run_machine(); // run one iteration of the state machine, so we run our on enter tasks for the initial DARK state
|
powerFSM.run_machine(); // run one iteration of the state machine, so we run our on enter tasks for the initial DARK state
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...)
|
|||||||
|
|
||||||
// If we are the first message on a report, include the header
|
// If we are the first message on a report, include the header
|
||||||
if (!isContinuationMessage) {
|
if (!isContinuationMessage) {
|
||||||
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice);
|
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true); // display local time on logfile
|
||||||
if (rtc_sec > 0) {
|
if (rtc_sec > 0) {
|
||||||
long hms = rtc_sec % SEC_PER_DAY;
|
long hms = rtc_sec % SEC_PER_DAY;
|
||||||
// hms += tz.tz_dsttime * SEC_PER_HOUR;
|
// hms += tz.tz_dsttime * SEC_PER_HOUR;
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ class ScanI2C
|
|||||||
MPU6050,
|
MPU6050,
|
||||||
LIS3DH,
|
LIS3DH,
|
||||||
BMA423,
|
BMA423,
|
||||||
|
BQ24295,
|
||||||
#ifdef HAS_NCP5623
|
#ifdef HAS_NCP5623
|
||||||
NCP5623,
|
NCP5623,
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -293,7 +293,18 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
|
|||||||
SCAN_SIMPLE_CASE(LPS22HB_ADDR, LPS22HB, "LPS22HB sensor found\n")
|
SCAN_SIMPLE_CASE(LPS22HB_ADDR, LPS22HB, "LPS22HB sensor found\n")
|
||||||
|
|
||||||
SCAN_SIMPLE_CASE(QMC6310_ADDR, QMC6310, "QMC6310 Highrate 3-Axis magnetic sensor found\n")
|
SCAN_SIMPLE_CASE(QMC6310_ADDR, QMC6310, "QMC6310 Highrate 3-Axis magnetic sensor found\n")
|
||||||
SCAN_SIMPLE_CASE(QMI8658_ADDR, QMI8658, "QMI8658 Highrate 6-Axis inertial measurement sensor found\n")
|
|
||||||
|
case QMI8658_ADDR:
|
||||||
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0A), 1); // get ID
|
||||||
|
if (registerValue == 0xC0) {
|
||||||
|
type = BQ24295;
|
||||||
|
LOG_INFO("BQ24295 PMU found\n");
|
||||||
|
} else {
|
||||||
|
type = QMI8658;
|
||||||
|
LOG_INFO("QMI8658 Highrate 6-Axis inertial measurement sensor found\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
SCAN_SIMPLE_CASE(QMC5883L_ADDR, QMC5883L, "QMC5883L Highrate 3-Axis magnetic sensor found\n")
|
SCAN_SIMPLE_CASE(QMC5883L_ADDR, QMC5883L, "QMC5883L Highrate 3-Axis magnetic sensor found\n")
|
||||||
|
|
||||||
SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031 air quality sensor found\n")
|
SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031 air quality sensor found\n")
|
||||||
|
|||||||
@@ -1379,7 +1379,7 @@ bool GPS::lookForLocation()
|
|||||||
t.tm_mon = reader.date.month() - 1;
|
t.tm_mon = reader.date.month() - 1;
|
||||||
t.tm_year = reader.date.year() - 1900;
|
t.tm_year = reader.date.year() - 1900;
|
||||||
t.tm_isdst = false;
|
t.tm_isdst = false;
|
||||||
p.timestamp = mktime(&t);
|
p.timestamp = gm_mktime(&t);
|
||||||
|
|
||||||
// Nice to have, if available
|
// Nice to have, if available
|
||||||
if (reader.satellites.isUpdated()) {
|
if (reader.satellites.isUpdated()) {
|
||||||
|
|||||||
@@ -75,10 +75,10 @@ uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const
|
|||||||
uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos)
|
uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos)
|
||||||
{
|
{
|
||||||
GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude);
|
GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude);
|
||||||
tm *t = localtime((time_t *)&pos.timestamp);
|
tm *t = gmtime((time_t *)&pos.timestamp);
|
||||||
if (getRTCQuality() > 0) { // use the device clock if we got time from somewhere. If not, use the GPS timestamp.
|
if (getRTCQuality() > 0) { // use the device clock if we got time from somewhere. If not, use the GPS timestamp.
|
||||||
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice);
|
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice);
|
||||||
t = localtime((time_t *)&rtc_sec);
|
t = gmtime((time_t *)&rtc_sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t len = snprintf(
|
uint32_t len = snprintf(
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ void readFromRTC()
|
|||||||
t.tm_hour = rtc.getHour();
|
t.tm_hour = rtc.getHour();
|
||||||
t.tm_min = rtc.getMinute();
|
t.tm_min = rtc.getMinute();
|
||||||
t.tm_sec = rtc.getSecond();
|
t.tm_sec = rtc.getSecond();
|
||||||
tv.tv_sec = mktime(&t);
|
tv.tv_sec = gm_mktime(&t);
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
LOG_DEBUG("Read RTC time from RV3028 as %ld\n", tv.tv_sec);
|
LOG_DEBUG("Read RTC time from RV3028 as %ld\n", tv.tv_sec);
|
||||||
timeStartMsec = now;
|
timeStartMsec = now;
|
||||||
@@ -68,7 +68,7 @@ void readFromRTC()
|
|||||||
t.tm_hour = tc.hour;
|
t.tm_hour = tc.hour;
|
||||||
t.tm_min = tc.minute;
|
t.tm_min = tc.minute;
|
||||||
t.tm_sec = tc.second;
|
t.tm_sec = tc.second;
|
||||||
tv.tv_sec = mktime(&t);
|
tv.tv_sec = gm_mktime(&t);
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
LOG_DEBUG("Read RTC time from PCF8563 as %ld\n", tv.tv_sec);
|
LOG_DEBUG("Read RTC time from PCF8563 as %ld\n", tv.tv_sec);
|
||||||
timeStartMsec = now;
|
timeStartMsec = now;
|
||||||
@@ -128,7 +128,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
|
|||||||
#else
|
#else
|
||||||
rtc.initI2C();
|
rtc.initI2C();
|
||||||
#endif
|
#endif
|
||||||
tm *t = localtime(&tv->tv_sec);
|
tm *t = gmtime(&tv->tv_sec);
|
||||||
rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
||||||
LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
|
LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
|
||||||
t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
|
t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
|
||||||
@@ -142,7 +142,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
|
|||||||
#else
|
#else
|
||||||
rtc.begin();
|
rtc.begin();
|
||||||
#endif
|
#endif
|
||||||
tm *t = localtime(&tv->tv_sec);
|
tm *t = gmtime(&tv->tv_sec);
|
||||||
rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
||||||
LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
|
LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
|
||||||
t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
|
t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
|
||||||
@@ -175,7 +175,9 @@ bool perhapsSetRTC(RTCQuality q, struct tm &t)
|
|||||||
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, 1970
|
||||||
(midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
|
(midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
|
||||||
*/
|
*/
|
||||||
time_t res = mktime(&t);
|
// horrible hack to make mktime TZ agnostic - best practise according to
|
||||||
|
// https://www.gnu.org/software/libc/manual/html_node/Broken_002ddown-Time.html
|
||||||
|
time_t res = gm_mktime(&t);
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
tv.tv_sec = res;
|
tv.tv_sec = res;
|
||||||
tv.tv_usec = 0; // time.centisecond() * (10 / 1000);
|
tv.tv_usec = 0; // time.centisecond() * (10 / 1000);
|
||||||
@@ -189,14 +191,33 @@ bool perhapsSetRTC(RTCQuality q, struct tm &t)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the timezone offset in seconds.
|
||||||
|
*
|
||||||
|
* @return The timezone offset in seconds.
|
||||||
|
*/
|
||||||
|
int32_t getTZOffset()
|
||||||
|
{
|
||||||
|
time_t now;
|
||||||
|
struct tm *gmt;
|
||||||
|
now = time(NULL);
|
||||||
|
gmt = gmtime(&now);
|
||||||
|
gmt->tm_isdst = -1;
|
||||||
|
return (int16_t)difftime(now, mktime(gmt));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current time in seconds since the Unix epoch (January 1, 1970).
|
* Returns the current time in seconds since the Unix epoch (January 1, 1970).
|
||||||
*
|
*
|
||||||
* @return The current time in seconds since the Unix epoch.
|
* @return The current time in seconds since the Unix epoch.
|
||||||
*/
|
*/
|
||||||
uint32_t getTime()
|
uint32_t getTime(bool local)
|
||||||
{
|
{
|
||||||
return (((uint32_t)millis() - timeStartMsec) / 1000) + zeroOffsetSecs;
|
if (local) {
|
||||||
|
return (((uint32_t)millis() - timeStartMsec) / 1000) + zeroOffsetSecs + getTZOffset();
|
||||||
|
} else {
|
||||||
|
return (((uint32_t)millis() - timeStartMsec) / 1000) + zeroOffsetSecs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -205,7 +226,19 @@ uint32_t getTime()
|
|||||||
* @param minQuality The minimum quality of the RTC time required for it to be considered valid.
|
* @param minQuality The minimum quality of the RTC time required for it to be considered valid.
|
||||||
* @return The current time from the RTC if it meets the minimum quality requirement, or 0 if the time is not valid.
|
* @return The current time from the RTC if it meets the minimum quality requirement, or 0 if the time is not valid.
|
||||||
*/
|
*/
|
||||||
uint32_t getValidTime(RTCQuality minQuality)
|
uint32_t getValidTime(RTCQuality minQuality, bool local)
|
||||||
{
|
{
|
||||||
return (currentQuality >= minQuality) ? getTime() : 0;
|
return (currentQuality >= minQuality) ? getTime(local) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t gm_mktime(struct tm *tm)
|
||||||
|
{
|
||||||
|
setenv("TZ", "GMT0", 1);
|
||||||
|
time_t res = mktime(tm);
|
||||||
|
if (*config.device.tzdef) {
|
||||||
|
setenv("TZ", config.device.tzdef, 1);
|
||||||
|
} else {
|
||||||
|
setenv("TZ", "UTC0", 1);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,13 +29,15 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv);
|
|||||||
bool perhapsSetRTC(RTCQuality q, struct tm &t);
|
bool perhapsSetRTC(RTCQuality q, struct tm &t);
|
||||||
|
|
||||||
/// Return time since 1970 in secs. While quality is RTCQualityNone we will be returning time based at zero
|
/// Return time since 1970 in secs. While quality is RTCQualityNone we will be returning time based at zero
|
||||||
uint32_t getTime();
|
uint32_t getTime(bool local = false);
|
||||||
|
|
||||||
/// Return time since 1970 in secs. If quality is RTCQualityNone return zero
|
/// Return time since 1970 in secs. If quality is RTCQualityNone return zero
|
||||||
uint32_t getValidTime(RTCQuality minQuality);
|
uint32_t getValidTime(RTCQuality minQuality, bool local = false);
|
||||||
|
|
||||||
void readFromRTC();
|
void readFromRTC();
|
||||||
|
|
||||||
|
time_t gm_mktime(struct tm *tm);
|
||||||
|
|
||||||
#define SEC_PER_DAY 86400
|
#define SEC_PER_DAY 86400
|
||||||
#define SEC_PER_HOUR 3600
|
#define SEC_PER_HOUR 3600
|
||||||
#define SEC_PER_MIN 60
|
#define SEC_PER_MIN 60
|
||||||
@@ -151,31 +151,12 @@ bool EInkDisplay::connect()
|
|||||||
|
|
||||||
#elif defined(HELTEC_WIRELESS_PAPER_V1_0) || defined(HELTEC_WIRELESS_PAPER)
|
#elif defined(HELTEC_WIRELESS_PAPER_V1_0) || defined(HELTEC_WIRELESS_PAPER)
|
||||||
{
|
{
|
||||||
// Is this a normal boot, or a wake from deep sleep?
|
|
||||||
esp_sleep_wakeup_cause_t wakeReason = esp_sleep_get_wakeup_cause();
|
|
||||||
|
|
||||||
// If waking from sleep, need to reverse rtc_gpio_isolate(), called in cpuDeepSleep()
|
|
||||||
// Otherwise, SPI won't work
|
|
||||||
if (wakeReason != ESP_SLEEP_WAKEUP_UNDEFINED) {
|
|
||||||
// HSPI + other display pins
|
|
||||||
rtc_gpio_hold_dis((gpio_num_t)PIN_EINK_SCLK);
|
|
||||||
rtc_gpio_hold_dis((gpio_num_t)PIN_EINK_DC);
|
|
||||||
rtc_gpio_hold_dis((gpio_num_t)PIN_EINK_RES);
|
|
||||||
rtc_gpio_hold_dis((gpio_num_t)PIN_EINK_BUSY);
|
|
||||||
rtc_gpio_hold_dis((gpio_num_t)PIN_EINK_CS);
|
|
||||||
rtc_gpio_hold_dis((gpio_num_t)PIN_EINK_MOSI);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start HSPI
|
// Start HSPI
|
||||||
hspi = new SPIClass(HSPI);
|
hspi = new SPIClass(HSPI);
|
||||||
hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS); // SCLK, MISO, MOSI, SS
|
hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS); // SCLK, MISO, MOSI, SS
|
||||||
|
|
||||||
// Enable VExt (ACTIVE LOW)
|
// VExt already enabled in setup()
|
||||||
// Unsure if called elsewhere first?
|
// RTC GPIO hold disabled in setup()
|
||||||
delay(100);
|
|
||||||
pinMode(Vext, OUTPUT);
|
|
||||||
digitalWrite(Vext, LOW);
|
|
||||||
delay(100);
|
|
||||||
|
|
||||||
// Create GxEPD2 objects
|
// Create GxEPD2 objects
|
||||||
auto lowLevel = new EINK_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY, *hspi);
|
auto lowLevel = new EINK_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY, *hspi);
|
||||||
|
|||||||
@@ -463,10 +463,33 @@ void EInkDynamicDisplay::onNotify(uint32_t notification)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAS_EINK_ASYNCFULL
|
#ifdef HAS_EINK_ASYNCFULL
|
||||||
// Run the post-update code if the hardware is ready
|
// Public: wait for an refresh already in progress, then run the post-update code. See Screen::setScreensaverFrames()
|
||||||
|
void EInkDynamicDisplay::joinAsyncRefresh()
|
||||||
|
{
|
||||||
|
// If no async refresh running, nothing to do
|
||||||
|
if (!asyncRefreshRunning)
|
||||||
|
return;
|
||||||
|
|
||||||
|
LOG_DEBUG("Joining an async refresh in progress\n");
|
||||||
|
|
||||||
|
// Continually poll the BUSY pin
|
||||||
|
while (adafruitDisplay->epd2.isBusy())
|
||||||
|
yield();
|
||||||
|
|
||||||
|
// If asyncRefreshRunning flag is still set, but display's BUSY pin reports the refresh is done
|
||||||
|
adafruitDisplay->endAsyncFull(); // Run the end of nextPage() code
|
||||||
|
EInkDisplay::endUpdate(); // Run base-class code to finish off update (NOT our derived class override)
|
||||||
|
asyncRefreshRunning = false; // Unset the flag
|
||||||
|
LOG_DEBUG("Refresh complete\n");
|
||||||
|
|
||||||
|
// Note: this code only works because of a modification to meshtastic/GxEPD2.
|
||||||
|
// It is only equipped to intercept calls to nextPage()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called from NotifiedWorkerThread. Run the post-update code if the hardware is ready
|
||||||
void EInkDynamicDisplay::pollAsyncRefresh()
|
void EInkDynamicDisplay::pollAsyncRefresh()
|
||||||
{
|
{
|
||||||
// We shouldn't be here..
|
// In theory, this condition should never be met
|
||||||
if (!asyncRefreshRunning)
|
if (!asyncRefreshRunning)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -119,20 +119,30 @@ class EInkDynamicDisplay : public EInkDisplay, protected concurrency::NotifiedWo
|
|||||||
|
|
||||||
// Conditional - async full refresh - only with modified meshtastic/GxEPD2
|
// Conditional - async full refresh - only with modified meshtastic/GxEPD2
|
||||||
#if defined(HAS_EINK_ASYNCFULL)
|
#if defined(HAS_EINK_ASYNCFULL)
|
||||||
|
public:
|
||||||
|
void joinAsyncRefresh(); // Main thread joins an async refresh already in progress. Blocks, then runs post-update code
|
||||||
|
|
||||||
|
protected:
|
||||||
void pollAsyncRefresh(); // Run the post-update code if the hardware is ready
|
void pollAsyncRefresh(); // Run the post-update code if the hardware is ready
|
||||||
void checkBusyAsyncRefresh(); // Check if display is busy running an async full-refresh (rejecting new frames)
|
void checkBusyAsyncRefresh(); // Check if display is busy running an async full-refresh (rejecting new frames)
|
||||||
void awaitRefresh(); // Hold control while an async refresh runs
|
void awaitRefresh(); // Hold control while an async refresh runs
|
||||||
void endUpdate() override {} // Disable base-class behavior of running post-update immediately after forceDisplay()
|
void endUpdate() override {} // Disable base-class behavior of running post-update immediately after forceDisplay()
|
||||||
bool asyncRefreshRunning = false; // Flag, checked by checkBusyAsyncRefresh()
|
bool asyncRefreshRunning = false; // Flag, checked by checkBusyAsyncRefresh()
|
||||||
#else
|
#else
|
||||||
|
public:
|
||||||
|
void joinAsyncRefresh() {} // Dummy method
|
||||||
|
|
||||||
|
protected:
|
||||||
void pollAsyncRefresh() {} // Dummy method. In theory, not reachable
|
void pollAsyncRefresh() {} // Dummy method. In theory, not reachable
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
// Tidier calls to addFrameFlag() from outside class
|
// Hide the ugly casts used in Screen.cpp
|
||||||
#define EINK_ADD_FRAMEFLAG(display, flag) static_cast<EInkDynamicDisplay *>(display)->addFrameFlag(EInkDynamicDisplay::flag)
|
#define EINK_ADD_FRAMEFLAG(display, flag) static_cast<EInkDynamicDisplay *>(display)->addFrameFlag(EInkDynamicDisplay::flag)
|
||||||
|
#define EINK_JOIN_ASYNCREFRESH(display) static_cast<EInkDynamicDisplay *>(display)->joinAsyncRefresh()
|
||||||
|
|
||||||
#else // !USE_EINK_DYNAMICDISPLAY
|
#else // !USE_EINK_DYNAMICDISPLAY
|
||||||
// Dummy-macro, removes the need for include guards
|
// Dummy-macro, removes the need for include guards
|
||||||
#define EINK_ADD_FRAMEFLAG(display, flag)
|
#define EINK_ADD_FRAMEFLAG(display, flag)
|
||||||
|
#define EINK_JOIN_ASYNCREFRESH(display)
|
||||||
#endif
|
#endif
|
||||||
@@ -528,7 +528,7 @@ static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, const NodeStat
|
|||||||
{
|
{
|
||||||
char usersString[20];
|
char usersString[20];
|
||||||
snprintf(usersString, sizeof(usersString), "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal());
|
snprintf(usersString, sizeof(usersString), "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal());
|
||||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)) && \
|
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(HX8357_CS)) && \
|
||||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||||
display->drawFastImage(x, y + 3, 8, 8, imgUser);
|
display->drawFastImage(x, y + 3, 8, 8, imgUser);
|
||||||
#else
|
#else
|
||||||
@@ -955,7 +955,7 @@ Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_O
|
|||||||
#elif defined(USE_SSD1306)
|
#elif defined(USE_SSD1306)
|
||||||
dispdev = new SSD1306Wire(address.address, -1, -1, geometry,
|
dispdev = new SSD1306Wire(address.address, -1, -1, geometry,
|
||||||
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
|
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
|
||||||
#elif defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ST7789_CS) || defined(RAK14014)
|
#elif defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ST7789_CS) || defined(RAK14014) || defined(HX8357_CS)
|
||||||
dispdev = new TFTDisplay(address.address, -1, -1, geometry,
|
dispdev = new TFTDisplay(address.address, -1, -1, geometry,
|
||||||
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
|
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
|
||||||
#elif defined(USE_EINK) && !defined(USE_EINK_DYNAMICDISPLAY)
|
#elif defined(USE_EINK) && !defined(USE_EINK_DYNAMICDISPLAY)
|
||||||
@@ -1101,7 +1101,7 @@ void Screen::setup()
|
|||||||
// Standard behaviour is to FLIP the screen (needed on T-Beam). If this config item is set, unflip it, and thereby logically
|
// Standard behaviour is to FLIP the screen (needed on T-Beam). If this config item is set, unflip it, and thereby logically
|
||||||
// flip it. If you have a headache now, you're welcome.
|
// flip it. If you have a headache now, you're welcome.
|
||||||
if (!config.display.flip_screen) {
|
if (!config.display.flip_screen) {
|
||||||
#if defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ST7789_CS) || defined(RAK14014)
|
#if defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ST7789_CS) || defined(RAK14014) || defined(HX8357_CS)
|
||||||
static_cast<TFTDisplay *>(dispdev)->flipScreenVertically();
|
static_cast<TFTDisplay *>(dispdev)->flipScreenVertically();
|
||||||
#else
|
#else
|
||||||
dispdev->flipScreenVertically();
|
dispdev->flipScreenVertically();
|
||||||
@@ -1153,10 +1153,33 @@ void Screen::setup()
|
|||||||
MeshModule::observeUIEvents(&uiFrameEventObserver);
|
MeshModule::observeUIEvents(&uiFrameEventObserver);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::forceDisplay()
|
void Screen::forceDisplay(bool forceUiUpdate)
|
||||||
{
|
{
|
||||||
// Nasty hack to force epaper updates for 'key' frames. FIXME, cleanup.
|
// Nasty hack to force epaper updates for 'key' frames. FIXME, cleanup.
|
||||||
#ifdef USE_EINK
|
#ifdef USE_EINK
|
||||||
|
// If requested, make sure queued commands are run, and UI has rendered a new frame
|
||||||
|
if (forceUiUpdate) {
|
||||||
|
// No delay between UI frame rendering
|
||||||
|
setFastFramerate();
|
||||||
|
|
||||||
|
// Make sure all CMDs have run first
|
||||||
|
while (!cmdQueue.isEmpty())
|
||||||
|
runOnce();
|
||||||
|
|
||||||
|
// Ensure at least one frame has drawn
|
||||||
|
uint64_t startUpdate;
|
||||||
|
do {
|
||||||
|
startUpdate = millis(); // Handle impossibly unlikely corner case of a millis() overflow..
|
||||||
|
delay(10);
|
||||||
|
ui->update();
|
||||||
|
} while (ui->getUiState()->lastUpdate < startUpdate);
|
||||||
|
|
||||||
|
// Return to normal frame rate
|
||||||
|
targetFramerate = IDLE_FRAMERATE;
|
||||||
|
ui->setTargetFPS(targetFramerate);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell EInk class to update the display
|
||||||
static_cast<EInkDisplay *>(dispdev)->forceDisplay();
|
static_cast<EInkDisplay *>(dispdev)->forceDisplay();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -1349,6 +1372,12 @@ void Screen::setScreensaverFrames(FrameCallback einkScreensaver)
|
|||||||
static FrameCallback screensaverFrame;
|
static FrameCallback screensaverFrame;
|
||||||
static OverlayCallback screensaverOverlay;
|
static OverlayCallback screensaverOverlay;
|
||||||
|
|
||||||
|
#if defined(HAS_EINK_ASYNCFULL) && defined(USE_EINK_DYNAMICDISPLAY)
|
||||||
|
// Join (await) a currently running async refresh, then run the post-update code.
|
||||||
|
// Avoid skipping of screensaver frame. Would otherwise be handled by NotifiedWorkerThread.
|
||||||
|
EINK_JOIN_ASYNCREFRESH(dispdev);
|
||||||
|
#endif
|
||||||
|
|
||||||
// If: one-off screensaver frame passed as argument. Handles doDeepSleep()
|
// If: one-off screensaver frame passed as argument. Handles doDeepSleep()
|
||||||
if (einkScreensaver != NULL) {
|
if (einkScreensaver != NULL) {
|
||||||
screensaverFrame = einkScreensaver;
|
screensaverFrame = einkScreensaver;
|
||||||
@@ -1370,10 +1399,9 @@ void Screen::setScreensaverFrames(FrameCallback einkScreensaver)
|
|||||||
ui->update();
|
ui->update();
|
||||||
} while (ui->getUiState()->lastUpdate < startUpdate);
|
} while (ui->getUiState()->lastUpdate < startUpdate);
|
||||||
|
|
||||||
#ifndef USE_EINK_DYNAMICDISPLAY
|
// Old EInkDisplay class
|
||||||
// Retrofit to EInkDisplay class
|
#if !defined(USE_EINK_DYNAMICDISPLAY)
|
||||||
delay(10);
|
static_cast<EInkDisplay *>(dispdev)->forceDisplay(0); // Screen::forceDisplay(), but override rate-limit
|
||||||
screen->forceDisplay();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Prepare now for next frame, shown when display wakes
|
// Prepare now for next frame, shown when display wakes
|
||||||
@@ -1490,8 +1518,11 @@ void Screen::handleShutdownScreen()
|
|||||||
{
|
{
|
||||||
LOG_DEBUG("showing shutdown screen\n");
|
LOG_DEBUG("showing shutdown screen\n");
|
||||||
showingNormalScreen = false;
|
showingNormalScreen = false;
|
||||||
EINK_ADD_FRAMEFLAG(dispdev, DEMAND_FAST); // E-Ink: Use fast-refresh for next frame, no skip please
|
#ifdef USE_EINK
|
||||||
|
EINK_ADD_FRAMEFLAG(dispdev, DEMAND_FAST); // Use fast-refresh for next frame, no skip please
|
||||||
EINK_ADD_FRAMEFLAG(dispdev, BLOCKING); // Edge case: if this frame is promoted to COSMETIC, wait for update
|
EINK_ADD_FRAMEFLAG(dispdev, BLOCKING); // Edge case: if this frame is promoted to COSMETIC, wait for update
|
||||||
|
handleSetOn(true); // Ensure power-on to receive deep-sleep screensaver (PowerFSM should handle?)
|
||||||
|
#endif
|
||||||
|
|
||||||
auto frame = [](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
|
auto frame = [](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
|
||||||
drawFrameText(display, state, x, y, "Shutting down...");
|
drawFrameText(display, state, x, y, "Shutting down...");
|
||||||
@@ -1499,14 +1530,17 @@ void Screen::handleShutdownScreen()
|
|||||||
static FrameCallback frames[] = {frame};
|
static FrameCallback frames[] = {frame};
|
||||||
|
|
||||||
setFrameImmediateDraw(frames);
|
setFrameImmediateDraw(frames);
|
||||||
forceDisplay();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::handleRebootScreen()
|
void Screen::handleRebootScreen()
|
||||||
{
|
{
|
||||||
LOG_DEBUG("showing reboot screen\n");
|
LOG_DEBUG("showing reboot screen\n");
|
||||||
showingNormalScreen = false;
|
showingNormalScreen = false;
|
||||||
EINK_ADD_FRAMEFLAG(dispdev, DEMAND_FAST); // E-Ink: Explicitly use fast-refresh for next frame
|
#ifdef USE_EINK
|
||||||
|
EINK_ADD_FRAMEFLAG(dispdev, DEMAND_FAST); // Use fast-refresh for next frame, no skip please
|
||||||
|
EINK_ADD_FRAMEFLAG(dispdev, BLOCKING); // Edge case: if this frame is promoted to COSMETIC, wait for update
|
||||||
|
handleSetOn(true); // Power-on to show rebooting screen (PowerFSM should handle?)
|
||||||
|
#endif
|
||||||
|
|
||||||
auto frame = [](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
|
auto frame = [](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
|
||||||
drawFrameText(display, state, x, y, "Rebooting...");
|
drawFrameText(display, state, x, y, "Rebooting...");
|
||||||
@@ -1675,7 +1709,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
|||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
if (millis() - storeForwardModule->lastHeartbeat >
|
if (millis() - storeForwardModule->lastHeartbeat >
|
||||||
(storeForwardModule->heartbeatInterval * 1200)) { // no heartbeat, overlap a bit
|
(storeForwardModule->heartbeatInterval * 1200)) { // no heartbeat, overlap a bit
|
||||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)) && \
|
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(HX8357_CS)) && \
|
||||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||||
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
|
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
|
||||||
imgQuestionL1);
|
imgQuestionL1);
|
||||||
@@ -1686,7 +1720,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
|||||||
imgQuestion);
|
imgQuestion);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)) && \
|
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(HX8357_CS)) && \
|
||||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||||
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 16, 8,
|
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 16, 8,
|
||||||
imgSFL1);
|
imgSFL1);
|
||||||
@@ -1700,7 +1734,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
|||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
// TODO: Raspberry Pi supports more than just the one screen size
|
// TODO: Raspberry Pi supports more than just the one screen size
|
||||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || ARCH_PORTDUINO) && \
|
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(HX8357_CS) || \
|
||||||
|
ARCH_PORTDUINO) && \
|
||||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||||
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
|
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
|
||||||
imgInfoL1);
|
imgInfoL1);
|
||||||
@@ -1861,7 +1896,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||||||
// Show uptime as days, hours, minutes OR seconds
|
// Show uptime as days, hours, minutes OR seconds
|
||||||
std::string uptime = screen->drawTimeDelta(days, hours, minutes, seconds);
|
std::string uptime = screen->drawTimeDelta(days, hours, minutes, seconds);
|
||||||
|
|
||||||
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice);
|
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true); // Display local timezone
|
||||||
if (rtc_sec > 0) {
|
if (rtc_sec > 0) {
|
||||||
long hms = rtc_sec % SEC_PER_DAY;
|
long hms = rtc_sec % SEC_PER_DAY;
|
||||||
// hms += tz.tz_dsttime * SEC_PER_HOUR;
|
// hms += tz.tz_dsttime * SEC_PER_HOUR;
|
||||||
@@ -1963,4 +1998,4 @@ int Screen::handleInputEvent(const InputEvent *event)
|
|||||||
} // namespace graphics
|
} // namespace graphics
|
||||||
#else
|
#else
|
||||||
graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {}
|
graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {}
|
||||||
#endif // HAS_SCREEN
|
#endif // HAS_SCREEN
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class Screen
|
|||||||
void setOn(bool) {}
|
void setOn(bool) {}
|
||||||
void print(const char *) {}
|
void print(const char *) {}
|
||||||
void doDeepSleep() {}
|
void doDeepSleep() {}
|
||||||
void forceDisplay() {}
|
void forceDisplay(bool forceUiUpdate = false) {}
|
||||||
void startBluetoothPinScreen(uint32_t pin) {}
|
void startBluetoothPinScreen(uint32_t pin) {}
|
||||||
void stopBluetoothPinScreen() {}
|
void stopBluetoothPinScreen() {}
|
||||||
void startRebootScreen() {}
|
void startRebootScreen() {}
|
||||||
@@ -150,7 +150,7 @@ class Screen : public concurrency::OSThread
|
|||||||
// We handle off commands immediately, because they might be called because the CPU is shutting down
|
// We handle off commands immediately, because they might be called because the CPU is shutting down
|
||||||
handleSetOn(false, einkScreensaver);
|
handleSetOn(false, einkScreensaver);
|
||||||
else
|
else
|
||||||
enqueueCmd(ScreenCmd{.cmd = on ? Cmd::SET_ON : Cmd::SET_OFF});
|
enqueueCmd(ScreenCmd{.cmd = Cmd::SET_ON});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -318,7 +318,7 @@ class Screen : public concurrency::OSThread
|
|||||||
int handleInputEvent(const InputEvent *arg);
|
int handleInputEvent(const InputEvent *arg);
|
||||||
|
|
||||||
/// Used to force (super slow) eink displays to draw critical frames
|
/// Used to force (super slow) eink displays to draw critical frames
|
||||||
void forceDisplay();
|
void forceDisplay(bool forceUiUpdate = false);
|
||||||
|
|
||||||
/// Draws our SSL cert screen during boot (called from WebServer)
|
/// Draws our SSL cert screen during boot (called from WebServer)
|
||||||
void setSSLFrames();
|
void setSSLFrames();
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#include "graphics/fonts/OLEDDisplayFontsUA.h"
|
#include "graphics/fonts/OLEDDisplayFontsUA.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)) && \
|
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(HX8357_CS)) && \
|
||||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||||
// The screen is bigger so use bigger fonts
|
// The screen is bigger so use bigger fonts
|
||||||
#define FONT_SMALL ArialMT_Plain_16 // Height: 19
|
#define FONT_SMALL ArialMT_Plain_16 // Height: 19
|
||||||
|
|||||||
@@ -333,7 +333,7 @@ static LGFX *tft = nullptr;
|
|||||||
#include <TFT_eSPI.h> // Graphics and font library for ILI9341 driver chip
|
#include <TFT_eSPI.h> // Graphics and font library for ILI9341 driver chip
|
||||||
|
|
||||||
static TFT_eSPI *tft = nullptr; // Invoke library, pins defined in User_Setup.h
|
static TFT_eSPI *tft = nullptr; // Invoke library, pins defined in User_Setup.h
|
||||||
#elif ARCH_PORTDUINO
|
#elif ARCH_PORTDUINO && HAS_SCREEN != 0
|
||||||
#include <LovyanGFX.hpp> // Graphics and font library for ST7735 driver chip
|
#include <LovyanGFX.hpp> // Graphics and font library for ST7735 driver chip
|
||||||
|
|
||||||
class LGFX : public lgfx::LGFX_Device
|
class LGFX : public lgfx::LGFX_Device
|
||||||
@@ -402,9 +402,96 @@ class LGFX : public lgfx::LGFX_Device
|
|||||||
};
|
};
|
||||||
|
|
||||||
static LGFX *tft = nullptr;
|
static LGFX *tft = nullptr;
|
||||||
|
|
||||||
|
#elif defined(HX8357_CS)
|
||||||
|
#include <LovyanGFX.hpp> // Graphics and font library for HX8357 driver chip
|
||||||
|
|
||||||
|
class LGFX : public lgfx::LGFX_Device
|
||||||
|
{
|
||||||
|
lgfx::Panel_HX8357D _panel_instance;
|
||||||
|
lgfx::Bus_SPI _bus_instance;
|
||||||
|
#if defined(USE_XPT2046)
|
||||||
|
lgfx::ITouch *_touch_instance;
|
||||||
|
// lgfx::Touch_XPT2046 _touch_instance;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ST7735_CS) || defined(ST7789_CS) || defined(ILI9341_DRIVER) || defined(RAK14014) || ARCH_PORTDUINO
|
public:
|
||||||
|
LGFX(void)
|
||||||
|
{
|
||||||
|
// Panel_HX8357D
|
||||||
|
{
|
||||||
|
// configure SPI
|
||||||
|
auto cfg = _bus_instance.config();
|
||||||
|
|
||||||
|
cfg.spi_host = HX8357_SPI_HOST;
|
||||||
|
cfg.spi_mode = 0;
|
||||||
|
cfg.freq_write = SPI_FREQUENCY; // SPI clock for transmission (up to 80MHz, rounded to the value obtained by dividing
|
||||||
|
// 80MHz by an integer)
|
||||||
|
cfg.freq_read = SPI_READ_FREQUENCY; // SPI clock when receiving
|
||||||
|
cfg.spi_3wire = false; // Set to true if reception is done on the MOSI pin
|
||||||
|
cfg.use_lock = true; // Set to true to use transaction locking
|
||||||
|
cfg.dma_channel = SPI_DMA_CH_AUTO; // SPI_DMA_CH_AUTO; // Set DMA channel to use (0=not use DMA / 1=1ch / 2=ch /
|
||||||
|
// SPI_DMA_CH_AUTO=auto setting)
|
||||||
|
cfg.pin_sclk = HX8357_SCK; // Set SPI SCLK pin number
|
||||||
|
cfg.pin_mosi = HX8357_MOSI; // Set SPI MOSI pin number
|
||||||
|
cfg.pin_miso = HX8357_MISO; // Set SPI MISO pin number (-1 = disable)
|
||||||
|
cfg.pin_dc = HX8357_RS; // Set SPI DC pin number (-1 = disable)
|
||||||
|
|
||||||
|
_bus_instance.config(cfg); // applies the set value to the bus.
|
||||||
|
_panel_instance.setBus(&_bus_instance); // set the bus on the panel.
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Set the display panel control.
|
||||||
|
auto cfg = _panel_instance.config(); // Gets a structure for display panel settings.
|
||||||
|
|
||||||
|
cfg.pin_cs = HX8357_CS; // Pin number where CS is connected (-1 = disable)
|
||||||
|
cfg.pin_rst = HX8357_RESET; // Pin number where RST is connected (-1 = disable)
|
||||||
|
cfg.pin_busy = HX8357_BUSY; // Pin number where BUSY is connected (-1 = disable)
|
||||||
|
|
||||||
|
cfg.panel_width = TFT_WIDTH; // actual displayable width
|
||||||
|
cfg.panel_height = TFT_HEIGHT; // actual displayable height
|
||||||
|
cfg.offset_x = TFT_OFFSET_X; // Panel offset amount in X direction
|
||||||
|
cfg.offset_y = TFT_OFFSET_Y; // Panel offset amount in Y direction
|
||||||
|
cfg.offset_rotation = TFT_OFFSET_ROTATION; // Rotation direction value offset 0~7 (4~7 is upside down)
|
||||||
|
cfg.dummy_read_pixel = 8; // Number of bits for dummy read before pixel readout
|
||||||
|
cfg.dummy_read_bits = 1; // Number of bits for dummy read before non-pixel data read
|
||||||
|
cfg.readable = true; // Set to true if data can be read
|
||||||
|
cfg.invert = TFT_INVERT; // Set to true if the light/darkness of the panel is reversed
|
||||||
|
cfg.rgb_order = false; // Set to true if the panel's red and blue are swapped
|
||||||
|
cfg.dlen_16bit = false;
|
||||||
|
cfg.bus_shared = true; // If the bus is shared with the SD card, set to true (bus control with drawJpgFile etc.)
|
||||||
|
|
||||||
|
_panel_instance.config(cfg);
|
||||||
|
}
|
||||||
|
#if defined(USE_XPT2046)
|
||||||
|
{
|
||||||
|
// Configure settings for touch control.
|
||||||
|
_touch_instance = new lgfx::Touch_XPT2046;
|
||||||
|
auto touch_cfg = _touch_instance->config();
|
||||||
|
|
||||||
|
touch_cfg.pin_cs = TOUCH_CS;
|
||||||
|
touch_cfg.x_min = 0;
|
||||||
|
touch_cfg.x_max = TFT_HEIGHT - 1;
|
||||||
|
touch_cfg.y_min = 0;
|
||||||
|
touch_cfg.y_max = TFT_WIDTH - 1;
|
||||||
|
touch_cfg.pin_int = -1;
|
||||||
|
touch_cfg.bus_shared = true;
|
||||||
|
touch_cfg.offset_rotation = 1;
|
||||||
|
|
||||||
|
_touch_instance->config(touch_cfg);
|
||||||
|
//_panel_instance->setTouch(_touch_instance);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
setPanel(&_panel_instance);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static LGFX *tft = nullptr;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ST7735_CS) || defined(ST7789_CS) || defined(ILI9341_DRIVER) || defined(RAK14014) || defined(HX8357_CS) || \
|
||||||
|
(ARCH_PORTDUINO && HAS_SCREEN != 0)
|
||||||
#include "SPILock.h"
|
#include "SPILock.h"
|
||||||
#include "TFTDisplay.h"
|
#include "TFTDisplay.h"
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
@@ -486,7 +573,13 @@ void TFTDisplay::sendCommand(uint8_t com)
|
|||||||
#ifdef VTFT_CTRL
|
#ifdef VTFT_CTRL
|
||||||
digitalWrite(VTFT_CTRL, LOW);
|
digitalWrite(VTFT_CTRL, LOW);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef UNPHONE
|
||||||
|
Wire.beginTransmission(0x26);
|
||||||
|
Wire.write(0x02);
|
||||||
|
Wire.write(0x04); // Backlight on
|
||||||
|
Wire.write(0x22); // G&B LEDs off
|
||||||
|
Wire.endTransmission();
|
||||||
|
#endif
|
||||||
#ifdef RAK14014
|
#ifdef RAK14014
|
||||||
#elif !defined(M5STACK)
|
#elif !defined(M5STACK)
|
||||||
tft->setBrightness(172);
|
tft->setBrightness(172);
|
||||||
@@ -513,6 +606,13 @@ void TFTDisplay::sendCommand(uint8_t com)
|
|||||||
#ifdef VTFT_CTRL
|
#ifdef VTFT_CTRL
|
||||||
digitalWrite(VTFT_CTRL, HIGH);
|
digitalWrite(VTFT_CTRL, HIGH);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef UNPHONE
|
||||||
|
Wire.beginTransmission(0x26);
|
||||||
|
Wire.write(0x02);
|
||||||
|
Wire.write(0x00); // Backlight off
|
||||||
|
Wire.write(0x22); // G&B LEDs off
|
||||||
|
Wire.endTransmission();
|
||||||
|
#endif
|
||||||
#ifdef RAK14014
|
#ifdef RAK14014
|
||||||
#elif !defined(M5STACK)
|
#elif !defined(M5STACK)
|
||||||
tft->setBrightness(0);
|
tft->setBrightness(0);
|
||||||
@@ -584,6 +684,14 @@ bool TFTDisplay::connect()
|
|||||||
pinMode(ST7735_BL_V05, OUTPUT);
|
pinMode(ST7735_BL_V05, OUTPUT);
|
||||||
digitalWrite(ST7735_BL_V05, TFT_BACKLIGHT_ON);
|
digitalWrite(ST7735_BL_V05, TFT_BACKLIGHT_ON);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef UNPHONE
|
||||||
|
Wire.beginTransmission(0x26);
|
||||||
|
Wire.write(0x02);
|
||||||
|
Wire.write(0x04); // Backlight on
|
||||||
|
Wire.write(0x22); // G&B LEDs off
|
||||||
|
Wire.endTransmission();
|
||||||
|
LOG_INFO("Power to TFT Backlight\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
tft->init();
|
tft->init();
|
||||||
|
|
||||||
@@ -605,4 +713,4 @@ bool TFTDisplay::connect()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ const uint8_t imgUser[] PROGMEM = {0x3C, 0x42, 0x99, 0xA5, 0xA5, 0x99, 0x42, 0x3
|
|||||||
const uint8_t imgPositionEmpty[] PROGMEM = {0x20, 0x30, 0x28, 0x24, 0x42, 0xFF};
|
const uint8_t imgPositionEmpty[] PROGMEM = {0x20, 0x30, 0x28, 0x24, 0x42, 0xFF};
|
||||||
const uint8_t imgPositionSolid[] PROGMEM = {0x20, 0x30, 0x38, 0x3C, 0x7E, 0xFF};
|
const uint8_t imgPositionSolid[] PROGMEM = {0x20, 0x30, 0x38, 0x3C, 0x7E, 0xFF};
|
||||||
|
|
||||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || ARCH_PORTDUINO) && \
|
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS) || defined(HX8357_CS) || \
|
||||||
|
ARCH_PORTDUINO) && \
|
||||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||||
const uint8_t imgQuestionL1[] PROGMEM = {0xff, 0x01, 0x01, 0x32, 0x7b, 0x49, 0x49, 0x6f, 0x26, 0x01, 0x01, 0xff};
|
const uint8_t imgQuestionL1[] PROGMEM = {0xff, 0x01, 0x01, 0x32, 0x7b, 0x49, 0x49, 0x6f, 0x26, 0x01, 0x01, 0xff};
|
||||||
const uint8_t imgQuestionL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f};
|
const uint8_t imgQuestionL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f};
|
||||||
@@ -30,4 +31,4 @@ const uint8_t imgQuestion[] PROGMEM = {0xbf, 0x41, 0xc0, 0x8b, 0xdb, 0x70, 0xa1,
|
|||||||
const uint8_t imgSF[] PROGMEM = {0xd2, 0xb7, 0xad, 0xbb, 0x92, 0x01, 0xfd, 0xfd, 0x15, 0x85, 0xf5};
|
const uint8_t imgSF[] PROGMEM = {0xd2, 0xb7, 0xad, 0xbb, 0x92, 0x01, 0xfd, 0xfd, 0x15, 0x85, 0xf5};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "img/icon.xbm"
|
#include "img/icon.xbm"
|
||||||
|
|||||||
@@ -217,7 +217,11 @@ int32_t KbI2cBase::runOnce()
|
|||||||
e.kbchar = 0xb7;
|
e.kbchar = 0xb7;
|
||||||
break;
|
break;
|
||||||
case 0x90: // fn+r
|
case 0x90: // fn+r
|
||||||
|
case 0x91: // fn+t
|
||||||
case 0x9b: // fn+s
|
case 0x9b: // fn+s
|
||||||
|
case 0xac: // fn+m
|
||||||
|
case 0x9e: // fn+g
|
||||||
|
case 0xaf: // fn+space
|
||||||
// just pass those unmodified
|
// just pass those unmodified
|
||||||
e.inputEvent = ANYKEY;
|
e.inputEvent = ANYKEY;
|
||||||
e.kbchar = c;
|
e.kbchar = c;
|
||||||
|
|||||||
27
src/main.cpp
27
src/main.cpp
@@ -589,6 +589,20 @@ void setup()
|
|||||||
if (config.display.oled != meshtastic_Config_DisplayConfig_OledType_OLED_AUTO)
|
if (config.display.oled != meshtastic_Config_DisplayConfig_OledType_OLED_AUTO)
|
||||||
screen_model = config.display.oled;
|
screen_model = config.display.oled;
|
||||||
|
|
||||||
|
#ifdef UNPHONE
|
||||||
|
// initialise IO expander with pinmodes
|
||||||
|
Wire.beginTransmission(0x26);
|
||||||
|
Wire.write(0x06);
|
||||||
|
Wire.write(0x7A);
|
||||||
|
Wire.write(0xDD);
|
||||||
|
Wire.endTransmission();
|
||||||
|
Wire.beginTransmission(0x26);
|
||||||
|
Wire.write(0x02);
|
||||||
|
Wire.write(0x04); // Backlight on
|
||||||
|
Wire.write(0x22); // G&B LEDs off
|
||||||
|
Wire.endTransmission();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(USE_SH1107)
|
#if defined(USE_SH1107)
|
||||||
screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1107; // set dimension of 128x128
|
screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1107; // set dimension of 128x128
|
||||||
display_geometry = GEOMETRY_128_128;
|
display_geometry = GEOMETRY_128_128;
|
||||||
@@ -649,6 +663,15 @@ void setup()
|
|||||||
// Initialize the screen first so we can show the logo while we start up everything else.
|
// Initialize the screen first so we can show the logo while we start up everything else.
|
||||||
screen = new graphics::Screen(screen_found, screen_model, screen_geometry);
|
screen = new graphics::Screen(screen_found, screen_model, screen_geometry);
|
||||||
|
|
||||||
|
// setup TZ prior to time actions.
|
||||||
|
if (*config.device.tzdef) {
|
||||||
|
setenv("TZ", config.device.tzdef, 1);
|
||||||
|
} else {
|
||||||
|
setenv("TZ", "GMT0", 1);
|
||||||
|
}
|
||||||
|
tzset();
|
||||||
|
LOG_DEBUG("Set Timezone to %s\n", getenv("TZ"));
|
||||||
|
|
||||||
readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time)
|
readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time)
|
||||||
|
|
||||||
#if !MESHTASTIC_EXCLUDE_GPS
|
#if !MESHTASTIC_EXCLUDE_GPS
|
||||||
@@ -686,7 +709,7 @@ void setup()
|
|||||||
|
|
||||||
// Don't call screen setup until after nodedb is setup (because we need
|
// Don't call screen setup until after nodedb is setup (because we need
|
||||||
// the current region name)
|
// the current region name)
|
||||||
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7789_CS)
|
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7789_CS) || defined(HX8357_CS)
|
||||||
screen->setup();
|
screen->setup();
|
||||||
#elif defined(ARCH_PORTDUINO)
|
#elif defined(ARCH_PORTDUINO)
|
||||||
if (screen_found.port != ScanI2C::I2CPort::NO_I2C || settingsMap[displayPanel]) {
|
if (screen_found.port != ScanI2C::I2CPort::NO_I2C || settingsMap[displayPanel]) {
|
||||||
@@ -986,4 +1009,4 @@ void loop()
|
|||||||
mainDelay.delay(delayMsec);
|
mainDelay.delay(delayMsec);
|
||||||
}
|
}
|
||||||
// if (didWake) LOG_DEBUG("wake!\n");
|
// if (didWake) LOG_DEBUG("wake!\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,12 @@ void LockingArduinoHal::spiEndTransaction()
|
|||||||
|
|
||||||
ArduinoHal::spiEndTransaction();
|
ArduinoHal::spiEndTransaction();
|
||||||
}
|
}
|
||||||
|
#if ARCH_PORTDUINO
|
||||||
|
void LockingArduinoHal::spiTransfer(uint8_t *out, size_t len, uint8_t *in)
|
||||||
|
{
|
||||||
|
spi->transfer(out, in, len);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
RadioLibInterface::RadioLibInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
|
RadioLibInterface::RadioLibInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
|
||||||
RADIOLIB_PIN_TYPE busy, PhysicalLayer *_iface)
|
RADIOLIB_PIN_TYPE busy, PhysicalLayer *_iface)
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ class LockingArduinoHal : public ArduinoHal
|
|||||||
|
|
||||||
void spiBeginTransaction() override;
|
void spiBeginTransaction() override;
|
||||||
void spiEndTransaction() override;
|
void spiEndTransaction() override;
|
||||||
|
#if ARCH_PORTDUINO
|
||||||
|
void spiTransfer(uint8_t *out, size_t len, uint8_t *in) override;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(USE_STM32WLx)
|
#if defined(USE_STM32WLx)
|
||||||
|
|||||||
@@ -30,12 +30,12 @@ typedef enum _meshtastic_Config_DeviceConfig_Role {
|
|||||||
meshtastic_Config_DeviceConfig_Role_REPEATER = 4,
|
meshtastic_Config_DeviceConfig_Role_REPEATER = 4,
|
||||||
/* Description: Broadcasts GPS position packets as priority.
|
/* Description: Broadcasts GPS position packets as priority.
|
||||||
Technical Details: Position Mesh packets will be prioritized higher and sent more frequently by default.
|
Technical Details: Position Mesh packets will be prioritized higher and sent more frequently by default.
|
||||||
When used in conjunction with power.is_power_saving = true, nodes will wake up,
|
When used in conjunction with power.is_power_saving = true, nodes will wake up,
|
||||||
send position, and then sleep for position.position_broadcast_secs seconds. */
|
send position, and then sleep for position.position_broadcast_secs seconds. */
|
||||||
meshtastic_Config_DeviceConfig_Role_TRACKER = 5,
|
meshtastic_Config_DeviceConfig_Role_TRACKER = 5,
|
||||||
/* Description: Broadcasts telemetry packets as priority.
|
/* Description: Broadcasts telemetry packets as priority.
|
||||||
Technical Details: Telemetry Mesh packets will be prioritized higher and sent more frequently by default.
|
Technical Details: Telemetry Mesh packets will be prioritized higher and sent more frequently by default.
|
||||||
When used in conjunction with power.is_power_saving = true, nodes will wake up,
|
When used in conjunction with power.is_power_saving = true, nodes will wake up,
|
||||||
send environment telemetry, and then sleep for telemetry.environment_update_interval seconds. */
|
send environment telemetry, and then sleep for telemetry.environment_update_interval seconds. */
|
||||||
meshtastic_Config_DeviceConfig_Role_SENSOR = 6,
|
meshtastic_Config_DeviceConfig_Role_SENSOR = 6,
|
||||||
/* Description: Optimized for ATAK system communication and reduces routine broadcasts.
|
/* Description: Optimized for ATAK system communication and reduces routine broadcasts.
|
||||||
@@ -50,7 +50,7 @@ typedef enum _meshtastic_Config_DeviceConfig_Role {
|
|||||||
Can be used for clandestine operation or to dramatically reduce airtime / power consumption */
|
Can be used for clandestine operation or to dramatically reduce airtime / power consumption */
|
||||||
meshtastic_Config_DeviceConfig_Role_CLIENT_HIDDEN = 8,
|
meshtastic_Config_DeviceConfig_Role_CLIENT_HIDDEN = 8,
|
||||||
/* Description: Broadcasts location as message to default channel regularly for to assist with device recovery.
|
/* Description: Broadcasts location as message to default channel regularly for to assist with device recovery.
|
||||||
Technical Details: Used to automatically send a text message to the mesh
|
Technical Details: Used to automatically send a text message to the mesh
|
||||||
with the current position of the device on a frequent interval:
|
with the current position of the device on a frequent interval:
|
||||||
"I'm lost! Position: lat / long" */
|
"I'm lost! Position: lat / long" */
|
||||||
meshtastic_Config_DeviceConfig_Role_LOST_AND_FOUND = 9,
|
meshtastic_Config_DeviceConfig_Role_LOST_AND_FOUND = 9,
|
||||||
@@ -281,6 +281,8 @@ typedef struct _meshtastic_Config_DeviceConfig {
|
|||||||
bool is_managed;
|
bool is_managed;
|
||||||
/* Disables the triple-press of user button to enable or disable GPS */
|
/* Disables the triple-press of user button to enable or disable GPS */
|
||||||
bool disable_triple_click;
|
bool disable_triple_click;
|
||||||
|
/* POSIX Timezone definition string from https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv. */
|
||||||
|
char tzdef[65];
|
||||||
} meshtastic_Config_DeviceConfig;
|
} meshtastic_Config_DeviceConfig;
|
||||||
|
|
||||||
/* Position Config */
|
/* Position Config */
|
||||||
@@ -583,7 +585,7 @@ extern "C" {
|
|||||||
|
|
||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}}
|
#define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}}
|
||||||
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0}
|
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, ""}
|
||||||
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
||||||
#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, ""}
|
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, ""}
|
||||||
@@ -592,7 +594,7 @@ extern "C" {
|
|||||||
#define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0}
|
#define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0}
|
||||||
#define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0}
|
#define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0}
|
||||||
#define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}}
|
#define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}}
|
||||||
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0}
|
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, ""}
|
||||||
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
||||||
#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, ""}
|
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, ""}
|
||||||
@@ -612,6 +614,7 @@ extern "C" {
|
|||||||
#define meshtastic_Config_DeviceConfig_double_tap_as_button_press_tag 8
|
#define meshtastic_Config_DeviceConfig_double_tap_as_button_press_tag 8
|
||||||
#define meshtastic_Config_DeviceConfig_is_managed_tag 9
|
#define meshtastic_Config_DeviceConfig_is_managed_tag 9
|
||||||
#define meshtastic_Config_DeviceConfig_disable_triple_click_tag 10
|
#define meshtastic_Config_DeviceConfig_disable_triple_click_tag 10
|
||||||
|
#define meshtastic_Config_DeviceConfig_tzdef_tag 11
|
||||||
#define meshtastic_Config_PositionConfig_position_broadcast_secs_tag 1
|
#define meshtastic_Config_PositionConfig_position_broadcast_secs_tag 1
|
||||||
#define meshtastic_Config_PositionConfig_position_broadcast_smart_enabled_tag 2
|
#define meshtastic_Config_PositionConfig_position_broadcast_smart_enabled_tag 2
|
||||||
#define meshtastic_Config_PositionConfig_fixed_position_tag 3
|
#define meshtastic_Config_PositionConfig_fixed_position_tag 3
|
||||||
@@ -711,7 +714,8 @@ X(a, STATIC, SINGULAR, UENUM, rebroadcast_mode, 6) \
|
|||||||
X(a, STATIC, SINGULAR, UINT32, node_info_broadcast_secs, 7) \
|
X(a, STATIC, SINGULAR, UINT32, node_info_broadcast_secs, 7) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, double_tap_as_button_press, 8) \
|
X(a, STATIC, SINGULAR, BOOL, double_tap_as_button_press, 8) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, is_managed, 9) \
|
X(a, STATIC, SINGULAR, BOOL, is_managed, 9) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, disable_triple_click, 10)
|
X(a, STATIC, SINGULAR, BOOL, disable_triple_click, 10) \
|
||||||
|
X(a, STATIC, SINGULAR, STRING, tzdef, 11)
|
||||||
#define meshtastic_Config_DeviceConfig_CALLBACK NULL
|
#define meshtastic_Config_DeviceConfig_CALLBACK NULL
|
||||||
#define meshtastic_Config_DeviceConfig_DEFAULT NULL
|
#define meshtastic_Config_DeviceConfig_DEFAULT NULL
|
||||||
|
|
||||||
@@ -829,7 +833,7 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg;
|
|||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define meshtastic_Config_BluetoothConfig_size 10
|
#define meshtastic_Config_BluetoothConfig_size 10
|
||||||
#define meshtastic_Config_DeviceConfig_size 32
|
#define meshtastic_Config_DeviceConfig_size 98
|
||||||
#define meshtastic_Config_DisplayConfig_size 28
|
#define meshtastic_Config_DisplayConfig_size 28
|
||||||
#define meshtastic_Config_LoRaConfig_size 80
|
#define meshtastic_Config_LoRaConfig_size 80
|
||||||
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
|
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
|
||||||
|
|||||||
@@ -6,13 +6,13 @@
|
|||||||
#error Regenerate this file with the current version of nanopb generator.
|
#error Regenerate this file with the current version of nanopb generator.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PB_BIND(meshtastic_DeviceState, meshtastic_DeviceState, 2)
|
PB_BIND(meshtastic_PositionLite, meshtastic_PositionLite, AUTO)
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(meshtastic_NodeInfoLite, meshtastic_NodeInfoLite, AUTO)
|
PB_BIND(meshtastic_NodeInfoLite, meshtastic_NodeInfoLite, AUTO)
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(meshtastic_PositionLite, meshtastic_PositionLite, AUTO)
|
PB_BIND(meshtastic_DeviceState, meshtastic_DeviceState, 2)
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(meshtastic_ChannelFile, meshtastic_ChannelFile, 2)
|
PB_BIND(meshtastic_ChannelFile, meshtastic_ChannelFile, 2)
|
||||||
|
|||||||
@@ -8,13 +8,25 @@
|
|||||||
#include "meshtastic/channel.pb.h"
|
#include "meshtastic/channel.pb.h"
|
||||||
#include "meshtastic/localonly.pb.h"
|
#include "meshtastic/localonly.pb.h"
|
||||||
#include "meshtastic/mesh.pb.h"
|
#include "meshtastic/mesh.pb.h"
|
||||||
#include "meshtastic/telemetry.pb.h"
|
|
||||||
#include "meshtastic/module_config.pb.h"
|
#include "meshtastic/module_config.pb.h"
|
||||||
|
#include "meshtastic/telemetry.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.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Enum definitions */
|
||||||
|
/* Font sizes for the device screen */
|
||||||
|
typedef enum _meshtastic_ScreenFonts {
|
||||||
|
/* TODO: REPLACE */
|
||||||
|
meshtastic_ScreenFonts_FONT_SMALL = 0,
|
||||||
|
/* TODO: REPLACE */
|
||||||
|
meshtastic_ScreenFonts_FONT_MEDIUM = 1,
|
||||||
|
/* TODO: REPLACE */
|
||||||
|
meshtastic_ScreenFonts_FONT_LARGE = 2
|
||||||
|
} meshtastic_ScreenFonts;
|
||||||
|
|
||||||
|
/* Struct definitions */
|
||||||
/* Position with static location information only for NodeDBLite */
|
/* Position with static location information only for NodeDBLite */
|
||||||
typedef struct _meshtastic_PositionLite {
|
typedef struct _meshtastic_PositionLite {
|
||||||
/* The new preferred location encoding, multiply by 1e-7 to get degrees
|
/* The new preferred location encoding, multiply by 1e-7 to get degrees
|
||||||
@@ -63,18 +75,6 @@ typedef struct _meshtastic_NodeInfoLite {
|
|||||||
bool is_favorite;
|
bool is_favorite;
|
||||||
} meshtastic_NodeInfoLite;
|
} meshtastic_NodeInfoLite;
|
||||||
|
|
||||||
/* Enum definitions */
|
|
||||||
/* TODO: REPLACE */
|
|
||||||
typedef enum _meshtastic_ScreenFonts {
|
|
||||||
/* TODO: REPLACE */
|
|
||||||
meshtastic_ScreenFonts_FONT_SMALL = 0,
|
|
||||||
/* TODO: REPLACE */
|
|
||||||
meshtastic_ScreenFonts_FONT_MEDIUM = 1,
|
|
||||||
/* TODO: REPLACE */
|
|
||||||
meshtastic_ScreenFonts_FONT_LARGE = 2
|
|
||||||
} meshtastic_ScreenFonts;
|
|
||||||
|
|
||||||
/* Struct definitions */
|
|
||||||
/* This message is never sent over the wire, but it is used for serializing DB
|
/* This message is never sent over the wire, but it is used for serializing DB
|
||||||
state to flash in the device code
|
state to flash in the device code
|
||||||
FIXME, since we write this each time we enter deep sleep (and have infinite
|
FIXME, since we write this each time we enter deep sleep (and have infinite
|
||||||
@@ -117,7 +117,6 @@ typedef struct _meshtastic_DeviceState {
|
|||||||
std::vector<meshtastic_NodeInfoLite> node_db_lite;
|
std::vector<meshtastic_NodeInfoLite> node_db_lite;
|
||||||
} meshtastic_DeviceState;
|
} meshtastic_DeviceState;
|
||||||
|
|
||||||
|
|
||||||
/* The on-disk saved channels */
|
/* The on-disk saved channels */
|
||||||
typedef struct _meshtastic_ChannelFile {
|
typedef struct _meshtastic_ChannelFile {
|
||||||
/* The channels our node knows about */
|
/* The channels our node knows about */
|
||||||
@@ -164,37 +163,27 @@ extern "C" {
|
|||||||
#define _meshtastic_ScreenFonts_MAX meshtastic_ScreenFonts_FONT_LARGE
|
#define _meshtastic_ScreenFonts_MAX meshtastic_ScreenFonts_FONT_LARGE
|
||||||
#define _meshtastic_ScreenFonts_ARRAYSIZE ((meshtastic_ScreenFonts)(meshtastic_ScreenFonts_FONT_LARGE+1))
|
#define _meshtastic_ScreenFonts_ARRAYSIZE ((meshtastic_ScreenFonts)(meshtastic_ScreenFonts_FONT_LARGE+1))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define meshtastic_PositionLite_location_source_ENUMTYPE meshtastic_Position_LocSource
|
#define meshtastic_PositionLite_location_source_ENUMTYPE meshtastic_Position_LocSource
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define meshtastic_OEMStore_oem_font_ENUMTYPE meshtastic_ScreenFonts
|
#define meshtastic_OEMStore_oem_font_ENUMTYPE meshtastic_ScreenFonts
|
||||||
|
|
||||||
|
|
||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default, 0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}, {{NULL}, NULL}}
|
|
||||||
#define meshtastic_NodeInfoLite_init_default {0, false, meshtastic_User_init_default, false, meshtastic_PositionLite_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, 0, 0}
|
|
||||||
#define meshtastic_PositionLite_init_default {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
|
#define meshtastic_PositionLite_init_default {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
|
||||||
|
#define meshtastic_NodeInfoLite_init_default {0, false, meshtastic_User_init_default, false, meshtastic_PositionLite_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, 0, 0}
|
||||||
|
#define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default, 0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}, {{NULL}, NULL}}
|
||||||
#define meshtastic_ChannelFile_init_default {0, {meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default}, 0}
|
#define meshtastic_ChannelFile_init_default {0, {meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default}, 0}
|
||||||
#define meshtastic_OEMStore_init_default {0, 0, {0, {0}}, _meshtastic_ScreenFonts_MIN, "", {0, {0}}, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default}
|
#define meshtastic_OEMStore_init_default {0, 0, {0, {0}}, _meshtastic_ScreenFonts_MIN, "", {0, {0}}, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default}
|
||||||
#define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero, 0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}, {{NULL}, NULL}}
|
|
||||||
#define meshtastic_NodeInfoLite_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_PositionLite_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, 0, 0}
|
|
||||||
#define meshtastic_PositionLite_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
|
#define meshtastic_PositionLite_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
|
||||||
|
#define meshtastic_NodeInfoLite_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_PositionLite_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, 0, 0}
|
||||||
|
#define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero, 0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}, {{NULL}, NULL}}
|
||||||
#define meshtastic_ChannelFile_init_zero {0, {meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero}, 0}
|
#define meshtastic_ChannelFile_init_zero {0, {meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero}, 0}
|
||||||
#define meshtastic_OEMStore_init_zero {0, 0, {0, {0}}, _meshtastic_ScreenFonts_MIN, "", {0, {0}}, false, meshtastic_LocalConfig_init_zero, false, meshtastic_LocalModuleConfig_init_zero}
|
#define meshtastic_OEMStore_init_zero {0, 0, {0, {0}}, _meshtastic_ScreenFonts_MIN, "", {0, {0}}, false, meshtastic_LocalConfig_init_zero, false, meshtastic_LocalModuleConfig_init_zero}
|
||||||
|
|
||||||
/* Field tags (for use in manual encoding/decoding) */
|
/* Field tags (for use in manual encoding/decoding) */
|
||||||
#define meshtastic_DeviceState_my_node_tag 2
|
|
||||||
#define meshtastic_DeviceState_owner_tag 3
|
|
||||||
#define meshtastic_DeviceState_receive_queue_tag 5
|
|
||||||
#define meshtastic_DeviceState_rx_text_message_tag 7
|
|
||||||
#define meshtastic_DeviceState_version_tag 8
|
|
||||||
#define meshtastic_DeviceState_no_save_tag 9
|
|
||||||
#define meshtastic_DeviceState_did_gps_reset_tag 11
|
|
||||||
#define meshtastic_DeviceState_rx_waypoint_tag 12
|
|
||||||
#define meshtastic_DeviceState_node_remote_hardware_pins_tag 13
|
|
||||||
#define meshtastic_DeviceState_node_db_lite_tag 14
|
|
||||||
#define meshtastic_PositionLite_latitude_i_tag 1
|
#define meshtastic_PositionLite_latitude_i_tag 1
|
||||||
#define meshtastic_PositionLite_longitude_i_tag 2
|
#define meshtastic_PositionLite_longitude_i_tag 2
|
||||||
#define meshtastic_PositionLite_altitude_tag 3
|
#define meshtastic_PositionLite_altitude_tag 3
|
||||||
@@ -210,6 +199,16 @@ extern "C" {
|
|||||||
#define meshtastic_NodeInfoLite_via_mqtt_tag 8
|
#define meshtastic_NodeInfoLite_via_mqtt_tag 8
|
||||||
#define meshtastic_NodeInfoLite_hops_away_tag 9
|
#define meshtastic_NodeInfoLite_hops_away_tag 9
|
||||||
#define meshtastic_NodeInfoLite_is_favorite_tag 10
|
#define meshtastic_NodeInfoLite_is_favorite_tag 10
|
||||||
|
#define meshtastic_DeviceState_my_node_tag 2
|
||||||
|
#define meshtastic_DeviceState_owner_tag 3
|
||||||
|
#define meshtastic_DeviceState_receive_queue_tag 5
|
||||||
|
#define meshtastic_DeviceState_rx_text_message_tag 7
|
||||||
|
#define meshtastic_DeviceState_version_tag 8
|
||||||
|
#define meshtastic_DeviceState_no_save_tag 9
|
||||||
|
#define meshtastic_DeviceState_did_gps_reset_tag 11
|
||||||
|
#define meshtastic_DeviceState_rx_waypoint_tag 12
|
||||||
|
#define meshtastic_DeviceState_node_remote_hardware_pins_tag 13
|
||||||
|
#define meshtastic_DeviceState_node_db_lite_tag 14
|
||||||
#define meshtastic_ChannelFile_channels_tag 1
|
#define meshtastic_ChannelFile_channels_tag 1
|
||||||
#define meshtastic_ChannelFile_version_tag 2
|
#define meshtastic_ChannelFile_version_tag 2
|
||||||
#define meshtastic_OEMStore_oem_icon_width_tag 1
|
#define meshtastic_OEMStore_oem_icon_width_tag 1
|
||||||
@@ -222,6 +221,32 @@ extern "C" {
|
|||||||
#define meshtastic_OEMStore_oem_local_module_config_tag 8
|
#define meshtastic_OEMStore_oem_local_module_config_tag 8
|
||||||
|
|
||||||
/* Struct field encoding specification for nanopb */
|
/* Struct field encoding specification for nanopb */
|
||||||
|
#define meshtastic_PositionLite_FIELDLIST(X, a) \
|
||||||
|
X(a, STATIC, SINGULAR, SFIXED32, latitude_i, 1) \
|
||||||
|
X(a, STATIC, SINGULAR, SFIXED32, longitude_i, 2) \
|
||||||
|
X(a, STATIC, SINGULAR, INT32, altitude, 3) \
|
||||||
|
X(a, STATIC, SINGULAR, FIXED32, time, 4) \
|
||||||
|
X(a, STATIC, SINGULAR, UENUM, location_source, 5)
|
||||||
|
#define meshtastic_PositionLite_CALLBACK NULL
|
||||||
|
#define meshtastic_PositionLite_DEFAULT NULL
|
||||||
|
|
||||||
|
#define meshtastic_NodeInfoLite_FIELDLIST(X, a) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, num, 1) \
|
||||||
|
X(a, STATIC, OPTIONAL, MESSAGE, user, 2) \
|
||||||
|
X(a, STATIC, OPTIONAL, MESSAGE, position, 3) \
|
||||||
|
X(a, STATIC, SINGULAR, FLOAT, snr, 4) \
|
||||||
|
X(a, STATIC, SINGULAR, FIXED32, last_heard, 5) \
|
||||||
|
X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, channel, 7) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, via_mqtt, 8) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, hops_away, 9) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, is_favorite, 10)
|
||||||
|
#define meshtastic_NodeInfoLite_CALLBACK NULL
|
||||||
|
#define meshtastic_NodeInfoLite_DEFAULT NULL
|
||||||
|
#define meshtastic_NodeInfoLite_user_MSGTYPE meshtastic_User
|
||||||
|
#define meshtastic_NodeInfoLite_position_MSGTYPE meshtastic_PositionLite
|
||||||
|
#define meshtastic_NodeInfoLite_device_metrics_MSGTYPE meshtastic_DeviceMetrics
|
||||||
|
|
||||||
#define meshtastic_DeviceState_FIELDLIST(X, a) \
|
#define meshtastic_DeviceState_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, OPTIONAL, MESSAGE, my_node, 2) \
|
X(a, STATIC, OPTIONAL, MESSAGE, my_node, 2) \
|
||||||
X(a, STATIC, OPTIONAL, MESSAGE, owner, 3) \
|
X(a, STATIC, OPTIONAL, MESSAGE, owner, 3) \
|
||||||
@@ -244,32 +269,6 @@ extern bool meshtastic_DeviceState_callback(pb_istream_t *istream, pb_ostream_t
|
|||||||
#define meshtastic_DeviceState_node_remote_hardware_pins_MSGTYPE meshtastic_NodeRemoteHardwarePin
|
#define meshtastic_DeviceState_node_remote_hardware_pins_MSGTYPE meshtastic_NodeRemoteHardwarePin
|
||||||
#define meshtastic_DeviceState_node_db_lite_MSGTYPE meshtastic_NodeInfoLite
|
#define meshtastic_DeviceState_node_db_lite_MSGTYPE meshtastic_NodeInfoLite
|
||||||
|
|
||||||
#define meshtastic_NodeInfoLite_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, num, 1) \
|
|
||||||
X(a, STATIC, OPTIONAL, MESSAGE, user, 2) \
|
|
||||||
X(a, STATIC, OPTIONAL, MESSAGE, position, 3) \
|
|
||||||
X(a, STATIC, SINGULAR, FLOAT, snr, 4) \
|
|
||||||
X(a, STATIC, SINGULAR, FIXED32, last_heard, 5) \
|
|
||||||
X(a, STATIC, OPTIONAL, MESSAGE, device_metrics, 6) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, channel, 7) \
|
|
||||||
X(a, STATIC, SINGULAR, BOOL, via_mqtt, 8) \
|
|
||||||
X(a, STATIC, SINGULAR, UINT32, hops_away, 9) \
|
|
||||||
X(a, STATIC, SINGULAR, BOOL, is_favorite, 10)
|
|
||||||
#define meshtastic_NodeInfoLite_CALLBACK NULL
|
|
||||||
#define meshtastic_NodeInfoLite_DEFAULT NULL
|
|
||||||
#define meshtastic_NodeInfoLite_user_MSGTYPE meshtastic_User
|
|
||||||
#define meshtastic_NodeInfoLite_position_MSGTYPE meshtastic_PositionLite
|
|
||||||
#define meshtastic_NodeInfoLite_device_metrics_MSGTYPE meshtastic_DeviceMetrics
|
|
||||||
|
|
||||||
#define meshtastic_PositionLite_FIELDLIST(X, a) \
|
|
||||||
X(a, STATIC, SINGULAR, SFIXED32, latitude_i, 1) \
|
|
||||||
X(a, STATIC, SINGULAR, SFIXED32, longitude_i, 2) \
|
|
||||||
X(a, STATIC, SINGULAR, INT32, altitude, 3) \
|
|
||||||
X(a, STATIC, SINGULAR, FIXED32, time, 4) \
|
|
||||||
X(a, STATIC, SINGULAR, UENUM, location_source, 5)
|
|
||||||
#define meshtastic_PositionLite_CALLBACK NULL
|
|
||||||
#define meshtastic_PositionLite_DEFAULT NULL
|
|
||||||
|
|
||||||
#define meshtastic_ChannelFile_FIELDLIST(X, a) \
|
#define meshtastic_ChannelFile_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, REPEATED, MESSAGE, channels, 1) \
|
X(a, STATIC, REPEATED, MESSAGE, channels, 1) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, version, 2)
|
X(a, STATIC, SINGULAR, UINT32, version, 2)
|
||||||
@@ -291,16 +290,16 @@ X(a, STATIC, OPTIONAL, MESSAGE, oem_local_module_config, 8)
|
|||||||
#define meshtastic_OEMStore_oem_local_config_MSGTYPE meshtastic_LocalConfig
|
#define meshtastic_OEMStore_oem_local_config_MSGTYPE meshtastic_LocalConfig
|
||||||
#define meshtastic_OEMStore_oem_local_module_config_MSGTYPE meshtastic_LocalModuleConfig
|
#define meshtastic_OEMStore_oem_local_module_config_MSGTYPE meshtastic_LocalModuleConfig
|
||||||
|
|
||||||
extern const pb_msgdesc_t meshtastic_DeviceState_msg;
|
|
||||||
extern const pb_msgdesc_t meshtastic_NodeInfoLite_msg;
|
|
||||||
extern const pb_msgdesc_t meshtastic_PositionLite_msg;
|
extern const pb_msgdesc_t meshtastic_PositionLite_msg;
|
||||||
|
extern const pb_msgdesc_t meshtastic_NodeInfoLite_msg;
|
||||||
|
extern const pb_msgdesc_t meshtastic_DeviceState_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_ChannelFile_msg;
|
extern const pb_msgdesc_t meshtastic_ChannelFile_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_OEMStore_msg;
|
extern const pb_msgdesc_t meshtastic_OEMStore_msg;
|
||||||
|
|
||||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||||
#define meshtastic_DeviceState_fields &meshtastic_DeviceState_msg
|
|
||||||
#define meshtastic_NodeInfoLite_fields &meshtastic_NodeInfoLite_msg
|
|
||||||
#define meshtastic_PositionLite_fields &meshtastic_PositionLite_msg
|
#define meshtastic_PositionLite_fields &meshtastic_PositionLite_msg
|
||||||
|
#define meshtastic_NodeInfoLite_fields &meshtastic_NodeInfoLite_msg
|
||||||
|
#define meshtastic_DeviceState_fields &meshtastic_DeviceState_msg
|
||||||
#define meshtastic_ChannelFile_fields &meshtastic_ChannelFile_msg
|
#define meshtastic_ChannelFile_fields &meshtastic_ChannelFile_msg
|
||||||
#define meshtastic_OEMStore_fields &meshtastic_OEMStore_msg
|
#define meshtastic_OEMStore_fields &meshtastic_OEMStore_msg
|
||||||
|
|
||||||
@@ -308,7 +307,7 @@ extern const pb_msgdesc_t meshtastic_OEMStore_msg;
|
|||||||
/* meshtastic_DeviceState_size depends on runtime parameters */
|
/* meshtastic_DeviceState_size depends on runtime parameters */
|
||||||
#define meshtastic_ChannelFile_size 702
|
#define meshtastic_ChannelFile_size 702
|
||||||
#define meshtastic_NodeInfoLite_size 160
|
#define meshtastic_NodeInfoLite_size 160
|
||||||
#define meshtastic_OEMStore_size 3278
|
#define meshtastic_OEMStore_size 3344
|
||||||
#define meshtastic_PositionLite_size 28
|
#define meshtastic_PositionLite_size 28
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
|
|||||||
#define meshtastic_LocalModuleConfig_fields &meshtastic_LocalModuleConfig_msg
|
#define meshtastic_LocalModuleConfig_fields &meshtastic_LocalModuleConfig_msg
|
||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define meshtastic_LocalConfig_size 469
|
#define meshtastic_LocalConfig_size 535
|
||||||
#define meshtastic_LocalModuleConfig_size 663
|
#define meshtastic_LocalModuleConfig_size 663
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -141,6 +141,11 @@ typedef enum _meshtastic_HardwareModel {
|
|||||||
/* Heltec Wireless Tracker with ESP32-S3 CPU, built-in GPS, and TFT
|
/* Heltec Wireless Tracker with ESP32-S3 CPU, built-in GPS, and TFT
|
||||||
Older "V1.0" Variant */
|
Older "V1.0" Variant */
|
||||||
meshtastic_HardwareModel_HELTEC_WIRELESS_TRACKER_V1_0 = 58,
|
meshtastic_HardwareModel_HELTEC_WIRELESS_TRACKER_V1_0 = 58,
|
||||||
|
/* unPhone with ESP32-S3, TFT touchscreen, LSM6DS3TR-C accelerometer and gyroscope */
|
||||||
|
meshtastic_HardwareModel_UNPHONE = 59,
|
||||||
|
/* Teledatics TD-LORAC NRF52840 based M.2 LoRA module
|
||||||
|
Compatible with the TD-WRLS development board */
|
||||||
|
meshtastic_HardwareModel_TD_LORAC = 60,
|
||||||
/* ------------------------------------------------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
|
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------ */
|
------------------------------------------------------------------------------------------------------------------------------------------ */
|
||||||
@@ -593,7 +598,7 @@ typedef struct _meshtastic_MeshPacket {
|
|||||||
meshtastic_MeshPacket_Delayed delayed;
|
meshtastic_MeshPacket_Delayed delayed;
|
||||||
/* Describes whether this packet passed via MQTT somewhere along the path it currently took. */
|
/* Describes whether this packet passed via MQTT somewhere along the path it currently took. */
|
||||||
bool via_mqtt;
|
bool via_mqtt;
|
||||||
/* Hop limit with which the original packet started. Sent via LoRa using three bits in the unencrypted header.
|
/* Hop limit with which the original packet started. Sent via LoRa using three bits in the unencrypted header.
|
||||||
When receiving a packet, the difference between hop_start and hop_limit gives how many hops it traveled. */
|
When receiving a packet, the difference between hop_start and hop_limit gives how many hops it traveled. */
|
||||||
uint8_t hop_start;
|
uint8_t hop_start;
|
||||||
} meshtastic_MeshPacket;
|
} meshtastic_MeshPacket;
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
#ifndef PB_MESHTASTIC_MESHTASTIC_MQTT_PB_H_INCLUDED
|
#ifndef PB_MESHTASTIC_MESHTASTIC_MQTT_PB_H_INCLUDED
|
||||||
#define PB_MESHTASTIC_MESHTASTIC_MQTT_PB_H_INCLUDED
|
#define PB_MESHTASTIC_MESHTASTIC_MQTT_PB_H_INCLUDED
|
||||||
#include <pb.h>
|
#include <pb.h>
|
||||||
#include "meshtastic/mesh.pb.h"
|
|
||||||
#include "meshtastic/config.pb.h"
|
#include "meshtastic/config.pb.h"
|
||||||
|
#include "meshtastic/mesh.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.
|
||||||
|
|||||||
@@ -12,7 +12,11 @@
|
|||||||
#include "detect/ScanI2C.h"
|
#include "detect/ScanI2C.h"
|
||||||
#include "mesh/generated/meshtastic/cannedmessages.pb.h"
|
#include "mesh/generated/meshtastic/cannedmessages.pb.h"
|
||||||
|
|
||||||
#include "main.h" // for cardkb_found
|
#include "main.h" // for cardkb_found
|
||||||
|
#include "modules/ExternalNotificationModule.h" // for buzzer control
|
||||||
|
#if !MESHTASTIC_EXCLUDE_GPS
|
||||||
|
#include "GPS.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef INPUTBROKER_MATRIX_TYPE
|
#ifndef INPUTBROKER_MATRIX_TYPE
|
||||||
#define INPUTBROKER_MATRIX_TYPE 0
|
#define INPUTBROKER_MATRIX_TYPE 0
|
||||||
@@ -397,6 +401,7 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x09: // tab
|
case 0x09: // tab
|
||||||
|
case 0x91: // alt+t for T-Deck that doesn't have a tab key
|
||||||
if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_CHANNEL) {
|
if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_CHANNEL) {
|
||||||
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
||||||
} else if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NODE) {
|
} else if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NODE) {
|
||||||
@@ -411,13 +416,44 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
break;
|
break;
|
||||||
// handle fn+s for shutdown
|
// handle fn+s for shutdown
|
||||||
case 0x9b:
|
case 0x9b:
|
||||||
screen->startShutdownScreen();
|
if (screen)
|
||||||
|
screen->startShutdownScreen();
|
||||||
shutdownAtMsec = millis() + DEFAULT_SHUTDOWN_SECONDS * 1000;
|
shutdownAtMsec = millis() + DEFAULT_SHUTDOWN_SECONDS * 1000;
|
||||||
|
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||||
break;
|
break;
|
||||||
// and fn+r for reboot
|
// and fn+r for reboot
|
||||||
case 0x90:
|
case 0x90:
|
||||||
screen->startRebootScreen();
|
if (screen)
|
||||||
|
screen->startRebootScreen();
|
||||||
rebootAtMsec = millis() + DEFAULT_REBOOT_SECONDS * 1000;
|
rebootAtMsec = millis() + DEFAULT_REBOOT_SECONDS * 1000;
|
||||||
|
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||||
|
break;
|
||||||
|
case 0x9e: // toggle GPS like triple press does
|
||||||
|
if (gps != nullptr) {
|
||||||
|
gps->toggleGpsMode();
|
||||||
|
}
|
||||||
|
if (screen)
|
||||||
|
screen->forceDisplay();
|
||||||
|
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// mute (switch off/toggle) external notifications on fn+m
|
||||||
|
case 0xac:
|
||||||
|
if (moduleConfig.external_notification.enabled == true) {
|
||||||
|
if (externalNotificationModule->getMute()) {
|
||||||
|
externalNotificationModule->setMute(false);
|
||||||
|
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||||
|
} else {
|
||||||
|
externalNotificationModule->stopNow(); // this will turn off all GPIO and sounds and idle the loop
|
||||||
|
externalNotificationModule->setMute(true);
|
||||||
|
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xaf: // fn+space send network ping like double press does
|
||||||
|
service.refreshLocalMeshNode();
|
||||||
|
service.sendNetworkPing(NODENUM_BROADCAST, true);
|
||||||
|
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (this->cursor == this->freetext.length()) {
|
if (this->cursor == this->freetext.length()) {
|
||||||
|
|||||||
@@ -336,7 +336,7 @@ ExternalNotificationModule::ExternalNotificationModule()
|
|||||||
|
|
||||||
ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshPacket &mp)
|
ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshPacket &mp)
|
||||||
{
|
{
|
||||||
if (moduleConfig.external_notification.enabled) {
|
if (moduleConfig.external_notification.enabled && !isMuted) {
|
||||||
#ifdef T_WATCH_S3
|
#ifdef T_WATCH_S3
|
||||||
drv.setWaveform(0, 75);
|
drv.setWaveform(0, 75);
|
||||||
drv.setWaveform(1, 56);
|
drv.setWaveform(1, 56);
|
||||||
@@ -445,7 +445,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
|
|||||||
setIntervalFromNow(0); // run once so we know if we should do something
|
setIntervalFromNow(0); // run once so we know if we should do something
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("External Notification Module Disabled\n");
|
LOG_INFO("External Notification Module Disabled or muted\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return ProcessMessage::CONTINUE; // Let others look at this message also if they want
|
return ProcessMessage::CONTINUE; // Let others look at this message also if they want
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ class ExternalNotificationModule : public SinglePortModule, private concurrency:
|
|||||||
void setExternalOff(uint8_t index = 0);
|
void setExternalOff(uint8_t index = 0);
|
||||||
bool getExternal(uint8_t index = 0);
|
bool getExternal(uint8_t index = 0);
|
||||||
|
|
||||||
|
void setMute(bool mute) { isMuted = mute; }
|
||||||
|
bool getMute() { return isMuted; }
|
||||||
|
|
||||||
void stopNow();
|
void stopNow();
|
||||||
|
|
||||||
void handleGetRingtone(const meshtastic_MeshPacket &req, meshtastic_AdminMessage *response);
|
void handleGetRingtone(const meshtastic_MeshPacket &req, meshtastic_AdminMessage *response);
|
||||||
@@ -56,6 +59,8 @@ class ExternalNotificationModule : public SinglePortModule, private concurrency:
|
|||||||
|
|
||||||
bool isNagging = false;
|
bool isNagging = false;
|
||||||
|
|
||||||
|
bool isMuted = false;
|
||||||
|
|
||||||
virtual AdminMessageHandleResult handleAdminMessageForModule(const meshtastic_MeshPacket &mp,
|
virtual AdminMessageHandleResult handleAdminMessageForModule(const meshtastic_MeshPacket &mp,
|
||||||
meshtastic_AdminMessage *request,
|
meshtastic_AdminMessage *request,
|
||||||
meshtastic_AdminMessage *response) override;
|
meshtastic_AdminMessage *response) override;
|
||||||
|
|||||||
@@ -114,8 +114,8 @@ size_t NeighborInfoModule::cleanUpNeighbors()
|
|||||||
(*numNeighbors)--;
|
(*numNeighbors)--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the neighbor list if we removed any neighbors
|
// Save the neighbor list if we removed any neighbors or neighbors were already updated upon receiving a packet
|
||||||
if (indices_to_remove.size() > 0) {
|
if (indices_to_remove.size() > 0 || shouldSave) {
|
||||||
saveProtoForModule();
|
saveProtoForModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,7 +210,6 @@ meshtastic_Neighbor *NeighborInfoModule::getOrCreateNeighbor(NodeNum originalSen
|
|||||||
// Only if this is the original sender, the broadcast interval corresponds to it
|
// Only if this is the original sender, the broadcast interval corresponds to it
|
||||||
if (originalSender == n && node_broadcast_interval_secs != 0)
|
if (originalSender == n && node_broadcast_interval_secs != 0)
|
||||||
nbr->node_broadcast_interval_secs = node_broadcast_interval_secs;
|
nbr->node_broadcast_interval_secs = node_broadcast_interval_secs;
|
||||||
saveProtoForModule(); // Save the updated neighbor
|
|
||||||
return nbr;
|
return nbr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,7 +227,7 @@ meshtastic_Neighbor *NeighborInfoModule::getOrCreateNeighbor(NodeNum originalSen
|
|||||||
new_nbr->node_broadcast_interval_secs = node_broadcast_interval_secs;
|
new_nbr->node_broadcast_interval_secs = node_broadcast_interval_secs;
|
||||||
else // Assume the same broadcast interval as us for the neighbor if we don't know it
|
else // Assume the same broadcast interval as us for the neighbor if we don't know it
|
||||||
new_nbr->node_broadcast_interval_secs = moduleConfig.neighbor_info.update_interval;
|
new_nbr->node_broadcast_interval_secs = moduleConfig.neighbor_info.update_interval;
|
||||||
saveProtoForModule(); // Save the new neighbor
|
shouldSave = true; // Save the new neighbor upon next cleanup
|
||||||
return new_nbr;
|
return new_nbr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,6 +254,8 @@ bool NeighborInfoModule::saveProtoForModule()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
okay &= nodeDB->saveProto(neighborInfoConfigFile, meshtastic_NeighborInfo_size, &meshtastic_NeighborInfo_msg, &neighborState);
|
okay &= nodeDB->saveProto(neighborInfoConfigFile, meshtastic_NeighborInfo_size, &meshtastic_NeighborInfo_msg, &neighborState);
|
||||||
|
if (okay)
|
||||||
|
shouldSave = false;
|
||||||
|
|
||||||
return okay;
|
return okay;
|
||||||
}
|
}
|
||||||
@@ -20,6 +20,9 @@ class NeighborInfoModule : public ProtobufModule<meshtastic_NeighborInfo>, priva
|
|||||||
|
|
||||||
bool saveProtoForModule();
|
bool saveProtoForModule();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool shouldSave = false; // Whether we should save the neighbor info to flash
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Note: this holds our local info.
|
// Note: this holds our local info.
|
||||||
meshtastic_NeighborInfo neighborState;
|
meshtastic_NeighborInfo neighborState;
|
||||||
|
|||||||
@@ -112,6 +112,12 @@ void NimbleBluetooth::shutdown()
|
|||||||
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
||||||
pAdvertising->reset();
|
pAdvertising->reset();
|
||||||
pAdvertising->stop();
|
pAdvertising->stop();
|
||||||
|
|
||||||
|
#if defined(HELTEC_WIRELESS_PAPER) || defined(HELTEC_WIRELESS_PAPER_V1_0)
|
||||||
|
// Saving of ~1mA
|
||||||
|
// Probably applicable to other ESP32 boards - unverified
|
||||||
|
NimBLEDevice::deinit();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NimbleBluetooth::isActive()
|
bool NimbleBluetooth::isActive()
|
||||||
|
|||||||
@@ -135,6 +135,8 @@
|
|||||||
#define HW_VENDOR meshtastic_HardwareModel_CHATTER_2
|
#define HW_VENDOR meshtastic_HardwareModel_CHATTER_2
|
||||||
#elif defined(STATION_G2)
|
#elif defined(STATION_G2)
|
||||||
#define HW_VENDOR meshtastic_HardwareModel_STATION_G2
|
#define HW_VENDOR meshtastic_HardwareModel_STATION_G2
|
||||||
|
#elif defined(UNPHONE)
|
||||||
|
#define HW_VENDOR meshtastic_HardwareModel_UNPHONE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@@ -157,4 +159,4 @@
|
|||||||
#define LORA_CS 18
|
#define LORA_CS 18
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32 // FIXME: may be different on ESP32-S3, etc.
|
#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32 // FIXME: may be different on ESP32-S3, etc.
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "NRF52Bluetooth.h"
|
#include "NRF52Bluetooth.h"
|
||||||
#include "BluetoothCommon.h"
|
#include "BluetoothCommon.h"
|
||||||
|
#include "PowerFSM.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "mesh/PhoneAPI.h"
|
#include "mesh/PhoneAPI.h"
|
||||||
@@ -318,6 +319,7 @@ void NRF52Bluetooth::onConnectionSecured(uint16_t conn_handle)
|
|||||||
bool NRF52Bluetooth::onPairingPasskey(uint16_t conn_handle, uint8_t const passkey[6], bool match_request)
|
bool NRF52Bluetooth::onPairingPasskey(uint16_t conn_handle, uint8_t const passkey[6], bool match_request)
|
||||||
{
|
{
|
||||||
LOG_INFO("BLE pairing process started with passkey %.3s %.3s\n", passkey, passkey + 3);
|
LOG_INFO("BLE pairing process started with passkey %.3s %.3s\n", passkey, passkey + 3);
|
||||||
|
powerFSM.trigger(EVENT_BLUETOOTH_PAIR);
|
||||||
screen->startBluetoothPinScreen(configuredPasskey);
|
screen->startBluetoothPinScreen(configuredPasskey);
|
||||||
|
|
||||||
if (match_request) {
|
if (match_request) {
|
||||||
|
|||||||
@@ -147,6 +147,18 @@ void initDeepSleep()
|
|||||||
|
|
||||||
LOG_INFO("Booted, wake cause %d (boot count %d), reset_reason=%s\n", wakeCause, bootCount, reason);
|
LOG_INFO("Booted, wake cause %d (boot count %d), reset_reason=%s\n", wakeCause, bootCount, reason);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if SOC_RTCIO_HOLD_SUPPORTED
|
||||||
|
// If waking from sleep, release any and all RTC GPIOs
|
||||||
|
if (wakeCause != ESP_SLEEP_WAKEUP_UNDEFINED) {
|
||||||
|
LOG_DEBUG("Disabling any holds on RTC IO pads\n");
|
||||||
|
for (uint8_t i = 0; i <= 45; i++) {
|
||||||
|
if (rtc_gpio_is_valid_gpio((gpio_num_t)i))
|
||||||
|
rtc_gpio_hold_dis((gpio_num_t)i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,6 +277,17 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false)
|
|||||||
if (shouldLoraWake(msecToWake)) {
|
if (shouldLoraWake(msecToWake)) {
|
||||||
enableLoraInterrupt();
|
enableLoraInterrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HELTEC_WIRELESS_PAPER) || defined(HELTEC_WIRELESS_PAPER_V1_0) // Applicable to most ESP32 boards?
|
||||||
|
// Avoid leakage through button pin
|
||||||
|
pinMode(BUTTON_PIN, INPUT);
|
||||||
|
rtc_gpio_hold_en((gpio_num_t)BUTTON_PIN);
|
||||||
|
|
||||||
|
// LoRa CS (RADIO_NSS) needs to stay HIGH, even during deep sleep
|
||||||
|
pinMode(LORA_CS, OUTPUT);
|
||||||
|
digitalWrite(LORA_CS, HIGH);
|
||||||
|
rtc_gpio_hold_en((gpio_num_t)LORA_CS);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
cpuDeepSleep(msecToWake);
|
cpuDeepSleep(msecToWake);
|
||||||
}
|
}
|
||||||
@@ -312,13 +335,11 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
|
|||||||
// assert(esp_sleep_enable_uart_wakeup(0) == ESP_OK);
|
// assert(esp_sleep_enable_uart_wakeup(0) == ESP_OK);
|
||||||
#endif
|
#endif
|
||||||
#ifdef BUTTON_PIN
|
#ifdef BUTTON_PIN
|
||||||
#if SOC_PM_SUPPORT_EXT_WAKEUP
|
// The enableLoraInterrupt() method is using ext0_wakeup, so we are forced to use GPIO wakeup
|
||||||
esp_sleep_enable_ext0_wakeup((gpio_num_t)(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN),
|
gpio_num_t pin = (gpio_num_t)(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN);
|
||||||
LOW); // when user presses, this button goes low
|
gpio_intr_disable(pin);
|
||||||
#else
|
gpio_wakeup_enable(pin, GPIO_INTR_LOW_LEVEL);
|
||||||
esp_sleep_enable_gpio_wakeup();
|
esp_sleep_enable_gpio_wakeup();
|
||||||
gpio_wakeup_enable((gpio_num_t)BUTTON_PIN, GPIO_INTR_LOW_LEVEL);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
enableLoraInterrupt();
|
enableLoraInterrupt();
|
||||||
#ifdef PMU_IRQ
|
#ifdef PMU_IRQ
|
||||||
@@ -342,6 +363,12 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
|
|||||||
}
|
}
|
||||||
assert(res == ESP_OK);
|
assert(res == ESP_OK);
|
||||||
|
|
||||||
|
#ifdef BUTTON_PIN
|
||||||
|
gpio_wakeup_disable(pin);
|
||||||
|
// Would have thought that need gpio_intr_enable() here, but nope..
|
||||||
|
// Works fine without it; crashes with it.
|
||||||
|
#endif
|
||||||
|
|
||||||
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
|
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
|
||||||
#ifdef BUTTON_PIN
|
#ifdef BUTTON_PIN
|
||||||
if (cause == ESP_SLEEP_WAKEUP_GPIO) {
|
if (cause == ESP_SLEEP_WAKEUP_GPIO) {
|
||||||
@@ -406,4 +433,4 @@ void enableLoraInterrupt()
|
|||||||
gpio_wakeup_enable((gpio_num_t)RF95_IRQ, GPIO_INTR_HIGH_LEVEL); // RF95 interrupt, active high
|
gpio_wakeup_enable((gpio_num_t)RF95_IRQ, GPIO_INTR_HIGH_LEVEL); // RF95 interrupt, active high
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2,3 +2,4 @@
|
|||||||
#define CANNED_MESSAGE_MODULE_ENABLE 1
|
#define CANNED_MESSAGE_MODULE_ENABLE 1
|
||||||
#define HAS_GPS 1
|
#define HAS_GPS 1
|
||||||
#define MAX_NUM_NODES settingsMap[maxnodes]
|
#define MAX_NUM_NODES settingsMap[maxnodes]
|
||||||
|
#define RADIOLIB_GODMODE 1
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ debug_init_cmds =
|
|||||||
# add our variants files to the include and src paths
|
# add our variants files to the include and src paths
|
||||||
build_flags = ${rp2040_base.build_flags}
|
build_flags = ${rp2040_base.build_flags}
|
||||||
-DRPI_PICO
|
-DRPI_PICO
|
||||||
-Ivariants/rpipico_slowclock
|
-Ivariants/rpipico-slowclock
|
||||||
-DDEBUG_RP2040_PORT=Serial2
|
-DDEBUG_RP2040_PORT=Serial2
|
||||||
-DHW_SPI1_DEVICE
|
-DHW_SPI1_DEVICE
|
||||||
-L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m0plus"
|
-L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m0plus"
|
||||||
@@ -25,4 +25,4 @@ lib_deps =
|
|||||||
${rp2040_base.lib_deps}
|
${rp2040_base.lib_deps}
|
||||||
debug_build_flags = ${rp2040_base.build_flags}
|
debug_build_flags = ${rp2040_base.build_flags}
|
||||||
-g
|
-g
|
||||||
-DNO_USB
|
-DNO_USB
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
#define EXT_NOTIFY_OUT 22
|
#define EXT_NOTIFY_OUT 22
|
||||||
#define BUTTON_PIN 17
|
#define BUTTON_PIN 17
|
||||||
|
|
||||||
|
#define LED_PIN LED_BUILTIN
|
||||||
|
|
||||||
#define BATTERY_PIN 26
|
#define BATTERY_PIN 26
|
||||||
// ratio of voltage divider = 3.0 (R17=200k, R18=100k)
|
// ratio of voltage divider = 3.0 (R17=200k, R18=100k)
|
||||||
#define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic
|
#define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic
|
||||||
@@ -51,4 +53,4 @@
|
|||||||
#define SX126X_RESET LORA_RESET
|
#define SX126X_RESET LORA_RESET
|
||||||
#define SX126X_DIO2_AS_RF_SWITCH
|
#define SX126X_DIO2_AS_RF_SWITCH
|
||||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
16
variants/unphone/platformio.ini
Normal file
16
variants/unphone/platformio.ini
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
[env:unphone]
|
||||||
|
;build_type = debug ; to make it possible to step through our jtag debugger
|
||||||
|
extends = esp32s3_base
|
||||||
|
board_level = extra
|
||||||
|
board = unphone9
|
||||||
|
upload_speed = 921600
|
||||||
|
monitor_speed = 115200
|
||||||
|
monitor_filters = esp32_exception_decoder
|
||||||
|
|
||||||
|
build_flags = ${esp32_base.build_flags}
|
||||||
|
-D UNPHONE
|
||||||
|
-D BOARD_HAS_PSRAM
|
||||||
|
-I variants/unphone
|
||||||
|
|
||||||
|
lib_deps = ${esp32s3_base.lib_deps}
|
||||||
|
lovyan03/LovyanGFX@^1.1.8
|
||||||
61
variants/unphone/variant.h
Normal file
61
variants/unphone/variant.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#define SPI_SCK 39
|
||||||
|
#define SPI_MOSI 40
|
||||||
|
#define SPI_MISO 41
|
||||||
|
|
||||||
|
// We use the RFM95W LoRa module
|
||||||
|
#define USE_RF95
|
||||||
|
#define LORA_SCK SPI_SCK
|
||||||
|
#define LORA_MOSI SPI_MOSI
|
||||||
|
#define LORA_MISO SPI_MISO
|
||||||
|
#define LORA_CS 44
|
||||||
|
#define LORA_DIO0 10 // AKA LORA_IRQ
|
||||||
|
#define LORA_RESET 42
|
||||||
|
#define LORA_DIO1 11
|
||||||
|
#define LORA_DIO2 RADIOLIB_NC // Not really used
|
||||||
|
|
||||||
|
// HX8357 TFT LCD
|
||||||
|
#define HX8357_CS 48
|
||||||
|
#define HX8357_RS 47 // AKA DC
|
||||||
|
#define HX8357_RESET 46
|
||||||
|
#define HX8357_SCK SPI_SCK
|
||||||
|
#define HX8357_MOSI SPI_MOSI
|
||||||
|
#define HX8357_MISO SPI_MISO
|
||||||
|
#define HX8357_BUSY -1
|
||||||
|
#define HX8357_SPI_HOST SPI2_HOST
|
||||||
|
#define SPI_FREQUENCY 40000000
|
||||||
|
#define SPI_READ_FREQUENCY 16000000
|
||||||
|
#define TFT_HEIGHT 480
|
||||||
|
#define TFT_WIDTH 320
|
||||||
|
#define TFT_OFFSET_X 0
|
||||||
|
#define TFT_OFFSET_Y 0
|
||||||
|
#define TFT_OFFSET_ROTATION 6 // the unPhone's screen is wired unusually, 0 is typical value here
|
||||||
|
#define TFT_INVERT false
|
||||||
|
#define SCREEN_ROTATE true
|
||||||
|
#define SCREEN_TRANSITION_FRAMERATE 5
|
||||||
|
|
||||||
|
#define HAS_TOUCHSCREEN 1
|
||||||
|
#define USE_XPT2046 1
|
||||||
|
#define TOUCH_CS 38
|
||||||
|
|
||||||
|
#define HAS_GPS 0 // the unphone doesn't have a gps module
|
||||||
|
#undef GPS_RX_PIN
|
||||||
|
#undef GPS_TX_PIN
|
||||||
|
|
||||||
|
#define HAS_SDCARD 1
|
||||||
|
#define SDCARD_CS 43
|
||||||
|
|
||||||
|
#define LED_PIN 13 // the red part of the RGB LED
|
||||||
|
#define LED_INVERTED 1
|
||||||
|
|
||||||
|
#define BUTTON_PIN 21 // Button 3 - square - top button in landscape mode
|
||||||
|
#define BUTTON_NEED_PULLUP // we do need a helping hand up
|
||||||
|
|
||||||
|
#define I2C_SDA 3 // I2C pins for this board
|
||||||
|
#define I2C_SCL 4
|
||||||
|
|
||||||
|
// ratio of voltage divider = 3.20 (R1=100k, R2=220k)
|
||||||
|
// #define ADC_MULTIPLIER 3.2
|
||||||
|
|
||||||
|
// #define BATTERY_PIN 13 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||||
|
// #define ADC_CHANNEL ADC2_GPIO13_CHANNEL
|
||||||
|
// #define BAT_MEASURE_ADC_UNIT 2
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
[VERSION]
|
[VERSION]
|
||||||
major = 2
|
major = 2
|
||||||
minor = 3
|
minor = 3
|
||||||
build = 3
|
build = 4
|
||||||
|
|||||||
Reference in New Issue
Block a user