#include "./DEPG0213BNS800.h" #ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS using namespace NicheGraphics::Drivers; // Describes the operation performed when a "fast refresh" is performed // Source: Modified from GxEPD2 (GxEPD2_213_BN) static const uint8_t LUT_FAST[] = { // 1 2 3 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // B2B (Existing black pixels) 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // B2W (New white pixels) 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // W2B (New black pixels) 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // W2W (Existing white pixels) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VCOM 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // 1. Any pixels changing W2B or B2W. Two medium taps. 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2. All pixels. One short tap. 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 3. Cooldown 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, // }; // How strongly the pixels are pulled and pushed void DEPG0213BNS800::configVoltages() { switch (updateType) { case FAST: // Reference: display datasheet, GxEPD1 sendCommand(0x03); // Gate voltage sendData(0x17); // VGH: 20V // Reference: display datasheet, GxEPD1 sendCommand(0x04); // Source voltage sendData(0x41); // VSH1: 15V sendData(0x00); // VSH2: NA sendData(0x32); // VSL: -15V // GxEPD1 sets this at -1.2V, but that seems to be drive the pixels very hard sendCommand(0x2C); // VCOM voltage sendData(0x08); // VCOM: -0.2V break; case FULL: default: // From OTP memory break; } } // Load settings about how the pixels are moved from old state to new state during a refresh // - manually specified, // - or with stored values from displays OTP memory void DEPG0213BNS800::configWaveform() { switch (updateType) { case FAST: sendCommand(0x3C); // Border waveform: sendData(0x80); // VSS sendCommand(0x32); // Write LUT register from MCU: sendData(LUT_FAST, sizeof(LUT_FAST)); // (describes operation for a FAST refresh) break; case FULL: default: // From OTP memory break; } } // Describes the sequence of events performed by the displays controller IC during a refresh // Includes "power up", "load settings from memory", "update the pixels", etc void DEPG0213BNS800::configUpdateSequence() { switch (updateType) { case FAST: sendCommand(0x22); // Set "update sequence" sendData(0xCF); // Differential, use manually loaded waveform break; case FULL: default: sendCommand(0x22); // Set "update sequence" sendData(0xF7); // Non-differential, load waveform from OTP break; } } // Once the refresh operation has been started, // begin periodically polling the display to check for completion, using the normal Meshtastic threading code // Only used when refresh is "async" void DEPG0213BNS800::detachFromUpdate() { switch (updateType) { case FAST: return beginPolling(50, 500); // At least 500ms, then poll every 50ms case FULL: default: return beginPolling(100, 3500); // At least 3500ms, then poll every 100ms } } // For this display, we do not need to re-write the new image. // We're overriding SSD16XX::finalizeUpdate to make this small optimization. // The display does also work just fine with the generic SSD16XX method, though. void DEPG0213BNS800::finalizeUpdate() { // Put a copy of the image into the "old memory". // Used with differential refreshes (e.g. FAST update), to determine which px need to move, and which can remain in place // We need to keep the "old memory" up to date, because don't know whether next refresh will be FULL or FAST etc. if (updateType != FULL) { // writeNewImage(); // Not required for this display writeOldImage(); sendCommand(0x7F); // Terminate image write without update wait(); } // Enter deep-sleep to save a few µA // Waking from this requires that display's reset pin is broken out if (pin_rst != 0xFF) deepSleep(); } #endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS