From cad9d5fdd821885adcd20fd67bf071331532bfd7 Mon Sep 17 00:00:00 2001 From: gemu Date: Sat, 7 Oct 2023 07:48:25 +0200 Subject: [PATCH] udisplay suport for GC3503V (#19682) * suport for GC3503V * disable debug --- lib/lib_display/UDisplay/uDisplay.cpp | 126 ++++++++++++++++++++++++-- lib/lib_display/UDisplay/uDisplay.h | 2 + 2 files changed, 120 insertions(+), 8 deletions(-) diff --git a/lib/lib_display/UDisplay/uDisplay.cpp b/lib/lib_display/UDisplay/uDisplay.cpp index 2f48351cc..6b2262f32 100755 --- a/lib/lib_display/UDisplay/uDisplay.cpp +++ b/lib/lib_display/UDisplay/uDisplay.cpp @@ -24,12 +24,17 @@ #include "esp8266toEsp32.h" #endif +#include "tasmota_options.h" extern int Cache_WriteBack_Addr(uint32_t addr, uint32_t size); //#define UDSP_DEBUG +#ifndef UDSP_LBSIZE +#define UDSP_LBSIZE 256 +#endif + #define renderer_swap(a, b) { int16_t t = a; a = b; b = t; } const uint16_t udisp_colors[]={UDISP_BLACK,UDISP_WHITE,UDISP_RED,UDISP_GREEN,UDISP_BLUE,UDISP_CYAN,UDISP_MAGENTA,\ @@ -133,7 +138,7 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) { } lut_partial = 0; lut_full = 0; - char linebuff[128]; + char linebuff[UDSP_LBSIZE]; while (*lp) { uint16_t llen = strlen_ln(lp); @@ -153,10 +158,50 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) { lp1++; section = *lp1++; if (section == 'I') { + if (*lp1 == 'C') { allcmd_mode = 1; lp1++; } + + if (*lp1 == 'S') { + // pecial case RGB with software SPI init clk,mosi,cs,reset + lp1++; + if (interface == _UDSP_RGB) { + // collect line and send directly + lp1++; + spi_nr = 4; + spi_dc = -1; + spi_miso = -1; + spi_clk = next_val(&lp1); + spi_mosi = next_val(&lp1); + spi_cs = next_val(&lp1); + reset = next_val(&lp1); + + pinMode(spi_cs, OUTPUT); + digitalWrite(spi_cs, HIGH); + + pinMode(spi_clk, OUTPUT); + digitalWrite(spi_clk, LOW); + + pinMode(spi_mosi, OUTPUT); + digitalWrite(spi_mosi, LOW); + + if (reset >= 0) { + pinMode(reset, OUTPUT); + digitalWrite(reset, HIGH); + delay(50); + reset_pin(50, 200); + } +#ifdef UDSP_DEBUG + Serial.printf("SSPI_MOSI : %d\n", spi_mosi); + Serial.printf("SSPI_SCLK : %d\n", spi_clk); + Serial.printf("SSPI_CS : %d\n", spi_cs); + Serial.printf("DSP RESET : %d\n", reset); +#endif + } + } + } else if (section == 'L') { if (*lp1 >= '1' && *lp1 <= '5') { lut_num = (*lp1 & 0x07); @@ -178,8 +223,9 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) { lut_cmd[0] = next_hex(&lp1); } if (*lp1 == ',') lp1++; + } - if (*lp1 != ':' && *lp1 != '\n' && *lp1 != ' ') { // Add space char + if (*lp1 && *lp1 != ':' && *lp1 != '\n' && *lp1 != ' ') { // Add space char switch (section) { case 'H': // header line @@ -286,12 +332,10 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) { break; case 'I': // init data - if (interface == _UDSP_I2C) { - dsp_cmds[dsp_ncmds++] = next_hex(&lp1); - if (!str2c(&lp1, ibuff, sizeof(ibuff))) { - dsp_cmds[dsp_ncmds++] = strtol(ibuff, 0, 16); - } - } else { + if (interface == _UDSP_RGB && spi_nr == 4) { + // special case RGB with SPI init + // collect line and send directly + dsp_ncmds = 0; while (1) { if (dsp_ncmds >= sizeof(dsp_cmds)) break; if (!str2c(&lp1, ibuff, sizeof(ibuff))) { @@ -300,6 +344,26 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) { break; } } + interface = _UDSP_SPI; + send_spi_icmds(dsp_ncmds); + interface = _UDSP_RGB; + + } else { + if (interface == _UDSP_I2C) { + dsp_cmds[dsp_ncmds++] = next_hex(&lp1); + if (!str2c(&lp1, ibuff, sizeof(ibuff))) { + dsp_cmds[dsp_ncmds++] = strtol(ibuff, 0, 16); + } + } 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; + } + } + } } break; case 'f': @@ -481,6 +545,7 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) { } } } + nextline: if (*lp == '\n' || *lp == ' ') { // Add space char lp++; } else { @@ -648,6 +713,50 @@ void uDisplay::delay_arg(uint32_t args) { extern int32_t ESP_ResetInfoReason(); +// special init for GC displays +void uDisplay::send_spi_icmds(uint16_t cmd_size) { +uint16_t index = 0; +uint16_t cmd_offset = 0; + + +#ifdef UDSP_DEBUG + Serial.printf("start send icmd table\n"); +#endif + while (1) { + uint8_t iob; + SPI_CS_LOW + iob = dsp_cmds[cmd_offset++]; + index++; + ulcd_command(iob); + uint8_t args = dsp_cmds[cmd_offset++]; + index++; +#ifdef UDSP_DEBUG + Serial.printf("cmd, args %02x, %d ", iob, args & 0x7f); +#endif + for (uint32_t cnt = 0; cnt < (args & 0x7f); cnt++) { + iob = dsp_cmds[cmd_offset++]; + index++; +#ifdef UDSP_DEBUG + Serial.printf("%02x ", iob); +#endif + ulcd_data8(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 icmd table\n"); +#endif + return; +} + + void uDisplay::send_spi_cmds(uint16_t cmd_offset, uint16_t cmd_size) { uint16_t index = 0; #ifdef UDSP_DEBUG @@ -2419,6 +2528,7 @@ void uDisplay::hw_write9(uint8_t val, uint8_t dc) { *dp = regvalue; REG_SET_BIT(SPI_CMD_REG(3), SPI_USR); while (REG_GET_FIELD(SPI_CMD_REG(3), SPI_USR)); + } #else diff --git a/lib/lib_display/UDisplay/uDisplay.h b/lib/lib_display/UDisplay/uDisplay.h index 88bcdce6f..238802dca 100755 --- a/lib/lib_display/UDisplay/uDisplay.h +++ b/lib/lib_display/UDisplay/uDisplay.h @@ -333,6 +333,8 @@ class uDisplay : public Renderer { void delay_arg(uint32_t arg); void Send_EP_Data(void); void send_spi_cmds(uint16_t cmd_offset, uint16_t cmd_size); + void send_spi_icmds(uint16_t cmd_size); + #ifdef USE_ESP32_S3 int8_t par_cs;