From 4e178389171bc34ea1e771c0611f453ee8ec5b45 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Wed, 14 Apr 2021 14:26:59 +0200 Subject: [PATCH 1/5] universal display update --- lib/lib_display/UDisplay/uDisplay.cpp | 590 ++++++++++++++++++++++---- lib/lib_display/UDisplay/uDisplay.h | 61 ++- tasmota/displaydesc/ILI9341_desc.txt | 38 +- tasmota/displaydesc/ILI9342_desc.txt | 36 ++ tasmota/displaydesc/ILI9488_desc.txt | 30 ++ tasmota/displaydesc/SH1106_desc.txt | 20 +- tasmota/displaydesc/SSD1351_desc.txt | 33 ++ tasmota/displaydesc/ST7789_desc.txt | 21 + tasmota/xdsp_17_universal.ino | 153 +++++-- 9 files changed, 817 insertions(+), 165 deletions(-) create mode 100644 tasmota/displaydesc/ILI9342_desc.txt create mode 100644 tasmota/displaydesc/ILI9488_desc.txt create mode 100644 tasmota/displaydesc/SSD1351_desc.txt create mode 100644 tasmota/displaydesc/ST7789_desc.txt diff --git a/lib/lib_display/UDisplay/uDisplay.cpp b/lib/lib_display/UDisplay/uDisplay.cpp index 0c15c8712..555b0059b 100644 --- a/lib/lib_display/UDisplay/uDisplay.cpp +++ b/lib/lib_display/UDisplay/uDisplay.cpp @@ -22,6 +22,7 @@ #include #include "uDisplay.h" +#define UDSP_DEBUG const uint16_t udisp_colors[]={UDISP_BLACK,UDISP_WHITE,UDISP_RED,UDISP_GREEN,UDISP_BLUE,UDISP_CYAN,UDISP_MAGENTA,\ UDISP_YELLOW,UDISP_NAVY,UDISP_DARKGREEN,UDISP_DARKCYAN,UDISP_MAROON,UDISP_PURPLE,UDISP_OLIVE,\ @@ -33,9 +34,15 @@ uint16_t uDisplay::GetColorFromIndex(uint8_t index) { } extern uint8_t *buffer; +extern uint8_t color_type; uDisplay::uDisplay(char *lp) : Renderer(800, 600) { // analyse decriptor + col_mode = 16; + sa_mode = 16; + saw_3 = 0xff; + dim_op = 0xff; + startline = 0xA1; uint8_t section = 0; dsp_ncmds = 0; char linebuff[128]; @@ -57,7 +64,9 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) { // id line lp1++; section = *lp1++; - } else { + if (*lp1 == ',') lp1++; + } + if (*lp1 != ':' && *lp1 != '\n') { switch (section) { case 'H': // header line @@ -69,6 +78,11 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) { gys = next_val(&lp1); setheight(gys); bpp = next_val(&lp1); + if (bpp == 1) { + color_type = uCOLOR_BW; + } else { + color_type = uCOLOR_COLOR; + } str2c(&lp1, ibuff, sizeof(ibuff)); if (!strncmp(ibuff, "I2C", 3)) { interface = _UDSP_I2C; @@ -90,7 +104,6 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) { spi_speed = next_val(&lp1); section = 0; - Serial.printf("%d %d %d %d %d %d %d %d\n", spi_cs, spi_clk, spi_mosi, spi_dc, bpanel, reset, spi_miso, spi_speed); } break; case 'S': @@ -127,29 +140,54 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) { } break; case 'o': - str2c(&lp1, ibuff, sizeof(ibuff)); - dsp_off = strtol(ibuff, 0, 16); + dsp_off = next_hex(&lp1); break; case 'O': - str2c(&lp1, ibuff, sizeof(ibuff)); - dsp_on = strtol(ibuff, 0, 16); + dsp_on = next_hex(&lp1); + break; + case 'R': + madctrl = next_hex(&lp1); + startline = next_hex(&lp1); break; case '0': - rot_0 = next_hex(&lp1); + rot[0] = next_hex(&lp1); + x_addr_offs[0] = next_hex(&lp1); + y_addr_offs[0] = next_hex(&lp1); + rot_t[0] = next_hex(&lp1); break; case '1': - rot_1 = next_hex(&lp1); + rot[1] = next_hex(&lp1); + x_addr_offs[1] = next_hex(&lp1); + y_addr_offs[1] = next_hex(&lp1); + rot_t[1] = next_hex(&lp1); break; case '2': - rot_2 = next_hex(&lp1); + rot[2] = next_hex(&lp1); + x_addr_offs[2] = next_hex(&lp1); + y_addr_offs[2] = next_hex(&lp1); + rot_t[2] = next_hex(&lp1); break; case '3': - rot_3 = next_hex(&lp1); + rot[3] = next_hex(&lp1); + x_addr_offs[3] = next_hex(&lp1); + y_addr_offs[3] = next_hex(&lp1); + rot_t[3] = next_hex(&lp1); break; case 'A': saw_1 = next_hex(&lp1); saw_2 = next_hex(&lp1); saw_3 = next_hex(&lp1); + sa_mode = next_val(&lp1); + break; + case 'P': + col_mode = next_val(&lp1); + break; + case 'i': + inv_off = next_hex(&lp1); + inv_on = next_hex(&lp1); + break; + case 'D': + dim_op = next_hex(&lp1); break; } } @@ -162,12 +200,32 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) { lp++; } } +#ifdef UDSP_DEBUG + Serial.printf("Nr. : %d\n", spi_nr); + Serial.printf("CS : %d\n", spi_cs); + Serial.printf("CLK : %d\n", spi_clk); + Serial.printf("MOSI: %d\n", spi_mosi); + Serial.printf("DC : %d\n", spi_dc); + Serial.printf("BPAN: %d\n", bpanel); + Serial.printf("RES : %d\n", reset); + Serial.printf("MISO: %d\n", spi_miso); + Serial.printf("SPED: %d\n", spi_speed*1000000); + Serial.printf("Pixels: %d\n", col_mode); + Serial.printf("SaMode: %d\n", sa_mode); + + + Serial.printf("opts: %02x,%02x,%02x\n", saw_3, dim_op, startline); + + Serial.printf("SetAddr : %x,%x,%x\n", saw_1, saw_2, saw_3); + + Serial.printf("Rot 0: %x,%x - %d - %d\n", madctrl, rot[0], x_addr_offs[0], y_addr_offs[0]); + +#endif } Renderer *uDisplay::Init(void) { - if (reset >= 0) { pinMode(reset, OUTPUT); digitalWrite(reset, HIGH); @@ -182,12 +240,21 @@ Renderer *uDisplay::Init(void) { Wire.begin(i2c_sda, i2c_scl); if (bpp < 16) { if (buffer) free(buffer); +#ifdef ESP8266 buffer = (uint8_t*)calloc((width()*height()*bpp)/8, 1); - - for (uint32_t cnt = 0; cnt < dsp_ncmds; cnt++) { - i2c_command(dsp_cmds[cnt]); +#else + if (psramFound()) { + buffer = (uint8_t*)heap_caps_malloc((width()*height()*bpp)/8, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + } else { + buffer = (uint8_t*)calloc((width()*height()*bpp)/8, 1); } +#endif } + + for (uint32_t cnt = 0; cnt < dsp_ncmds; cnt++) { + i2c_command(dsp_cmds[cnt]); + } + } if (interface == _UDSP_SPI) { if (bpanel >= 0) { @@ -209,19 +276,38 @@ Renderer *uDisplay::Init(void) { digitalWrite(spi_cs, HIGH); } - spiSettings = SPISettings(spi_speed, MSBFIRST, SPI_MODE3); - #ifdef ESP8266 - SPI.begin(); - uspi = &SPI; -#else - if (spi_nr != 1) { - uspi = new SPIClass(HSPI); - } else { + if (spi_nr <= 1) { + SPI.begin(); uspi = &SPI; + } else { + pinMode(spi_clk, OUTPUT); + digitalWrite(spi_clk, LOW); + pinMode(spi_mosi, OUTPUT); + digitalWrite(spi_mosi, LOW); + pinMode(spi_dc, OUTPUT); + digitalWrite(spi_dc, LOW); } - uspi->begin(spi_clk, spi_miso, spi_mosi, -1); -#endif +#endif // ESP8266 + +#ifdef ESP32 + if (spi_nr == 1) { + uspi = &SPI; + uspi->begin(spi_clk, spi_miso, spi_mosi, -1); + } else if (spi_nr == 2) { + uspi = new SPIClass(HSPI); + uspi->begin(spi_clk, spi_miso, spi_mosi, -1); + } else { + pinMode(spi_clk, OUTPUT); + digitalWrite(spi_clk, LOW); + pinMode(spi_mosi, OUTPUT); + digitalWrite(spi_mosi, LOW); + pinMode(spi_dc, OUTPUT); + digitalWrite(spi_dc, LOW); + } +#endif // ESP32 + + spiSettings = SPISettings((uint32_t)spi_speed*1000000, MSBFIRST, SPI_MODE3); uint16_t index = 0; @@ -229,20 +315,29 @@ Renderer *uDisplay::Init(void) { while (1) { uint8_t iob; SPI_CS_LOW - SPI_DC_LOW + iob = dsp_cmds[index++]; - uspi->write(iob); - SPI_DC_HIGH + spi_command(iob); + uint8_t args = dsp_cmds[index++]; - //Serial.printf("cmd, args %x, %d ", iob, args&0x7f); - for (uint32_t cnt = 0; cnt < (args & 0x7f); cnt++) { +#ifdef UDSP_DEBUG + Serial.printf("cmd, args %x, %d ", iob, args&0x1f); +#endif + for (uint32_t cnt = 0; cnt < (args & 0x1f); cnt++) { iob = dsp_cmds[index++]; - //Serial.printf("%02x ", iob ); - uspi->write(iob); +#ifdef UDSP_DEBUG + Serial.printf("%02x ", iob ); +#endif + spi_data8(iob); } SPI_CS_HIGH - //Serial.printf("\n"); - if (args & 0x80) delay(120); +#ifdef UDSP_DEBUG + Serial.printf("\n"); +#endif + if (args & 0x80) { + if (args&0x60) delay(500); + else delay(150); + } if (index >= dsp_ncmds) break; } SPI_END_TRANSACTION @@ -265,12 +360,85 @@ void uDisplay::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) { } void uDisplay::spi_command(uint8_t val) { + + if (spi_dc < 0) { + if (spi_nr > 2) { + write9(val, 0); + } else { + hw_write9(val, 0); + } + } else { + SPI_DC_LOW + if (spi_nr > 2) { + write8(val); + } else { + uspi->write(val); + } + SPI_DC_HIGH + } +} + +void uDisplay::spi_data8(uint8_t val) { + if (spi_dc < 0) { + if (spi_nr > 2) { + write9(val, 1); + } else { + hw_write9(val, 1); + } + } else { + if (spi_nr > 2) { + write8(val); + } else { + uspi->write(val); + } + } +} + +void uDisplay::spi_data16(uint16_t val) { + if (spi_dc < 0) { + if (spi_nr > 2) { + write9(val >> 8, 1); + write9(val, 1); + } else { + hw_write9(val >> 8, 1); + hw_write9(val, 1); + } + } else { + if (spi_nr > 2) { + write16(val); + } else { + uspi->write16(val); + } + } +} + +void uDisplay::spi_data32(uint32_t val) { + if (spi_dc < 0) { + if (spi_nr > 2) { + write9(val >> 24, 1); + write9(val >> 16, 1); + write9(val >> 8, 1); + write9(val, 1); + } else { + hw_write9(val >> 24, 1); + hw_write9(val >> 16, 1); + hw_write9(val >> 8, 1); + hw_write9(val, 1); + } + } else { + if (spi_nr > 2) { + write32(val); + } else { + uspi->write32(val); + } + } +} + +void uDisplay::spi_command_one(uint8_t val) { SPI_BEGIN_TRANSACTION - SPI_DC_LOW SPI_CS_LOW - uspi->write(val); + spi_command(val); SPI_CS_HIGH - SPI_DC_HIGH SPI_END_TRANSACTION } @@ -282,17 +450,13 @@ void uDisplay::i2c_command(uint8_t val) { Wire.endTransmission(); } -#define SH1106_SETLOWCOLUMN 0 -#define SH1106_SETHIGHCOLUMN 0x10 -#define SH1106_SETSTARTLINE 0x40 - void uDisplay::Updateframe(void) { if (interface == _UDSP_I2C) { - i2c_command(SH1106_SETLOWCOLUMN | 0x0); // low col = 0 - i2c_command(SH1106_SETHIGHCOLUMN | 0x0); // hi col = 0 - i2c_command(SH1106_SETSTARTLINE | 0x0); // line #0 + i2c_command(saw_1 | 0x0); // low col = 0 + i2c_command(saw_2 | 0x0); // hi col = 0 + i2c_command(saw_3 | 0x0); // line #0 uint8_t ys = gys >> 3; uint8_t xs = gxs >> 3; @@ -338,8 +502,23 @@ void uDisplay::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { setAddrWindow_int(x, y, 1, h); - while (h--) { - uspi->write16(color); + if (col_mode == 18) { + uint8_t r = (color & 0xF800) >> 11; + uint8_t g = (color & 0x07E0) >> 5; + uint8_t b = color & 0x001F; + r = (r * 255) / 31; + g = (g * 255) / 63; + b = (b * 255) / 31; + + while (h--) { + spi_data8(r); + spi_data8(g); + spi_data8(b); + } + } else { + while (h--) { + WriteColor(color); + } } SPI_CS_HIGH @@ -365,9 +544,23 @@ void uDisplay::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { setAddrWindow_int(x, y, w, 1); + if (col_mode == 18) { + uint8_t r = (color & 0xF800) >> 11; + uint8_t g = (color & 0x07E0) >> 5; + uint8_t b = color & 0x001F; + r = (r * 255) / 31; + g = (g * 255) / 63; + b = (b * 255) / 31; - while (w--) { - uspi->write16(color); + while (w--) { + spi_data8(r); + spi_data8(g); + spi_data8(b); + } + } else { + while (w--) { + WriteColor(color); + } } SPI_CS_HIGH @@ -387,7 +580,6 @@ void uDisplay::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t col return; } - // rudimentary clipping (drawChar w/big text requires this) if((x >= gxs) || (y >= gys)) return; if((x + w - 1) >= gxs) w = gxs - x; if((y + h - 1) >= gys) h = gys - y; @@ -398,15 +590,60 @@ void uDisplay::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t col setAddrWindow_int(x, y, w, h); - for (y = h; y > 0; y--) { - for (x = w; x > 0; x--) { - uspi->write16(color); + if (col_mode == 18) { + uint8_t r = (color & 0xF800) >> 11; + uint8_t g = (color & 0x07E0) >> 5; + uint8_t b = color & 0x001F; + r = (r * 255) / 31; + g = (g * 255) / 63; + b = (b * 255) / 31; + + for (y = h; y > 0; y--) { + for (x = w; x > 0; x--) { + spi_data8(r); + spi_data8(g); + spi_data8(b); + } + } + + } else { + for (y = h; y > 0; y--) { + for (x = w; x > 0; x--) { + WriteColor(color); + } } } SPI_CS_HIGH SPI_END_TRANSACTION } +/* + +// pack RGB into uint32 +uint32_t pack_rgb(uint32_t r, uint32_t g, uint32_t b) { + uint32_t data; + data=r<<23; + data|=g<<14; + data|=b<<5; + data|=0b10000000010000000010000000000000; + return ulswap(data); +} + +// init 27 bit mode +uint32_t data=pack_rgb(r,g,b); +REG_SET_BIT(SPI_USER_REG(3), SPI_USR_MOSI); +REG_WRITE(SPI_MOSI_DLEN_REG(3), 27 - 1); +uint32_t *dp=(uint32_t*)SPI_W0_REG(3); +digitalWrite( _cs, LOW); +for(y=h; y>0; y--) { + for(x=w; x>0; x--) { + while (REG_GET_FIELD(SPI_CMD_REG(3), SPI_USR)); + *dp=data; + REG_SET_BIT(SPI_CMD_REG(3), SPI_USR); + } +} +*/ + void uDisplay::Splash(void) { setTextFont(splash_font); @@ -427,38 +664,75 @@ void uDisplay::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) } } +#define udisp_swap(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))) ///< No-temp-var swap operation + void uDisplay::setAddrWindow_int(uint16_t x, uint16_t y, uint16_t w, uint16_t h) { - uint32_t xa = ((uint32_t)x << 16) | (x+w-1); - uint32_t ya = ((uint32_t)y << 16) | (y+h-1); + x += x_addr_offs[cur_rot]; + y += y_addr_offs[cur_rot]; - SPI_DC_LOW - uspi->write(saw_1); - SPI_DC_HIGH + if (sa_mode == 16) { + uint32_t xa = ((uint32_t)x << 16) | (x+w-1); + uint32_t ya = ((uint32_t)y << 16) | (y+h-1); - uspi->write32(xa); + spi_command(saw_1); + spi_data32(xa); - SPI_DC_LOW - uspi->write(saw_2); - SPI_DC_HIGH + spi_command(saw_2); + spi_data32(ya); - uspi->write32(ya); - - SPI_DC_LOW - uspi->write(saw_3); // write to RAM - SPI_DC_HIGH + if (saw_3 != 0xff) { + spi_command(saw_3); // write to RAM + } + } else { + uint16_t x2 = x + w - 1, + y2 = y + h - 1; + if (cur_rot & 1) { // Vertical address increment mode + udisp_swap(x,y); + udisp_swap(x2,y2); + } + spi_command(saw_1); + spi_data8(x); + spi_data8(x2); + spi_command(saw_2); + spi_data8(y); + spi_data8(y2); + if (saw_3 != 0xff) { + spi_command(saw_3); // write to RAM + } + } } + void uDisplay::pushColors(uint16_t *data, uint16_t len, boolean first) { uint16_t color; while (len--) { color = *data++; - uspi->write16(color); + WriteColor(color); } } +void uDisplay::WriteColor(uint16_t color) { + + if (col_mode == 18) { + uint8_t r = (color & 0xF800) >> 11; + uint8_t g = (color & 0x07E0) >> 5; + uint8_t b = color & 0x001F; + + r = (r * 255) / 31; + g = (g * 255) / 63; + b = (b * 255) / 31; + + spi_data8(r); + spi_data8(g); + spi_data8(b); + } else { + spi_data16(color); + } +} + void uDisplay::drawPixel(int16_t x, int16_t y, uint16_t color) { if (interface != _UDSP_SPI) { @@ -466,7 +740,7 @@ void uDisplay::drawPixel(int16_t x, int16_t y, uint16_t color) { return; } - if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return; + if ((x < 0) || (x >= _width) || (y < 0) || (y >= _height)) return; SPI_BEGIN_TRANSACTION @@ -475,44 +749,60 @@ void uDisplay::drawPixel(int16_t x, int16_t y, uint16_t color) { setAddrWindow_int(x, y, 1, 1); - uspi->write16(color); + WriteColor(color); SPI_CS_HIGH SPI_END_TRANSACTION } -void uDisplay::setRotation(uint8_t m) { +void uDisplay::setRotation(uint8_t rotation) { + cur_rot = rotation; + if (interface != _UDSP_SPI) { - Renderer::setRotation(m); + Renderer::setRotation(cur_rot); return; } + if (interface == _UDSP_SPI) { + SPI_BEGIN_TRANSACTION + SPI_CS_LOW + spi_command(madctrl); + spi_data8(rot[cur_rot]); + if (sa_mode == 8) { + spi_command(startline); + spi_data8((cur_rot < 2) ? height() : 0); + } + + SPI_CS_HIGH + SPI_END_TRANSACTION + } switch (rotation) { case 0: - if (interface == _UDSP_SPI) spi_command(rot_0); _width = gxs; _height = gys; break; case 1: - if (interface == _UDSP_SPI) spi_command(rot_1); _width = gys; _height = gxs; break; case 2: - if (interface == _UDSP_SPI) spi_command(rot_2); _width = gxs; _height = gys; break; case 3: - if (interface == _UDSP_SPI) spi_command(rot_3); _width = gys; _height = gxs; break; } + } +void udisp_bpwr(uint8_t on); + void uDisplay::DisplayOnff(int8_t on) { + udisp_bpwr(on); + if (interface == _UDSP_I2C) { if (on) { i2c_command(dsp_on); @@ -521,7 +811,7 @@ void uDisplay::DisplayOnff(int8_t on) { } } else { if (on) { - spi_command(dsp_on); + spi_command_one(dsp_on); if (bpanel >= 0) { #ifdef ESP32 ledcWrite(ESP32_PWM_CHANNEL, dimmer); @@ -531,7 +821,7 @@ void uDisplay::DisplayOnff(int8_t on) { } } else { - spi_command(dsp_off); + spi_command_one(dsp_off); if (bpanel >= 0) { #ifdef ESP32 ledcWrite(ESP32_PWM_CHANNEL, 0); @@ -543,16 +833,60 @@ void uDisplay::DisplayOnff(int8_t on) { } } +void uDisplay::invertDisplay(boolean i) { + if (i) { + spi_command_one(inv_on); + } else { + spi_command_one(inv_off); + } +} + +void udisp_dimm(uint8_t dim); + void uDisplay::dim(uint8_t dim) { dimmer = dim; if (dimmer > 15) dimmer = 15; dimmer = ((float)dimmer / 15.0) * 255.0; #ifdef ESP32 - ledcWrite(ESP32_PWM_CHANNEL, dimmer); + if (bpanel >= 0) { + ledcWrite(ESP32_PWM_CHANNEL, dimmer); + } else { + udisp_dimm(dim); + } #endif + if (dim_op != 0xff) { + SPI_BEGIN_TRANSACTION + SPI_CS_LOW + spi_command(dim_op); + spi_data8(dim); + SPI_CS_HIGH + SPI_END_TRANSACTION + } } +void uDisplay::TS_RotConvert(int16_t *x, int16_t *y) { + int16_t temp; + + switch (rot_t[cur_rot]) { + case 0: + break; + case 1: + temp = *y; + *y = height() - *x; + *x = temp; + break; + case 2: + *x = width() - *x; + *y = height() - *y; + break; + case 3: + temp = *y; + *y = *x; + *x = width() - temp; + break; + } +} uint8_t uDisplay::strlen_ln(char *str) { for (uint32_t cnt = 0; cnt < 256; cnt++) { @@ -596,12 +930,106 @@ uint32_t uDisplay::str2c(char **sp, char *vp, uint32_t len) { int32_t uDisplay::next_val(char **sp) { char ibuff[16]; - str2c(sp, ibuff, sizeof(ibuff)); - return atoi(ibuff); + if (!str2c(sp, ibuff, sizeof(ibuff))) { + return atoi(ibuff); + } + return 0xff; } uint32_t uDisplay::next_hex(char **sp) { char ibuff[16]; - str2c(sp, ibuff, sizeof(ibuff)); - return strtol(ibuff, 0, 16); + if (!str2c(sp, ibuff, sizeof(ibuff))) { + return strtol(ibuff, 0, 16); + } + return 0xff; +} + +#ifdef ESP32 +#include "soc/spi_reg.h" +#include "soc/spi_struct.h" +#include "esp32-hal-spi.h" +#include "esp32-hal.h" +#include "soc/spi_struct.h" + +// since ardunio transferBits ia completely disfunctional +// we use our own hardware driver for 9 bit spi +void uDisplay::hw_write9(uint8_t val, uint8_t dc) { + + uint32_t regvalue = val >> 1; + if (dc) regvalue |= 0x80; + else regvalue &= 0x7f; + if (val & 1) regvalue |= 0x8000; + + REG_SET_BIT(SPI_USER_REG(3), SPI_USR_MOSI); + REG_WRITE(SPI_MOSI_DLEN_REG(3), 9 - 1); + uint32_t *dp = (uint32_t*)SPI_W0_REG(3); + *dp = regvalue; + REG_SET_BIT(SPI_CMD_REG(3), SPI_USR); + while (REG_GET_FIELD(SPI_CMD_REG(3), SPI_USR)); +} + +#else +#include "spi_register.h" +void uDisplay::hw_write9(uint8_t val, uint8_t dc) { + + uint32_t regvalue; + uint8_t bytetemp; + if (!dc) { + bytetemp = (val>> 1) & 0x7f; + } else { + bytetemp = (val >> 1) | 0x80; + } + + regvalue = ((8 & SPI_USR_COMMAND_BITLEN) << SPI_USR_COMMAND_BITLEN_S) | ((uint32)bytetemp); //configure transmission variable,9bit transmission length and first 8 command bit + if (val & 0x01) regvalue |= BIT15; //write the 9th bit + while (READ_PERI_REG(SPI_CMD(1)) & SPI_USR); //waiting for spi module available + WRITE_PERI_REG(SPI_USER2(1), regvalue); //write command and command length into spi reg + SET_PERI_REG_MASK(SPI_CMD(1), SPI_USR); //transmission start + +} +#endif + +#define USECACHE ICACHE_RAM_ATTR + + +void USECACHE uDisplay::write8(uint8_t val) { + for (uint8_t bit = 0x80; bit; bit >>= 1) { + GPIO_CLR(spi_clk); + if (val & bit) GPIO_SET(spi_mosi); + else GPIO_CLR(spi_mosi); + GPIO_SET(spi_clk); + } +} + +void USECACHE uDisplay::write9(uint8_t val, uint8_t dc) { + + GPIO_CLR(spi_clk); + if (dc) GPIO_SET(spi_mosi); + else GPIO_CLR(spi_mosi); + GPIO_SET(spi_clk); + + for (uint8_t bit = 0x80; bit; bit >>= 1) { + GPIO_CLR(spi_clk); + if (val & bit) GPIO_SET(spi_mosi); + else GPIO_CLR(spi_mosi); + GPIO_SET(spi_clk); + } +} + +void USECACHE uDisplay::write16(uint16_t val) { + for (uint16_t bit = 0x8000; bit; bit >>= 1) { + GPIO_CLR(spi_clk); + if (val & bit) GPIO_SET(spi_mosi); + else GPIO_CLR(spi_mosi); + GPIO_SET(spi_clk); + } +} + +void USECACHE uDisplay::write32(uint32_t val) { + for (uint32_t bit = 0x80000000; bit; bit >>= 1) { + GPIO_CLR(spi_clk); + if (val & bit) GPIO_SET(spi_mosi); + else GPIO_CLR(spi_mosi); + GPIO_SET(spi_clk); + } } diff --git a/lib/lib_display/UDisplay/uDisplay.h b/lib/lib_display/UDisplay/uDisplay.h index f5f3c789d..f3bc1b277 100644 --- a/lib/lib_display/UDisplay/uDisplay.h +++ b/lib/lib_display/UDisplay/uDisplay.h @@ -10,6 +10,7 @@ #define UDISP1_WHITE 1 #define UDISP1_BLACK 0 +enum uColorType { uCOLOR_BW, uCOLOR_COLOR }; // Color definitions #define UDISP_BLACK 0x0000 /* 0, 0, 0 */ @@ -32,12 +33,24 @@ #define UDISP_GREENYELLOW 0xAFE5 /* 173, 255, 47 */ #define UDISP_PINK 0xF81F -#define SPI_BEGIN_TRANSACTION uspi->beginTransaction(spiSettings); -#define SPI_END_TRANSACTION uspi->endTransaction(); -#define SPI_CS_LOW if (spi_cs >= 0) digitalWrite(spi_cs, LOW); -#define SPI_CS_HIGH if (spi_cs >= 0) digitalWrite(spi_cs, HIGH); -#define SPI_DC_LOW if (spi_dc >= 0) digitalWrite(spi_dc, LOW); -#define SPI_DC_HIGH if (spi_dc >= 0) digitalWrite(spi_dc, HIGH); +#ifdef ESP8266 +#define PIN_OUT_SET 0x60000304 +#define PIN_OUT_CLEAR 0x60000308 +#define GPIO_SET(A) WRITE_PERI_REG( PIN_OUT_SET, 1 << A) +#define GPIO_CLR(A) WRITE_PERI_REG( PIN_OUT_CLEAR, 1 << A) +#else +#undef GPIO_SET +#define GPIO_SET(A) GPIO.out_w1ts = (1 << A) +#undef GPIO_CLR +#define GPIO_CLR(A) GPIO.out_w1tc = (1 << A) +#endif + +#define SPI_BEGIN_TRANSACTION if (spi_nr <= 2) uspi->beginTransaction(spiSettings); +#define SPI_END_TRANSACTION if (spi_nr <= 2) uspi->endTransaction(); +#define SPI_CS_LOW if (spi_cs >= 0) GPIO_CLR(spi_cs); +#define SPI_CS_HIGH if (spi_cs >= 0) GPIO_SET(spi_cs); +#define SPI_DC_LOW if (spi_dc >= 0) GPIO_CLR(spi_dc); +#define SPI_DC_HIGH if (spi_dc >= 0) GPIO_SET(spi_dc); #define ESP32_PWM_CHANNEL 1 @@ -58,6 +71,8 @@ class uDisplay : public Renderer { void fillScreen(uint16_t color); void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); void pushColors(uint16_t *data, uint16_t len, boolean first); + void TS_RotConvert(int16_t *x, int16_t *y); + void invertDisplay(boolean i); private: void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); @@ -67,6 +82,18 @@ class uDisplay : public Renderer { uint32_t str2c(char **sp, char *vp, uint32_t len); void i2c_command(uint8_t val); void spi_command(uint8_t val); + void spi_command_one(uint8_t val); + void spi_data8(uint8_t val); + void spi_data16(uint16_t val); + void spi_data32(uint32_t val); + void write8(uint8_t val); + void write9(uint8_t val, uint8_t dc); + void hw_write9(uint8_t val, uint8_t dc); + void write16(uint16_t val); + void write32(uint32_t val); + void spi_data9(uint8_t d, uint8_t dc); + void WriteColor(uint16_t color); + uint8_t strlen_ln(char *str); int32_t next_val(char **sp); uint32_t next_hex(char **sp); @@ -98,17 +125,27 @@ class uDisplay : public Renderer { int8_t spi_miso; uint8_t dimmer; SPIClass *uspi; + uint8_t sspi; SPISettings spiSettings; - uint32_t spi_speed; + uint8_t spi_speed; uint8_t spi_nr = 1; - uint8_t rot_0; - uint8_t rot_1; - uint8_t rot_2; - uint8_t rot_3; + uint8_t madctrl; + uint8_t startline; + uint8_t rot[4]; + uint8_t rot_t[4]; + uint16_t x_addr_offs[4]; + uint16_t y_addr_offs[4]; uint8_t saw_1; uint8_t saw_2; uint8_t saw_3; - uint8_t flags; + uint8_t cur_rot; + uint8_t col_mode; + uint8_t inv_on; + uint8_t inv_off; + uint8_t sa_mode; + uint8_t dim_op; }; + + #endif // _UDISP_ diff --git a/tasmota/displaydesc/ILI9341_desc.txt b/tasmota/displaydesc/ILI9341_desc.txt index 6aab1b1c5..c9f6e8964 100644 --- a/tasmota/displaydesc/ILI9341_desc.txt +++ b/tasmota/displaydesc/ILI9341_desc.txt @@ -1,10 +1,5 @@ -; name,xs,ys,bpp,interface, spi_nr cs, sclk,mosi,dc, bp ,reset,miso,spi_speed -:H -ILI9341,240,320,16,SPI,1,*,*,*,*,*,*,*,40000000 -; splash settings, font, size, fgcol, bgcol, x,y -:S -2,1,1,0,40,20 -; initialyze +:H,ILI9341,240,320,16,SPI,1,*,*,*,*,*,*,*,40 +:S,2,1,1,0,40,20 :I EF,3,03,80,02 CF,3,00,C1,30 @@ -27,24 +22,13 @@ F2,1,00 E0,0F,0F,31,2B,0C,0E,08,4E,F1,37,07,10,03,0E,09,00 E1,0F,00,0E,14,03,11,07,31,C1,48,08,0F,0C,31,36,0F 11,80 -29,80 -; off -:o -28 -; on -:O -29 -; set adress window -:A -2A,2B,2C -; rotation -:0 -48 -:1 -28 -:2 -88 -:3 -E8 +29,80 +:o,28 +:O,29 +:A,2A,2B,2C +:R,36 +:0,48,00,00,00 +:1,28,00,00,01 +:2,88,00,00,02 +:3,E8,00,00,02 # - diff --git a/tasmota/displaydesc/ILI9342_desc.txt b/tasmota/displaydesc/ILI9342_desc.txt new file mode 100644 index 000000000..0f2b32e35 --- /dev/null +++ b/tasmota/displaydesc/ILI9342_desc.txt @@ -0,0 +1,36 @@ +:H,ILI9342,320,240,16,SPI,1,*,*,*,*,*,*,*,40 +:S,2,1,3,0,100,100 +:I +EF,3,03,80,02 +CF,3,00,C1,30 +ED,4,64,03,12,81 +E8,3,85,00,78 +CB,5,39,2C,00,34,02 +F7,1,20 +EA,2,00,00 +C0,1,23 +C1,1,10 +C5,2,3e,28 +C7,1,86 +36,1,48 +37,1,00 +3A,1,55 +B1,2,00,18 +B6,3,08,82,27 +F2,1,00 +26,1,01 +E0,0F,0F,31,2B,0C,0E,08,4E,F1,37,07,10,03,0E,09,00 +E1,0F,00,0E,14,03,11,07,31,C1,48,08,0F,0C,31,36,0F +21,80 +11,80 +29,80 +:o,28 +:O,29 +:A,2A,2B,2C +:R,36 +:0,08,00,00,00 +:1,A8,00,00,01 +:2,C8,00,00,02 +:3,68,00,00,03 +:TI2,38,22,21 +# diff --git a/tasmota/displaydesc/ILI9488_desc.txt b/tasmota/displaydesc/ILI9488_desc.txt new file mode 100644 index 000000000..1aac15cd2 --- /dev/null +++ b/tasmota/displaydesc/ILI9488_desc.txt @@ -0,0 +1,30 @@ +:H,ILI9488,480,320,16,SPI,1,*,*,*,*,*,*,-1,10 +:S,2,1,1,0,40,20 +:I +E0,0F,00,03,09,08,16,0A,3F,78,4C,09,0A,08,16,1A,0F +E1,0F,00,16,19,03,0F,05,32,45,46,04,0E,0D,35,37,0F +C0,2,17,15 +C1,1,41 +C5,3,00,12,80 +36,1,48 +3A,1,66 +B0,1,80 +B1,1,A0 +B4,1,02 +B6,2,02,02 +E9,1,00 +F7,4,A9,51,2C,82 +11,80 +29,0 +:o,28 +:O,29 +:A,2A,2B,2C +:R,36 +;:0,48,00,00,00 +:0,28,00,00,01 +:1,28,00,00,00 +:2,E8,00,00,03 +:3,88,00,00,02 +:P,18 +:TI1,38,4,5 +# diff --git a/tasmota/displaydesc/SH1106_desc.txt b/tasmota/displaydesc/SH1106_desc.txt index 954cb3740..2d3f76fdf 100644 --- a/tasmota/displaydesc/SH1106_desc.txt +++ b/tasmota/displaydesc/SH1106_desc.txt @@ -1,10 +1,5 @@ -; name,xs,ys,bpp,interface, address, scl,sda,reset -:H -SH1106,128,64,1,I2C,3c,*,*,* -; splash settings, font, size, fgcol, bgcol, x,y -:S -0,1,1,0,40,20 -; init register settings +:H,SH1106,128,64,1,I2C,3c,*,*,* +:S,0,2,1,0,30,20 :I AE D5,80 @@ -22,10 +17,7 @@ DB,40 A4 A6 AF -; switch display off -:o -AE -; switch display on -:O -AF -# \ No newline at end of file +:o,AE +:O,AF +:A,00,10,40 +# diff --git a/tasmota/displaydesc/SSD1351_desc.txt b/tasmota/displaydesc/SSD1351_desc.txt new file mode 100644 index 000000000..955ffda19 --- /dev/null +++ b/tasmota/displaydesc/SSD1351_desc.txt @@ -0,0 +1,33 @@ +:H,SSD1351,128,128,16,SPI,1,*,*,*,-1,-1,-1,-1,10 +:S,1,1,1,0,40,10 +:I +FD,1,12 +FD,1,B1 +AE,0 +B3,1,F1 +CA,e0,7F +A2,1,00 +B5,1,00 +AB,1,01 +B1,1,32 +BE,1,05 +A1,1,00 +A6,0 +C1,3,C8,80,C8 +C7,1,0F +B4,3,A0,B5,55 +B6,1,01 +96,1,00 +9E,0 +AF,80 +:o,AE +:O,AF +:A,15,75,5C,8 +:R,A0,A1 +:0,74,00,00,01 +:1,77,00,00,00 +:2,76,00,00,03 +:3,75,00,00,02 +:i,A6,A7 +:D,C7 +# diff --git a/tasmota/displaydesc/ST7789_desc.txt b/tasmota/displaydesc/ST7789_desc.txt new file mode 100644 index 000000000..fcdbd389c --- /dev/null +++ b/tasmota/displaydesc/ST7789_desc.txt @@ -0,0 +1,21 @@ + +:H,ST7789,240,240,16,SPI,1,*,*,*,*,*,-1,-1,40 +:S,2,1,3,0,80,30 +:I +01,A0 +11,A0 +3A,81,55 +36,81,00 +21,80 +13,80 +29,A0 +:o,28 +:O,29 +:A,2A,2B,2C +:R,36 +:0,C0,00,50,00 +:1,A0,50,00,01 +:2,00,00,00,02 +:3,60,00,00,03 +:TI2,38,32,23 +# diff --git a/tasmota/xdsp_17_universal.ino b/tasmota/xdsp_17_universal.ino index c72b4cb85..9ae3eeeb4 100644 --- a/tasmota/xdsp_17_universal.ino +++ b/tasmota/xdsp_17_universal.ino @@ -27,17 +27,18 @@ uDisplay *udisp; bool udisp_init_done = false; +uint8_t ctouch_counter; extern uint8_t color_type; extern uint16_t fg_color; extern uint16_t bg_color; #ifdef USE_UFILESYS -extern FS *ufsp; +extern FS *ffsp; #endif #define DISPDESC_SIZE 1000 -#define DSP_ROM_DESC +//#define DSP_ROM_DESC /*********************************************************************************************/ #ifdef DSP_ROM_DESC @@ -45,11 +46,9 @@ extern FS *ufsp; const char DSP_SAMPLE_DESC[] PROGMEM = // name,xs,ys,bpp,interface, (HEX) address, scl,sda,reset // '*' means take pin number from tasmota -":H\n" -"SH1106,128,64,1,I2C,3c,*,*,*\n" +":H,SH1106,128,64,1,I2C,3c,*,*,*\n" // splash settings, font, size, fgcol, bgcol, x,y -":S\n" -"0,1,1,0,40,20\n" +":S,0,1,1,0,40,20\n" // init register settings, must be in HEX ":I\n" "AE\n" @@ -69,11 +68,10 @@ const char DSP_SAMPLE_DESC[] PROGMEM = "A6\n" "AF\n" // switch display off -":o\n" -"AE\n" +":o,AE\n" // switch display on -":O\n" -"AF\n" +":O,AF\n" +":A,00,10,40\n" "#\n"; #endif // DSP_ROM_DESC @@ -86,17 +84,15 @@ char *fbuff; if (TasmotaGlobal.gpio_optiona.udisplay_driver) { Settings.display_model = XDSP_17; - fg_color = 1; - bg_color = 0; color_type = COLOR_BW; fbuff = (char*)calloc(DISPDESC_SIZE, 1); if (!fbuff) return; #ifdef USE_UFILESYS - if (ufsp && !TasmotaGlobal.no_autoexec) { + if (ffsp && !TasmotaGlobal.no_autoexec) { File fp; - fp = ufsp->open("/dispdesc.txt", "r"); + fp = ffsp->open("/dispdesc.txt", "r"); if (fp > 0) { uint32_t size = fp.size(); fp.read((uint8_t*)fbuff, size); @@ -136,26 +132,24 @@ char *fbuff; return; } // now replace tasmota vars before passing to driver - char *cp = strstr(ddesc, "I2C"); + char *cp = strstr(ddesc, "I2C,"); if (cp) { cp += 4; //,3c,22,21,-1 - // i2c addr - //if (*cp == '*') { - // Settings.display_address - //} - uint8_t i2caddr = strtol(cp, 0, 16); + uint8_t i2caddr = strtol(cp, &cp, 16); + int8_t scl, sda; + scl = replacepin(&cp, Pin(GPIO_I2C_SCL)); + sda = replacepin(&cp, Pin(GPIO_I2C_SDA)); + replacepin(&cp, Pin(GPIO_OLED_RESET)); + + Wire.begin(sda, scl); if (I2cSetDevice(i2caddr)) { I2cSetActiveFound(i2caddr, "DSP-I2C"); } - cp+=3; - //replacepin(&cp, Settings.display_address); - replacepin(&cp, Pin(GPIO_I2C_SCL)); - replacepin(&cp, Pin(GPIO_I2C_SDA)); - replacepin(&cp, Pin(GPIO_OLED_RESET)); + } - cp = strstr(ddesc, "SPI"); + cp = strstr(ddesc, "SPI,"); if (cp) { cp += 4; //; 7 params nr,cs,sclk,mosi,dc,bl,reset,miso @@ -188,10 +182,57 @@ char *fbuff; /* File fp; - fp = ufsp->open("/dump.txt", "w"); - fp.write(ddesc, DISPDESC_SIZE); + fp = ffsp->open("/dump.txt", "w"); + fp.write((uint8_t*)ddesc, DISPDESC_SIZE); fp.close(); -*/ + */ + + + // checck for touch option TI1 or TI2 +#ifdef USE_FT5206 + cp = strstr(ddesc, ":TI"); + if (cp) { + uint8_t wire_n = 1; + cp+=3; + wire_n = (*cp & 3) - 1; + cp+=2; + + uint8_t i2caddr = strtol(cp, &cp, 16); + int8_t scl, sda; + scl = replacepin(&cp, Pin(GPIO_I2C_SCL)); + sda = replacepin(&cp, Pin(GPIO_I2C_SDA)); + + if (wire_n == 0) { + Wire.begin(sda, scl); + } +#ifdef ESP32 + if (wire_n == 1) { + Wire1.begin(sda, scl, 400000); + } +#endif + //AddLog(LOG_LEVEL_INFO, PSTR("DSP: touch %x, %d, %d, %d!"), i2caddr, wire_n, scl, sda); + if (I2cSetDevice(i2caddr, wire_n)) { + I2cSetActiveFound(i2caddr, "FT5206", wire_n); + } + // start digitizer +#ifdef ESP32 + if (!wire_n) Touch_Init(Wire); + else Touch_Init(Wire1); +#else + if (!wire_n) Touch_Init(Wire); +#endif + } +#endif + +#ifdef USE_XPT2046 + cp = strstr(ddesc, ":TS,"); + if (cp) { + cp+=4; + uint8_t touch_cs = replacepin(&cp, Pin(GPIO_XPT2046_CS)); + Touch_Init(touch_cs); + } +#endif + // release desc buffer if (fbuff) free(fbuff); @@ -204,7 +245,7 @@ char *fbuff; bg_color = udisp->bgcol(); renderer->DisplayInit(DISPLAY_INIT_MODE, Settings.display_size, Settings.display_rotate, Settings.display_font); - + renderer->dim(Settings.display_dimmer); #ifdef SHOW_SPLASH udisp->Splash(); @@ -218,7 +259,39 @@ char *fbuff; /*********************************************************************************************/ -void replacepin(char **cp, uint16_t pin) { + +void core2_disp_pwr(uint8_t on); +void core2_disp_dim(uint8_t dim); + +void udisp_bpwr(uint8_t on) { +#ifdef USE_M5STACK_CORE2 + core2_disp_pwr(on); +#endif +} + +void udisp_dimm(uint8_t dim) { +#ifdef USE_M5STACK_CORE2 + core2_disp_dim(dim); +#endif +} + +void TS_RotConvert(int16_t *x, int16_t *y) { + if (udisp) udisp->TS_RotConvert(x, y); +} + +#if defined(USE_FT5206) || defined(USE_XPT2046) +void udisp_CheckTouch() { + ctouch_counter++; + if (2 == ctouch_counter) { + // every 100 ms should be enough + ctouch_counter = 0; + Touch_Check(TS_RotConvert); + } +} +#endif + +int8_t replacepin(char **cp, uint16_t pin) { + int8_t res = 0; char *lp = *cp; if (*lp == ',') lp++; if (*lp == '*') { @@ -229,10 +302,12 @@ void replacepin(char **cp, uint16_t pin) { memmove(lp + slen, lp + 1, strlen(lp)); memmove(lp, val, slen); } + res= strtol(lp, 0, 10); char *np = strchr(lp, ','); if (np) { *cp = np + 1; } + return res; } #ifdef USE_DISPLAY_MODES1TO5 @@ -318,11 +393,27 @@ bool Xdsp17(uint8_t function) case FUNC_DISPLAY_MODEL: result = true; break; + #ifdef USE_DISPLAY_MODES1TO5 case FUNC_DISPLAY_EVERY_SECOND: UDISP_Refresh(); break; #endif // USE_DISPLAY_MODES1TO5 + +#if defined(USE_FT5206) || defined(USE_XPT2046) +#ifdef USE_TOUCH_BUTTONS + case FUNC_DISPLAY_EVERY_50_MSECOND: +#if defined(USE_FT5206) + if (FT5206_found) { +#elif defined(USE_XPT2046) + if (XPT2046_found) { +#endif + udisp_CheckTouch(); + } + break; +#endif // USE_TOUCH_BUTTONS +#endif // USE_FT5206 + } } return result; From 264fdb1f942a1a1415c5fb21b15803c494ea3717 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <39969427+ascillato2@users.noreply.github.com> Date: Wed, 14 Apr 2021 09:59:02 -0300 Subject: [PATCH 2/5] Updated Italian Translation --- tasmota/language/it_IT.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 879f7575d..1979c569d 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -28,7 +28,7 @@ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command Prefix to translate cmnd, stat and tele. * - * Updated until v9.3.1.2 - Last update 13.04.2021 + * Updated until v9.3.1.3 - Last update 14.04.2021 \*********************************************************************/ #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -266,7 +266,7 @@ #define D_CONFIGURE_LOGGING "Livelli registri" #define D_CONFIGURE_OTHER "Altre impostazioni" #define D_CONFIRM_RESET_CONFIGURATION "Conferma ripristino impostazioni" -#define D_RESET_CONFIGURATION "Ripristino impostazioni" +#define D_RESET_CONFIGURATION "Impostazioni predefinite" #define D_BACKUP_CONFIGURATION "Backup impostazioni" #define D_RESTORE_CONFIGURATION "Ripristino impostazioni" #define D_MAIN_MENU "Menu principale" From 452598402838b5ea79161e143f4fc62c3a6c5b3d Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 14 Apr 2021 15:30:01 +0200 Subject: [PATCH 3/5] Update changelog --- CHANGELOG.md | 2 +- RELEASENOTES.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53b5473c4..41ec5a960 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ All notable changes to this project will be documented in this file. ## [9.3.1.3] ### Added - Optional GUI file editor enabled with define ``GUI_EDIT_FILE`` by barbudor (#11668) -- Initial support for universal display driver UDisplay by Gerhard Mutz (#11665) +- Initial support for universal display driver UDisplay by Gerhard Mutz. Enable by selecting any GPIO as ``Option A3`` (#11665) ### Changed - In tasmota-sensors.bin enabled support for VL53L0X and disabled TSL2561 (#11711) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 3c7f6c798..921800545 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -102,7 +102,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota - Extent compile time SetOptions support [#11204](https://github.com/arendst/Tasmota/issues/11204) - Tasmota discovery as alternative to Home Assistant discovery using define ``USE_TASMOTA_DISCOVERY`` - Optional GUI file editor enabled with define ``GUI_EDIT_FILE`` by barbudor [#11668](https://github.com/arendst/Tasmota/issues/11668) -- Initial support for universal display driver UDisplay by Gerhard Mutz [#11665](https://github.com/arendst/Tasmota/issues/11665) +- Initial support for universal display driver UDisplay by Gerhard Mutz. Enable by selecting any GPIO as ``Option A3`` [#11665](https://github.com/arendst/Tasmota/issues/11665) - ESP32 Extent BLE [#11212](https://github.com/arendst/Tasmota/issues/11212) - ESP32 support for WS2812 hardware driver via RMT or I2S - ESP32 support for secondary I2C controller From a451ad9836fe57ff957faec9846e2f21cd5cdd87 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <39969427+ascillato2@users.noreply.github.com> Date: Wed, 14 Apr 2021 10:41:18 -0300 Subject: [PATCH 4/5] Updated Italian Translation --- tasmota/language/it_IT.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 1979c569d..0c27874f2 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -267,8 +267,8 @@ #define D_CONFIGURE_OTHER "Altre impostazioni" #define D_CONFIRM_RESET_CONFIGURATION "Conferma ripristino impostazioni" #define D_RESET_CONFIGURATION "Impostazioni predefinite" -#define D_BACKUP_CONFIGURATION "Backup impostazioni" -#define D_RESTORE_CONFIGURATION "Ripristino impostazioni" +#define D_BACKUP_CONFIGURATION "Salva impostazioni" +#define D_RESTORE_CONFIGURATION "Carica impostazioni" #define D_MAIN_MENU "Menu principale" #define D_MODULE_PARAMETERS "Parametri modulo" From b6b0ca1b6c2d1875562ce7a7fc13e7ded926eae4 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 14 Apr 2021 16:09:34 +0200 Subject: [PATCH 5/5] Remove autoexec.bat multiline command support Remove autoexec.bat multiline command support and fix backlog command support. --- tasmota/xdrv_50_filesystem.ino | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tasmota/xdrv_50_filesystem.ino b/tasmota/xdrv_50_filesystem.ino index c187df02c..b745d8594 100644 --- a/tasmota/xdrv_50_filesystem.ino +++ b/tasmota/xdrv_50_filesystem.ino @@ -360,7 +360,7 @@ bool UfsExecuteCommandFileReady(void) { void UfsExecuteCommandFileLoop(void) { if (UfsExecuteCommandFileReady() || !ffs_type) { return; } - if (TimeReached(TasmotaGlobal.backlog_timer) && strlen(UfsData.run_file) && !UfsData.run_file_mutex) { + if (BACKLOG_EMPTY && strlen(UfsData.run_file) && !UfsData.run_file_mutex) { File file = ffsp->open(UfsData.run_file, "r"); if (!file || !file.seek(UfsData.run_file_pos)) { UfsData.run_file_pos = -1; // Signal file ready @@ -380,9 +380,9 @@ void UfsExecuteCommandFileLoop(void) { if ((buf[0] == '\n') || (buf[0] == '\r')) { break; // End of command with linefeed or carriage return } - else if (index && !comment && (buf[0] == ';')) { - break; // End of command on multi command line - } +// else if (index && !comment && (buf[0] == ';')) { +// break; // End of command on multi command line +// } else if ((0 == index) && isspace(buf[0])) { // Skip leading spaces (' ','\t','\n','\v','\f','\r') } @@ -401,11 +401,7 @@ void UfsExecuteCommandFileLoop(void) { UfsData.run_file_pos = (file.available()) ? file.position() : -1; file.close(); if (strlen(cmd_line)) { - bool nodelay = (!(!strncasecmp_P(cmd_line, PSTR(D_CMND_DELAY), strlen(D_CMND_DELAY)))); ExecuteCommand(cmd_line, SRC_FILE); - if (nodelay) { - TasmotaGlobal.backlog_timer = millis(); // Reset backlog_timer which has been set by ExecuteCommand (CommandHandler) - } } UfsData.run_file_mutex = false;