diff --git a/.github/workflows/Tasmota_build.yml b/.github/workflows/Tasmota_build.yml index 40fd060ba..47736dea5 100644 --- a/.github/workflows/Tasmota_build.yml +++ b/.github/workflows/Tasmota_build.yml @@ -1382,7 +1382,7 @@ jobs: mkdir -p ./firmware/tasmota/languages mkdir -p ./firmware/tasmota32/languages mkdir -p ./firmware/tasmota32/ESP32_needed_files/ - mkdir -p ./firmware/tasmota32/Odroid_go_needed_files/ + mkdir -p ./firmware/tasmota32/Odroid_go_and_core2_needed_files/ mkdir -p ./firmware/map [ ! -f ./mv_firmware/map/* ] || mv ./mv_firmware/map/* ./firmware/map/ [ ! -f ./mv_firmware/firmware/tasmota.* ] || mv ./mv_firmware/firmware/tasmota.* ./firmware/tasmota/ @@ -1403,7 +1403,7 @@ jobs: [ ! -f ./mv_firmware/firmware/tasmota32* ] || mv ./mv_firmware/firmware/tasmota32* ./firmware/tasmota32/languages/ [ ! -f ./mv_firmware/firmware/* ] || mv ./mv_firmware/firmware/* ./firmware/tasmota/languages/ [ ! -f ./tools/Esptool/ESP32/*.* ] || mv ./tools/Esptool/ESP32/*.* ./firmware/tasmota32/ESP32_needed_files/ - [ ! -f ./tools/Esptool/Odroid_go/*.* ] || mv ./tools/Esptool/Odroid_go/*.* ./firmware/tasmota32/Odroid_go_needed_files/ + [ ! -f ./tools/Esptool/Odroid_go_and_core2/*.* ] || mv ./tools/Esptool/Odroid_go_and_core2/*.* ./firmware/tasmota32/Odroid_go_and_core2_needed_files/ [ ! -f ./FIRMWARE.md ] || mv -f ./FIRMWARE.md ./README.md - name: Commit files # transfer the new binaries back into the repository run: | diff --git a/.github/workflows/Tasmota_build_master.yml b/.github/workflows/Tasmota_build_master.yml index 4bef7a371..e00ae3788 100644 --- a/.github/workflows/Tasmota_build_master.yml +++ b/.github/workflows/Tasmota_build_master.yml @@ -1382,7 +1382,7 @@ jobs: mkdir -p ./firmware/tasmota/languages mkdir -p ./firmware/tasmota32/languages mkdir -p ./firmware/tasmota32/ESP32_needed_files/ - mkdir -p ./firmware/tasmota32/Odroid_go_needed_files/ + mkdir -p ./firmware/tasmota32/Odroid_go_and_core2_needed_files/ mkdir -p ./firmware/map [ ! -f ./mv_firmware/map/* ] || mv ./mv_firmware/map/* ./firmware/map/ [ ! -f ./mv_firmware/firmware/tasmota.* ] || mv ./mv_firmware/firmware/tasmota.* ./firmware/tasmota/ @@ -1403,7 +1403,7 @@ jobs: [ ! -f ./mv_firmware/firmware/tasmota32* ] || mv ./mv_firmware/firmware/tasmota32* ./firmware/tasmota32/languages/ [ ! -f ./mv_firmware/firmware/* ] || mv ./mv_firmware/firmware/* ./firmware/tasmota/languages/ [ ! -f ./tools/Esptool/ESP32/*.* ] || mv ./tools/Esptool/ESP32/*.* ./firmware/tasmota32/ESP32_needed_files/ - [ ! -f ./tools/Esptool/Odroid_go/*.* ] || mv ./tools/Esptool/Odroid_go/*.* ./firmware/tasmota32/Odroid_go_needed_files/ + [ ! -f ./tools/Esptool/Odroid_go_and_core2/*.* ] || mv ./tools/Esptool/Odroid_go_and_core2/*.* ./firmware/tasmota32/Odroid_go_and_core2_needed_files/ [ ! -f ./FIRMWARE.md ] || mv -f ./RELEASENOTES.md ./README.md - name: Commit files # transfer the new binaries back into the repository run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b5b9e848..87cfc3f1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ All notable changes to this project will be documented in this file. - Optional GUI file editor enabled with define ``GUI_EDIT_FILE`` by barbudor (#11668) - Initial support for universal display driver UDisplay by Gerhard Mutz. Enable by selecting any GPIO as ``Option A3`` (#11665) +### Breaking Changed +- ESP32 partition layout changed to accomodate more file space on most and more code space on core2 and odroid-go (#11746) + ### Changed - In tasmota-sensors.bin enabled support for VL53L0X and disabled TSL2561 (#11711) - Add HLW8012/BL0937 average pulse calculation by Alex Lovett (#11722) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 4a7ba03a6..2036bb721 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -108,6 +108,9 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota - ESP32 support for secondary I2C controller - ESP32 support for internal Hall Effect sensor connected to both GPIO36 and GPIO39 only +### Breaking Changed +- ESP32 partition layout changed to accomodate more file space on most and more code space on core2 and odroid-go [#11746](https://github.com/arendst/Tasmota/issues/11746) + ### Changed - TasmotaSerial library from v3.2.0 to v3.3.0 - PubSubClient library from EspEasy v2.7.12 to Tasmota v2.8.12 diff --git a/boards/esp32c3.json b/boards/esp32c3.json new file mode 100644 index 000000000..bc703484c --- /dev/null +++ b/boards/esp32c3.json @@ -0,0 +1,29 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32c3_out.ld" + }, + "core": "esp32", + "f_cpu": "160000000L", + "f_flash": "80000000L", + "flash_mode": "dio", + "mcu": "esp32c3", + "variant": "esp32c3" + }, + "connectivity": [ + "wifi" + ], + "frameworks": [ + "arduino" + ], + "name": "Espressif ESP32-C3", + "upload": { + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://docs.espressif.com/projects/esp-idf/en/latest", + "vendor": "Espressif" +} diff --git a/boards/esp8266_1M.json b/boards/esp8266_1M.json new file mode 100644 index 000000000..7a0eb335d --- /dev/null +++ b/boards/esp8266_1M.json @@ -0,0 +1,32 @@ +{ + "build": { + "arduino": { + "ldscript": "eagle.flash.1m.ld" + }, + "core": "esp8266", + "extra_flags": "-DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_ESP01", + "f_cpu": "80000000L", + "f_flash": "40000000L", + "flash_mode": "dout", + "mcu": "esp8266", + "variant": "generic" + }, + "connectivity": [ + "wifi" + ], + "frameworks": [ + "arduino", + "esp8266-rtos-sdk", + "esp8266-nonos-sdk" + ], + "name": "Espressif Generic ESP8266 ESP-01 1M", + "upload": { + "maximum_ram_size": 81920, + "maximum_size": 1048576, + "require_upload_port": true, + "resetmethod": "ck", + "speed": 115200 + }, + "url": "http://www.esp8266.com/wiki/doku.php?id=esp8266-module-family", + "vendor": "Espressif" +} diff --git a/lib/default/Ext-printf/src/ext_printf.cpp b/lib/default/Ext-printf/src/ext_printf.cpp index f027d5ba4..5256ea637 100644 --- a/lib/default/Ext-printf/src/ext_printf.cpp +++ b/lib/default/Ext-printf/src/ext_printf.cpp @@ -126,7 +126,7 @@ void * __va_cur_ptr4(va_list &va) { // >>> Reading a_ptr=0x3FFFFD70 *a_ptr=6 // >>> Reading a_ptr=0x3FFFFD74 *a_ptr=7 // >>> Reading a_ptr=0x3FFFFD78 *a_ptr=8 -#elif defined(__RISC_V__) +#elif CONFIG_IDF_TARGET_ESP32C3 // ESP32-C3 RISC_V // #define __va_argsiz_tas(t) (((sizeof(t) + sizeof(int) - 1) / sizeof(int)) * sizeof(int)) #define va_cur_ptr4(va,T) ( (T*) __va_cur_ptr4(va) ) void * __va_cur_ptr4(va_list &va) { diff --git a/lib/default/TasmotaSerial-3.3.0/src/TasmotaSerial.cpp b/lib/default/TasmotaSerial-3.3.0/src/TasmotaSerial.cpp index 0ea060517..db3e3ccfa 100644 --- a/lib/default/TasmotaSerial-3.3.0/src/TasmotaSerial.cpp +++ b/lib/default/TasmotaSerial-3.3.0/src/TasmotaSerial.cpp @@ -42,6 +42,8 @@ TasmotaSerial *tms_obj_list[16]; static int tasmota_serial_index = 2; // Allow UART2 and UART1 only #elif CONFIG_IDF_TARGET_ESP32S2 // ESP32-S2 static int tasmota_serial_index = 1; // Allow UART1 only +#elif CONFIG_IDF_TARGET_ESP32C3 // ESP32-C3 +static int tasmota_serial_index = 1; // Allow UART1 only #endif #endif // ESP32 diff --git a/lib/lib_display/UDisplay/uDisplay.cpp b/lib/lib_display/UDisplay/uDisplay.cpp index 555b0059b..0694a0d3c 100644 --- a/lib/lib_display/UDisplay/uDisplay.cpp +++ b/lib/lib_display/UDisplay/uDisplay.cpp @@ -18,8 +18,6 @@ */ #include -#include -#include #include "uDisplay.h" #define UDSP_DEBUG @@ -42,6 +40,14 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) { sa_mode = 16; saw_3 = 0xff; dim_op = 0xff; + dsp_off = 0xff; + dsp_on = 0xff; + lutpsize = 0; + lutfsize = 0; + lutptime = 35; + lutftime = 350; + lut3time = 10; + ep_mode = 0; startline = 0xA1; uint8_t section = 0; dsp_ncmds = 0; @@ -174,10 +180,20 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) { 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); + if (interface == _UDSP_I2C) { + saw_1 = next_hex(&lp1); + i2c_page_start = next_hex(&lp1); + i2c_page_end = next_hex(&lp1); + saw_2 = next_hex(&lp1); + i2c_col_start = next_hex(&lp1); + i2c_col_end = next_hex(&lp1); + saw_3 = next_hex(&lp1); + } else { + 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); @@ -189,6 +205,31 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) { case 'D': dim_op = next_hex(&lp1); break; + case 'L': + while (1) { + if (!str2c(&lp1, ibuff, sizeof(ibuff))) { + lut_full[lutfsize++] = strtol(ibuff, 0, 16); + } else { + break; + } + if (lutfsize >= sizeof(lut_full)) break; + } + break; + case 'l': + while (1) { + if (!str2c(&lp1, ibuff, sizeof(ibuff))) { + lut_partial[lutpsize++] = strtol(ibuff, 0, 16); + } else { + break; + } + if (lutpsize >= sizeof(lut_partial)) break; + } + break; + case 'T': + lutftime = next_val(&lp1); + lutptime = next_val(&lp1); + lut3time = next_val(&lp1); + break; } } } @@ -200,26 +241,54 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) { lp++; } } + + if (lutfsize && lutpsize) { + ep_mode = 1; + } + #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("xs : %d\n", gxs); + Serial.printf("ys : %d\n", gys); + Serial.printf("bpp: %d\n", bpp); - Serial.printf("opts: %02x,%02x,%02x\n", saw_3, dim_op, startline); + if (interface == _UDSP_SPI) { + 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("SetAddr : %x,%x,%x\n", saw_1, saw_2, saw_3); + Serial.printf("opts: %02x,%02x,%02x\n", saw_3, dim_op, startline); - Serial.printf("Rot 0: %x,%x - %d - %d\n", madctrl, rot[0], x_addr_offs[0], y_addr_offs[0]); + 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]); + + if (ep_mode) { + Serial.printf("LUT_Partial : %d\n", lutpsize); + Serial.printf("LUT_Full : %d\n", lutfsize); + } + } + if (interface == _UDSP_I2C) { + Serial.printf("Addr : %02x\n", i2caddr); + Serial.printf("SCL : %d\n", i2c_scl); + Serial.printf("SDA : %d\n", i2c_sda); + + Serial.printf("SPA : %x\n", saw_1); + Serial.printf("pa_sta: %x\n", i2c_page_start); + Serial.printf("pa_end: %x\n", i2c_page_end); + Serial.printf("SCA : %x\n", saw_2); + Serial.printf("ca_sta: %x\n", i2c_col_start); + Serial.printf("pa_end: %x\n", i2c_col_end); + Serial.printf("WRA : %x\n", saw_3); + } #endif } @@ -237,26 +306,46 @@ Renderer *uDisplay::Init(void) { } if (interface == _UDSP_I2C) { - Wire.begin(i2c_sda, i2c_scl); + wire = &Wire; + wire->begin(i2c_sda, i2c_scl); if (bpp < 16) { if (buffer) free(buffer); #ifdef ESP8266 - buffer = (uint8_t*)calloc((width()*height()*bpp)/8, 1); + buffer = (uint8_t*)calloc((gxs * gys * bpp) / 8, 1); #else if (psramFound()) { - buffer = (uint8_t*)heap_caps_malloc((width()*height()*bpp)/8, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + buffer = (uint8_t*)heap_caps_malloc((gxs * gys * bpp) / 8, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); } else { - buffer = (uint8_t*)calloc((width()*height()*bpp)/8, 1); + buffer = (uint8_t*)calloc((gxs * gys * bpp) / 8, 1); } #endif } +#ifdef UDSP_DEBUG + Serial.printf("I2C cmds: %d\n", dsp_ncmds); +#endif for (uint32_t cnt = 0; cnt < dsp_ncmds; cnt++) { i2c_command(dsp_cmds[cnt]); +#ifdef UDSP_DEBUG + Serial.printf("cmd = %x\n", dsp_cmds[cnt]); +#endif } } if (interface == _UDSP_SPI) { + + if (ep_mode) { + #ifdef ESP8266 + buffer = (uint8_t*)calloc((gxs * gys * bpp) / 8, 1); + #else + if (psramFound()) { + buffer = (uint8_t*)heap_caps_malloc((gxs * gys * bpp) / 8, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + } else { + buffer = (uint8_t*)calloc((gxs * gys * bpp) / 8, 1); + } + #endif + } + if (bpanel >= 0) { #ifdef ESP32 ledcSetup(ESP32_PWM_CHANNEL, 4000, 8); @@ -285,8 +374,6 @@ Renderer *uDisplay::Init(void) { digitalWrite(spi_clk, LOW); pinMode(spi_mosi, OUTPUT); digitalWrite(spi_mosi, LOW); - pinMode(spi_dc, OUTPUT); - digitalWrite(spi_dc, LOW); } #endif // ESP8266 @@ -302,8 +389,6 @@ Renderer *uDisplay::Init(void) { digitalWrite(spi_clk, LOW); pinMode(spi_mosi, OUTPUT); digitalWrite(spi_mosi, LOW); - pinMode(spi_dc, OUTPUT); - digitalWrite(spi_dc, LOW); } #endif // ESP32 @@ -321,7 +406,7 @@ Renderer *uDisplay::Init(void) { uint8_t args = dsp_cmds[index++]; #ifdef UDSP_DEBUG - Serial.printf("cmd, args %x, %d ", iob, args&0x1f); + Serial.printf("cmd, args %02x, %d ", iob, args&0x1f); #endif for (uint32_t cnt = 0; cnt < (args & 0x1f); cnt++) { iob = dsp_cmds[index++]; @@ -343,10 +428,35 @@ Renderer *uDisplay::Init(void) { SPI_END_TRANSACTION } + + // must init luts on epaper + if (ep_mode) { + Init_EPD(DISPLAY_INIT_FULL); + Init_EPD(DISPLAY_INIT_PARTIAL); + } + return this; } -void uDisplay::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) { + +void uDisplay::DisplayInit(int8_t p, int8_t size, int8_t rot, int8_t font) { + if (p !=DISPLAY_INIT_MODE && ep_mode) { + if (p == DISPLAY_INIT_PARTIAL) { + if (lutpsize) { + SetLut(lut_partial); + Updateframe_EPD(); + delay(lutptime * 10); + } + return; + } else if (p == DISPLAY_INIT_FULL) { + if (lutfsize) { + SetLut(lut_full); + Updateframe_EPD(); + delay(lutftime * 10); + } + return; + } + } else { setRotation(rot); invertDisplay(false); setTextWrap(false); @@ -357,6 +467,11 @@ void uDisplay::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) { setCursor(0,0); fillScreen(bg_col); Updateframe(); + +#ifdef UDSP_DEBUG + Serial.printf("Dsp Init complete \n"); +#endif + } } void uDisplay::spi_command(uint8_t val) { @@ -444,25 +559,59 @@ void uDisplay::spi_command_one(uint8_t val) { void uDisplay::i2c_command(uint8_t val) { //Serial.printf("%02x\n",val ); - Wire.beginTransmission(i2caddr); - Wire.write(0); - Wire.write(val); - Wire.endTransmission(); + wire->beginTransmission(i2caddr); + wire->write(0); + wire->write(val); + wire->endTransmission(); } +#define WIRE_MAX 32 + void uDisplay::Updateframe(void) { + if (ep_mode) { + Updateframe_EPD(); + return; + } + if (interface == _UDSP_I2C) { - i2c_command(saw_1 | 0x0); // low col = 0 - i2c_command(saw_2 | 0x0); // hi col = 0 - i2c_command(saw_3 | 0x0); // line #0 + + #if 0 + i2c_command(saw_1); + i2c_command(i2c_page_start); + i2c_command(i2c_page_end); + i2c_command(saw_2); + i2c_command(i2c_col_start); + i2c_command(i2c_col_end); + + uint16_t count = gxs * ((gys + 7) / 8); + uint8_t *ptr = buffer; + wire->beginTransmission(i2caddr); + i2c_command(saw_3); + uint8_t bytesOut = 1; + while (count--) { + if (bytesOut >= WIRE_MAX) { + wire->endTransmission(); + wire->beginTransmission(i2caddr); + i2c_command(saw_3); + bytesOut = 1; + } + i2c_command(*ptr++); + bytesOut++; + } + wire->endTransmission(); +#else + + i2c_command(saw_1 | 0x0); // set low col = 0, 0x00 + i2c_command(i2c_page_start | 0x0); // set hi col = 0, 0x10 + i2c_command(i2c_page_end | 0x0); // set startline line #0, 0x40 uint8_t ys = gys >> 3; uint8_t xs = gxs >> 3; //uint8_t xs = 132 >> 3; - uint8_t m_row = 0; - uint8_t m_col = 2; + uint8_t m_row = saw_2; + uint8_t m_col = i2c_col_start; uint16_t p = 0; @@ -470,24 +619,32 @@ void uDisplay::Updateframe(void) { for ( i = 0; i < ys; i++) { // send a bunch of data in one xmission - i2c_command(0xB0 + i + m_row);//set page address - i2c_command(m_col & 0xf);//set lower column address - i2c_command(0x10 | (m_col >> 4));//set higher column address + i2c_command(0xB0 + i + m_row); //set page address + i2c_command(m_col & 0xf); //set lower column address + i2c_command(0x10 | (m_col >> 4)); //set higher column address - for( j = 0; j < 8; j++){ - Wire.beginTransmission(i2caddr); - Wire.write(0x40); + for ( j = 0; j < 8; j++) { + wire->beginTransmission(i2caddr); + wire->write(0x40); for ( k = 0; k < xs; k++, p++) { - Wire.write(buffer[p]); + wire->write(buffer[p]); } - Wire.endTransmission(); - } + wire->endTransmission(); } } +#endif + } + + } void uDisplay::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { + if (ep_mode) { + drawFastVLine_EPD(x, y, h, color); + return; + } + if (interface != _UDSP_SPI) { Renderer::drawFastVLine(x, y, h, color); return; @@ -528,6 +685,12 @@ void uDisplay::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { void uDisplay::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { + + if (ep_mode) { + drawFastHLine_EPD(x, y, w, color); + return; + } + if (interface != _UDSP_SPI) { Renderer::drawFastHLine(x, y, w, color); return; @@ -575,6 +738,12 @@ void uDisplay::fillScreen(uint16_t color) { // fill a rectangle void uDisplay::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) { + + if (ep_mode) { + fillRect_EPD(x, y, w, h, color); + return; + } + if (interface != _UDSP_SPI) { Renderer::fillRect(x, y, w, h, color); return; @@ -646,6 +815,9 @@ for(y=h; y>0; y--) { void uDisplay::Splash(void) { + if (ep_mode) { + delay(lut3time * 10); + } setTextFont(splash_font); setTextSize(splash_size); DrawStringAt(splash_xp, splash_yp, dname, fg_col, 0); @@ -670,7 +842,7 @@ void uDisplay::setAddrWindow_int(uint16_t x, uint16_t y, uint16_t w, uint16_t h) x += x_addr_offs[cur_rot]; y += y_addr_offs[cur_rot]; - if (sa_mode == 16) { + if (sa_mode != 8) { uint32_t xa = ((uint32_t)x << 16) | (x+w-1); uint32_t ya = ((uint32_t)y << 16) | (y+h-1); @@ -735,11 +907,19 @@ void uDisplay::WriteColor(uint16_t color) { void uDisplay::drawPixel(int16_t x, int16_t y, uint16_t color) { + + if (ep_mode) { + drawPixel_EPD(x, y, color); + return; + } + if (interface != _UDSP_SPI) { Renderer::drawPixel(x, y, color); return; } + + if ((x < 0) || (x >= _width) || (y < 0) || (y >= _height)) return; @@ -763,7 +943,13 @@ void uDisplay::setRotation(uint8_t rotation) { Renderer::setRotation(cur_rot); return; } + if (interface == _UDSP_SPI) { + + if (ep_mode) { + Renderer::setRotation(cur_rot); + return; + } SPI_BEGIN_TRANSACTION SPI_CS_LOW spi_command(madctrl); @@ -801,6 +987,10 @@ void udisp_bpwr(uint8_t on); void uDisplay::DisplayOnff(int8_t on) { + if (ep_mode) { + return; + } + udisp_bpwr(on); if (interface == _UDSP_I2C) { @@ -811,7 +1001,7 @@ void uDisplay::DisplayOnff(int8_t on) { } } else { if (on) { - spi_command_one(dsp_on); + if (dsp_on != 0xff) spi_command_one(dsp_on); if (bpanel >= 0) { #ifdef ESP32 ledcWrite(ESP32_PWM_CHANNEL, dimmer); @@ -821,7 +1011,7 @@ void uDisplay::DisplayOnff(int8_t on) { } } else { - spi_command_one(dsp_off); + if (dsp_off != 0xff) spi_command_one(dsp_off); if (bpanel >= 0) { #ifdef ESP32 ledcWrite(ESP32_PWM_CHANNEL, 0); @@ -834,10 +1024,24 @@ void uDisplay::DisplayOnff(int8_t on) { } void uDisplay::invertDisplay(boolean i) { - if (i) { - spi_command_one(inv_on); - } else { - spi_command_one(inv_off); + + if (ep_mode) { + return; + } + + if (interface == _UDSP_SPI) { + if (i) { + spi_command_one(inv_on); + } else { + spi_command_one(inv_off); + } + } + if (interface == _UDSP_I2C) { + if (i) { + i2c_command(inv_on); + } else { + i2c_command(inv_off); + } } } @@ -845,22 +1049,30 @@ 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 - if (bpanel >= 0) { - ledcWrite(ESP32_PWM_CHANNEL, dimmer); - } else { - udisp_dimm(dim); + + if (ep_mode) { + return; } + + if (interface == _UDSP_SPI) { + if (dimmer > 15) dimmer = 15; + dimmer = ((float)dimmer / 15.0) * 255.0; +#ifdef ESP32 + 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 + + if (dim_op != 0xff) { + SPI_BEGIN_TRANSACTION + SPI_CS_LOW + spi_command(dim_op); + spi_data8(dim); + SPI_CS_HIGH + SPI_END_TRANSACTION + } } } @@ -1033,3 +1245,249 @@ void USECACHE uDisplay::write32(uint32_t val) { GPIO_SET(spi_clk); } } + + +// epaper section + +// EPD2IN9 commands +#define DRIVER_OUTPUT_CONTROL 0x01 +#define BOOSTER_SOFT_START_CONTROL 0x0C +#define GATE_SCAN_START_POSITION 0x0F +#define DEEP_SLEEP_MODE 0x10 +#define DATA_ENTRY_MODE_SETTING 0x11 +#define SW_RESET 0x12 +#define TEMPERATURE_SENSOR_CONTROL 0x1A +#define MASTER_ACTIVATION 0x20 +#define DISPLAY_UPDATE_CONTROL_1 0x21 +#define DISPLAY_UPDATE_CONTROL_2 0x22 +#define WRITE_RAM 0x24 +#define WRITE_VCOM_REGISTER 0x2C +#define WRITE_LUT_REGISTER 0x32 +#define SET_DUMMY_LINE_PERIOD 0x3A +#define SET_GATE_TIME 0x3B +#define BORDER_WAVEFORM_CONTROL 0x3C +#define SET_RAM_X_ADDRESS_START_END_POSITION 0x44 +#define SET_RAM_Y_ADDRESS_START_END_POSITION 0x45 +#define SET_RAM_X_ADDRESS_COUNTER 0x4E +#define SET_RAM_Y_ADDRESS_COUNTER 0x4F +#define TERMINATE_FRAME_READ_WRITE 0xFF + + +void uDisplay::spi_data8_EPD(uint8_t val) { + SPI_BEGIN_TRANSACTION + SPI_CS_LOW + spi_data8(val); + SPI_CS_HIGH + SPI_END_TRANSACTION +} + +void uDisplay::spi_command_EPD(uint8_t val) { + SPI_BEGIN_TRANSACTION + SPI_CS_LOW + spi_command(val); + SPI_CS_HIGH + SPI_END_TRANSACTION +} + +void uDisplay::Init_EPD(int8_t p) { + if (p == DISPLAY_INIT_PARTIAL) { + SetLut(lut_partial); + } else { + SetLut(lut_full); + } + ClearFrameMemory(0xFF); + Updateframe_EPD(); + if (p == DISPLAY_INIT_PARTIAL) { + delay(lutptime * 10); + } else { + delay(lutftime * 10); + } +} + +void uDisplay::ClearFrameMemory(unsigned char color) { + SetMemoryArea(0, 0, gxs - 1, gys - 1); + SetMemoryPointer(0, 0); + spi_command_EPD(WRITE_RAM); + /* send the color data */ + for (int i = 0; i < gxs / 8 * gys; i++) { + spi_data8_EPD(color); + } +} + +void uDisplay::SetLut(const unsigned char* lut) { + spi_command_EPD(WRITE_LUT_REGISTER); + /* the length of look-up table is 30 bytes */ + for (int i = 0; i < lutfsize; i++) { + spi_data8_EPD(lut[i]); + } +} + +void uDisplay::Updateframe_EPD(void) { + SetFrameMemory(buffer, 0, 0, gxs, gys); + DisplayFrame(); +} + +void uDisplay::DisplayFrame(void) { + spi_command_EPD(DISPLAY_UPDATE_CONTROL_2); + spi_data8_EPD(0xC4); + spi_command_EPD(MASTER_ACTIVATION); + spi_data8_EPD(TERMINATE_FRAME_READ_WRITE); +} + +void uDisplay::SetMemoryArea(int x_start, int y_start, int x_end, int y_end) { + spi_command_EPD(SET_RAM_X_ADDRESS_START_END_POSITION); + /* x point must be the multiple of 8 or the last 3 bits will be ignored */ + spi_data8_EPD((x_start >> 3) & 0xFF); + spi_data8_EPD((x_end >> 3) & 0xFF); + spi_command_EPD(SET_RAM_Y_ADDRESS_START_END_POSITION); + spi_data8_EPD(y_start & 0xFF); + spi_data8_EPD((y_start >> 8) & 0xFF); + spi_data8_EPD(y_end & 0xFF); + spi_data8_EPD((y_end >> 8) & 0xFF); +} + +void uDisplay::SetFrameMemory(const unsigned char* image_buffer) { + SetMemoryArea(0, 0, gxs - 1, gys - 1); + SetMemoryPointer(0, 0); + spi_command_EPD(WRITE_RAM); + /* send the image data */ + for (int i = 0; i < gxs / 8 * gys; i++) { + spi_data8_EPD(image_buffer[i] ^ 0xff); + } +} + +void uDisplay::SetMemoryPointer(int x, int y) { + spi_command_EPD(SET_RAM_X_ADDRESS_COUNTER); + /* x point must be the multiple of 8 or the last 3 bits will be ignored */ + spi_data8_EPD((x >> 3) & 0xFF); + spi_command_EPD(SET_RAM_Y_ADDRESS_COUNTER); + spi_data8_EPD(y & 0xFF); + spi_data8_EPD((y >> 8) & 0xFF); +} + +void uDisplay::SetFrameMemory( + const unsigned char* image_buffer, + uint16_t x, + uint16_t y, + uint16_t image_width, + uint16_t image_height +) { + uint16_t x_end; + uint16_t 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 &= 0xFFF8; + image_width &= 0xFFF8; + if (x + image_width >= gxs) { + x_end = gxs - 1; + } else { + x_end = x + image_width - 1; + } + if (y + image_height >= gys) { + y_end = gys - 1; + } else { + y_end = y + image_height - 1; + } + + if (!x && !y && image_width == gxs && image_height == gys) { + SetFrameMemory(image_buffer); + return; + } + + SetMemoryArea(x, y, x_end, y_end); + SetMemoryPointer(x, y); + spi_command_EPD(WRITE_RAM); + /* send the image data */ + 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(image_buffer[i + j * (image_width / 8)]^0xff); + } + } +} + +#define IF_INVERT_COLOR 1 +#define renderer_swap(a, b) { int16_t t = a; a = b; b = t; } +/** + * @brief: this draws a pixel by absolute coordinates. + * this function won't be affected by the rotate parameter. + * we must use this for epaper because these displays have a strange and different bit pattern + */ +void uDisplay::DrawAbsolutePixel(int x, int y, int16_t color) { + + int16_t w = width(), h = height(); + if (cur_rot == 1 || cur_rot == 3) { + renderer_swap(w, h); + } + + if (x < 0 || x >= w || y < 0 || y >= h) { + return; + } + if (IF_INVERT_COLOR) { + if (color) { + buffer[(x + y * w) / 8] |= 0x80 >> (x % 8); + } else { + buffer[(x + y * w) / 8] &= ~(0x80 >> (x % 8)); + } + } else { + if (color) { + buffer[(x + y * w) / 8] &= ~(0x80 >> (x % 8)); + } else { + buffer[(x + y * w) / 8] |= 0x80 >> (x % 8); + } + } +} + +void uDisplay::drawPixel_EPD(int16_t x, int16_t y, uint16_t color) { + if (!buffer) return; + if ((x < 0) || (x >= width()) || (y < 0) || (y >= height())) + return; + + // check rotation, move pixel around if necessary + switch (cur_rot) { + case 1: + renderer_swap(x, y); + x = gxs - x - 1; + break; + case 2: + x = gxs - x - 1; + y = gys - y - 1; + break; + case 3: + renderer_swap(x, y); + y = gys - y - 1; + break; + } + + // x is which column + DrawAbsolutePixel(x, y, color); + +} + + +void uDisplay::fillRect_EPD(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) { + for (uint32_t yp = y; yp < y + h; yp++) { + for (uint32_t xp = x; xp < x + w; xp++) { + drawPixel_EPD(xp , yp , color); + } + } +} +void uDisplay::drawFastVLine_EPD(int16_t x, int16_t y, int16_t h, uint16_t color) { + while (h--) { + drawPixel_EPD(x , y , color); + y++; + } +} +void uDisplay::drawFastHLine_EPD(int16_t x, int16_t y, int16_t w, uint16_t color) { + while (w--) { + drawPixel_EPD(x , y , color); + x++; + } +} diff --git a/lib/lib_display/UDisplay/uDisplay.h b/lib/lib_display/UDisplay/uDisplay.h index f3bc1b277..793b1cc8f 100644 --- a/lib/lib_display/UDisplay/uDisplay.h +++ b/lib/lib_display/UDisplay/uDisplay.h @@ -3,6 +3,8 @@ #include #include +#include +#include #define _UDSP_I2C 1 #define _UDSP_SPI 2 @@ -10,6 +12,10 @@ #define UDISP1_WHITE 1 #define UDISP1_BLACK 0 +#define DISPLAY_INIT_MODE 0 +#define DISPLAY_INIT_PARTIAL 1 +#define DISPLAY_INIT_FULL 2 + enum uColorType { uCOLOR_BW, uCOLOR_COLOR }; // Color definitions @@ -93,7 +99,22 @@ class uDisplay : public Renderer { void write32(uint32_t val); void spi_data9(uint8_t d, uint8_t dc); void WriteColor(uint16_t color); - + void SetLut(const unsigned char* lut); + void DisplayFrame(void); + void Updateframe_EPD(); + void SetFrameMemory(const unsigned char* image_buffer); + void SetFrameMemory(const unsigned char* image_buffer, uint16_t x, uint16_t y, uint16_t image_width, uint16_t image_height); + void SetMemoryArea(int x_start, int y_start, int x_end, int y_end); + void SetMemoryPointer(int x, int y); + void DrawAbsolutePixel(int x, int y, int16_t color); + void drawPixel_EPD(int16_t x, int16_t y, uint16_t color); + void fillRect_EPD(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); + void drawFastVLine_EPD(int16_t x, int16_t y, int16_t h, uint16_t color); + void drawFastHLine_EPD(int16_t x, int16_t y, int16_t w, uint16_t color); + void Init_EPD(int8_t p); + void spi_command_EPD(uint8_t val); + void spi_data8_EPD(uint8_t val); + void ClearFrameMemory(unsigned char color); uint8_t strlen_ln(char *str); int32_t next_val(char **sp); uint32_t next_hex(char **sp); @@ -103,7 +124,12 @@ class uDisplay : public Renderer { uint8_t interface; uint8_t i2caddr; int8_t i2c_scl; + TwoWire *wire; int8_t i2c_sda; + uint8_t i2c_col_start; + uint8_t i2c_col_end; + uint8_t i2c_page_start; + uint8_t i2c_page_end; int8_t reset; uint8_t dsp_cmds[128]; uint8_t dsp_ncmds; @@ -144,6 +170,14 @@ class uDisplay : public Renderer { uint8_t inv_off; uint8_t sa_mode; uint8_t dim_op; + uint8_t lutfsize; + uint8_t lutpsize; + uint16_t lutftime; + uint16_t lutptime; + uint16_t lut3time; + uint8_t ep_mode; + uint8_t lut_full[64]; + uint8_t lut_partial[64]; }; diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp b/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp index 65ceed801..d11d09931 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp @@ -24,6 +24,8 @@ #include "esp32/rom/rtc.h" #elif CONFIG_IDF_TARGET_ESP32S2 // ESP32-S2 #include "esp32s2/rom/rtc.h" + #elif CONFIG_IDF_TARGET_ESP32C3 // ESP32-C3 + #include "esp32c3/rom/rtc.h" #else #error Target CONFIG_IDF_TARGET is not supported #endif diff --git a/platformio.ini b/platformio.ini index 9468f5102..97e8fe901 100644 --- a/platformio.ini +++ b/platformio.ini @@ -26,12 +26,9 @@ extra_configs = platformio_tasmota32.ini [common] framework = arduino -board = esp01_1m board_build.filesystem = littlefs custom_unpack_dir = unpacked_littlefs board_build.flash_mode = dout -board_build.ldscript = eagle.flash.1m.ld - platform = ${core.platform} platform_packages = ${core.platform_packages} build_unflags = ${core.build_unflags} @@ -89,6 +86,7 @@ build_flags = -DCORE_DEBUG_LEVEL=0 [esp82xx_defaults] +board = esp8266_1M build_flags = ${esp_defaults.build_flags} -DNDEBUG -DFP_IN_IROM diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 9821e2e97..66de45c80 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -35,6 +35,7 @@ default_envs = ; tasmota32-ir ; tasmota32-ircustom ; tasmota32solo1 +; tasmota32c3 ; tasmota32s2 ; tasmota32-odroidgo ; tasmota32-core2 @@ -175,15 +176,38 @@ build_flags = ${common32.build_flags} extends = env:tasmota32_base board = esp32s2 board_build.flash_mode = qio -platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/arduino-esp32/releases/download/esp32-2.0.0-pre/esp32-2.0.0-pre.zip +platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/v.2.0.0.pre/framework-arduinoespressif32-master-cf457d412.tar.gz platformio/tool-mklittlefs @ ~1.203.200522 platformio/tool-esptoolpy @ ~1.30000.0 build_unflags = ${esp32_defaults.build_unflags} -build_flags = ${common32.build_flags} +build_flags = ${common32.build_flags} -DFIRMWARE_LITE +lib_extra_dirs = lib/libesp32 +lib_ignore = + NimBLE-Arduino + Micro-RTSP + ESP32-HomeKit + + +; *** EXPERIMENTAL Tasmota version for ESP32-C3 +[env:tasmota32c3] +extends = env:tasmota32_base +board = esp32c3 +platform = https://github.com/Jason2866/platform-espressif32.git#feature/arduino-c3 +platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/v.2.0.0.pre/framework-arduinoespressif32-master-cf457d412.tar.gz + ; needed toolchain for Windows + toolchain-riscv32 @ https://github.com/Jason2866/platform-espressif32/releases/download/8.4.0/riscv32-esp-elf-gcc8_4_0-crosstool-ng-1.24.0-123-g64eb9ff-win32.zip + ; needed toolchain for Linux + ;toolchain-riscv32 @ https://github.com/Jason2866/platform-espressif32/releases/download/8.4.0/riscv32-esp-elf-gcc8_4_0-crosstool-ng-1.24.0-123-g64eb9ff-linux-amd64.tar.gz + ; needed toolchain for MacOS + ;toolchain-riscv32 @ https://github.com/Jason2866/platform-espressif32/releases/download/8.4.0/riscv32-esp-elf-gcc8_4_0-crosstool-ng-1.24.0-123-g64eb9ff-macos.tar.gz + platformio/tool-mklittlefs @ ~1.203.200522 +build_unflags = ${esp32_defaults.build_unflags} -mtarget-align +build_flags = ${esp32_defaults.build_flags} -DFIRMWARE_LITE + ;-DESP32_STAGE=true +lib_extra_dirs = lib/libesp32 lib_ignore = NimBLE-Arduino Micro-RTSP - ESP32 Ethernet ; *** EXPERIMENTAL Tasmota version for Arduino ESP32 IDF4.4. Linking not working. [env:tasmota32idf4] diff --git a/platformio_tasmota32.ini b/platformio_tasmota32.ini index 3a8c42192..0391e8c85 100644 --- a/platformio_tasmota32.ini +++ b/platformio_tasmota32.ini @@ -2,6 +2,7 @@ ; *** expect the unexpected. Some features not working!!! *** [common32] +framework = ${common.framework} platform = ${core32.platform} platform_packages = ${core32.platform_packages} build_unflags = ${core32.build_unflags} @@ -9,7 +10,6 @@ build_flags = ${core32.build_flags} board = esp32dev board_build.filesystem = ${common.board_build.filesystem} custom_unpack_dir = ${common.custom_unpack_dir} -board_build.ldscript = esp32_out.ld board_build.partitions = esp32_partition_app1856k_spiffs320k.csv board_build.flash_mode = ${common.board_build.flash_mode} board_build.f_flash = ${common.board_build.f_flash} diff --git a/platformio_tasmota_env.ini b/platformio_tasmota_env.ini index cd468af55..c0b3e7294 100644 --- a/platformio_tasmota_env.ini +++ b/platformio_tasmota_env.ini @@ -2,9 +2,8 @@ platform = ${common.platform} platform_packages = ${common.platform_packages} framework = ${common.framework} -board = ${common.board} +board = ${esp82xx_defaults.board} board_build.filesystem = ${common.board_build.filesystem} -board_build.ldscript = ${common.board_build.ldscript} board_build.flash_mode = ${common.board_build.flash_mode} board_build.f_flash = ${common.board_build.f_flash} board_build.f_cpu = ${common.board_build.f_cpu} diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini index 54722290c..3a44b2675 100644 --- a/platformio_tasmota_env32.ini +++ b/platformio_tasmota_env32.ini @@ -3,7 +3,6 @@ framework = ${common.framework} platform = ${common32.platform} platform_packages = ${common32.platform_packages} board = ${common32.board} -board_build.ldscript = ${common32.board_build.ldscript} board_build.partitions = ${common32.board_build.partitions} board_build.flash_mode = ${common32.board_build.flash_mode} board_build.f_flash = ${common32.board_build.f_flash} diff --git a/tasmota/displaydesc/ILI9341_desc.txt b/tasmota/displaydesc/ILI9341_desc.txt index c9f6e8964..ccc37bc15 100644 --- a/tasmota/displaydesc/ILI9341_desc.txt +++ b/tasmota/displaydesc/ILI9341_desc.txt @@ -25,10 +25,11 @@ E1,0F,00,0E,14,03,11,07,31,C1,48,08,0F,0C,31,36,0F 29,80 :o,28 :O,29 -:A,2A,2B,2C +:A,2A,2B,2C,16 :R,36 :0,48,00,00,00 :1,28,00,00,01 :2,88,00,00,02 -:3,E8,00,00,02 +:3,E8,00,00,03 +:i,20,21 # diff --git a/tasmota/displaydesc/ILI9342_desc.txt b/tasmota/displaydesc/ILI9342_desc.txt index 0f2b32e35..3e3fc3b09 100644 --- a/tasmota/displaydesc/ILI9342_desc.txt +++ b/tasmota/displaydesc/ILI9342_desc.txt @@ -26,11 +26,12 @@ E1,0F,00,0E,14,03,11,07,31,C1,48,08,0F,0C,31,36,0F 29,80 :o,28 :O,29 -:A,2A,2B,2C +:A,2A,2B,2C,16 :R,36 :0,08,00,00,00 :1,A8,00,00,01 :2,C8,00,00,02 :3,68,00,00,03 +:i,21,20 :TI2,38,22,21 # diff --git a/tasmota/displaydesc/ILI9488_desc.txt b/tasmota/displaydesc/ILI9488_desc.txt index 1aac15cd2..36485fc18 100644 --- a/tasmota/displaydesc/ILI9488_desc.txt +++ b/tasmota/displaydesc/ILI9488_desc.txt @@ -1,4 +1,4 @@ -:H,ILI9488,480,320,16,SPI,1,*,*,*,*,*,*,-1,10 +:H,ILI9488,480,320,16,SPI,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 @@ -18,7 +18,7 @@ F7,4,A9,51,2C,82 29,0 :o,28 :O,29 -:A,2A,2B,2C +:A,2A,2B,2C,16 :R,36 ;:0,48,00,00,00 :0,28,00,00,01 @@ -26,5 +26,6 @@ F7,4,A9,51,2C,82 :2,E8,00,00,03 :3,88,00,00,02 :P,18 -:TI1,38,4,5 +:i,20,21 +:TI1,38,*,* # diff --git a/tasmota/displaydesc/SD1306_desc.txt b/tasmota/displaydesc/SD1306_desc.txt new file mode 100644 index 000000000..15bafcac1 --- /dev/null +++ b/tasmota/displaydesc/SD1306_desc.txt @@ -0,0 +1,24 @@ +:H,SD1306,128,64,1,I2C,3c,*,*,* +:S,0,2,1,0,30,20 +:I +AE +D5,80 +A8,3f +D3,00 +40 +8D,14 +20,00 +A1 +C8 +DA,12 +81,9F +D9F1 +DB,40 +A4 +A6 +AF +:o,AE +:O,AF +:A,00,10,40,00,00 +:i,A6,A7 +# diff --git a/tasmota/displaydesc/SH1106_desc.txt b/tasmota/displaydesc/SH1106_desc.txt index 2d3f76fdf..81948549e 100644 --- a/tasmota/displaydesc/SH1106_desc.txt +++ b/tasmota/displaydesc/SH1106_desc.txt @@ -19,5 +19,6 @@ A6 AF :o,AE :O,AF -:A,00,10,40 +:A,00,10,40,00,02 +:i,A6,A7 # diff --git a/tasmota/displaydesc/SSD1351_desc.txt b/tasmota/displaydesc/SSD1351_desc.txt index 955ffda19..806c8c7a8 100644 --- a/tasmota/displaydesc/SSD1351_desc.txt +++ b/tasmota/displaydesc/SSD1351_desc.txt @@ -1,4 +1,4 @@ -:H,SSD1351,128,128,16,SPI,1,*,*,*,-1,-1,-1,-1,10 +:H,SSD1351,128,128,16,SPI,1,*,*,*,*,*,*,*,10 :S,1,1,1,0,40,10 :I FD,1,12 diff --git a/tasmota/displaydesc/ST7789_desc.txt b/tasmota/displaydesc/ST7789_desc.txt index fcdbd389c..6b21397ac 100644 --- a/tasmota/displaydesc/ST7789_desc.txt +++ b/tasmota/displaydesc/ST7789_desc.txt @@ -1,5 +1,5 @@ -:H,ST7789,240,240,16,SPI,1,*,*,*,*,*,-1,-1,40 +:H,ST7789,240,240,16,SPI,1,*,*,*,*,*,*,*,40 :S,2,1,3,0,80,30 :I 01,A0 @@ -17,5 +17,6 @@ :1,A0,50,00,01 :2,00,00,00,02 :3,60,00,00,03 +i:20,21 :TI2,38,32,23 # diff --git a/tasmota/displaydesc/WS_epaper29_desc.txt b/tasmota/displaydesc/WS_epaper29_desc.txt new file mode 100644 index 000000000..6a8b455fb --- /dev/null +++ b/tasmota/displaydesc/WS_epaper29_desc.txt @@ -0,0 +1,17 @@ +H,E-PAPER-29,128,296,1,SPI,1,*,*,*,*,*,*,*,10 +:S,1,1,1,0,10,10 +:I +01,3,27,01,00 +0C,3,D7,D6,9D +2C,1,A8 +3A,1,1A +3B,1,08 +11,1,03 +:L +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 +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 +# diff --git a/tasmota/displaydesc/readme.md b/tasmota/displaydesc/readme.md new file mode 100644 index 000000000..a9e29555d --- /dev/null +++ b/tasmota/displaydesc/readme.md @@ -0,0 +1,19 @@ +Display Descriptor files for use with universal display driver. +2 (3) options to select a display driver + +1. file system driven if UFILESYSTEM is in place (preferred option for normal use) + to select a display rename the file to "dispdesc.txt" and put into flash file system. +2. scripter driven as a special section >d in scripter. + copy the file to a script section >d and place a ->displayreinit cmd into the >B section + (preferred for developing or modifying display driver) +3. rule buffer 3 driven + copy descriptor to rule buffer number 3 but do not enable rule 3 + (descriptor may not contain ANY spaces in this mode) +(4.) compile the descriptor into driver. + convert the file to a const char array and place into source xdsp_universal.ino + and replace the example array there + #define DSP_ROM_DESC + +for further info about display descriptors read the tasmota docs display part. + +the current files define the standard resolutions. if you change the resolution settings +sometimes you also have to change some register values in the init or address map section diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 42498308e..9870ca0a3 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -256,7 +256,7 @@ #define D_CONFIGURATION "Einstellungen" #define D_INFORMATION "Informationen" #define D_FIRMWARE_UPGRADE "Firmware Update" -#define D_MANAGEMENT "Consoles" +#define D_MANAGEMENT "Konsolen" #define D_CONSOLE "Konsole" #define D_CONFIRM_RESTART "Wirklich neustarten?" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index bac302306..b79b4b456 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -1,5 +1,5 @@ /* - es-ES.h - localization for Spanish - Spain for Tasmota (translation also valid for all latinamerica) + es-ES.h - localization for Spanish - Spain for Tasmota (International Spanish valid for all latinamerica) Copyright (C) 2021 Adrian Scillato @@ -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 + * Updated until v9.3.1.3 \*********************************************************************/ #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -256,7 +256,7 @@ #define D_CONFIGURATION "Configuración" #define D_INFORMATION "Información" #define D_FIRMWARE_UPGRADE "Actualizar Firmware" -#define D_MANAGEMENT "Consoles" +#define D_MANAGEMENT "Consolas" #define D_CONSOLE "Consola" #define D_CONFIRM_RESTART "Confirmar Reinicio" @@ -926,9 +926,9 @@ #define D_MANAGE_FILE_SYSTEM "Explorar Archivos" #define D_FS_SIZE "Tamaño" #define D_FS_FREE "Libre" -#define D_NEW_FILE "newfile.txt" -#define D_CREATE_NEW_FILE "Create and edit new file" -#define D_EDIT_FILE "Edit File" +#define D_NEW_FILE "nuevo.txt" +#define D_CREATE_NEW_FILE "Crear y editar un archivo nuevo" +#define D_EDIT_FILE "Editar Archivo" //xsns_67_as3935.ino #define D_AS3935_GAIN "Ganancia:" @@ -946,7 +946,7 @@ #define D_AS3935_DISTDET "Perturbancia detectada" #define D_AS3935_INTNOEV "Interrupción sin evento!" #define D_AS3935_FLICKER "IRQ flicker!" -#define D_AS3935_POWEROFF "Power Off" +#define D_AS3935_POWEROFF "Apagado" #define D_AS3935_NOMESS "Escuchando..." #define D_AS3935_ON "Encendido" #define D_AS3935_OFF "Apagado" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 96eb91ee0..ab529c2e4 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.3 - Last update 14.04.2021 + * Updated until v9.3.1.3 - Last update 16.04.2021 \*********************************************************************/ #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -256,7 +256,7 @@ #define D_CONFIGURATION "Impostazioni" #define D_INFORMATION "Informazioni" #define D_FIRMWARE_UPGRADE "Aggiorna firmware" -#define D_MANAGEMENT "Consoles" +#define D_MANAGEMENT "Console" #define D_CONSOLE "Console" #define D_CONFIRM_RESTART "Conferma riavvio" @@ -268,8 +268,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" diff --git a/tasmota/support_esp.ino b/tasmota/support_esp.ino index a1a469b96..e5a9b40d6 100644 --- a/tasmota/support_esp.ino +++ b/tasmota/support_esp.ino @@ -78,6 +78,27 @@ void *special_realloc(void *ptr, size_t size) { return realloc(ptr, size); } +String GetDeviceHardware(void) { + char buff[10]; + // esptool.py get_efuses + uint32_t efuse1 = *(uint32_t*)(0x3FF00050); + uint32_t efuse2 = *(uint32_t*)(0x3FF00054); +// uint32_t efuse3 = *(uint32_t*)(0x3FF00058); +// uint32_t efuse4 = *(uint32_t*)(0x3FF0005C); + + bool is_8285 = ( (efuse1 & (1 << 4)) || (efuse2 & (1 << 16)) ); + if (is_8285 && (ESP.getFlashChipRealSize() > 1048576)) { + is_8285 = false; // ESP8285 can only have 1M flash + } + if (is_8285) { + strcpy_P(buff, PSTR("ESP8285")); + } else { + strcpy_P(buff, PSTR("ESP8266EX")); + } + + return String(buff); +} + #endif /*********************************************************************************************\ @@ -96,6 +117,8 @@ void *special_realloc(void *ptr, size_t size) { #include "esp32/rom/rtc.h" #elif CONFIG_IDF_TARGET_ESP32S2 // ESP32-S2 #include "esp32s2/rom/rtc.h" + #elif CONFIG_IDF_TARGET_ESP32C3 // ESP32-C3 + #include "esp32c3/rom/rtc.h" #else #error Target CONFIG_IDF_TARGET is not supported #endif @@ -221,6 +244,8 @@ extern "C" { #include "esp32/rom/spi_flash.h" #elif CONFIG_IDF_TARGET_ESP32S2 // ESP32-S2 #include "esp32s2/rom/spi_flash.h" + #elif CONFIG_IDF_TARGET_ESP32C3 // ESP32-C3 + #include "esp32c3/rom/spi_flash.h" #else #error Target CONFIG_IDF_TARGET is not supported #endif @@ -476,43 +501,158 @@ float CpuTemperature(void) { return ConvertTemp(temperatureRead()); } +/* +#if CONFIG_IDF_TARGET_ESP32S2 +#include "esp32s2/esp_efuse.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/esp_efuse.h" +#elif CONFIG_IDF_TARGET_ESP32C3 +#include "esp32c3/esp_efuse.h" +#endif +*/ + +String GetDeviceHardware(void) { +/* +Source: esp-idf esp_system.h and esptool + +typedef enum { + CHIP_ESP32 = 1, //!< ESP32 + CHIP_ESP32S2 = 2, //!< ESP32-S2 + CHIP_ESP32S3 = 4, //!< ESP32-S3 + CHIP_ESP32C3 = 5, //!< ESP32-C3 +} esp_chip_model_t; + +// Chip feature flags, used in esp_chip_info_t +#define CHIP_FEATURE_EMB_FLASH BIT(0) //!< Chip has embedded flash memory +#define CHIP_FEATURE_WIFI_BGN BIT(1) //!< Chip has 2.4GHz WiFi +#define CHIP_FEATURE_BLE BIT(4) //!< Chip has Bluetooth LE +#define CHIP_FEATURE_BT BIT(5) //!< Chip has Bluetooth Classic + +// The structure represents information about the chip +typedef struct { + esp_chip_model_t model; //!< chip model, one of esp_chip_model_t + uint32_t features; //!< bit mask of CHIP_FEATURE_x feature flags + uint8_t cores; //!< number of CPU cores + uint8_t revision; //!< chip revision number +} esp_chip_info_t; + +*/ + esp_chip_info_t chip_info; + esp_chip_info(&chip_info); + + uint32_t chip_model = chip_info.model; + uint32_t chip_revision = chip_info.revision; +// uint32_t chip_revision = ESP.getChipRevision(); + bool rev3 = (3 == chip_revision); +// bool single_core = (1 == ESP.getChipCores()); + bool single_core = (1 == chip_info.cores); + + if (chip_model < 2) { // ESP32 +#ifdef CONFIG_IDF_TARGET_ESP32 +/* esptool: + def get_pkg_version(self): + word3 = self.read_efuse(3) + pkg_version = (word3 >> 9) & 0x07 + pkg_version += ((word3 >> 2) & 0x1) << 3 + return pkg_version +*/ + uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG); + uint32_t pkg_version = chip_ver & 0x7; + + switch (pkg_version) { + case 0: + if (single_core) { return F("ESP32-S0WDQ6"); } + else { return F("ESP32-D0WDQ6"); } + case 1: + if (single_core) { return F("ESP32-S0WD"); } + else { return F("ESP32-D0WD"); } + case 2: return F("ESP32-D2WD"); + case 4: return F("ESP32-U4WDH"); + case 5: + if (rev3) { return F("ESP32-PICO-V3"); } + else { return F("ESP32-PICO-D4"); } + case 6: return F("ESP32-PICO-V3-02"); + } +#endif // CONFIG_IDF_TARGET_ESP32 + return F("ESP32"); + } + else if (2 == chip_model) { // ESP32-S2 +#ifdef CONFIG_IDF_TARGET_ESP32S2 +/* esptool: + def get_pkg_version(self): + num_word = 3 + block1_addr = self.EFUSE_BASE + 0x044 + word3 = self.read_reg(block1_addr + (4 * num_word)) + pkg_version = (word3 >> 21) & 0x0F + return pkg_version +*/ + uint32_t chip_ver = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_PKG_VERSION); + uint32_t pkg_version = chip_ver & 0x7; +// uint32_t pkg_version = esp_efuse_get_pkg_ver(); + + switch (pkg_version) { + case 0: return F("ESP32-S2"); + case 1: return F("ESP32-S2FH16"); + case 2: return F("ESP32-S2FH32"); + } +#endif // CONFIG_IDF_TARGET_ESP32S2 + return F("ESP32-S2"); + } + else if (4 == chip_model) { // ESP32-S3 + return F("ESP32-S3"); + } + else if (5 == chip_model) { // ESP32-C3 +#ifdef CONFIG_IDF_TARGET_ESP32C3 +/* esptool: + def get_pkg_version(self): + num_word = 3 + block1_addr = self.EFUSE_BASE + 0x044 + word3 = self.read_reg(block1_addr + (4 * num_word)) + pkg_version = (word3 >> 21) & 0x0F + return pkg_version +*/ + uint32_t chip_ver = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_PKG_VERSION); + uint32_t pkg_version = chip_ver & 0x7; +// uint32_t pkg_version = esp_efuse_get_pkg_ver(); + + switch (pkg_version) { + case 0: return F("ESP32-C3"); + } +#endif // CONFIG_IDF_TARGET_ESP32C3 + return F("ESP32-C3"); + } + else if (6 == chip_model) { // ESP32-S3(beta3) + return F("ESP32-S3(beta3)"); + } + else if (7 == chip_model) { // ESP32-C6 +#ifdef CONFIG_IDF_TARGET_ESP32C6 +/* esptool: + def get_pkg_version(self): + num_word = 3 + block1_addr = self.EFUSE_BASE + 0x044 + word3 = self.read_reg(block1_addr + (4 * num_word)) + pkg_version = (word3 >> 21) & 0x0F + return pkg_version +*/ + uint32_t chip_ver = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_PKG_VERSION); + uint32_t pkg_version = chip_ver & 0x7; +// uint32_t pkg_version = esp_efuse_get_pkg_ver(); + + switch (pkg_version) { + case 0: return F("ESP32-C6"); + } +#endif // CONFIG_IDF_TARGET_ESP32C6 + return F("ESP32-C6"); + } + return F("ESP32"); +} + #endif // ESP32 /*********************************************************************************************\ * ESP Support \*********************************************************************************************/ -String GetDeviceHardware(void) { - char buff[10]; -#ifdef ESP8266 - // esptool.py get_efuses - uint32_t efuse1 = *(uint32_t*)(0x3FF00050); - uint32_t efuse2 = *(uint32_t*)(0x3FF00054); -// uint32_t efuse3 = *(uint32_t*)(0x3FF00058); -// uint32_t efuse4 = *(uint32_t*)(0x3FF0005C); - - bool is_8285 = ( (efuse1 & (1 << 4)) || (efuse2 & (1 << 16)) ); - if (is_8285 && (ESP.getFlashChipRealSize() > 1048576)) { - is_8285 = false; // ESP8285 can only have 1M flash - } - if (is_8285) { - strcpy_P(buff, PSTR("ESP8285")); - } else { - strcpy_P(buff, PSTR("ESP8266EX")); - } -#endif // ESP8266 - -#ifdef ESP32 -#if CONFIG_IDF_TARGET_ESP32S2 // ESP32-S2 - strcpy_P(buff, PSTR("ESP32-S2")); -#else - strcpy_P(buff, PSTR("ESP32")); -#endif // CONFIG_IDF_TARGET_ESP32S2 -#endif // ESP32 - - return String(buff); -} - uint32_t ESP_getFreeHeap1024(void) { return ESP_getFreeHeap() / 1024; } diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index bd8c392ee..e0ad51e8e 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -87,8 +87,10 @@ const uint16_t VL53L0X_MAX_SENSORS = 8; // Max number of VL53L0X sensors #ifdef ESP32 const uint8_t MAX_I2C = 2; // Max number of I2C controllers (ESP32 = 2) +const uint8_t MAX_SPI = 2; // Max number of Hardware SPI controllers (ESP32 = 2) #else const uint8_t MAX_I2C = 0; // Max number of I2C controllers (ESP8266 = 0, no choice) +const uint8_t MAX_SPI = 0; // Max number of Hardware SPI controllers (ESP8266 = 0, no choice) #endif // Changes to the following MAX_ defines need to be in line with enum SettingsTextIndex diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 74940db07..913889e49 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -407,11 +407,11 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif #ifdef USE_SPI - AGPIO(GPIO_SPI_MISO), // SPI MISO - AGPIO(GPIO_SPI_MOSI), // SPI MOSI - AGPIO(GPIO_SPI_CLK), // SPI Clk - AGPIO(GPIO_SPI_CS), // SPI Chip Select - AGPIO(GPIO_SPI_DC), // SPI Data Direction + AGPIO(GPIO_SPI_MISO) + MAX_SPI, // SPI MISO + AGPIO(GPIO_SPI_MOSI) + MAX_SPI, // SPI MOSI + AGPIO(GPIO_SPI_CLK) + MAX_SPI, // SPI Clk + AGPIO(GPIO_SPI_CS) + MAX_SPI, // SPI Chip Select + AGPIO(GPIO_SPI_DC) + MAX_SPI, // SPI Data Direction #ifdef USE_NRF24 AGPIO(GPIO_NRF24_CS), AGPIO(GPIO_NRF24_DC), diff --git a/tasmota/user_config_override_sample.h b/tasmota/user_config_override_sample.h index ae434bb9c..3bfa1269f 100644 --- a/tasmota/user_config_override_sample.h +++ b/tasmota/user_config_override_sample.h @@ -20,9 +20,6 @@ #ifndef _USER_CONFIG_OVERRIDE_H_ #define _USER_CONFIG_OVERRIDE_H_ -// force the compiler to show a warning to confirm that this file is included -#warning **** user_config_override.h: Using Settings from this File **** - /*****************************************************************************************************\ * USAGE: * To modify the stock configuration without changing the my_user_config.h file: diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index f18cc0b4b..1e1dece40 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -2359,7 +2359,7 @@ void HandleInformation(void) #endif // USE_DISCOVERY WSContentSend_P(PSTR("}1}2 ")); // Empty line - WSContentSend_P(PSTR("}1" D_ESP_CHIP_ID "}2%d"), ESP_getChipId()); + WSContentSend_P(PSTR("}1" D_ESP_CHIP_ID "}2%d (%s)"), ESP_getChipId(), GetDeviceHardware().c_str()); #ifdef ESP8266 WSContentSend_P(PSTR("}1" D_FLASH_CHIP_ID "}20x%06X"), ESP.getFlashChipId()); #endif diff --git a/tasmota/xdrv_50_filesystem.ino b/tasmota/xdrv_50_filesystem.ino index 6f3289145..51d178f40 100644 --- a/tasmota/xdrv_50_filesystem.ino +++ b/tasmota/xdrv_50_filesystem.ino @@ -588,15 +588,15 @@ const char UFS_FORM_SDC_HREFedit[] PROGMEM = "📝"; // 📝 const char HTTP_EDITOR_FORM_START[] PROGMEM = - "
 " D_EDIT_FILE " " - "
" - "

" - "" - "" - "
"; + "" + "" + ""; #endif // #ifdef GUI_EDIT_FILE @@ -905,7 +905,6 @@ void UfsUploadFileClose(void) { ufs_upload_file.close(); } - //****************************************************************************************** // File Editor //****************************************************************************************** @@ -917,45 +916,44 @@ void UfsEditor(void) { AddLog(LOG_LEVEL_DEBUG, PSTR("UFS: UfsEditor GET")); - String fname; + char fname_input[UFS_FILENAME_SIZE]; if (Webserver->hasArg(F("file"))) { - fname = Webserver->arg(F("file")); + WebGetArg(PSTR("file"), fname_input, sizeof(fname_input)); + } else { + snprintf_P(fname_input, sizeof(fname_input), PSTR(D_NEW_FILE)); } - else { - fname = D_NEW_FILE; - } - if (fname[0] != '/') fname = "/" +fname; + char fname[UFS_FILENAME_SIZE]; + UfsFilename(fname, fname_input); // Trim spaces and add slash - AddLog(LOG_LEVEL_DEBUG, PSTR("UFS: UfsEditor: file=%s, ffs_type=%d, TfsFileExist=%d"), fname.c_str(), ffs_type, TfsFileExists(fname.c_str())); + AddLog(LOG_LEVEL_DEBUG, PSTR("UFS: UfsEditor: file=%s, ffs_type=%d, TfsFileExist=%d"), fname, ffs_type, TfsFileExists(fname)); WSContentStart_P(PSTR(D_EDIT_FILE)); WSContentSendStyle(); - WSContentSend_P(HTTP_EDITOR_FORM_START, fname.c_str()); + char *bfname = fname +1; + WSContentSend_P(HTTP_EDITOR_FORM_START, bfname); // Skip leading slash - if (ffs_type && TfsFileExists(fname.c_str())) { - File fp = ffsp->open(fname.c_str(), "r"); + if (ffs_type && TfsFileExists(fname)) { + File fp = ffsp->open(fname, "r"); if (!fp) { AddLog(LOG_LEVEL_DEBUG, PSTR("UFS: UfsEditor: file open failed")); WSContentSend_P(D_NEW_FILE); + } else { + uint8_t *buf = (uint8_t*)malloc(FILE_BUFFER_SIZE+1); + size_t filelen = fp.size(); + AddLog(LOG_LEVEL_DEBUG, PSTR("UFS: UfsEditor: file len=%d"), filelen); + while (filelen > 0) { + size_t l = fp.read(buf, FILE_BUFFER_SIZE); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("UFS: UfsEditor: read=%d"), l); + if (l < 0) { break; } + buf[l] = '\0'; + WSContentSend_P((const char*)buf); + filelen -= l; + } + fp.close(); + free(buf); + AddLog(LOG_LEVEL_DEBUG, PSTR("UFS: UfsEditor: read done")); } - else { - uint8_t *buf = (uint8_t*)malloc(FILE_BUFFER_SIZE+1); - size_t filelen = fp.size(); - AddLog(LOG_LEVEL_DEBUG, PSTR("UFS: UfsEditor: file len=%d"), filelen); - while ( filelen > 0 ) { - size_t l = fp.read(buf, FILE_BUFFER_SIZE); - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("UFS: UfsEditor: read=%d"), l); - if (l < 0) break; - buf[l] = '\0'; - WSContentSend_P((const char*)buf); - filelen -= l; - } - fp.close(); - free(buf); - AddLog(LOG_LEVEL_DEBUG, PSTR("UFS: UfsEditor: read done")); - } - } - else { + } else { WSContentSend_P(D_NEW_FILE); } @@ -974,8 +972,12 @@ void UfsEditorUpload(void) { WSSend(400, CT_PLAIN, F("400: Bad request - no filename")); return; } - String name = Webserver->arg("name"); - AddLog(LOG_LEVEL_DEBUG, PSTR("UFS: UfsEditor: file '%s'"), name.c_str()); + + char fname_input[UFS_FILENAME_SIZE]; + WebGetArg(PSTR("name"), fname_input, sizeof(fname_input)); + char fname[UFS_FILENAME_SIZE]; + UfsFilename(fname, fname_input); // Trim spaces and add slash + AddLog(LOG_LEVEL_DEBUG, PSTR("UFS: UfsEditor: file '%s'"), fname); if (!Webserver->hasArg("content")) { AddLog(LOG_LEVEL_ERROR, PSTR("UFS: UfsEditor: file upload - no content")); @@ -991,10 +993,10 @@ void UfsEditorUpload(void) { return; } - File fp = ffsp->open(name.c_str(), "w"); - if(!fp) { + File fp = ffsp->open(fname, "w"); + if (!fp) { Web.upload_error = 1; - AddLog(LOG_LEVEL_ERROR, PSTR("UFS: UfsEditor: 400: invalid file name '%s'"), name.c_str()); + AddLog(LOG_LEVEL_ERROR, PSTR("UFS: UfsEditor: 400: invalid file name '%s'"), fname); WSSend(400, CT_PLAIN, F("400: bad request - invalid filename")); return; } @@ -1005,7 +1007,7 @@ void UfsEditorUpload(void) { } if (!fp.print(content)) { - AddLog(LOG_LEVEL_ERROR, PSTR("UFS: UfsEditor: write error on '%s'"), name.c_str()); + AddLog(LOG_LEVEL_ERROR, PSTR("UFS: UfsEditor: write error on '%s'"), fname); } fp.close(); @@ -1014,7 +1016,7 @@ void UfsEditorUpload(void) { Webserver->send(303); } -#endif // #ifdef GUI_EDIT_FILE +#endif // GUI_EDIT_FILE #endif // USE_WEBSERVER diff --git a/tasmota/xdrv_52_3_berry_light.ino b/tasmota/xdrv_52_3_berry_light.ino index 2f3832234..aadeea032 100644 --- a/tasmota/xdrv_52_3_berry_light.ino +++ b/tasmota/xdrv_52_3_berry_light.ino @@ -24,8 +24,8 @@ #include /*********************************************************************************************\ - * - * + * + * \*********************************************************************************************/ extern "C" { @@ -43,7 +43,7 @@ extern "C" { if (Light.device > 0) { // we have a light - + uint8_t channels[LST_MAX]; char s_rgb[8] = {0}; // RGB raw levels light_controller.calcLevels(channels); @@ -207,7 +207,7 @@ extern "C" { // channels if (map_find(vm, "channels")) { if (be_isinstance(vm, -1)) { - be_getbuiltin(vm, "list"); // add "list" class + be_getbuiltin(vm, "list"); // add "list" class if (be_isderived(vm, -2)) { be_pop(vm, 1); // remove "list" class from top int32_t list_size = get_list_size(vm); @@ -303,9 +303,9 @@ extern "C" { } int32_t l_getlight(struct bvm *vm) __attribute__ ((weak, alias ("b_light_missing"))); int32_t l_setlight(struct bvm *vm) __attribute__ ((weak, alias ("b_light_missing"))); - int32_t gamma8(struct bvm *vm) __attribute__ ((weak, alias ("b_light_missing"))); - int32_t gamma10(struct bvm *vm) __attribute__ ((weak, alias ("b_light_missing"))); - int32_t reverse_gamma10(struct bvm *vm) __attribute__ ((weak, alias ("b_light_missing"))); + int32_t l_gamma8(struct bvm *vm) __attribute__ ((weak, alias ("b_light_missing"))); + int32_t l_gamma10(struct bvm *vm) __attribute__ ((weak, alias ("b_light_missing"))); + int32_t l_rev_gamma10(struct bvm *vm) __attribute__ ((weak, alias ("b_light_missing"))); #endif // #ifdef USE_LIGHT } diff --git a/tasmota/xdsp_17_universal.ino b/tasmota/xdsp_17_universal.ino index 419a94d12..b91cc0550 100644 --- a/tasmota/xdsp_17_universal.ino +++ b/tasmota/xdsp_17_universal.ino @@ -71,7 +71,8 @@ const char DSP_SAMPLE_DESC[] PROGMEM = ":o,AE\n" // switch display on ":O,AF\n" -":A,00,10,40\n" +":A,00,10,40,00,02\n" +":i,A6,A7\n" "#\n"; #endif // DSP_ROM_DESC @@ -117,6 +118,24 @@ char *fbuff; } #endif // USE_SCRIPT +#ifdef USE_RULES + if (!bitRead(Settings.rule_enabled, 2) && !ddesc) { + // only if rule3 is not enabled for rules + char *cp = Settings.rules[2]; + while (*cp == ' ') cp++; + memcpy(fbuff, cp, DISPDESC_SIZE - 1); + if (fbuff[0] == ':' && fbuff[1] == 'H') { + // assume display descriptor, replace space with line feed + for (uint32_t cnt = 0; cnt < DISPDESC_SIZE; cnt++) { + if (fbuff[cnt] == ' ') fbuff[cnt] = '\n'; + } + ddesc = fbuff; + AddLog(LOG_LEVEL_INFO, PSTR("DSP: Rule 3 descriptor used")); + } + + } +#endif // USE_RULES + #ifdef DSP_ROM_DESC if (!ddesc) { @@ -176,17 +195,16 @@ char *fbuff; } } - // init renderer - if (udisp) delete udisp; - udisp = new uDisplay(ddesc); - /* File fp; fp = ffsp->open("/dump.txt", "w"); fp.write((uint8_t*)ddesc, DISPDESC_SIZE); fp.close(); - */ +*/ + // init renderer + if (udisp) delete udisp; + udisp = new uDisplay(ddesc); // checck for touch option TI1 or TI2 #ifdef USE_FT5206 diff --git a/tools/Esptool/ESP32/partitions.bin b/tools/Esptool/ESP32/partitions.bin index 7ae174cb4..f1e66d048 100644 Binary files a/tools/Esptool/ESP32/partitions.bin and b/tools/Esptool/ESP32/partitions.bin differ