From 33d2f78d21265cbf89386fe1bce306fb765479da Mon Sep 17 00:00:00 2001 From: Austin Date: Thu, 26 Dec 2024 13:59:26 -0500 Subject: [PATCH 01/16] meshtasticd-docker: simplify, add USB compose (#5662) --- .env.example | 4 ++ .github/workflows/build_docker.yml | 21 --------- Dockerfile | 70 +++++++++++++++--------------- docker-compose.yml | 29 +++++++++---- 4 files changed, 61 insertions(+), 63 deletions(-) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 000000000..72d95970a --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +# Absolute path to the local meshtastic config.yaml file +CONFIG_PATH=/path/to/meshtastic/config.yaml +# USB device to passthrough (`lsusb -t`: look for `ch341`) +USB_DEVICE=/dev/bus/usb/001/037 diff --git a/.github/workflows/build_docker.yml b/.github/workflows/build_docker.yml index bb5a394fd..13817a8cf 100644 --- a/.github/workflows/build_docker.yml +++ b/.github/workflows/build_docker.yml @@ -10,12 +10,6 @@ jobs: build-native: runs-on: ubuntu-latest steps: - - name: Install libs needed for native build - shell: bash - run: | - sudo apt-get update --fix-missing - sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev libusb-1.0-0-dev - - name: Checkout code uses: actions/checkout@v4 with: @@ -23,21 +17,6 @@ jobs: ref: ${{github.event.pull_request.head.ref}} repository: ${{github.event.pull_request.head.repo.full_name}} - - name: Upgrade python tools - shell: bash - run: | - python -m pip install --upgrade pip - pip install -U platformio adafruit-nrfutil - pip install -U meshtastic --pre - - - name: Upgrade platformio - shell: bash - run: | - pio upgrade - - - name: Build Native - run: bin/build-native.sh - - name: Get release version string run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT id: version diff --git a/Dockerfile b/Dockerfile index ca216e04b..f3b294a5b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,32 +1,29 @@ -FROM debian:bookworm-slim AS builder +# trunk-ignore-all(terrascan/AC_DOCKER_0002): Known terrascan issue +# trunk-ignore-all(hadolint/DL3008): Use latest version of apt packages for buildchain +# trunk-ignore-all(trivy/DS002): We must run as root for this container +# trunk-ignore-all(checkov/CKV_DOCKER_8): We must run as root for this container +# trunk-ignore-all(hadolint/DL3002): We must run as root for this container +FROM python:3.12-bookworm AS builder ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Etc/UTC -# http://bugs.python.org/issue19846 -# > At the moment, setting "LANG=C" on a Linux system *fundamentally breaks Python 3*, and that's not OK. -ENV LANG C.UTF-8 - -# Install build deps -USER root - -# 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 \ - libusb-1.0-0-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 +# Install Dependencies +ENV PIP_ROOT_USER_ACTION=ignore +RUN apt-get update && apt-get install --no-install-recommends -y wget g++ zip git ca-certificates \ + libgpiod-dev libyaml-cpp-dev libbluetooth-dev libi2c-dev \ + libusb-1.0-0-dev libulfius-dev liborcania-dev libssl-dev pkg-config && \ + apt-get clean && rm -rf /var/lib/apt/lists/* && \ + pip install --no-cache-dir -U platformio==6.1.16 && \ + mkdir /tmp/firmware +# Copy source code WORKDIR /tmp/firmware -RUN python3 -m venv /tmp/firmware -RUN bash -o pipefail -c "source bin/activate; pip3 install --no-cache-dir -U platformio==6.1.15" -# 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 bash -o pipefail -c "source ./bin/activate && bash ./bin/build-native.sh" -RUN cp "/tmp/firmware/release/meshtasticd_linux_$(uname -m)" "/tmp/firmware/release/meshtasticd" +COPY . /tmp/firmware + +# Build +RUN bash ./bin/build-native.sh && \ + cp "/tmp/firmware/release/meshtasticd_linux_$(uname -m)" "/tmp/firmware/release/meshtasticd" ##### PRODUCTION BUILD ############# @@ -35,20 +32,25 @@ 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 libusb-1.0-0-dev liborcania2.3 libssl3 && \ - apt-get clean && rm -rf /var/lib/apt/lists/* +# nosemgrep: dockerfile.security.last-user-is-root.last-user-is-root +USER root -RUN groupadd -g 1000 mesh && useradd -ml -u 1000 -g 1000 mesh -USER mesh +RUN apt-get update && apt-get --no-install-recommends -y install libc-bin libc6 libgpiod2 libyaml-cpp0.7 libi2c0 libulfius2.7 libusb-1.0-0-dev liborcania2.3 libssl3 && \ + apt-get clean && rm -rf /var/lib/apt/lists/* \ + && mkdir -p /var/lib/meshtasticd \ + && mkdir -p /etc/meshtasticd/config.d -WORKDIR /home/mesh -COPY --from=builder /tmp/firmware/release/meshtasticd /home/mesh/ +# Fetch compiled binary from the builder +COPY --from=builder /tmp/firmware/release/meshtasticd /usr/sbin/ +# Copy config templates +COPY ./bin/config.d /etc/meshtasticd/available.d -RUN mkdir data -VOLUME /home/mesh/data +WORKDIR /var/lib/meshtasticd +VOLUME /var/lib/meshtasticd -CMD [ "sh", "-cx", "./meshtasticd -d /home/mesh/data --hwid=${HWID:-$RANDOM}" ] +# Expose Meshtastic TCP API port from the host +EXPOSE 4403 + +CMD [ "sh", "-cx", "meshtasticd -d /var/lib/meshtasticd" ] HEALTHCHECK NONE \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 82f2647e8..4aac318c5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,13 +1,26 @@ -version: "3.7" +# USB-Based Meshtastic container-node! + +# Copy .env.example to .env and set the USB_DEVICE and CONFIG_PATH variables services: meshtastic-node: build: . - deploy: - mode: replicated - replicas: 4 - networks: - - mesh + container_name: meshtasticd -networks: - mesh: + # Pass USB device through to the container + devices: + - "${USB_DEVICE}" + + # Mount local config file and named volume for data persistence + volumes: + - "${CONFIG_PATH}:/etc/meshtasticd/config.yaml:ro" + - meshtastic_data:/var/lib/meshtasticd + + # Forward the container’s port 4403 to the host + ports: + - 4403:4403 + + restart: unless-stopped + +volumes: + meshtastic_data: From b12ac6d564be4558047231d5ad946a908dfbbd7f Mon Sep 17 00:00:00 2001 From: Austin Date: Thu, 26 Dec 2024 14:00:50 -0500 Subject: [PATCH 02/16] meshtasticd-docker: Alpine container (#5659) --- alpine.Dockerfile | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 alpine.Dockerfile diff --git a/alpine.Dockerfile b/alpine.Dockerfile new file mode 100644 index 000000000..115602b3b --- /dev/null +++ b/alpine.Dockerfile @@ -0,0 +1,42 @@ +# trunk-ignore-all(trivy/DS002): We must run as root for this container +# trunk-ignore-all(checkov/CKV_DOCKER_8): We must run as root for this container +# trunk-ignore-all(hadolint/DL3002): We must run as root for this container + +FROM python:3.12-alpine3.21 AS builder + +ENV PIP_ROOT_USER_ACTION=ignore +RUN apk add bash g++ libstdc++-dev linux-headers zip git ca-certificates libgpiod-dev yaml-cpp-dev bluez-dev \ + libusb-dev i2c-tools-dev openssl-dev pkgconf argp-standalone && \ + pip install --no-cache-dir -U platformio==6.1.16 && \ + mkdir /tmp/firmware + +WORKDIR /tmp/firmware +COPY . /tmp/firmware + +# Create small package (no debugging symbols) +# Add `argp` for musl +ENV PLATFORMIO_BUILD_FLAGS="-Os -ffunction-sections -fdata-sections -Wl,--gc-sections -largp" + +RUN bash ./bin/build-native.sh && \ + cp "/tmp/firmware/release/meshtasticd_linux_$(uname -m)" "/tmp/firmware/release/meshtasticd" + +# ##### PRODUCTION BUILD ############# + +FROM alpine:3.21 + +# nosemgrep: dockerfile.security.last-user-is-root.last-user-is-root +USER root + +RUN apk add libstdc++ libgpiod yaml-cpp libusb i2c-tools \ + && mkdir -p /var/lib/meshtasticd \ + && mkdir -p /etc/meshtasticd/config.d +COPY --from=builder /tmp/firmware/release/meshtasticd /usr/sbin/ + +WORKDIR /var/lib/meshtasticd +VOLUME /var/lib/meshtasticd + +EXPOSE 4403 + +CMD [ "sh", "-cx", "meshtasticd --fsdir=/var/lib/meshtasticd" ] + +HEALTHCHECK NONE \ No newline at end of file From b1d25ac7b72045a82c3c1820a4bc878e9c9e4032 Mon Sep 17 00:00:00 2001 From: Tavis Date: Thu, 26 Dec 2024 15:08:31 -0800 Subject: [PATCH 03/16] fix for nrf52 lfs assert boot loop (#5670) * fix for nrf52 lfs assert boot loop * guard format in ifdef FSCom block * add ifndef portduino for format call --- src/FSCommon.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/FSCommon.cpp b/src/FSCommon.cpp index 6cd17dac8..df46c1941 100644 --- a/src/FSCommon.cpp +++ b/src/FSCommon.cpp @@ -55,6 +55,15 @@ extern "C" void lfs_assert(const char *reason) { LOG_ERROR("LFS assert: %s", reason); lfs_assert_failed = true; + +#ifndef ARCH_PORTDUINO +#ifdef FSCom + // CORRUPTED FILESYSTEM. This causes bootloop so + // might as well try formatting now. + LOG_ERROR("Trying FSCom.format()"); + FSCom.format(); +#endif +#endif } /** From cd198fcf3f0f608cfbe2ee34ad08fba7c85a2af1 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Fri, 27 Dec 2024 10:46:21 +1100 Subject: [PATCH 04/16] cherry-pick: device-ui persistency (#5570) * device-ui persistency * review update --------- Co-authored-by: mverch67 --- src/mesh/NodeDB.cpp | 8 ++++++++ src/mesh/NodeDB.h | 1 + src/mesh/PhoneAPI.cpp | 11 +++++++++-- src/mesh/PhoneAPI.h | 1 + src/modules/AdminModule.cpp | 30 ++++++++++++++++++++++++++++-- src/modules/AdminModule.h | 2 ++ 6 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 2af85e4f5..54ea570ff 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -57,6 +57,7 @@ NodeDB *nodeDB = nullptr; EXT_RAM_BSS_ATTR meshtastic_DeviceState devicestate; meshtastic_MyNodeInfo &myNodeInfo = devicestate.my_node; meshtastic_LocalConfig config; +meshtastic_DeviceUIConfig uiconfig{.screen_brightness = 153, .screen_timeout = 30}; meshtastic_LocalModuleConfig moduleConfig; meshtastic_ChannelFile channelFile; @@ -895,6 +896,7 @@ void NodeDB::pickNewNodeNum() static const char *prefFileName = "/prefs/db.proto"; static const char *configFileName = "/prefs/config.proto"; +static const char *uiconfigFileName = "/prefs/uiconfig.proto"; static const char *moduleConfigFileName = "/prefs/module.proto"; static const char *channelFileName = "/prefs/channels.proto"; @@ -1054,6 +1056,12 @@ void NodeDB::loadFromDisk() } } + state = loadProto(uiconfigFileName, meshtastic_DeviceUIConfig_size, sizeof(meshtastic_DeviceUIConfig), + &meshtastic_DeviceUIConfig_msg, &uiconfig); + if (state == LoadFileResult::LOAD_SUCCESS) { + LOG_INFO("Loaded UIConfig\n"); + } + // 2.4.X - configuration migration to update new default intervals if (moduleConfig.version < 23) { LOG_DEBUG("ModuleConfig version %d is stale, upgrading to new default intervals", moduleConfig.version); diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index 7e51a1240..c8c0d3170 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -29,6 +29,7 @@ extern meshtastic_DeviceState devicestate; extern meshtastic_ChannelFile channelFile; extern meshtastic_MyNodeInfo &myNodeInfo; extern meshtastic_LocalConfig config; +extern meshtastic_DeviceUIConfig uiconfig; extern meshtastic_LocalModuleConfig moduleConfig; extern meshtastic_User &owner; extern meshtastic_Position localPosition; diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index f49718c5e..c665c60bb 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -188,7 +188,6 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf) case STATE_SEND_NOTHING: LOG_DEBUG("FromRadio=STATE_SEND_NOTHING"); break; - case STATE_SEND_MY_INFO: LOG_DEBUG("FromRadio=STATE_SEND_MY_INFO"); // If the user has specified they don't want our node to share its location, make sure to tell the phone @@ -196,11 +195,18 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf) fromRadioScratch.which_payload_variant = meshtastic_FromRadio_my_info_tag; strncpy(myNodeInfo.pio_env, optstr(APP_ENV), sizeof(myNodeInfo.pio_env)); fromRadioScratch.my_info = myNodeInfo; - state = STATE_SEND_OWN_NODEINFO; + state = STATE_SEND_UIDATA; service->refreshLocalMeshNode(); // Update my NodeInfo because the client will be asking for it soon. break; + case STATE_SEND_UIDATA: + LOG_INFO("getFromRadio=STATE_SEND_UIDATA\n"); + fromRadioScratch.which_payload_variant = meshtastic_FromRadio_deviceuiConfig_tag; + fromRadioScratch.deviceuiConfig = uiconfig; + state = STATE_SEND_OWN_NODEINFO; + break; + case STATE_SEND_OWN_NODEINFO: { LOG_DEBUG("Send My NodeInfo"); auto us = nodeDB->readNextMeshNode(readIndex); @@ -518,6 +524,7 @@ bool PhoneAPI::available() case STATE_SEND_NOTHING: return false; case STATE_SEND_MY_INFO: + case STATE_SEND_UIDATA: case STATE_SEND_CHANNELS: case STATE_SEND_CONFIG: case STATE_SEND_MODULECONFIG: diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h index 3247fee5c..31538a0ab 100644 --- a/src/mesh/PhoneAPI.h +++ b/src/mesh/PhoneAPI.h @@ -34,6 +34,7 @@ class PhoneAPI { enum State { STATE_SEND_NOTHING, // Initial state, don't send anything until the client starts asking for config + STATE_SEND_UIDATA, // send stored data for device-ui STATE_SEND_MY_INFO, // send our my info record STATE_SEND_OWN_NODEINFO, STATE_SEND_METADATA, diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index 69b2c0a38..7f737a205 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -175,6 +175,12 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta LOG_INFO("Client set ham mode"); handleSetHamMode(r->set_ham_mode); break; + case meshtastic_AdminMessage_get_ui_config_request_tag: { + LOG_INFO("Client is getting device-ui config\n"); + handleGetDeviceUIConfig(mp); + handled = true; + break; + } /** * Other @@ -234,6 +240,11 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta reboot(DEFAULT_REBOOT_SECONDS); break; } + case meshtastic_AdminMessage_store_ui_config_tag: { + LOG_INFO("Storing device-ui config\n"); + handleStoreDeviceUIConfig(r->store_ui_config); + break; + } case meshtastic_AdminMessage_begin_edit_settings_tag: { LOG_INFO("Begin transaction for editing settings"); hasOpenEditTransaction = true; @@ -995,6 +1006,14 @@ void AdminModule::handleGetChannel(const meshtastic_MeshPacket &req, uint32_t ch } } +void AdminModule::handleGetDeviceUIConfig(const meshtastic_MeshPacket &req) +{ + meshtastic_AdminMessage r = meshtastic_AdminMessage_init_default; + r.which_payload_variant = meshtastic_AdminMessage_get_ui_config_response_tag; + r.store_ui_config = uiconfig; + myReply = allocDataProtobuf(r); +} + void AdminModule::reboot(int32_t seconds) { LOG_INFO("Reboot in %d seconds", seconds); @@ -1015,6 +1034,11 @@ void AdminModule::saveChanges(int saveWhat, bool shouldReboot) } } +void AdminModule::handleStoreDeviceUIConfig(const meshtastic_DeviceUIConfig &uicfg) +{ + nodeDB->saveProto("/prefs/uiconfig.proto", meshtastic_DeviceUIConfig_size, &meshtastic_DeviceUIConfig_msg, &uicfg); +} + void AdminModule::handleSetHamMode(const meshtastic_HamParameters &p) { // Set call sign and override lora limitations for licensed use @@ -1081,7 +1105,8 @@ bool AdminModule::messageIsResponse(const meshtastic_AdminMessage *r) r->which_payload_variant == meshtastic_AdminMessage_get_ringtone_response_tag || r->which_payload_variant == meshtastic_AdminMessage_get_device_connection_status_response_tag || r->which_payload_variant == meshtastic_AdminMessage_get_node_remote_hardware_pins_response_tag || - r->which_payload_variant == meshtastic_NodeRemoteHardwarePinsResponse_node_remote_hardware_pins_tag) + r->which_payload_variant == meshtastic_NodeRemoteHardwarePinsResponse_node_remote_hardware_pins_tag || + r->which_payload_variant == meshtastic_AdminMessage_get_ui_config_response_tag) return true; else return false; @@ -1097,7 +1122,8 @@ bool AdminModule::messageIsRequest(const meshtastic_AdminMessage *r) r->which_payload_variant == meshtastic_AdminMessage_get_device_metadata_request_tag || r->which_payload_variant == meshtastic_AdminMessage_get_ringtone_request_tag || r->which_payload_variant == meshtastic_AdminMessage_get_device_connection_status_request_tag || - r->which_payload_variant == meshtastic_AdminMessage_get_node_remote_hardware_pins_request_tag) + r->which_payload_variant == meshtastic_AdminMessage_get_node_remote_hardware_pins_request_tag || + r->which_payload_variant == meshtastic_AdminMessage_get_ui_config_request_tag) return true; else return false; diff --git a/src/modules/AdminModule.h b/src/modules/AdminModule.h index b99e86707..ee2ebfd96 100644 --- a/src/modules/AdminModule.h +++ b/src/modules/AdminModule.h @@ -43,6 +43,7 @@ class AdminModule : public ProtobufModule, public Obser void handleGetDeviceMetadata(const meshtastic_MeshPacket &req); void handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &req); void handleGetNodeRemoteHardwarePins(const meshtastic_MeshPacket &req); + void handleGetDeviceUIConfig(const meshtastic_MeshPacket &req); /** * Setters */ @@ -52,6 +53,7 @@ class AdminModule : public ProtobufModule, public Obser void handleSetModuleConfig(const meshtastic_ModuleConfig &c); void handleSetChannel(); void handleSetHamMode(const meshtastic_HamParameters &req); + void handleStoreDeviceUIConfig(const meshtastic_DeviceUIConfig &uicfg); void reboot(int32_t seconds); void setPassKey(meshtastic_AdminMessage *res); From 8f8e304216c3b1af259066805f3b4337ca213d68 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 26 Dec 2024 18:58:26 -0600 Subject: [PATCH 05/16] Add packet length to printPacket() (#5672) --- src/mesh/RadioInterface.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 5161ac41f..5a18ab0c0 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -313,6 +313,7 @@ void printPacket(const char *prefix, const meshtastic_MeshPacket *p) out += DEBUG_PORT.mt_sprintf(" failId=%08x", s.ackVariant.fail_id); */ } else { out += " encrypted"; + out += DEBUG_PORT.mt_sprintf(" len=%d", p->encrypted.size + sizeof(PacketHeader)); } if (p->rx_time != 0) @@ -622,4 +623,4 @@ size_t RadioInterface::beginSending(meshtastic_MeshPacket *p) sendingPacket = p; return p->encrypted.size + sizeof(PacketHeader); -} \ No newline at end of file +} From ed39d14c8525130b9ef86cae03c575484a18e6cf Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Fri, 27 Dec 2024 18:01:02 +1100 Subject: [PATCH 06/16] Remove remaining \n from log lines. (#5675) --- src/detect/ScanI2CTwoWire.cpp | 6 +++--- src/input/MPR121Keyboard.cpp | 2 +- src/input/TouchScreenBase.cpp | 6 +++--- src/mesh/NodeDB.cpp | 2 +- src/mesh/PhoneAPI.cpp | 4 ++-- src/modules/AdminModule.cpp | 8 ++++---- src/motion/QMA6100PSensor.cpp | 6 +++--- variants/rak2560/RAK9154Sensor.cpp | 18 +++++++++--------- 8 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index 6e695c22f..a786f874d 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -458,11 +458,11 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) i2cBus->endTransmission(); len = i2cBus->readBytes(info, 5); if (len == 5 && memcmp(expectedInfo, info, len) == 0) { - LOG_INFO("NXP SE050 crypto chip found\n"); + LOG_INFO("NXP SE050 crypto chip found"); type = NXP_SE050; } else { - LOG_INFO("FT6336U touchscreen found\n"); + LOG_INFO("FT6336U touchscreen found"); type = FT6336U; } break; @@ -510,4 +510,4 @@ void ScanI2CTwoWire::logFoundDevice(const char *device, uint8_t address) { LOG_INFO("%s found at address 0x%x", device, address); } -#endif \ No newline at end of file +#endif diff --git a/src/input/MPR121Keyboard.cpp b/src/input/MPR121Keyboard.cpp index 078d80272..f35b942b1 100644 --- a/src/input/MPR121Keyboard.cpp +++ b/src/input/MPR121Keyboard.cpp @@ -87,7 +87,7 @@ uint8_t MPR121_KeyMap[12] = {2, 5, 8, 11, 1, 4, 7, 10, 0, 3, 6, 9}; MPR121Keyboard::MPR121Keyboard() : m_wire(nullptr), m_addr(0), readCallback(nullptr), writeCallback(nullptr) { - // LOG_DEBUG("MPR121 @ %02x\n", m_addr); + // LOG_DEBUG("MPR121 @ %02x", m_addr); state = Init; last_key = -1; last_tap = 0L; diff --git a/src/input/TouchScreenBase.cpp b/src/input/TouchScreenBase.cpp index a63203362..d2f7b54f8 100644 --- a/src/input/TouchScreenBase.cpp +++ b/src/input/TouchScreenBase.cpp @@ -113,13 +113,13 @@ int32_t TouchScreenBase::runOnce() if (_tapped) { _tapped = false; e.touchEvent = static_cast(TOUCH_ACTION_TAP); - LOG_DEBUG("action TAP(%d/%d)\n", _last_x, _last_y); + LOG_DEBUG("action TAP(%d/%d)", _last_x, _last_y); } } else { if (_tapped && (time_t(millis()) - _start) > TIME_LONG_PRESS - 50) { _tapped = false; e.touchEvent = static_cast(TOUCH_ACTION_TAP); - LOG_DEBUG("action TAP(%d/%d)\n", _last_x, _last_y); + LOG_DEBUG("action TAP(%d/%d)", _last_x, _last_y); } } #else @@ -156,4 +156,4 @@ void TouchScreenBase::hapticFeedback() drv.setWaveform(1, 0); // end waveform drv.go(); #endif -} \ No newline at end of file +} diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 54ea570ff..9dbe92b7c 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -1059,7 +1059,7 @@ void NodeDB::loadFromDisk() state = loadProto(uiconfigFileName, meshtastic_DeviceUIConfig_size, sizeof(meshtastic_DeviceUIConfig), &meshtastic_DeviceUIConfig_msg, &uiconfig); if (state == LoadFileResult::LOAD_SUCCESS) { - LOG_INFO("Loaded UIConfig\n"); + LOG_INFO("Loaded UIConfig"); } // 2.4.X - configuration migration to update new default intervals diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index c665c60bb..36045bcf9 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -201,7 +201,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf) break; case STATE_SEND_UIDATA: - LOG_INFO("getFromRadio=STATE_SEND_UIDATA\n"); + LOG_INFO("getFromRadio=STATE_SEND_UIDATA"); fromRadioScratch.which_payload_variant = meshtastic_FromRadio_deviceuiConfig_tag; fromRadioScratch.deviceuiConfig = uiconfig; state = STATE_SEND_OWN_NODEINFO; @@ -664,4 +664,4 @@ int PhoneAPI::onNotify(uint32_t newValue) } return timeout ? -1 : 0; // If we timed out, MeshService should stop iterating through observers as we just removed one -} \ No newline at end of file +} diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index 7f737a205..6fd2952c0 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -176,7 +176,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta handleSetHamMode(r->set_ham_mode); break; case meshtastic_AdminMessage_get_ui_config_request_tag: { - LOG_INFO("Client is getting device-ui config\n"); + LOG_INFO("Client is getting device-ui config"); handleGetDeviceUIConfig(mp); handled = true; break; @@ -241,7 +241,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta break; } case meshtastic_AdminMessage_store_ui_config_tag: { - LOG_INFO("Storing device-ui config\n"); + LOG_INFO("Storing device-ui config"); handleStoreDeviceUIConfig(r->store_ui_config); break; } @@ -488,7 +488,7 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c) IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_ROUTER, meshtastic_Config_DeviceConfig_Role_REPEATER)) { config.device.rebroadcast_mode = meshtastic_Config_DeviceConfig_RebroadcastMode_ALL; - const char *warning = "Rebroadcast mode can't be set to NONE for a router or repeater\n"; + const char *warning = "Rebroadcast mode can't be set to NONE for a router or repeater"; LOG_WARN(warning); sendWarning(warning); } @@ -1149,4 +1149,4 @@ void disableBluetooth() nrf52Bluetooth->shutdown(); #endif #endif -} \ No newline at end of file +} diff --git a/src/motion/QMA6100PSensor.cpp b/src/motion/QMA6100PSensor.cpp index 4c5bc14d2..eb81e16c7 100644 --- a/src/motion/QMA6100PSensor.cpp +++ b/src/motion/QMA6100PSensor.cpp @@ -88,13 +88,13 @@ bool QMA6100PSingleton::init(ScanI2C::FoundDevice device) bool status = begin(device.address.address, &Wire); #endif if (status != true) { - LOG_WARN("QMA6100P init begin failed\n"); + LOG_WARN("QMA6100P init begin failed"); return false; } delay(20); // SW reset to make sure the device starts in a known state if (softwareReset() != true) { - LOG_WARN("QMA6100P init reset failed\n"); + LOG_WARN("QMA6100P init reset failed"); return false; } delay(20); @@ -180,4 +180,4 @@ bool QMA6100PSingleton::setWakeOnMotion() return true; } -#endif \ No newline at end of file +#endif diff --git a/variants/rak2560/RAK9154Sensor.cpp b/variants/rak2560/RAK9154Sensor.cpp index 9f660947e..43affe581 100644 --- a/variants/rak2560/RAK9154Sensor.cpp +++ b/variants/rak2560/RAK9154Sensor.cpp @@ -37,11 +37,11 @@ static void onewire_evt(const uint8_t pid, const uint8_t sid, const SNHUBAPI_EVT break; case SNHUBAPI_EVT_ADD_SID: - // LOG_INFO("+ADD:SID:[%02x]\r\n", msg[0]); + // LOG_INFO("+ADD:SID:[%02x]", msg[0]); break; case SNHUBAPI_EVT_ADD_PID: - // LOG_INFO("+ADD:PID:[%02x]\r\n", msg[0]); + // LOG_INFO("+ADD:PID:[%02x]", msg[0]); #ifdef BOOT_DATA_REQ provision = msg[0]; #endif @@ -55,12 +55,12 @@ static void onewire_evt(const uint8_t pid, const uint8_t sid, const SNHUBAPI_EVT case SNHUBAPI_EVT_SDATA_REQ: - // LOG_INFO("+EVT:PID[%02x],IPSO[%02x]\r\n",pid,msg[0]); + // LOG_INFO("+EVT:PID[%02x],IPSO[%02x]",pid,msg[0]); // for( uint16_t i=1; i 0) ? true : false; } -#endif // HAS_RAKPROT \ No newline at end of file +#endif // HAS_RAKPROT From ae93f3fa3f617dcffa118a930fcac2d106b466b6 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Fri, 27 Dec 2024 22:12:33 +1100 Subject: [PATCH 07/16] TFT branch - minor cherry picks (#5676) * fix missing include * fix request, add handled --------- Co-authored-by: mverch67 --- src/mesh/http/ContentHelper.h | 1 + src/modules/AdminModule.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mesh/http/ContentHelper.h b/src/mesh/http/ContentHelper.h index a80c39f47..e5d3a2f57 100644 --- a/src/mesh/http/ContentHelper.h +++ b/src/mesh/http/ContentHelper.h @@ -1,5 +1,6 @@ #include #include +#include #define BoolToString(x) ((x) ? "true" : "false") diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index 6fd2952c0..6b19f04e3 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -243,6 +243,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta case meshtastic_AdminMessage_store_ui_config_tag: { LOG_INFO("Storing device-ui config"); handleStoreDeviceUIConfig(r->store_ui_config); + handled = true; break; } case meshtastic_AdminMessage_begin_edit_settings_tag: { @@ -1010,7 +1011,7 @@ void AdminModule::handleGetDeviceUIConfig(const meshtastic_MeshPacket &req) { meshtastic_AdminMessage r = meshtastic_AdminMessage_init_default; r.which_payload_variant = meshtastic_AdminMessage_get_ui_config_response_tag; - r.store_ui_config = uiconfig; + r.get_ui_config_response = uiconfig; myReply = allocDataProtobuf(r); } From 26a4d6c87a961aae5d5a1d9c3c2d2700dc248547 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Fri, 27 Dec 2024 22:13:45 +1100 Subject: [PATCH 08/16] Cherry-pick: Mesh-tab (#5674) * mesh-tab targets * update meshtab voltage divider * fix DIO1 wakeup * update mesh-tab tft configs * update mesh-tab ini * rotation fix; added ST7789 3.2" display * mesh-tab touch updates * mesh-tab: enable alert message menu * mesh-tab rotation upside-down * use MESH_TAB hardware model definition * use board definition for mesh-tab --------- Co-authored-by: mverch67 --- src/platform/esp32/architecture.h | 2 + variants/diy/platformio.ini | 70 -------- variants/mesh-tab/pins_arduino.h | 65 +++++++ variants/mesh-tab/platformio.ini | 233 ++++++++++++++++++++++++++ variants/{diy => }/mesh-tab/variant.h | 23 ++- 5 files changed, 316 insertions(+), 77 deletions(-) create mode 100644 variants/mesh-tab/pins_arduino.h create mode 100644 variants/mesh-tab/platformio.ini rename variants/{diy => }/mesh-tab/variant.h (67%) diff --git a/src/platform/esp32/architecture.h b/src/platform/esp32/architecture.h index 1a274aa28..742b295b5 100644 --- a/src/platform/esp32/architecture.h +++ b/src/platform/esp32/architecture.h @@ -174,6 +174,8 @@ #define HW_VENDOR meshtastic_HardwareModel_SENSECAP_INDICATOR #elif defined(SEEED_XIAO_S3) #define HW_VENDOR meshtastic_HardwareModel_SEEED_XIAO_S3 +#elif defined(MESH_TAB) +#define HW_VENDOR meshtastic_HardwareModel_MESH_TAB #endif // ----------------------------------------------------------------------------- diff --git a/variants/diy/platformio.ini b/variants/diy/platformio.ini index b60d46996..b7f3f6a92 100644 --- a/variants/diy/platformio.ini +++ b/variants/diy/platformio.ini @@ -87,73 +87,3 @@ build_flags = -D ARDUINO_USB_MODE=0 -D ARDUINO_USB_CDC_ON_BOOT=1 -I variants/diy/t-energy-s3_e22 - -; esp32-s3 + ra-sh01 lora + 3.2" ILI9143 -[env:mesh-tab] -extends = esp32s3_base -board = um_feathers3 -board_level = extra -board_upload.flash_size = 16MB -board_build.partitions = default_16MB.csv -upload_protocol = esptool -build_flags = ${esp32s3_base.build_flags} - -D MESH_TAB - -D PRIVATE_HW - -D CONFIG_ARDUHAL_ESP_LOG - -D CONFIG_ARDUHAL_LOG_COLORS=1 - -D CONFIG_DISABLE_HAL_LOCKS=1 ; "feels" to be a bit more stable without locks - -D MESHTASTIC_EXCLUDE_CANNEDMESSAGES=1 - -D MESHTASTIC_EXCLUDE_INPUTBROKER=1 - -D MESHTASTIC_EXCLUDE_BLUETOOTH=1 - -D MESHTASTIC_EXCLUDE_WEBSERVER=1 - -D LV_LVGL_H_INCLUDE_SIMPLE - -D LV_CONF_INCLUDE_SIMPLE - -D LV_COMP_CONF_INCLUDE_SIMPLE - -D LV_USE_SYSMON=0 - -D LV_USE_PROFILER=0 - -D LV_USE_PERF_MONITOR=0 - -D LV_USE_MEM_MONITOR=0 - -D LV_USE_LOG=0 - -D LV_BUILD_TEST=0 - -D USE_LOG_DEBUG - -D LOG_DEBUG_INC=\"DebugConfiguration.h\" - -D RADIOLIB_SPI_PARANOID=0 - -D MAX_NUM_NODES=250 - -D MAX_THREADS=40 - -D HAS_SCREEN=0 - -D HAS_TFT=1 - -D RAM_SIZE=1024 - -D LGFX_DRIVER_TEMPLATE - -D LGFX_DRIVER=LGFX_GENERIC - -D LGFX_PANEL=ILI9341 - -D LGFX_OFFSET_ROTATION=1 - -D LGFX_TOUCH=XPT2046 - -D LGFX_PIN_SCK=12 - -D LGFX_PIN_MOSI=13 - -D LGFX_PIN_MISO=11 - -D LGFX_PIN_DC=16 - -D LGFX_PIN_CS=10 - -D LGFX_PIN_RST=-1 - -D LGFX_PIN_BL=42 - -D LGFX_TOUCH_INT=41 - -D LGFX_TOUCH_CS=7 - -D LGFX_TOUCH_CLK=12 - -D LGFX_TOUCH_DO=11 - -D LGFX_TOUCH_DIN=13 - -D LGFX_TOUCH_X_MIN=300 - -D LGFX_TOUCH_X_MAX=3900 - -D LGFX_TOUCH_Y_MIN=400 - -D LGFX_TOUCH_Y_MAX=3900 - -D VIEW_320x240 - -D USE_PACKET_API - -I lib/device-ui/generated/ui_320x240 - -I variants/diy/mesh-tab -build_src_filter = ${esp32_base.build_src_filter} - +<../lib/device-ui/generated/ui_320x240> - +<../lib/device-ui/resources> - +<../lib/device-ui/locale> - +<../lib/device-ui/source> -lib_deps = ${esp32_base.lib_deps} - lovyan03/LovyanGFX@^1.1.16 - earlephilhower/ESP8266Audio@^1.9.7 - earlephilhower/ESP8266SAM@^1.0.1 \ No newline at end of file diff --git a/variants/mesh-tab/pins_arduino.h b/variants/mesh-tab/pins_arduino.h new file mode 100644 index 000000000..c995f638c --- /dev/null +++ b/variants/mesh-tab/pins_arduino.h @@ -0,0 +1,65 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include "soc/soc_caps.h" +#include + +#define USB_VID 0x303A +#define USB_PID 0x80D6 + +static const uint8_t TX = 43; +static const uint8_t RX = 44; + +static const uint8_t SDA = 8; +static const uint8_t SCL = 9; + +static const uint8_t SS = 5; +static const uint8_t MOSI = 35; +static const uint8_t MISO = 37; +static const uint8_t SDO = 35; +static const uint8_t SDI = 37; +static const uint8_t SCK = 36; + +static const uint8_t A0 = 1; +static const uint8_t A1 = 2; +static const uint8_t A2 = 3; +static const uint8_t A3 = 4; +static const uint8_t A4 = 5; +static const uint8_t A5 = 6; +static const uint8_t A6 = 7; +static const uint8_t A7 = 8; +static const uint8_t A8 = 9; +static const uint8_t A9 = 10; +static const uint8_t A10 = 11; +static const uint8_t A11 = 12; +static const uint8_t A12 = 13; + +static const uint8_t T1 = 1; +static const uint8_t T3 = 3; +static const uint8_t T5 = 5; +static const uint8_t T6 = 6; +static const uint8_t T7 = 7; +static const uint8_t T8 = 8; +static const uint8_t T9 = 9; +static const uint8_t T10 = 10; +static const uint8_t T11 = 11; +static const uint8_t T12 = 12; +static const uint8_t T14 = 14; + +static const uint8_t VBAT_SENSE = 2; +static const uint8_t VBUS_SENSE = 34; + +// User LED +#define LED_BUILTIN 13 +#define BUILTIN_LED LED_BUILTIN // backward compatibility + +static const uint8_t RGB_DATA = 40; +// RGB_BUILTIN and RGB_BRIGHTNESS can be used in new Arduino API neopixelWrite() +#define RGB_BUILTIN (RGB_DATA + SOC_GPIO_PIN_COUNT) +#define RGB_BRIGHTNESS 64 + +static const uint8_t RGB_PWR = 39; +static const uint8_t LDO2 = 39; +static const uint8_t LED = 13; + +#endif /* Pins_Arduino_h */ diff --git a/variants/mesh-tab/platformio.ini b/variants/mesh-tab/platformio.ini new file mode 100644 index 000000000..26b072cde --- /dev/null +++ b/variants/mesh-tab/platformio.ini @@ -0,0 +1,233 @@ +; Base for Mesh-Tab device (esp32-s3 N16R2 + ra-sh01 lora) +; https://github.com/valzzu/Mesh-Tab +[mesh_tab_base] +extends = esp32s3_base +board = mesh-tab +board_level = extra +board_upload.flash_size = 16MB +board_build.partitions = default_16MB.csv +upload_protocol = esptool +build_flags = ${esp32s3_base.build_flags} + -D MESH_TAB + -D CONFIG_ARDUHAL_ESP_LOG + -D CONFIG_ARDUHAL_LOG_COLORS=1 + -D CONFIG_DISABLE_HAL_LOCKS=1 + -D MESHTASTIC_EXCLUDE_CANNEDMESSAGES=1 + -D MESHTASTIC_EXCLUDE_INPUTBROKER=1 + -D MESHTASTIC_EXCLUDE_BLUETOOTH=1 + -D MESHTASTIC_EXCLUDE_WEBSERVER=1 + -D LV_LVGL_H_INCLUDE_SIMPLE + -D LV_CONF_INCLUDE_SIMPLE + -D LV_COMP_CONF_INCLUDE_SIMPLE + -D LV_USE_SYSMON=0 + -D LV_USE_PROFILER=0 + -D LV_USE_PERF_MONITOR=0 + -D LV_USE_MEM_MONITOR=0 + -D LV_USE_LOG=0 + -D LV_BUILD_TEST=0 + -D USE_LOG_DEBUG + -D LOG_DEBUG_INC=\"DebugConfiguration.h\" + -D RADIOLIB_SPI_PARANOID=0 + -D MAX_NUM_NODES=250 + -D MAX_THREADS=40 + -D HAS_SCREEN=0 + -D HAS_TFT=1 + -D USE_PIN_BUZZER + -D RAM_SIZE=1024 + -D LGFX_DRIVER_TEMPLATE + -D LGFX_DRIVER=LGFX_GENERIC + -D LGFX_PIN_SCK=12 + -D LGFX_PIN_MOSI=13 + -D LGFX_PIN_MISO=11 + -D LGFX_PIN_DC=16 + -D LGFX_PIN_CS=10 + -D LGFX_PIN_RST=-1 + -D LGFX_PIN_BL=42 + -D LGFX_TOUCH_INT=41 + -D VIEW_320x240 + -D USE_PACKET_API + -I lib/device-ui/generated/ui_320x240 + -I variants/mesh-tab +build_src_filter = ${esp32_base.build_src_filter} + +<../lib/device-ui/generated/ui_320x240> + +<../lib/device-ui/resources> + +<../lib/device-ui/locale> + +<../lib/device-ui/source> +lib_deps = ${esp32_base.lib_deps} + lovyan03/LovyanGFX@^1.1.16 + +; 3.2" TN TFT ST7789 / XPT2046: https://vi.aliexpress.com/item/1005005933490544.html +[env:mesh-tab-3-2-TN-resistive] +extends = mesh_tab_base +build_flags = ${mesh_tab_base.build_flags} + -D LGFX_SCREEN_WIDTH=240 + -D LGFX_SCREEN_HEIGHT=320 + -D LGFX_PANEL=ST7789 + -D LGFX_INVERT_COLOR=false + -D LGFX_RGB_ORDER=false + -D LGFX_ROTATION=3 + -D LGFX_TOUCH=XPT2046 + -D SPI_FREQUENCY=60000000 + -D LGFX_TOUCH_SPI_FREQ=2500000 + -D LGFX_TOUCH_SPI_HOST=2 + -D LGFX_TOUCH_CS=7 + -D LGFX_TOUCH_CLK=12 + -D LGFX_TOUCH_DO=11 + -D LGFX_TOUCH_DIN=13 + -D LGFX_TOUCH_X_MIN=300 + -D LGFX_TOUCH_X_MAX=3900 + -D LGFX_TOUCH_Y_MIN=400 + -D LGFX_TOUCH_Y_MAX=3900 + -D LGFX_TOUCH_ROTATION=4 + +; 3.2" IPS TFT ILI9341 / XPT2046: https://www.aliexpress.com/item/1005006258575617.html +[env:mesh-tab-3-2-IPS-resistive] +extends = mesh_tab_base +build_flags = ${mesh_tab_base.build_flags} + -D LGFX_SCREEN_WIDTH=240 + -D LGFX_SCREEN_HEIGHT=320 + -D LGFX_PANEL=ILI9341 + -D LGFX_INVERT_COLOR=true + -D LGFX_RGB_ORDER=false + -D LGFX_ROTATION=1 + -D LGFX_TOUCH=XPT2046 + -D SPI_FREQUENCY=60000000 ; if image is distorted then lower to 40 MHz + -D LGFX_TOUCH_SPI_FREQ=2500000 + -D LGFX_TOUCH_SPI_HOST=2 + -D LGFX_TOUCH_CS=7 + -D LGFX_TOUCH_CLK=12 + -D LGFX_TOUCH_DO=11 + -D LGFX_TOUCH_DIN=13 + -D LGFX_TOUCH_X_MIN=300 + -D LGFX_TOUCH_X_MAX=3900 + -D LGFX_TOUCH_Y_MIN=400 + -D LGFX_TOUCH_Y_MAX=3900 + -D LGFX_TOUCH_ROTATION=4 + +; 3.5" IPS TFT ILI9488 / XPT2046: https://vi.aliexpress.com/item/1005006333922639.html +[env:mesh-tab-3-5-IPS-resistive] +extends = mesh_tab_base +build_flags = ${mesh_tab_base.build_flags} + -D DISPLAY_SET_RESOLUTION + -D LGFX_SCREEN_WIDTH=320 + -D LGFX_SCREEN_HEIGHT=480 + -D LGFX_PANEL=ILI9488 + -D LGFX_INVERT_COLOR=true + -D LGFX_RGB_ORDER=false + -D LGFX_DLEN_16BITS=false + -D LGFX_ROTATION=0 + -D LGFX_TOUCH=XPT2046 + -D SPI_FREQUENCY=40000000 ; may go higher upto 40/60/80 MHz + -D LGFX_TOUCH_SPI_FREQ=2500000 + -D LGFX_TOUCH_SPI_HOST=2 + -D LGFX_TOUCH_CS=7 + -D LGFX_TOUCH_CLK=12 + -D LGFX_TOUCH_DO=11 + -D LGFX_TOUCH_DIN=13 + -D LGFX_TOUCH_X_MIN=300 + -D LGFX_TOUCH_X_MAX=3900 + -D LGFX_TOUCH_Y_MIN=400 + -D LGFX_TOUCH_Y_MAX=3900 + -D LGFX_TOUCH_ROTATION=0 + +; 3.5" TN TFT ILI9488 / XPT2046: https://vi.aliexpress.com/item/32985467436.html +[env:mesh-tab-3-5-TN-resistive] +extends = mesh_tab_base +build_flags = ${mesh_tab_base.build_flags} + -D DISPLAY_SET_RESOLUTION + -D LGFX_SCREEN_WIDTH=320 + -D LGFX_SCREEN_HEIGHT=480 + -D LGFX_PANEL=HX8357B + -D SPI_FREQUENCY=60000000 + -D LGFX_INVERT_COLOR=false + -D LGFX_RGB_ORDER=false + -D LGFX_DLEN_16BITS=false + -D LGFX_ROTATION=4 + -D LGFX_TOUCH=XPT2046 + -D LGFX_TOUCH_SPI_FREQ=2500000 + -D LGFX_TOUCH_SPI_HOST=2 + -D LGFX_TOUCH_CS=7 + -D LGFX_TOUCH_CLK=12 + -D LGFX_TOUCH_DO=11 + -D LGFX_TOUCH_DIN=13 + -D LGFX_TOUCH_X_MIN=300 + -D LGFX_TOUCH_X_MAX=3900 + -D LGFX_TOUCH_Y_MIN=400 + -D LGFX_TOUCH_Y_MAX=3900 + -D LGFX_TOUCH_ROTATION=2 + +; 3.2" IPS TFT ILI9341 / FT6236: https://vi.aliexpress.com/item/1005006624072350.html +[env:mesh-tab-3-2-IPS-capacitive] +extends = mesh_tab_base +build_flags = ${mesh_tab_base.build_flags} + -D LGFX_SCREEN_WIDTH=240 + -D LGFX_SCREEN_HEIGHT=320 + -D LGFX_PANEL=ILI9341 + -D LGFX_INVERT_COLOR=true + -D LGFX_RGB_ORDER=false + -D LGFX_ROTATION=1 + -D LGFX_TOUCH=FT5x06 + -D SPI_FREQUENCY=40000000 ; may go higher upto 60/80 MHz + -D LGFX_TOUCH_I2C_PORT=0 + -D LGFX_TOUCH_I2C_ADDR=0x38 + -D LGFX_TOUCH_I2C_SDA=8 + -D LGFX_TOUCH_I2C_SCL=9 + -D LGFX_TOUCH_RST=7 + -D LGFX_TOUCH_X_MIN=0 + -D LGFX_TOUCH_X_MAX=319 + -D LGFX_TOUCH_Y_MIN=0 + -D LGFX_TOUCH_Y_MAX=479 + -D LGFX_TOUCH_ROTATION=0 + -D LGFX_TOUCH_I2C_FREQ=1000000 + +; 3.5" IPS TFT ILI9488 / FT6236: https://vi.aliexpress.com/item/1005006893699919.html +[env:mesh-tab-3-5-IPS-capacitive] +extends = mesh_tab_base +build_flags = ${mesh_tab_base.build_flags} + -D DISPLAY_SET_RESOLUTION + -D LGFX_SCREEN_WIDTH=320 + -D LGFX_SCREEN_HEIGHT=480 + -D LGFX_PANEL=ILI9488 + -D LGFX_INVERT_COLOR=true + -D LGFX_RGB_ORDER=false + -D LGFX_DLEN_16BITS=false + -D LGFX_ROTATION=1 + -D LGFX_TOUCH=FT5x06 + -D SPI_FREQUENCY=30000000 ; may go higher upto 40/60/80 MHz + -D LGFX_TOUCH_I2C_PORT=0 + -D LGFX_TOUCH_I2C_ADDR=0x38 + -D LGFX_TOUCH_I2C_SDA=8 + -D LGFX_TOUCH_I2C_SCL=9 + -D LGFX_TOUCH_RST=7 + -D LGFX_TOUCH_X_MIN=0 + -D LGFX_TOUCH_X_MAX=319 + -D LGFX_TOUCH_Y_MIN=0 + -D LGFX_TOUCH_Y_MAX=479 + -D LGFX_TOUCH_ROTATION=1 + -D LGFX_TOUCH_I2C_FREQ=1000000 + +; 4.0" IPS TFT ILI9488 / FT6236: https://vi.aliexpress.com/item/1005007082906950.html +[env:mesh-tab-4-0-IPS-capacitive] +extends = mesh_tab_base +build_flags = ${mesh_tab_base.build_flags} + -D DISPLAY_SET_RESOLUTION + -D LGFX_SCREEN_WIDTH=320 + -D LGFX_SCREEN_HEIGHT=480 + -D LGFX_PANEL=HX8357B + -D LGFX_INVERT_COLOR=true + -D LGFX_RGB_ORDER=false + -D LGFX_DLEN_16BITS=false + -D LGFX_ROTATION=4 + -D LGFX_TOUCH=FT5x06 + -D SPI_FREQUENCY=30000000 ; may go higher upto 40/60/80 MHz + -D LGFX_TOUCH_I2C_PORT=0 + -D LGFX_TOUCH_I2C_ADDR=0x38 + -D LGFX_TOUCH_I2C_SDA=8 + -D LGFX_TOUCH_I2C_SCL=9 + -D LGFX_TOUCH_RST=7 + -D LGFX_TOUCH_X_MIN=0 + -D LGFX_TOUCH_X_MAX=319 + -D LGFX_TOUCH_Y_MIN=0 + -D LGFX_TOUCH_Y_MAX=479 + -D LGFX_TOUCH_ROTATION=1 + -D LGFX_TOUCH_I2C_FREQ=1000000 \ No newline at end of file diff --git a/variants/diy/mesh-tab/variant.h b/variants/mesh-tab/variant.h similarity index 67% rename from variants/diy/mesh-tab/variant.h rename to variants/mesh-tab/variant.h index 0a23a3c36..533c931bc 100644 --- a/variants/diy/mesh-tab/variant.h +++ b/variants/mesh-tab/variant.h @@ -7,8 +7,8 @@ // Analog pins #define BATTERY_PIN 4 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage -// ratio of voltage divider = 2.0 -#define ADC_MULTIPLIER 2.11 // 2.0 + 10% for correction of display undervoltage. +// ratio of voltage divider (100k, 220k) +#define ADC_MULTIPLIER 1.6 // 1.45 + 10% for correction of display undervoltage. #define ADC_CHANNEL ADC1_GPIO4_CHANNEL // LED @@ -17,6 +17,9 @@ // Button #define BUTTON_PIN 0 +// Button +#define PIN_BUZZER 5 + // GPS #define GPS_RX_PIN 18 #define GPS_TX_PIN 17 @@ -28,20 +31,26 @@ #define SPI_CS 10 #define SDCARD_CS 6 +// LORA MODULES +#define USE_SX1262 + // LORA SPI #define LORA_SCK 36 #define LORA_MISO 37 #define LORA_MOSI 35 #define LORA_CS 39 -// LORA MODULES -#define USE_SX1262 - // LORA CONFIG +#define LORA_DIO0 -1 // a No connect on the SX1262 module +#define LORA_RESET 14 +#define LORA_DIO1 15 // SX1262 IRQ +#define LORA_DIO2 40 // SX1262 BUSY +#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262 + #define SX126X_CS LORA_CS -#define SX126X_DIO1 15 +#define SX126X_DIO1 LORA_DIO1 #define SX126X_DIO2_AS_RF_SWITCH -#define SX126X_BUSY 40 +#define SX126X_BUSY LORA_DIO2 #define SX126X_RESET 14 #define SX126X_RXEN 47 #define SX126X_TXEN RADIOLIB_NC // Assuming that DIO2 is connected to TXEN pin From e5accf4e1da0bc95f13a3af98caf74d434b75fab Mon Sep 17 00:00:00 2001 From: aussieklutz Date: Fri, 27 Dec 2024 23:16:08 +1000 Subject: [PATCH 09/16] Enable the autoconf settings for MPR121 based keyboards, to make it more flexible for varying implementations. (#5680) Co-authored-by: Ben Meadors --- src/input/MPR121Keyboard.cpp | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/input/MPR121Keyboard.cpp b/src/input/MPR121Keyboard.cpp index f35b942b1..9bca6801d 100644 --- a/src/input/MPR121Keyboard.cpp +++ b/src/input/MPR121Keyboard.cpp @@ -29,6 +29,8 @@ #define _MPR121_REG_CONFIG1 0x5C #define _MPR121_REG_CONFIG2 0x5D #define _MPR121_REG_ELECTRODE_CONFIG 0x5E +#define _MPR121_REG_AUTOCONF_CTRL0 0x7B +#define _MPR121_REG_AUTOCONF_CTRL1 0x7C #define _MPR121_REG_SOFT_RESET 0x80 #define _KEY_MASK 0x0FFF // Key mask for the first 12 bits @@ -132,18 +134,18 @@ void MPR121Keyboard::reset() writeRegister(_MPR121_REG_ELECTRODE_CONFIG, 0x00); delay(100); - LOG_DEBUG("MPR121 Configure"); + LOG_DEBUG("MPR121 Configuring"); // Set touch release thresholds for (uint8_t i = 0; i < 12; i++) { // Set touch threshold - writeRegister(_MPR121_REG_TOUCH_THRESHOLD + (i * 2), 15); + writeRegister(_MPR121_REG_TOUCH_THRESHOLD + (i * 2), 10); delay(20); // Set release threshold - writeRegister(_MPR121_REG_RELEASE_THRESHOLD + (i * 2), 7); + writeRegister(_MPR121_REG_RELEASE_THRESHOLD + (i * 2), 5); delay(20); } // Configure filtering and baseline registers - writeRegister(_MPR121_REG_MAX_HALF_DELTA_RISING, 0x01); + writeRegister(_MPR121_REG_MAX_HALF_DELTA_RISING, 0x05); delay(20); writeRegister(_MPR121_REG_MAX_HALF_DELTA_FALLING, 0x01); delay(20); @@ -153,7 +155,7 @@ void MPR121Keyboard::reset() delay(20); writeRegister(_MPR121_REG_NOISE_HALF_DELTA_TOUCHED, 0x00); delay(20); - writeRegister(_MPR121_REG_NOISE_COUNT_LIMIT_RISING, 0x0e); + writeRegister(_MPR121_REG_NOISE_COUNT_LIMIT_RISING, 0x05); delay(20); writeRegister(_MPR121_REG_NOISE_COUNT_LIMIT_FALLING, 0x01); delay(20); @@ -165,18 +167,19 @@ void MPR121Keyboard::reset() delay(20); writeRegister(_MPR121_REG_FILTER_DELAY_COUNT_TOUCHED, 0x00); delay(20); - // Set Debounce to 0x02 - writeRegister(_MPR121_REG_DEBOUNCE, 0x00); + writeRegister(_MPR121_REG_AUTOCONF_CTRL0, 0x04); // Auto-config enable delay(20); - // Set Filter1 itterations and discharge current 6x and 16uA respectively (0x10) - writeRegister(_MPR121_REG_CONFIG1, 0x10); + writeRegister(_MPR121_REG_AUTOCONF_CTRL1, 0x00); // Ensure no auto-config interrupt delay(20); - // Set CDT to 0.5us, Filter2 itterations to 4x, and Sample interval = 0 (0x20) - writeRegister(_MPR121_REG_CONFIG2, 0x20); + writeRegister(_MPR121_REG_DEBOUNCE, 0x02); + delay(20); + writeRegister(_MPR121_REG_CONFIG1, 0x20); + delay(20); + writeRegister(_MPR121_REG_CONFIG2, 0x21); delay(20); // Enter run mode by Seting partial filter calibration tracking, disable proximity detection, enable 12 channels writeRegister(_MPR121_REG_ELECTRODE_CONFIG, - ECR_CALIBRATION_TRACK_FROM_PARTIAL_FILTER | ECR_PROXIMITY_DETECTION_OFF | ECR_TOUCH_DETECTION_12CH); + ECR_CALIBRATION_TRACK_FROM_FULL_FILTER | ECR_PROXIMITY_DETECTION_OFF | ECR_TOUCH_DETECTION_12CH); delay(100); LOG_DEBUG("MPR121 Run"); state = Idle; @@ -427,4 +430,4 @@ void MPR121Keyboard::writeRegister(uint8_t reg, uint8_t value) if (writeCallback) { writeCallback(m_addr, data[0], &(data[1]), 1); } -} +} \ No newline at end of file From 51331179361f225d52fcdc60bc026fbb45bac459 Mon Sep 17 00:00:00 2001 From: Mictronics Date: Fri, 27 Dec 2024 16:12:26 +0100 Subject: [PATCH 10/16] Fix issue #5665. (#5678) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix issue #5665. --------- Co-authored-by: Ben Meadors Co-authored-by: Thomas Göttgens Co-authored-by: GUVWAF <78759985+GUVWAF@users.noreply.github.com> --- src/mesh/aes-ccm.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/mesh/aes-ccm.cpp b/src/mesh/aes-ccm.cpp index 8bc2989bf..a650ba2fc 100644 --- a/src/mesh/aes-ccm.cpp +++ b/src/mesh/aes-ccm.cpp @@ -18,12 +18,9 @@ static void WPA_PUT_BE16(uint8_t *a, uint16_t val) static void xor_aes_block(uint8_t *dst, const uint8_t *src) { - uint32_t *d = (uint32_t *)dst; - uint32_t *s = (uint32_t *)src; - *d++ ^= *s++; - *d++ ^= *s++; - *d++ ^= *s++; - *d++ ^= *s++; + for (uint8_t i = 0; i < AES_BLOCK_SIZE; i++) { + dst[i] ^= src[i]; + } } static void aes_ccm_auth_start(size_t M, size_t L, const uint8_t *nonce, const uint8_t *aad, size_t aad_len, size_t plain_len, uint8_t *x) From 2b33be2feaa0ef1f79a72a51d779dc6eca563b69 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Fri, 27 Dec 2024 15:49:24 -0600 Subject: [PATCH 11/16] Exclude health telemetry by macro (#5679) --- platformio.ini | 9 ++++++--- src/configuration.h | 1 + src/modules/Modules.cpp | 4 +++- src/modules/Telemetry/HealthTelemetry.cpp | 4 ++-- src/modules/Telemetry/HealthTelemetry.h | 4 ++-- src/modules/Telemetry/Sensor/MAX30102Sensor.cpp | 4 ++-- src/modules/Telemetry/Sensor/MAX30102Sensor.h | 4 ++-- 7 files changed, 18 insertions(+), 12 deletions(-) diff --git a/platformio.ini b/platformio.ini index 41f1ca764..bf50b7646 100644 --- a/platformio.ini +++ b/platformio.ini @@ -81,7 +81,8 @@ build_flags = -Wno-missing-field-initializers -DRADIOLIB_EXCLUDE_LORAWAN=1 -DMESHTASTIC_EXCLUDE_DROPZONE=1 -DMESHTASTIC_EXCLUDE_REMOTEHARDWARE=1 - -DMESHTASTIC_EXCLUDE_POWERSTRESS=1 ; exclude power stress test module from main firmware + -DMESHTASTIC_EXCLUDE_HEALTH_TELEMETRY=1 + -DMESHTASTIC_EXCLUDE_POWERSTRESS=1 ; exclude power stress test module from main firmware #-DBUILD_EPOCH=$UNIX_TIME ;-D OLED_PL @@ -153,7 +154,6 @@ lib_deps = sparkfun/SparkFun 9DoF IMU Breakout - ICM 20948 - Arduino Library@1.2.13 ClosedCube OPT3001@1.1.2 emotibit/EmotiBit MLX90632@1.0.8 - sparkfun/SparkFun MAX3010x Pulse and Proximity Sensor Library@1.1.2 adafruit/Adafruit MLX90614 Library@2.1.5 https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502 boschsensortec/BME68x Sensor Library@1.1.40407 @@ -161,4 +161,7 @@ lib_deps = mprograms/QMC5883LCompass@1.2.3 dfrobot/DFRobot_RTU@1.0.3 https://github.com/meshtastic/DFRobot_LarkWeatherStation#4de3a9cadef0f6a5220a8a906cf9775b02b0040d - robtillaart/INA226@0.6.0 + robtillaart/INA226@0.6.0 + + ; Health Sensor Libraries + sparkfun/SparkFun MAX3010x Pulse and Proximity Sensor Library@1.1.2 \ No newline at end of file diff --git a/src/configuration.h b/src/configuration.h index b5727508d..fbac2c1f6 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -312,6 +312,7 @@ along with this program. If not, see . #define MESHTASTIC_EXCLUDE_AUDIO 1 #define MESHTASTIC_EXCLUDE_DETECTIONSENSOR 1 #define MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR 1 +#define MESHTASTIC_EXCLUDE_HEALTH_TELEMETRY 1 #define MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION 1 #define MESHTASTIC_EXCLUDE_PAXCOUNTER 1 #define MESHTASTIC_EXCLUDE_POWER_TELEMETRY 1 diff --git a/src/modules/Modules.cpp b/src/modules/Modules.cpp index 9baed824c..58158ad3c 100644 --- a/src/modules/Modules.cpp +++ b/src/modules/Modules.cpp @@ -195,11 +195,13 @@ void setupModules() if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I].first > 0) { new AirQualityTelemetryModule(); } +#if !MESHTASTIC_EXCLUDE_HEALTH_TELEMETRY if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_MAX30102].first > 0 || nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_MLX90614].first > 0) { new HealthTelemetryModule(); } #endif +#endif #if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_POWER_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR new PowerTelemetryModule(); #endif @@ -245,4 +247,4 @@ void setupModules() // NOTE! This module must be added LAST because it likes to check for replies from other modules and avoid sending extra // acks routingModule = new RoutingModule(); -} +} \ No newline at end of file diff --git a/src/modules/Telemetry/HealthTelemetry.cpp b/src/modules/Telemetry/HealthTelemetry.cpp index 22534e9f5..1b9b49813 100644 --- a/src/modules/Telemetry/HealthTelemetry.cpp +++ b/src/modules/Telemetry/HealthTelemetry.cpp @@ -1,6 +1,6 @@ #include "configuration.h" -#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO) +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !MESHTASTIC_EXCLUDE_HEALTH_TELEMETRY && !defined(ARCH_PORTDUINO) #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "Default.h" @@ -246,4 +246,4 @@ bool HealthTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) return false; } -#endif +#endif \ No newline at end of file diff --git a/src/modules/Telemetry/HealthTelemetry.h b/src/modules/Telemetry/HealthTelemetry.h index fe84f2d27..01e4c2372 100644 --- a/src/modules/Telemetry/HealthTelemetry.h +++ b/src/modules/Telemetry/HealthTelemetry.h @@ -1,6 +1,6 @@ #include "configuration.h" -#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO) +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !MESHTASTIC_EXCLUDE_HEALTH_TELEMETRY && !defined(ARCH_PORTDUINO) #pragma once #include "../mesh/generated/meshtastic/telemetry.pb.h" @@ -57,4 +57,4 @@ class HealthTelemetryModule : private concurrency::OSThread, public ProtobufModu uint32_t sensor_read_error_count = 0; }; -#endif +#endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/MAX30102Sensor.cpp b/src/modules/Telemetry/Sensor/MAX30102Sensor.cpp index 88128a6db..f99956925 100644 --- a/src/modules/Telemetry/Sensor/MAX30102Sensor.cpp +++ b/src/modules/Telemetry/Sensor/MAX30102Sensor.cpp @@ -1,6 +1,6 @@ #include "configuration.h" -#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO) +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !MESHTASTIC_EXCLUDE_HEALTH_TELEMETRY && !defined(ARCH_PORTDUINO) #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "MAX30102Sensor.h" @@ -80,4 +80,4 @@ bool MAX30102Sensor::getMetrics(meshtastic_Telemetry *measurement) return true; } -#endif +#endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/MAX30102Sensor.h b/src/modules/Telemetry/Sensor/MAX30102Sensor.h index 426d9d365..026e30ed0 100644 --- a/src/modules/Telemetry/Sensor/MAX30102Sensor.h +++ b/src/modules/Telemetry/Sensor/MAX30102Sensor.h @@ -1,6 +1,6 @@ #include "configuration.h" -#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO) +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !MESHTASTIC_EXCLUDE_HEALTH_TELEMETRY && !defined(ARCH_PORTDUINO) #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "TelemetrySensor.h" @@ -23,4 +23,4 @@ class MAX30102Sensor : public TelemetrySensor virtual bool getMetrics(meshtastic_Telemetry *measurement) override; }; -#endif +#endif \ No newline at end of file From b2808063d0488bcd2a2c3b17aa134ecf865513eb Mon Sep 17 00:00:00 2001 From: Erayd Date: Sat, 28 Dec 2024 11:52:18 +1300 Subject: [PATCH 12/16] Add new ROUTER_LATE role (#5528) Will always rebroadcast packets, but will do so after all other modes. Intended for router nodes that are there to provide additional coverage in areas not already covered by other routers, or to bridge around problematic terrain, but should not be given priority over other routers in order to avoid unnecessaraily consuming hops. By default, this role will rebroadcast during the normal client window. However, if another node is overheard rebroadcasting the packet, then it will be moved to a second window *after* the normal client one, with the same timing behaviour. --- src/mesh/FloodingRouter.cpp | 6 ++- src/mesh/MeshPacketQueue.cpp | 26 +++++++++++-- src/mesh/MeshPacketQueue.h | 4 +- src/mesh/RadioInterface.cpp | 20 ++++++++-- src/mesh/RadioInterface.h | 9 +++++ src/mesh/RadioLibInterface.cpp | 70 +++++++++++++++++++++++++--------- src/mesh/RadioLibInterface.h | 15 +++++++- 7 files changed, 120 insertions(+), 30 deletions(-) diff --git a/src/mesh/FloodingRouter.cpp b/src/mesh/FloodingRouter.cpp index e29c596df..f94540905 100644 --- a/src/mesh/FloodingRouter.cpp +++ b/src/mesh/FloodingRouter.cpp @@ -24,11 +24,15 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p) printPacket("Ignore dupe incoming msg", p); rxDupe++; if (config.device.role != meshtastic_Config_DeviceConfig_Role_ROUTER && - config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER) { + config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER && + config.device.role != meshtastic_Config_DeviceConfig_Role_ROUTER_LATE) { // cancel rebroadcast of this message *if* there was already one, unless we're a router/repeater! if (Router::cancelSending(p->from, p->id)) txRelayCanceled++; } + if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER_LATE && iface) { + iface->clampToLateRebroadcastWindow(getFrom(p), p->id); + } /* If the original transmitter is doing retransmissions (hopStart equals hopLimit) for a reliable transmission, e.g., when the ACK got lost, we will handle the packet again to make sure it gets an ACK to its packet. */ diff --git a/src/mesh/MeshPacketQueue.cpp b/src/mesh/MeshPacketQueue.cpp index 99ef41c1e..d7ee65800 100644 --- a/src/mesh/MeshPacketQueue.cpp +++ b/src/mesh/MeshPacketQueue.cpp @@ -16,6 +16,12 @@ inline uint32_t getPriority(const meshtastic_MeshPacket *p) bool CompareMeshPacketFunc(const meshtastic_MeshPacket *p1, const meshtastic_MeshPacket *p2) { assert(p1 && p2); + + // If one packet is in the late transmit window, prefer the other one + if ((bool)p1->tx_after != (bool)p2->tx_after) { + return !p1->tx_after; + } + auto p1p = getPriority(p1), p2p = getPriority(p2); // If priorities differ, use that // for equal priorities, prefer packets already on mesh. @@ -94,11 +100,11 @@ meshtastic_MeshPacket *MeshPacketQueue::getFront() } /** Attempt to find and remove a packet from this queue. Returns a pointer to the removed packet, or NULL if not found */ -meshtastic_MeshPacket *MeshPacketQueue::remove(NodeNum from, PacketId id) +meshtastic_MeshPacket *MeshPacketQueue::remove(NodeNum from, PacketId id, bool tx_normal, bool tx_late) { for (auto it = queue.begin(); it != queue.end(); it++) { auto p = (*it); - if (getFrom(p) == from && p->id == id) { + if (getFrom(p) == from && p->id == id && ((tx_normal && !p->tx_after) || (tx_late && p->tx_after))) { queue.erase(it); return p; } @@ -114,9 +120,10 @@ bool MeshPacketQueue::replaceLowerPriorityPacket(meshtastic_MeshPacket *p) if (queue.empty()) { return false; // No packets to replace } + // Check if the packet at the back has a lower priority than the new packet auto &backPacket = queue.back(); - if (backPacket->priority < p->priority) { + if (!backPacket->tx_after && backPacket->priority < p->priority) { // Remove the back packet packetPool.release(backPacket); queue.pop_back(); @@ -125,6 +132,19 @@ bool MeshPacketQueue::replaceLowerPriorityPacket(meshtastic_MeshPacket *p) return true; } + if (backPacket->tx_after) { + // Check if there's a non-late packet with lower priority + auto it = queue.end(); + auto refPacket = *--it; + for (; refPacket->tx_after && it != queue.begin(); refPacket = *--it) + ; + if (!refPacket->tx_after && refPacket->priority < p->priority) { + packetPool.release(refPacket); + enqueue(refPacket); + return true; + } + } + // If the back packet's priority is not lower, no replacement occurs return false; } \ No newline at end of file diff --git a/src/mesh/MeshPacketQueue.h b/src/mesh/MeshPacketQueue.h index 3c28fc5ce..b41a214b9 100644 --- a/src/mesh/MeshPacketQueue.h +++ b/src/mesh/MeshPacketQueue.h @@ -36,5 +36,5 @@ class MeshPacketQueue meshtastic_MeshPacket *getFront(); /** Attempt to find and remove a packet from this queue. Returns the packet which was removed from the queue */ - meshtastic_MeshPacket *remove(NodeNum from, PacketId id); -}; + meshtastic_MeshPacket *remove(NodeNum from, PacketId id, bool tx_normal = true, bool tx_late = true); +}; \ No newline at end of file diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 5a18ab0c0..b1403f3b6 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -254,8 +254,8 @@ uint32_t RadioInterface::getTxDelayMsec() return random(0, pow(2, CWsize)) * slotTimeMsec; } -/** The delay to use when we want to flood a message */ -uint32_t RadioInterface::getTxDelayMsecWeighted(float snr) +/** The CW size to use when calculating SNR_based delays */ +uint8_t RadioInterface::getCWsize(float snr) { // The minimum value for a LoRa SNR const uint32_t SNR_MIN = -20; @@ -263,10 +263,24 @@ uint32_t RadioInterface::getTxDelayMsecWeighted(float snr) // The maximum value for a LoRa SNR const uint32_t SNR_MAX = 15; + return map(snr, SNR_MIN, SNR_MAX, CWmin, CWmax); +} + +/** The worst-case SNR_based packet delay */ +uint32_t RadioInterface::getTxDelayMsecWeightedWorst(float snr) +{ + uint8_t CWsize = getCWsize(snr); + // offset the maximum delay for routers: (2 * CWmax * slotTimeMsec) + return (2 * CWmax * slotTimeMsec) + pow(2, CWsize) * slotTimeMsec; +} + +/** The delay to use when we want to flood a message */ +uint32_t RadioInterface::getTxDelayMsecWeighted(float snr) +{ // high SNR = large CW size (Long Delay) // low SNR = small CW size (Short Delay) uint32_t delay = 0; - uint8_t CWsize = map(snr, SNR_MIN, SNR_MAX, CWmin, CWmax); + uint8_t CWsize = getCWsize(snr); // LOG_DEBUG("rx_snr of %f so setting CWsize to:%d", snr, CWsize); if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER || config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) { diff --git a/src/mesh/RadioInterface.h b/src/mesh/RadioInterface.h index 89a4c7087..652b2269c 100644 --- a/src/mesh/RadioInterface.h +++ b/src/mesh/RadioInterface.h @@ -173,9 +173,18 @@ class RadioInterface /** The delay to use when we want to send something */ uint32_t getTxDelayMsec(); + /** The CW to use when calculating SNR_based delays */ + uint8_t getCWsize(float snr); + + /** The worst-case SNR_based packet delay */ + uint32_t getTxDelayMsecWeightedWorst(float snr); + /** The delay to use when we want to flood a message. Use a weighted scale based on SNR */ uint32_t getTxDelayMsecWeighted(float snr); + /** If the packet is not already in the late rebroadcast window, move it there */ + virtual void clampToLateRebroadcastWindow(NodeNum from, PacketId id) { return; } + /** * Calculate airtime per * https://www.rs-online.com/designspark/rel-assets/ds-assets/uploads/knowledge-items/application-notes-for-the-internet-of-things/LoRa%20Design%20Guide.pdf diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp index e416160eb..997b1d6fe 100644 --- a/src/mesh/RadioLibInterface.cpp +++ b/src/mesh/RadioLibInterface.cpp @@ -235,12 +235,12 @@ void RadioLibInterface::onNotify(uint32_t notification) case ISR_TX: handleTransmitInterrupt(); startReceive(); - startTransmitTimer(); + setTransmitDelay(); break; case ISR_RX: handleReceiveInterrupt(); startReceive(); - startTransmitTimer(); + setTransmitDelay(); break; case TRANSMIT_DELAY_COMPLETED: @@ -250,23 +250,32 @@ void RadioLibInterface::onNotify(uint32_t notification) if (!canSendImmediately()) { setTransmitDelay(); // currently Rx/Tx-ing: reset random delay } else { - if (isChannelActive()) { // check if there is currently a LoRa packet on the channel - startReceive(); // try receiving this packet, afterwards we'll be trying to transmit again - setTransmitDelay(); + meshtastic_MeshPacket *txp = txQueue.getFront(); + assert(txp); + long delay_remaining = txp->tx_after ? txp->tx_after - millis() : 0; + if (delay_remaining > 0) { + // There's still some delay pending on this packet, so resume waiting for it to elapse + notifyLater(delay_remaining, TRANSMIT_DELAY_COMPLETED, false); } else { - // Send any outgoing packets we have ready as fast as possible to keep the time between channel scan and - // actual transmission as short as possible - meshtastic_MeshPacket *txp = txQueue.dequeue(); - assert(txp); - bool sent = startSend(txp); - if (sent) { - // Packet has been sent, count it toward our TX airtime utilization. - uint32_t xmitMsec = getPacketTime(txp); - airTime->logAirtime(TX_LOG, xmitMsec); + if (isChannelActive()) { // check if there is currently a LoRa packet on the channel + startReceive(); // try receiving this packet, afterwards we'll be trying to transmit again + setTransmitDelay(); + } else { + // Send any outgoing packets we have ready as fast as possible to keep the time between channel scan and + // actual transmission as short as possible + txp = txQueue.dequeue(); + assert(txp); + bool sent = startSend(txp); + if (sent) { + // Packet has been sent, count it toward our TX airtime utilization. + uint32_t xmitMsec = getPacketTime(txp); + airTime->logAirtime(TX_LOG, xmitMsec); + } } } } } else { + // Do nothing, because the queue is empty } break; default: @@ -277,15 +286,24 @@ void RadioLibInterface::onNotify(uint32_t notification) void RadioLibInterface::setTransmitDelay() { meshtastic_MeshPacket *p = txQueue.getFront(); + if (!p) { + return; // noop if there's nothing in the queue + } + // We want all sending/receiving to be done by our daemon thread. // We use a delay here because this packet might have been sent in response to a packet we just received. // So we want to make sure the other side has had a chance to reconfigure its radio. - /* We assume if rx_snr = 0 and rx_rssi = 0, the packet was generated locally. - * This assumption is valid because of the offset generated by the radio to account for the noise - * floor. - */ - if (p->rx_snr == 0 && p->rx_rssi == 0) { + if (p->tx_after) { + unsigned long add_delay = p->rx_rssi ? getTxDelayMsecWeighted(p->rx_snr) : getTxDelayMsec(); + unsigned long now = millis(); + p->tx_after = max(p->tx_after + add_delay, now + add_delay); + notifyLater(now - p->tx_after, TRANSMIT_DELAY_COMPLETED, false); + } else if (p->rx_snr == 0 && p->rx_rssi == 0) { + /* We assume if rx_snr = 0 and rx_rssi = 0, the packet was generated locally. + * This assumption is valid because of the offset generated by the radio to account for the noise + * floor. + */ startTransmitTimer(true); } else { // If there is a SNR, start a timer scaled based on that SNR. @@ -312,6 +330,20 @@ void RadioLibInterface::startTransmitTimerSNR(float snr) } } +/** + * If the packet is not already in the late rebroadcast window, move it there + */ +void RadioLibInterface::clampToLateRebroadcastWindow(NodeNum from, PacketId id) +{ + // Look for non-late packets only, so we don't do this twice! + meshtastic_MeshPacket *p = txQueue.remove(from, id, true, false); + if (p) { + p->tx_after = millis() + getTxDelayMsecWeightedWorst(p->rx_snr); + txQueue.enqueue(p); + LOG_DEBUG("Move existing queued packet to the late rebroadcast window %dms from now", p->tx_after - millis()); + } +} + void RadioLibInterface::handleTransmitInterrupt() { // This can be null if we forced the device to enter standby mode. In that case diff --git a/src/mesh/RadioLibInterface.h b/src/mesh/RadioLibInterface.h index d6101ae37..dff58c9ad 100644 --- a/src/mesh/RadioLibInterface.h +++ b/src/mesh/RadioLibInterface.h @@ -140,10 +140,16 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified * doing the transmit */ void setTransmitDelay(); - /** random timer with certain min. and max. settings */ + /** + * random timer with certain min. and max. settings + * @return Timestamp after which the packet may be sent + */ void startTransmitTimer(bool withDelay = true); - /** timer scaled to SNR of to be flooded packet */ + /** + * timer scaled to SNR of to be flooded packet + * @return Timestamp after which the packet may be sent + */ void startTransmitTimerSNR(float snr); void handleTransmitInterrupt(); @@ -193,4 +199,9 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified virtual void setStandby(); const char *radioLibErr = "RadioLib err="; + + /** + * If the packet is not already in the late rebroadcast window, move it there + */ + void clampToLateRebroadcastWindow(NodeNum from, PacketId id); }; \ No newline at end of file From ad726ad684d1e608b9428c5f72e4785f958eb2e2 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Sun, 29 Dec 2024 01:29:58 +1100 Subject: [PATCH 13/16] More meshtab cherry-pick (#5681) * board definition for mesh-tab (not yet used) * use board definition for mesh-tab --------- Co-authored-by: mverch67 --- boards/mesh-tab.json | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 boards/mesh-tab.json diff --git a/boards/mesh-tab.json b/boards/mesh-tab.json new file mode 100644 index 000000000..52c65bf77 --- /dev/null +++ b/boards/mesh-tab.json @@ -0,0 +1,42 @@ +{ + "build": { + "arduino": { + "ldscript": "esp32s3_out.ld", + "partitions": "default_16MB.csv", + "memory_type": "qio_qspi" + }, + "core": "esp32", + "extra_flags": [ + "-DBOARD_HAS_PSRAM", + "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_USB_MODE=0", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [["0x303A", "0x80D6"]], + "mcu": "esp32s3", + "variant": "mesh-tab" + }, + "connectivity": ["wifi", "bluetooth", "lora"], + "debug": { + "default_tool": "esp-builtin", + "onboard_tools": ["esp-builtin"], + "openocd_target": "esp32s3.cfg" + }, + "frameworks": ["arduino", "espidf"], + "name": "ESP32-S3 WROOM-1 N16R2 (16 MB FLASH, 2 MB PSRAM)", + "upload": { + "flash_size": "16MB", + "maximum_ram_size": 327680, + "maximum_size": 16777216, + "use_1200bps_touch": true, + "wait_for_upload_port": true, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://github.com/valzzu/Mesh-Tab", + "vendor": "Espressif" +} From 31a5b9c122ee29c20330b8c71e25e693ab6c7aeb Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sat, 28 Dec 2024 08:30:53 -0600 Subject: [PATCH 14/16] Cleanup and exclude external sensor macro to make T1000-E binaries much smaller --- src/modules/AdminModule.cpp | 1 - src/modules/Telemetry/EnvironmentTelemetry.cpp | 15 ++++++++++----- variants/tracker-t1000-e/platformio.ini | 3 ++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index 6b19f04e3..6ca362061 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -1106,7 +1106,6 @@ bool AdminModule::messageIsResponse(const meshtastic_AdminMessage *r) r->which_payload_variant == meshtastic_AdminMessage_get_ringtone_response_tag || r->which_payload_variant == meshtastic_AdminMessage_get_device_connection_status_response_tag || r->which_payload_variant == meshtastic_AdminMessage_get_node_remote_hardware_pins_response_tag || - r->which_payload_variant == meshtastic_NodeRemoteHardwarePinsResponse_node_remote_hardware_pins_tag || r->which_payload_variant == meshtastic_AdminMessage_get_ui_config_response_tag) return true; else diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index 92d964f7d..008da5c71 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -18,6 +18,7 @@ #include #include +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR_EXTERNAL // Sensors #include "Sensor/AHT10.h" #include "Sensor/BME280Sensor.h" @@ -36,7 +37,6 @@ #include "Sensor/SHT31Sensor.h" #include "Sensor/SHT4XSensor.h" #include "Sensor/SHTC3Sensor.h" -#include "Sensor/T1000xSensor.h" #include "Sensor/TSL2591Sensor.h" #include "Sensor/VEML7700Sensor.h" @@ -58,11 +58,12 @@ MLX90632Sensor mlx90632Sensor; DFRobotLarkSensor dfRobotLarkSensor; NAU7802Sensor nau7802Sensor; BMP3XXSensor bmp3xxSensor; +CGRadSensSensor cgRadSens; +#endif #ifdef T1000X_SENSOR_EN +#include "Sensor/T1000xSensor.h" T1000xSensor t1000xSensor; #endif -CGRadSensSensor cgRadSens; - #define FAILED_STATE_SENSOR_READ_MULTIPLIER 10 #define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true @@ -104,7 +105,7 @@ int32_t EnvironmentTelemetryModule::runOnce() // therefore, we should only enable the sensor loop if measurement is also enabled #ifdef T1000X_SENSOR_EN result = t1000xSensor.runOnce(); -#else +#elif !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR_EXTERNAL if (dfRobotLarkSensor.hasSensor()) result = dfRobotLarkSensor.runOnce(); if (bmp085Sensor.hasSensor()) @@ -159,8 +160,10 @@ int32_t EnvironmentTelemetryModule::runOnce() if (!moduleConfig.telemetry.environment_measurement_enabled) { return disable(); } else { +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR_EXTERNAL if (bme680Sensor.hasSensor()) result = bme680Sensor.runTrigger(); +#endif } if (((lastSentToMesh == 0) || @@ -499,6 +502,7 @@ AdminMessageHandleResult EnvironmentTelemetryModule::handleAdminMessageForModule meshtastic_AdminMessage *response) { AdminMessageHandleResult result = AdminMessageHandleResult::NOT_HANDLED; +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR_EXTERNAL if (dfRobotLarkSensor.hasSensor()) { result = dfRobotLarkSensor.handleAdminMessage(mp, request, response); if (result != AdminMessageHandleResult::NOT_HANDLED) @@ -609,7 +613,8 @@ AdminMessageHandleResult EnvironmentTelemetryModule::handleAdminMessageForModule if (result != AdminMessageHandleResult::NOT_HANDLED) return result; } +#endif return result; } -#endif +#endif \ No newline at end of file diff --git a/variants/tracker-t1000-e/platformio.ini b/variants/tracker-t1000-e/platformio.ini index 075811610..0bce9fbb5 100644 --- a/variants/tracker-t1000-e/platformio.ini +++ b/variants/tracker-t1000-e/platformio.ini @@ -4,6 +4,7 @@ board = tracker-t1000-e build_flags = ${nrf52840_base.build_flags} -Ivariants/tracker-t1000-e -Isrc/platform/nrf52/softdevice -Isrc/platform/nrf52/softdevice/nrf52 -DTRACKER_T1000_E -L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard" -DGPS_POWER_TOGGLE + -DMESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR_EXTERNAL=1 board_build.ldscript = src/platform/nrf52/nrf52840_s140_v7.ld build_src_filter = ${nrf52_base.build_src_filter} +<../variants/tracker-t1000-e> lib_deps = @@ -11,4 +12,4 @@ lib_deps = https://github.com/meshtastic/QMA6100P_Arduino_Library.git#14c900b8b2e4feaac5007a7e41e0c1b7f0841136 debug_tool = jlink ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) -upload_protocol = nrfutil +upload_protocol = nrfutil \ No newline at end of file From 43d6b31603691e8fec01ade16c7b292bb07b59f2 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Sun, 29 Dec 2024 01:31:54 +1100 Subject: [PATCH 15/16] TFT branch grab-bag (#5683) Selection of minor edits from the TFT branch that are too challenging to cherry-pick cleanly, including: * introducing the HAS_TFT flag * fixing pins in unphone * Adding pinterdevice to portduino settings --- src/configuration.h | 5 ++++- src/graphics/Screen.cpp | 2 +- src/graphics/TFTDisplay.cpp | 2 +- src/main.cpp | 5 ++++- src/mesh/PhoneAPI.h | 8 ++++---- src/mesh/wifi/WiFiAPClient.cpp | 2 +- src/modules/CannedMessageModule.h | 6 ++++-- src/modules/Modules.cpp | 2 +- src/platform/portduino/PortduinoGlue.cpp | 6 +++++- src/platform/portduino/PortduinoGlue.h | 3 ++- variants/unphone/pins_arduino.h | 8 -------- 11 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/configuration.h b/src/configuration.h index fbac2c1f6..994f1e72e 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -250,6 +250,9 @@ along with this program. If not, see . #ifndef HAS_SCREEN #define HAS_SCREEN 0 #endif +#ifndef HAS_TFT +#define HAS_TFT 0 +#endif #ifndef HAS_WIRE #define HAS_WIRE 0 #endif @@ -362,4 +365,4 @@ along with this program. If not, see . #endif #include "DebugConfiguration.h" -#include "RF95Configuration.h" \ No newline at end of file +#include "RF95Configuration.h" diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 27ea6f414..4cfb8701e 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -1718,7 +1718,7 @@ void Screen::setup() #endif serialSinceMsec = millis(); -#if ARCH_PORTDUINO +#if ARCH_PORTDUINO && !HAS_TFT if (settingsMap[touchscreenModule]) { touchScreenImpl1 = new TouchScreenImpl1(dispdev->getWidth(), dispdev->getHeight(), static_cast(dispdev)->getTouch); diff --git a/src/graphics/TFTDisplay.cpp b/src/graphics/TFTDisplay.cpp index 87c3f7de9..4f2af670b 100644 --- a/src/graphics/TFTDisplay.cpp +++ b/src/graphics/TFTDisplay.cpp @@ -347,7 +347,7 @@ static LGFX *tft = nullptr; #include // Graphics and font library for ILI9342 driver chip static TFT_eSPI *tft = nullptr; // Invoke library, pins defined in User_Setup.h -#elif ARCH_PORTDUINO && HAS_SCREEN != 0 +#elif ARCH_PORTDUINO && HAS_SCREEN != 0 && !HAS_TFT #include // Graphics and font library for ST7735 driver chip class LGFX : public lgfx::LGFX_Device diff --git a/src/main.cpp b/src/main.cpp index f4bb11535..5982e709d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -40,6 +40,7 @@ #include #ifdef ARCH_ESP32 +#include "freertosinc.h" #if !MESHTASTIC_EXCLUDE_WEBSERVER #include "mesh/http/WebServer.h" #endif @@ -173,6 +174,8 @@ std::pair nodeTelemetrySensorsMap[_meshtastic_TelemetrySenso Router *router = NULL; // Users of router don't care what sort of subclass implements that API +const char *firmware_version = optstr(APP_VERSION_SHORT); + const char *getDeviceName() { uint8_t dmac[6]; @@ -1275,4 +1278,4 @@ void loop() mainDelay.delay(delayMsec); } } -#endif \ No newline at end of file +#endif diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h index 31538a0ab..681b244c8 100644 --- a/src/mesh/PhoneAPI.h +++ b/src/mesh/PhoneAPI.h @@ -149,6 +149,9 @@ class PhoneAPI */ virtual void onNowHasData(uint32_t fromRadioNum) {} + /// begin a new connection + void handleStartConfig(); + private: void releasePhonePacket(); @@ -158,9 +161,6 @@ class PhoneAPI void releaseClientNotification(); - /// begin a new connection - void handleStartConfig(); - bool wasSeenRecently(uint32_t packetId); /** @@ -171,4 +171,4 @@ class PhoneAPI /// If the mesh service tells us fromNum has changed, tell the phone virtual int onNotify(uint32_t newValue) override; -}; \ No newline at end of file +}; diff --git a/src/mesh/wifi/WiFiAPClient.cpp b/src/mesh/wifi/WiFiAPClient.cpp index f9e5d1cc9..38aa2e2a2 100644 --- a/src/mesh/wifi/WiFiAPClient.cpp +++ b/src/mesh/wifi/WiFiAPClient.cpp @@ -430,4 +430,4 @@ uint8_t getWifiDisconnectReason() { return wifiDisconnectReason; } -#endif \ No newline at end of file +#endif diff --git a/src/modules/CannedMessageModule.h b/src/modules/CannedMessageModule.h index fd9ffc9b6..a91933a0f 100644 --- a/src/modules/CannedMessageModule.h +++ b/src/modules/CannedMessageModule.h @@ -117,8 +117,10 @@ class CannedMessageModule : public SinglePortModule, public ObservableshouldDraw(); } virtual Observable *getUIFrameObservable() override { return this; } - virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) override; virtual bool interceptingKeyboardInput() override; +#if !HAS_TFT + virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) override; +#endif virtual AdminMessageHandleResult handleAdminMessageForModule(const meshtastic_MeshPacket &mp, meshtastic_AdminMessage *request, meshtastic_AdminMessage *response) override; @@ -228,4 +230,4 @@ class CannedMessageModule : public SinglePortModule, public Observableinit(); #endif // INPUTBROKER_MATRIX_TYPE #endif // HAS_BUTTON -#if ARCH_PORTDUINO +#if ARCH_PORTDUINO && !HAS_TFT aLinuxInputImpl = new LinuxInputImpl(); aLinuxInputImpl->init(); #endif diff --git a/src/platform/portduino/PortduinoGlue.cpp b/src/platform/portduino/PortduinoGlue.cpp index 82fd8de66..4fadc3ca9 100644 --- a/src/platform/portduino/PortduinoGlue.cpp +++ b/src/platform/portduino/PortduinoGlue.cpp @@ -153,6 +153,7 @@ void portduinoSetup() std::string gpioChipName = "gpiochip"; settingsStrings[i2cdev] = ""; settingsStrings[keyboardDevice] = ""; + settingsStrings[pointerDevice] = ""; settingsStrings[webserverrootpath] = ""; settingsStrings[spidev] = ""; settingsStrings[displayspidev] = ""; @@ -455,6 +456,8 @@ bool loadConfig(const char *configPath) settingsMap[displayPanel] = ili9341; else if (yamlConfig["Display"]["Panel"].as("") == "ILI9342") settingsMap[displayPanel] = ili9342; + else if (yamlConfig["Display"]["Panel"].as("") == "ILI9486") + settingsMap[displayPanel] = ili9486; else if (yamlConfig["Display"]["Panel"].as("") == "ILI9488") settingsMap[displayPanel] = ili9488; else if (yamlConfig["Display"]["Panel"].as("") == "HX8357D") @@ -515,6 +518,7 @@ bool loadConfig(const char *configPath) } if (yamlConfig["Input"]) { settingsStrings[keyboardDevice] = (yamlConfig["Input"]["KeyboardDevice"]).as(""); + settingsStrings[pointerDevice] = (yamlConfig["Input"]["PointerDevice"]).as(""); } if (yamlConfig["Webserver"]) { @@ -570,4 +574,4 @@ bool MAC_from_string(std::string mac_str, uint8_t *dmac) } else { return false; } -} \ No newline at end of file +} diff --git a/src/platform/portduino/PortduinoGlue.h b/src/platform/portduino/PortduinoGlue.h index 9cf9b6678..5bc07df6a 100644 --- a/src/platform/portduino/PortduinoGlue.h +++ b/src/platform/portduino/PortduinoGlue.h @@ -55,6 +55,7 @@ enum configNames { displayOffsetY, displayInvert, keyboardDevice, + pointerDevice, logoutputlevel, traceFilename, webserver, @@ -66,7 +67,7 @@ enum configNames { config_directory, mac_address }; -enum { no_screen, x11, st7789, st7735, st7735s, st7796, ili9341, ili9342, ili9488, hx8357d }; +enum { no_screen, x11, st7789, st7735, st7735s, st7796, ili9341, ili9342, ili9486, ili9488, hx8357d }; enum { no_touchscreen, xpt2046, stmpe610, gt911, ft5x06 }; enum { level_error, level_warn, level_info, level_debug, level_trace }; diff --git a/variants/unphone/pins_arduino.h b/variants/unphone/pins_arduino.h index c4e9add1c..74067359f 100644 --- a/variants/unphone/pins_arduino.h +++ b/variants/unphone/pins_arduino.h @@ -6,14 +6,6 @@ #define USB_VID 0x16D0 #define USB_PID 0x1178 -#define EXTERNAL_NUM_INTERRUPTS 46 -#define NUM_DIGITAL_PINS 48 -#define NUM_ANALOG_INPUTS 20 - -#define analogInputToDigitalPin(p) (((p) < 20) ? (analogChannelToDigitalPin(p)) : -1) -#define digitalPinToInterrupt(p) (((p) < 48) ? (p) : -1) -#define digitalPinHasPWM(p) (p < 46) - #define LED_BUILTIN 13 #define BUILTIN_LED LED_BUILTIN // backward compatibility From 89ebafc8b8d85ee12002b9c574f8472d99e9ec50 Mon Sep 17 00:00:00 2001 From: Tom Fifield Date: Sun, 29 Dec 2024 01:32:24 +1100 Subject: [PATCH 16/16] Minor TFT branch cherry-picks (#5682) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update indicator board * Fixed the issue that indicator device uploads via rp2040 serial port in some cases. * esp debug logs * USB mode=1 messed up the debug log * dummy for config transfer (#5154) --------- Co-authored-by: mverch67 Co-authored-by: virgil Co-authored-by: Thomas Göttgens --- boards/seeed-sensecap-indicator.json | 8 +++++--- boards/t-deck.json | 2 +- src/mesh/PhoneAPI.cpp | 4 ++++ src/modules/AdminModule.cpp | 7 +++++++ 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/boards/seeed-sensecap-indicator.json b/boards/seeed-sensecap-indicator.json index 3fc57126f..0a02fc882 100644 --- a/boards/seeed-sensecap-indicator.json +++ b/boards/seeed-sensecap-indicator.json @@ -15,10 +15,12 @@ ], "f_cpu": "240000000L", "f_flash": "80000000L", + "f_boot": "120000000L", + "boot": "qio", "flash_mode": "qio", "hwids": [["0x1A86", "0x7523"]], "mcu": "esp32s3", - "variant": "esp32s3r8" + "variant": "esp32s3" }, "connectivity": ["wifi", "bluetooth", "lora"], "debug": { @@ -32,9 +34,9 @@ "flash_size": "8MB", "maximum_ram_size": 327680, "maximum_size": 8388608, - "require_upload_port": true, + "require_upload_port": false, "use_1200bps_touch": true, - "wait_for_upload_port": true, + "wait_for_upload_port": false, "speed": 921600 }, "url": "https://www.seeedstudio.com/Indicator-for-Meshtastic.html", diff --git a/boards/t-deck.json b/boards/t-deck.json index d62ec48e6..b112921b9 100644 --- a/boards/t-deck.json +++ b/boards/t-deck.json @@ -10,7 +10,7 @@ "-DARDUINO_USB_CDC_ON_BOOT=1", "-DARDUINO_USB_MODE=0", "-DARDUINO_RUNNING_CORE=1", - "-DARDUINO_EVENT_RUNNING_CORE=0" + "-DARDUINO_EVENT_RUNNING_CORE=1" ], "f_cpu": "240000000L", "f_flash": "80000000L", diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index 36045bcf9..8c1ba74c7 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -164,6 +164,7 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength) * * Our sending states progress in the following sequence (the client apps ASSUME THIS SEQUENCE, DO NOT CHANGE IT): STATE_SEND_MY_INFO, // send our my info record + STATE_SEND_UIDATA, STATE_SEND_OWN_NODEINFO, STATE_SEND_METADATA, STATE_SEND_CHANNELS @@ -290,6 +291,9 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf) LOG_DEBUG("Send config: sessionkey"); fromRadioScratch.config.which_payload_variant = meshtastic_Config_sessionkey_tag; break; + case meshtastic_Config_device_ui_tag: // NOOP! + fromRadioScratch.config.which_payload_variant = meshtastic_Config_device_ui_tag; + break; default: LOG_ERROR("Unknown config type %d", config_state); } diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index 6ca362061..fc3b914e5 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -633,6 +633,9 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c) requiresReboot = false; break; + case meshtastic_Config_device_ui_tag: + // NOOP! This is handled by handleStoreDeviceUIConfig + break; } if (requiresReboot && !hasOpenEditTransaction) { disableBluetooth(); @@ -795,6 +798,10 @@ void AdminModule::handleGetConfig(const meshtastic_MeshPacket &req, const uint32 LOG_INFO("Get config: Sessionkey"); res.get_config_response.which_payload_variant = meshtastic_Config_sessionkey_tag; break; + case meshtastic_AdminMessage_ConfigType_DEVICEUI_CONFIG: + // NOOP! This is handled by handleGetDeviceUIConfig + res.get_config_response.which_payload_variant = meshtastic_Config_device_ui_tag; + break; } // NOTE: The phone app needs to know the ls_secs value so it can properly expect sleep behavior. // So even if we internally use 0 to represent 'use default' we still need to send the value we are