Files
ESP8266lib/ext/e-ink/Waveshare_4_2.h
kazu ac74587ee7 fixed some issue with SoftI2C not working (missing delay)
added code for a waveshare eInk
refactored some old code to match with the new SoftI2C
2020-10-18 10:49:59 +02:00

256 lines
7.7 KiB
C++

#include "Waveshare.h"
template <int PIN_CS, int PIN_BUSY, int PIN_RST, int PIN_DC, typename SPI> class Waveshare_4_2 : public Waveshare<PIN_CS, PIN_BUSY, PIN_RST, PIN_DC, SPI> {
static constexpr const char* NAME = "E-Ink 4.2\"";
public:
enum class Mode {
BLACK_WHITE,
BLACK_WHITE_RED,
};
public:
Waveshare_4_2(SPI& spi) : Waveshare<PIN_CS, PIN_BUSY, PIN_RST, PIN_DC, SPI>(spi) {
}
public:
struct Window {
uint16_t x1; // must be multiple of 8
uint16_t y1;
uint16_t w; // must be multiple of 8
uint16_t h;
Window(uint16_t x1, uint16_t y1, uint16_t w, uint16_t h) : x1(x1), y1(y1), w(w), h(h) {}
};
void setWindow(Window& win) {
this->sendCommand(0x90);
this->sendData((win.x1) >> 8);
this->sendData((win.x1) >> 0);
this->sendData((win.x1+win.w-1) >> 8);
this->sendData((win.x1+win.w-1) >> 0);
this->sendData(win.y1 >> 8);
this->sendData(win.y1 >> 0);
this->sendData((win.y1+win.h-1) >> 8);
this->sendData((win.y1+win.h-1) >> 0);
this->sendData(0x0); // 0 = refresh only the window, 1 = refresh everything??
}
void enableWindow() {
this->sendCommand(0x91);
}
void disableWindow() {
this->sendCommand(0x92);
}
void init(Mode mode) {
debugMod(NAME, "init()");
this->reset();
this->send3(0x06, 0x17, 0x17, 0x17); // BOOSTER_SOFT_START
this->sendCommand(0x04); // POWER_ON
this->waitUntilIdle();
uint8_t cfg = 0x0F;
if (mode == Mode::BLACK_WHITE) {cfg |= (1<<4);}
this->send1(0x00, cfg); // PANEL_SETTING
this->send1(0x50, 0xF7); // VCOM_AND_DATA_INTERVAL_SETTING
//this->sendCommand(0x10);//DATA_START_TRANSMISSION_1
//usleep(10*1000);
debugMod(NAME, "init() complete");
}
void loadBlack(const uint8_t* black) {
this->sendCommand(0x10);
if (black) {
for (int i = 0; i < 400*300/8; ++i) {this->sendData(~reverse(black[i]));}
} else {
for (int i = 0; i < 400*300/8; ++i) {this->sendData(~0x00);}
}
this->sendCommand(0x11);
}
void loadRed(const uint8_t* red) {
this->sendCommand(0x13);
if (red) {
for (int i = 0; i < 400*300/8; ++i) {this->sendData(~reverse(red[i]));}
} else {
for (int i = 0; i < 400*300/8; ++i) {this->sendData(~0x00);}
}
this->sendCommand(0x11);
}
static uint8_t reverse(uint8_t a) {
return
((a & 0x1) << 7) | ((a & 0x2) << 5) |
((a & 0x4) << 3) | ((a & 0x8) << 1) |
((a & 0x10) >> 1) | ((a & 0x20) >> 3) |
((a & 0x40) >> 5) | ((a & 0x80) >> 7);
}
void show() {
debugMod(NAME, "refresh");
this->sendCommand(0x12);//DISPLAY_REFRESH
usleep(100*1000);
this->waitUntilIdle();
debugMod(NAME, "refresh done");
debugMod(NAME, "sleep");
this->send1(0x50, 0x17);//VCOM_AND_DATA_INTERVAL_SETTING
this->send1(0x82, 0x00);//VCM_DC_SETTING_REGISTER, to solve Vcom drop
this->send4(0x01, 0x02, 0x00, 0x00, 0x00);//POWER_SETTING
this->waitUntilIdle();
this->sendCommand(0x02);//POWER_OFF
debugMod(NAME, "sleep done");
}
private:
unsigned char lut_dc_4in2[44] = {
0x00, 0x17, 0x00, 0x00, 0x00, 0x02, 0x00, 0x17, 0x17, 0x00, 0x00,
0x02, 0x00, 0x0A, 0x01, 0x00, 0x00, 0x01, 0x00, 0x0E, 0x0E, 0x00,
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
//R21H
unsigned char lut_ww_4in2[42] = {
0x40, 0x17, 0x00, 0x00, 0x00, 0x02, 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 0x40, 0x0A,
0x01, 0x00, 0x00, 0x01, 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
//R22H r
unsigned char lut_bw_4in2[42] = {
0x40, 0x17, 0x00, 0x00, 0x00, 0x02, 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 0x40, 0x0A,
0x01, 0x00, 0x00, 0x01, 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
//R24H b
unsigned char lut_bb_4in2[42] = {
0x80, 0x17, 0x00, 0x00, 0x00, 0x02, 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 0x80, 0x0A,
0x01, 0x00, 0x00, 0x01, 0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
//R23H w
unsigned char lut_wb_4in2[42] = {
0x80, 0x17, 0x00, 0x00, 0x00, 0x02, 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 0x80, 0x0A,
0x01, 0x00, 0x00, 0x01, 0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
};
/*
int EPD_Init_4in2()
{
EPD_Reset();
EPD_SendCommand(0x01);//POWER_SETTING
EPD_SendData(0x03); // VDS_EN, VDG_EN
EPD_SendData(0x00); // VCOM_HV, VGHL_LV[1], VGHL_LV[0]
EPD_SendData(0x2F); // VDH
EPD_SendData(0x2F); // VDL
EPD_SendData(0xFF); // VDHR
EPD_Send_3(0x06, 0x17, 0x17, 0x17);//BOOSTER_SOFT_START
EPD_SendCommand(0x04);//POWER_ON
EPD_WaitUntilIdle();
EPD_Send_2(0x00, 0xBF, 0x0B);//PANEL_SETTING: // KW-BF KWR-AF BWROTP 0f
EPD_Send_1(0x30, 0x3C);//PLL_CONTROL: 3A 100HZ, 29 150Hz, 39 200HZ, 31 171HZ
EPD_Send_4(0x61, 1, 144, 1, 44);// RESOLUTION_SETTING: HI(W), LO(W), HI(H), LO(H)
EPD_Send_1(0x82, 0x12);// VCM_DC_SETTING
EPD_Send_1(0x50, 0x97);// VCOM_AND_DATA_INTERVAL_SETTING: VBDF 17|D7 VBDW 97 VBDB 57 VBDF F7 VBDW 77 VBDB 37 VBDR B7
EPD_lut(0x20,44,&lut_dc_4in2[0]);// LUT_FOR_VCOM
EPD_lut(0x21,42,&lut_ww_4in2[0]);// LUT_WHITE_TO_WHITE
EPD_lut(0x22,42,&lut_bw_4in2[0]);// LUT_BLACK_TO_WHITE
EPD_lut(0x23,42,&lut_wb_4in2[0]);// LUT_WHITE_TO_BLACK
EPD_lut(0x24,42,&lut_bb_4in2[0]);// LUT_BLACK_TO_BLACK
EPD_SendCommand(0x10);//DATA_START_TRANSMISSION_1
delay(2);
for(int i = 0; i < 400*300; i++)EPD_SendData(0xFF);//Red channel
EPD_SendCommand(0x13);//DATA_START_TRANSMISSION_2
delay(2);
return 0;
}
unsigned char lut_dc_4in2b[] =
{
0x00, 0x17, 0x00, 0x00, 0x00, 0x02, 0x00, 0x17, 0x17, 0x00, 0x00,
0x02, 0x00, 0x0A, 0x01, 0x00, 0x00, 0x01, 0x00, 0x0E, 0x0E, 0x00,
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
//R21H
unsigned char lut_ww_4in2b[] =
{
0x40, 0x17, 0x00, 0x00, 0x00, 0x02, 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 0x40, 0x0A,
0x01, 0x00, 0x00, 0x01, 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
//R22H r
unsigned char lut_bw_4in2b[] =
{
0x40, 0x17, 0x00, 0x00, 0x00, 0x02, 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 0x40, 0x0A,
0x01, 0x00, 0x00, 0x01, 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
//R24H b
unsigned char lut_bb_4in2b[] =
{
0x80, 0x17, 0x00, 0x00, 0x00, 0x02, 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 0x80, 0x0A,
0x01, 0x00, 0x00, 0x01, 0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
//R23H w
unsigned char lut_wb_4in2b[] =
{
0x80, 0x17, 0x00, 0x00, 0x00, 0x02, 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 0x80, 0x0A,
0x01, 0x00, 0x00, 0x01, 0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
int EPD_Init_4in2b()
{
EPD_Reset();
EPD_Send_3(0x06,0x17,0x17,0x17);//BOOSTER_SOFT_START
EPD_SendCommand(0x04);//POWER_ON
EPD_WaitUntilIdle();
EPD_Send_1(0x00, 0x0F);//PANEL_SETTING
EPD_Send_1(0x50,0xF7);// VCOM_AND_DATA_INTERVAL_SETTING
EPD_SendCommand(0x10);//DATA_START_TRANSMISSION_1
delay(2);
return 0;
}
*/