This should explode in multiple ways. Let's see.

This commit is contained in:
Thomas Göttgens
2026-04-18 20:14:16 +02:00
parent 6208c243f9
commit 69794d495f
215 changed files with 3092 additions and 3079 deletions
@@ -0,0 +1,44 @@
/*
NicheGraphics setup for M5Stack CoreInk (1.54" 200x200 GDEW0154M09).
The GDEW0154M09 uses an SSD1681-class controller, so the GDEY0154D67 panel
profile (same controller family, same resolution) drives it directly.
LoRa and the e-ink panel share the default SPI bus (SCLK=18, MOSI=23);
use the board's default SPI instance rather than spinning up a separate
HSPI peripheral on the same pins.
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Panels/GDEY0154D67.h"
class M5CoreInkPanel : public NicheGraphics::Panels::GDEY0154D67
{
protected:
SPIClass *beginSpi() override
{
SPI.begin();
return &SPI;
}
};
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new M5CoreInkPanel();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panel->rotation());
display->setDisplayResilience(10, 2.0f);
return display;
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+7 -10
View File
@@ -1,25 +1,22 @@
[env:m5stack-coreink]
extends = esp32_base
extends = esp32_base, niche
board = m5stack-coreink
board_check = true
build_src_filter =
build_src_filter =
${esp32_base.build_src_filter}
build_flags =
${niche.build_src_filter}
build_flags =
${esp32_base.build_flags}
${niche.build_flags}
-I variants/esp32/m5stack_coreink
;-D RADIOLIB_VERBOSE
-Ofast
-D__MCUXPRESSO
-DEINK_DISPLAY_MODEL=GxEPD2_154_M09
-DEINK_WIDTH=200
-DEINK_HEIGHT=200
-DUSER_SETUP_LOADED
-DM5_COREINK
-DM5_COREINK
-DM5STACK
lib_deps =
lib_deps =
${esp32_base.lib_deps}
# renovate: datasource=custom.pio depName=GxEPD2 packageName=zinggjm/library/GxEPD2
zinggjm/GxEPD2@1.6.8
# renovate: datasource=custom.pio depName=SensorLib packageName=lewisxhe/library/SensorLib
lewisxhe/SensorLib@0.3.4
lib_ignore =
@@ -0,0 +1,42 @@
/*
NicheGraphics setup for Elecrow ThinkNode-M5 (GDEY0154D67 1.54" on HSPI).
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Panels/GDEY0154D67.h"
class ThinkNodeM5Panel : public NicheGraphics::Panels::GDEY0154D67
{
protected:
SPIClass *beginSpi() override
{
auto *hspi = new SPIClass(HSPI);
hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS);
return hspi;
}
// Old GxEPD2 path used setRotation(4) (= 0° + mirror). BaseUIEInkDisplay does not implement
// mirroring; expose 0 here and rely on hardware orientation. Adjust if testing shows otherwise.
public:
uint8_t rotation() const override { return 0; }
};
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new ThinkNodeM5Panel();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panel->rotation());
display->setDisplayResilience(10, 1.5f);
return display;
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -9,29 +9,20 @@ custom_meshtastic_images = thinknode_m1.svg
custom_meshtastic_tags = Elecrow
custom_meshtastic_requires_dfu = false
extends = esp32s3_base
extends = esp32s3_base, niche
board = ESP32-S3-WROOM-1-N4
build_src_filter =
${esp32s3_base.build_src_filter}
+<../variants/esp32s3/ELECROW-ThinkNode-M5>
${niche.build_src_filter}
build_flags =
${esp32s3_base.build_flags}
${niche.build_flags}
-D ELECROW_ThinkNode_M5
-I variants/esp32s3/ELECROW-ThinkNode-M5
-DEINK_DISPLAY_MODEL=GxEPD2_154_D67
-DEINK_WIDTH=200
-DEINK_HEIGHT=200
-DUSE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
-DEINK_LIMIT_FASTREFRESH=10 ; How many consecutive fast-refreshes are permitted //20
-DEINK_LIMIT_RATE_BACKGROUND_SEC=10 ; Minimum interval between BACKGROUND updates //30
-DEINK_LIMIT_RATE_RESPONSIVE_SEC=1 ; Minimum interval between RESPONSIVE updates
; -DEINK_LIMIT_GHOSTING_PX=2000 ; (Optional) How much image ghosting is tolerated
-DEINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached.
lib_deps = ${esp32s3_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
https://github.com/meshtastic/GxEPD2/archive/c7eb4c3c167cf396ef4f541cc5d4c6aa42f3c46b.zip
# renovate: datasource=custom.pio depName=PCA9557-arduino packageName=maxpromer/library/PCA9557-arduino
maxpromer/PCA9557-arduino@1.0.0
# renovate: datasource=custom.pio depName=SensorLib packageName=lewisxhe/library/SensorLib
@@ -0,0 +1,61 @@
/*
NicheGraphics setup for the CrowPanel ESP32-S3 ePaper boards.
This directory is shared by three envs that each pick a different panel via
CROWPANEL_ESP32S3_{2,4,5}_EPAPER macros in platformio.ini.
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "graphics/BaseUIEInkDisplay.h"
#if defined(CROWPANEL_ESP32S3_2_EPAPER)
#include "graphics/eink/Panels/GDEY029T94.h"
using CrowpanelBasePanel = NicheGraphics::Panels::GDEY029T94;
#elif defined(CROWPANEL_ESP32S3_4_EPAPER)
#include "graphics/eink/Panels/HINK_E042A87.h"
using CrowpanelBasePanel = NicheGraphics::Panels::HINK_E042A87;
#elif defined(CROWPANEL_ESP32S3_5_EPAPER)
#include "graphics/eink/Panels/GDEY0579T93.h"
using CrowpanelBasePanel = NicheGraphics::Panels::GDEY0579T93;
#else
#error "No CROWPANEL_ESP32S3_*_EPAPER macro defined for this env"
#endif
class CrowpanelPanel : public CrowpanelBasePanel
{
protected:
SPIClass *beginSpi() override
{
auto *hspi = new SPIClass(HSPI);
hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS);
return hspi;
}
void prePowerOn() override
{
#ifdef VEXT_ENABLE
pinMode(VEXT_ENABLE, OUTPUT);
digitalWrite(VEXT_ENABLE, VEXT_ON_VALUE);
delay(10);
#endif
}
};
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new CrowpanelPanel();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panel->rotation());
display->setDisplayResilience(20, 1.5f);
return display;
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -1,5 +1,5 @@
[env:crowpanel-esp32s3-5-epaper]
extends = esp32s3_base
[crowpanel_epaper_base]
extends = esp32s3_base, niche
board_build.arduino.memory_type = qio_opi
board_build.flash_mode = qio
board_build.psram_type = opi
@@ -10,80 +10,32 @@ board = esp32-s3-devkitc-1
;upload_port = /dev/ttyUSB0
board_level = extra
upload_protocol = esptool
build_flags =
build_src_filter =
${esp32s3_base.build_src_filter}
${niche.build_src_filter}
build_flags =
${esp32s3_base.build_flags}
-D CROWPANEL_ESP32S3_5_EPAPER
${niche.build_flags}
-I variants/esp32s3/crowpanel-esp32s3-5-epaper
-D PRIVATE_HW
-DBOARD_HAS_PSRAM
-DEINK_DISPLAY_MODEL=GxEPD2_579_GDEY0579T93 ;https://www.good-display.com/product/439.html
-DEINK_WIDTH=792
-DEINK_HEIGHT=272
-DUSE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
-DEINK_LIMIT_FASTREFRESH=100 ; How many consecutive fast-refreshes are permitted
;-DEINK_LIMIT_RATE_BACKGROUND_SEC=30 ; Minimum interval between BACKGROUND updates
;-DEINK_LIMIT_RATE_RESPONSIVE_SEC=1
lib_deps =
${esp32s3_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
https://github.com/meshtastic/GxEPD2/archive/c7eb4c3c167cf396ef4f541cc5d4c6aa42f3c46b.zip
[env:crowpanel-esp32s3-5-epaper]
extends = crowpanel_epaper_base
build_flags =
${crowpanel_epaper_base.build_flags}
-D CROWPANEL_ESP32S3_5_EPAPER
[env:crowpanel-esp32s3-4-epaper]
extends = esp32s3_base
board_build.arduino.memory_type = qio_opi
board_build.flash_mode = qio
board_build.psram_type = opi
board_upload.flash_size = 8MB
board_upload.maximum_size = 8388608
board_build.partitions = default_8MB.csv
board = esp32-s3-devkitc-1
;upload_port = /dev/ttyUSB0
board_level = extra
upload_protocol = esptool
build_flags =
${esp32s3_base.build_flags}
extends = crowpanel_epaper_base
build_flags =
${crowpanel_epaper_base.build_flags}
-D CROWPANEL_ESP32S3_4_EPAPER
-I variants/esp32s3/crowpanel-esp32s3-5-epaper
-D PRIVATE_HW
-DBOARD_HAS_PSRAM
-DEINK_DISPLAY_MODEL=GxEPD2_420_GYE042A87 ; similar Panel: GDEY042T81 : https://www.good-display.com/product/386.html
-DEINK_WIDTH=400
-DEINK_HEIGHT=300
-DUSE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
-DEINK_LIMIT_FASTREFRESH=100 ; How many consecutive fast-refreshes are permitted
;-DEINK_LIMIT_RATE_BACKGROUND_SEC=30 ; Minimum interval between BACKGROUND updates
;-DEINK_LIMIT_RATE_RESPONSIVE_SEC=1
lib_deps =
${esp32s3_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
https://github.com/meshtastic/GxEPD2/archive/c7eb4c3c167cf396ef4f541cc5d4c6aa42f3c46b.zip
[env:crowpanel-esp32s3-2-epaper]
extends = esp32s3_base
board_build.arduino.memory_type = qio_opi
board_build.flash_mode = qio
board_build.psram_type = opi
board_upload.flash_size = 8MB
board_upload.maximum_size = 8388608
board_build.partitions = default_8MB.csv
board = esp32-s3-devkitc-1
;upload_port = /dev/ttyUSB0
board_level = extra
upload_protocol = esptool
build_flags =
${esp32s3_base.build_flags}
extends = crowpanel_epaper_base
build_flags =
${crowpanel_epaper_base.build_flags}
-D CROWPANEL_ESP32S3_2_EPAPER
-I variants/esp32s3/crowpanel-esp32s3-5-epaper
-D PRIVATE_HW
-DBOARD_HAS_PSRAM
-DEINK_DISPLAY_MODEL=GxEPD2_290_GDEY029T94 ;https://www.good-display.com/product/389.html
-DEINK_WIDTH=296
-DEINK_HEIGHT=128
-DUSE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
-DEINK_LIMIT_FASTREFRESH=100 ; How many consecutive fast-refreshes are permitted
;-DEINK_LIMIT_RATE_BACKGROUND_SEC=30 ; Minimum interval between BACKGROUND updates
;-DEINK_LIMIT_RATE_RESPONSIVE_SEC=1
lib_deps =
${esp32s3_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
https://github.com/meshtastic/GxEPD2/archive/c7eb4c3c167cf396ef4f541cc5d4c6aa42f3c46b.zip
@@ -0,0 +1,45 @@
/*
NicheGraphics setup for the DIY ESP32-S3 2.9" e-ink reference board
(as shipped: GDEW029T5D, 128x296, UC8151D controller).
The UC8151D init/command set is close enough to SSD1680 that GDEY029T94
(same 128x296 geometry, SSD1680-based) is used as the panel profile.
If the specific UC8151D panel behaves oddly (ghosting, inverted colours,
wrong refresh sequence), swap this panel profile for a UC8151D one.
Uses the default SPI bus, which is shared with the SX1280 LoRa module.
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Panels/GDEY029T94.h"
class DiyEsp32S3EinkPanel : public NicheGraphics::Panels::GDEY029T94
{
protected:
SPIClass *beginSpi() override
{
SPI.begin();
return &SPI;
}
};
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new DiyEsp32S3EinkPanel();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panel->rotation());
display->setDisplayResilience(7, 1.5f);
return display;
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -1,6 +1,6 @@
[env:my-esp32s3-diy-eink]
board_level = extra
extends = esp32s3_base
extends = esp32s3_base, niche
board = my_esp32s3_diy_eink
board_build.arduino.memory_type = dio_opi
board_build.mcu = esp32s3
@@ -10,19 +10,18 @@ upload_protocol = esptool
upload_speed = 921600
lib_deps =
${esp32s3_base.lib_deps}
# renovate: datasource=custom.pio depName=GxEPD2 packageName=zinggjm/library/GxEPD2
zinggjm/GxEPD2@1.6.8
build_unflags =
${esp32s3_base.build_unflags}
-DARDUINO_USB_MODE=1
build_flags =
build_src_filter =
${esp32s3_base.build_src_filter}
${niche.build_src_filter}
build_flags =
${esp32s3_base.build_flags}
${niche.build_flags}
-D PRIVATE_HW
-I variants/esp32s3/diy/my_esp32s3_diy_eink
-Dmy
-DEINK_DISPLAY_MODEL=GxEPD2_290_T5D
-DEINK_WIDTH=296
-DEINK_HEIGHT=128
-DBOARD_HAS_PSRAM
-mfix-esp32-psram-cache-issue
-DARDUINO_USB_MODE=0
@@ -0,0 +1,38 @@
/*
NicheGraphics setup for the ESP32-S3-Pico board (GDEY029T94 2.9" on the default SPI bus).
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Panels/GDEY029T94.h"
class Esp32S3PicoPanel : public NicheGraphics::Panels::GDEY029T94
{
protected:
SPIClass *beginSpi() override
{
// Old GxEPD2 path used the default SPI bus; preserve that to avoid SPI conflicts.
SPI.begin();
return &SPI;
}
};
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new Esp32S3PicoPanel();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panel->rotation());
display->setDisplayResilience(7, 1.5f);
return display;
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -1,7 +1,7 @@
[env:ESP32-S3-Pico]
board_level = extra
extends = esp32s3_base
extends = esp32s3_base, niche
upload_protocol = esptool
board = esp32-s3-pico
board_build.partitions = default_16MB.csv
@@ -12,15 +12,13 @@ board_upload.require_upload_port = yes
;upload_port = /dev/ttyACM0
build_src_filter = ${esp32s3_base.build_src_filter}
${niche.build_src_filter}
build_flags = ${esp32s3_base.build_flags}
${niche.build_flags}
-DESP32_S3_PICO
;-DPRIVATE_HW
-Ivariants/esp32s3/esp32-s3-pico
-DBOARD_HAS_PSRAM
-DEINK_DISPLAY_MODEL=GxEPD2_290_T94_V2
-DEINK_WIDTH=296
-DEINK_HEIGHT=128
lib_deps = ${esp32s3_base.lib_deps}
# renovate: datasource=custom.pio depName=GxEPD2 packageName=zinggjm/library/GxEPD2
zinggjm/GxEPD2@1.6.8
@@ -1,119 +1,130 @@
/*
NicheGraphics setup for Heltec Vision Master E-213 (HSPI; runtime-detected 2.13" panel).
Panel choice depends on detectEInk() output:
- LCMEN213EFC1 (V1, unmarked)
- E0213A367 (V1.1, V1.2)
Both panels share the same SPI wiring; the difference is the controller/waveform.
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
// InkHUD-specific components
// ---------------------------
#include "graphics/niche/InkHUD/InkHUD.h"
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Panels/E0213A367.h"
#include "graphics/eink/Panels/LCMEN213EFC1.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/FavoritesMap/FavoritesMapApplet.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 "buzz.h"
#include "einkDetect.h"
// Shared NicheGraphics components
// --------------------------------
#include "graphics/niche/Drivers/EInk/E0213A367.h"
#include "graphics/niche/Drivers/EInk/LCMEN2R13EFC1.h"
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "graphics/niche/Applets/User/AllMessage/AllMessageApplet.h"
#include "graphics/niche/Applets/User/DM/DMApplet.h"
#include "graphics/niche/Applets/User/FavoritesMap/FavoritesMapApplet.h"
#include "graphics/niche/Applets/User/Heard/HeardApplet.h"
#include "graphics/niche/Applets/User/Positions/PositionsApplet.h"
#include "graphics/niche/Applets/User/RecentsList/RecentsListApplet.h"
#include "graphics/niche/Applets/User/ThreadedMessage/ThreadedMessageApplet.h"
#include "graphics/niche/InkHUD.h"
#include "graphics/niche/Inputs/TwoButton.h"
#endif
#include "buzz.h" // Button feedback
#include "einkDetect.h" // Detect display model at runtime
template <typename Base> class VMe213Panel : public Base
{
protected:
SPIClass *beginSpi() override
{
auto *hspi = new SPIClass(HSPI);
hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS);
return hspi;
}
};
struct VMe213DetectedDriver {
NicheGraphics::Drivers::EInk *driver;
uint8_t fastPerFull;
float stress;
uint8_t rotation;
};
static VMe213DetectedDriver detectAndCreateVMe213Driver()
{
EInkDetectionResult model = detectEInk();
VMe213DetectedDriver out{nullptr, 10, 1.5f, 3};
if (model == EInkDetectionResult::LCMEN213EFC1) {
auto *p = new VMe213Panel<NicheGraphics::Panels::LCMEN213EFC1>();
out.driver = p->create();
out.rotation = p->rotation();
out.fastPerFull = 10;
out.stress = 1.5f;
} else { // E0213A367 (V1.1, V1.2)
auto *p = new VMe213Panel<NicheGraphics::Panels::E0213A367>();
out.driver = p->create();
out.rotation = p->rotation();
out.fastPerFull = 15;
out.stress = 3.0f;
}
return out;
}
#ifdef MESHTASTIC_INCLUDE_INKHUD
void setupNicheGraphics()
{
using namespace NicheGraphics;
// Detect E-Ink Model
// -------------------
EInkDetectionResult displayModel = detectEInk();
// 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
// -----------------------------
Drivers::EInk *driver;
if (displayModel == EInkDetectionResult::LCMEN213EFC1) // V1 (unmarked)
driver = new Drivers::LCMEN213EFC1;
else if (displayModel == EInkDetectionResult::E0213A367) // V1.1
driver = new Drivers::E0213A367;
driver->begin(hspi, PIN_EINK_DC, PIN_EINK_CS, PIN_EINK_BUSY, PIN_EINK_RES);
// InkHUD
// ----------------------------
VMe213DetectedDriver detected = detectAndCreateVMe213Driver();
InkHUD::InkHUD *inkhud = InkHUD::InkHUD::getInstance();
inkhud->setDriver(detected.driver);
inkhud->setDisplayResilience(detected.fastPerFull, detected.stress);
// Set the E-Ink driver
inkhud->setDriver(driver);
// Set how many FAST updates per FULL update
// Set how unhealthy additional FAST updates beyond this number are
if (displayModel == EInkDetectionResult::LCMEN213EFC1) // V1 (unmarked)
inkhud->setDisplayResilience(10, 1.5);
else if (displayModel == EInkDetectionResult::E0213A367) // V1.1
inkhud->setDisplayResilience(15, 3);
// Select fonts
InkHUD::Applet::fontLarge = FREESANS_12PT_WIN1252;
InkHUD::Applet::fontMedium = FREESANS_9PT_WIN1252;
InkHUD::Applet::fontSmall = FREESANS_6PT_WIN1252;
// Customize default settings
inkhud->persistence->settings.userTiles.maxCount = 2; // How many tiles can the display handle?
inkhud->persistence->settings.rotation = 3; // 270 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.userTiles.maxCount = 2;
inkhud->persistence->settings.rotation = 3;
inkhud->persistence->settings.userTiles.count = 1;
inkhud->persistence->settings.optionalMenuItems.nextTile = false;
// Pick applets
// Note: order of applets determines priority of "auto-show" feature
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("Favorites Map", new InkHUD::FavoritesMapApplet); // -
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("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("Favorites Map", new InkHUD::FavoritesMapApplet);
inkhud->addApplet("Recents List", new InkHUD::RecentsListApplet);
inkhud->addApplet("Heard", new InkHUD::HeardApplet, true, false, 0);
// Start running InkHUD
inkhud->begin();
// Buttons
// --------------------------
Inputs::TwoButton *buttons = Inputs::TwoButton::getInstance(); // Shared NicheGraphics component
// #0: Main User Button
Inputs::TwoButton *buttons = Inputs::TwoButton::getInstance();
buttons->setWiring(0, Inputs::TwoButton::getUserButtonPin());
buttons->setHandlerShortPress(0, [inkhud]() { inkhud->shortpress(); });
buttons->setHandlerLongPress(0, [inkhud]() { inkhud->longpress(); });
// #1: Aux Button
buttons->setWiring(1, PIN_BUTTON2);
buttons->setHandlerShortPress(1, [inkhud]() {
inkhud->nextTile();
playChirp();
});
// Begin handling button events
buttons->start();
}
#else
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
VMe213DetectedDriver detected = detectAndCreateVMe213Driver();
auto *display = new NicheGraphics::BaseUIEInkDisplay(detected.driver, detected.rotation);
display->setDisplayResilience(detected.fastPerFull, detected.stress);
return display;
}
#endif
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -11,26 +11,20 @@ custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 8MB
custom_meshtastic_has_ink_hud = true
extends = esp32s3_base
extends = esp32s3_base, niche
board = heltec_vision_master_e213
board_build.partitions = default_8MB.csv
build_flags =
build_src_filter =
${esp32s3_base.build_src_filter}
${niche.build_src_filter}
build_flags =
${esp32s3_base.build_flags}
-Ivariants/esp32s3/heltec_vision_master_e213
${niche.build_flags}
-Ivariants/esp32s3/heltec_vision_master_e213
-DHELTEC_VISION_MASTER_E213
-DUSE_EINK
-DGXEPD2_DRIVER_0=GxEPD2_213_FC1
-DGXEPD2_DRIVER_1=GxEPD2_213_E0213A367
-DEINK_WIDTH=250
-DEINK_HEIGHT=122
-DUSE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
-DEINK_LIMIT_FASTREFRESH=10 ; 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.
-DEINK_HASQUIRK_GHOSTING ; Display model is identified as "prone to ghosting"
lib_deps =
${esp32s3_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
https://github.com/meshtastic/GxEPD2/archive/c7eb4c3c167cf396ef4f541cc5d4c6aa42f3c46b.zip
upload_speed = 115200
[env:heltec-vision-master-e213-inkhud]
@@ -41,7 +35,7 @@ board_build.partitions = default_8MB.csv
build_src_filter =
${esp32s3_base.build_src_filter}
${inkhud.build_src_filter}
build_flags =
build_flags =
${esp32s3_base.build_flags}
${inkhud.build_flags}
-I variants/esp32s3/heltec_vision_master_e213
@@ -1,13 +1,14 @@
/*
Most of the Meshtastic firmware uses preprocessor macros throughout the code to support different hardware variants.
NicheGraphics attempts a different approach:
NicheGraphics setup for Heltec Vision Master E-290.
Per-device config takes place in this setupNicheGraphics() method
(And a small amount in platformio.ini)
Supports two UI builds that share this file:
- InkHUD build (MESHTASTIC_INCLUDE_INKHUD defined)
- BaseUI build (MESHTASTIC_INCLUDE_INKHUD not defined)
This file sets up InkHUD for Heltec VM-E290.
Different NicheGraphics UIs and different hardware variants will each have their own setup procedure.
The panel itself (DEPG0290BNS800, SSD1680, 128x296) is defined once in
graphics/eink/Panels/DEPG0290BNS800.h
The variant only overrides what is specific to this board — here, that's the HSPI pin bring-up.
*/
@@ -17,100 +18,111 @@ Different NicheGraphics UIs and different hardware variants will each have their
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
// InkHUD-specific components
// ---------------------------
#include "graphics/niche/InkHUD/InkHUD.h"
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Panels/DEPG0290BNS800.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/FavoritesMap/FavoritesMapApplet.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/EInk/DEPG0290BNS800.h"
#include "graphics/niche/Inputs/TwoButton.h"
// Button feedback
#include "buzz.h"
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "graphics/niche/Applets/User/AllMessage/AllMessageApplet.h"
#include "graphics/niche/Applets/User/DM/DMApplet.h"
#include "graphics/niche/Applets/User/FavoritesMap/FavoritesMapApplet.h"
#include "graphics/niche/Applets/User/Heard/HeardApplet.h"
#include "graphics/niche/Applets/User/Positions/PositionsApplet.h"
#include "graphics/niche/Applets/User/RecentsList/RecentsListApplet.h"
#include "graphics/niche/Applets/User/ThreadedMessage/ThreadedMessageApplet.h"
#include "graphics/niche/InkHUD.h"
#include "graphics/niche/Inputs/TwoButton.h"
#endif
// Board-specific: display is wired to HSPI with explicit pins.
class VMe290Panel : public NicheGraphics::Panels::DEPG0290BNS800
{
protected:
SPIClass *beginSpi() override
{
auto *hspi = new SPIClass(HSPI);
hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS);
return hspi;
}
};
static NicheGraphics::Drivers::EInk *createVMe290Driver(uint8_t *outRotation)
{
auto *panel = new VMe290Panel();
*outRotation = panel->rotation();
return panel->create();
}
#ifdef MESHTASTIC_INCLUDE_INKHUD
static void setupVMe290Buttons(std::function<void()> shortPress, std::function<void()> longPress,
std::function<void()> auxShortPress)
{
using namespace NicheGraphics;
auto *buttons = Inputs::TwoButton::getInstance();
buttons->setWiring(0, Inputs::TwoButton::getUserButtonPin());
buttons->setHandlerShortPress(0, shortPress);
buttons->setHandlerLongPress(0, longPress);
buttons->setWiring(1, PIN_BUTTON2);
buttons->setHandlerShortPress(1, auxShortPress);
buttons->start();
}
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
// -----------------------------
Drivers::EInk *driver = new Drivers::DEPG0290BNS800;
driver->begin(hspi, PIN_EINK_DC, PIN_EINK_CS, PIN_EINK_BUSY);
// InkHUD
// ----------------------------
uint8_t panelRotation;
Drivers::EInk *driver = createVMe290Driver(&panelRotation);
(void)panelRotation; // InkHUD uses its own settings.rotation below
InkHUD::InkHUD *inkhud = InkHUD::InkHUD::getInstance();
// Set the E-Ink 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);
// Select fonts
InkHUD::Applet::fontLarge = FREESANS_12PT_WIN1252;
InkHUD::Applet::fontMedium = FREESANS_9PT_WIN1252;
InkHUD::Applet::fontSmall = FREESANS_6PT_WIN1252;
// Customize default settings
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.userTiles.maxCount = 2;
inkhud->persistence->settings.rotation = 1;
inkhud->persistence->settings.userTiles.count = 1;
inkhud->persistence->settings.optionalMenuItems.nextTile = false;
// Pick applets
// Note: order of applets determines priority of "auto-show" feature
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("Favorites Map", new InkHUD::FavoritesMapApplet); // -
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("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("Favorites Map", new InkHUD::FavoritesMapApplet);
inkhud->addApplet("Recents List", new InkHUD::RecentsListApplet);
inkhud->addApplet("Heard", new InkHUD::HeardApplet, true, false, 0);
// Start running InkHUD
inkhud->begin();
// Buttons
// --------------------------
Inputs::TwoButton *buttons = Inputs::TwoButton::getInstance(); // A shared NicheGraphics component
// #0: Main User Button
buttons->setWiring(0, Inputs::TwoButton::getUserButtonPin());
buttons->setHandlerShortPress(0, [inkhud]() { inkhud->shortpress(); });
buttons->setHandlerLongPress(0, [inkhud]() { inkhud->longpress(); });
// #1: Aux Button
buttons->setWiring(1, PIN_BUTTON2);
buttons->setHandlerShortPress(1, [inkhud]() {
inkhud->nextTile();
playChirp();
});
// Begin handling button events
buttons->start();
setupVMe290Buttons([inkhud]() { inkhud->shortpress(); }, [inkhud]() { inkhud->longpress(); },
[inkhud]() {
inkhud->nextTile();
playChirp();
});
}
#else // BaseUI path
void setupNicheGraphics()
{
// BaseUI handles its own input via the default ButtonThread. Nothing extra to set up here.
}
#endif
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
uint8_t panelRotation;
NicheGraphics::Drivers::EInk *driver = createVMe290Driver(&panelRotation);
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panelRotation);
display->setDisplayResilience(7, 1.5f);
return display;
}
#endif // MESHTASTIC_INCLUDE_INKHUD
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -1,4 +1,4 @@
; Using the original screen class
; BaseUI build, using NicheGraphics drivers (no GxEPD2).
[env:heltec-vision-master-e290]
custom_meshtastic_hw_model = 68
custom_meshtastic_hw_model_slug = HELTEC_VISION_MASTER_E290
@@ -12,38 +12,32 @@ custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 8MB
custom_meshtastic_has_ink_hud = true
extends = esp32s3_base
extends = esp32s3_base, niche
board = heltec_vision_master_e290
board_build.partitions = default_8MB.csv
build_flags =
${esp32s3_base.build_flags}
build_src_filter =
${esp32s3_base.build_src_filter}
${niche.build_src_filter}
build_flags =
${esp32s3_base.build_flags}
${niche.build_flags}
-I variants/esp32s3/heltec_vision_master_e290
-D DISPLAY_FLIP_SCREEN ; Orient so the LoRa antenna faces up
-D HELTEC_VISION_MASTER_E290
-D BUTTON_CLICK_MS=200
-D EINK_DISPLAY_MODEL=GxEPD2_290_BN8
-D EINK_WIDTH=296
-D EINK_HEIGHT=128
-D USE_EINK
-D USE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
-D EINK_LIMIT_FASTREFRESH=10 ; How many consecutive fast-refreshes are permitted
-D EINK_HASQUIRK_GHOSTING ; Display model is identified as "prone to ghosting"
lib_deps =
${esp32s3_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
https://github.com/meshtastic/GxEPD2/archive/c7eb4c3c167cf396ef4f541cc5d4c6aa42f3c46b.zip
upload_speed = 115200
[env:heltec-vision-master-e290-inkhud]
extends = esp32s3_base, inkhud
board = heltec_vision_master_e290
board_build.partitions = default_8MB.csv
build_src_filter =
build_src_filter =
${esp32s3_base.build_src_filter}
${inkhud.build_src_filter}
build_flags =
build_flags =
${esp32s3_base.build_flags}
${inkhud.build_flags}
-I variants/esp32s3/heltec_vision_master_e290
@@ -1,112 +1,121 @@
/*
NicheGraphics setup for Heltec Wireless Paper (HSPI; runtime-detected 2.13" panel).
Panel choice depends on detectEInk() output:
- LCMEN213EFC1 (V1.1)
- E0213A367 (V1.1.1, V1.2)
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
// InkHUD-specific components
// ---------------------------
#include "graphics/niche/InkHUD/InkHUD.h"
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Panels/E0213A367.h"
#include "graphics/eink/Panels/LCMEN213EFC1.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/FavoritesMap/FavoritesMapApplet.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 "einkDetect.h"
// Shared NicheGraphics components
// --------------------------------
#include "graphics/niche/Drivers/EInk/E0213A367.h"
#include "graphics/niche/Drivers/EInk/LCMEN2R13EFC1.h"
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "graphics/niche/Applets/User/AllMessage/AllMessageApplet.h"
#include "graphics/niche/Applets/User/DM/DMApplet.h"
#include "graphics/niche/Applets/User/FavoritesMap/FavoritesMapApplet.h"
#include "graphics/niche/Applets/User/Heard/HeardApplet.h"
#include "graphics/niche/Applets/User/Positions/PositionsApplet.h"
#include "graphics/niche/Applets/User/RecentsList/RecentsListApplet.h"
#include "graphics/niche/Applets/User/ThreadedMessage/ThreadedMessageApplet.h"
#include "graphics/niche/InkHUD.h"
#include "graphics/niche/Inputs/TwoButton.h"
#endif
#include "einkDetect.h" // Detect display model at runtime
template <typename Base> class HeltecWPPanel : public Base
{
protected:
SPIClass *beginSpi() override
{
auto *hspi = new SPIClass(HSPI);
hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS);
return hspi;
}
};
struct HeltecWPDetectedDriver {
NicheGraphics::Drivers::EInk *driver;
uint8_t fastPerFull;
float stress;
uint8_t rotation;
};
static HeltecWPDetectedDriver detectAndCreateHeltecWPDriver()
{
EInkDetectionResult model = detectEInk();
HeltecWPDetectedDriver out{nullptr, 10, 1.5f, 3};
if (model == EInkDetectionResult::LCMEN213EFC1) {
auto *p = new HeltecWPPanel<NicheGraphics::Panels::LCMEN213EFC1>();
out.driver = p->create();
out.rotation = p->rotation();
out.fastPerFull = 10;
out.stress = 1.5f;
} else {
auto *p = new HeltecWPPanel<NicheGraphics::Panels::E0213A367>();
out.driver = p->create();
out.rotation = p->rotation();
out.fastPerFull = 15;
out.stress = 3.0f;
}
return out;
}
#ifdef MESHTASTIC_INCLUDE_INKHUD
void setupNicheGraphics()
{
using namespace NicheGraphics;
// Detect E-Ink Model
// -------------------
EInkDetectionResult displayModel = detectEInk();
// 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
// -----------------------------
Drivers::EInk *driver;
if (displayModel == EInkDetectionResult::LCMEN213EFC1) // V1.1
driver = new Drivers::LCMEN213EFC1;
else if (displayModel == EInkDetectionResult::E0213A367) // V1.1.1, V1.2
driver = new Drivers::E0213A367;
driver->begin(hspi, PIN_EINK_DC, PIN_EINK_CS, PIN_EINK_BUSY, PIN_EINK_RES);
// InkHUD
// ----------------------------
HeltecWPDetectedDriver detected = detectAndCreateHeltecWPDriver();
InkHUD::InkHUD *inkhud = InkHUD::InkHUD::getInstance();
inkhud->setDriver(detected.driver);
inkhud->setDisplayResilience(detected.fastPerFull, detected.stress);
// Set the E-Ink driver
inkhud->setDriver(driver);
// Set how many FAST updates per FULL update
// Set how unhealthy additional FAST updates beyond this number are
if (displayModel == EInkDetectionResult::LCMEN213EFC1) // V1.1 (unmarked)
inkhud->setDisplayResilience(10, 1.5);
else if (displayModel == EInkDetectionResult::E0213A367) // V1.1.1, V1.2
inkhud->setDisplayResilience(15, 3);
// Select fonts
InkHUD::Applet::fontLarge = FREESANS_12PT_WIN1252;
InkHUD::Applet::fontMedium = FREESANS_9PT_WIN1252;
InkHUD::Applet::fontSmall = FREESANS_6PT_WIN1252;
// Customize default settings
inkhud->persistence->settings.userTiles.maxCount = 2; // How many tiles can the display handle?
inkhud->persistence->settings.rotation = 3; // 270 degrees clockwise
inkhud->persistence->settings.userTiles.count = 1; // One tile only by default, keep things simple for new users
inkhud->persistence->settings.userTiles.maxCount = 2;
inkhud->persistence->settings.rotation = 3;
inkhud->persistence->settings.userTiles.count = 1;
// Pick applets
// Note: order of applets determines priority of "auto-show" feature
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("Favorites Map", new InkHUD::FavoritesMapApplet, false, false); // -
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->addApplet("Favorites Map", new InkHUD::FavoritesMapApplet, false, false);
// Start running InkHUD
inkhud->begin();
// Buttons
// --------------------------
Inputs::TwoButton *buttons = Inputs::TwoButton::getInstance(); // Shared NicheGraphics component
// #0: Main User Button
Inputs::TwoButton *buttons = Inputs::TwoButton::getInstance();
buttons->setWiring(0, Inputs::TwoButton::getUserButtonPin());
buttons->setHandlerShortPress(0, [inkhud]() { inkhud->shortpress(); });
buttons->setHandlerLongPress(0, [inkhud]() { inkhud->longpress(); });
// No aux button on this board
// Begin handling button events
buttons->start();
}
#else
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
HeltecWPDetectedDriver detected = detectAndCreateHeltecWPDriver();
auto *display = new NicheGraphics::BaseUIEInkDisplay(detected.driver, detected.rotation);
display->setDisplayResilience(detected.fastPerFull, detected.stress);
return display;
}
#endif
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -1,4 +1,3 @@
; Using the original screen class
[env:heltec-wireless-paper]
custom_meshtastic_hw_model = 49
custom_meshtastic_hw_model_slug = HELTEC_WIRELESS_PAPER
@@ -11,26 +10,20 @@ custom_meshtastic_tags = Heltec
custom_meshtastic_partition_scheme = 8MB
custom_meshtastic_has_ink_hud = true
extends = esp32s3_base
extends = esp32s3_base, niche
board = heltec_wifi_lora_32_V3
board_build.partitions = default_8MB.csv
build_flags =
${esp32s3_base.build_flags}
build_src_filter =
${esp32s3_base.build_src_filter}
${niche.build_src_filter}
build_flags =
${esp32s3_base.build_flags}
${niche.build_flags}
-I variants/esp32s3/heltec_wireless_paper
-D HELTEC_WIRELESS_PAPER
-D GXEPD2_DRIVER_0=GxEPD2_213_FC1
-D GXEPD2_DRIVER_1=GxEPD2_213_E0213A367
-D EINK_WIDTH=250
-D EINK_HEIGHT=122
-D HELTEC_WIRELESS_PAPER
-D USE_EINK
-D USE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
-D EINK_LIMIT_FASTREFRESH=10 ; How many consecutive fast-refreshes are permitted
-D EINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached.
-D EINK_HASQUIRK_GHOSTING ; Display model is identified as "prone to ghosting"
lib_deps =
${esp32s3_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
https://github.com/meshtastic/GxEPD2/archive/c7eb4c3c167cf396ef4f541cc5d4c6aa42f3c46b.zip
upload_speed = 115200
[env:heltec-wireless-paper-inkhud]
@@ -0,0 +1,38 @@
/*
NicheGraphics setup for Heltec Wireless Paper V1.0 (DEPG0213BNS800 on HSPI).
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Panels/DEPG0213BNS800.h"
class HeltecWirelessPaperV1Panel : public NicheGraphics::Panels::DEPG0213BNS800
{
protected:
SPIClass *beginSpi() override
{
auto *hspi = new SPIClass(HSPI);
hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS);
return hspi;
}
};
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new HeltecWirelessPaperV1Panel();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panel->rotation());
display->setDisplayResilience(5, 1.5f);
return display;
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -9,22 +9,18 @@ custom_meshtastic_images = heltec-wireless-paper-v1_0.svg
custom_meshtastic_tags = Heltec
custom_meshtastic_partition_scheme = 8MB
extends = esp32s3_base
extends = esp32s3_base, niche
board_level = extra
board = heltec_wifi_lora_32_V3
board_build.partitions = default_8MB.csv
build_flags =
${esp32s3_base.build_flags}
-I variants/esp32s3/heltec_wireless_paper_v1
build_src_filter =
${esp32s3_base.build_src_filter}
${niche.build_src_filter}
build_flags =
${esp32s3_base.build_flags}
${niche.build_flags}
-I variants/esp32s3/heltec_wireless_paper_v1
-D HELTEC_WIRELESS_PAPER_V1_0
-D EINK_DISPLAY_MODEL=GxEPD2_213_BN
-D EINK_WIDTH=250
-D EINK_HEIGHT=122
-D USE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
-D EINK_LIMIT_FASTREFRESH=5 ; How many consecutive fast-refreshes are permitted
-D EINK_LIMIT_GHOSTING_PX=2000 ; (Optional) How much image ghosting is tolerated
lib_deps =
${esp32s3_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
https://github.com/meshtastic/GxEPD2/archive/c7eb4c3c167cf396ef4f541cc5d4c6aa42f3c46b.zip
upload_speed = 115200
+72 -55
View File
@@ -1,58 +1,79 @@
/*
NicheGraphics setup for LILYGO Mini ePaper S3 (GDEW0102T4 1.02" on HSPI).
Shared by both BaseUI and InkHUD envs.
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
// InkHUD-specific components
#include "graphics/niche/InkHUD/InkHUD.h"
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Drivers/GDEW0102T4.h"
#include "graphics/eink/Panels/GDEW0102T4.h"
// Applets
#include "graphics/niche/InkHUD/Applet.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/FavoritesMap/FavoritesMapApplet.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/SystemApplet.h"
// Shared NicheGraphics components
#include "graphics/niche/Drivers/EInk/GDEW0102T4.h"
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "graphics/niche/Applet.h"
#include "graphics/niche/Applets/User/AllMessage/AllMessageApplet.h"
#include "graphics/niche/Applets/User/DM/DMApplet.h"
#include "graphics/niche/Applets/User/FavoritesMap/FavoritesMapApplet.h"
#include "graphics/niche/Applets/User/Heard/HeardApplet.h"
#include "graphics/niche/Applets/User/Positions/PositionsApplet.h"
#include "graphics/niche/Applets/User/RecentsList/RecentsListApplet.h"
#include "graphics/niche/Applets/User/ThreadedMessage/ThreadedMessageApplet.h"
#include "graphics/niche/InkHUD.h"
#include "graphics/niche/Inputs/TwoButtonExtended.h"
#include "graphics/niche/SystemApplet.h"
#endif
class MiniEpaperS3Panel : public NicheGraphics::Panels::GDEW0102T4
{
public:
uint8_t rotation() const override { return 0; }
protected:
void prePowerOn() override
{
pinMode(PIN_EINK_EN, OUTPUT);
digitalWrite(PIN_EINK_EN, HIGH);
delay(10);
}
SPIClass *beginSpi() override
{
auto *hspi = new SPIClass(HSPI);
hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS);
return hspi;
}
};
static NicheGraphics::Drivers::EInk *makeMiniEpaperS3Driver()
{
auto *panel = new MiniEpaperS3Panel();
auto *driver = panel->create();
// Tuned fast-refresh values: reg30 reg50 reg82 lutW2 lutB2 = 11 F2 04 11 0D
static_cast<NicheGraphics::Drivers::GDEW0102T4 *>(driver)->setFastConfig({0x11, 0xF2, 0x04, 0x11, 0x0D});
return driver;
}
#ifdef MESHTASTIC_INCLUDE_INKHUD
void setupNicheGraphics()
{
using namespace NicheGraphics;
// Power-enable the E-Ink panel on this board before any SPI traffic.
pinMode(PIN_EINK_EN, OUTPUT);
digitalWrite(PIN_EINK_EN, HIGH);
delay(10);
// Display uses HSPI on this board
SPIClass *hspi = new SPIClass(HSPI);
hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS);
Drivers::GDEW0102T4 *displayDriver = new Drivers::GDEW0102T4;
displayDriver->begin(hspi, PIN_EINK_DC, PIN_EINK_CS, PIN_EINK_BUSY, PIN_EINK_RES);
// Tuned fast-refresh values reg30 reg50 reg82 lutW2 lutB2 = 11 F2 04 11 0D
displayDriver->setFastConfig({0x11, 0xF2, 0x04, 0x11, 0x0D});
Drivers::EInk *driver = displayDriver;
Drivers::EInk *driver = makeMiniEpaperS3Driver();
InkHUD::InkHUD *inkhud = InkHUD::InkHUD::getInstance();
inkhud->setDriver(driver);
// Slightly stricter FAST/FULL
inkhud->setDisplayResilience(5, 1.5);
inkhud->twoWayRocker = true;
// Fonts
InkHUD::Applet::fontLarge = FREESANS_9PT_WIN1252;
InkHUD::Applet::fontMedium = FREESANS_6PT_WIN1252;
InkHUD::Applet::fontSmall = FREESANS_6PT_WIN1252;
// Small display defaults
inkhud->persistence->settings.rotation = 0;
inkhud->persistence->settings.userTiles.maxCount = 1;
inkhud->persistence->settings.userTiles.count = 1;
@@ -60,41 +81,28 @@ void setupNicheGraphics()
inkhud->persistence->settings.joystick.aligned = true;
inkhud->persistence->settings.optionalMenuItems.nextTile = false;
// Pick applets
// Note: order of applets determines priority of "auto-show" feature
inkhud->addApplet("All Messages", new InkHUD::AllMessageApplet, false, false); // -
inkhud->addApplet("DMs", new InkHUD::DMApplet, true, false); // Activated, not autoshown
inkhud->addApplet("Channel 0", new InkHUD::ThreadedMessageApplet(0), true, true); // Activated, Autoshown
inkhud->addApplet("Channel 1", new InkHUD::ThreadedMessageApplet(1), false, false); // -
inkhud->addApplet("Positions", new InkHUD::PositionsApplet, true); // Activated
inkhud->addApplet("Favorites Map", new InkHUD::FavoritesMapApplet, false, false); // -
inkhud->addApplet("Recents List", new InkHUD::RecentsListApplet, false, false); // -
inkhud->addApplet("Heard", new InkHUD::HeardApplet, true, false, 0); // Activated, not autoshown, default on tile 0
// Start running InkHUD
inkhud->addApplet("All Messages", new InkHUD::AllMessageApplet, false, false);
inkhud->addApplet("DMs", new InkHUD::DMApplet, true, false);
inkhud->addApplet("Channel 0", new InkHUD::ThreadedMessageApplet(0), true, true);
inkhud->addApplet("Channel 1", new InkHUD::ThreadedMessageApplet(1), false, false);
inkhud->addApplet("Positions", new InkHUD::PositionsApplet, true);
inkhud->addApplet("Favorites Map", new InkHUD::FavoritesMapApplet, false, false);
inkhud->addApplet("Recents List", new InkHUD::RecentsListApplet, false, false);
inkhud->addApplet("Heard", new InkHUD::HeardApplet, true, false, 0);
inkhud->begin();
// Enforce two-way rocker behavior regardless of persisted settings.
inkhud->persistence->settings.joystick.enabled = true;
inkhud->persistence->settings.joystick.aligned = true;
inkhud->persistence->settings.optionalMenuItems.nextTile = false;
// Inputs
Inputs::TwoButtonExtended *buttons = Inputs::TwoButtonExtended::getInstance();
// Center press (boot button)
buttons->setWiring(0, INPUTDRIVER_TWO_WAY_ROCKER_BTN, true);
// Match baseUI encoder long-press feel.
buttons->setTiming(0, 75, 300);
buttons->setHandlerShortPress(0, [inkhud]() { inkhud->shortpress(); });
buttons->setHandlerLongPress(0, [inkhud]() { inkhud->longpress(); });
// LEFT rocker pin is IO4; RIGHT rocker pin is IO3.
buttons->setTwoWayRockerWiring(INPUTDRIVER_TWO_WAY_ROCKER_LEFT, INPUTDRIVER_TWO_WAY_ROCKER_RIGHT, true);
buttons->setJoystickDebounce(50);
// Two-way rocker behavior:
// - when a system applet is handling input (menu, tips, etc): LEFT=up, RIGHT=down
// - otherwise: LEFT=previous applet, RIGHT=next applet
buttons->setTwoWayRockerPressHandlers(
[inkhud]() {
bool systemHandlingInput = false;
@@ -104,7 +112,6 @@ void setupNicheGraphics()
break;
}
}
if (systemHandlingInput)
inkhud->navUp();
else
@@ -118,7 +125,6 @@ void setupNicheGraphics()
break;
}
}
if (systemHandlingInput)
inkhud->navDown();
else
@@ -127,5 +133,16 @@ void setupNicheGraphics()
buttons->start();
}
#else
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
NicheGraphics::Drivers::EInk *driver = makeMiniEpaperS3Driver();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, 0);
display->setDisplayResilience(3, 1.5f);
return display;
}
#endif
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+6 -11
View File
@@ -10,28 +10,23 @@ custom_meshtastic_tags = LilyGo
custom_meshtastic_requires_dfu = no
custom_meshtastic_has_mui = false
extends = esp32s3_base
extends = esp32s3_base, niche
board = mini-epaper-s3
board_check = true
upload_protocol = esptool
build_flags =
build_src_filter =
${esp32s3_base.build_src_filter}
${niche.build_src_filter}
build_flags =
${esp32s3_base.build_flags}
${niche.build_flags}
-I variants/esp32s3/mini-epaper-s3
-D MINI_EPAPER_S3
-D USE_EINK
-D EINK_DISPLAY_MODEL=GxEPD2_102
-D EINK_WIDTH=128
-D EINK_HEIGHT=80
-D USE_EINK_DYNAMICDISPLAY
-D EINK_LIMIT_FASTREFRESH=3
-D EINK_BACKGROUND_USES_FAST
-D EINK_HASQUIRK_GHOSTING
lib_deps =
${esp32s3_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
https://github.com/meshtastic/GxEPD2/archive/c7eb4c3c167cf396ef4f541cc5d4c6aa42f3c46b.zip
# renovate: datasource=custom.pio depName=SensorLib packageName=lewisxhe/library/SensorLib
lewisxhe/SensorLib@0.3.4
@@ -0,0 +1,39 @@
/*
NicheGraphics setup for LILYGO T-Deck Pro (GDEQ031T10 3.1" 240x320 on the default SPI bus).
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Panels/GDEQ031T10.h"
class TDeckProPanel : public NicheGraphics::Panels::GDEQ031T10
{
protected:
SPIClass *beginSpi() override
{
// Old GxEPD2 path used the global SPI bus on this board.
SPI.begin();
return &SPI;
}
};
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new TDeckProPanel();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panel->rotation());
// T-Deck Pro types frequently; allow more FAST refreshes between FULLs than the default.
display->setDisplayResilience(15, 1.5f);
return display;
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+4 -8
View File
@@ -11,7 +11,7 @@ custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 16MB
custom_meshtastic_has_mui = false
extends = esp32s3_base
extends = esp32s3_base, niche
board = t-deck-pro
board_check = true
upload_protocol = esptool
@@ -19,22 +19,18 @@ upload_protocol = esptool
build_src_filter =
${esp32s3_base.build_src_filter}
+<../variants/esp32s3/t-deck-pro>
${niche.build_src_filter}
build_flags =
build_flags =
${esp32s3_base.build_flags} -I variants/esp32s3/t-deck-pro
${niche.build_flags}
-D T_DECK_PRO
-D USE_EINK
-D EINK_DISPLAY_MODEL=GxEPD2_310_GDEQ031T10
-D EINK_WIDTH=240
-D EINK_HEIGHT=320
;-D USE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
-D EINK_LIMIT_FASTREFRESH=10 ; How many consecutive fast-refreshes are permitted
-D EINK_LIMIT_GHOSTING_PX=2000 ; (Optional) How much image ghosting is tolerated
lib_deps =
${esp32s3_base.lib_deps}
# renovate: datasource=custom.pio depName=GxEPD2 packageName=zinggjm/library/GxEPD2
zinggjm/GxEPD2@1.6.8
# renovate: datasource=git-refs depName=CSE_Touch packageName=https://github.com/CIRCUITSTATE/CSE_Touch gitBranch=main
https://github.com/CIRCUITSTATE/CSE_Touch/archive/b44f23b6f870b848f1fbe453c190879bc6cfaafa.zip
# renovate: datasource=github-tags depName=CSE_CST328 packageName=CIRCUITSTATE/CSE_CST328
+83 -89
View File
@@ -1,123 +1,117 @@
/*
Most of the Meshtastic firmware uses preprocessor macros throughout the code to support different hardware variants.
NicheGraphics attempts a different approach:
NicheGraphics setup for LILYGO T5 ePaper Pro (ED047TC1, 960x540, parallel via FastEPD).
Per-device config takes place in this setupNicheGraphics() method
(And a small amount in platformio.ini)
Three envs share this directory:
- t5s3-epaper-v1 (BaseUI, BB_PANEL_LILYGO_T5PRO)
- t5s3-epaper-v2 (BaseUI, BB_PANEL_LILYGO_T5PRO_V2 + GPIO-expander setup)
- t5s3_epaper_inkhud (InkHUD on V2)
This file sets up InkHUD for Heltec VM-E290.
Different NicheGraphics UIs and different hardware variants will each have their own setup procedure.
The active panel is selected by the T5_S3_EPAPER_PRO_V1 / T5_S3_EPAPER_PRO_V2 macros from platformio.ini.
*/
#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"
#include "FastEPD.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"
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Drivers/EInkParallel.h"
#include "graphics/eink/Panels/T5Epaper.h"
// Shared NicheGraphics components
// --------------------------------
#include "graphics/niche/Drivers/Backlight/LatchingBacklight.h"
#include "graphics/niche/Drivers/EInk/DEPG0290BNS800.h"
#include "graphics/niche/Inputs/TwoButton.h"
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "graphics/niche/Applets/User/AllMessage/AllMessageApplet.h"
#include "graphics/niche/Applets/User/DM/DMApplet.h"
#include "graphics/niche/Applets/User/Heard/HeardApplet.h"
#include "graphics/niche/Applets/User/Positions/PositionsApplet.h"
#include "graphics/niche/Applets/User/RecentsList/RecentsListApplet.h"
#include "graphics/niche/Applets/User/ThreadedMessage/ThreadedMessageApplet.h"
#include "graphics/niche/InkHUD.h"
#endif
#if defined(T5_S3_EPAPER_PRO_V2)
class T5V2Driver : public NicheGraphics::Drivers::EInkParallel
{
public:
T5V2Driver() : EInkParallel(960, 540, BB_PANEL_LILYGO_T5PRO_V2, 28000000) {}
protected:
void postPanelInit() override
{
// V2 uses a GPIO expander; raise port-0 pins 0..7 high (as the legacy driver did).
FASTEPD *epd = fastEpd();
for (int i = 0; i < 8; i++) {
epd->ioPinMode(i, OUTPUT);
epd->ioWrite(i, HIGH);
}
}
};
#elif defined(T5_S3_EPAPER_PRO_V1)
class T5V1Driver : public NicheGraphics::Drivers::EInkParallel
{
public:
T5V1Driver() : EInkParallel(960, 540, BB_PANEL_LILYGO_T5PRO, 28000000) {}
};
#else
#error "t5s3_epaper requires T5_S3_EPAPER_PRO_V1 or T5_S3_EPAPER_PRO_V2"
#endif
class T5EpaperPanel : public NicheGraphics::Panels::T5EpaperPanel
{
protected:
NicheGraphics::Drivers::EInkParallel *makeDriver() override
{
#if defined(T5_S3_EPAPER_PRO_V2)
return new T5V2Driver();
#else
return new T5V1Driver();
#endif
}
};
#ifdef MESHTASTIC_INCLUDE_INKHUD
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
// ----------------------------
auto *panel = new T5EpaperPanel();
Drivers::EInk *driver = panel->create();
InkHUD::InkHUD *inkhud = InkHUD::InkHUD::getInstance();
// Set the driver
inkhud->setDriver(driver);
inkhud->setDisplayResilience(20, 1.5);
// 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::fontLarge = FREESANS_12PT_WIN1252;
InkHUD::Applet::fontMedium = 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
inkhud->persistence->settings.userTiles.maxCount = 4;
inkhud->persistence->settings.userTiles.count = 1;
// 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("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); // Activated
inkhud->addApplet("Positions", new InkHUD::PositionsApplet, true);
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);
inkhud->addApplet("Heard", new InkHUD::HeardApplet, true, false, 0);
// 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();
}
#else
void setupNicheGraphics() {}
#endif
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new T5EpaperPanel();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, 0);
display->setDisplayResilience(20, 1.5f);
return display;
}
#endif
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+6 -7
View File
@@ -1,26 +1,25 @@
[t5s3_epaper_base]
extends = esp32s3_base
extends = esp32s3_base, niche
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}
${esp32_base.build_flags}
${niche.build_flags}
-I variants/esp32s3/t5s3_epaper
-D T5_S3_EPAPER_PRO
-D USE_EINK
-D USE_EINK_PARALLELDISPLAY
-D NICHE_HAS_FASTEPD ; activate NicheGraphics parallel-EPD driver (FastEPD)
-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 =
build_src_filter =
${esp32s3_base.build_src_filter}
+<../variants/esp32s3/t5s3_epaper>
${niche.build_src_filter}
lib_deps =
${esp32s3_base.lib_deps}
# renovate: datasource=custom.pio depName=SensorLib packageName=lewisxhe/library/SensorLib
@@ -1,91 +1,90 @@
/*
NicheGraphics setup for LILYGO T-LoRa T3-S3 ePaper (DEPG0213BNS800 on HSPI).
Shared by both BaseUI and InkHUD envs.
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
// InkHUD-specific components
// ---------------------------
#include "graphics/niche/InkHUD/InkHUD.h"
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Panels/DEPG0213BNS800.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/FavoritesMap/FavoritesMapApplet.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/EInk/DEPG0213BNS800.h"
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "graphics/niche/Applets/User/AllMessage/AllMessageApplet.h"
#include "graphics/niche/Applets/User/DM/DMApplet.h"
#include "graphics/niche/Applets/User/FavoritesMap/FavoritesMapApplet.h"
#include "graphics/niche/Applets/User/Heard/HeardApplet.h"
#include "graphics/niche/Applets/User/Positions/PositionsApplet.h"
#include "graphics/niche/Applets/User/RecentsList/RecentsListApplet.h"
#include "graphics/niche/Applets/User/ThreadedMessage/ThreadedMessageApplet.h"
#include "graphics/niche/InkHUD.h"
#include "graphics/niche/Inputs/TwoButton.h"
#endif
class TLoraT3S3Panel : public NicheGraphics::Panels::DEPG0213BNS800
{
protected:
SPIClass *beginSpi() override
{
auto *hspi = new SPIClass(HSPI);
hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS);
return hspi;
}
};
#ifdef MESHTASTIC_INCLUDE_INKHUD
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
// -----------------------------
Drivers::EInk *driver = new Drivers::DEPG0213BNS800;
driver->begin(hspi, PIN_EINK_DC, PIN_EINK_CS, PIN_EINK_BUSY, PIN_EINK_RES);
// InkHUD
// ----------------------------
auto *panel = new TLoraT3S3Panel();
Drivers::EInk *driver = panel->create();
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(15, 1.5);
// Select fonts
InkHUD::Applet::fontLarge = FREESANS_12PT_WIN1252;
InkHUD::Applet::fontMedium = FREESANS_9PT_WIN1252;
InkHUD::Applet::fontSmall = FREESANS_6PT_WIN1252;
// Customize default settings
inkhud->persistence->settings.userTiles.maxCount = 2; // How many tiles can the display handle?
inkhud->persistence->settings.rotation = 3; // 270 degrees clockwise
inkhud->persistence->settings.userTiles.count = 1; // One tile only by default, keep things simple for new users
inkhud->persistence->settings.userTiles.maxCount = 2;
inkhud->persistence->settings.rotation = 3;
inkhud->persistence->settings.userTiles.count = 1;
// Pick applets
// Note: order of applets determines priority of "auto-show" feature
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("Favorites Map", new InkHUD::FavoritesMapApplet); // -
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("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("Favorites Map", new InkHUD::FavoritesMapApplet);
inkhud->addApplet("Recents List", new InkHUD::RecentsListApplet);
inkhud->addApplet("Heard", new InkHUD::HeardApplet, true, false, 0);
// Start running InkHUD
inkhud->begin();
// Buttons
// --------------------------
Inputs::TwoButton *buttons = Inputs::TwoButton::getInstance(); // Shared NicheGraphics component
// Setup the main user button
Inputs::TwoButton *buttons = Inputs::TwoButton::getInstance();
buttons->setWiring(0, Inputs::TwoButton::getUserButtonPin(), true);
buttons->setHandlerShortPress(0, [inkhud]() { inkhud->shortpress(); });
buttons->setHandlerLongPress(0, [inkhud]() { inkhud->longpress(); });
buttons->start();
}
#else
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new TLoraT3S3Panel();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panel->rotation());
display->setDisplayResilience(15, 1.5f);
return display;
}
#endif
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -10,29 +10,23 @@ custom_meshtastic_tags = LilyGo
custom_meshtastic_requires_dfu = true
custom_meshtastic_has_ink_hud = true
extends = esp32s3_base
extends = esp32s3_base, niche
board = tlora-t3s3-v1
board_check = true
upload_protocol = esptool
build_flags =
build_src_filter =
${esp32s3_base.build_src_filter}
${niche.build_src_filter}
build_flags =
${esp32s3_base.build_flags}
${niche.build_flags}
-D TLORA_T3S3_EPAPER
-I variants/esp32s3/tlora_t3s3_epaper
-DUSE_EINK
-DEINK_DISPLAY_MODEL=GxEPD2_213_BN
-DEINK_WIDTH=250
-DEINK_HEIGHT=122
-DUSE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
-DEINK_LIMIT_FASTREFRESH=20 ; How many consecutive fast-refreshes are permitted //20
-DEINK_LIMIT_RATE_BACKGROUND_SEC=30 ; Minimum interval between BACKGROUND updates //30
-DEINK_LIMIT_RATE_RESPONSIVE_SEC=1 ; Minimum interval between RESPONSIVE updates
-DEINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached.
lib_deps =
${esp32s3_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
https://github.com/meshtastic/GxEPD2/archive/c7eb4c3c167cf396ef4f541cc5d4c6aa42f3c46b.zip
[env:tlora-t3s3-epaper-inkhud]
extends = esp32s3_base, inkhud
@@ -0,0 +1,35 @@
/*
NicheGraphics setup for the Nordic pca10059 dongle + 4.2" e-ink DIY build
(as shipped: GDEW042M01, 400x300, UC8276 controller).
No UC8276 driver exists in the NicheGraphics tree, so this uses the
HINK_E042A87 profile (same 400x300 geometry, SSD1680-based). The command
sets differ; if the panel misbehaves, drop in a UC8276 profile here.
Uses SPI1 per variant.h (SCLK=P0.09, MOSI=P0.10), which is the default
for nRF52 panel profiles.
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Panels/HINK_E042A87.h"
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new NicheGraphics::Panels::HINK_E042A87();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panel->rotation());
display->setDisplayResilience(10, 2.0f);
return display;
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -1,16 +1,12 @@
[env:pca10059_diy_eink]
board_level = extra
extends = nrf52840_base
extends = nrf52840_base, niche
board = nordic_pca10059
build_flags = ${nrf52840_base.build_flags}
${niche.build_flags}
-Ivariants/nrf52840/Dongle_nRF52840-pca10059-v1
-D NORDIC_PCA10059
-DEINK_DISPLAY_MODEL=GxEPD2_420_M01
-DEINK_WIDTH=300
-DEINK_HEIGHT=400
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/Dongle_nRF52840-pca10059-v1>
lib_deps =
build_src_filter = ${nrf52_base.build_src_filter} ${niche.build_src_filter} +<../variants/nrf52840/Dongle_nRF52840-pca10059-v1>
lib_deps =
${nrf52840_base.lib_deps}
# renovate: datasource=custom.pio depName=GxEPD2 packageName=zinggjm/library/GxEPD2
zinggjm/GxEPD2@1.6.8
debug_tool = jlink
@@ -1,120 +1,93 @@
/*
NicheGraphics setup for Elecrow ThinkNode-M1 (GDEY0154D67 1.54" on SPI1).
Shared by both BaseUI and InkHUD envs.
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
// InkHUD-specific components
// ---------------------------
#include "graphics/niche/InkHUD/InkHUD.h"
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Backlight/LatchingBacklight.h"
#include "graphics/eink/Panels/GDEY0154D67.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/FavoritesMap/FavoritesMapApplet.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/GDEY0154D67.h"
#include "graphics/niche/Inputs/TwoButton.h"
// Button feedback
#include "buzz.h"
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "graphics/niche/Applets/User/AllMessage/AllMessageApplet.h"
#include "graphics/niche/Applets/User/DM/DMApplet.h"
#include "graphics/niche/Applets/User/FavoritesMap/FavoritesMapApplet.h"
#include "graphics/niche/Applets/User/Heard/HeardApplet.h"
#include "graphics/niche/Applets/User/Positions/PositionsApplet.h"
#include "graphics/niche/Applets/User/RecentsList/RecentsListApplet.h"
#include "graphics/niche/Applets/User/ThreadedMessage/ThreadedMessageApplet.h"
#include "graphics/niche/InkHUD.h"
#include "graphics/niche/Inputs/TwoButton.h"
#endif
#ifdef MESHTASTIC_INCLUDE_INKHUD
void setupNicheGraphics()
{
using namespace NicheGraphics;
// SPI
// -----------------------------
// For NRF52 platforms, SPI pins are defined in variant.h
SPI1.begin();
// E-Ink Driver
// -----------------------------
Drivers::EInk *driver = new Drivers::GDEY0154D67;
driver->begin(&SPI1, PIN_EINK_DC, PIN_EINK_CS, PIN_EINK_BUSY, PIN_EINK_RES);
// InkHUD
// ----------------------------
auto *panel = new Panels::GDEY0154D67();
Drivers::EInk *driver = panel->create();
InkHUD::InkHUD *inkhud = InkHUD::InkHUD::getInstance();
// Set the E-Ink driver
inkhud->setDriver(driver);
// Set how many FAST updates per FULL update
// Set how unhealthy additional FAST updates beyond this number are
// Todo: observe the display's performance in-person and adjust accordingly.
// Currently set to the values given by Elecrow for EInkDynamicDisplay.
inkhud->setDisplayResilience(10, 1.5);
// Select fonts
InkHUD::Applet::fontLarge = FREESANS_12PT_WIN1252;
InkHUD::Applet::fontMedium = FREESANS_9PT_WIN1252;
InkHUD::Applet::fontSmall = FREESANS_6PT_WIN1252;
// Customize default settings
inkhud->persistence->settings.userTiles.maxCount = 2; // Two applets side-by-side
inkhud->persistence->settings.optionalFeatures.batteryIcon = true; // Device definitely has a battery
inkhud->persistence->settings.userTiles.maxCount = 2;
inkhud->persistence->settings.optionalFeatures.batteryIcon = true;
// Setup backlight controller
// Note: button is attached 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
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, no autoshow, default on tile 0
inkhud->addApplet("Favorites Map", new InkHUD::FavoritesMapApplet, false, false); // -
// Start running InkHUD
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("Favorites Map", new InkHUD::FavoritesMapApplet);
inkhud->addApplet("Recents List", new InkHUD::RecentsListApplet);
inkhud->addApplet("Heard", new InkHUD::HeardApplet, true, false, 0);
inkhud->begin();
// Buttons
// --------------------------
Inputs::TwoButton *buttons = Inputs::TwoButton::getInstance(); // Shared NicheGraphics component
// Elecrow diagram: https://www.elecrow.com/download/product/CIL12901M/ThinkNode-M1_User_Manual.pdf
// #0: Main User Button
// Labeled "Page Turn Button" by manual
buttons->setWiring(0, PIN_BUTTON2);
buttons->setTiming(0, 50, 500); // Todo: confirm 50ms is adequate debounce
Inputs::TwoButton *buttons = Inputs::TwoButton::getInstance();
buttons->setWiring(0, Inputs::TwoButton::getUserButtonPin());
buttons->setHandlerShortPress(0, [inkhud]() { inkhud->shortpress(); });
buttons->setHandlerLongPress(0, [inkhud]() { inkhud->longpress(); });
// #1: Aux Button
// Labeled "Function Button" by manual
// Todo: additional features
buttons->setWiring(1, PIN_BUTTON1);
buttons->setTiming(1, 50, 500); // 500ms before latch
buttons->setHandlerDown(1, [backlight]() { backlight->peek(); });
buttons->setHandlerLongPress(1, [backlight]() {
backlight->latch();
playBoop();
});
buttons->setHandlerShortPress(1, [backlight]() {
backlight->off();
playChirp();
});
// Begin handling button events
#ifdef PIN_BUTTON2
buttons->setWiring(1, PIN_BUTTON2);
buttons->setHandlerShortPress(1, [backlight]() { backlight->latch(); });
buttons->setHandlerLongPress(1, [backlight]() { backlight->off(); });
#endif
buttons->start();
}
#else
void setupNicheGraphics()
{
// Backlight on by default for the original BaseUI build.
pinMode(PIN_EINK_EN, OUTPUT);
digitalWrite(PIN_EINK_EN, HIGH);
}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new NicheGraphics::Panels::GDEY0154D67();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panel->rotation());
display->setDisplayResilience(10, 1.5f);
return display;
}
#endif
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -10,31 +10,20 @@ custom_meshtastic_images = thinknode_m1.svg
custom_meshtastic_tags = Elecrow
custom_meshtastic_has_ink_hud = true
extends = nrf52840_base
extends = nrf52840_base, niche
board = ThinkNode-M1
board_check = true
debug_tool = jlink
# add -DCFG_SYSVIEW if you want to use the Segger systemview tool for OS profiling.
build_flags = ${nrf52840_base.build_flags}
${niche.build_flags}
-Ivariants/nrf52840/ELECROW-ThinkNode-M1
-DELECROW_ThinkNode_M1
-DUSE_EINK
-DEINK_DISPLAY_MODEL=GxEPD2_154_D67
-DEINK_WIDTH=200
-DEINK_HEIGHT=200
-DUSE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
-DEINK_LIMIT_FASTREFRESH=10 ; How many consecutive fast-refreshes are permitted //20
-DEINK_LIMIT_RATE_BACKGROUND_SEC=10 ; Minimum interval between BACKGROUND updates //30
-DEINK_LIMIT_RATE_RESPONSIVE_SEC=1 ; Minimum interval between RESPONSIVE updates
; -DEINK_LIMIT_GHOSTING_PX=2000 ; (Optional) How much image ghosting is tolerated
-DEINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached.
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/ELECROW-ThinkNode-M1>
lib_deps =
build_src_filter = ${nrf52_base.build_src_filter} ${niche.build_src_filter} +<../variants/nrf52840/ELECROW-ThinkNode-M1>
lib_deps =
${nrf52840_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
https://github.com/meshtastic/GxEPD2/archive/c7eb4c3c167cf396ef4f541cc5d4c6aa42f3c46b.zip
# renovate: datasource=custom.pio depName=nRF52_PWM packageName=khoih-prog/library/nRF52_PWM
khoih-prog/nRF52_PWM@1.0.1
;upload_protocol = fs
@@ -44,15 +33,15 @@ extends = nrf52840_base, inkhud
board = ThinkNode-M1
board_check = true
debug_tool = jlink
build_flags =
build_flags =
${nrf52840_base.build_flags}
${inkhud.build_flags}
-I variants/nrf52840/ELECROW-ThinkNode-M1
-D ELECROW_ThinkNode_M1
build_src_filter =
${nrf52_base.build_src_filter}
build_src_filter =
${nrf52_base.build_src_filter}
${inkhud.build_src_filter}
+<../variants/nrf52840/ELECROW-ThinkNode-M1>
lib_deps =
lib_deps =
${inkhud.lib_deps} ; InkHUD libs first, so we get GFXRoot instead of AdafruitGFX
${nrf52840_base.lib_deps}
@@ -0,0 +1,27 @@
/*
NicheGraphics setup for ME25LS01-4Y10TD e-ink board (GDEY042T81 4.2" on SPI1).
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Panels/GDEY042T81.h"
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new NicheGraphics::Panels::GDEY042T81();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panel->rotation());
display->setDisplayResilience(10, 2.0f);
return display;
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -1,22 +1,18 @@
[env:ME25LS01-4Y10TD_e-ink]
extends = nrf52840_base
extends = nrf52840_base, niche
board = me25ls01-4y10td
board_level = extra
; platform = https://github.com/maxgerhardt/platform-nordicnrf52#cac6fcf943a41accd2aeb4f3659ae297a73f422e
build_flags = ${nrf52840_base.build_flags}
${niche.build_flags}
-Ivariants/nrf52840/ME25LS01-4Y10TD_e-ink
-Isrc/platform/nrf52/softdevice
-Isrc/platform/nrf52/softdevice/nrf52
-DME25LS01_4Y10TD
-DEINK_DISPLAY_MODEL=GxEPD2_420_GDEY042T81
-DEINK_WIDTH=400
-DEINK_HEIGHT=300
board_build.ldscript = src/platform/nrf52/nrf52840_s140_v7.ld
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/ME25LS01-4Y10TD_e-ink>
lib_deps =
build_src_filter = ${nrf52_base.build_src_filter} ${niche.build_src_filter} +<../variants/nrf52840/ME25LS01-4Y10TD_e-ink>
lib_deps =
${nrf52840_base.lib_deps}
# renovate: datasource=custom.pio depName=GxEPD2 packageName=zinggjm/library/GxEPD2
zinggjm/GxEPD2@1.6.8
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
upload_protocol = nrfutil
;upload_port = /dev/ttyACM1
@@ -0,0 +1,35 @@
/*
NicheGraphics setup for the MakerPython nRF52840 + SX1280 DIY e-ink board
(as shipped: GDEW029T5D, 128x296, UC8151D controller).
The UC8151D init/command set is close enough to SSD1680 that GDEY029T94
(same 128x296 geometry, SSD1680-based) is used as the panel profile.
If the panel misbehaves, drop in a UC8151D profile here.
Uses SPI1 per variant.h (SCLK=P0.02, MOSI=P0.28), which is the default
for nRF52 panel profiles.
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Panels/GDEY029T94.h"
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new NicheGraphics::Panels::GDEY029T94();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panel->rotation());
display->setDisplayResilience(7, 1.5f);
return display;
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -1,20 +1,16 @@
[env:makerpython_nrf52840_sx1280_eink]
board_level = extra
extends = nrf52840_base
extends = nrf52840_base, niche
board = nordic_pca10059
build_flags = ${nrf52840_base.build_flags}
${niche.build_flags}
-Ivariants/nrf52840/MakePython_nRF52840_eink
-D PRIVATE_HW
-D PIN_EINK_EN
-DEINK_DISPLAY_MODEL=GxEPD2_290_T5D
-DEINK_WIDTH=296
-DEINK_HEIGHT=128
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/MakePython_nRF52840_eink>
lib_deps =
build_src_filter = ${nrf52_base.build_src_filter} ${niche.build_src_filter} +<../variants/nrf52840/MakePython_nRF52840_eink>
lib_deps =
${nrf52840_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master
https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip
# renovate: datasource=custom.pio depName=GxEPD2 packageName=zinggjm/library/GxEPD2
zinggjm/GxEPD2@1.6.8
debug_tool = jlink
;upload_port = /dev/ttyACM4
+1 -3
View File
@@ -6,8 +6,6 @@ build_flags = ${nrf52840_base.build_flags}
-I variants/nrf52840/TWC_mesh_v4
-D TWC_mesh_v4
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/TWC_mesh_v4>
lib_deps =
lib_deps =
${nrf52840_base.lib_deps}
# renovate: datasource=custom.pio depName=GxEPD2 packageName=zinggjm/library/GxEPD2
zinggjm/GxEPD2@1.6.8
debug_tool = jlink
@@ -6,25 +6,24 @@
// InkHUD-specific components
// ---------------------------
#include "graphics/niche/InkHUD/InkHUD.h"
#include "graphics/niche/InkHUD.h"
#include "graphics/niche/Inputs/TwoButton.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/FavoritesMap/FavoritesMapApplet.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/Applets/User/AllMessage/AllMessageApplet.h"
#include "graphics/niche/Applets/User/DM/DMApplet.h"
#include "graphics/niche/Applets/User/FavoritesMap/FavoritesMapApplet.h"
#include "graphics/niche/Applets/User/Heard/HeardApplet.h"
#include "graphics/niche/Applets/User/Positions/PositionsApplet.h"
#include "graphics/niche/Applets/User/RecentsList/RecentsListApplet.h"
#include "graphics/niche/Applets/User/ThreadedMessage/ThreadedMessageApplet.h"
// Shared NicheGraphics components
// --------------------------------
#include "graphics/niche/Drivers/EInk/HINK_E0213A289.h" // WeAct 2.13"
#include "graphics/niche/Drivers/EInk/HINK_E042A87.h" // WeAct 4.2"
#include "graphics/niche/Drivers/EInk/ZJY128296_029EAAMFGN.h" // WeAct 2.9"
#include "graphics/niche/Drivers/EInk/ZJY200200_0154DAAMFGN.h" // WeACt 1.54"
#include "graphics/niche/Inputs/TwoButton.h"
#include "graphics/eink/Drivers/HINK_E0213A289.h" // WeAct 2.13"
#include "graphics/eink/Drivers/HINK_E042A87.h" // WeAct 4.2"
#include "graphics/eink/Drivers/ZJY128296_029EAAMFGN.h" // WeAct 2.9"
#include "graphics/eink/Drivers/ZJY200200_0154DAAMFGN.h" // WeACt 1.54"
#if !defined(INKHUD_BUILDCONF_DRIVER) || !defined(INKHUD_BUILDCONF_DISPLAYRESILIENCE)
#error If not using a DIY preset, display model and resilience must be set manually
@@ -6,25 +6,24 @@
// InkHUD-specific components
// ---------------------------
#include "graphics/niche/InkHUD/InkHUD.h"
#include "graphics/niche/InkHUD.h"
#include "graphics/niche/Inputs/TwoButton.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/FavoritesMap/FavoritesMapApplet.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/Applets/User/AllMessage/AllMessageApplet.h"
#include "graphics/niche/Applets/User/DM/DMApplet.h"
#include "graphics/niche/Applets/User/FavoritesMap/FavoritesMapApplet.h"
#include "graphics/niche/Applets/User/Heard/HeardApplet.h"
#include "graphics/niche/Applets/User/Positions/PositionsApplet.h"
#include "graphics/niche/Applets/User/RecentsList/RecentsListApplet.h"
#include "graphics/niche/Applets/User/ThreadedMessage/ThreadedMessageApplet.h"
// Shared NicheGraphics components
// --------------------------------
#include "graphics/niche/Drivers/EInk/HINK_E0213A289.h" // WeAct 2.13"
#include "graphics/niche/Drivers/EInk/HINK_E042A87.h" // WeAct 4.2"
#include "graphics/niche/Drivers/EInk/ZJY128296_029EAAMFGN.h" // WeAct 2.9"
#include "graphics/niche/Drivers/EInk/ZJY200200_0154DAAMFGN.h" // WeACt 1.54"
#include "graphics/niche/Inputs/TwoButton.h"
#include "graphics/eink/Drivers/HINK_E0213A289.h" // WeAct 2.13"
#include "graphics/eink/Drivers/HINK_E042A87.h" // WeAct 4.2"
#include "graphics/eink/Drivers/ZJY128296_029EAAMFGN.h" // WeAct 2.9"
#include "graphics/eink/Drivers/ZJY200200_0154DAAMFGN.h" // WeACt 1.54"
#if !defined(INKHUD_BUILDCONF_DRIVER) || !defined(INKHUD_BUILDCONF_DISPLAYRESILIENCE)
// cppcheck-suppress preprocessorErrorDirective
@@ -1,92 +1,80 @@
/*
NicheGraphics setup for Heltec Mesh Pocket (LCMEN2R13ECC1 2.13" on SPI1).
Shared by both BaseUI and InkHUD envs (5000 and 10000 mAh variants).
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
// InkHUD-specific components
// ---------------------------
#include "graphics/niche/InkHUD/InkHUD.h"
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Panels/LCMEN2R13ECC1.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/FavoritesMap/FavoritesMapApplet.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/EInk/LCMEN2R13ECC1.h"
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "graphics/niche/Applets/User/AllMessage/AllMessageApplet.h"
#include "graphics/niche/Applets/User/DM/DMApplet.h"
#include "graphics/niche/Applets/User/FavoritesMap/FavoritesMapApplet.h"
#include "graphics/niche/Applets/User/Heard/HeardApplet.h"
#include "graphics/niche/Applets/User/Positions/PositionsApplet.h"
#include "graphics/niche/Applets/User/RecentsList/RecentsListApplet.h"
#include "graphics/niche/Applets/User/ThreadedMessage/ThreadedMessageApplet.h"
#include "graphics/niche/InkHUD.h"
#include "graphics/niche/Inputs/TwoButton.h"
#endif
#ifdef MESHTASTIC_INCLUDE_INKHUD
void setupNicheGraphics()
{
using namespace NicheGraphics;
// SPI
// -----------------------------
// For NRF52 platforms, SPI pins are defined in variant.h
SPI1.begin();
// E-Ink Driver
// -----------------------------
Drivers::EInk *driver = new Drivers::LCMEN2R13ECC1;
driver->begin(&SPI1, PIN_EINK_DC, PIN_EINK_CS, PIN_EINK_BUSY, PIN_EINK_RES);
// InkHUD
// ----------------------------
auto *panel = new Panels::LCMEN2R13ECC1();
Drivers::EInk *driver = panel->create();
InkHUD::InkHUD *inkhud = InkHUD::InkHUD::getInstance();
// Set the E-Ink driver
inkhud->setDriver(driver);
// Set how many FAST updates per FULL update
// Set how unhealthy additional FAST updates beyond this number are
inkhud->setDisplayResilience(10, 1.5);
// Select fonts
InkHUD::Applet::fontLarge = FREESANS_12PT_WIN1253;
InkHUD::Applet::fontMedium = FREESANS_9PT_WIN1253;
InkHUD::Applet::fontSmall = FREESANS_6PT_WIN1253;
// Customize default settings
inkhud->persistence->settings.userTiles.maxCount = 2; // How many tiles can the display handle?
inkhud->persistence->settings.rotation = 3; // 270 degrees clockwise
inkhud->persistence->settings.userTiles.count = 1; // One tile only by default, keep things simple for new users
inkhud->persistence->settings.userTiles.maxCount = 2;
inkhud->persistence->settings.rotation = 3;
inkhud->persistence->settings.userTiles.count = 1;
inkhud->persistence->settings.optionalMenuItems.nextTile = true;
// Pick applets
// Note: order of applets determines priority of "auto-show" feature
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("Favorites Map", new InkHUD::FavoritesMapApplet); // -
inkhud->addApplet("Recents List", new InkHUD::RecentsListApplet); // -
inkhud->addApplet("Heard", new InkHUD::HeardApplet, true, false, 0); // Activated, no autoshow, default on tile 0
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("Favorites Map", new InkHUD::FavoritesMapApplet);
inkhud->addApplet("Recents List", new InkHUD::RecentsListApplet);
inkhud->addApplet("Heard", new InkHUD::HeardApplet, true, false, 0);
// Start running InkHUD
inkhud->begin();
// Buttons
// --------------------------
Inputs::TwoButton *buttons = Inputs::TwoButton::getInstance(); // Shared NicheGraphics component
// #0: Main User Button
Inputs::TwoButton *buttons = Inputs::TwoButton::getInstance();
buttons->setWiring(0, Inputs::TwoButton::getUserButtonPin());
buttons->setHandlerShortPress(0, [inkhud]() { inkhud->shortpress(); });
buttons->setHandlerLongPress(0, [inkhud]() { inkhud->longpress(); });
// Begin handling button events
buttons->start();
}
#else
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new NicheGraphics::Panels::LCMEN2R13ECC1();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panel->rotation());
display->setDisplayResilience(10, 1.5f);
return display;
}
#endif
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -4,7 +4,7 @@ custom_meshtastic_support_level = 1
custom_meshtastic_images = heltec_mesh_pocket.svg
custom_meshtastic_tags = Heltec
extends = nrf52840_base
extends = nrf52840_base, niche
board = heltec_mesh_pocket
debug_tool = jlink
custom_device_hw_model = 94
@@ -17,29 +17,16 @@ custom_meshtastic_variant = 5000mAh
custom_meshtastic_key = heltec_mesh_pocket
custom_meshtastic_has_ink_hud = true
# add -DCFG_SYSVIEW if you want to use the Segger systemview tool for OS profiling.
build_flags = ${nrf52840_base.build_flags}
${niche.build_flags}
-Ivariants/nrf52840/heltec_mesh_pocket
-DHELTEC_MESH_POCKET
-DHELTEC_MESH_POCKET_BATTERY_5000
-DUSE_EINK
-DEINK_DISPLAY_MODEL=GxEPD2_213_B74
-DEINK_WIDTH=250
-DEINK_HEIGHT=122
-DUSE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
-DEINK_LIMIT_FASTREFRESH=10 ; How many consecutive fast-refreshes are permitted
-DEINK_LIMIT_RATE_BACKGROUND_SEC=30 ; Minimum interval between BACKGROUND updates
-DEINK_LIMIT_RATE_RESPONSIVE_SEC=1 ; Minimum interval between RESPONSIVE updates
; -D EINK_LIMIT_GHOSTING_PX=2000 ; (Optional) How much image ghosting is tolerated
-DEINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached.
-DEINK_HASQUIRK_GHOSTING ; Display model is identified as "prone to ghosting"
-DEINK_HASQUIRK_WEAKFASTREFRESH ; Pixels set with fast-refresh are easy to clear, disrupted by sunlight
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/heltec_mesh_pocket>
lib_deps =
build_src_filter = ${nrf52_base.build_src_filter} ${niche.build_src_filter} +<../variants/nrf52840/heltec_mesh_pocket>
lib_deps =
${nrf52840_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
https://github.com/meshtastic/GxEPD2/archive/c7eb4c3c167cf396ef4f541cc5d4c6aa42f3c46b.zip
[env:heltec-mesh-pocket-5000-inkhud]
extends = nrf52840_base, inkhud
@@ -52,9 +39,9 @@ custom_meshtastic_actively_supported = true
custom_meshtastic_variant = 5000mAh InkHUD
custom_meshtastic_key = heltec_mesh_pocket
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/heltec_mesh_pocket> ${inkhud.build_src_filter}
build_flags =
build_flags =
${inkhud.build_flags}
${nrf52840_base.build_flags}
${nrf52840_base.build_flags}
-I variants/nrf52840/heltec_mesh_pocket
-D HELTEC_MESH_POCKET
-D HELTEC_MESH_POCKET_BATTERY_5000
@@ -69,7 +56,7 @@ custom_meshtastic_support_level = 1
custom_meshtastic_images = heltec_mesh_pocket.svg
custom_meshtastic_tags = Heltec
extends = nrf52840_base
extends = nrf52840_base, niche
board = heltec_mesh_pocket
debug_tool = jlink
custom_meshtastic_hw_model = 94
@@ -81,29 +68,16 @@ custom_meshtastic_variant = 10000mAh
custom_meshtastic_key = heltec_mesh_pocket
custom_meshtastic_has_ink_hud = true
# add -DCFG_SYSVIEW if you want to use the Segger systemview tool for OS profiling.
build_flags = ${nrf52840_base.build_flags}
${niche.build_flags}
-Ivariants/nrf52840/heltec_mesh_pocket
-DHELTEC_MESH_POCKET
-DHELTEC_MESH_POCKET_BATTERY_10000
-DUSE_EINK
-DEINK_DISPLAY_MODEL=GxEPD2_213_B74
-DEINK_WIDTH=250
-DEINK_HEIGHT=122
-DUSE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
-DEINK_LIMIT_FASTREFRESH=10 ; How many consecutive fast-refreshes are permitted
-DEINK_LIMIT_RATE_BACKGROUND_SEC=30 ; Minimum interval between BACKGROUND updates
-DEINK_LIMIT_RATE_RESPONSIVE_SEC=1 ; Minimum interval between RESPONSIVE updates
; -D EINK_LIMIT_GHOSTING_PX=2000 ; (Optional) How much image ghosting is tolerated
-DEINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached.
-DEINK_HASQUIRK_GHOSTING ; Display model is identified as "prone to ghosting"
-DEINK_HASQUIRK_WEAKFASTREFRESH ; Pixels set with fast-refresh are easy to clear, disrupted by sunlight
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/heltec_mesh_pocket>
lib_deps =
build_src_filter = ${nrf52_base.build_src_filter} ${niche.build_src_filter} +<../variants/nrf52840/heltec_mesh_pocket>
lib_deps =
${nrf52840_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
https://github.com/meshtastic/GxEPD2/archive/c7eb4c3c167cf396ef4f541cc5d4c6aa42f3c46b.zip
[env:heltec-mesh-pocket-10000-inkhud]
extends = nrf52840_base, inkhud
@@ -116,9 +90,9 @@ custom_meshtastic_actively_supported = true
custom_meshtastic_variant = 10000mAh InkHUD
custom_meshtastic_key = heltec_mesh_pocket
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/heltec_mesh_pocket> ${inkhud.build_src_filter}
build_flags =
build_flags =
${inkhud.build_flags}
${nrf52840_base.build_flags}
${nrf52840_base.build_flags}
-I variants/nrf52840/heltec_mesh_pocket
-D HELTEC_MESH_POCKET
-D HELTEC_MESH_POCKET_BATTERY_10000
@@ -1,92 +1,93 @@
/*
NicheGraphics setup for Heltec MeshSolar E-Ink (E0213A367 2.13" on SPI1).
Shared by both BaseUI (heltec-mesh-solar-eink) and InkHUD (heltec-mesh-solar-inkhud).
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
// InkHUD-specific components
// ---------------------------
#include "graphics/niche/InkHUD/InkHUD.h"
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Panels/E0213A367.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/FavoritesMap/FavoritesMapApplet.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/EInk/E0213A367.h"
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "graphics/niche/Applets/User/AllMessage/AllMessageApplet.h"
#include "graphics/niche/Applets/User/DM/DMApplet.h"
#include "graphics/niche/Applets/User/FavoritesMap/FavoritesMapApplet.h"
#include "graphics/niche/Applets/User/Heard/HeardApplet.h"
#include "graphics/niche/Applets/User/Positions/PositionsApplet.h"
#include "graphics/niche/Applets/User/RecentsList/RecentsListApplet.h"
#include "graphics/niche/Applets/User/ThreadedMessage/ThreadedMessageApplet.h"
#include "graphics/niche/InkHUD.h"
#include "graphics/niche/Inputs/TwoButton.h"
#endif
class HeltecMeshSolarPanel : public NicheGraphics::Panels::E0213A367
{
protected:
void prePowerOn() override
{
#ifdef PIN_SCREEN_VDD_CTL
pinMode(PIN_SCREEN_VDD_CTL, OUTPUT);
digitalWrite(PIN_SCREEN_VDD_CTL, HIGH);
delay(10);
#endif
}
};
#ifdef MESHTASTIC_INCLUDE_INKHUD
void setupNicheGraphics()
{
using namespace NicheGraphics;
// SPI
// -----------------------------
// For NRF52 platforms, SPI pins are defined in variant.h
SPI1.begin();
// E-Ink Driver
// -----------------------------
Drivers::EInk *driver = new Drivers::E0213A367;
driver->begin(&SPI1, PIN_EINK_DC, PIN_EINK_CS, PIN_EINK_BUSY, PIN_EINK_RES);
// InkHUD
// ----------------------------
auto *panel = new HeltecMeshSolarPanel();
Drivers::EInk *driver = panel->create();
InkHUD::InkHUD *inkhud = InkHUD::InkHUD::getInstance();
// Set the E-Ink driver
inkhud->setDriver(driver);
// Set how many FAST updates per FULL update
// Set how unhealthy additional FAST updates beyond this number are
inkhud->setDisplayResilience(10, 1.5);
// Select fonts
InkHUD::Applet::fontLarge = FREESANS_12PT_WIN1252;
InkHUD::Applet::fontMedium = FREESANS_9PT_WIN1252;
InkHUD::Applet::fontSmall = FREESANS_6PT_WIN1252;
// Customize default settings
inkhud->persistence->settings.userTiles.maxCount = 2; // How many tiles can the display handle?
inkhud->persistence->settings.rotation = 3; // 270 degrees clockwise
inkhud->persistence->settings.userTiles.count = 1; // One tile only by default, keep things simple for new users
inkhud->persistence->settings.userTiles.maxCount = 2;
inkhud->persistence->settings.rotation = 3;
inkhud->persistence->settings.userTiles.count = 1;
inkhud->persistence->settings.optionalMenuItems.nextTile = true;
// Pick applets
// Note: order of applets determines priority of "auto-show" feature
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("Favorites Map", new InkHUD::FavoritesMapApplet); // -
inkhud->addApplet("Recents List", new InkHUD::RecentsListApplet); // -
inkhud->addApplet("Heard", new InkHUD::HeardApplet, true, false, 0); // Activated, no autoshow, default on tile 0
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("Favorites Map", new InkHUD::FavoritesMapApplet);
inkhud->addApplet("Recents List", new InkHUD::RecentsListApplet);
inkhud->addApplet("Heard", new InkHUD::HeardApplet, true, false, 0);
// Start running InkHUD
inkhud->begin();
// Buttons
// --------------------------
Inputs::TwoButton *buttons = Inputs::TwoButton::getInstance(); // Shared NicheGraphics component
// #0: Main User Button
Inputs::TwoButton *buttons = Inputs::TwoButton::getInstance();
buttons->setWiring(0, Inputs::TwoButton::getUserButtonPin());
buttons->setHandlerShortPress(0, [inkhud]() { inkhud->shortpress(); });
buttons->setHandlerLongPress(0, [inkhud]() { inkhud->longpress(); });
// Begin handling button events
buttons->start();
}
#else
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new HeltecMeshSolarPanel();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panel->rotation());
display->setDisplayResilience(10, 1.5f);
return display;
}
#endif
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -11,7 +11,7 @@ build_flags = ${nrf52840_base.build_flags}
-DHELTEC_MESH_SOLAR
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/heltec_mesh_solar>
lib_deps =
lib_deps =
${nrf52840_base.lib_deps}
# renovate: datasource=git-refs depName=NMIoT-meshsolar packageName=https://github.com/NMIoT/meshsolar gitBranch=main
https://github.com/NMIoT/meshsolar/archive/dfc5330dad443982e6cdd37a61d33fc7252f468b.zip
@@ -33,8 +33,10 @@ build_flags = ${heltec_mesh_solar_base.build_flags}
-DSPI_INTERFACES_COUNT=1
[env:heltec-mesh-solar-eink]
extends = heltec_mesh_solar_base
extends = heltec_mesh_solar_base, niche
build_src_filter = ${heltec_mesh_solar_base.build_src_filter} ${niche.build_src_filter}
build_flags = ${heltec_mesh_solar_base.build_flags}
${niche.build_flags}
-DHELTEC_MESH_SOLAR_EINK
-DSPI_INTERFACES_COUNT=2
-DUSE_EINK
@@ -48,15 +50,6 @@ build_flags = ${heltec_mesh_solar_base.build_flags}
-DPIN_SPI1_MISO=-1
-DPIN_SPI1_MOSI=PIN_EINK_MOSI
-DPIN_SPI1_SCK=PIN_EINK_SCLK
-DEINK_DISPLAY_MODEL=GxEPD2_213_E0213A367
-DEINK_WIDTH=250
-DEINK_HEIGHT=122
-DUSE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
-DEINK_LIMIT_FASTREFRESH=10 ; How many consecutive fast-refreshes are permitted
-DEINK_LIMIT_RATE_BACKGROUND_SEC=30 ; Minimum interval between BACKGROUND updates
-DEINK_LIMIT_RATE_RESPONSIVE_SEC=1 ; Minimum interval between RESPONSIVE updates
-DEINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached.
-DEINK_HASQUIRK_GHOSTING ; Display model is identified as "prone to ghosting"
-DENABLE_MESSAGE_PERSISTENCE=0 ; Disable flash persistence for space-limited build
-DMESHTASTIC_EXCLUDE_WIFI=1
-DMESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION=1
@@ -67,8 +60,6 @@ build_flags = ${heltec_mesh_solar_base.build_flags}
-DMESHTASTIC_EXCLUDE_WAYPOINT=1
lib_deps =
${heltec_mesh_solar_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
https://github.com/meshtastic/GxEPD2/archive/c7eb4c3c167cf396ef4f541cc5d4c6aa42f3c46b.zip
[env:heltec-mesh-solar-inkhud]
extends = heltec_mesh_solar_base, inkhud
@@ -0,0 +1,28 @@
/*
NicheGraphics setup for MeshLink (LoraItalia) ePaper build (GDEY0213B74 2.13" on SPI1).
Only used by env:meshlink_eink (the env:meshlink build has no display).
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Panels/GDEY0213B74.h"
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new NicheGraphics::Panels::GDEY0213B74();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panel->rotation());
display->setDisplayResilience(5, 1.5f);
return display;
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+4 -16
View File
@@ -21,11 +21,12 @@ debug_tool = jlink
;upload_protocol = jlink
[env:meshlink_eink]
extends = nrf52840_base
extends = nrf52840_base, niche
board = meshlink
board_level = extra
;board_check = true
build_flags = ${nrf52840_base.build_flags}
${niche.build_flags}
-I variants/nrf52840/meshlink
-D MESHLINK
-DRADIOLIB_EXCLUDE_SX128X=1
@@ -33,23 +34,10 @@ build_flags = ${nrf52840_base.build_flags}
-DRADIOLIB_EXCLUDE_LR11X0=1
-DRADIOLIB_EXCLUDE_LR2021=1
-D USE_EINK
-D EINK_DISPLAY_MODEL=GxEPD2_213_B74
-D EINK_WIDTH=250
-D EINK_HEIGHT=122
-D USE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
-D EINK_LIMIT_FASTREFRESH=5 ; How many consecutive fast-refreshes are permitted
-D EINK_LIMIT_RATE_BACKGROUND_SEC=30 ; Minimum interval between BACKGROUND updates
-D EINK_LIMIT_RATE_RESPONSIVE_SEC=1 ; Minimum interval between RESPONSIVE updates
-D EINK_LIMIT_GHOSTING_PX=2000 ; (Optional) How much image ghosting is tolerated
-D EINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached.
-D EINK_HASQUIRK_VICIOUSFASTREFRESH ; Identify that pixels drawn by fast-refresh are harder to clear
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/meshlink>
lib_deps =
build_src_filter = ${nrf52_base.build_src_filter} ${niche.build_src_filter} +<../variants/nrf52840/meshlink>
lib_deps =
${nrf52840_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
https://github.com/meshtastic/GxEPD2/archive/c7eb4c3c167cf396ef4f541cc5d4c6aa42f3c46b.zip
debug_tool = jlink
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
; Note: as of 6/2013 the serial/bootloader based programming takes approximately 30 seconds
@@ -0,0 +1,43 @@
/*
NicheGraphics setup for RAK4631 + RAK14000 ePaper module (2.13" BN, DEPG0213BNS800 on SPI1).
BaseUI build only - no InkHUD env.
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Panels/DEPG0213BNS800.h"
class RAK4631EpaperPanel : public NicheGraphics::Panels::DEPG0213BNS800
{
protected:
SPIClass *beginSpi() override
{
// RAK14000 is wired to SPI1 via pins declared in variant.h.
// Init settings cloned from the legacy GxEPD2 path on this board.
SPI1.begin();
return &SPI1;
}
};
void setupNicheGraphics()
{
// BaseUI handles buttons through its default ButtonThread. Nothing extra here.
}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new RAK4631EpaperPanel();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panel->rotation());
display->setDisplayResilience(7, 1.5f);
return display;
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -1,22 +1,18 @@
; The very slick RAK wireless RAK 4631 / 4630 board - Firmware for 5005 with the RAK 14000 ePaper
[env:rak4631_eink]
extends = nrf52840_base
extends = nrf52840_base, niche
board = wiscore_rak4631
build_flags = ${nrf52840_base.build_flags}
${niche.build_flags}
-I variants/nrf52840/rak4631_epaper
-D RAK_4631
-DEINK_DISPLAY_MODEL=GxEPD2_213_BN
-DEINK_WIDTH=250
-DEINK_HEIGHT=122
-DRADIOLIB_EXCLUDE_SX128X=1
-DRADIOLIB_EXCLUDE_SX127X=1
-DRADIOLIB_EXCLUDE_LR11X0=1
-DRADIOLIB_EXCLUDE_LR2021=1
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/rak4631_epaper>
lib_deps =
build_src_filter = ${nrf52_base.build_src_filter} ${niche.build_src_filter} +<../variants/nrf52840/rak4631_epaper>
lib_deps =
${nrf52840_base.lib_deps}
# renovate: datasource=custom.pio depName=GxEPD2 packageName=zinggjm/library/GxEPD2
zinggjm/GxEPD2@1.6.8
# renovate: datasource=custom.pio depName=Melopero RV3028 packageName=melopero/library/Melopero RV3028
melopero/Melopero RV3028@1.2.0
# renovate: datasource=custom.pio depName=RAK NCP5623 RGB LED packageName=rakwireless/library/RAKwireless NCP5623 RGB LED library
@@ -1,24 +1,20 @@
; The very slick RAK wireless RAK 4631 / 4630 board - Firmware for 5005 with the RAK 14000 ePaper
[env:rak4631_eink_onrxtx]
board_level = extra
extends = nrf52840_base
extends = nrf52840_base, niche
board = wiscore_rak4631
build_flags = ${nrf52840_base.build_flags}
${niche.build_flags}
-I variants/nrf52840/rak4631_epaper
-D RAK_4631
-D PIN_EINK_EN=34
-D EINK_DISPLAY_MODEL=GxEPD2_213_BN
-D EINK_WIDTH=250
-D EINK_HEIGHT=122
-D RADIOLIB_EXCLUDE_SX128X=1
-D RADIOLIB_EXCLUDE_SX127X=1
-D RADIOLIB_EXCLUDE_LR11X0=1
-D RADIOLIB_EXCLUDE_LR2021=1
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/rak4631_epaper_onrxtx>
lib_deps =
build_src_filter = ${nrf52_base.build_src_filter} ${niche.build_src_filter} +<../variants/nrf52840/rak4631_epaper_onrxtx>
lib_deps =
${nrf52840_base.lib_deps}
# renovate: datasource=custom.pio depName=GxEPD2 packageName=zinggjm/library/GxEPD2
zinggjm/GxEPD2@1.6.8
# renovate: datasource=custom.pio depName=Melopero RV3028 packageName=melopero/library/Melopero RV3028
melopero/Melopero RV3028@1.2.0
# renovate: datasource=custom.pio depName=RAK NCP5623 RGB LED packageName=rakwireless/library/RAKwireless NCP5623 RGB LED library
@@ -7,9 +7,6 @@ build_flags = ${nrf52840_base.build_flags}
-I variants/nrf52840/rak4631_eth_gw
-D RAK_4631
-DHAS_UDP_MULTICAST=1
-DEINK_DISPLAY_MODEL=GxEPD2_213_BN
-DEINK_WIDTH=250
-DEINK_HEIGHT=122
-DNRF52_USE_JSON=1
-DMESHTASTIC_EXCLUDE_WIFI=1
-DMESHTASTIC_EXCLUDE_SCREEN=1
@@ -15,9 +15,6 @@ board_check = true
build_flags = ${nrf52840_base.build_flags}
-I variants/nrf52840/rak4631_nomadstar_meteor_pro
-D NOMADSTAR_METEOR_PRO
-DEINK_DISPLAY_MODEL=GxEPD2_213_BN
-DEINK_WIDTH=250
-DEINK_HEIGHT=122
-DRADIOLIB_EXCLUDE_SX128X=1
-DRADIOLIB_EXCLUDE_SX127X=1
-DRADIOLIB_EXCLUDE_LR11X0=1
@@ -15,9 +15,6 @@ build_flags = ${nrf52840_base.build_flags}
-Ivariants/nrf52840/rak_wismeshtap
-DWISMESH_TAP
-DRAK_4631
-DEINK_DISPLAY_MODEL=GxEPD2_213_BN
-DEINK_WIDTH=250
-DEINK_HEIGHT=122
-DMESHTASTIC_EXCLUDE_WIFI=1
-DMESHTASTIC_EXCLUDE_DETECTIONSENSOR=1
-DMESHTASTIC_EXCLUDE_STOREFORWARD=1
@@ -1,119 +1,105 @@
/*
NicheGraphics setup for Seeed Wio Tracker L1 E-Ink (ZJY122250_0213BAAMFGN 2.13" on SPI1).
Shared by both BaseUI and InkHUD envs.
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
// InkHUD-specific components
// ---------------------------
#include "graphics/niche/InkHUD/InkHUD.h"
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Panels/ZJY122250_0213BAAMFGN.h"
// Applets
#include "graphics/niche/InkHUD/Applets/Examples/UserAppletInputExample/UserAppletInputExample.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/FavoritesMap/FavoritesMapApplet.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/EInk/ZJY122250_0213BAAMFGN.h"
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "graphics/niche/Applets/Examples/UserAppletInputExample/UserAppletInputExample.h"
#include "graphics/niche/Applets/User/AllMessage/AllMessageApplet.h"
#include "graphics/niche/Applets/User/DM/DMApplet.h"
#include "graphics/niche/Applets/User/FavoritesMap/FavoritesMapApplet.h"
#include "graphics/niche/Applets/User/Heard/HeardApplet.h"
#include "graphics/niche/Applets/User/Positions/PositionsApplet.h"
#include "graphics/niche/Applets/User/RecentsList/RecentsListApplet.h"
#include "graphics/niche/Applets/User/ThreadedMessage/ThreadedMessageApplet.h"
#include "graphics/niche/InkHUD.h"
#include "graphics/niche/Inputs/TwoButtonExtended.h"
#endif
#ifdef MESHTASTIC_INCLUDE_INKHUD
void setupNicheGraphics()
{
using namespace NicheGraphics;
// SPI
// -----------------------------
// For NRF52 platforms, SPI pins are defined in variant.h
SPI1.begin();
// E-Ink Driver
// -----------------------------
Drivers::EInk *driver = new Drivers::ZJY122250_0213BAAMFGN;
driver->begin(&SPI1, PIN_EINK_DC, PIN_EINK_CS, PIN_EINK_BUSY, PIN_EINK_RES);
// InkHUD
// ----------------------------
auto *panel = new Panels::ZJY122250_0213BAAMFGN();
Drivers::EInk *driver = panel->create();
InkHUD::InkHUD *inkhud = InkHUD::InkHUD::getInstance();
// Set the E-Ink driver
inkhud->setDriver(driver);
// Set how many FAST updates per FULL update
inkhud->setDisplayResilience(15);
// Select fonts
InkHUD::Applet::fontLarge = FREESANS_12PT_WIN1252;
InkHUD::Applet::fontMedium = FREESANS_9PT_WIN1252;
InkHUD::Applet::fontSmall = FREESANS_6PT_WIN1252;
// Customize default settings
inkhud->persistence->settings.rotation = 1; // 90 degrees clockwise
inkhud->persistence->settings.rotation = 1;
#if HAS_TRACKBALL
inkhud->persistence->settings.joystick.enabled = true; // Device uses a joystick
inkhud->persistence->settings.joystick.alignment = 3; // 270 degrees
inkhud->persistence->settings.optionalMenuItems.nextTile = false; // Use joystick instead
inkhud->persistence->settings.joystick.enabled = true;
inkhud->persistence->settings.joystick.alignment = 3;
inkhud->persistence->settings.optionalMenuItems.nextTile = false;
#endif
inkhud->persistence->settings.optionalFeatures.batteryIcon = true; // Device definitely has a battery
inkhud->persistence->settings.userTiles.count = 1; // One tile only by default, keep things simple for new users
inkhud->persistence->settings.userTiles.maxCount = 2; // Two applets side-by-side
inkhud->persistence->settings.optionalFeatures.batteryIcon = true;
inkhud->persistence->settings.userTiles.count = 1;
inkhud->persistence->settings.userTiles.maxCount = 2;
// Pick applets
// Note: order of applets determines priority of "auto-show" feature
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, no autoshow, default on tile 0
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->addApplet("Favorites Map", new InkHUD::FavoritesMapApplet, false, false);
inkhud->addApplet("Favorites Map", new InkHUD::FavoritesMapApplet, false, false); // -
// Start running InkHUD
inkhud->begin();
// Buttons
// --------------------------
Inputs::TwoButtonExtended *buttons = Inputs::TwoButtonExtended::getInstance(); // Shared NicheGraphics component
Inputs::TwoButtonExtended *buttons = Inputs::TwoButtonExtended::getInstance();
#if HAS_TRACKBALL
// #0: Exit Button
buttons->setWiring(0, Inputs::TwoButtonExtended::getUserButtonPin());
buttons->setTiming(0, 75, 500);
buttons->setHandlerShortPress(0, [inkhud]() { inkhud->exitShort(); });
buttons->setHandlerLongPress(0, [inkhud]() { inkhud->exitLong(); });
// #1: Joystick Center
buttons->setWiring(1, TB_PRESS);
buttons->setTiming(1, 75, 500);
buttons->setHandlerShortPress(1, [inkhud]() { inkhud->shortpress(); });
buttons->setHandlerLongPress(1, [inkhud]() { inkhud->longpress(); });
// Joystick Directions
buttons->setJoystickWiring(TB_UP, TB_DOWN, TB_LEFT, TB_RIGHT);
buttons->setJoystickDebounce(50);
buttons->setJoystickPressHandlers([inkhud]() { inkhud->navUp(); }, [inkhud]() { inkhud->navDown(); },
[inkhud]() { inkhud->navLeft(); }, [inkhud]() { inkhud->navRight(); });
#else
// #0: User Button
buttons->setWiring(0, Inputs::TwoButtonExtended::getUserButtonPin());
buttons->setTiming(0, 75, 500);
buttons->setHandlerShortPress(0, [inkhud]() { inkhud->shortpress(); });
buttons->setHandlerLongPress(0, [inkhud]() { inkhud->longpress(); });
#endif
// Begin handling button events
buttons->start();
}
#else
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new NicheGraphics::Panels::ZJY122250_0213BAAMFGN();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panel->rotation());
display->setDisplayResilience(10, 1.5f);
return display;
}
#endif
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -10,45 +10,33 @@ custom_meshtastic_tags = Seeed
custom_meshtastic_has_ink_hud = true
board = seeed_wio_tracker_L1
extends = nrf52840_base
extends = nrf52840_base, niche
;board_level = extra
build_flags = ${nrf52840_base.build_flags}
${niche.build_flags}
-I variants/nrf52840/seeed_wio_tracker_L1_eink
-D SEEED_WIO_TRACKER_L1_EINK
-D SEEED_WIO_TRACKER_L1
-I src/platform/nrf52/softdevice
-I src/platform/nrf52/softdevice/nrf52
-DUSE_EINK
-DEINK_DISPLAY_MODEL=GxEPD2_213_B74
-DEINK_WIDTH=250
-DEINK_HEIGHT=122
-DUSE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
-DEINK_LIMIT_FASTREFRESH=10 ; How many consecutive fast-refreshes are permitted
-DEINK_LIMIT_RATE_BACKGROUND_SEC=30 ; Minimum interval between BACKGROUND updates
-DEINK_LIMIT_RATE_RESPONSIVE_SEC=1 ; Minimum interval between RESPONSIVE updates
; -D EINK_LIMIT_GHOSTING_PX=2000 ; (Optional) How much image ghosting is tolerated
-DEINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached.
-DEINK_HASQUIRK_GHOSTING ; Display model is identified as "prone to ghosting"
-DEINK_HASQUIRK_WEAKFASTREFRESH ; Pixels set with fast-refresh are easy to clear, disrupted by sunlight
board_build.ldscript = src/platform/nrf52/nrf52840_s140_v7.ld
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/seeed_wio_tracker_L1_eink>
build_src_filter = ${nrf52_base.build_src_filter} ${niche.build_src_filter} +<../variants/nrf52840/seeed_wio_tracker_L1_eink>
lib_deps =
${nrf52840_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
https://github.com/meshtastic/GxEPD2/archive/c7eb4c3c167cf396ef4f541cc5d4c6aa42f3c46b.zip
debug_tool = jlink
[env:seeed_wio_tracker_L1_eink-inkhud]
board = seeed_wio_tracker_L1
extends = nrf52840_base, inkhud
build_flags =
build_flags =
${nrf52840_base.build_flags}
${inkhud.build_flags}
-I variants/nrf52840/seeed_wio_tracker_L1_eink
-D SEEED_WIO_TRACKER_L1
-D BUTTON_PIN=D13
board_build.ldscript = src/platform/nrf52/nrf52840_s140_v7.ld
build_src_filter =
build_src_filter =
${nrf52_base.build_src_filter}
${inkhud.build_src_filter}
+<../variants/nrf52840/seeed_wio_tracker_L1_eink>
@@ -0,0 +1,27 @@
/*
NicheGraphics setup for LILYGO T-Echo Lite (GDEH0122T61 1.22" on SPI1).
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Panels/GDEH0122T61.h"
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new NicheGraphics::Panels::GDEH0122T61();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panel->rotation());
display->setDisplayResilience(20, 1.5f);
return display;
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+4 -12
View File
@@ -9,26 +9,18 @@ custom_meshtastic_display_name = LILYGO T-Echo Lite
custom_meshtastic_images = techo_lite.svg
custom_meshtastic_tags = LilyGo
extends = nrf52840_base
extends = nrf52840_base, niche
board = t-echo
board_check = true
debug_tool = jlink
# add -DCFG_SYSVIEW if you want to use the Segger systemview tool for OS profiling.
build_flags = ${nrf52840_base.build_flags}
${niche.build_flags}
-Ivariants/nrf52840/t-echo-lite
-D T_ECHO_LITE
-D EINK_DISPLAY_MODEL=GxEPD2_122_T61
-D EINK_WIDTH=192
-D EINK_HEIGHT=176
-D USE_EINK
-D USE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
-D EINK_LIMIT_FASTREFRESH=20 ; How many consecutive fast-refreshes are permitted
-D EINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached.
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/t-echo-lite>
lib_deps =
build_src_filter = ${nrf52_base.build_src_filter} ${niche.build_src_filter} +<../variants/nrf52840/t-echo-lite>
lib_deps =
${nrf52840_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
https://github.com/meshtastic/GxEPD2/archive/c7eb4c3c167cf396ef4f541cc5d4c6aa42f3c46b.zip
;upload_protocol = fs
+39 -16
View File
@@ -1,29 +1,39 @@
/*
NicheGraphics setup for LILYGO T-Echo Plus (GDEY0154D67 1.54" on SPI1).
Shared by both BaseUI and InkHUD envs.
*/
#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/FavoritesMap/FavoritesMapApplet.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"
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Backlight/LatchingBacklight.h"
#include "graphics/eink/Panels/GDEY0154D67.h"
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "graphics/niche/Applets/User/AllMessage/AllMessageApplet.h"
#include "graphics/niche/Applets/User/DM/DMApplet.h"
#include "graphics/niche/Applets/User/FavoritesMap/FavoritesMapApplet.h"
#include "graphics/niche/Applets/User/Heard/HeardApplet.h"
#include "graphics/niche/Applets/User/Positions/PositionsApplet.h"
#include "graphics/niche/Applets/User/RecentsList/RecentsListApplet.h"
#include "graphics/niche/Applets/User/ThreadedMessage/ThreadedMessageApplet.h"
#include "graphics/niche/InkHUD.h"
#include "graphics/niche/Inputs/TwoButton.h"
#endif
#ifdef MESHTASTIC_INCLUDE_INKHUD
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);
auto *panel = new Panels::GDEY0154D67();
Drivers::EInk *driver = panel->create();
InkHUD::InkHUD *inkhud = InkHUD::InkHUD::getInstance();
inkhud->setDriver(driver);
@@ -51,12 +61,12 @@ void setupNicheGraphics()
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(); });
#ifdef PIN_BUTTON_TOUCH
buttons->setWiring(1, PIN_BUTTON_TOUCH);
buttons->setTiming(1, 50, 5000);
buttons->setHandlerDown(1, [inkhud, backlight]() {
@@ -65,8 +75,21 @@ void setupNicheGraphics()
});
buttons->setHandlerLongPress(1, [backlight]() { backlight->latch(); });
buttons->setHandlerShortPress(1, [backlight]() { backlight->off(); });
#endif
buttons->start();
}
#else
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new NicheGraphics::Panels::GDEY0154D67();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panel->rotation());
display->setDisplayResilience(20, 1.5f);
return display;
}
#endif
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+3 -9
View File
@@ -10,29 +10,23 @@ custom_meshtastic_tags = LilyGo
custom_meshtastic_requires_dfu = true
custom_meshtastic_has_ink_hud = true
extends = nrf52840_base
extends = nrf52840_base, niche
board = t-echo
board_level = pr
board_check = true
debug_tool = jlink
build_flags = ${nrf52840_base.build_flags}
${niche.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>
build_src_filter = ${nrf52_base.build_src_filter} ${niche.build_src_filter} +<../variants/nrf52840/t-echo-plus>
lib_deps =
${nrf52840_base.lib_deps}
https://github.com/meshtastic/GxEPD2/archive/55f618961db45a23eff0233546430f1e5a80f63a.zip
# renovate: datasource=custom.pio depName=PCF8563 packageName=lewisxhe/library/PCF8563_Library
lewisxhe/PCF8563_Library@1.0.1
# renovate: datasource=custom.pio depName=Adafruit DRV2605 packageName=adafruit/library/Adafruit DRV2605 Library
+49 -78
View File
@@ -1,128 +1,99 @@
/*
NicheGraphics setup for LILYGO T-Echo (GDEY0154D67 1.54" on SPI1).
Shared by both BaseUI (env:t-echo) and InkHUD (env:t-echo-inkhud).
*/
#pragma once
#include "configuration.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
// InkHUD-specific components
// ---------------------------
#include "graphics/niche/InkHUD/InkHUD.h"
#include "graphics/BaseUIEInkDisplay.h"
#include "graphics/eink/Backlight/LatchingBacklight.h"
#include "graphics/eink/Panels/GDEY0154D67.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/FavoritesMap/FavoritesMapApplet.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/GDEY0154D67.h"
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "graphics/niche/Applets/User/AllMessage/AllMessageApplet.h"
#include "graphics/niche/Applets/User/DM/DMApplet.h"
#include "graphics/niche/Applets/User/FavoritesMap/FavoritesMapApplet.h"
#include "graphics/niche/Applets/User/Heard/HeardApplet.h"
#include "graphics/niche/Applets/User/Positions/PositionsApplet.h"
#include "graphics/niche/Applets/User/RecentsList/RecentsListApplet.h"
#include "graphics/niche/Applets/User/ThreadedMessage/ThreadedMessageApplet.h"
#include "graphics/niche/InkHUD.h"
#include "graphics/niche/Inputs/TwoButton.h"
// Special case - fix T-Echo's touch button
// ----------------------------------------
// On a handful of T-Echos, LoRa TX triggers the capacitive touch
// To avoid this, we lockout the button during TX
#include "mesh/RadioLibInterface.h"
#endif
#ifdef MESHTASTIC_INCLUDE_INKHUD
void setupNicheGraphics()
{
using namespace NicheGraphics;
// SPI
// -----------------------------
// For NRF52 platforms, SPI pins are defined in variant.h
SPI1.begin();
// E-Ink Driver
// -----------------------------
Drivers::EInk *driver = new Drivers::GDEY0154D67;
driver->begin(&SPI1, PIN_EINK_DC, PIN_EINK_CS, PIN_EINK_BUSY, PIN_EINK_RES);
// InkHUD
// ----------------------------
auto *panel = new Panels::GDEY0154D67();
Drivers::EInk *driver = panel->create();
InkHUD::InkHUD *inkhud = InkHUD::InkHUD::getInstance();
// Set the E-Ink driver
inkhud->setDriver(driver);
// Set how many FAST updates per FULL update
// Set how unhealthy additional FAST updates beyond this number are
inkhud->setDisplayResilience(20, 1.5);
// Select fonts
InkHUD::Applet::fontLarge = FREESANS_12PT_WIN1252;
InkHUD::Applet::fontMedium = FREESANS_9PT_WIN1252;
InkHUD::Applet::fontSmall = FREESANS_6PT_WIN1252;
// Customize default settings
inkhud->persistence->settings.userTiles.maxCount = 2; // Two applets side-by-side
inkhud->persistence->settings.rotation = 3; // 270 degrees clockwise
inkhud->persistence->settings.optionalFeatures.batteryIcon = true; // Device definitely has a battery
inkhud->persistence->settings.optionalMenuItems.backlight = true; // Until proves capacitive button works by touching it
inkhud->persistence->settings.userTiles.maxCount = 2;
inkhud->persistence->settings.rotation = 3;
inkhud->persistence->settings.optionalFeatures.batteryIcon = true;
inkhud->persistence->settings.optionalMenuItems.backlight = true;
// Setup backlight controller
// Note: AUX button attached 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
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("Favorites Map", new InkHUD::FavoritesMapApplet); // -
inkhud->addApplet("Recents List", new InkHUD::RecentsListApplet); // -
inkhud->addApplet("Heard", new InkHUD::HeardApplet, true, false, 0); // Activated, no autoshow, default on tile 0
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("Favorites Map", new InkHUD::FavoritesMapApplet);
inkhud->addApplet("Recents List", new InkHUD::RecentsListApplet);
inkhud->addApplet("Heard", new InkHUD::HeardApplet, true, false, 0);
// Start running InkHUD
inkhud->begin();
// Buttons
// --------------------------
Inputs::TwoButton *buttons = Inputs::TwoButton::getInstance(); // Shared NicheGraphics component
// #0: Main User Button
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(); });
// #1: Aux Button (Capacitive Touch Button)
// - short: momentary backlight
// - long: latch backlight on
buttons->setWiring(1, PIN_BUTTON_TOUCH);
buttons->setTiming(1, 50, 5000); // 5 seconds before latch - limited by T-Echo's capacitive touch IC
buttons->setTiming(1, 50, 5000);
buttons->setHandlerDown(1, [inkhud, backlight]() {
// Discard the button press if radio is active
// Rare hardware fault: LoRa activity triggers touch button
if (!RadioLibInterface::instance || RadioLibInterface::instance->isSending())
return;
// Backlight on (while held)
backlight->peek();
// Handler has run, which confirms touch button wasn't removed as part of DIY build.
// No longer need the fallback backlight toggle in menu.
inkhud->persistence->settings.optionalMenuItems.backlight = false;
});
buttons->setHandlerLongPress(1, [backlight]() { backlight->latch(); });
buttons->setHandlerShortPress(1, [backlight]() { backlight->off(); });
// Begin handling button events
buttons->start();
}
#else
void setupNicheGraphics() {}
NicheGraphics::BaseUIEInkDisplay *setupNicheGraphicsBaseUI()
{
auto *panel = new NicheGraphics::Panels::GDEY0154D67();
NicheGraphics::Drivers::EInk *driver = panel->create();
auto *display = new NicheGraphics::BaseUIEInkDisplay(driver, panel->rotation());
display->setDisplayResilience(20, 1.5f);
return display;
}
#endif
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+8 -17
View File
@@ -1,4 +1,3 @@
; Using original screen class
[env:t-echo]
custom_meshtastic_hw_model = 7
custom_meshtastic_hw_model_slug = T_ECHO
@@ -10,28 +9,20 @@ custom_meshtastic_images = t-echo.svg
custom_meshtastic_tags = LilyGo
custom_meshtastic_has_ink_hud = true
extends = nrf52840_base
extends = nrf52840_base, niche
board = t-echo
board_level = pr
board_check = true
debug_tool = jlink
# add -DCFG_SYSVIEW if you want to use the Segger systemview tool for OS profiling.
build_flags = ${nrf52840_base.build_flags}
${niche.build_flags}
-Ivariants/nrf52840/t-echo
-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.
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/t-echo>
lib_deps =
build_src_filter = ${nrf52_base.build_src_filter} ${niche.build_src_filter} +<../variants/nrf52840/t-echo>
lib_deps =
${nrf52840_base.lib_deps}
# renovate: datasource=git-refs depName=meshtastic-GxEPD2 packageName=https://github.com/meshtastic/GxEPD2 gitBranch=master
https://github.com/meshtastic/GxEPD2/archive/c7eb4c3c167cf396ef4f541cc5d4c6aa42f3c46b.zip
# renovate: datasource=custom.pio depName=SensorLib packageName=lewisxhe/library/SensorLib
lewisxhe/SensorLib@0.3.4
;upload_protocol = fs
@@ -42,15 +33,15 @@ board = t-echo
board_level = pr
board_check = true
debug_tool = jlink
build_flags =
build_flags =
${nrf52840_base.build_flags}
${inkhud.build_flags}
-I variants/nrf52840/t-echo
build_src_filter =
${nrf52_base.build_src_filter}
build_src_filter =
${nrf52_base.build_src_filter}
${inkhud.build_src_filter}
+<../variants/nrf52840/t-echo>
lib_deps =
lib_deps =
${inkhud.lib_deps} ; InkHUD libs first, so we get GFXRoot instead of AdafruitGFX
${nrf52840_base.lib_deps}
# renovate: datasource=custom.pio depName=SensorLib packageName=lewisxhe/library/SensorLib