mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-08 10:57:51 +00:00
Compare commits
12 Commits
t5-epaper-
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a6c4683ddc | ||
|
|
da11cc739d | ||
|
|
594f27c3ff | ||
|
|
15f5b35859 | ||
|
|
21ca25404a | ||
|
|
3a90781e1b | ||
|
|
1e914140ca | ||
|
|
b5e952b008 | ||
|
|
11b5f1a4fe | ||
|
|
f9c9350f45 | ||
|
|
a5b2d4a9d5 | ||
|
|
7fb95841e4 |
2
.github/workflows/test_native.yml
vendored
2
.github/workflows/test_native.yml
vendored
@@ -143,7 +143,7 @@ jobs:
|
|||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|
||||||
- name: Test Report
|
- name: Test Report
|
||||||
uses: dorny/test-reporter@v2.3.0
|
uses: dorny/test-reporter@v2.5.0
|
||||||
with:
|
with:
|
||||||
name: PlatformIO Tests
|
name: PlatformIO Tests
|
||||||
path: testreport.xml
|
path: testreport.xml
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ plugins:
|
|||||||
uri: https://github.com/trunk-io/plugins
|
uri: https://github.com/trunk-io/plugins
|
||||||
lint:
|
lint:
|
||||||
enabled:
|
enabled:
|
||||||
- checkov@3.2.496
|
- checkov@3.2.497
|
||||||
- renovate@42.66.14
|
- renovate@42.72.0
|
||||||
- prettier@3.7.4
|
- prettier@3.7.4
|
||||||
- trufflehog@3.92.4
|
- trufflehog@3.92.4
|
||||||
- yamllint@1.37.1
|
- yamllint@1.37.1
|
||||||
@@ -21,7 +21,7 @@ lint:
|
|||||||
- markdownlint@0.47.0
|
- markdownlint@0.47.0
|
||||||
- oxipng@10.0.0
|
- oxipng@10.0.0
|
||||||
- svgo@4.0.0
|
- svgo@4.0.0
|
||||||
- actionlint@1.7.9
|
- actionlint@1.7.10
|
||||||
- flake8@7.3.0
|
- flake8@7.3.0
|
||||||
- hadolint@2.14.0
|
- hadolint@2.14.0
|
||||||
- shfmt@3.6.0
|
- shfmt@3.6.0
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
"build": {
|
|
||||||
"arduino": {
|
|
||||||
"ldscript": "esp32s3_out.ld",
|
|
||||||
"memory_type": "qio_opi",
|
|
||||||
"partitions": "default_16MB.csv"
|
|
||||||
},
|
|
||||||
"core": "esp32",
|
|
||||||
"extra_flags": [
|
|
||||||
"-DBOARD_HAS_PSRAM",
|
|
||||||
"-DARDUINO_RUNNING_CORE=1",
|
|
||||||
"-DARDUINO_EVENT_RUNNING_CORE=0",
|
|
||||||
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
|
||||||
"-DARDUINO_USB_MODE=1"
|
|
||||||
],
|
|
||||||
"f_cpu": "240000000L",
|
|
||||||
"f_flash": "80000000L",
|
|
||||||
"flash_mode": "qio",
|
|
||||||
"hwids": [["0x303A", "0x1001"]],
|
|
||||||
"mcu": "esp32s3",
|
|
||||||
"variant": "esp32s3"
|
|
||||||
},
|
|
||||||
"connectivity": ["wifi", "bluetooth", "lora"],
|
|
||||||
"debug": {
|
|
||||||
"openocd_target": "esp32s3.cfg"
|
|
||||||
},
|
|
||||||
"frameworks": ["arduino", "espidf"],
|
|
||||||
"name": "LilyGo T5-ePaper-S3",
|
|
||||||
"upload": {
|
|
||||||
"flash_size": "16MB",
|
|
||||||
"maximum_ram_size": 327680,
|
|
||||||
"maximum_size": 16777216,
|
|
||||||
"require_upload_port": true,
|
|
||||||
"speed": 921600
|
|
||||||
},
|
|
||||||
"url": "https://lilygo.cc/products/t5-e-paper-s3-pro",
|
|
||||||
"vendor": "LILYGO"
|
|
||||||
}
|
|
||||||
@@ -123,7 +123,7 @@ lib_deps =
|
|||||||
[device-ui_base]
|
[device-ui_base]
|
||||||
lib_deps =
|
lib_deps =
|
||||||
# renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master
|
# renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master
|
||||||
https://github.com/meshtastic/device-ui/archive/940ba8570f59c59c3508643f4d72840de716ce20.zip
|
https://github.com/meshtastic/device-ui/archive/272defcb35651461830ebfd1b39c9167c8f49317.zip
|
||||||
|
|
||||||
; Common libs for environmental measurements in telemetry module
|
; Common libs for environmental measurements in telemetry module
|
||||||
[environmental_base]
|
[environmental_base]
|
||||||
|
|||||||
Submodule protobufs updated: 9beb80f1d3...c2e45a3fc9
@@ -68,7 +68,7 @@ ScanI2C::DeviceType ScanI2CTwoWire::probeOLED(ScanI2C::DeviceAddress addr) const
|
|||||||
if (r == 0x08 || r == 0x00) {
|
if (r == 0x08 || r == 0x00) {
|
||||||
logFoundDevice("SH1106", (uint8_t)addr.address);
|
logFoundDevice("SH1106", (uint8_t)addr.address);
|
||||||
o_probe = SCREEN_SH1106; // SH1106
|
o_probe = SCREEN_SH1106; // SH1106
|
||||||
} else if (r == 0x03 || r == 0x04 || r == 0x06 || r == 0x07) {
|
} else if (r == 0x03 || r == 0x04 || r == 0x06 || r == 0x07 || r == 0x05) {
|
||||||
logFoundDevice("SSD1306", (uint8_t)addr.address);
|
logFoundDevice("SSD1306", (uint8_t)addr.address);
|
||||||
o_probe = SCREEN_SSD1306; // SSD1306
|
o_probe = SCREEN_SSD1306; // SSD1306
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
|
||||||
#if defined(USE_EINK) && !defined(USE_EINK_PARALLELDISPLAY)
|
#ifdef USE_EINK
|
||||||
#include "EInkDisplay2.h"
|
#include "EInkDisplay2.h"
|
||||||
#include "SPILock.h"
|
#include "SPILock.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
@@ -148,7 +148,7 @@ bool EInkDisplay::connect()
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(TTGO_T_ECHO) || defined(ELECROW_ThinkNode_M1) || defined(T_ECHO_LITE)
|
#if defined(TTGO_T_ECHO) || defined(ELECROW_ThinkNode_M1) || defined(T_ECHO_LITE) || defined(TTGO_T_ECHO_PLUS)
|
||||||
{
|
{
|
||||||
auto lowLevel = new EINK_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY, SPI1);
|
auto lowLevel = new EINK_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY, SPI1);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#if defined(USE_EINK) && !defined(USE_EINK_PARALLELDISPLAY)
|
#ifdef USE_EINK
|
||||||
|
|
||||||
#include "GxEPD2_BW.h"
|
#include "GxEPD2_BW.h"
|
||||||
#include <OLEDDisplay.h>
|
#include <OLEDDisplay.h>
|
||||||
|
|||||||
@@ -1,424 +0,0 @@
|
|||||||
#include "EInkParallelDisplay.h"
|
|
||||||
|
|
||||||
#ifdef USE_EINK_PARALLELDISPLAY
|
|
||||||
|
|
||||||
#include "Wire.h"
|
|
||||||
#include "variant.h"
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <atomic>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "FastEPD.h"
|
|
||||||
|
|
||||||
// Thresholds for choosing partial vs full update
|
|
||||||
#ifndef EPD_PARTIAL_THRESHOLD_ROWS
|
|
||||||
#define EPD_PARTIAL_THRESHOLD_ROWS 128 // if changed region <= this many rows, prefer partial
|
|
||||||
#endif
|
|
||||||
#ifndef EPD_FULLSLOW_PERIOD
|
|
||||||
#define EPD_FULLSLOW_PERIOD 100 // every N full updates do a slow (CLEAR_SLOW) full refresh
|
|
||||||
#endif
|
|
||||||
#ifndef EPD_RESPONSIVE_MIN_MS
|
|
||||||
#define EPD_RESPONSIVE_MIN_MS 1000 // simple rate-limit (ms) for responsive updates
|
|
||||||
#endif
|
|
||||||
|
|
||||||
EInkParallelDisplay::EInkParallelDisplay(uint16_t width, uint16_t height, EpdRotation rot) : epaper(nullptr), rotation(rot)
|
|
||||||
{
|
|
||||||
LOG_INFO("init EInkParallelDisplay");
|
|
||||||
// Set dimensions in OLEDDisplay base class
|
|
||||||
this->geometry = GEOMETRY_RAWMODE;
|
|
||||||
this->displayWidth = width;
|
|
||||||
this->displayHeight = height;
|
|
||||||
|
|
||||||
// Round shortest side up to nearest byte, to prevent truncation causing an undersized buffer
|
|
||||||
uint16_t shortSide = min(width, height);
|
|
||||||
uint16_t longSide = max(width, height);
|
|
||||||
if (shortSide % 8 != 0)
|
|
||||||
shortSide = (shortSide | 7) + 1;
|
|
||||||
|
|
||||||
this->displayBufferSize = longSide * (shortSide / 8);
|
|
||||||
|
|
||||||
#ifdef EINK_LIMIT_GHOSTING_PX
|
|
||||||
// allocate dirty pixel buffer same size as epaper buffers (rowBytes * height)
|
|
||||||
size_t rowBytes = (this->displayWidth + 7) / 8;
|
|
||||||
dirtyPixelsSize = rowBytes * this->displayHeight;
|
|
||||||
dirtyPixels = (uint8_t *)calloc(dirtyPixelsSize, 1);
|
|
||||||
ghostPixelCount = 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
EInkParallelDisplay::~EInkParallelDisplay()
|
|
||||||
{
|
|
||||||
#ifdef EINK_LIMIT_GHOSTING_PX
|
|
||||||
if (dirtyPixels) {
|
|
||||||
free(dirtyPixels);
|
|
||||||
dirtyPixels = nullptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// If an async full update is running, wait for it to finish
|
|
||||||
if (asyncFullRunning.load()) {
|
|
||||||
// wait a short while for task to finish
|
|
||||||
for (int i = 0; i < 50 && asyncFullRunning.load(); ++i) {
|
|
||||||
delay(50);
|
|
||||||
}
|
|
||||||
if (asyncTaskHandle) {
|
|
||||||
// Let it finish or delete it
|
|
||||||
vTaskDelete(asyncTaskHandle);
|
|
||||||
asyncTaskHandle = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete epaper;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Called by the OLEDDisplay::init() path.
|
|
||||||
*/
|
|
||||||
bool EInkParallelDisplay::connect()
|
|
||||||
{
|
|
||||||
LOG_INFO("Do EPD init");
|
|
||||||
if (!epaper) {
|
|
||||||
epaper = new FASTEPD;
|
|
||||||
#if defined(T5_S3_EPAPER_PRO_V1)
|
|
||||||
epaper->initPanel(BB_PANEL_LILYGO_T5PRO, 28000000);
|
|
||||||
#elif defined(T5_S3_EPAPER_PRO_V2)
|
|
||||||
epaper->initPanel(BB_PANEL_LILYGO_T5PRO_V2, 28000000);
|
|
||||||
epaper->ioPinMode(0, OUTPUT);
|
|
||||||
epaper->ioWrite(0, HIGH);
|
|
||||||
#else
|
|
||||||
#error "unsupported EPD device!"
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// epaper->setRotation(rotation); // does not work, messes up width/height
|
|
||||||
epaper->setMode(BB_MODE_1BPP);
|
|
||||||
epaper->clearWhite();
|
|
||||||
epaper->fullUpdate(true);
|
|
||||||
|
|
||||||
#ifdef EINK_LIMIT_GHOSTING_PX
|
|
||||||
// After a full/clear the dirty tracking should be reset
|
|
||||||
resetGhostPixelTracking();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* sendCommand - simple passthrough (not required for epd_driver-based path)
|
|
||||||
*/
|
|
||||||
void EInkParallelDisplay::sendCommand(uint8_t com)
|
|
||||||
{
|
|
||||||
LOG_DEBUG("EInkParallelDisplay::sendCommand %d", (int)com);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Start a background task that will perform a blocking fullUpdate(). This lets
|
|
||||||
* display() return quickly while the heavy refresh runs in the background.
|
|
||||||
*/
|
|
||||||
void EInkParallelDisplay::startAsyncFullUpdate(int clearMode)
|
|
||||||
{
|
|
||||||
if (asyncFullRunning.load())
|
|
||||||
return; // already running
|
|
||||||
|
|
||||||
asyncFullRunning.store(true);
|
|
||||||
// pass 'this' as parameter
|
|
||||||
BaseType_t rc = xTaskCreatePinnedToCore(EInkParallelDisplay::asyncFullUpdateTask, "epd_full", 4096 / sizeof(StackType_t),
|
|
||||||
this, 2, &asyncTaskHandle,
|
|
||||||
#if CONFIG_FREERTOS_UNICORE
|
|
||||||
0
|
|
||||||
#else
|
|
||||||
1
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
if (rc != pdPASS) {
|
|
||||||
LOG_WARN("Failed to create async full-update task, falling back to blocking update");
|
|
||||||
epaper->fullUpdate(clearMode, false);
|
|
||||||
epaper->backupPlane();
|
|
||||||
asyncFullRunning.store(false);
|
|
||||||
asyncTaskHandle = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FreeRTOS task entry: runs the full update and then backs up plane.
|
|
||||||
*/
|
|
||||||
void EInkParallelDisplay::asyncFullUpdateTask(void *pvParameters)
|
|
||||||
{
|
|
||||||
EInkParallelDisplay *self = static_cast<EInkParallelDisplay *>(pvParameters);
|
|
||||||
if (!self) {
|
|
||||||
vTaskDelete(nullptr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// choose CLEAR_SLOW occasionally
|
|
||||||
int clearMode = CLEAR_FAST;
|
|
||||||
if (self->fastRefreshCount >= EPD_FULLSLOW_PERIOD) {
|
|
||||||
clearMode = CLEAR_SLOW;
|
|
||||||
self->fastRefreshCount = 0;
|
|
||||||
} else {
|
|
||||||
// when running async full, treat it as a full so reset fast count
|
|
||||||
self->fastRefreshCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
self->epaper->fullUpdate(clearMode, false);
|
|
||||||
self->epaper->backupPlane();
|
|
||||||
|
|
||||||
#ifdef EINK_LIMIT_GHOSTING_PX
|
|
||||||
// A full refresh clears ghosting state
|
|
||||||
self->resetGhostPixelTracking();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
self->asyncFullRunning.store(false);
|
|
||||||
self->asyncTaskHandle = nullptr;
|
|
||||||
|
|
||||||
// delete this task
|
|
||||||
vTaskDelete(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convert the OLEDDisplay buffer (vertical byte layout) into the 1bpp horizontal-bytes
|
|
||||||
* buffer used by the FASTEPD library. For performance we write directly into FASTEPD's
|
|
||||||
* currentBuffer() while comparing against previousBuffer() to detect changed rows.
|
|
||||||
* After conversion we call FASTEPD::partialUpdate() or FASTEPD::fullUpdate() according
|
|
||||||
* to a heuristic so only the minimal region is refreshed.
|
|
||||||
*/
|
|
||||||
void EInkParallelDisplay::display(void)
|
|
||||||
{
|
|
||||||
const uint16_t w = this->displayWidth;
|
|
||||||
const uint16_t h = this->displayHeight;
|
|
||||||
|
|
||||||
// Simple rate limiting: avoid very-frequent responsive updates
|
|
||||||
uint32_t nowMs = millis();
|
|
||||||
if (lastUpdateMs != 0 && (nowMs - lastUpdateMs) < EPD_RESPONSIVE_MIN_MS) {
|
|
||||||
LOG_DEBUG("rate-limited, skipping update");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// bytes per row in epd format (one byte = 8 horizontal pixels)
|
|
||||||
const uint32_t rowBytes = (w + 7) / 8;
|
|
||||||
|
|
||||||
// Get pointers to internal buffers
|
|
||||||
uint8_t *cur = epaper->currentBuffer();
|
|
||||||
uint8_t *prev = epaper->previousBuffer(); // may be NULL on first init
|
|
||||||
|
|
||||||
// Track changed row range while converting
|
|
||||||
int newTop = h; // min changed row (initialized to out-of-range)
|
|
||||||
int newBottom = -1; // max changed row
|
|
||||||
|
|
||||||
#ifdef FAST_EPD_PARTIAL_UPDATE_BUG
|
|
||||||
// Track changed byte column range (for clipped fullUpdate fallback)
|
|
||||||
int newLeftByte = (int)rowBytes;
|
|
||||||
int newRightByte = -1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Compute a quick hash of the incoming OLED buffer (so we can skip identical frames)
|
|
||||||
uint32_t imageHash = 0;
|
|
||||||
uint32_t bufBytes = (w / 8) * h; // vertical-byte layout size
|
|
||||||
for (uint32_t bi = 0; bi < bufBytes; ++bi) {
|
|
||||||
imageHash ^= ((uint32_t)buffer[bi]) << (bi & 31);
|
|
||||||
}
|
|
||||||
if (imageHash == previousImageHash) {
|
|
||||||
// LOG_DEBUG("image identical to previous, skipping update");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef EINK_LIMIT_GHOSTING_PX
|
|
||||||
// reset ghost count for this conversion pass; we'll mark bits that change
|
|
||||||
ghostPixelCount = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Convert: OLED buffer layout -> FASTEPD 1bpp horizontal-bytes layout into cur,
|
|
||||||
// comparing against prev when available to detect changes.
|
|
||||||
for (uint32_t y = 0; y < h; ++y) {
|
|
||||||
const uint32_t base = (y >> 3) * w; // (y/8) * width
|
|
||||||
const uint8_t bitMask = (uint8_t)(1u << (y & 7)); // mask for this row in vertical-byte layout
|
|
||||||
const uint32_t rowBase = y * rowBytes;
|
|
||||||
|
|
||||||
// process full 8-pixel bytes
|
|
||||||
for (uint32_t xb = 0; xb < rowBytes; ++xb) {
|
|
||||||
uint32_t x0 = xb * 8;
|
|
||||||
// read up to 8 source bytes (vertical-byte per column)
|
|
||||||
uint8_t b0 = (x0 + 0 < w) ? buffer[base + x0 + 0] : 0;
|
|
||||||
uint8_t b1 = (x0 + 1 < w) ? buffer[base + x0 + 1] : 0;
|
|
||||||
uint8_t b2 = (x0 + 2 < w) ? buffer[base + x0 + 2] : 0;
|
|
||||||
uint8_t b3 = (x0 + 3 < w) ? buffer[base + x0 + 3] : 0;
|
|
||||||
uint8_t b4 = (x0 + 4 < w) ? buffer[base + x0 + 4] : 0;
|
|
||||||
uint8_t b5 = (x0 + 5 < w) ? buffer[base + x0 + 5] : 0;
|
|
||||||
uint8_t b6 = (x0 + 6 < w) ? buffer[base + x0 + 6] : 0;
|
|
||||||
uint8_t b7 = (x0 + 7 < w) ? buffer[base + x0 + 7] : 0;
|
|
||||||
|
|
||||||
// build output byte: MSB = leftmost pixel
|
|
||||||
uint8_t out = 0;
|
|
||||||
out |= (uint8_t)((b0 & bitMask) ? 0x80 : 0x00);
|
|
||||||
out |= (uint8_t)((b1 & bitMask) ? 0x40 : 0x00);
|
|
||||||
out |= (uint8_t)((b2 & bitMask) ? 0x20 : 0x00);
|
|
||||||
out |= (uint8_t)((b3 & bitMask) ? 0x10 : 0x00);
|
|
||||||
out |= (uint8_t)((b4 & bitMask) ? 0x08 : 0x00);
|
|
||||||
out |= (uint8_t)((b5 & bitMask) ? 0x04 : 0x00);
|
|
||||||
out |= (uint8_t)((b6 & bitMask) ? 0x02 : 0x00);
|
|
||||||
out |= (uint8_t)((b7 & bitMask) ? 0x01 : 0x00);
|
|
||||||
|
|
||||||
// handle partial byte at end of row by masking off invalid bits
|
|
||||||
uint8_t mask = 0xFF;
|
|
||||||
uint32_t bitsRemain = (w > x0) ? (w - x0) : 0;
|
|
||||||
if (bitsRemain > 0 && bitsRemain < 8) {
|
|
||||||
mask = (uint8_t)(0xFF << (8 - bitsRemain));
|
|
||||||
out &= mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
// invert to FASTEPD polarity
|
|
||||||
out = (~out) & mask;
|
|
||||||
|
|
||||||
uint32_t pos = rowBase + xb;
|
|
||||||
uint8_t prevVal = prev ? (prev[pos] & mask) : 0x00;
|
|
||||||
// Consider this byte changed if previous buffer differs (or prev is null)
|
|
||||||
bool changed = (prev == nullptr) || (prevVal != out);
|
|
||||||
|
|
||||||
#ifdef EINK_LIMIT_GHOSTING_PX
|
|
||||||
if (changed && prev)
|
|
||||||
markDirtyBits(prev, pos, mask, out);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// mark row changed only if the previous buffer differs
|
|
||||||
if (changed) {
|
|
||||||
if (y < (uint32_t)newTop)
|
|
||||||
newTop = y;
|
|
||||||
if ((int)y > newBottom)
|
|
||||||
newBottom = y;
|
|
||||||
#ifdef FAST_EPD_PARTIAL_UPDATE_BUG
|
|
||||||
// record changed column bytes
|
|
||||||
if ((int)xb < newLeftByte)
|
|
||||||
newLeftByte = (int)xb;
|
|
||||||
if ((int)xb > newRightByte)
|
|
||||||
newRightByte = (int)xb;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always write the computed value into the current buffer (avoid leaving stale bytes)
|
|
||||||
cur[pos] = (cur[pos] & ~mask) | out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If nothing changed, avoid any panel update
|
|
||||||
if (newBottom < 0) {
|
|
||||||
LOG_DEBUG("no pixel changes detected, skipping update (conv)");
|
|
||||||
previousImageHash = imageHash; // still remember that frame
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Choose partial vs full update using heuristic
|
|
||||||
// Decide if we should force a full update after many fast updates
|
|
||||||
bool forceFull = (fastRefreshCount >= EPD_FULLSLOW_PERIOD);
|
|
||||||
|
|
||||||
#ifdef EINK_LIMIT_GHOSTING_PX
|
|
||||||
// If ghost pixels exceed limit, force a full update to clear ghosting
|
|
||||||
if (ghostPixelCount > ghostPixelLimit) {
|
|
||||||
LOG_WARN("ghost pixels %u > limit %u, forcing full refresh", ghostPixelCount, ghostPixelLimit);
|
|
||||||
forceFull = true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Compute pixel bounds from newTop/newBottom
|
|
||||||
int startRow = (newTop / 8) * 8;
|
|
||||||
int endRow = (newBottom / 8) * 8 + 7;
|
|
||||||
|
|
||||||
LOG_DEBUG("EPD update rows=%d..%d alignedRows=%d..%d rowBytes=%u", newTop, newBottom, startRow, endRow, rowBytes);
|
|
||||||
|
|
||||||
if (epaper->getMode() == BB_MODE_1BPP && !forceFull && (newBottom - newTop) <= EPD_PARTIAL_THRESHOLD_ROWS) {
|
|
||||||
// Prefer partial update path if driver is reliable; otherwise use clipped fullUpdate fallback.
|
|
||||||
#ifdef FAST_EPD_PARTIAL_UPDATE_BUG
|
|
||||||
// Workaround for FastEPD partial update bug: use clipped fullUpdate instead
|
|
||||||
// Build a pixel rectangle for a clipped fullUpdate using the changed columns
|
|
||||||
int startCol = (newLeftByte <= newRightByte) ? (newLeftByte * 8) : 0;
|
|
||||||
int endCol = (newLeftByte <= newRightByte) ? ((newRightByte + 1) * 8 - 1) : (w - 1);
|
|
||||||
|
|
||||||
BB_RECT rect{startCol, startRow, endCol - startCol + 1, endRow - startRow + 1};
|
|
||||||
// LOG_DEBUG("Using clipped fullUpdate rect x=%d y=%d w=%d h=%d", rect.x, rect.y, rect.w, rect.h);
|
|
||||||
epaper->fullUpdate(CLEAR_FAST, false, &rect);
|
|
||||||
#else
|
|
||||||
// Use rows for partial update
|
|
||||||
LOG_DEBUG("calling partialUpdate startRow=%d endRow=%d", startRow, endRow);
|
|
||||||
epaper->partialUpdate(true, startRow, endRow);
|
|
||||||
#endif
|
|
||||||
epaper->backupPlane();
|
|
||||||
fastRefreshCount++;
|
|
||||||
} else {
|
|
||||||
// Full update: run async if possible (startAsyncFullUpdate will fall back to blocking)
|
|
||||||
startAsyncFullUpdate(forceFull ? CLEAR_SLOW : CLEAR_FAST);
|
|
||||||
}
|
|
||||||
|
|
||||||
lastUpdateMs = millis();
|
|
||||||
previousImageHash = imageHash;
|
|
||||||
|
|
||||||
// Keep same behavior as before
|
|
||||||
lastDrawMsec = millis();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef EINK_LIMIT_GHOSTING_PX
|
|
||||||
// markDirtyBits: mark per-bit dirty flags and update ghostPixelCount
|
|
||||||
void EInkParallelDisplay::markDirtyBits(const uint8_t *prevBuf, uint32_t pos, uint8_t mask, uint8_t out)
|
|
||||||
{
|
|
||||||
// defensive: need dirtyPixels allocated and prevBuf valid
|
|
||||||
if (!dirtyPixels || !prevBuf)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// 'out' is in FASTEPD polarity (1 = black, 0 = white)
|
|
||||||
uint8_t newBlack = out & mask; // bits that will be black now
|
|
||||||
uint8_t newWhite = (~out) & mask; // bits that will be white now
|
|
||||||
|
|
||||||
// previously recorded dirty bits for this byte
|
|
||||||
uint8_t before = dirtyPixels[pos];
|
|
||||||
|
|
||||||
// Ghost bits: bits that were previously marked dirty and are now being driven white
|
|
||||||
uint8_t ghostBits = before & newWhite;
|
|
||||||
if (ghostBits) {
|
|
||||||
ghostPixelCount += __builtin_popcount((unsigned)ghostBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only mark bits dirty when they turn black now (accumulate until a full refresh)
|
|
||||||
uint8_t newlyDirty = newBlack & (~before);
|
|
||||||
if (newlyDirty) {
|
|
||||||
dirtyPixels[pos] |= newlyDirty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset ghost tracking (call after a full refresh)
|
|
||||||
void EInkParallelDisplay::resetGhostPixelTracking()
|
|
||||||
{
|
|
||||||
if (!dirtyPixels)
|
|
||||||
return;
|
|
||||||
memset(dirtyPixels, 0, dirtyPixelsSize);
|
|
||||||
ghostPixelCount = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* forceDisplay: use lastDrawMsec
|
|
||||||
*/
|
|
||||||
bool EInkParallelDisplay::forceDisplay(uint32_t msecLimit)
|
|
||||||
{
|
|
||||||
uint32_t now = millis();
|
|
||||||
if (lastDrawMsec == 0 || (now - lastDrawMsec) > msecLimit) {
|
|
||||||
display();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EInkParallelDisplay::endUpdate()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
// ensure any async full update is started/completed
|
|
||||||
if (asyncFullRunning.load()) {
|
|
||||||
// nothing to do; background task will run and call backupPlane when done
|
|
||||||
} else {
|
|
||||||
epaper->fullUpdate(CLEAR_FAST, false);
|
|
||||||
epaper->backupPlane();
|
|
||||||
#ifdef EINK_LIMIT_GHOSTING_PX
|
|
||||||
resetGhostPixelTracking();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "configuration.h"
|
|
||||||
|
|
||||||
#ifdef USE_EINK_PARALLELDISPLAY
|
|
||||||
#include <OLEDDisplay.h>
|
|
||||||
|
|
||||||
#include <atomic>
|
|
||||||
#include <freertos/FreeRTOS.h>
|
|
||||||
#include <freertos/task.h>
|
|
||||||
|
|
||||||
class FASTEPD;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapter for E-Ink 8-bit parallel displays (EPD), specifically devices supported by FastEPD library
|
|
||||||
*/
|
|
||||||
class EInkParallelDisplay : public OLEDDisplay
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum EpdRotation {
|
|
||||||
EPD_ROT_LANDSCAPE = 0,
|
|
||||||
EPD_ROT_PORTRAIT = 90,
|
|
||||||
EPD_ROT_INVERTED_LANDSCAPE = 180,
|
|
||||||
EPD_ROT_INVERTED_PORTRAIT = 270,
|
|
||||||
};
|
|
||||||
|
|
||||||
EInkParallelDisplay(uint16_t width, uint16_t height, EpdRotation rotation);
|
|
||||||
virtual ~EInkParallelDisplay();
|
|
||||||
|
|
||||||
// OLEDDisplay virtuals
|
|
||||||
bool connect() override;
|
|
||||||
void sendCommand(uint8_t com) override;
|
|
||||||
int getBufferOffset(void) override { return 0; }
|
|
||||||
|
|
||||||
void display(void) override;
|
|
||||||
bool forceDisplay(uint32_t msecLimit = 1000);
|
|
||||||
void endUpdate();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
uint32_t lastDrawMsec = 0;
|
|
||||||
FASTEPD *epaper;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Async full-refresh support
|
|
||||||
std::atomic<bool> asyncFullRunning{false};
|
|
||||||
TaskHandle_t asyncTaskHandle = nullptr;
|
|
||||||
void startAsyncFullUpdate(int clearMode);
|
|
||||||
static void asyncFullUpdateTask(void *pvParameters);
|
|
||||||
|
|
||||||
#ifdef EINK_LIMIT_GHOSTING_PX
|
|
||||||
// helpers
|
|
||||||
void resetGhostPixelTracking();
|
|
||||||
void markDirtyBits(const uint8_t *prevBuf, uint32_t pos, uint8_t mask, uint8_t out);
|
|
||||||
void countGhostPixelsAndMaybePromote(int &newTop, int &newBottom, bool &forceFull);
|
|
||||||
|
|
||||||
// per-bit dirty buffer (same format as epaper buffers): one bit == one pixel
|
|
||||||
uint8_t *dirtyPixels = nullptr;
|
|
||||||
size_t dirtyPixelsSize = 0;
|
|
||||||
uint32_t ghostPixelCount = 0;
|
|
||||||
uint32_t ghostPixelLimit = EINK_LIMIT_GHOSTING_PX;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
EpdRotation rotation;
|
|
||||||
uint32_t previousImageHash = 0;
|
|
||||||
uint32_t lastUpdateMs = 0;
|
|
||||||
int fastRefreshCount = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -27,7 +27,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "meshUtils.h"
|
#include "meshUtils.h"
|
||||||
#if HAS_SCREEN
|
#if HAS_SCREEN
|
||||||
#include "EInkParallelDisplay.h"
|
|
||||||
#include <OLEDDisplay.h>
|
#include <OLEDDisplay.h>
|
||||||
|
|
||||||
#include "DisplayFormatters.h"
|
#include "DisplayFormatters.h"
|
||||||
@@ -368,14 +367,12 @@ Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_O
|
|||||||
defined(RAK14014) || defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST7796_CS) || defined(HACKADAY_COMMUNICATOR)
|
defined(RAK14014) || defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST7796_CS) || defined(HACKADAY_COMMUNICATOR)
|
||||||
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) && !defined(USE_EINK_PARALLELDISPLAY)
|
#elif defined(USE_EINK) && !defined(USE_EINK_DYNAMICDISPLAY)
|
||||||
dispdev = new EInkDisplay(address.address, -1, -1, geometry,
|
dispdev = new EInkDisplay(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)
|
||||||
dispdev = new EInkDynamicDisplay(address.address, -1, -1, geometry,
|
dispdev = new EInkDynamicDisplay(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_PARALLELDISPLAY)
|
|
||||||
dispdev = new EInkParallelDisplay(EPD_WIDTH, EPD_HEIGHT, EInkParallelDisplay::EPD_ROT_PORTRAIT);
|
|
||||||
#elif defined(USE_ST7567)
|
#elif defined(USE_ST7567)
|
||||||
dispdev = new ST7567Wire(address.address, -1, -1, geometry,
|
dispdev = new ST7567Wire(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);
|
||||||
@@ -754,11 +751,7 @@ void Screen::forceDisplay(bool forceUiUpdate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Tell EInk class to update the display
|
// Tell EInk class to update the display
|
||||||
#if defined(USE_EINK_PARALLELDISPLAY)
|
|
||||||
static_cast<EInkParallelDisplay *>(dispdev)->forceDisplay();
|
|
||||||
#elif defined(USE_EINK)
|
|
||||||
static_cast<EInkDisplay *>(dispdev)->forceDisplay();
|
static_cast<EInkDisplay *>(dispdev)->forceDisplay();
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
// No delay between UI frame rendering
|
// No delay between UI frame rendering
|
||||||
if (forceUiUpdate) {
|
if (forceUiUpdate) {
|
||||||
@@ -975,10 +968,8 @@ void Screen::setScreensaverFrames(FrameCallback einkScreensaver)
|
|||||||
ui->update();
|
ui->update();
|
||||||
} while (ui->getUiState()->lastUpdate < startUpdate);
|
} while (ui->getUiState()->lastUpdate < startUpdate);
|
||||||
|
|
||||||
#if defined(USE_EINK_PARALLELDISPLAY)
|
|
||||||
static_cast<EInkParallelDisplay *>(dispdev)->forceDisplay(0);
|
|
||||||
#elif defined(USE_EINK) && !defined(USE_EINK_DYNAMICDISPLAY)
|
|
||||||
// Old EInkDisplay class
|
// Old EInkDisplay class
|
||||||
|
#if !defined(USE_EINK_DYNAMICDISPLAY)
|
||||||
static_cast<EInkDisplay *>(dispdev)->forceDisplay(0); // Screen::forceDisplay(), but override rate-limit
|
static_cast<EInkDisplay *>(dispdev)->forceDisplay(0); // Screen::forceDisplay(), but override rate-limit
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
#include "graphics/fonts/OLEDDisplayFontsCS.h"
|
#include "graphics/fonts/OLEDDisplayFontsCS.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CROWPANEL_ESP32S3_5_EPAPER) || defined(T5_S3_EPAPER_PRO)
|
#if defined(CROWPANEL_ESP32S3_5_EPAPER) && defined(USE_EINK)
|
||||||
#include "graphics/fonts/EinkDisplayFonts.h"
|
#include "graphics/fonts/EinkDisplayFonts.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
|
|
||||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
|
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
|
||||||
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST7796_CS) || \
|
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST7796_CS) || \
|
||||||
defined(USE_ST7796) || defined(HACKADAY_COMMUNICATOR)) && \
|
defined(HACKADAY_COMMUNICATOR) || defined(USE_ST7796)) && \
|
||||||
!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 FONT_MEDIUM_LOCAL // Height: 19
|
#define FONT_SMALL FONT_MEDIUM_LOCAL // Height: 19
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
#define FONT_LARGE FONT_LARGE_LOCAL // Height: 28
|
#define FONT_LARGE FONT_LARGE_LOCAL // Height: 28
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CROWPANEL_ESP32S3_5_EPAPER) || defined(T5_S3_EPAPER_PRO)
|
#if defined(CROWPANEL_ESP32S3_5_EPAPER) && defined(USE_EINK)
|
||||||
#undef FONT_SMALL
|
#undef FONT_SMALL
|
||||||
#undef FONT_MEDIUM
|
#undef FONT_MEDIUM
|
||||||
#undef FONT_LARGE
|
#undef FONT_LARGE
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
|
|
||||||
#include <GFX.h> // GFXRoot drawing lib
|
#include <GFX.h> // GFXRoot drawing lib
|
||||||
|
|
||||||
#include "mesh/MeshModule.h"
|
|
||||||
#include "mesh/MeshTypes.h"
|
#include "mesh/MeshTypes.h"
|
||||||
|
|
||||||
#include "./AppletFont.h"
|
#include "./AppletFont.h"
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ bool ButtonThread::initButton(const ButtonConfig &config)
|
|||||||
_activeLow = config.activeLow;
|
_activeLow = config.activeLow;
|
||||||
_touchQuirk = config.touchQuirk;
|
_touchQuirk = config.touchQuirk;
|
||||||
_intRoutine = config.intRoutine;
|
_intRoutine = config.intRoutine;
|
||||||
|
_pressHandler = config.onPress;
|
||||||
|
_releaseHandler = config.onRelease;
|
||||||
|
_suppressLeadUp = config.suppressLeadUpSound;
|
||||||
_longLongPress = config.longLongPress;
|
_longLongPress = config.longLongPress;
|
||||||
|
|
||||||
userButton = OneButton(config.pinNumber, config.activeLow, config.activePullup);
|
userButton = OneButton(config.pinNumber, config.activeLow, config.activePullup);
|
||||||
@@ -133,6 +136,8 @@ int32_t ButtonThread::runOnce()
|
|||||||
|
|
||||||
// Detect start of button press
|
// Detect start of button press
|
||||||
if (buttonCurrentlyPressed && !buttonWasPressed) {
|
if (buttonCurrentlyPressed && !buttonWasPressed) {
|
||||||
|
if (_pressHandler)
|
||||||
|
_pressHandler();
|
||||||
buttonPressStartTime = millis();
|
buttonPressStartTime = millis();
|
||||||
leadUpPlayed = false;
|
leadUpPlayed = false;
|
||||||
leadUpSequenceActive = false;
|
leadUpSequenceActive = false;
|
||||||
@@ -140,7 +145,7 @@ int32_t ButtonThread::runOnce()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Progressive lead-up sound system
|
// Progressive lead-up sound system
|
||||||
if (buttonCurrentlyPressed && (millis() - buttonPressStartTime) >= BUTTON_LEADUP_MS) {
|
if (!_suppressLeadUp && buttonCurrentlyPressed && (millis() - buttonPressStartTime) >= BUTTON_LEADUP_MS) {
|
||||||
|
|
||||||
// Start the progressive sequence if not already active
|
// Start the progressive sequence if not already active
|
||||||
if (!leadUpSequenceActive) {
|
if (!leadUpSequenceActive) {
|
||||||
@@ -160,6 +165,8 @@ int32_t ButtonThread::runOnce()
|
|||||||
|
|
||||||
// Reset when button is released
|
// Reset when button is released
|
||||||
if (!buttonCurrentlyPressed && buttonWasPressed) {
|
if (!buttonCurrentlyPressed && buttonWasPressed) {
|
||||||
|
if (_releaseHandler)
|
||||||
|
_releaseHandler();
|
||||||
leadUpSequenceActive = false;
|
leadUpSequenceActive = false;
|
||||||
resetLeadUpSequence();
|
resetLeadUpSequence();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ struct ButtonConfig {
|
|||||||
bool activePullup = true;
|
bool activePullup = true;
|
||||||
uint32_t pullupSense = 0;
|
uint32_t pullupSense = 0;
|
||||||
voidFuncPtr intRoutine = nullptr;
|
voidFuncPtr intRoutine = nullptr;
|
||||||
|
voidFuncPtr onPress = nullptr; // Optional edge callbacks
|
||||||
|
voidFuncPtr onRelease = nullptr; // Optional edge callbacks
|
||||||
|
bool suppressLeadUpSound = false;
|
||||||
input_broker_event singlePress = INPUT_BROKER_NONE;
|
input_broker_event singlePress = INPUT_BROKER_NONE;
|
||||||
input_broker_event longPress = INPUT_BROKER_NONE;
|
input_broker_event longPress = INPUT_BROKER_NONE;
|
||||||
uint16_t longPressTime = 500;
|
uint16_t longPressTime = 500;
|
||||||
@@ -94,6 +97,9 @@ class ButtonThread : public Observable<const InputEvent *>, public concurrency::
|
|||||||
input_broker_event _shortLong = INPUT_BROKER_NONE;
|
input_broker_event _shortLong = INPUT_BROKER_NONE;
|
||||||
|
|
||||||
voidFuncPtr _intRoutine = nullptr;
|
voidFuncPtr _intRoutine = nullptr;
|
||||||
|
voidFuncPtr _pressHandler = nullptr;
|
||||||
|
voidFuncPtr _releaseHandler = nullptr;
|
||||||
|
bool _suppressLeadUp = false;
|
||||||
uint16_t _longPressTime = 500;
|
uint16_t _longPressTime = 500;
|
||||||
uint16_t _longLongPressTime = 3900;
|
uint16_t _longLongPressTime = 3900;
|
||||||
int _pinNum = 0;
|
int _pinNum = 0;
|
||||||
|
|||||||
40
src/main.cpp
40
src/main.cpp
@@ -107,6 +107,10 @@ NRF52Bluetooth *nrf52Bluetooth = nullptr;
|
|||||||
|
|
||||||
#if defined(BUTTON_PIN_TOUCH)
|
#if defined(BUTTON_PIN_TOUCH)
|
||||||
ButtonThread *TouchButtonThread = nullptr;
|
ButtonThread *TouchButtonThread = nullptr;
|
||||||
|
#if defined(TTGO_T_ECHO_PLUS) && defined(PIN_EINK_EN)
|
||||||
|
static bool touchBacklightWasOn = false;
|
||||||
|
static bool touchBacklightActive = false;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO)
|
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO)
|
||||||
@@ -205,7 +209,7 @@ ScanI2C::FoundDevice rgb_found = ScanI2C::FoundDevice(ScanI2C::DeviceType::NONE,
|
|||||||
/// The I2C address of our Air Quality Indicator (if found)
|
/// The I2C address of our Air Quality Indicator (if found)
|
||||||
ScanI2C::DeviceAddress aqi_found = ScanI2C::ADDRESS_NONE;
|
ScanI2C::DeviceAddress aqi_found = ScanI2C::ADDRESS_NONE;
|
||||||
|
|
||||||
#if defined(T_WATCH_S3) || defined(T_LORA_PAGER)
|
#ifdef HAS_DRV2605
|
||||||
Adafruit_DRV2605 drv;
|
Adafruit_DRV2605 drv;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -394,12 +398,6 @@ void setup()
|
|||||||
io.pinMode(EXPANDS_GPIO_EN, OUTPUT);
|
io.pinMode(EXPANDS_GPIO_EN, OUTPUT);
|
||||||
io.digitalWrite(EXPANDS_GPIO_EN, HIGH);
|
io.digitalWrite(EXPANDS_GPIO_EN, HIGH);
|
||||||
io.pinMode(EXPANDS_SD_PULLEN, INPUT);
|
io.pinMode(EXPANDS_SD_PULLEN, INPUT);
|
||||||
#elif defined(T5_S3_EPAPER_PRO)
|
|
||||||
pinMode(LORA_CS, OUTPUT);
|
|
||||||
digitalWrite(LORA_CS, HIGH);
|
|
||||||
pinMode(SDCARD_CS, OUTPUT);
|
|
||||||
digitalWrite(SDCARD_CS, HIGH);
|
|
||||||
pinMode(BOARD_BL_EN, OUTPUT);
|
|
||||||
#elif defined(HACKADAY_COMMUNICATOR)
|
#elif defined(HACKADAY_COMMUNICATOR)
|
||||||
pinMode(KB_INT, INPUT);
|
pinMode(KB_INT, INPUT);
|
||||||
#endif
|
#endif
|
||||||
@@ -794,7 +792,6 @@ void setup()
|
|||||||
// We do this as early as possible because this loads preferences from flash
|
// We do this as early as possible because this loads preferences from flash
|
||||||
// but we need to do this after main cpu init (esp32setup), because we need the random seed set
|
// but we need to do this after main cpu init (esp32setup), because we need the random seed set
|
||||||
nodeDB = new NodeDB;
|
nodeDB = new NodeDB;
|
||||||
|
|
||||||
#if HAS_TFT
|
#if HAS_TFT
|
||||||
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_COLOR) {
|
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_COLOR) {
|
||||||
tftSetup();
|
tftSetup();
|
||||||
@@ -840,7 +837,12 @@ void setup()
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(T_WATCH_S3) || defined(T_LORA_PAGER)
|
#ifdef HAS_DRV2605
|
||||||
|
#if defined(PIN_DRV_EN)
|
||||||
|
pinMode(PIN_DRV_EN, OUTPUT);
|
||||||
|
digitalWrite(PIN_DRV_EN, HIGH);
|
||||||
|
delay(10);
|
||||||
|
#endif
|
||||||
drv.begin();
|
drv.begin();
|
||||||
drv.selectLibrary(1);
|
drv.selectLibrary(1);
|
||||||
// I2C trigger by sending 'go' command
|
// I2C trigger by sending 'go' command
|
||||||
@@ -876,7 +878,7 @@ void setup()
|
|||||||
SPI.begin();
|
SPI.begin();
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
// ESP32
|
// ESP32
|
||||||
#if defined(HW_SPI1_DEVICE)
|
#if defined(HW_SPI1_DEVICE)
|
||||||
SPI1.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
|
SPI1.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
|
||||||
LOG_DEBUG("SPI1.begin(SCK=%d, MISO=%d, MOSI=%d, NSS=%d)", LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
|
LOG_DEBUG("SPI1.begin(SCK=%d, MISO=%d, MOSI=%d, NSS=%d)", LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
|
||||||
@@ -1045,6 +1047,24 @@ void setup()
|
|||||||
};
|
};
|
||||||
touchConfig.singlePress = INPUT_BROKER_NONE;
|
touchConfig.singlePress = INPUT_BROKER_NONE;
|
||||||
touchConfig.longPress = INPUT_BROKER_BACK;
|
touchConfig.longPress = INPUT_BROKER_BACK;
|
||||||
|
#if defined(TTGO_T_ECHO_PLUS) && defined(PIN_EINK_EN)
|
||||||
|
// On T-Echo Plus the touch pad should only drive the backlight, not UI navigation/sounds
|
||||||
|
touchConfig.longPress = INPUT_BROKER_NONE;
|
||||||
|
touchConfig.suppressLeadUpSound = true;
|
||||||
|
touchConfig.onPress = []() {
|
||||||
|
touchBacklightWasOn = uiconfig.screen_brightness == 1;
|
||||||
|
if (!touchBacklightWasOn) {
|
||||||
|
digitalWrite(PIN_EINK_EN, HIGH);
|
||||||
|
}
|
||||||
|
touchBacklightActive = true;
|
||||||
|
};
|
||||||
|
touchConfig.onRelease = []() {
|
||||||
|
if (touchBacklightActive && !touchBacklightWasOn) {
|
||||||
|
digitalWrite(PIN_EINK_EN, LOW);
|
||||||
|
}
|
||||||
|
touchBacklightActive = false;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
TouchButtonThread->initButton(touchConfig);
|
TouchButtonThread->initButton(touchConfig);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ extern bool eink_found;
|
|||||||
extern bool pmu_found;
|
extern bool pmu_found;
|
||||||
extern bool isUSBPowered;
|
extern bool isUSBPowered;
|
||||||
|
|
||||||
#if defined(T_WATCH_S3) || defined(T_LORA_PAGER)
|
#ifdef HAS_DRV2605
|
||||||
#include <Adafruit_DRV2605.h>
|
#include <Adafruit_DRV2605.h>
|
||||||
extern Adafruit_DRV2605 drv;
|
extern Adafruit_DRV2605 drv;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -744,8 +744,11 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
|
|||||||
MeshModule::callModules(*p, src);
|
MeshModule::callModules(*p, src);
|
||||||
|
|
||||||
#if !MESHTASTIC_EXCLUDE_MQTT
|
#if !MESHTASTIC_EXCLUDE_MQTT
|
||||||
// Mark as pki_encrypted if it is not yet decoded and MQTT encryption is also enabled, hash matches and it's a DM not to
|
if (p_encrypted == nullptr) {
|
||||||
// us (because we would be able to decrypt it)
|
LOG_WARN("p_encrypted is null, skipping MQTT publish");
|
||||||
|
} else {
|
||||||
|
// Mark as pki_encrypted if it is not yet decoded and MQTT encryption is also enabled, hash matches and it's a DM not
|
||||||
|
// to us (because we would be able to decrypt it)
|
||||||
if (decodedState == DecodeState::DECODE_FAILURE && moduleConfig.mqtt.encryption_enabled && p->channel == 0x00 &&
|
if (decodedState == DecodeState::DECODE_FAILURE && moduleConfig.mqtt.encryption_enabled && p->channel == 0x00 &&
|
||||||
!isBroadcast(p->to) && !isToUs(p))
|
!isBroadcast(p->to) && !isToUs(p))
|
||||||
p_encrypted->pki_encrypted = true;
|
p_encrypted->pki_encrypted = true;
|
||||||
@@ -753,6 +756,7 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
|
|||||||
if ((decodedState == DecodeState::DECODE_SUCCESS || p_encrypted->pki_encrypted) && moduleConfig.mqtt.enabled &&
|
if ((decodedState == DecodeState::DECODE_SUCCESS || p_encrypted->pki_encrypted) && moduleConfig.mqtt.enabled &&
|
||||||
!isFromUs(p) && mqtt)
|
!isFromUs(p) && mqtt)
|
||||||
mqtt->onSend(*p_encrypted, *p, p->channel);
|
mqtt->onSend(*p_encrypted, *p, p->channel);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ PB_BIND(meshtastic_AdminMessage, meshtastic_AdminMessage, 2)
|
|||||||
PB_BIND(meshtastic_AdminMessage_InputEvent, meshtastic_AdminMessage_InputEvent, AUTO)
|
PB_BIND(meshtastic_AdminMessage_InputEvent, meshtastic_AdminMessage_InputEvent, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(meshtastic_AdminMessage_OTAEvent, meshtastic_AdminMessage_OTAEvent, AUTO)
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(meshtastic_HamParameters, meshtastic_HamParameters, AUTO)
|
PB_BIND(meshtastic_HamParameters, meshtastic_HamParameters, AUTO)
|
||||||
|
|
||||||
|
|
||||||
@@ -33,3 +36,5 @@ PB_BIND(meshtastic_KeyVerificationAdmin, meshtastic_KeyVerificationAdmin, AUTO)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,16 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Enum definitions */
|
/* Enum definitions */
|
||||||
|
/* Firmware update mode for OTA updates */
|
||||||
|
typedef enum _meshtastic_OTAMode {
|
||||||
|
/* Do not reboot into OTA mode */
|
||||||
|
meshtastic_OTAMode_NO_REBOOT_OTA = 0,
|
||||||
|
/* Reboot into OTA mode for BLE firmware update */
|
||||||
|
meshtastic_OTAMode_OTA_BLE = 1,
|
||||||
|
/* Reboot into OTA mode for WiFi firmware update */
|
||||||
|
meshtastic_OTAMode_OTA_WIFI = 2
|
||||||
|
} meshtastic_OTAMode;
|
||||||
|
|
||||||
/* TODO: REPLACE */
|
/* TODO: REPLACE */
|
||||||
typedef enum _meshtastic_AdminMessage_ConfigType {
|
typedef enum _meshtastic_AdminMessage_ConfigType {
|
||||||
/* TODO: REPLACE */
|
/* TODO: REPLACE */
|
||||||
@@ -103,6 +113,17 @@ typedef struct _meshtastic_AdminMessage_InputEvent {
|
|||||||
uint16_t touch_y;
|
uint16_t touch_y;
|
||||||
} meshtastic_AdminMessage_InputEvent;
|
} meshtastic_AdminMessage_InputEvent;
|
||||||
|
|
||||||
|
typedef PB_BYTES_ARRAY_T(32) meshtastic_AdminMessage_OTAEvent_ota_hash_t;
|
||||||
|
/* User is requesting an over the air update.
|
||||||
|
Node will reboot into the OTA loader */
|
||||||
|
typedef struct _meshtastic_AdminMessage_OTAEvent {
|
||||||
|
/* Tell the node to reboot into OTA mode for firmware update via BLE or WiFi (ESP32 only for now) */
|
||||||
|
meshtastic_OTAMode reboot_ota_mode;
|
||||||
|
/* A 32 byte hash of the OTA firmware.
|
||||||
|
Used to verify the integrity of the firmware before applying an update. */
|
||||||
|
meshtastic_AdminMessage_OTAEvent_ota_hash_t ota_hash;
|
||||||
|
} meshtastic_AdminMessage_OTAEvent;
|
||||||
|
|
||||||
/* Parameters for setting up Meshtastic for ameteur radio usage */
|
/* Parameters for setting up Meshtastic for ameteur radio usage */
|
||||||
typedef struct _meshtastic_HamParameters {
|
typedef struct _meshtastic_HamParameters {
|
||||||
/* Amateur radio call sign, eg. KD2ABC */
|
/* Amateur radio call sign, eg. KD2ABC */
|
||||||
@@ -261,7 +282,8 @@ typedef struct _meshtastic_AdminMessage {
|
|||||||
/* Tell the node to factory reset config everything; all device state and configuration will be returned to factory defaults and BLE bonds will be cleared. */
|
/* Tell the node to factory reset config everything; all device state and configuration will be returned to factory defaults and BLE bonds will be cleared. */
|
||||||
int32_t factory_reset_device;
|
int32_t factory_reset_device;
|
||||||
/* Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot)
|
/* Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot)
|
||||||
Only Implemented for ESP32 Devices. This needs to be issued to send a new main firmware via bluetooth. */
|
Only Implemented for ESP32 Devices. This needs to be issued to send a new main firmware via bluetooth.
|
||||||
|
Deprecated in favor of reboot_ota_mode in 2.7.17 */
|
||||||
int32_t reboot_ota_seconds;
|
int32_t reboot_ota_seconds;
|
||||||
/* This message is only supported for the simulator Portduino build.
|
/* This message is only supported for the simulator Portduino build.
|
||||||
If received the simulator will exit successfully. */
|
If received the simulator will exit successfully. */
|
||||||
@@ -275,6 +297,8 @@ typedef struct _meshtastic_AdminMessage {
|
|||||||
/* Tell the node to reset the nodedb.
|
/* Tell the node to reset the nodedb.
|
||||||
When true, favorites are preserved through reset. */
|
When true, favorites are preserved through reset. */
|
||||||
bool nodedb_reset;
|
bool nodedb_reset;
|
||||||
|
/* Tell the node to reset into the OTA Loader */
|
||||||
|
meshtastic_AdminMessage_OTAEvent ota_request;
|
||||||
};
|
};
|
||||||
/* The node generates this key and sends it with any get_x_response packets.
|
/* The node generates this key and sends it with any get_x_response packets.
|
||||||
The client MUST include the same key with any set_x commands. Key expires after 300 seconds.
|
The client MUST include the same key with any set_x commands. Key expires after 300 seconds.
|
||||||
@@ -288,6 +312,10 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Helper constants for enums */
|
/* Helper constants for enums */
|
||||||
|
#define _meshtastic_OTAMode_MIN meshtastic_OTAMode_NO_REBOOT_OTA
|
||||||
|
#define _meshtastic_OTAMode_MAX meshtastic_OTAMode_OTA_WIFI
|
||||||
|
#define _meshtastic_OTAMode_ARRAYSIZE ((meshtastic_OTAMode)(meshtastic_OTAMode_OTA_WIFI+1))
|
||||||
|
|
||||||
#define _meshtastic_AdminMessage_ConfigType_MIN meshtastic_AdminMessage_ConfigType_DEVICE_CONFIG
|
#define _meshtastic_AdminMessage_ConfigType_MIN meshtastic_AdminMessage_ConfigType_DEVICE_CONFIG
|
||||||
#define _meshtastic_AdminMessage_ConfigType_MAX meshtastic_AdminMessage_ConfigType_DEVICEUI_CONFIG
|
#define _meshtastic_AdminMessage_ConfigType_MAX meshtastic_AdminMessage_ConfigType_DEVICEUI_CONFIG
|
||||||
#define _meshtastic_AdminMessage_ConfigType_ARRAYSIZE ((meshtastic_AdminMessage_ConfigType)(meshtastic_AdminMessage_ConfigType_DEVICEUI_CONFIG+1))
|
#define _meshtastic_AdminMessage_ConfigType_ARRAYSIZE ((meshtastic_AdminMessage_ConfigType)(meshtastic_AdminMessage_ConfigType_DEVICEUI_CONFIG+1))
|
||||||
@@ -311,6 +339,8 @@ extern "C" {
|
|||||||
#define meshtastic_AdminMessage_payload_variant_remove_backup_preferences_ENUMTYPE meshtastic_AdminMessage_BackupLocation
|
#define meshtastic_AdminMessage_payload_variant_remove_backup_preferences_ENUMTYPE meshtastic_AdminMessage_BackupLocation
|
||||||
|
|
||||||
|
|
||||||
|
#define meshtastic_AdminMessage_OTAEvent_reboot_ota_mode_ENUMTYPE meshtastic_OTAMode
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -320,12 +350,14 @@ extern "C" {
|
|||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define meshtastic_AdminMessage_init_default {0, {0}, {0, {0}}}
|
#define meshtastic_AdminMessage_init_default {0, {0}, {0, {0}}}
|
||||||
#define meshtastic_AdminMessage_InputEvent_init_default {0, 0, 0, 0}
|
#define meshtastic_AdminMessage_InputEvent_init_default {0, 0, 0, 0}
|
||||||
|
#define meshtastic_AdminMessage_OTAEvent_init_default {_meshtastic_OTAMode_MIN, {0, {0}}}
|
||||||
#define meshtastic_HamParameters_init_default {"", 0, 0, ""}
|
#define meshtastic_HamParameters_init_default {"", 0, 0, ""}
|
||||||
#define meshtastic_NodeRemoteHardwarePinsResponse_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, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}}
|
#define meshtastic_NodeRemoteHardwarePinsResponse_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, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}}
|
||||||
#define meshtastic_SharedContact_init_default {0, false, meshtastic_User_init_default, 0, 0}
|
#define meshtastic_SharedContact_init_default {0, false, meshtastic_User_init_default, 0, 0}
|
||||||
#define meshtastic_KeyVerificationAdmin_init_default {_meshtastic_KeyVerificationAdmin_MessageType_MIN, 0, 0, false, 0}
|
#define meshtastic_KeyVerificationAdmin_init_default {_meshtastic_KeyVerificationAdmin_MessageType_MIN, 0, 0, false, 0}
|
||||||
#define meshtastic_AdminMessage_init_zero {0, {0}, {0, {0}}}
|
#define meshtastic_AdminMessage_init_zero {0, {0}, {0, {0}}}
|
||||||
#define meshtastic_AdminMessage_InputEvent_init_zero {0, 0, 0, 0}
|
#define meshtastic_AdminMessage_InputEvent_init_zero {0, 0, 0, 0}
|
||||||
|
#define meshtastic_AdminMessage_OTAEvent_init_zero {_meshtastic_OTAMode_MIN, {0, {0}}}
|
||||||
#define meshtastic_HamParameters_init_zero {"", 0, 0, ""}
|
#define meshtastic_HamParameters_init_zero {"", 0, 0, ""}
|
||||||
#define meshtastic_NodeRemoteHardwarePinsResponse_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, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}}
|
#define meshtastic_NodeRemoteHardwarePinsResponse_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, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}}
|
||||||
#define meshtastic_SharedContact_init_zero {0, false, meshtastic_User_init_zero, 0, 0}
|
#define meshtastic_SharedContact_init_zero {0, false, meshtastic_User_init_zero, 0, 0}
|
||||||
@@ -336,6 +368,8 @@ extern "C" {
|
|||||||
#define meshtastic_AdminMessage_InputEvent_kb_char_tag 2
|
#define meshtastic_AdminMessage_InputEvent_kb_char_tag 2
|
||||||
#define meshtastic_AdminMessage_InputEvent_touch_x_tag 3
|
#define meshtastic_AdminMessage_InputEvent_touch_x_tag 3
|
||||||
#define meshtastic_AdminMessage_InputEvent_touch_y_tag 4
|
#define meshtastic_AdminMessage_InputEvent_touch_y_tag 4
|
||||||
|
#define meshtastic_AdminMessage_OTAEvent_reboot_ota_mode_tag 1
|
||||||
|
#define meshtastic_AdminMessage_OTAEvent_ota_hash_tag 2
|
||||||
#define meshtastic_HamParameters_call_sign_tag 1
|
#define meshtastic_HamParameters_call_sign_tag 1
|
||||||
#define meshtastic_HamParameters_tx_power_tag 2
|
#define meshtastic_HamParameters_tx_power_tag 2
|
||||||
#define meshtastic_HamParameters_frequency_tag 3
|
#define meshtastic_HamParameters_frequency_tag 3
|
||||||
@@ -403,6 +437,7 @@ extern "C" {
|
|||||||
#define meshtastic_AdminMessage_shutdown_seconds_tag 98
|
#define meshtastic_AdminMessage_shutdown_seconds_tag 98
|
||||||
#define meshtastic_AdminMessage_factory_reset_config_tag 99
|
#define meshtastic_AdminMessage_factory_reset_config_tag 99
|
||||||
#define meshtastic_AdminMessage_nodedb_reset_tag 100
|
#define meshtastic_AdminMessage_nodedb_reset_tag 100
|
||||||
|
#define meshtastic_AdminMessage_ota_request_tag 102
|
||||||
#define meshtastic_AdminMessage_session_passkey_tag 101
|
#define meshtastic_AdminMessage_session_passkey_tag 101
|
||||||
|
|
||||||
/* Struct field encoding specification for nanopb */
|
/* Struct field encoding specification for nanopb */
|
||||||
@@ -461,7 +496,8 @@ X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_seconds,reboot_second
|
|||||||
X(a, STATIC, ONEOF, INT32, (payload_variant,shutdown_seconds,shutdown_seconds), 98) \
|
X(a, STATIC, ONEOF, INT32, (payload_variant,shutdown_seconds,shutdown_seconds), 98) \
|
||||||
X(a, STATIC, ONEOF, INT32, (payload_variant,factory_reset_config,factory_reset_config), 99) \
|
X(a, STATIC, ONEOF, INT32, (payload_variant,factory_reset_config,factory_reset_config), 99) \
|
||||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,nodedb_reset,nodedb_reset), 100) \
|
X(a, STATIC, ONEOF, BOOL, (payload_variant,nodedb_reset,nodedb_reset), 100) \
|
||||||
X(a, STATIC, SINGULAR, BYTES, session_passkey, 101)
|
X(a, STATIC, SINGULAR, BYTES, session_passkey, 101) \
|
||||||
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,ota_request,ota_request), 102)
|
||||||
#define meshtastic_AdminMessage_CALLBACK NULL
|
#define meshtastic_AdminMessage_CALLBACK NULL
|
||||||
#define meshtastic_AdminMessage_DEFAULT NULL
|
#define meshtastic_AdminMessage_DEFAULT NULL
|
||||||
#define meshtastic_AdminMessage_payload_variant_get_channel_response_MSGTYPE meshtastic_Channel
|
#define meshtastic_AdminMessage_payload_variant_get_channel_response_MSGTYPE meshtastic_Channel
|
||||||
@@ -482,6 +518,7 @@ X(a, STATIC, SINGULAR, BYTES, session_passkey, 101)
|
|||||||
#define meshtastic_AdminMessage_payload_variant_store_ui_config_MSGTYPE meshtastic_DeviceUIConfig
|
#define meshtastic_AdminMessage_payload_variant_store_ui_config_MSGTYPE meshtastic_DeviceUIConfig
|
||||||
#define meshtastic_AdminMessage_payload_variant_add_contact_MSGTYPE meshtastic_SharedContact
|
#define meshtastic_AdminMessage_payload_variant_add_contact_MSGTYPE meshtastic_SharedContact
|
||||||
#define meshtastic_AdminMessage_payload_variant_key_verification_MSGTYPE meshtastic_KeyVerificationAdmin
|
#define meshtastic_AdminMessage_payload_variant_key_verification_MSGTYPE meshtastic_KeyVerificationAdmin
|
||||||
|
#define meshtastic_AdminMessage_payload_variant_ota_request_MSGTYPE meshtastic_AdminMessage_OTAEvent
|
||||||
|
|
||||||
#define meshtastic_AdminMessage_InputEvent_FIELDLIST(X, a) \
|
#define meshtastic_AdminMessage_InputEvent_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, event_code, 1) \
|
X(a, STATIC, SINGULAR, UINT32, event_code, 1) \
|
||||||
@@ -491,6 +528,12 @@ X(a, STATIC, SINGULAR, UINT32, touch_y, 4)
|
|||||||
#define meshtastic_AdminMessage_InputEvent_CALLBACK NULL
|
#define meshtastic_AdminMessage_InputEvent_CALLBACK NULL
|
||||||
#define meshtastic_AdminMessage_InputEvent_DEFAULT NULL
|
#define meshtastic_AdminMessage_InputEvent_DEFAULT NULL
|
||||||
|
|
||||||
|
#define meshtastic_AdminMessage_OTAEvent_FIELDLIST(X, a) \
|
||||||
|
X(a, STATIC, SINGULAR, UENUM, reboot_ota_mode, 1) \
|
||||||
|
X(a, STATIC, SINGULAR, BYTES, ota_hash, 2)
|
||||||
|
#define meshtastic_AdminMessage_OTAEvent_CALLBACK NULL
|
||||||
|
#define meshtastic_AdminMessage_OTAEvent_DEFAULT NULL
|
||||||
|
|
||||||
#define meshtastic_HamParameters_FIELDLIST(X, a) \
|
#define meshtastic_HamParameters_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, STRING, call_sign, 1) \
|
X(a, STATIC, SINGULAR, STRING, call_sign, 1) \
|
||||||
X(a, STATIC, SINGULAR, INT32, tx_power, 2) \
|
X(a, STATIC, SINGULAR, INT32, tx_power, 2) \
|
||||||
@@ -524,6 +567,7 @@ X(a, STATIC, OPTIONAL, UINT32, security_number, 4)
|
|||||||
|
|
||||||
extern const pb_msgdesc_t meshtastic_AdminMessage_msg;
|
extern const pb_msgdesc_t meshtastic_AdminMessage_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_AdminMessage_InputEvent_msg;
|
extern const pb_msgdesc_t meshtastic_AdminMessage_InputEvent_msg;
|
||||||
|
extern const pb_msgdesc_t meshtastic_AdminMessage_OTAEvent_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_HamParameters_msg;
|
extern const pb_msgdesc_t meshtastic_HamParameters_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePinsResponse_msg;
|
extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePinsResponse_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_SharedContact_msg;
|
extern const pb_msgdesc_t meshtastic_SharedContact_msg;
|
||||||
@@ -532,6 +576,7 @@ extern const pb_msgdesc_t meshtastic_KeyVerificationAdmin_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_AdminMessage_fields &meshtastic_AdminMessage_msg
|
#define meshtastic_AdminMessage_fields &meshtastic_AdminMessage_msg
|
||||||
#define meshtastic_AdminMessage_InputEvent_fields &meshtastic_AdminMessage_InputEvent_msg
|
#define meshtastic_AdminMessage_InputEvent_fields &meshtastic_AdminMessage_InputEvent_msg
|
||||||
|
#define meshtastic_AdminMessage_OTAEvent_fields &meshtastic_AdminMessage_OTAEvent_msg
|
||||||
#define meshtastic_HamParameters_fields &meshtastic_HamParameters_msg
|
#define meshtastic_HamParameters_fields &meshtastic_HamParameters_msg
|
||||||
#define meshtastic_NodeRemoteHardwarePinsResponse_fields &meshtastic_NodeRemoteHardwarePinsResponse_msg
|
#define meshtastic_NodeRemoteHardwarePinsResponse_fields &meshtastic_NodeRemoteHardwarePinsResponse_msg
|
||||||
#define meshtastic_SharedContact_fields &meshtastic_SharedContact_msg
|
#define meshtastic_SharedContact_fields &meshtastic_SharedContact_msg
|
||||||
@@ -540,6 +585,7 @@ extern const pb_msgdesc_t meshtastic_KeyVerificationAdmin_msg;
|
|||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define MESHTASTIC_MESHTASTIC_ADMIN_PB_H_MAX_SIZE meshtastic_AdminMessage_size
|
#define MESHTASTIC_MESHTASTIC_ADMIN_PB_H_MAX_SIZE meshtastic_AdminMessage_size
|
||||||
#define meshtastic_AdminMessage_InputEvent_size 14
|
#define meshtastic_AdminMessage_InputEvent_size 14
|
||||||
|
#define meshtastic_AdminMessage_OTAEvent_size 36
|
||||||
#define meshtastic_AdminMessage_size 511
|
#define meshtastic_AdminMessage_size 511
|
||||||
#define meshtastic_HamParameters_size 31
|
#define meshtastic_HamParameters_size 31
|
||||||
#define meshtastic_KeyVerificationAdmin_size 25
|
#define meshtastic_KeyVerificationAdmin_size 25
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ PB_BIND(meshtastic_Data, meshtastic_Data, 2)
|
|||||||
PB_BIND(meshtastic_KeyVerification, meshtastic_KeyVerification, AUTO)
|
PB_BIND(meshtastic_KeyVerification, meshtastic_KeyVerification, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(meshtastic_StoreForwardPlusPlus, meshtastic_StoreForwardPlusPlus, 2)
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(meshtastic_Waypoint, meshtastic_Waypoint, AUTO)
|
PB_BIND(meshtastic_Waypoint, meshtastic_Waypoint, AUTO)
|
||||||
|
|
||||||
|
|
||||||
@@ -121,6 +124,8 @@ PB_BIND(meshtastic_ChunkedPayloadResponse, meshtastic_ChunkedPayloadResponse, AU
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -92,8 +92,8 @@ typedef enum _meshtastic_HardwareModel {
|
|||||||
Less common/prototype boards listed here (needs one more byte over the air)
|
Less common/prototype boards listed here (needs one more byte over the air)
|
||||||
--------------------------------------------------------------------------- */
|
--------------------------------------------------------------------------- */
|
||||||
meshtastic_HardwareModel_LORA_RELAY_V1 = 32,
|
meshtastic_HardwareModel_LORA_RELAY_V1 = 32,
|
||||||
/* TODO: REPLACE */
|
/* T-Echo Plus device from LilyGo */
|
||||||
meshtastic_HardwareModel_NRF52840DK = 33,
|
meshtastic_HardwareModel_T_ECHO_PLUS = 33,
|
||||||
/* TODO: REPLACE */
|
/* TODO: REPLACE */
|
||||||
meshtastic_HardwareModel_PPR = 34,
|
meshtastic_HardwareModel_PPR = 34,
|
||||||
/* TODO: REPLACE */
|
/* TODO: REPLACE */
|
||||||
@@ -475,9 +475,28 @@ typedef enum _meshtastic_Routing_Error {
|
|||||||
meshtastic_Routing_Error_ADMIN_PUBLIC_KEY_UNAUTHORIZED = 37,
|
meshtastic_Routing_Error_ADMIN_PUBLIC_KEY_UNAUTHORIZED = 37,
|
||||||
/* Airtime fairness rate limit exceeded for a packet
|
/* Airtime fairness rate limit exceeded for a packet
|
||||||
This typically enforced per portnum and is used to prevent a single node from monopolizing airtime */
|
This typically enforced per portnum and is used to prevent a single node from monopolizing airtime */
|
||||||
meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED = 38
|
meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED = 38,
|
||||||
|
/* PKI encryption failed, due to no public key for the remote node
|
||||||
|
This is different from PKI_UNKNOWN_PUBKEY which indicates a failure upon receiving a packet */
|
||||||
|
meshtastic_Routing_Error_PKI_SEND_FAIL_PUBLIC_KEY = 39
|
||||||
} meshtastic_Routing_Error;
|
} meshtastic_Routing_Error;
|
||||||
|
|
||||||
|
/* Enum of message types */
|
||||||
|
typedef enum _meshtastic_StoreForwardPlusPlus_SFPP_message_type {
|
||||||
|
/* Send an announcement of the canonical tip of a chain */
|
||||||
|
meshtastic_StoreForwardPlusPlus_SFPP_message_type_CANON_ANNOUNCE = 0,
|
||||||
|
/* Query whether a specific link is on the chain */
|
||||||
|
meshtastic_StoreForwardPlusPlus_SFPP_message_type_CHAIN_QUERY = 1,
|
||||||
|
/* Request the next link in the chain */
|
||||||
|
meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_REQUEST = 3,
|
||||||
|
/* Provide a link to add to the chain */
|
||||||
|
meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE = 4,
|
||||||
|
/* If we must fragment, send the first half */
|
||||||
|
meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE_FIRSTHALF = 5,
|
||||||
|
/* If we must fragment, send the second half */
|
||||||
|
meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE_SECONDHALF = 6
|
||||||
|
} meshtastic_StoreForwardPlusPlus_SFPP_message_type;
|
||||||
|
|
||||||
/* The priority of this message for sending.
|
/* The priority of this message for sending.
|
||||||
Higher priorities are sent first (when managing the transmit queue).
|
Higher priorities are sent first (when managing the transmit queue).
|
||||||
This field is never sent over the air, it is only used internally inside of a local device node.
|
This field is never sent over the air, it is only used internally inside of a local device node.
|
||||||
@@ -782,6 +801,34 @@ typedef struct _meshtastic_KeyVerification {
|
|||||||
meshtastic_KeyVerification_hash2_t hash2;
|
meshtastic_KeyVerification_hash2_t hash2;
|
||||||
} meshtastic_KeyVerification;
|
} meshtastic_KeyVerification;
|
||||||
|
|
||||||
|
typedef PB_BYTES_ARRAY_T(32) meshtastic_StoreForwardPlusPlus_message_hash_t;
|
||||||
|
typedef PB_BYTES_ARRAY_T(32) meshtastic_StoreForwardPlusPlus_commit_hash_t;
|
||||||
|
typedef PB_BYTES_ARRAY_T(32) meshtastic_StoreForwardPlusPlus_root_hash_t;
|
||||||
|
typedef PB_BYTES_ARRAY_T(240) meshtastic_StoreForwardPlusPlus_message_t;
|
||||||
|
/* The actual over-the-mesh message doing store and forward++ */
|
||||||
|
typedef struct _meshtastic_StoreForwardPlusPlus {
|
||||||
|
/* Which message type is this */
|
||||||
|
meshtastic_StoreForwardPlusPlus_SFPP_message_type sfpp_message_type;
|
||||||
|
/* The hash of the specific message */
|
||||||
|
meshtastic_StoreForwardPlusPlus_message_hash_t message_hash;
|
||||||
|
/* The hash of a link on a chain */
|
||||||
|
meshtastic_StoreForwardPlusPlus_commit_hash_t commit_hash;
|
||||||
|
/* the root hash of a chain */
|
||||||
|
meshtastic_StoreForwardPlusPlus_root_hash_t root_hash;
|
||||||
|
/* The encrypted bytes from a message */
|
||||||
|
meshtastic_StoreForwardPlusPlus_message_t message;
|
||||||
|
/* Message ID of the contained message */
|
||||||
|
uint32_t encapsulated_id;
|
||||||
|
/* Destination of the contained message */
|
||||||
|
uint32_t encapsulated_to;
|
||||||
|
/* Sender of the contained message */
|
||||||
|
uint32_t encapsulated_from;
|
||||||
|
/* The receive time of the message in question */
|
||||||
|
uint32_t encapsulated_rxtime;
|
||||||
|
/* Used in a LINK_REQUEST to specify the message X spots back from head */
|
||||||
|
uint32_t chain_count;
|
||||||
|
} meshtastic_StoreForwardPlusPlus;
|
||||||
|
|
||||||
/* Waypoint message, used to share arbitrary locations across the mesh */
|
/* Waypoint message, used to share arbitrary locations across the mesh */
|
||||||
typedef struct _meshtastic_Waypoint {
|
typedef struct _meshtastic_Waypoint {
|
||||||
/* Id of the waypoint */
|
/* Id of the waypoint */
|
||||||
@@ -1307,8 +1354,12 @@ extern "C" {
|
|||||||
#define _meshtastic_Position_AltSource_ARRAYSIZE ((meshtastic_Position_AltSource)(meshtastic_Position_AltSource_ALT_BAROMETRIC+1))
|
#define _meshtastic_Position_AltSource_ARRAYSIZE ((meshtastic_Position_AltSource)(meshtastic_Position_AltSource_ALT_BAROMETRIC+1))
|
||||||
|
|
||||||
#define _meshtastic_Routing_Error_MIN meshtastic_Routing_Error_NONE
|
#define _meshtastic_Routing_Error_MIN meshtastic_Routing_Error_NONE
|
||||||
#define _meshtastic_Routing_Error_MAX meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED
|
#define _meshtastic_Routing_Error_MAX meshtastic_Routing_Error_PKI_SEND_FAIL_PUBLIC_KEY
|
||||||
#define _meshtastic_Routing_Error_ARRAYSIZE ((meshtastic_Routing_Error)(meshtastic_Routing_Error_RATE_LIMIT_EXCEEDED+1))
|
#define _meshtastic_Routing_Error_ARRAYSIZE ((meshtastic_Routing_Error)(meshtastic_Routing_Error_PKI_SEND_FAIL_PUBLIC_KEY+1))
|
||||||
|
|
||||||
|
#define _meshtastic_StoreForwardPlusPlus_SFPP_message_type_MIN meshtastic_StoreForwardPlusPlus_SFPP_message_type_CANON_ANNOUNCE
|
||||||
|
#define _meshtastic_StoreForwardPlusPlus_SFPP_message_type_MAX meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE_SECONDHALF
|
||||||
|
#define _meshtastic_StoreForwardPlusPlus_SFPP_message_type_ARRAYSIZE ((meshtastic_StoreForwardPlusPlus_SFPP_message_type)(meshtastic_StoreForwardPlusPlus_SFPP_message_type_LINK_PROVIDE_SECONDHALF+1))
|
||||||
|
|
||||||
#define _meshtastic_MeshPacket_Priority_MIN meshtastic_MeshPacket_Priority_UNSET
|
#define _meshtastic_MeshPacket_Priority_MIN meshtastic_MeshPacket_Priority_UNSET
|
||||||
#define _meshtastic_MeshPacket_Priority_MAX meshtastic_MeshPacket_Priority_MAX
|
#define _meshtastic_MeshPacket_Priority_MAX meshtastic_MeshPacket_Priority_MAX
|
||||||
@@ -1338,6 +1389,8 @@ extern "C" {
|
|||||||
#define meshtastic_Data_portnum_ENUMTYPE meshtastic_PortNum
|
#define meshtastic_Data_portnum_ENUMTYPE meshtastic_PortNum
|
||||||
|
|
||||||
|
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_sfpp_message_type_ENUMTYPE meshtastic_StoreForwardPlusPlus_SFPP_message_type
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define meshtastic_MeshPacket_priority_ENUMTYPE meshtastic_MeshPacket_Priority
|
#define meshtastic_MeshPacket_priority_ENUMTYPE meshtastic_MeshPacket_Priority
|
||||||
@@ -1380,6 +1433,7 @@ extern "C" {
|
|||||||
#define meshtastic_Routing_init_default {0, {meshtastic_RouteDiscovery_init_default}}
|
#define meshtastic_Routing_init_default {0, {meshtastic_RouteDiscovery_init_default}}
|
||||||
#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
|
#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
|
||||||
#define meshtastic_KeyVerification_init_default {0, {0, {0}}, {0, {0}}}
|
#define meshtastic_KeyVerification_init_default {0, {0, {0}}, {0, {0}}}
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_init_default {_meshtastic_StoreForwardPlusPlus_SFPP_message_type_MIN, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_Waypoint_init_default {0, false, 0, false, 0, 0, 0, "", "", 0}
|
#define meshtastic_Waypoint_init_default {0, false, 0, false, 0, 0, 0, "", "", 0}
|
||||||
#define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0}
|
#define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0}
|
||||||
#define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN}
|
#define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN}
|
||||||
@@ -1411,6 +1465,7 @@ extern "C" {
|
|||||||
#define meshtastic_Routing_init_zero {0, {meshtastic_RouteDiscovery_init_zero}}
|
#define meshtastic_Routing_init_zero {0, {meshtastic_RouteDiscovery_init_zero}}
|
||||||
#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
|
#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
|
||||||
#define meshtastic_KeyVerification_init_zero {0, {0, {0}}, {0, {0}}}
|
#define meshtastic_KeyVerification_init_zero {0, {0, {0}}, {0, {0}}}
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_init_zero {_meshtastic_StoreForwardPlusPlus_SFPP_message_type_MIN, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_Waypoint_init_zero {0, false, 0, false, 0, 0, 0, "", "", 0}
|
#define meshtastic_Waypoint_init_zero {0, false, 0, false, 0, 0, 0, "", "", 0}
|
||||||
#define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0}
|
#define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0}
|
||||||
#define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN}
|
#define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0, _meshtastic_MeshPacket_TransportMechanism_MIN}
|
||||||
@@ -1489,6 +1544,16 @@ extern "C" {
|
|||||||
#define meshtastic_KeyVerification_nonce_tag 1
|
#define meshtastic_KeyVerification_nonce_tag 1
|
||||||
#define meshtastic_KeyVerification_hash1_tag 2
|
#define meshtastic_KeyVerification_hash1_tag 2
|
||||||
#define meshtastic_KeyVerification_hash2_tag 3
|
#define meshtastic_KeyVerification_hash2_tag 3
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_sfpp_message_type_tag 1
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_message_hash_tag 2
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_commit_hash_tag 3
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_root_hash_tag 4
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_message_tag 5
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_encapsulated_id_tag 6
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_encapsulated_to_tag 7
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_encapsulated_from_tag 8
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_encapsulated_rxtime_tag 9
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_chain_count_tag 10
|
||||||
#define meshtastic_Waypoint_id_tag 1
|
#define meshtastic_Waypoint_id_tag 1
|
||||||
#define meshtastic_Waypoint_latitude_i_tag 2
|
#define meshtastic_Waypoint_latitude_i_tag 2
|
||||||
#define meshtastic_Waypoint_longitude_i_tag 3
|
#define meshtastic_Waypoint_longitude_i_tag 3
|
||||||
@@ -1705,6 +1770,20 @@ X(a, STATIC, SINGULAR, BYTES, hash2, 3)
|
|||||||
#define meshtastic_KeyVerification_CALLBACK NULL
|
#define meshtastic_KeyVerification_CALLBACK NULL
|
||||||
#define meshtastic_KeyVerification_DEFAULT NULL
|
#define meshtastic_KeyVerification_DEFAULT NULL
|
||||||
|
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_FIELDLIST(X, a) \
|
||||||
|
X(a, STATIC, SINGULAR, UENUM, sfpp_message_type, 1) \
|
||||||
|
X(a, STATIC, SINGULAR, BYTES, message_hash, 2) \
|
||||||
|
X(a, STATIC, SINGULAR, BYTES, commit_hash, 3) \
|
||||||
|
X(a, STATIC, SINGULAR, BYTES, root_hash, 4) \
|
||||||
|
X(a, STATIC, SINGULAR, BYTES, message, 5) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, encapsulated_id, 6) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, encapsulated_to, 7) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, encapsulated_from, 8) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, encapsulated_rxtime, 9) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, chain_count, 10)
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_CALLBACK NULL
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_DEFAULT NULL
|
||||||
|
|
||||||
#define meshtastic_Waypoint_FIELDLIST(X, a) \
|
#define meshtastic_Waypoint_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, id, 1) \
|
X(a, STATIC, SINGULAR, UINT32, id, 1) \
|
||||||
X(a, STATIC, OPTIONAL, SFIXED32, latitude_i, 2) \
|
X(a, STATIC, OPTIONAL, SFIXED32, latitude_i, 2) \
|
||||||
@@ -1980,6 +2059,7 @@ extern const pb_msgdesc_t meshtastic_RouteDiscovery_msg;
|
|||||||
extern const pb_msgdesc_t meshtastic_Routing_msg;
|
extern const pb_msgdesc_t meshtastic_Routing_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_Data_msg;
|
extern const pb_msgdesc_t meshtastic_Data_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_KeyVerification_msg;
|
extern const pb_msgdesc_t meshtastic_KeyVerification_msg;
|
||||||
|
extern const pb_msgdesc_t meshtastic_StoreForwardPlusPlus_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_Waypoint_msg;
|
extern const pb_msgdesc_t meshtastic_Waypoint_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_MqttClientProxyMessage_msg;
|
extern const pb_msgdesc_t meshtastic_MqttClientProxyMessage_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_MeshPacket_msg;
|
extern const pb_msgdesc_t meshtastic_MeshPacket_msg;
|
||||||
@@ -2013,6 +2093,7 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
|
|||||||
#define meshtastic_Routing_fields &meshtastic_Routing_msg
|
#define meshtastic_Routing_fields &meshtastic_Routing_msg
|
||||||
#define meshtastic_Data_fields &meshtastic_Data_msg
|
#define meshtastic_Data_fields &meshtastic_Data_msg
|
||||||
#define meshtastic_KeyVerification_fields &meshtastic_KeyVerification_msg
|
#define meshtastic_KeyVerification_fields &meshtastic_KeyVerification_msg
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_fields &meshtastic_StoreForwardPlusPlus_msg
|
||||||
#define meshtastic_Waypoint_fields &meshtastic_Waypoint_msg
|
#define meshtastic_Waypoint_fields &meshtastic_Waypoint_msg
|
||||||
#define meshtastic_MqttClientProxyMessage_fields &meshtastic_MqttClientProxyMessage_msg
|
#define meshtastic_MqttClientProxyMessage_fields &meshtastic_MqttClientProxyMessage_msg
|
||||||
#define meshtastic_MeshPacket_fields &meshtastic_MeshPacket_msg
|
#define meshtastic_MeshPacket_fields &meshtastic_MeshPacket_msg
|
||||||
@@ -2069,6 +2150,7 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
|
|||||||
#define meshtastic_QueueStatus_size 23
|
#define meshtastic_QueueStatus_size 23
|
||||||
#define meshtastic_RouteDiscovery_size 256
|
#define meshtastic_RouteDiscovery_size 256
|
||||||
#define meshtastic_Routing_size 259
|
#define meshtastic_Routing_size 259
|
||||||
|
#define meshtastic_StoreForwardPlusPlus_size 377
|
||||||
#define meshtastic_ToRadio_size 504
|
#define meshtastic_ToRadio_size 504
|
||||||
#define meshtastic_User_size 115
|
#define meshtastic_User_size 115
|
||||||
#define meshtastic_Waypoint_size 165
|
#define meshtastic_Waypoint_size 165
|
||||||
|
|||||||
@@ -86,6 +86,11 @@ typedef enum _meshtastic_PortNum {
|
|||||||
/* Paxcounter lib included in the firmware
|
/* Paxcounter lib included in the firmware
|
||||||
ENCODING: protobuf */
|
ENCODING: protobuf */
|
||||||
meshtastic_PortNum_PAXCOUNTER_APP = 34,
|
meshtastic_PortNum_PAXCOUNTER_APP = 34,
|
||||||
|
/* Store and Forward++ module included in the firmware
|
||||||
|
ENCODING: protobuf
|
||||||
|
This module is specifically for Native Linux nodes, and provides a Git-style
|
||||||
|
chain of messages. */
|
||||||
|
meshtastic_PortNum_STORE_FORWARD_PLUSPLUS_APP = 35,
|
||||||
/* Provides a hardware serial interface to send and receive from the Meshtastic network.
|
/* Provides a hardware serial interface to send and receive from the Meshtastic network.
|
||||||
Connect to the RX/TX pins of a device with 38400 8N1. Packets received from the Meshtastic
|
Connect to the RX/TX pins of a device with 38400 8N1. Packets received from the Meshtastic
|
||||||
network is forwarded to the RX pin while sending a packet to TX will go out to the Mesh network.
|
network is forwarded to the RX pin while sending a packet to TX will go out to the Mesh network.
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ int32_t ExternalNotificationModule::runOnce()
|
|||||||
delay = EXT_NOTIFICATION_FAST_THREAD_MS;
|
delay = EXT_NOTIFICATION_FAST_THREAD_MS;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(T_WATCH_S3) || defined(T_LORA_PAGER)
|
#ifdef HAS_DRV2605
|
||||||
drv.go();
|
drv.go();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -283,7 +283,7 @@ void ExternalNotificationModule::setExternalState(uint8_t index, bool on)
|
|||||||
#ifdef UNPHONE
|
#ifdef UNPHONE
|
||||||
unphone.rgb(red, green, blue);
|
unphone.rgb(red, green, blue);
|
||||||
#endif
|
#endif
|
||||||
#if defined(T_WATCH_S3) || defined(T_LORA_PAGER)
|
#ifdef HAS_DRV2605
|
||||||
if (on) {
|
if (on) {
|
||||||
drv.go();
|
drv.go();
|
||||||
} else {
|
} else {
|
||||||
@@ -319,7 +319,7 @@ void ExternalNotificationModule::stopNow()
|
|||||||
externalTurnedOn[i] = 0;
|
externalTurnedOn[i] = 0;
|
||||||
}
|
}
|
||||||
setIntervalFromNow(0);
|
setIntervalFromNow(0);
|
||||||
#if defined(T_WATCH_S3) || defined(T_LORA_PAGER)
|
#ifdef HAS_DRV2605
|
||||||
drv.stop();
|
drv.stop();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -63,9 +63,9 @@
|
|||||||
SerialModule *serialModule;
|
SerialModule *serialModule;
|
||||||
SerialModuleRadio *serialModuleRadio;
|
SerialModuleRadio *serialModuleRadio;
|
||||||
|
|
||||||
#if defined(TTGO_T_ECHO) || defined(CANARYONE) || defined(MESHLINK) || defined(ELECROW_ThinkNode_M1) || \
|
#if defined(TTGO_T_ECHO) || defined(TTGO_T_ECHO_PLUS) || defined(CANARYONE) || defined(MESHLINK) || \
|
||||||
defined(ELECROW_ThinkNode_M5) || defined(HELTEC_MESH_SOLAR) || defined(T_ECHO_LITE) || defined(ELECROW_ThinkNode_M3) || \
|
defined(ELECROW_ThinkNode_M1) || defined(ELECROW_ThinkNode_M5) || defined(HELTEC_MESH_SOLAR) || defined(T_ECHO_LITE) || \
|
||||||
defined(MUZI_BASE)
|
defined(ELECROW_ThinkNode_M3) || defined(MUZI_BASE)
|
||||||
SerialModule::SerialModule() : StreamAPI(&Serial), concurrency::OSThread("Serial")
|
SerialModule::SerialModule() : StreamAPI(&Serial), concurrency::OSThread("Serial")
|
||||||
{
|
{
|
||||||
api_type = TYPE_SERIAL;
|
api_type = TYPE_SERIAL;
|
||||||
@@ -204,8 +204,9 @@ int32_t SerialModule::runOnce()
|
|||||||
Serial.begin(baud);
|
Serial.begin(baud);
|
||||||
Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
|
Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
|
||||||
}
|
}
|
||||||
#elif !defined(TTGO_T_ECHO) && !defined(T_ECHO_LITE) && !defined(CANARYONE) && !defined(MESHLINK) && \
|
#elif !defined(TTGO_T_ECHO) && !defined(TTGO_T_ECHO_PLUS) && !defined(T_ECHO_LITE) && !defined(CANARYONE) && \
|
||||||
!defined(ELECROW_ThinkNode_M1) && !defined(ELECROW_ThinkNode_M3) && !defined(ELECROW_ThinkNode_M5) && !defined(MUZI_BASE)
|
!defined(MESHLINK) && !defined(ELECROW_ThinkNode_M1) && !defined(ELECROW_ThinkNode_M3) && !defined(ELECROW_ThinkNode_M5) && \
|
||||||
|
!defined(MUZI_BASE)
|
||||||
if (moduleConfig.serial.rxd && moduleConfig.serial.txd) {
|
if (moduleConfig.serial.rxd && moduleConfig.serial.txd) {
|
||||||
#ifdef ARCH_RP2040
|
#ifdef ARCH_RP2040
|
||||||
Serial2.setFIFOSize(RX_BUFFER);
|
Serial2.setFIFOSize(RX_BUFFER);
|
||||||
@@ -261,7 +262,7 @@ int32_t SerialModule::runOnce()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(TTGO_T_ECHO) && !defined(T_ECHO_LITE) && !defined(CANARYONE) && !defined(MESHLINK) && \
|
#if !defined(TTGO_T_ECHO) && !defined(TTGO_T_ECHO_PLUS) && !defined(T_ECHO_LITE) && !defined(CANARYONE) && !defined(MESHLINK) && \
|
||||||
!defined(ELECROW_ThinkNode_M1) && !defined(ELECROW_ThinkNode_M3) && !defined(ELECROW_ThinkNode_M5) && !defined(MUZI_BASE)
|
!defined(ELECROW_ThinkNode_M1) && !defined(ELECROW_ThinkNode_M3) && !defined(ELECROW_ThinkNode_M5) && !defined(MUZI_BASE)
|
||||||
else if ((moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_WS85)) {
|
else if ((moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_WS85)) {
|
||||||
processWXSerial();
|
processWXSerial();
|
||||||
@@ -536,9 +537,9 @@ ParsedLine parseLine(const char *line)
|
|||||||
*/
|
*/
|
||||||
void SerialModule::processWXSerial()
|
void SerialModule::processWXSerial()
|
||||||
{
|
{
|
||||||
#if !defined(TTGO_T_ECHO) && !defined(T_ECHO_LITE) && !defined(CANARYONE) && !defined(CONFIG_IDF_TARGET_ESP32C6) && \
|
#if !defined(TTGO_T_ECHO) && !defined(TTGO_T_ECHO_PLUS) && !defined(T_ECHO_LITE) && !defined(CANARYONE) && \
|
||||||
!defined(MESHLINK) && !defined(ELECROW_ThinkNode_M1) && !defined(ELECROW_ThinkNode_M3) && !defined(ELECROW_ThinkNode_M5) && \
|
!defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(MESHLINK) && !defined(ELECROW_ThinkNode_M1) && \
|
||||||
!defined(ARCH_STM32WL) && !defined(MUZI_BASE)
|
!defined(ELECROW_ThinkNode_M3) && !defined(ELECROW_ThinkNode_M5) && !defined(ARCH_STM32WL) && !defined(MUZI_BASE)
|
||||||
static unsigned int lastAveraged = 0;
|
static unsigned int lastAveraged = 0;
|
||||||
static unsigned int averageIntervalMillis = 300000; // 5 minutes hard coded.
|
static unsigned int averageIntervalMillis = 300000; // 5 minutes hard coded.
|
||||||
static double dir_sum_sin = 0;
|
static double dir_sum_sin = 0;
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
#include "configuration.h"
|
|
||||||
|
|
||||||
#ifdef T5_S3_EPAPER_PRO
|
|
||||||
|
|
||||||
#include "TouchDrvGT911.hpp"
|
|
||||||
#include "Wire.h"
|
|
||||||
#include "input/TouchScreenImpl1.h"
|
|
||||||
|
|
||||||
TouchDrvGT911 touch;
|
|
||||||
|
|
||||||
bool readTouch(int16_t *x, int16_t *y)
|
|
||||||
{
|
|
||||||
if (!digitalRead(GT911_PIN_INT)) {
|
|
||||||
int16_t raw_x;
|
|
||||||
int16_t raw_y;
|
|
||||||
if (touch.getPoint(&raw_x, &raw_y)) {
|
|
||||||
// rotate 90° for landscape
|
|
||||||
*x = raw_y;
|
|
||||||
*y = EPD_WIDTH - 1 - raw_x;
|
|
||||||
LOG_DEBUG("touched(%d/%d)", *x, *y);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// T5-S3-ePaper Pro specific (late-) init
|
|
||||||
void lateInitVariant(void)
|
|
||||||
{
|
|
||||||
touch.setPins(GT911_PIN_RST, GT911_PIN_INT);
|
|
||||||
if (touch.begin(Wire, GT911_SLAVE_ADDRESS_L, GT911_PIN_SDA, GT911_PIN_SCL)) {
|
|
||||||
touchScreenImpl1 = new TouchScreenImpl1(EPD_WIDTH, EPD_HEIGHT, readTouch);
|
|
||||||
touchScreenImpl1->init();
|
|
||||||
} else {
|
|
||||||
LOG_ERROR("Failed to find touch controller!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -66,6 +66,8 @@
|
|||||||
#define HW_VENDOR meshtastic_HardwareModel_T_ECHO
|
#define HW_VENDOR meshtastic_HardwareModel_T_ECHO
|
||||||
#elif defined(T_ECHO_LITE)
|
#elif defined(T_ECHO_LITE)
|
||||||
#define HW_VENDOR meshtastic_HardwareModel_T_ECHO_LITE
|
#define HW_VENDOR meshtastic_HardwareModel_T_ECHO_LITE
|
||||||
|
#elif defined(TTGO_T_ECHO_PLUS)
|
||||||
|
#define HW_VENDOR meshtastic_HardwareModel_T_ECHO_PLUS
|
||||||
#elif defined(ELECROW_ThinkNode_M1)
|
#elif defined(ELECROW_ThinkNode_M1)
|
||||||
#define HW_VENDOR meshtastic_HardwareModel_THINKNODE_M1
|
#define HW_VENDOR meshtastic_HardwareModel_THINKNODE_M1
|
||||||
#elif defined(ELECROW_ThinkNode_M3)
|
#elif defined(ELECROW_ThinkNode_M3)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
[env:tbeam]
|
[env:tbeam]
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = ttgo-t-beam
|
board = ttgo-t-beam
|
||||||
board_level = extra
|
|
||||||
board_check = true
|
board_check = true
|
||||||
lib_deps = ${esp32_base.lib_deps}
|
lib_deps = ${esp32_base.lib_deps}
|
||||||
build_flags = ${esp32_base.build_flags}
|
build_flags = ${esp32_base.build_flags}
|
||||||
@@ -14,7 +14,7 @@ upload_speed = 921600
|
|||||||
|
|
||||||
[env:tbeam-displayshield]
|
[env:tbeam-displayshield]
|
||||||
extends = env:tbeam
|
extends = env:tbeam
|
||||||
|
board_level = extra
|
||||||
build_flags =
|
build_flags =
|
||||||
${env:tbeam.build_flags}
|
${env:tbeam.build_flags}
|
||||||
-D USE_ST7796
|
-D USE_ST7796
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
#define SCREEN_TRANSITION_FRAMERATE 5 // fps
|
#define SCREEN_TRANSITION_FRAMERATE 5 // fps
|
||||||
#define USE_TFTDISPLAY 1
|
#define USE_TFTDISPLAY 1
|
||||||
|
|
||||||
|
#define HAS_DRV2605 1
|
||||||
|
|
||||||
#define HAS_TOUCHSCREEN 1
|
#define HAS_TOUCHSCREEN 1
|
||||||
#define SCREEN_TOUCH_INT 16
|
#define SCREEN_TOUCH_INT 16
|
||||||
#define SCREEN_TOUCH_USE_I2C1
|
#define SCREEN_TOUCH_USE_I2C1
|
||||||
|
|||||||
@@ -1,123 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Most of the Meshtastic firmware uses preprocessor macros throughout the code to support different hardware variants.
|
|
||||||
NicheGraphics attempts a different approach:
|
|
||||||
|
|
||||||
Per-device config takes place in this setupNicheGraphics() method
|
|
||||||
(And a small amount in platformio.ini)
|
|
||||||
|
|
||||||
This file sets up InkHUD for Heltec VM-E290.
|
|
||||||
Different NicheGraphics UIs and different hardware variants will each have their own setup procedure.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "configuration.h"
|
|
||||||
#include "mesh/MeshModule.h"
|
|
||||||
|
|
||||||
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
|
||||||
|
|
||||||
// InkHUD-specific components
|
|
||||||
// ---------------------------
|
|
||||||
// #include "graphics/niche/InkHUD/InkHUD.h"
|
|
||||||
#include "graphics/niche/InkHUD/WindowManager.h"
|
|
||||||
|
|
||||||
// Applets
|
|
||||||
#include "graphics/niche/InkHUD/Applets/User/AllMessage/AllMessageApplet.h"
|
|
||||||
#include "graphics/niche/InkHUD/Applets/User/DM/DMApplet.h"
|
|
||||||
#include "graphics/niche/InkHUD/Applets/User/Heard/HeardApplet.h"
|
|
||||||
#include "graphics/niche/InkHUD/Applets/User/Positions/PositionsApplet.h"
|
|
||||||
#include "graphics/niche/InkHUD/Applets/User/RecentsList/RecentsListApplet.h"
|
|
||||||
#include "graphics/niche/InkHUD/Applets/User/ThreadedMessage/ThreadedMessageApplet.h"
|
|
||||||
|
|
||||||
// Shared NicheGraphics components
|
|
||||||
// --------------------------------
|
|
||||||
#include "graphics/niche/Drivers/Backlight/LatchingBacklight.h"
|
|
||||||
#include "graphics/niche/Drivers/EInk/DEPG0290BNS800.h"
|
|
||||||
#include "graphics/niche/Inputs/TwoButton.h"
|
|
||||||
|
|
||||||
void setupNicheGraphics()
|
|
||||||
{
|
|
||||||
using namespace NicheGraphics;
|
|
||||||
|
|
||||||
// SPI
|
|
||||||
// -----------------------------
|
|
||||||
|
|
||||||
// Display is connected to HSPI
|
|
||||||
SPIClass *hspi = new SPIClass(HSPI);
|
|
||||||
hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS);
|
|
||||||
|
|
||||||
// E-Ink Driver
|
|
||||||
// -----------------------------
|
|
||||||
|
|
||||||
// Use E-Ink driver
|
|
||||||
Drivers::EInk *driver = new Drivers::DEPG0290BNS800;
|
|
||||||
driver->begin(hspi, PIN_EINK_DC, PIN_EINK_CS, PIN_EINK_BUSY);
|
|
||||||
|
|
||||||
// InkHUD
|
|
||||||
// ----------------------------
|
|
||||||
|
|
||||||
InkHUD::InkHUD *inkhud = InkHUD::InkHUD::getInstance();
|
|
||||||
|
|
||||||
// Set the driver
|
|
||||||
inkhud->setDriver(driver);
|
|
||||||
|
|
||||||
// Set how many FAST updates per FULL update
|
|
||||||
// Set how unhealthy additional FAST updates beyond this number are
|
|
||||||
inkhud->setDisplayResilience(7, 1.5);
|
|
||||||
|
|
||||||
// Prepare fonts
|
|
||||||
InkHUD::Applet::fontLarge = FREESANS_9PT_WIN1252;
|
|
||||||
InkHUD::Applet::fontSmall = FREESANS_6PT_WIN1252;
|
|
||||||
|
|
||||||
// Init settings, and customize defaults
|
|
||||||
inkhud->persistence->settings.userTiles.maxCount = 2; // How many tiles can the display handle?
|
|
||||||
inkhud->persistence->settings.rotation = 1; // 90 degrees clockwise
|
|
||||||
inkhud->persistence->settings.userTiles.count = 1; // One tile only by default, keep things simple for new users
|
|
||||||
inkhud->persistence->settings.optionalMenuItems.nextTile = false; // Behavior handled by aux button instead
|
|
||||||
inkhud->persistence->settings.optionalFeatures.batteryIcon = true; // Device definitely has a battery
|
|
||||||
|
|
||||||
// Setup backlight
|
|
||||||
// Note: AUX button behavior configured further down
|
|
||||||
Drivers::LatchingBacklight *backlight = Drivers::LatchingBacklight::getInstance();
|
|
||||||
backlight->setPin(PIN_EINK_EN);
|
|
||||||
|
|
||||||
// Pick applets
|
|
||||||
// Note: order of applets determines priority of "auto-show" feature
|
|
||||||
// Optional arguments for defaults:
|
|
||||||
// - is activated?
|
|
||||||
// - is autoshown?
|
|
||||||
// - is foreground on a specific tile (index)?
|
|
||||||
inkhud->addApplet("All Messages", new InkHUD::AllMessageApplet, true, true); // Activated, autoshown
|
|
||||||
inkhud->addApplet("DMs", new InkHUD::DMApplet);
|
|
||||||
inkhud->addApplet("Channel 0", new InkHUD::ThreadedMessageApplet(0));
|
|
||||||
inkhud->addApplet("Channel 1", new InkHUD::ThreadedMessageApplet(1));
|
|
||||||
inkhud->addApplet("Positions", new InkHUD::PositionsApplet, true); // Activated
|
|
||||||
inkhud->addApplet("Recents List", new InkHUD::RecentsListApplet);
|
|
||||||
inkhud->addApplet("Heard", new InkHUD::HeardApplet, true, false, 0); // Activated, not autoshown, default on tile 0
|
|
||||||
// inkhud->addApplet("Basic", new InkHUD::BasicExampleApplet);
|
|
||||||
// inkhud->addApplet("NewMsg", new InkHUD::NewMsgExampleApplet);
|
|
||||||
|
|
||||||
// Start running InkHUD
|
|
||||||
inkhud->begin();
|
|
||||||
|
|
||||||
// Buttons
|
|
||||||
// --------------------------
|
|
||||||
|
|
||||||
Inputs::TwoButton *buttons = Inputs::TwoButton::getInstance(); // A shared NicheGraphics component
|
|
||||||
|
|
||||||
// Setup the main user button (0)
|
|
||||||
buttons->setWiring(0, BUTTON_PIN);
|
|
||||||
buttons->setHandlerShortPress(0, []() { InkHUD::InkHUD::getInstance()->shortpress(); });
|
|
||||||
buttons->setHandlerLongPress(0, []() { InkHUD::InkHUD::getInstance()->longpress(); });
|
|
||||||
|
|
||||||
// Setup the aux button (1)
|
|
||||||
// Bonus feature of VME290
|
|
||||||
buttons->setWiring(1, BUTTON_PIN_SECONDARY);
|
|
||||||
buttons->setHandlerShortPress(1, []() { InkHUD::InkHUD::getInstance()->nextTile(); });
|
|
||||||
|
|
||||||
buttons->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
#ifndef Pins_Arduino_h
|
|
||||||
#define Pins_Arduino_h
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define USB_VID 0x303a
|
|
||||||
#define USB_PID 0x1001
|
|
||||||
|
|
||||||
#if defined(T5_S3_EPAPER_PRO_V1)
|
|
||||||
// The default Wire will be mapped to RTC, Touch, BQ25896, and BQ27220
|
|
||||||
static const uint8_t SDA = 6;
|
|
||||||
static const uint8_t SCL = 5;
|
|
||||||
|
|
||||||
// Default SPI will be mapped to Radio
|
|
||||||
static const uint8_t SS = 46;
|
|
||||||
static const uint8_t MOSI = 17;
|
|
||||||
static const uint8_t MISO = 8;
|
|
||||||
static const uint8_t SCK = 18;
|
|
||||||
|
|
||||||
#define SPI_MOSI (17)
|
|
||||||
#define SPI_SCK (18)
|
|
||||||
#define SPI_MISO (8)
|
|
||||||
#define SPI_CS (16)
|
|
||||||
|
|
||||||
#else // T5_S3_EPAPER_PRO_V2
|
|
||||||
// The default Wire will be mapped to RTC, Touch, PCA9535, BQ25896, and BQ27220
|
|
||||||
static const uint8_t SDA = 39;
|
|
||||||
static const uint8_t SCL = 40;
|
|
||||||
|
|
||||||
// Default SPI will be mapped to Radio
|
|
||||||
static const uint8_t SS = 46;
|
|
||||||
static const uint8_t MOSI = 13;
|
|
||||||
static const uint8_t MISO = 21;
|
|
||||||
static const uint8_t SCK = 14;
|
|
||||||
|
|
||||||
#define SPI_MOSI (13)
|
|
||||||
#define SPI_SCK (14)
|
|
||||||
#define SPI_MISO (21)
|
|
||||||
#define SPI_CS (12)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* Pins_Arduino_h */
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
[t5s3_epaper_base]
|
|
||||||
extends = esp32s3_base
|
|
||||||
board = t5-epaper-s3
|
|
||||||
board_build.partition = default_16MB.csv
|
|
||||||
board_check = true
|
|
||||||
upload_protocol = esptool
|
|
||||||
build_flags = -fno-strict-aliasing
|
|
||||||
${esp32_base.build_flags}
|
|
||||||
-I variants/esp32s3/t5s3_epaper
|
|
||||||
-D T5_S3_EPAPER_PRO
|
|
||||||
-D USE_EINK
|
|
||||||
-D USE_EINK_PARALLELDISPLAY
|
|
||||||
-D PRIVATE_HW
|
|
||||||
-D TOUCH_THRESHOLD_X=60
|
|
||||||
-D TOUCH_THRESHOLD_Y=40
|
|
||||||
-D TIME_LONG_PRESS=500
|
|
||||||
; -D EINK_LIMIT_GHOSTING_PX=5000
|
|
||||||
-D EPD_FULLSLOW_PERIOD=100
|
|
||||||
-D FAST_EPD_PARTIAL_UPDATE_BUG ; use rect area update instead of partial
|
|
||||||
|
|
||||||
build_src_filter =
|
|
||||||
${esp32s3_base.build_src_filter}
|
|
||||||
lib_deps =
|
|
||||||
${esp32s3_base.lib_deps}
|
|
||||||
lewisxhe/XPowersLib@0.3.1
|
|
||||||
lewisxhe/SensorLib@0.3.1
|
|
||||||
https://github.com/mverch67/BQ27220/archive/07d92be846abd8a0258a50c23198dac0858b22ed.zip
|
|
||||||
https://github.com/mverch67/FastEPD/archive/0df1bff329b6fc782e062f611758880762340647.zip
|
|
||||||
|
|
||||||
[env:t5s3_epaper_inkhud]
|
|
||||||
extends = t5s3_epaper_base, inkhud
|
|
||||||
build_flags =
|
|
||||||
${t5s3_epaper_base.build_flags}
|
|
||||||
${inkhud.build_flags}
|
|
||||||
-D SDCARD_USE_SPI1
|
|
||||||
-D T5_S3_EPAPER_PRO_V2
|
|
||||||
build_src_filter =
|
|
||||||
${t5s3_epaper_base.build_src_filter}
|
|
||||||
${inkhud.build_src_filter}
|
|
||||||
lib_deps =
|
|
||||||
${inkhud.lib_deps} ; InkHUD libs first, so we get GFXRoot instead of AdafruitGFX
|
|
||||||
${t5s3_epaper_base.lib_deps}
|
|
||||||
|
|
||||||
|
|
||||||
[env:t5s3-epaper-v1] ; H752
|
|
||||||
extends = t5s3_epaper_base
|
|
||||||
build_flags =
|
|
||||||
${t5s3_epaper_base.build_flags}
|
|
||||||
-D T5_S3_EPAPER_PRO_V1
|
|
||||||
-D GPS_DEFAULT_NOT_PRESENT=1
|
|
||||||
|
|
||||||
[env:t5s3-epaper-v2] ; H752-01
|
|
||||||
extends = t5s3_epaper_base
|
|
||||||
build_flags =
|
|
||||||
${t5s3_epaper_base.build_flags}
|
|
||||||
-D T5_S3_EPAPER_PRO_V2
|
|
||||||
-D SDCARD_USE_SPI1
|
|
||||||
-D GPS_POWER_TOGGLE
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
|
|
||||||
// Display (E-Ink) ED047TC1 - 8bit parallel
|
|
||||||
#define EPD_WIDTH 960
|
|
||||||
#define EPD_HEIGHT 540
|
|
||||||
|
|
||||||
#define CANNED_MESSAGE_MODULE_ENABLE 1
|
|
||||||
#define USE_VIRTUAL_KEYBOARD 1
|
|
||||||
|
|
||||||
#if defined(T5_S3_EPAPER_PRO_V1)
|
|
||||||
#define BOARD_BL_EN 40
|
|
||||||
#else
|
|
||||||
#define BOARD_BL_EN 11
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define I2C_SDA SDA
|
|
||||||
#define I2C_SCL SCL
|
|
||||||
|
|
||||||
#define HAS_TOUCHSCREEN 1
|
|
||||||
#define GT911_PIN_SDA SDA
|
|
||||||
#define GT911_PIN_SCL SCL
|
|
||||||
#if defined(T5_S3_EPAPER_PRO_V1)
|
|
||||||
#define GT911_PIN_INT 15
|
|
||||||
#define GT911_PIN_RST 41
|
|
||||||
#else
|
|
||||||
#define GT911_PIN_INT 3
|
|
||||||
#define GT911_PIN_RST 9
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PCF85063_RTC 0x51
|
|
||||||
#define HAS_RTC 1
|
|
||||||
#define PCF85063_INT 2
|
|
||||||
|
|
||||||
#define USE_POWERSAVE
|
|
||||||
#define SLEEP_TIME 120
|
|
||||||
|
|
||||||
// GPS
|
|
||||||
#if !defined(T5_S3_EPAPER_PRO_V1)
|
|
||||||
#define GPS_RX_PIN 44
|
|
||||||
#define GPS_TX_PIN 43
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(T5_S3_EPAPER_PRO_V1)
|
|
||||||
#define BUTTON_PIN 48
|
|
||||||
#define PIN_BUTTON2 0
|
|
||||||
#define ALT_BUTTON_PIN PIN_BUTTON2
|
|
||||||
#else
|
|
||||||
#define BUTTON_PIN 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// SD card
|
|
||||||
#define HAS_SDCARD
|
|
||||||
#define SDCARD_CS SPI_CS
|
|
||||||
#define SD_SPI_FREQUENCY 75000000U
|
|
||||||
|
|
||||||
// battery charger BQ25896
|
|
||||||
#define HAS_PPM 1
|
|
||||||
#define XPOWERS_CHIP_BQ25896
|
|
||||||
|
|
||||||
// battery quality management BQ27220
|
|
||||||
#define HAS_BQ27220 1
|
|
||||||
#define BQ27220_I2C_SDA SDA
|
|
||||||
#define BQ27220_I2C_SCL SCL
|
|
||||||
#define BQ27220_DESIGN_CAPACITY 1500
|
|
||||||
|
|
||||||
// LoRa
|
|
||||||
#define USE_SX1262
|
|
||||||
#define USE_SX1268
|
|
||||||
|
|
||||||
#define LORA_SCK SCK
|
|
||||||
#define LORA_MISO MISO
|
|
||||||
#define LORA_MOSI MOSI
|
|
||||||
#define LORA_CS 46
|
|
||||||
|
|
||||||
#define LORA_DIO0 -1
|
|
||||||
#if defined(T5_S3_EPAPER_PRO_V1)
|
|
||||||
#define LORA_RESET 43
|
|
||||||
#define LORA_DIO1 3 // SX1262 IRQ
|
|
||||||
#define LORA_DIO2 44 // SX1262 BUSY
|
|
||||||
#define LORA_DIO3
|
|
||||||
#else
|
|
||||||
#define LORA_RESET 1
|
|
||||||
#define LORA_DIO1 10 // SX1262 IRQ
|
|
||||||
#define LORA_DIO2 47 // SX1262 BUSY
|
|
||||||
#define LORA_DIO3
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SX126X_CS LORA_CS
|
|
||||||
#define SX126X_DIO1 LORA_DIO1
|
|
||||||
#define SX126X_BUSY LORA_DIO2
|
|
||||||
#define SX126X_RESET LORA_RESET
|
|
||||||
#define SX126X_DIO2_AS_RF_SWITCH
|
|
||||||
#define SX126X_DIO3_TCXO_VOLTAGE 2.4
|
|
||||||
@@ -26,6 +26,8 @@
|
|||||||
#define I2C_SDA SDA
|
#define I2C_SDA SDA
|
||||||
#define I2C_SCL SCL
|
#define I2C_SCL SCL
|
||||||
|
|
||||||
|
#define HAS_DRV2605 1
|
||||||
|
|
||||||
#define USE_POWERSAVE
|
#define USE_POWERSAVE
|
||||||
#define SLEEP_TIME 120
|
#define SLEEP_TIME 120
|
||||||
|
|
||||||
|
|||||||
70
variants/nrf52840/t-echo-plus/nicheGraphics.h
Normal file
70
variants/nrf52840/t-echo-plus/nicheGraphics.h
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "configuration.h"
|
||||||
|
|
||||||
|
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||||
|
|
||||||
|
#include "graphics/niche/Drivers/Backlight/LatchingBacklight.h"
|
||||||
|
#include "graphics/niche/Drivers/EInk/GDEY0154D67.h"
|
||||||
|
#include "graphics/niche/InkHUD/Applets/User/AllMessage/AllMessageApplet.h"
|
||||||
|
#include "graphics/niche/InkHUD/Applets/User/DM/DMApplet.h"
|
||||||
|
#include "graphics/niche/InkHUD/Applets/User/Heard/HeardApplet.h"
|
||||||
|
#include "graphics/niche/InkHUD/Applets/User/Positions/PositionsApplet.h"
|
||||||
|
#include "graphics/niche/InkHUD/Applets/User/RecentsList/RecentsListApplet.h"
|
||||||
|
#include "graphics/niche/InkHUD/Applets/User/ThreadedMessage/ThreadedMessageApplet.h"
|
||||||
|
#include "graphics/niche/InkHUD/InkHUD.h"
|
||||||
|
#include "graphics/niche/Inputs/TwoButton.h"
|
||||||
|
|
||||||
|
void setupNicheGraphics()
|
||||||
|
{
|
||||||
|
using namespace NicheGraphics;
|
||||||
|
|
||||||
|
SPI1.begin();
|
||||||
|
|
||||||
|
Drivers::EInk *driver = new Drivers::GDEY0154D67;
|
||||||
|
driver->begin(&SPI1, PIN_EINK_DC, PIN_EINK_CS, PIN_EINK_BUSY, PIN_EINK_RES);
|
||||||
|
|
||||||
|
InkHUD::InkHUD *inkhud = InkHUD::InkHUD::getInstance();
|
||||||
|
inkhud->setDriver(driver);
|
||||||
|
inkhud->setDisplayResilience(20, 1.5);
|
||||||
|
InkHUD::Applet::fontLarge = FREESANS_12PT_WIN1252;
|
||||||
|
InkHUD::Applet::fontMedium = FREESANS_9PT_WIN1252;
|
||||||
|
InkHUD::Applet::fontSmall = FREESANS_6PT_WIN1252;
|
||||||
|
inkhud->persistence->settings.userTiles.maxCount = 2;
|
||||||
|
inkhud->persistence->settings.rotation = 3;
|
||||||
|
inkhud->persistence->settings.optionalFeatures.batteryIcon = true;
|
||||||
|
inkhud->persistence->settings.optionalMenuItems.backlight = true;
|
||||||
|
|
||||||
|
Drivers::LatchingBacklight *backlight = Drivers::LatchingBacklight::getInstance();
|
||||||
|
backlight->setPin(PIN_EINK_BL);
|
||||||
|
|
||||||
|
inkhud->addApplet("All Messages", new InkHUD::AllMessageApplet, true, true);
|
||||||
|
inkhud->addApplet("DMs", new InkHUD::DMApplet);
|
||||||
|
inkhud->addApplet("Channel 0", new InkHUD::ThreadedMessageApplet(0));
|
||||||
|
inkhud->addApplet("Channel 1", new InkHUD::ThreadedMessageApplet(1));
|
||||||
|
inkhud->addApplet("Positions", new InkHUD::PositionsApplet, true);
|
||||||
|
inkhud->addApplet("Recents List", new InkHUD::RecentsListApplet);
|
||||||
|
inkhud->addApplet("Heard", new InkHUD::HeardApplet, true, false, 0);
|
||||||
|
|
||||||
|
inkhud->begin();
|
||||||
|
|
||||||
|
Inputs::TwoButton *buttons = Inputs::TwoButton::getInstance();
|
||||||
|
|
||||||
|
buttons->setWiring(0, Inputs::TwoButton::getUserButtonPin());
|
||||||
|
buttons->setTiming(0, 75, 500);
|
||||||
|
buttons->setHandlerShortPress(0, [inkhud]() { inkhud->shortpress(); });
|
||||||
|
buttons->setHandlerLongPress(0, [inkhud]() { inkhud->longpress(); });
|
||||||
|
|
||||||
|
buttons->setWiring(1, PIN_BUTTON_TOUCH);
|
||||||
|
buttons->setTiming(1, 50, 5000);
|
||||||
|
buttons->setHandlerDown(1, [inkhud, backlight]() {
|
||||||
|
backlight->peek();
|
||||||
|
inkhud->persistence->settings.optionalMenuItems.backlight = false;
|
||||||
|
});
|
||||||
|
buttons->setHandlerLongPress(1, [backlight]() { backlight->latch(); });
|
||||||
|
buttons->setHandlerShortPress(1, [backlight]() { backlight->off(); });
|
||||||
|
|
||||||
|
buttons->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
26
variants/nrf52840/t-echo-plus/platformio.ini
Normal file
26
variants/nrf52840/t-echo-plus/platformio.ini
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
[env:t-echo-plus]
|
||||||
|
extends = nrf52840_base
|
||||||
|
board = t-echo
|
||||||
|
board_level = pr
|
||||||
|
board_check = true
|
||||||
|
debug_tool = jlink
|
||||||
|
|
||||||
|
build_flags = ${nrf52840_base.build_flags}
|
||||||
|
-DTTGO_T_ECHO_PLUS
|
||||||
|
-Ivariants/nrf52840/t-echo-plus
|
||||||
|
-DEINK_DISPLAY_MODEL=GxEPD2_154_D67
|
||||||
|
-DEINK_WIDTH=200
|
||||||
|
-DEINK_HEIGHT=200
|
||||||
|
-DUSE_EINK
|
||||||
|
-DUSE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
|
||||||
|
-DEINK_LIMIT_FASTREFRESH=20 ; How many consecutive fast-refreshes are permitted
|
||||||
|
-DEINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached.
|
||||||
|
-DI2C_NO_RESCAN
|
||||||
|
|
||||||
|
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/t-echo-plus>
|
||||||
|
|
||||||
|
lib_deps =
|
||||||
|
${nrf52840_base.lib_deps}
|
||||||
|
https://github.com/meshtastic/GxEPD2/archive/55f618961db45a23eff0233546430f1e5a80f63a.zip
|
||||||
|
lewisxhe/PCF8563_Library@^1.0.1
|
||||||
|
adafruit/Adafruit DRV2605 Library@1.2.4
|
||||||
24
variants/nrf52840/t-echo-plus/variant.cpp
Normal file
24
variants/nrf52840/t-echo-plus/variant.cpp
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#include "variant.h"
|
||||||
|
#include "nrf.h"
|
||||||
|
#include "wiring_constants.h"
|
||||||
|
#include "wiring_digital.h"
|
||||||
|
|
||||||
|
const uint32_t g_ADigitalPinMap[] = {
|
||||||
|
// P0 - pins 0 and 1 are hardwired for xtal and should never be enabled
|
||||||
|
0xff, 0xff, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||||
|
|
||||||
|
// P1
|
||||||
|
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47};
|
||||||
|
|
||||||
|
void initVariant()
|
||||||
|
{
|
||||||
|
// LEDs (if populated)
|
||||||
|
pinMode(PIN_LED1, OUTPUT);
|
||||||
|
ledOff(PIN_LED1);
|
||||||
|
|
||||||
|
pinMode(PIN_LED2, OUTPUT);
|
||||||
|
ledOff(PIN_LED2);
|
||||||
|
|
||||||
|
pinMode(PIN_LED3, OUTPUT);
|
||||||
|
ledOff(PIN_LED3);
|
||||||
|
}
|
||||||
145
variants/nrf52840/t-echo-plus/variant.h
Normal file
145
variants/nrf52840/t-echo-plus/variant.h
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
#ifndef _VARIANT_T_ECHO_PLUS_
|
||||||
|
#define _VARIANT_T_ECHO_PLUS_
|
||||||
|
|
||||||
|
#define VARIANT_MCK (64000000ul)
|
||||||
|
#define USE_LFXO
|
||||||
|
|
||||||
|
#include "WVariant.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Pin counts
|
||||||
|
#define PINS_COUNT (48)
|
||||||
|
#define NUM_DIGITAL_PINS (48)
|
||||||
|
#define NUM_ANALOG_INPUTS (1)
|
||||||
|
#define NUM_ANALOG_OUTPUTS (0)
|
||||||
|
|
||||||
|
// LEDs (not documented on pinmap; keep defaults for compatibility)
|
||||||
|
#define PIN_LED1 (0 + 14)
|
||||||
|
#define PIN_LED2 (0 + 15)
|
||||||
|
#define PIN_LED3 (0 + 13)
|
||||||
|
|
||||||
|
#define LED_RED PIN_LED3
|
||||||
|
#define LED_BLUE PIN_LED1
|
||||||
|
#define LED_GREEN PIN_LED2
|
||||||
|
|
||||||
|
#define LED_BUILTIN LED_BLUE
|
||||||
|
#define LED_CONN LED_GREEN
|
||||||
|
|
||||||
|
#define LED_STATE_ON 0
|
||||||
|
|
||||||
|
// Buttons / touch
|
||||||
|
#define PIN_BUTTON1 (32 + 10)
|
||||||
|
#define BUTTON_ACTIVE_LOW true
|
||||||
|
#define BUTTON_ACTIVE_PULLUP true
|
||||||
|
#define PIN_BUTTON2 (0 + 18) // reset-labelled but usable as GPIO
|
||||||
|
#define PIN_BUTTON_TOUCH (0 + 11) // capacitive touch
|
||||||
|
#define BUTTON_TOUCH_ACTIVE_LOW true
|
||||||
|
#define BUTTON_TOUCH_ACTIVE_PULLUP true
|
||||||
|
|
||||||
|
#define BUTTON_CLICK_MS 400
|
||||||
|
#define BUTTON_TOUCH_MS 200
|
||||||
|
|
||||||
|
// Analog
|
||||||
|
#define PIN_A0 (4)
|
||||||
|
#define BATTERY_PIN PIN_A0
|
||||||
|
static const uint8_t A0 = PIN_A0;
|
||||||
|
#define ADC_RESOLUTION 14
|
||||||
|
#define BATTERY_SENSE_RESOLUTION_BITS 12
|
||||||
|
#define BATTERY_SENSE_RESOLUTION 4096.0
|
||||||
|
#undef AREF_VOLTAGE
|
||||||
|
#define AREF_VOLTAGE 3.0
|
||||||
|
#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
|
||||||
|
#define ADC_MULTIPLIER (2.0F)
|
||||||
|
|
||||||
|
// NFC
|
||||||
|
#define PIN_NFC1 (9)
|
||||||
|
#define PIN_NFC2 (10)
|
||||||
|
|
||||||
|
// I2C (IMU BHI260AP, RTC, etc.)
|
||||||
|
#define WIRE_INTERFACES_COUNT 1
|
||||||
|
#define PIN_WIRE_SDA (0 + 26)
|
||||||
|
#define PIN_WIRE_SCL (0 + 27)
|
||||||
|
#define HAS_BHI260AP
|
||||||
|
|
||||||
|
#define TP_SER_IO (0 + 11)
|
||||||
|
|
||||||
|
// RTC interrupt
|
||||||
|
#define PIN_RTC_INT (0 + 16)
|
||||||
|
|
||||||
|
// QSPI flash
|
||||||
|
#define PIN_QSPI_SCK (32 + 14)
|
||||||
|
#define PIN_QSPI_CS (32 + 15)
|
||||||
|
#define PIN_QSPI_IO0 (32 + 12)
|
||||||
|
#define PIN_QSPI_IO1 (32 + 13)
|
||||||
|
#define PIN_QSPI_IO2 (0 + 7)
|
||||||
|
#define PIN_QSPI_IO3 (0 + 5)
|
||||||
|
|
||||||
|
// On-board QSPI Flash
|
||||||
|
#define EXTERNAL_FLASH_DEVICES MX25R1635F
|
||||||
|
#define EXTERNAL_FLASH_USE_QSPI
|
||||||
|
|
||||||
|
// LoRa SX1262
|
||||||
|
#define USE_SX1262
|
||||||
|
#define USE_SX1268
|
||||||
|
#define SX126X_CS (0 + 24)
|
||||||
|
#define SX126X_DIO1 (0 + 20)
|
||||||
|
#define SX1262_DIO3 (0 + 21)
|
||||||
|
#define SX126X_BUSY (0 + 17)
|
||||||
|
#define SX126X_RESET (0 + 25)
|
||||||
|
#define SX126X_DIO2_AS_RF_SWITCH
|
||||||
|
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||||
|
#define TCXO_OPTIONAL
|
||||||
|
|
||||||
|
#define SPI_INTERFACES_COUNT 2
|
||||||
|
|
||||||
|
#define PIN_SPI_MISO (0 + 23)
|
||||||
|
#define PIN_SPI_MOSI (0 + 22)
|
||||||
|
#define PIN_SPI_SCK (0 + 19)
|
||||||
|
|
||||||
|
// E-paper (1.54" per pinmap)
|
||||||
|
// Alias PIN_EINK_EN to keep common eink power control code working
|
||||||
|
#define PIN_EINK_BL (32 + 11) // backlight / panel power switch
|
||||||
|
#define PIN_EINK_EN PIN_EINK_BL
|
||||||
|
#define PIN_EINK_CS (0 + 30)
|
||||||
|
#define PIN_EINK_BUSY (0 + 3)
|
||||||
|
#define PIN_EINK_DC (0 + 28)
|
||||||
|
#define PIN_EINK_RES (0 + 2)
|
||||||
|
#define PIN_EINK_SCLK (0 + 31)
|
||||||
|
#define PIN_EINK_MOSI (0 + 29) // also called SDI
|
||||||
|
|
||||||
|
// Power control
|
||||||
|
#define PIN_POWER_EN (0 + 12)
|
||||||
|
|
||||||
|
#define PIN_SPI1_MISO (32 + 7) // Placeholder MISO; keep off QSPI pins to avoid contention
|
||||||
|
#define PIN_SPI1_MOSI PIN_EINK_MOSI
|
||||||
|
#define PIN_SPI1_SCK PIN_EINK_SCLK
|
||||||
|
|
||||||
|
// GPS (TX/RX/Wake/Reset/PPS per pinmap)
|
||||||
|
#define GPS_L76K
|
||||||
|
#define PIN_GPS_REINIT (32 + 5) // Reset
|
||||||
|
#define PIN_GPS_STANDBY (32 + 2) // Wake
|
||||||
|
#define PIN_GPS_PPS (32 + 4)
|
||||||
|
#define GPS_TX_PIN (32 + 8)
|
||||||
|
#define GPS_RX_PIN (32 + 9)
|
||||||
|
#define GPS_THREAD_INTERVAL 50
|
||||||
|
|
||||||
|
#define PIN_SERIAL1_RX GPS_RX_PIN
|
||||||
|
#define PIN_SERIAL1_TX GPS_TX_PIN
|
||||||
|
|
||||||
|
// Sensors / accessories
|
||||||
|
#define PIN_BUZZER (0 + 6)
|
||||||
|
#define PIN_DRV_EN (0 + 8)
|
||||||
|
|
||||||
|
#define HAS_DRV2605 1
|
||||||
|
|
||||||
|
// Battery / ADC already defined above
|
||||||
|
#define HAS_RTC 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user