mirror of https://github.com/arendst/Tasmota.git
Epaper update (#17727)
* update epaper descriptors * epaper rewrite * add busy invert option * fix v2 partial refresh * prepare for large descriptors
This commit is contained in:
parent
beb021210d
commit
853909cb35
|
@ -86,6 +86,10 @@ void Renderer::Begin(int16_t p1,int16_t p2,int16_t p3) {
|
|||
|
||||
}
|
||||
|
||||
void Renderer::Sleep(void) {
|
||||
|
||||
}
|
||||
|
||||
void Renderer::Updateframe() {
|
||||
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ typedef struct LVGL_PARAMS {
|
|||
uint8_t use_dma : 1;
|
||||
uint8_t swap_color : 1;
|
||||
uint8_t async_dma : 1; // force DMA completion before returning, avoid conflict with other devices on same bus. If set you should make sure the display is the only device on the bus
|
||||
uint8_t resvd_1 : 1;
|
||||
uint8_t busy_invert : 1;
|
||||
uint8_t resvd_2 : 1;
|
||||
uint8_t resvd_3 : 1;
|
||||
uint8_t resvd_4 : 1;
|
||||
|
@ -86,6 +86,7 @@ public:
|
|||
virtual uint16_t bgcol(void);
|
||||
virtual int8_t color_type(void);
|
||||
virtual void Splash(void);
|
||||
virtual void Sleep(void);
|
||||
virtual char *devname(void);
|
||||
virtual LVGL_PARAMS *lvgl_pars(void);
|
||||
virtual void ep_update_mode(uint8_t mode);
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
|
||||
#define EPD_29_V2
|
||||
|
||||
//#define BUSY_PIN 16
|
||||
|
||||
|
||||
Epd::Epd(int16_t width, int16_t height) :
|
||||
Paint(width,height) {
|
||||
}
|
||||
|
@ -38,30 +41,35 @@ void Epd::DisplayOnff(int8_t on) {
|
|||
}
|
||||
|
||||
void Epd::Updateframe() {
|
||||
#ifdef EPD_29_V2
|
||||
if (mode == DISPLAY_INIT_PARTIAL) {
|
||||
SetFrameMemory_Partial(framebuffer, 0, 0, EPD_WIDTH,EPD_HEIGHT);
|
||||
DisplayFrame_Partial();
|
||||
} else {
|
||||
SetFrameMemory(framebuffer, 0, 0, EPD_WIDTH,EPD_HEIGHT);
|
||||
DisplayFrame();
|
||||
}
|
||||
#else
|
||||
SetFrameMemory(framebuffer, 0, 0, EPD_WIDTH,EPD_HEIGHT);
|
||||
DisplayFrame();
|
||||
#endif
|
||||
//Serial.printf("update\n");
|
||||
}
|
||||
|
||||
#define DISPLAY_INIT_MODE 0
|
||||
#define DISPLAY_INIT_PARTIAL 1
|
||||
#define DISPLAY_INIT_FULL 2
|
||||
|
||||
|
||||
void Epd::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) {
|
||||
// ignore update mode
|
||||
if (p==DISPLAY_INIT_PARTIAL) {
|
||||
if (p == DISPLAY_INIT_PARTIAL) {
|
||||
Init(lut_partial_update);
|
||||
//ClearFrameMemory(0xFF); // bit set = white, bit reset = black
|
||||
DisplayFrame();
|
||||
delay(500);
|
||||
delay_busy(500);
|
||||
return;
|
||||
//Serial.printf("partial\n");
|
||||
} else if (p==DISPLAY_INIT_FULL) {
|
||||
} else if (p == DISPLAY_INIT_FULL) {
|
||||
Init(lut_full_update);
|
||||
//ClearFrameMemory(0xFF); // bit set = white, bit reset = black
|
||||
DisplayFrame();
|
||||
delay(3500);
|
||||
delay_busy(3500);
|
||||
//Serial.printf("full\n");
|
||||
return;
|
||||
} else {
|
||||
|
@ -80,25 +88,31 @@ void Epd::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) {
|
|||
disp_bpp = 1;
|
||||
}
|
||||
|
||||
void Epd::Begin(int16_t cs,int16_t mosi,int16_t sclk) {
|
||||
cs_pin=cs;
|
||||
mosi_pin=mosi;
|
||||
sclk_pin=sclk;
|
||||
void Epd::Begin(int16_t cs,int16_t mosi,int16_t sclk, int16_t rst, int16_t busy) {
|
||||
cs_pin = cs;
|
||||
mosi_pin = mosi;
|
||||
sclk_pin = sclk;
|
||||
rst_pin = rst;
|
||||
busy_pin = busy;
|
||||
#ifdef BUSY_PIN
|
||||
busy_pin = BUSY_PIN;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Epd::Init(int8_t p) {
|
||||
if (p==DISPLAY_INIT_PARTIAL) {
|
||||
if (p == DISPLAY_INIT_PARTIAL) {
|
||||
Init(lut_partial_update);
|
||||
} else {
|
||||
Init(lut_full_update);
|
||||
}
|
||||
mode = p;
|
||||
ClearFrameMemory(0xFF);
|
||||
DisplayFrame();
|
||||
if (p==DISPLAY_INIT_PARTIAL) {
|
||||
delay(350);
|
||||
if (p == DISPLAY_INIT_PARTIAL) {
|
||||
delay_busy(350);
|
||||
} else {
|
||||
delay(3500);
|
||||
delay_busy(3500);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,6 +128,9 @@ int Epd::Init(const unsigned char* lut) {
|
|||
sclk_pin=pin[GPIO_SSPI_SCLK];
|
||||
*/
|
||||
|
||||
if (framebuffer) {
|
||||
// free(framebuffer);
|
||||
}
|
||||
framebuffer = (uint8_t*)malloc(EPD_WIDTH * EPD_HEIGHT / 8);
|
||||
if (!framebuffer) return -1;
|
||||
|
||||
|
@ -125,14 +142,24 @@ int Epd::Init(const unsigned char* lut) {
|
|||
digitalWrite(mosi_pin,LOW);
|
||||
digitalWrite(sclk_pin,LOW);
|
||||
|
||||
if (rst_pin >= 0) {
|
||||
pinMode(rst_pin, OUTPUT);
|
||||
digitalWrite(rst_pin, HIGH);
|
||||
}
|
||||
|
||||
if (busy_pin >= 0) {
|
||||
pinMode(busy_pin, INPUT_PULLUP);
|
||||
}
|
||||
|
||||
width = EPD_WIDTH;
|
||||
height = EPD_HEIGHT;
|
||||
|
||||
#ifdef EPD_29_V2
|
||||
/* EPD hardware init start */
|
||||
WaitUntilIdle();
|
||||
Reset();
|
||||
|
||||
SendCommand(0x12); //SWRESET
|
||||
WaitUntilIdle();
|
||||
delay_busy(100);
|
||||
|
||||
SendCommand(0x01); //Driver output control
|
||||
SendData(0x27);
|
||||
|
@ -149,9 +176,10 @@ int Epd::Init(const unsigned char* lut) {
|
|||
SendData(0x80);
|
||||
|
||||
SetMemoryPointer(0, 0);
|
||||
WaitUntilIdle();
|
||||
delay_busy(10);
|
||||
|
||||
SetLut_by_host(lut_full_update);
|
||||
mode = DISPLAY_INIT_FULL;
|
||||
|
||||
#else
|
||||
/* EPD hardware init start */
|
||||
|
@ -197,31 +225,33 @@ void Epd::SendData(unsigned char data) {
|
|||
// SpiTransfer(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief: Wait until the busy_pin goes LOW
|
||||
*/
|
||||
void Epd::WaitUntilIdle(void) {
|
||||
|
||||
#ifdef EPD_29_V2
|
||||
delay(100);
|
||||
#endif
|
||||
|
||||
return;
|
||||
//while(DigitalRead(busy_pin) == HIGH) { //LOW: idle, HIGH: busy
|
||||
// DelayMs(100);
|
||||
//}
|
||||
void Epd::delay_busy(uint32_t wait) {
|
||||
if (busy_pin >= 0) {
|
||||
while (digitalRead(busy_pin) == HIGH) { //LOW: idle, HIGH: busy
|
||||
delay(10);
|
||||
}
|
||||
} else {
|
||||
delay(wait);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief: module reset.
|
||||
* often used to awaken the module in deep sleep,
|
||||
* see Epd::Sleep();
|
||||
*/
|
||||
void Epd::Reset(void) {
|
||||
//DigitalWrite(reset_pin, LOW); //module reset
|
||||
//delay(200);
|
||||
//DigitalWrite(reset_pin, HIGH);
|
||||
//delay(200);
|
||||
if (rst_pin >= 0) {
|
||||
digitalWrite(rst_pin, LOW); //module reset
|
||||
delay(200);
|
||||
digitalWrite(rst_pin, HIGH);
|
||||
delay(200);
|
||||
} else {
|
||||
SendCommand(0x12);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EPD_29_V2
|
||||
|
@ -230,7 +260,7 @@ void Epd::SetLut(const unsigned char *lut) {
|
|||
SendCommand(0x32);
|
||||
for(count=0; count<153; count++)
|
||||
SendData(lut[count]);
|
||||
WaitUntilIdle();
|
||||
delay_busy(50);
|
||||
}
|
||||
|
||||
|
||||
|
@ -276,6 +306,7 @@ void Epd::SetFrameMemory(
|
|||
uint16_t image_width,
|
||||
uint16_t image_height
|
||||
) {
|
||||
|
||||
uint16_t x_end;
|
||||
uint16_t y_end;
|
||||
|
||||
|
@ -366,15 +397,94 @@ void Epd::ClearFrameMemory(unsigned char color) {
|
|||
* set the other memory area.
|
||||
*/
|
||||
void Epd::DisplayFrame(void) {
|
||||
SendCommand(DISPLAY_UPDATE_CONTROL_2);
|
||||
SendCommand(DISPLAY_UPDATE_CONTROL_2); // 0x22
|
||||
#ifdef EPD_29_V2
|
||||
SendData(0xC7);
|
||||
#else
|
||||
SendData(0xC4);
|
||||
SendCommand(MASTER_ACTIVATION);
|
||||
#endif
|
||||
SendCommand(MASTER_ACTIVATION); // 0x20
|
||||
#ifndef EPD_29_V2
|
||||
SendCommand(TERMINATE_FRAME_READ_WRITE);
|
||||
WaitUntilIdle();
|
||||
#endif
|
||||
delay_busy(10);
|
||||
}
|
||||
|
||||
void Epd::DisplayFrame_Partial(void) {
|
||||
SendCommand(0x22);
|
||||
SendData(0x0F);
|
||||
SendCommand(0x20);
|
||||
delay_busy(10);
|
||||
}
|
||||
|
||||
#ifdef EPD_29_V2
|
||||
|
||||
void Epd::SetFrameMemory_Partial(const unsigned char* image_buffer, int x, int y, int image_width, int image_height) {
|
||||
int x_end;
|
||||
int y_end;
|
||||
|
||||
if (
|
||||
image_buffer == NULL ||
|
||||
x < 0 || image_width < 0 ||
|
||||
y < 0 || image_height < 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
/* x point must be the multiple of 8 or the last 3 bits will be ignored */
|
||||
x &= 0xF8;
|
||||
image_width &= 0xF8;
|
||||
if (x + image_width >= this->width) {
|
||||
x_end = this->width - 1;
|
||||
} else {
|
||||
x_end = x + image_width - 1;
|
||||
}
|
||||
if (y + image_height >= this->height) {
|
||||
y_end = this->height - 1;
|
||||
} else {
|
||||
y_end = y + image_height - 1;
|
||||
}
|
||||
|
||||
if (rst_pin >= 0) {
|
||||
digitalWrite(rst_pin, LOW);
|
||||
delay(2);
|
||||
digitalWrite(rst_pin, HIGH);
|
||||
delay(2);
|
||||
} else {
|
||||
SendCommand(0x12);
|
||||
}
|
||||
SetLut(lut_partial_update);
|
||||
SendCommand(0x37);
|
||||
SendData(0x00);
|
||||
SendData(0x00);
|
||||
SendData(0x00);
|
||||
SendData(0x00);
|
||||
SendData(0x00);
|
||||
SendData(0x40);
|
||||
SendData(0x00);
|
||||
SendData(0x00);
|
||||
SendData(0x00);
|
||||
SendData(0x00);
|
||||
|
||||
SendCommand(0x3C); //BorderWavefrom
|
||||
SendData(0x80);
|
||||
|
||||
SendCommand(0x22);
|
||||
SendData(0xC0);
|
||||
SendCommand(0x20);
|
||||
delay_busy(100);
|
||||
|
||||
SetMemoryArea(x, y, x_end, y_end);
|
||||
SetMemoryPointer(x, y);
|
||||
SendCommand(0x24);
|
||||
/* send the image data */
|
||||
for (int j = 0; j < y_end - y + 1; j++) {
|
||||
for (int i = 0; i < (x_end - x + 1) / 8; i++) {
|
||||
SendData(image_buffer[i + j * (image_width / 8)]^0xff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef EPD_29_V2
|
||||
/**
|
||||
* @brief: private function to specify the memory area for data R/W
|
||||
*/
|
||||
|
@ -390,6 +500,15 @@ void Epd::SetMemoryArea(int x_start, int y_start, int x_end, int y_end) {
|
|||
SendData((y_end >> 8) & 0xFF);
|
||||
}
|
||||
#else
|
||||
|
||||
void Epd::SetFrameMemory_Partial(
|
||||
const unsigned char* image_buffer,
|
||||
int x,
|
||||
int y,
|
||||
int image_width,
|
||||
int image_height
|
||||
) {
|
||||
}
|
||||
/**
|
||||
* @brief: private function to specify the memory area for data R/W
|
||||
*/
|
||||
|
@ -419,7 +538,7 @@ void Epd::SetMemoryPointer(int x, int y) {
|
|||
SendCommand(0x4F);
|
||||
SendData(y & 0xFF);
|
||||
SendData((y >> 8) & 0xFF);
|
||||
WaitUntilIdle();
|
||||
delay_busy(10);
|
||||
}
|
||||
#else
|
||||
/**
|
||||
|
@ -432,7 +551,7 @@ void Epd::SetMemoryPointer(int x, int y) {
|
|||
SendCommand(SET_RAM_Y_ADDRESS_COUNTER);
|
||||
SendData(y & 0xFF);
|
||||
SendData((y >> 8) & 0xFF);
|
||||
WaitUntilIdle();
|
||||
delay_busy(10);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -444,7 +563,7 @@ void Epd::SetMemoryPointer(int x, int y) {
|
|||
*/
|
||||
void Epd::Sleep() {
|
||||
SendCommand(DEEP_SLEEP_MODE);
|
||||
WaitUntilIdle();
|
||||
delay_busy(10);
|
||||
}
|
||||
|
||||
#ifdef EPD_29_V2
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
#include "epdpaint.h"
|
||||
|
||||
|
||||
#define DISPLAY_INIT_MODE 0
|
||||
#define DISPLAY_INIT_PARTIAL 1
|
||||
#define DISPLAY_INIT_FULL 2
|
||||
|
||||
// Display resolution
|
||||
#define EPD_WIDTH 128
|
||||
#define EPD_HEIGHT 296
|
||||
|
@ -91,23 +95,27 @@ public:
|
|||
|
||||
void DisplayOnff(int8_t on);
|
||||
void DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font);
|
||||
void Begin(int16_t p1,int16_t p2,int16_t p3);
|
||||
void Begin(int16_t cs,int16_t mosi,int16_t sclk, int16_t rst = -1, int16_t busy = -1);
|
||||
|
||||
void Updateframe();
|
||||
|
||||
private:
|
||||
unsigned int reset_pin;
|
||||
unsigned int dc_pin;
|
||||
unsigned int busy_pin;
|
||||
const unsigned char* lut;
|
||||
unsigned int cs_pin;
|
||||
signed int rst_pin;
|
||||
signed int busy_pin;
|
||||
unsigned int mosi_pin;
|
||||
unsigned int sclk_pin;
|
||||
|
||||
unsigned char mode;
|
||||
void delay_busy(uint32_t wait);
|
||||
void SetLut(const unsigned char* lut);
|
||||
void SetMemoryArea(int x_start, int y_start, int x_end, int y_end);
|
||||
void SetMemoryPointer(int x, int y);
|
||||
void SetLut_by_host(const unsigned char* lut);
|
||||
|
||||
void SetFrameMemory_Partial(const unsigned char* image_buffer,int x,int y,int image_width,int image_height);
|
||||
void DisplayFrame_Partial(void);
|
||||
//void fastSPIwrite(uint8_t d,uint8_t dc);
|
||||
};
|
||||
|
||||
|
|
|
@ -66,6 +66,18 @@ uDisplay::~uDisplay(void) {
|
|||
if (_i80_bus) {
|
||||
esp_lcd_del_i80_bus(_i80_bus);
|
||||
}
|
||||
|
||||
if (lut_full) {
|
||||
free(lut_full);
|
||||
}
|
||||
if (lut_partial) {
|
||||
free(lut_partial);
|
||||
}
|
||||
for (uint16_t cnt = 0; cnt < MAX_LUTS; cnt++ ) {
|
||||
if (lut_array[cnt]) {
|
||||
free(lut_array[cnt]);
|
||||
}
|
||||
}
|
||||
#endif // USE_ESP32_S3
|
||||
}
|
||||
|
||||
|
@ -86,6 +98,7 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
|
|||
lutptime = 35;
|
||||
lutftime = 350;
|
||||
lut3time = 10;
|
||||
busy_pin = -1;
|
||||
ep_mode = 0;
|
||||
fg_col = 1;
|
||||
bg_col = 0;
|
||||
|
@ -96,6 +109,8 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
|
|||
startline = 0xA1;
|
||||
uint8_t section = 0;
|
||||
dsp_ncmds = 0;
|
||||
epc_part_cnt = 0;
|
||||
epc_full_cnt = 0;
|
||||
lut_num = 0;
|
||||
lvgl_param.data = 0;
|
||||
lvgl_param.fluslines = 40;
|
||||
|
@ -103,8 +118,10 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
|
|||
rot_t[1] = 1;
|
||||
rot_t[2] = 2;
|
||||
rot_t[3] = 3;
|
||||
epcoffs_full = 0;
|
||||
epcoffs_part = 0;
|
||||
|
||||
for (uint32_t cnt = 0; cnt < 5; cnt++) {
|
||||
for (uint32_t cnt = 0; cnt < MAX_LUTS; cnt++) {
|
||||
lut_cnt[cnt] = 0;
|
||||
lut_cmd[cnt] = 0xff;
|
||||
}
|
||||
|
@ -135,9 +152,22 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
|
|||
} else if (section == 'L') {
|
||||
if (*lp1 >= '1' && *lp1 <= '5') {
|
||||
lut_num = (*lp1 & 0x07);
|
||||
lp1+=2;
|
||||
lp1 += 2;
|
||||
lut_siz[lut_num - 1] = next_val(&lp1);
|
||||
lut_array[lut_num - 1] = (uint8_t*)malloc(lut_siz[lut_num - 1]);
|
||||
lut_cmd[lut_num - 1] = next_hex(&lp1);
|
||||
} else {
|
||||
lut_num = 0;
|
||||
lp1++;
|
||||
lut_siz_full = next_val(&lp1);
|
||||
lut_full = (uint8_t*)malloc(lut_siz_full);
|
||||
lut_cmd[0] = next_hex(&lp1);
|
||||
}
|
||||
} else if (section == 'l') {
|
||||
lp1++;
|
||||
lut_siz_partial = next_val(&lp1);
|
||||
lut_partial = (uint8_t*)malloc(lut_siz_partial);
|
||||
lut_cmd[0] = next_hex(&lp1);
|
||||
}
|
||||
if (*lp1 == ',') lp1++;
|
||||
}
|
||||
|
@ -182,7 +212,6 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
|
|||
reset = next_val(&lp1);
|
||||
spi_miso = next_val(&lp1);
|
||||
spi_speed = next_val(&lp1);
|
||||
|
||||
section = 0;
|
||||
} else if (!strncmp(ibuff, "PAR", 3)) {
|
||||
#ifdef USE_ESP32_S3
|
||||
|
@ -256,13 +285,42 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
|
|||
}
|
||||
} else {
|
||||
while (1) {
|
||||
if (dsp_ncmds >= sizeof(dsp_cmds)) break;
|
||||
if (!str2c(&lp1, ibuff, sizeof(ibuff))) {
|
||||
dsp_cmds[dsp_ncmds++] = strtol(ibuff, 0, 16);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
if (dsp_ncmds >= sizeof(dsp_cmds)) break;
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
// epaper full update cmds
|
||||
if (!epcoffs_full) {
|
||||
epcoffs_full = dsp_ncmds;
|
||||
epc_full_cnt = 0;
|
||||
}
|
||||
while (1) {
|
||||
if (epc_full_cnt >= sizeof(dsp_cmds)) break;
|
||||
if (!str2c(&lp1, ibuff, sizeof(ibuff))) {
|
||||
dsp_cmds[epcoffs_full + epc_full_cnt++] = strtol(ibuff, 0, 16);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
// epaper partial update cmds
|
||||
if (!epcoffs_part) {
|
||||
epcoffs_part = dsp_ncmds + epc_full_cnt;
|
||||
epc_part_cnt = 0;
|
||||
}
|
||||
while (1) {
|
||||
if (epc_part_cnt >= sizeof(dsp_cmds)) break;
|
||||
if (!str2c(&lp1, ibuff, sizeof(ibuff))) {
|
||||
dsp_cmds[epcoffs_part + epc_part_cnt++] = strtol(ibuff, 0, 16);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -338,6 +396,11 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
|
|||
sa_mode = next_val(&lp1);
|
||||
}
|
||||
break;
|
||||
case 'a':
|
||||
saw_1 = next_hex(&lp1);
|
||||
saw_2 = next_hex(&lp1);
|
||||
saw_3 = next_hex(&lp1);
|
||||
break;
|
||||
case 'P':
|
||||
col_mode = next_val(&lp1);
|
||||
break;
|
||||
|
@ -350,34 +413,43 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
|
|||
break;
|
||||
case 'L':
|
||||
if (!lut_num) {
|
||||
if (!lut_full) {
|
||||
break;
|
||||
}
|
||||
while (1) {
|
||||
if (!str2c(&lp1, ibuff, sizeof(ibuff))) {
|
||||
lut_full[lutfsize++] = strtol(ibuff, 0, 16);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
if (lutfsize >= LUTMAXSIZE) break;
|
||||
if (lutfsize >= lut_siz_full) break;
|
||||
}
|
||||
} else {
|
||||
uint8_t index = lut_num - 1;
|
||||
if (!lut_array[index]) {
|
||||
break;
|
||||
}
|
||||
while (1) {
|
||||
if (!str2c(&lp1, ibuff, sizeof(ibuff))) {
|
||||
lut_array[lut_cnt[index]++][index] = strtol(ibuff, 0, 16);
|
||||
lut_array[index][lut_cnt[index]++] = strtol(ibuff, 0, 16);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
if (lut_cnt[index] >= LUTMAXSIZE) break;
|
||||
if (lut_cnt[index] >= lut_siz[index]) break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
if (!lut_partial) {
|
||||
break;
|
||||
}
|
||||
while (1) {
|
||||
if (!str2c(&lp1, ibuff, sizeof(ibuff))) {
|
||||
lut_partial[lutpsize++] = strtol(ibuff, 0, 16);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
if (lutpsize >= LUTMAXSIZE) break;
|
||||
if (lutpsize >= lut_siz_partial) break;
|
||||
}
|
||||
break;
|
||||
case 'T':
|
||||
|
@ -452,8 +524,8 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
|
|||
Serial.printf("Rot 0: %x,%x - %d - %d\n", madctrl, rot[0], x_addr_offs[0], y_addr_offs[0]);
|
||||
|
||||
if (ep_mode == 1) {
|
||||
Serial.printf("LUT_Partial : %d\n", lutpsize);
|
||||
Serial.printf("LUT_Full : %d\n", lutfsize);
|
||||
Serial.printf("LUT_Partial : %d - %d - %x - %d - %d\n", lut_siz_partial, lutpsize, lut_cmd[0], epcoffs_part, epc_part_cnt);
|
||||
Serial.printf("LUT_Full : %d - %d - %x - %d - %d\n", lut_siz_full, lutfsize, lut_cmd[0], epcoffs_full, epc_full_cnt);
|
||||
}
|
||||
if (ep_mode == 2) {
|
||||
Serial.printf("LUT_SIZE 1: %d\n", lut_cnt[0]);
|
||||
|
@ -533,11 +605,144 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("Dsp class init complete\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void uDisplay::delay_arg(uint32_t args) {
|
||||
uint32_t delay_ms = 0;
|
||||
switch (args & 0xE0) {
|
||||
case 0x80: delay_ms = 150; break;
|
||||
case 0xA0: delay_ms = 10; break;
|
||||
case 0xE0: delay_ms = 500; break;
|
||||
}
|
||||
if (delay_ms > 0) {
|
||||
delay(delay_ms);
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("delay %d ms\n", delay_ms);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// epaper pseudo opcodes
|
||||
#define EP_RESET 0x60
|
||||
#define EP_LUT_FULL 0x61
|
||||
#define EP_LUT_PARTIAL 0x62
|
||||
#define EP_WAITIDLE 0x63
|
||||
#define EP_SET_MEM_AREA 0x64
|
||||
#define EP_SET_MEM_PTR 0x65
|
||||
#define EP_SEND_DATA 0x66
|
||||
#define EP_CLR_FRAME 0x67
|
||||
#define EP_SEND_FRAME 0x68
|
||||
|
||||
void uDisplay::send_spi_cmds(uint16_t cmd_offset, uint16_t cmd_size) {
|
||||
uint16_t index = 0;
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("start send cmd table\n");
|
||||
#endif
|
||||
while (1) {
|
||||
uint8_t iob;
|
||||
SPI_CS_LOW
|
||||
iob = dsp_cmds[cmd_offset++];
|
||||
index++;
|
||||
if (ep_mode == 1 && iob >= EP_RESET) {
|
||||
// epaper pseudo opcodes
|
||||
uint8_t args = dsp_cmds[cmd_offset++];
|
||||
index++;
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("cmd, args %02x, %d ", iob, args & 0x1f);
|
||||
#endif
|
||||
switch (iob) {
|
||||
case EP_RESET:
|
||||
if (args & 1) {
|
||||
iob = dsp_cmds[cmd_offset++];
|
||||
index++;
|
||||
}
|
||||
reset_pin(iob, iob);
|
||||
break;
|
||||
case EP_LUT_FULL:
|
||||
SetLut(lut_full);
|
||||
ep_update_mode = DISPLAY_INIT_FULL;
|
||||
break;
|
||||
case EP_LUT_PARTIAL:
|
||||
SetLut(lut_partial);
|
||||
ep_update_mode = DISPLAY_INIT_PARTIAL;
|
||||
break;
|
||||
case EP_WAITIDLE:
|
||||
if (args & 1) {
|
||||
iob = dsp_cmds[cmd_offset++];
|
||||
index++;
|
||||
}
|
||||
//delay(iob * 10);
|
||||
delay_sync(iob * 10);
|
||||
break;
|
||||
case EP_SET_MEM_AREA:
|
||||
SetMemoryArea(0, 0, gxs - 1, gys - 1);
|
||||
break;
|
||||
case EP_SET_MEM_PTR:
|
||||
SetMemoryPointer(0, 0);
|
||||
break;
|
||||
case EP_SEND_DATA:
|
||||
Send_EP_Data();
|
||||
break;
|
||||
case EP_CLR_FRAME:
|
||||
ClearFrameMemory(0xFF);
|
||||
break;
|
||||
case EP_SEND_FRAME:
|
||||
SetFrameMemory(framebuffer);
|
||||
break;
|
||||
}
|
||||
#ifdef UDSP_DEBUG
|
||||
if (args & 1) {
|
||||
Serial.printf("%02x ", iob );
|
||||
}
|
||||
Serial.printf("\n");
|
||||
#endif
|
||||
if (args & 0x80) { // delay after the command
|
||||
delay_arg(args);
|
||||
}
|
||||
} else {
|
||||
ulcd_command(iob);
|
||||
uint8_t args = dsp_cmds[cmd_offset++];
|
||||
index++;
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("cmd, args %02x, %d ", iob, args & 0x1f);
|
||||
#endif
|
||||
for (uint32_t cnt = 0; cnt < (args & 0x1f); cnt++) {
|
||||
iob = dsp_cmds[cmd_offset++];
|
||||
index++;
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("%02x ", iob );
|
||||
#endif
|
||||
if (!allcmd_mode) {
|
||||
ulcd_data8(iob);
|
||||
} else {
|
||||
ulcd_command(iob);
|
||||
}
|
||||
}
|
||||
SPI_CS_HIGH
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("\n");
|
||||
#endif
|
||||
if (args & 0x80) { // delay after the command
|
||||
delay_arg(args);
|
||||
}
|
||||
}
|
||||
if (index >= cmd_size) break;
|
||||
}
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("end send cmd table\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
Renderer *uDisplay::Init(void) {
|
||||
extern bool UsePSRAM(void);
|
||||
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("Dsp Init 1 start \n");
|
||||
#endif
|
||||
|
||||
// for any bpp below native 16 bits, we allocate a local framebuffer to copy into
|
||||
if (ep_mode || bpp < 16) {
|
||||
if (framebuffer) free(framebuffer);
|
||||
|
@ -549,10 +754,9 @@ Renderer *uDisplay::Init(void) {
|
|||
} else {
|
||||
framebuffer = (uint8_t*)calloc((gxs * gys * bpp) / 8, 1);
|
||||
}
|
||||
#endif
|
||||
#endif // ESP8266
|
||||
}
|
||||
|
||||
|
||||
if (interface == _UDSP_I2C) {
|
||||
if (wire_n == 0) {
|
||||
wire = &Wire;
|
||||
|
@ -561,7 +765,7 @@ Renderer *uDisplay::Init(void) {
|
|||
if (wire_n == 1) {
|
||||
wire = &Wire1;
|
||||
}
|
||||
#endif
|
||||
#endif // ESP32
|
||||
wire->begin(i2c_sda, i2c_scl); // TODO: aren't I2C buses already initialized? Shouldn't this be moved to display driver?
|
||||
|
||||
#ifdef UDSP_DEBUG
|
||||
|
@ -604,6 +808,10 @@ Renderer *uDisplay::Init(void) {
|
|||
digitalWrite(spi_clk, LOW);
|
||||
pinMode(spi_mosi, OUTPUT);
|
||||
digitalWrite(spi_mosi, LOW);
|
||||
if (spi_miso >= 0) {
|
||||
pinMode(spi_miso, INPUT_PULLUP);
|
||||
busy_pin = spi_miso;
|
||||
}
|
||||
}
|
||||
#endif // ESP8266
|
||||
|
||||
|
@ -628,6 +836,13 @@ Renderer *uDisplay::Init(void) {
|
|||
digitalWrite(spi_clk, LOW);
|
||||
pinMode(spi_mosi, OUTPUT);
|
||||
digitalWrite(spi_mosi, LOW);
|
||||
if (spi_miso >= 0) {
|
||||
busy_pin = spi_miso;
|
||||
pinMode(spi_miso, INPUT_PULLUP);
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("Dsp busy pin: %d\n", busy_pin);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif // ESP32
|
||||
|
||||
|
@ -639,56 +854,11 @@ Renderer *uDisplay::Init(void) {
|
|||
pinMode(reset, OUTPUT);
|
||||
digitalWrite(reset, HIGH);
|
||||
delay(50);
|
||||
digitalWrite(reset, LOW);
|
||||
delay(50);
|
||||
digitalWrite(reset, HIGH);
|
||||
delay(200);
|
||||
reset_pin(50, 200);
|
||||
}
|
||||
|
||||
uint16_t index = 0;
|
||||
while (1) {
|
||||
uint8_t iob;
|
||||
SPI_CS_LOW
|
||||
send_spi_cmds(0, dsp_ncmds);
|
||||
|
||||
iob = dsp_cmds[index++];
|
||||
ulcd_command(iob);
|
||||
|
||||
uint8_t args = dsp_cmds[index++];
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("cmd, args %02x, %d ", iob, args&0x1f);
|
||||
#endif
|
||||
for (uint32_t cnt = 0; cnt < (args & 0x1f); cnt++) {
|
||||
iob = dsp_cmds[index++];
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("%02x ", iob );
|
||||
#endif
|
||||
if (!allcmd_mode) {
|
||||
ulcd_data8(iob);
|
||||
} else {
|
||||
ulcd_command(iob);
|
||||
}
|
||||
}
|
||||
SPI_CS_HIGH
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("\n");
|
||||
#endif
|
||||
if (args & 0x80) { // delay after the command
|
||||
uint32_t delay_ms = 0;
|
||||
switch (args & 0xE0) {
|
||||
case 0x80: delay_ms = 150; break;
|
||||
case 0xA0: delay_ms = 10; break;
|
||||
case 0xE0: delay_ms = 500; break;
|
||||
}
|
||||
if (delay_ms > 0) {
|
||||
delay(delay_ms);
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("delay %d ms\n", delay_ms);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
if (index >= dsp_ncmds) break;
|
||||
}
|
||||
SPI_END_TRANSACTION
|
||||
|
||||
}
|
||||
|
@ -795,10 +965,7 @@ Renderer *uDisplay::Init(void) {
|
|||
pinMode(reset, OUTPUT);
|
||||
digitalWrite(reset, HIGH);
|
||||
delay(50);
|
||||
digitalWrite(reset, LOW);
|
||||
delay(50);
|
||||
digitalWrite(reset, HIGH);
|
||||
delay(200);
|
||||
reset_pin(50, 200);
|
||||
}
|
||||
|
||||
esp_lcd_i80_bus_config_t bus_config = {
|
||||
|
@ -900,8 +1067,8 @@ Renderer *uDisplay::Init(void) {
|
|||
|
||||
// must init luts on epaper
|
||||
if (ep_mode) {
|
||||
Init_EPD(DISPLAY_INIT_FULL);
|
||||
if (ep_mode == 1) Init_EPD(DISPLAY_INIT_PARTIAL);
|
||||
if (ep_mode == 2) Init_EPD(DISPLAY_INIT_FULL);
|
||||
//if (ep_mode == 1) Init_EPD(DISPLAY_INIT_PARTIAL);
|
||||
}
|
||||
|
||||
#ifdef UDSP_DEBUG
|
||||
|
@ -910,18 +1077,23 @@ Renderer *uDisplay::Init(void) {
|
|||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void uDisplay::DisplayInit(int8_t p, int8_t size, int8_t rot, int8_t font) {
|
||||
if (p != DISPLAY_INIT_MODE && ep_mode) {
|
||||
ep_update_mode = p;
|
||||
if (p == DISPLAY_INIT_PARTIAL) {
|
||||
if (lutpsize) {
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("init partial epaper mode\n");
|
||||
#endif
|
||||
SetLut(lut_partial);
|
||||
Updateframe_EPD();
|
||||
delay(lutptime * 10);
|
||||
delay_sync(lutptime * 10);
|
||||
}
|
||||
return;
|
||||
} else if (p == DISPLAY_INIT_FULL) {
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("init full epaper mode\n");
|
||||
#endif
|
||||
if (lutfsize) {
|
||||
SetLut(lut_full);
|
||||
Updateframe_EPD();
|
||||
|
@ -930,7 +1102,7 @@ void uDisplay::DisplayInit(int8_t p, int8_t size, int8_t rot, int8_t font) {
|
|||
ClearFrame_42();
|
||||
DisplayFrame_42();
|
||||
}
|
||||
delay(lutftime * 10);
|
||||
delay_sync(lutftime * 10);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
@ -953,6 +1125,36 @@ void uDisplay::DisplayInit(int8_t p, int8_t size, int8_t rot, int8_t font) {
|
|||
}
|
||||
}
|
||||
|
||||
void uDisplay::reset_pin(int32_t msl, int32_t msh) {
|
||||
if (reset > 0) {
|
||||
digitalWrite(reset, LOW);
|
||||
delay(msl);
|
||||
digitalWrite(reset, HIGH);
|
||||
delay(msh);
|
||||
}
|
||||
}
|
||||
|
||||
#define UDSP_BUSY_TIMEOUT 3000
|
||||
// epaper sync or delay
|
||||
void uDisplay::delay_sync(int32_t ms) {
|
||||
uint8_t busy_level = HIGH;
|
||||
if (lvgl_param.busy_invert) {
|
||||
busy_level = LOW;
|
||||
}
|
||||
uint32_t time = millis();
|
||||
if (busy_pin > 0) {
|
||||
|
||||
while (digitalRead(busy_pin) == busy_level) {
|
||||
delay(1);
|
||||
if ((millis() - time) > UDSP_BUSY_TIMEOUT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
delay(ms);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uDisplay::ulcd_command(uint8_t val) {
|
||||
|
||||
|
@ -1462,12 +1664,16 @@ void uDisplay::Splash(void) {
|
|||
|
||||
if (ep_mode) {
|
||||
Updateframe();
|
||||
delay(lut3time * 10);
|
||||
delay_sync(lut3time * 10);
|
||||
}
|
||||
setTextFont(splash_font);
|
||||
setTextSize(splash_size);
|
||||
DrawStringAt(splash_xp, splash_yp, dname, fg_col, 0);
|
||||
Updateframe();
|
||||
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("draw splash\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void uDisplay::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
|
||||
|
@ -2116,7 +2322,7 @@ uint32_t uDisplay::str2c(char **sp, char *vp, uint32_t len) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
uint8_t slen = strlen(lp);
|
||||
uint16_t slen = strlen(lp);
|
||||
if (slen) {
|
||||
strlcpy(vp, *sp, len);
|
||||
*sp = lp + slen;
|
||||
|
@ -2320,9 +2526,9 @@ void uDisplay::Init_EPD(int8_t p) {
|
|||
ClearFrame_42();
|
||||
}
|
||||
if (p == DISPLAY_INIT_PARTIAL) {
|
||||
delay(lutptime * 10);
|
||||
delay_sync(lutptime * 10);
|
||||
} else {
|
||||
delay(lutftime * 10);
|
||||
delay_sync(lutftime * 10);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2338,58 +2544,66 @@ void uDisplay::ClearFrameMemory(unsigned char color) {
|
|||
|
||||
void uDisplay::SetLuts(void) {
|
||||
uint8_t index, count;
|
||||
for (index = 0; index < 5; index++) {
|
||||
spi_command_EPD(lut_cmd[index]); //vcom
|
||||
for (index = 0; index < MAX_LUTS; index++) {
|
||||
spi_command_EPD(lut_cmd[index]);
|
||||
for (count = 0; count < lut_cnt[index]; count++) {
|
||||
spi_data8_EPD(lut_array[count][index]);
|
||||
spi_data8_EPD(lut_array[index][count]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void uDisplay::DisplayFrame_42(void) {
|
||||
uint16_t Width, Height;
|
||||
Width = (gxs % 8 == 0) ? (gxs / 8 ): (gxs / 8 + 1);
|
||||
Height = gys;
|
||||
|
||||
spi_command_EPD(saw_1);
|
||||
for(int i = 0; i < gxs / 8 * gys; i++) {
|
||||
spi_data8_EPD(0xFF);
|
||||
}
|
||||
delay(2);
|
||||
|
||||
spi_command_EPD(saw_2);
|
||||
for (uint16_t j = 0; j < Height; j++) {
|
||||
for (uint16_t i = 0; i < Width; i++) {
|
||||
spi_data8_EPD(framebuffer[i + j * Width] ^ 0xff);
|
||||
}
|
||||
for(int i = 0; i < gxs / 8 * gys; i++) {
|
||||
spi_data8_EPD(framebuffer[i]^0xff);
|
||||
}
|
||||
delay(2);
|
||||
|
||||
SetLuts();
|
||||
|
||||
spi_command_EPD(saw_3);
|
||||
delay(100);
|
||||
delay_sync(100);
|
||||
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("EPD Diplayframe\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void uDisplay::ClearFrame_42(void) {
|
||||
uint16_t Width, Height;
|
||||
Width = (gxs % 8 == 0)? (gxs / 8 ): (gxs / 8 + 1);
|
||||
Height = gys;
|
||||
|
||||
|
||||
void uDisplay::ClearFrame_42(void) {
|
||||
spi_command_EPD(saw_1);
|
||||
for (uint16_t j = 0; j < Height; j++) {
|
||||
for (uint16_t i = 0; i < Width; i++) {
|
||||
for (uint16_t j = 0; j < gys; j++) {
|
||||
for (uint16_t i = 0; i < gxs; i++) {
|
||||
spi_data8_EPD(0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
spi_command_EPD(saw_2);
|
||||
for (uint16_t j = 0; j < Height; j++) {
|
||||
for (uint16_t i = 0; i < Width; i++) {
|
||||
for (uint16_t j = 0; j < gys; j++) {
|
||||
for (uint16_t i = 0; i < gxs; i++) {
|
||||
spi_data8_EPD(0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
spi_command_EPD(saw_3);
|
||||
delay(100);
|
||||
delay_sync(100);
|
||||
#ifdef UDSP_DEBUG
|
||||
Serial.printf("EPD Clearframe\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void uDisplay::SetLut(const unsigned char* lut) {
|
||||
spi_command_EPD(WRITE_LUT_REGISTER);
|
||||
//spi_command_EPD(WRITE_LUT_REGISTER);
|
||||
spi_command_EPD(lut_cmd[0]);
|
||||
/* the length of look-up table is 30 bytes */
|
||||
for (int i = 0; i < lutfsize; i++) {
|
||||
spi_data8_EPD(lut[i]);
|
||||
|
@ -2398,8 +2612,21 @@ void uDisplay::SetLut(const unsigned char* lut) {
|
|||
|
||||
void uDisplay::Updateframe_EPD(void) {
|
||||
if (ep_mode == 1) {
|
||||
SetFrameMemory(framebuffer, 0, 0, gxs, gys);
|
||||
DisplayFrame_29();
|
||||
switch (ep_update_mode) {
|
||||
case DISPLAY_INIT_PARTIAL:
|
||||
if (epc_part_cnt) {
|
||||
send_spi_cmds(epcoffs_part, epc_part_cnt);
|
||||
}
|
||||
break;
|
||||
case DISPLAY_INIT_FULL:
|
||||
if (epc_full_cnt) {
|
||||
send_spi_cmds(epcoffs_full, epc_full_cnt);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
SetFrameMemory(framebuffer, 0, 0, gxs, gys);
|
||||
DisplayFrame_29();
|
||||
}
|
||||
} else {
|
||||
DisplayFrame_42();
|
||||
}
|
||||
|
@ -2443,6 +2670,28 @@ void uDisplay::SetMemoryPointer(int x, int y) {
|
|||
spi_data8_EPD((y >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void uDisplay::Send_EP_Data() {
|
||||
for (int i = 0; i < gys / 8 * gys; i++) {
|
||||
spi_data8_EPD(framebuffer[i]^0xff);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void uDisplay::Send_EP_Data() {
|
||||
uint16_t image_width = gxs & 0xFFF8;
|
||||
uint16_t x = 0;
|
||||
uint16_t y = 0;
|
||||
uint16_t x_end = gxs - 1;
|
||||
uint16_t y_end = gys - 1;
|
||||
|
||||
for (uint16_t j = 0; j < y_end - y + 1; j++) {
|
||||
for (uint16_t i = 0; i < (x_end - x + 1) / 8; i++) {
|
||||
spi_data8_EPD(framebuffer[i + j * (image_width / 8)]^0xff);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void uDisplay::SetFrameMemory(
|
||||
const unsigned char* image_buffer,
|
||||
uint16_t x,
|
||||
|
|
|
@ -48,6 +48,8 @@ static inline void gpio_lo(int_fast8_t pin) { if (pin >= 0) *get_gpio_lo_reg(pin
|
|||
#define UDISP1_WHITE 1
|
||||
#define UDISP1_BLACK 0
|
||||
|
||||
#define MAX_LUTS 5
|
||||
|
||||
#define DISPLAY_INIT_MODE 0
|
||||
#define DISPLAY_INIT_PARTIAL 1
|
||||
#define DISPLAY_INIT_FULL 2
|
||||
|
@ -107,7 +109,6 @@ enum uColorType { uCOLOR_BW, uCOLOR_COLOR };
|
|||
#define SPI_DC_LOW if (spi_dc >= 0) GPIO_CLR_SLOW(spi_dc);
|
||||
#define SPI_DC_HIGH if (spi_dc >= 0) GPIO_SET_SLOW(spi_dc);
|
||||
|
||||
#define LUTMAXSIZE 64
|
||||
|
||||
#ifdef USE_ESP32_S3
|
||||
struct esp_lcd_i80_bus_t {
|
||||
|
@ -245,7 +246,7 @@ class uDisplay : public Renderer {
|
|||
uint8_t i2c_page_start;
|
||||
uint8_t i2c_page_end;
|
||||
int8_t reset;
|
||||
uint8_t dsp_cmds[128];
|
||||
uint8_t dsp_cmds[256];
|
||||
uint8_t dsp_ncmds;
|
||||
uint8_t dsp_on;
|
||||
uint8_t dsp_off;
|
||||
|
@ -289,16 +290,27 @@ class uDisplay : public Renderer {
|
|||
uint8_t dim_op;
|
||||
uint8_t lutfsize;
|
||||
uint8_t lutpsize;
|
||||
uint16_t lutftime;
|
||||
int16_t lutftime;
|
||||
int8_t busy_pin;
|
||||
uint16_t lutptime;
|
||||
uint16_t lut3time;
|
||||
uint16_t lut_num;
|
||||
uint8_t ep_mode;
|
||||
uint8_t lut_full[LUTMAXSIZE];
|
||||
uint8_t lut_partial[LUTMAXSIZE];
|
||||
uint8_t lut_array[LUTMAXSIZE][5];
|
||||
uint8_t lut_cnt[5];
|
||||
uint8_t lut_cmd[5];
|
||||
uint8_t ep_update_mode;
|
||||
uint8_t *lut_full;
|
||||
uint8_t lut_siz_full;
|
||||
uint8_t *lut_partial;
|
||||
uint8_t lut_siz_partial;
|
||||
|
||||
uint8_t epcoffs_full;
|
||||
uint8_t epc_full_cnt;
|
||||
uint8_t epcoffs_part;
|
||||
uint8_t epc_part_cnt;
|
||||
|
||||
uint8_t *lut_array[MAX_LUTS];
|
||||
uint8_t lut_cnt[MAX_LUTS];
|
||||
uint8_t lut_cmd[MAX_LUTS];
|
||||
uint8_t lut_siz[MAX_LUTS];
|
||||
uint16_t seta_xp1;
|
||||
uint16_t seta_xp2;
|
||||
uint16_t seta_yp1;
|
||||
|
@ -308,6 +320,11 @@ class uDisplay : public Renderer {
|
|||
int16_t rotmap_ymin;
|
||||
int16_t rotmap_ymax;
|
||||
void pushColorsMono(uint16_t *data, uint16_t len, bool rgb16_swap = false);
|
||||
void delay_sync(int32_t time);
|
||||
void reset_pin(int32_t delayl, int32_t delayh);
|
||||
void delay_arg(uint32_t arg);
|
||||
void Send_EP_Data(void);
|
||||
void send_spi_cmds(uint16_t cmd_offset, uint16_t cmd_size);
|
||||
|
||||
#ifdef USE_ESP32_S3
|
||||
int8_t par_cs;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
:H,E-PAPER-29,128,296,1,SPI,1,*,*,*,*,*,*,*,10
|
||||
:H,E-PAPER-29-V1,128,296,1,SPI,3,*,*,*,*,*,*,*,10
|
||||
:S,1,1,1,0,10,10
|
||||
:I
|
||||
01,3,27,01,00
|
||||
|
@ -7,10 +7,23 @@
|
|||
3A,1,1A
|
||||
3B,1,08
|
||||
11,1,03
|
||||
:L
|
||||
62,0
|
||||
:f
|
||||
61,0
|
||||
68,0
|
||||
22,1,c4
|
||||
20,0
|
||||
ff,0
|
||||
:p
|
||||
62,0
|
||||
68,0
|
||||
22,1,c4
|
||||
20,0
|
||||
ff,0
|
||||
:L,30,32
|
||||
02,02,01,11,12,12,22,22,66,69,69,59,58,99,99
|
||||
88,00,00,00,00,F8,B4,13,51,35,51,51,19,01,00
|
||||
:l
|
||||
:l,30,32
|
||||
10,18,18,08,18,18,08,00,00,00,00,00,00,00,00
|
||||
00,00,00,00,00,13,14,44,12,00,00,00,00,00,00
|
||||
:T,350,35,10
|
|
@ -0,0 +1,96 @@
|
|||
:H,E-PAPER-29-V2,128,296,1,SPI,4,*,*,*,*,*,*,*,10
|
||||
:S,1,1,1,0,10,10
|
||||
:I
|
||||
12,0
|
||||
63,1,80
|
||||
01,3,27,01,00
|
||||
11,1,03
|
||||
64,0
|
||||
21,2,00,80
|
||||
65,0
|
||||
63,1,80
|
||||
61,0
|
||||
63,1,80
|
||||
3f,1,22
|
||||
03,1,17
|
||||
04,3,41,00,32
|
||||
2c,1,36
|
||||
67,0
|
||||
22,1,c7;
|
||||
20,0
|
||||
63,1,80
|
||||
24,0
|
||||
66,0
|
||||
22,1,c7
|
||||
20,0
|
||||
63,1,80
|
||||
62
|
||||
:f
|
||||
64,0
|
||||
65,0
|
||||
24,0
|
||||
66,0
|
||||
22,1,c7
|
||||
20,0
|
||||
63,1,80
|
||||
:p
|
||||
60,1,2
|
||||
62,0
|
||||
63,1,80
|
||||
37,0a,00,00,00,00,00,40,00,00,00,00
|
||||
3c,1,80
|
||||
22,1,c0
|
||||
20,0
|
||||
63,1,80
|
||||
64,0
|
||||
65,0
|
||||
24,0
|
||||
66,0
|
||||
22,1,0f
|
||||
20,0
|
||||
63,1,80
|
||||
62,0
|
||||
|
||||
:L,153,32
|
||||
80,66,00,00,00,00,00,00,40,00,00,00
|
||||
10,66,00,00,00,00,00,00,20,00,00,00
|
||||
80,66,00,00,00,00,00,00,40,00,00,00
|
||||
10,66,00,00,00,00,00,00,20,00,00,00
|
||||
00,00,00,00,00,00,00,00,00,00,00,00
|
||||
14,08,00,00,00,00,01
|
||||
0A,0A,00,0A,0A,00,01
|
||||
00,00,00,00,00,00,00
|
||||
00,00,00,00,00,00,00
|
||||
00,00,00,00,00,00,00
|
||||
00,00,00,00,00,00,00
|
||||
00,00,00,00,00,00,00
|
||||
00,00,00,00,00,00,00
|
||||
14,08,00,01,00,00,01
|
||||
00,00,00,00,00,00,01
|
||||
00,00,00,00,00,00,00
|
||||
00,00,00,00,00,00,00
|
||||
44,44,44,44,44,44,00,00,00
|
||||
|
||||
:l,153,32
|
||||
00,40,00,00,00,00,00,00,00,00,00,00
|
||||
80,80,00,00,00,00,00,00,00,00,00,00
|
||||
40,40,00,00,00,00,00,00,00,00,00,00
|
||||
00,80,00,00,00,00,00,00,00,00,00,00
|
||||
00,00,00,00,00,00,00,00,00,00,00,00
|
||||
0A,00,00,00,00,00,02
|
||||
01,00,00,00,00,00,00
|
||||
01,00,00,00,00,00,00
|
||||
00,00,00,00,00,00,00
|
||||
00,00,00,00,00,00,00
|
||||
00,00,00,00,00,00,00
|
||||
00,00,00,00,00,00,00
|
||||
00,00,00,00,00,00,00
|
||||
00,00,00,00,00,00,00
|
||||
00,00,00,00,00,00,00
|
||||
00,00,00,00,00,00,00
|
||||
00,00,00,00,00,00,00
|
||||
22,22,22,22,22,22,00,00,00
|
||||
|
||||
|
||||
:T,350,35,10
|
||||
#
|
|
@ -1,25 +1,26 @@
|
|||
:H,E-PAPER-42,400,300,1,SPI,1,*,*,*,*,*,*,*,10
|
||||
:H,E-PAPER-42,400,300,1,SPI,4,*,*,*,*,*,*,*,10
|
||||
:S,1,1,1,0,10,10
|
||||
:B,60,8
|
||||
:I
|
||||
01,5,03,00,2b,2b,03
|
||||
01,5,03,00,2b,2b,ff
|
||||
06,3,17,17,17
|
||||
04,80
|
||||
00,1,3F
|
||||
30,1,3C
|
||||
61,4,01,90,01,2C
|
||||
82,1,28
|
||||
82,1,12
|
||||
50,1,97
|
||||
:A,10,13,12
|
||||
:a,10,13,12
|
||||
:T,450,10,450
|
||||
:L1,20
|
||||
00,17,00,00,00,02
|
||||
:L1,44,20
|
||||
40,17,00,00,00,02
|
||||
00,17,17,00,00,02
|
||||
00,0A,01,00,00,01
|
||||
00,0E,0E,00,00,02
|
||||
00,00,00,00,00,00
|
||||
00,00,00,00,00,00
|
||||
00,00,00,00,00,00,00,00
|
||||
:L2,21
|
||||
:L2,42,21
|
||||
40,17,00,00,00,02
|
||||
90,17,17,00,00,02
|
||||
40,0A,01,00,00,01
|
||||
|
@ -27,15 +28,15 @@ A0,0E,0E,00,00,02
|
|||
00,00,00,00,00,00
|
||||
00,00,00,00,00,00
|
||||
00,00,00,00,00,00
|
||||
:L3,22
|
||||
:L3,42,22
|
||||
40,17,00,00,00,02
|
||||
90,17,17,00,00,02
|
||||
A0,0A,01,00,00,01
|
||||
00,0E,0E,00,00,02
|
||||
40,0A,01,00,00,01
|
||||
A0,0E,0E,00,00,02
|
||||
00,00,00,00,00,00
|
||||
00,00,00,00,00,00
|
||||
00,00,00,00,00,00
|
||||
:L4,23
|
||||
:L4,42,23
|
||||
80,17,00,00,00,02
|
||||
90,17,17,00,00,02
|
||||
80,0A,01,00,00,01
|
||||
|
@ -43,7 +44,7 @@ A0,0A,01,00,00,01
|
|||
00,00,00,00,00,00
|
||||
00,00,00,00,00,00
|
||||
00,00,00,00,00,00
|
||||
:L5,24
|
||||
:L5,42,24
|
||||
80,17,00,00,00,02
|
||||
90,17,17,00,00,02
|
||||
80,0A,01,00,00,01
|
||||
|
|
|
@ -50,7 +50,9 @@ extern uint16_t fg_color;
|
|||
extern uint16_t bg_color;
|
||||
#endif
|
||||
|
||||
#ifndef DISPDESC_SIZE
|
||||
#define DISPDESC_SIZE 1000
|
||||
#endif
|
||||
|
||||
void Core2DisplayPower(uint8_t on);
|
||||
void Core2DisplayDim(uint8_t dim);
|
||||
|
@ -94,6 +96,11 @@ int8_t cs;
|
|||
fp = ffsp->open(DISP_DESC_FILE, "r");
|
||||
if (fp > 0) {
|
||||
uint32_t size = fp.size();
|
||||
if (size > DISPDESC_SIZE - 50) {
|
||||
free(fbuff);
|
||||
fbuff = (char*)calloc(size + 50, 1);
|
||||
if (!fbuff) return 0;
|
||||
}
|
||||
fp.read((uint8_t*)fbuff, size);
|
||||
fp.close();
|
||||
ddesc = fbuff;
|
||||
|
@ -148,6 +155,7 @@ int8_t cs;
|
|||
if (fbuff) free(fbuff);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// now replace tasmota vars before passing to driver
|
||||
char *cp = strstr(ddesc, "I2C");
|
||||
if (cp) {
|
||||
|
@ -296,6 +304,7 @@ int8_t cs;
|
|||
delete renderer;
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("DSP: reinit"));
|
||||
}
|
||||
|
||||
udisp = new uDisplay(ddesc);
|
||||
|
||||
// checck for touch option TI1 or TI2
|
||||
|
|
Loading…
Reference in New Issue