diff --git a/src/OneBitDisplay.h b/src/OneBitDisplay.h index 1dca90c..78dc220 100644 --- a/src/OneBitDisplay.h +++ b/src/OneBitDisplay.h @@ -50,6 +50,7 @@ enum { OBD_CHIP_SSD16xx, // EPD OBD_CHIP_UC8151, // EPD OBD_CHIP_SHARP, // all Sharp LCDs + OBD_CHIP_IL3820, // EPD OBD_CHIP_COUNT }; @@ -108,6 +109,7 @@ enum { EPD29B_128x296, EPD29R_128x296, EPD29Y_128x296, // DEPG0290YN + EPD29G_128x296, // GDEH029A1 EPD293_128x296, EPD42R_400x300, EPD42R2_400x300, // GDEQ042Z21 @@ -265,6 +267,48 @@ enum reg2 { SSD1608_NOP = 0xFF, }; +// EPD29G_128x296 (IL3820) commands very likely to SSD1608 +enum reg3 { + IL3820_DRIVER_CONTROL = 0x01, + IL3820_GATE_VOLTAGE = 0x03, + IL3820_SOURCE_VOLTAGE = 0x04, + IL3820_DISPLAY_CONTROL = 0x07, + IL3820_NON_OVERLAP = 0x0B, + IL3820_BOOSTER_SOFT_START = 0x0C, + IL3820_GATE_SCAN_START = 0x0F, + IL3820_DEEP_SLEEP = 0x10, + IL3820_DATA_MODE = 0x11, + IL3820_SW_RESET = 0x12, + IL3820_TEMP_WRITE = 0x1A, + IL3820_TEMP_READ = 0x1B, + IL3820_TEMP_CONTROL = 0x1C, + IL3820_TEMP_LOAD = 0x1D, + IL3820_MASTER_ACTIVATE = 0x20, + IL3820_DISP_CTRL1 = 0x21, + IL3820_DISP_CTRL2 = 0x22, + IL3820_WRITE_RAM = 0x24, + //IL3820_WRITE_ALTRAM = 0x26, //-- + IL3820_READ_RAM = 0x25, + IL3820_VCOM_SENSE = 0x28, + IL3820_VCOM_DURATION = 0x29, + IL3820_PGM_VCOM_OTP = 0x2A, //+ + IL3820_WRITE_VCOM = 0x2C, + IL3820_READ_OTP = 0x2D, + IL3820_PGM_WS_OTP = 0x30, //++ + IL3820_WRITE_LUT = 0x32, + IL3820_READ_LUT = 0x32, //++ + IL3820_PGM_OTP_SEL = 0x36, //++ + IL3820_OTP_SEL_CTRL = 0x37, //++ + IL3820_WRITE_DUMMY = 0x3A, + IL3820_WRITE_GATELINE = 0x3B, + IL3820_WRITE_BORDER = 0x3C, + IL3820_SET_RAMXPOS = 0x44, + IL3820_SET_RAMYPOS = 0x45, + IL3820_SET_RAMXCOUNT = 0x4E, + IL3820_SET_RAMYCOUNT = 0x4F, + IL3820_NOP = 0xFF, +}; + #define BUSY_WAIT 0xff // Proportional font data taken from Adafruit_GFX library diff --git a/src/obd.inl b/src/obd.inl index 6496cfd..7387ee5 100644 --- a/src/obd.inl +++ b/src/obd.inl @@ -791,6 +791,51 @@ const uint8_t epd213b_init_sequence_full[] PROGMEM = 0x00 // end of table }; /* epd213b_init_sequence_full[] */ +// Controller IL3820/IL3829 +#define GxGDEH029A1_X_PIXELS 128 +#define GxGDEH029A1_Y_PIXELS 296 +const uint8_t epd_IL3820_init_sequence_full[] PROGMEM = +{ + 0x04, IL3820_DRIVER_CONTROL, (GxGDEH029A1_Y_PIXELS - 1) % 256, (GxGDEH029A1_Y_PIXELS - 1) / 256, 0x00, // Pannel configuration, Gate selection + 0x04, IL3820_BOOSTER_SOFT_START, 0xd7, 0xd6, 0x9d, // softstart // X decrease, Y decrease + 0x02, IL3820_WRITE_VCOM, 0xa8, // VCOMVol// VCOM setting + 0x02, IL3820_WRITE_DUMMY, 0x1a, // dummy line per gate + 0x02, IL3820_WRITE_GATELINE, 0x08, // Gate time setting + 0x02, IL3820_DATA_MODE, 0x03, //(em) + 0x03, IL3820_SET_RAMXPOS, 0x00, (GxGDEH029A1_X_PIXELS - 1) / 8, + 0x05, IL3820_SET_RAMYPOS, 0x00, 0x00, (GxGDEH029A1_Y_PIXELS -1) % 256, (GxGDEH029A1_Y_PIXELS -1) / 256, // X-source area,Y-gate area + 0x02, IL3820_SET_RAMXCOUNT, 0x00, // set ram pointer + 0x03, IL3820_SET_RAMYCOUNT, 0x00, 0x00, + 0x1F, IL3820_WRITE_LUT, // command + 0x50, 0xAA, 0x55, 0xAA, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //LUTDefault_full + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //LUTDefault_full + 0x02, IL3820_DISP_CTRL2, 0xC0 , // Begin poweron + 0x01, IL3820_MASTER_ACTIVATE, + BUSY_WAIT, // End poweron + 0x00 +}; /* epd_IL3820_init_sequence_full[] */ + +const uint8_t epd_IL3820_init_sequence_fast[] PROGMEM = +{ + 0x04, IL3820_DRIVER_CONTROL, (GxGDEH029A1_Y_PIXELS - 1) % 256, (GxGDEH029A1_Y_PIXELS - 1) / 256, 0x00, // Pannel configuration, Gate selection + 0x04, IL3820_BOOSTER_SOFT_START, 0xd7, 0xd6, 0x9d, // softstart // X decrease, Y decrease + 0x02, IL3820_WRITE_VCOM, 0xa8, // VCOMVol// VCOM setting + 0x02, IL3820_WRITE_DUMMY, 0x1a, // dummy line per gate + 0x02, IL3820_WRITE_GATELINE, 0x08, // Gate time setting + 0x02, IL3820_DATA_MODE, 0x03, //(em) + 0x03, IL3820_SET_RAMXPOS, 0x00, (GxGDEH029A1_X_PIXELS - 1) / 8, + 0x05, IL3820_SET_RAMYPOS, 0x00, 0x00, (GxGDEH029A1_Y_PIXELS -1) % 256, (GxGDEH029A1_Y_PIXELS -1) / 256, // X-source area,Y-gate area + 0x02, IL3820_SET_RAMXCOUNT, 0x00, // set ram pointer + 0x03, IL3820_SET_RAMYCOUNT, 0x00, 0x00, + 0x1F, IL3820_WRITE_LUT, // command + 0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //LUTDefault_part + 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //LUTDefault_part + 0x02, IL3820_DISP_CTRL2, 0xC0 , // Begin poweron + 0x01, IL3820_MASTER_ACTIVATE, + BUSY_WAIT, // End poweron + 0x00 +}; /* epd_IL3820_init_sequence_fast[] */ + const uint8_t epd293_init_sequence_full[] PROGMEM = { // 0x01, SSD1608_SW_RESET, @@ -1989,6 +2034,19 @@ void obdSPIInit(OBDISP *pOBD, int iType, int iDC, int iCS, int iReset, int iMOSI pOBD->pInitFull = epd154_init_sequence_full; return; } + else if (iType == EPD29G_128x296) + { + pOBD->native_width = pOBD->width = 128; + pOBD->native_height = pOBD->height = 296; + pOBD->type = EPD29G_128x296; // the rest is the same + pOBD->pInitFull = epd_IL3820_init_sequence_full; + pOBD->pInitFast = epd_IL3820_init_sequence_fast; + pOBD->busy_idle = LOW; + pOBD->chip_type = OBD_CHIP_IL3820; + pOBD->iFlags |= OBD_HAS_FAST_UPDATE; + pOBD->can_flip = 0; + return; // nothing else to do yet + } else if (iType == EPD29_128x296 || iType == EPD213B_104x212 || iType == EPD37_240x416) { pOBD->iFlags |= OBD_HAS_FAST_UPDATE; @@ -2779,6 +2837,22 @@ void EPD154_Finish(OBDISP *pOBD, int bPartial) EPDWaitBusy(pOBD, 0); } /* EPD154_Finish() */ +void EPD_IL3820_Finish(OBDISP *pOBD, int bPartial) { + if (bPartial) { + EPD_CMD2(pOBD, IL3820_DISP_CTRL2, 0x04); + } else { + EPD_CMD2(pOBD, IL3820_DISP_CTRL2, 0xc4); + } + obdWriteCommand(pOBD, IL3820_MASTER_ACTIVATE); + EPDWaitBusy(pOBD, 0); + + /*Serial.println("EPD_IL3820_Finish - Power off"); + EPD_CMD2(pOBD, IL3820_DISP_CTRL2, 0xc3); + obdWriteCommand(pOBD, IL3820_MASTER_ACTIVATE); + delay(80); + EPDWaitBusy(pOBD, 0);*/ +} /* EPD_IL3820_Finish() */ + void EPD75_Begin(OBDISP *pOBD, int x, int y, int w, int h, int bPartial) { uint8_t ucLine[16]; @@ -2801,6 +2875,7 @@ void EPD75_Begin(OBDISP *pOBD, int x, int y, int w, int h, int bPartial) // RawWriteData(pOBD, ucLine, 9); // boundaries } } + void EPD29_Begin(OBDISP *pOBD, int x, int y, int w, int h, int bPartial) { uint8_t ucLine[8]; @@ -2943,6 +3018,13 @@ static int EPDDumpFast(OBDISP *pOBD, uint8_t *pBuffer, int x, int y, int w, int EPD27_Begin(pOBD, 0, 0, pOBD->width, pOBD->height, true); #ifndef WIMPY_MCU EPDWriteImage(pOBD, UC8151_DTM2, NULL, 0, 0, pOBD->width, pOBD->height, 0); +#endif + obdWriteCommand(pOBD, UC8151_DRF); + } + if (pOBD->type == EPD29G_128x296) { + EPDSendCMDSequence(pOBD, pOBD->pInitFast); +#ifndef WIMPY_MCU + EPDWriteImage(pOBD, IL3820_WRITE_RAM, NULL, 0, 0, pOBD->width, pOBD->height, 0); #endif obdWriteCommand(pOBD, UC8151_DRF); } @@ -3807,6 +3889,18 @@ static int EPDDumpBuffer(OBDISP *pOBD, int bRefresh, int bWait) EPD29_Finish(pOBD, false); } } + + if (pOBD->type == EPD29G_128x296){ + EPDSendCMDSequence(pOBD, pOBD->pInitFull); +#ifndef WIMPY_MCU + if (pOBD->ucScreen) { + EPDWriteImage(pOBD, IL3820_WRITE_RAM, NULL, 0, 0, pOBD->width, pOBD->height, 0); + } +#endif + if (bRefresh) { + EPD_IL3820_Finish(pOBD, false); + } + } if (pOBD->type == EPD27_176x264) { EPD27_Begin(pOBD, 0, 0, pOBD->width, pOBD->height, false); obdWriteCommand(pOBD, UC8151_DTM1);