diff --git a/boards/t5-epaper-s3.json b/boards/t5-epaper-s3.json new file mode 100644 index 000000000..8d47b1866 --- /dev/null +++ b/boards/t5-epaper-s3.json @@ -0,0 +1,38 @@ +{ + "build": { + "arduino": { + "ldscript": "esp32s3_out.ld", + "memory_type": "qio_opi", + "partitions": "default_16MB.csv" + }, + "core": "esp32", + "extra_flags": [ + "-DBOARD_HAS_PSRAM", + "-DARDUINO_RUNNING_CORE=0", + "-DARDUINO_EVENT_RUNNING_CORE=0", + "-DARDUINO_USB_CDC_ON_BOOT=1", + "-DARDUINO_USB_MODE=1" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [["0x303A", "0x1001"]], + "mcu": "esp32s3", + "variant": "esp32s3" + }, + "connectivity": ["wifi", "bluetooth", "lora"], + "debug": { + "openocd_target": "esp32s3.cfg" + }, + "frameworks": ["arduino", "espidf"], + "name": "LilyGo T5-ePaper-S3", + "upload": { + "flash_size": "16MB", + "maximum_ram_size": 327680, + "maximum_size": 16777216, + "require_upload_port": true, + "speed": 921600 + }, + "url": "https://lilygo.cc/products/t5-e-paper-s3-pro", + "vendor": "LILYGO" +} diff --git a/src/graphics/niche/InkHUD/Applet.h b/src/graphics/niche/InkHUD/Applet.h index 8f4466647..159a4bfa3 100644 --- a/src/graphics/niche/InkHUD/Applet.h +++ b/src/graphics/niche/InkHUD/Applet.h @@ -15,6 +15,7 @@ #include // GFXRoot drawing lib +#include "mesh/MeshModule.h" #include "mesh/MeshTypes.h" #include "./AppletFont.h" diff --git a/variants/t5s3_epaper/nicheGraphics.h b/variants/t5s3_epaper/nicheGraphics.h new file mode 100644 index 000000000..baadc3d28 --- /dev/null +++ b/variants/t5s3_epaper/nicheGraphics.h @@ -0,0 +1,135 @@ +/* + +Most of the Meshtastic firmware uses preprocessor macros throughout the code to support different hardware variants. +NicheGraphics attempts a different approach: + +Per-device config takes place in this setupNicheGraphics() method +(And a small amount in platformio.ini) + +This file sets up InkHUD for Heltec VM-E290. +Different NicheGraphics UIs and different hardware variants will each have their own setup procedure. + +*/ + +#pragma once + +#include "configuration.h" +#include "mesh/MeshModule.h" + +#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS + +// InkHUD-specific components +// --------------------------- +// #include "graphics/niche/InkHUD/InkHUD.h" +#include "graphics/niche/InkHUD/WindowManager.h" + +// Applets +#include "graphics/niche/InkHUD/Applets/User/AllMessage/AllMessageApplet.h" +#include "graphics/niche/InkHUD/Applets/User/DM/DMApplet.h" +#include "graphics/niche/InkHUD/Applets/User/Heard/HeardApplet.h" +#include "graphics/niche/InkHUD/Applets/User/Positions/PositionsApplet.h" +#include "graphics/niche/InkHUD/Applets/User/RecentsList/RecentsListApplet.h" +#include "graphics/niche/InkHUD/Applets/User/ThreadedMessage/ThreadedMessageApplet.h" + +// #include "graphics/niche/InkHUD/Applets/Examples/BasicExample/BasicExampleApplet.h" +// #include "graphics/niche/InkHUD/Applets/Examples/NewMsgExample/NewMsgExampleApplet.h" + +// Shared NicheGraphics components +// -------------------------------- +#include "graphics/niche/Drivers/Backlight/LatchingBacklight.h" +#include "graphics/niche/Drivers/EInk/DEPG0290BNS800.h" +#include "graphics/niche/Inputs/TwoButton.h" + +#include "graphics/niche/Fonts/FreeSans6pt7b.h" +#include "graphics/niche/Fonts/FreeSans6pt8bCyrillic.h" +#include + +void setupNicheGraphics() +{ + using namespace NicheGraphics; + + // SPI + // ----------------------------- + + // Display is connected to HSPI + SPIClass *hspi = new SPIClass(HSPI); + hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS); + + // E-Ink Driver + // ----------------------------- + + // Use E-Ink driver + Drivers::EInk *driver = new Drivers::DEPG0290BNS800; + driver->begin(hspi, PIN_EINK_DC, PIN_EINK_CS, PIN_EINK_BUSY); + + // InkHUD + // ---------------------------- + + InkHUD::InkHUD *inkhud = InkHUD::InkHUD::getInstance(); + + // Set the driver + inkhud->setDriver(driver); + + // Set how many FAST updates per FULL update + // Set how unhealthy additional FAST updates beyond this number are + inkhud->setDisplayResilience(7, 1.5); + + // Prepare fonts + InkHUD::Applet::fontLarge = InkHUD::AppletFont(FreeSans9pt7b); + InkHUD::Applet::fontSmall = InkHUD::AppletFont(FreeSans6pt7b); + /* + // Font localization demo: Cyrillic + InkHUD::Applet::fontSmall = InkHUD::AppletFont(FreeSans6pt8bCyrillic); + InkHUD::Applet::fontSmall.addSubstitutionsWin1251(); + */ + + // Init settings, and customize defaults + inkhud->persistence->settings.userTiles.maxCount = 2; // How many tiles can the display handle? + inkhud->persistence->settings.rotation = 1; // 90 degrees clockwise + inkhud->persistence->settings.userTiles.count = 1; // One tile only by default, keep things simple for new users + inkhud->persistence->settings.optionalMenuItems.nextTile = false; // Behavior handled by aux button instead + inkhud->persistence->settings.optionalFeatures.batteryIcon = true; // Device definitely has a battery + + // Setup backlight + // Note: AUX button behavior configured further down + Drivers::LatchingBacklight *backlight = Drivers::LatchingBacklight::getInstance(); + backlight->setPin(PIN_EINK_EN); + + // Pick applets + // Note: order of applets determines priority of "auto-show" feature + // Optional arguments for defaults: + // - is activated? + // - is autoshown? + // - is foreground on a specific tile (index)? + inkhud->addApplet("All Messages", new InkHUD::AllMessageApplet, true, true); // Activated, autoshown + inkhud->addApplet("DMs", new InkHUD::DMApplet); + inkhud->addApplet("Channel 0", new InkHUD::ThreadedMessageApplet(0)); + inkhud->addApplet("Channel 1", new InkHUD::ThreadedMessageApplet(1)); + inkhud->addApplet("Positions", new InkHUD::PositionsApplet, true); // Activated + inkhud->addApplet("Recents List", new InkHUD::RecentsListApplet); + inkhud->addApplet("Heard", new InkHUD::HeardApplet, true, false, 0); // Activated, not autoshown, default on tile 0 + // inkhud->addApplet("Basic", new InkHUD::BasicExampleApplet); + // inkhud->addApplet("NewMsg", new InkHUD::NewMsgExampleApplet); + + // Start running InkHUD + inkhud->begin(); + + // Buttons + // -------------------------- + + Inputs::TwoButton *buttons = Inputs::TwoButton::getInstance(); // A shared NicheGraphics component + + // Setup the main user button (0) + buttons->setWiring(0, BUTTON_PIN); + buttons->setHandlerShortPress(0, []() { InkHUD::InkHUD::getInstance()->shortpress(); }); + buttons->setHandlerLongPress(0, []() { InkHUD::InkHUD::getInstance()->longpress(); }); + + // Setup the aux button (1) + // Bonus feature of VME290 + buttons->setWiring(1, BUTTON_PIN_SECONDARY); + buttons->setHandlerShortPress(1, []() { InkHUD::InkHUD::getInstance()->nextTile(); }); + + buttons->start(); +} + +#endif \ No newline at end of file diff --git a/variants/t5s3_epaper/pins_arduino.h b/variants/t5s3_epaper/pins_arduino.h new file mode 100644 index 000000000..ccde8a5f9 --- /dev/null +++ b/variants/t5s3_epaper/pins_arduino.h @@ -0,0 +1,27 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +#define USB_VID 0x303a +#define USB_PID 0x1001 + +// The default Wire will be mapped to RTC and Touch +static const uint8_t SDA = 39; +static const uint8_t SCL = 40; + +// Default SPI will be mapped to Radio +static const uint8_t SS = 46; +static const uint8_t MOSI = 17; +static const uint8_t MISO = 8; +static const uint8_t SCK = 18; + +// Default SPI1 will be mapped to SD Card +#define SPI_MOSI (13) +#define SPI_SCK (14) +#define SPI_MISO (21) +#define SPI_CS (16) + +#define SDCARD_CS SPI_CS + +#endif /* Pins_Arduino_h */ diff --git a/variants/t5s3_epaper/platformio.ini b/variants/t5s3_epaper/platformio.ini new file mode 100644 index 000000000..59b1db657 --- /dev/null +++ b/variants/t5s3_epaper/platformio.ini @@ -0,0 +1,29 @@ +[env:t5s3-epaper-inkhud] +extends = esp32s3_base, inkhud +board = t5-epaper-s3 +board_build.partition = default_16MB.csv +board_check = false +upload_protocol = esptool + +build_flags = + ${esp32_base.build_flags} + ${inkhud.build_flags} + -I variants/t5s3_epaper + -D PRIVATE_HW + -D MESHTASTIC_EXCLUDE_I2C=1 + -D MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR=1 +; -D GPS_POWER_TOGGLE + -D HAS_SDCARD + -D SDCARD_USE_SPI1 + -D PCF8563_RTC=0x51 + +build_src_filter = + ${esp32s3_base.build_src_filter} + ${inkhud.build_src_filter} + +lib_deps = + ${inkhud.lib_deps} ; InkHUD libs first, so we get GFXRoot instead of AdafruitGFX + ${esp32s3_base.lib_deps} + lewisxhe/PCF8563_Library@^1.0.1 + lewisxhe/XPowersLib@^0.2.3 + lewisxhe/SensorLib@^0.2.2 \ No newline at end of file diff --git a/variants/t5s3_epaper/variant.h b/variants/t5s3_epaper/variant.h new file mode 100644 index 000000000..dcf438973 --- /dev/null +++ b/variants/t5s3_epaper/variant.h @@ -0,0 +1,49 @@ + +// TODO: Display (E-Ink) +#define PIN_EINK_EN 11 // BL +#define PIN_EINK_CS 11 +#define PIN_EINK_BUSY -1 +#define PIN_EINK_DC 21 +#define PIN_EINK_RES -1 +#define PIN_EINK_SCLK 14 +#define PIN_EINK_MOSI 13 // SDI + +#define EPD_WIDTH 960 +#define EPD_HEIGHT 540 + +// TODO: battery voltage measurement (I2C) +// BQ25896 +// BQ27220 + +// #define I2C_SDA SDA +// #define I2C_SCL SCL + +// optional GPS +#define GPS_DEFAULT_NOT_PRESENT 1 +// #define GPS_RX_PIN 43 +// #define GPS_TX_PIN 44 + +#define BUTTON_PIN 48 +#define BUTTON_PIN_SECONDARY 0 + +#define USE_SX1262 +#define LORA_SCK 18 +#define LORA_MISO 8 +#define LORA_MOSI 17 +#define LORA_CS 46 +#define LORA_RESET 1 + +#define LORA_DIO0 +#define LORA_DIO1 10 +#define LORA_DIO2 +#define LORA_RXEN NC +#define LORA_TXEN NC + +#ifdef USE_SX1262 +#define SX126X_CS LORA_CS +#define SX126X_DIO1 LORA_DIO1 +#define SX126X_BUSY 47 +#define SX126X_RESET LORA_RESET +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 2.4 +#endif