Files
firmware/src/graphics/niche/Drivers/EInk
todd-herbert ba93097bb7 Add InkHUD driver for WeAct Studio 1.54" display module (#7000)
* Strip redundant code from E-Ink driver

* Begin polling for E-Ink update completion sooner
In some cases, we might be waiting longer than we need to.

* E-Ink driver for WeAct 1.54" display
Currently identical to the popular GDEY0154D67 model. Kept separate now in case the drivers need to diverge in future.

* Put back code which sets the number of gate lines
2025-06-12 19:59:28 -05:00
..

NicheGraphics - E-Ink Driver

A driver for E-Ink SPI displays. Suitable for re-use by various NicheGraphics UIs.

Your UI should use the class NicheGraphics::Drivers::EInk . When you set up a hardware variant, you will use one of the specific display model classes, which extend the EInk class.

An example setup might look like this:

void setupNicheGraphics()
{
    using namespace NicheGraphics;

    // An imaginary UI
    YourCustomUI *yourUI = new YourCustomUI();

    // Setup SPI
    SPIClass *hspi = new SPIClass(HSPI);
    hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS);

    // Setup Enk driver
    Drivers::EInk *driver = new Drivers::DEPG0290BNS800;
    driver->begin(hspi, PIN_EINK_DC, PIN_EINK_CS, PIN_EINK_BUSY);

    // Pass the driver to your UI
    YourUI::driver = driver;
}

Methods

update(uint8_t *imageData, UpdateTypes type)

Update the image on the display

  • imageData to draw to the display.
  • type which type of update to perform.
    • FULL
    • FAST (partial refresh)
    • (Other custom types may be possible)

The imageData is a 1-bit image. X-Pixels are 8-per byte, with the MSB being the leftmost pixel. This was not an InkHUD design decision; it is the raw format accepted by the E-Ink display controllers ICs.

To-do: add a helper method to InkHUD::Drivers::EInk to do this arithmetic for you.

uint16_t w = driver::width();
uint16_t h = driver::height();

uint8_t image[ (w/8) * h ]; // X pixels are 8-per-byte

image[0] |= (1 << 7); // Set pixel x=0, y=0
image[0] |= (1 << 0); // Set pixel x=7, y=0
image[1] |= (1 << 7); // Set pixel x=8, y=0

uint8_t x = 12;
uint8_t y = 2;
uint8_t yBytes = y * (w/8);
uint8_t xBytes = x / 8;
uint8_t xBits = (7-x) % 8;
image[yByte + xByte] |= (1 << xBits); // Set pixel x=12, y=2

await()

Wait for an in-progress update to complete before continuing

supports(UpdateTypes type)

Check if display supports a specific update type. true if supported.

  • type type to check

busy()

Check if display is already performing an update(). true if already updating.

width()

Width of the display, in pixels. Note: most displays are portrait. Your UI will need to implement rotation in software.

height()

Height of the display, in pixels. Note: most displays are portrait. Your UI will need to implement rotation in software.

Supporting New Displays

This topic is not covered in depth, but these notes may be helpful.

The InkHUD::Drivers::EInk class contains only the mechanism for implementing an E-Ink driver on-top of Meshtastic's OSThread. A driver for a specific display needs to extend this class.

Controller IC

If your display uses a controller IC from Solomon Systech, you can probably extend the existing Drivers::SSD16XX class, making only minor modifications.

At this stage, displays using controller ICS from other manufacturers (UltraChip, Fitipower, etc) need to manually implemented. See Drivers::LCMEN2R13EFC1 for an example.

Generic base classes for manufacturers other than Solomon Systech might be added here in future.

Finding Information

Flex-Connector Labels

The orange flex-connector attached to E-Ink displays is often printed with an identifying label. This is not a totally unique identifier, but does give a very strong clue as to the true model of the display, which can be used to search out further information.

Datasheets

The manufacturer of a DIY display module may publish a datasheet. These are often incomplete, but might reveal the true model of the display, or the controller IC.

If you can determine the true model name of the display, you can likely find a more complete datasheet on the display manufacturer's website. This will often provide a "typical operating sequence"; a general overview of the code used to drive the display

Example Code

The manufacturer of a DIY module may publish example code. You may have more luck finding example code published by the display manufacturer themselves, if you can determine the true model of the panel. These examples are a very valuable reference.

Other E-Ink drivers

Libraries like ZinggJM's GxEPD2 can be valuable sources of information, although your panel may not be specifically supported, and only compatible with a driver there, so some caution is advised.

The display selection file in GxEPD2's Hello World example is also a useful resource for matching "flex connector labels" with display models, but the flex connector label is not a unique identifier, so this is only another clue.