From 21656fdd81bc177a02f81eb58fe8e9945f6aecd0 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Mon, 18 May 2020 10:19:13 +0200 Subject: [PATCH 1/4] ra8876 esp32 --- lib/Xlatb_RA8876-gemu-1.0/RA8876.cpp | 52 ++++++++++++++++++++++++---- lib/Xlatb_RA8876-gemu-1.0/RA8876.h | 1 + tasmota/xdsp_10_RA8876.ino | 17 +++++++-- 3 files changed, 61 insertions(+), 9 deletions(-) diff --git a/lib/Xlatb_RA8876-gemu-1.0/RA8876.cpp b/lib/Xlatb_RA8876-gemu-1.0/RA8876.cpp index 850b2bb8a..1d9a893e4 100644 --- a/lib/Xlatb_RA8876-gemu-1.0/RA8876.cpp +++ b/lib/Xlatb_RA8876-gemu-1.0/RA8876.cpp @@ -66,13 +66,14 @@ RA8876::RA8876(int8_t cs,int8_t mosi,int8_t miso,int8_t sclk,int8_t bp) : Render //#define RA8876_CS_LOW digitalWrite(m_csPin, LOW) //#define RA8876_CS_HIGH digitalWrite(m_csPin, HIGH) -#ifdef ESP8266 +#ifndef ESP32 #define RA8876_CS_LOW GPOC=(1<= 0x21) || (c <= 0x7F))) diff --git a/lib/Xlatb_RA8876-gemu-1.0/RA8876.h b/lib/Xlatb_RA8876-gemu-1.0/RA8876.h index b27698027..5bf8b404f 100644 --- a/lib/Xlatb_RA8876-gemu-1.0/RA8876.h +++ b/lib/Xlatb_RA8876-gemu-1.0/RA8876.h @@ -23,6 +23,7 @@ #include #include +#undef SPRINT #define SPRINT(A) {char str[32];sprintf(str,"val: %d ",A);Serial.println((char*)str);} diff --git a/tasmota/xdsp_10_RA8876.ino b/tasmota/xdsp_10_RA8876.ino index 9c86ff2d7..6a44708cb 100644 --- a/tasmota/xdsp_10_RA8876.ino +++ b/tasmota/xdsp_10_RA8876.ino @@ -71,11 +71,24 @@ void RA8876_InitDriver() fg_color = RA8876_WHITE; bg_color = RA8876_BLACK; +#ifdef ESP32 +#define HW_SPI_MOSI 23 +#define HW_SPI_MISO 19 +#define HW_SPI_CLK 18 +#else +#undef HW_SPI_MOSI +#define HW_SPI_MOSI 13 +#undef HW_SPI_MISO +#define HW_SPI_MISO 12 +#undef HW_SPI_CLK +#define HW_SPI_CLK 14 +#endif + // init renderer, must use hardware spi - if (PinUsed(GPIO_SSPI_CS) && (Pin(GPIO_SSPI_MOSI)==13) && (Pin(GPIO_SSPI_MISO)==12) && (Pin(GPIO_SSPI_SCLK)==14)) { + if (PinUsed(GPIO_SSPI_CS) && (Pin(GPIO_SSPI_MOSI)==HW_SPI_MOSI) && (Pin(GPIO_SSPI_MISO)==HW_SPI_MISO) && (Pin(GPIO_SSPI_SCLK)==HW_SPI_CLK)) { ra8876 = new RA8876(Pin(GPIO_SSPI_CS),Pin(GPIO_SSPI_MOSI),Pin(GPIO_SSPI_MISO),Pin(GPIO_SSPI_SCLK),Pin(GPIO_BACKLIGHT)); } else { - if (PinUsed(GPIO_SPI_CS) && (Pin(GPIO_SPI_MOSI)==13) && (Pin(GPIO_SPI_MISO)==12) && (Pin(GPIO_SPI_CLK)==14)) { + if (PinUsed(GPIO_SPI_CS) && (Pin(GPIO_SPI_MOSI)==HW_SPI_MOSI) && (Pin(GPIO_SPI_MISO)==HW_SPI_MISO) && (Pin(GPIO_SPI_CLK)==HW_SPI_CLK)) { ra8876 = new RA8876(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_MOSI),Pin(GPIO_SPI_MISO),Pin(GPIO_SPI_CLK),Pin(GPIO_BACKLIGHT)); } else { return; From 88627a5a41a99e2ec53ec66942b93e27e01f6277 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Mon, 18 May 2020 10:25:18 +0200 Subject: [PATCH 2/4] support for jpeg pictures on color lcds --- tasmota/support_jpeg.ino | 157 ++++++++++++++++++++++++++++++++++++ tasmota/xdrv_13_display.ino | 122 +++++++++++++++++++++------- 2 files changed, 249 insertions(+), 30 deletions(-) create mode 100644 tasmota/support_jpeg.ino diff --git a/tasmota/support_jpeg.ino b/tasmota/support_jpeg.ino new file mode 100644 index 000000000..7e811cd76 --- /dev/null +++ b/tasmota/support_jpeg.ino @@ -0,0 +1,157 @@ +/* + jpeg_utils.c - Version header file for Tasmota + + Copyright (C) 2020 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#ifdef ESP32 +#ifdef JPEG_PICTS + +#include "img_converters.h" +#include "esp_jpg_decode.h" + +void rgb888_to_565(uint8_t *in, uint16_t *out, uint32_t len) { +uint8_t red, grn, blu; +uint16_t b , g, r; + + for (uint32_t cnt=0; cnt> 3) & 0x1f; + g = ((grn >> 2) & 0x3f) << 5; + r = ((red >> 3) & 0x1f) << 11; + *out++ = (r | g | b); + } +} + +typedef struct { + uint16_t width; + uint16_t height; + uint16_t data_offset; + const uint8_t *input; + uint8_t *output; +} rgb_jpg_decoder; + +//input buffer +static uint32_t _jpg_read(void * arg, size_t index, uint8_t *buf, size_t len) +{ + rgb_jpg_decoder * jpeg = (rgb_jpg_decoder *)arg; + if(buf) { + memcpy(buf, jpeg->input + index, len); + } + return len; +} + +//output buffer and image width +static bool _rgb_write(void * arg, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint8_t *data) +{ + rgb_jpg_decoder * jpeg = (rgb_jpg_decoder *)arg; + if(!data){ + if(x == 0 && y == 0){ + //write start + jpeg->width = w; + jpeg->height = h; + //if output is null, this is BMP + if(!jpeg->output){ + jpeg->output = (uint8_t *)malloc((w*h*3)+jpeg->data_offset); + if(!jpeg->output){ + return false; + } + } + } else { + //write end + } + return true; + } + + size_t jw = jpeg->width*3; + size_t t = y * jw; + size_t b = t + (h * jw); + size_t l = x * 3; + uint8_t *out = jpeg->output+jpeg->data_offset; + uint8_t *o = out; + size_t iy, ix; + + w = w * 3; + + for(iy=t; iy= data_size) return false; //Check to protect against segmentation faults + if(data[i] != 0xFF) return false; //Check that we are truly at the start of another block + if(data[i+1] == 0xC0) { //0xFFC0 is the "Start of frame" marker which contains the file size + //The structure of the 0xFFC0 block is quite simple [0xFFC0][ushort length][uchar precision][ushort x][ushort y] + *height = data[i+5]*256 + data[i+6]; + *width = data[i+7]*256 + data[i+8]; + return true; + } + else + { + i+=2; //Skip the block marker + block_length = data[i] * 256 + data[i+1]; //Go to the next block + } + } + return false; //If this point is reached then no size was found + }else{ return false; } //Not a valid JFIF string + + }else{ return false; } //Not a valid SOI header +} + +#endif // JPEG_PICTS +#endif //ESP32 diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino index e490d0bd1..2d0ef4f0f 100644 --- a/tasmota/xdrv_13_display.ino +++ b/tasmota/xdrv_13_display.ino @@ -1500,47 +1500,109 @@ void CmndDisplayRows(void) /*********************************************************************************************\ * optional drivers \*********************************************************************************************/ +#ifdef ESP32 +#ifdef JPEG_PICTS +#include "img_converters.h" +#include "esp_jpg_decode.h" +bool jpg2rgb888(const uint8_t *src, size_t src_len, uint8_t * out, jpg_scale_t scale); +char get_jpeg_size(unsigned char* data, unsigned int data_size, unsigned short *width, unsigned short *height); +void rgb888_to_565(uint8_t *in, uint16_t *out, uint32_t len); +#endif +#endif + #if defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT) +#define XBUFF_LEN 128 void Draw_RGB_Bitmap(char *file,uint16_t xp, uint16_t yp) { if (!renderer) return; - - //if (!strstr(file,".RGB")) return; File fp; - fp=SD.open(file,FILE_READ); - if (!fp) return; - uint16_t xsize; - fp.read((uint8_t*)&xsize,2); - uint16_t ysize; - fp.read((uint8_t*)&ysize,2); + char *ending = strrchr(file,'.'); + if (!ending) return; + ending++; + char estr[8]; + memset(estr,0,sizeof(estr)); + for (uint32_t cnt=0; cntsetAddrWindow(xp,yp,xp+xsize,yp+ysize); - for(int16_t j=0; j=2) renderer->pushColors(rgb,len/2,true); + uint16_t xdiv=xsize/XBUFF_LEN; + renderer->setAddrWindow(xp,yp,xp+xsize,yp+ysize); + for(int16_t j=0; j=2) renderer->pushColors(rgb,len/2,true); + } + OsWatchLoop(); } - OsWatchLoop(); - } - renderer->setAddrWindow(0,0,0,0); + renderer->setAddrWindow(0,0,0,0); #else - for(int16_t j=0; jwritePixel(xp+i,yp,rgb); + for(int16_t j=0; jwritePixel(xp+i,yp,rgb); + } + delay(0); + OsWatchLoop(); + yp++; } - delay(0); - OsWatchLoop(); - yp++; - } #endif - fp.close(); + fp.close(); + } else if (!strcmp(estr,"jpg")) { + // jpeg files on ESP32 with more memory +#ifdef ESP32 +#ifdef JPEG_PICTS + if (psramFound()) { + fp=SD.open(file,FILE_READ); + if (!fp) return; + uint32_t size = fp.size(); + uint8_t *mem = (uint8_t *)heap_caps_malloc(size+4, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + if (mem) { + uint8_t res=fp.read(mem, size); + if (res) { + uint16_t xsize; + uint16_t ysize; + if (mem[0]==0xff && mem[1]==0xd8) { + get_jpeg_size(mem, size, &xsize, &ysize); + Serial.printf(" x,y %d - %d\n",xsize, ysize ); + if (xsize && ysize) { + uint8_t *out_buf = (uint8_t *)heap_caps_malloc((xsize*ysize*3)+4, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + if (out_buf) { + uint8_t *ob=out_buf; + jpg2rgb888(mem, size, out_buf, (jpg_scale_t)JPG_SCALE_NONE); + uint16_t pixels=xsize*ysize/XBUFF_LEN; + renderer->setAddrWindow(xp,yp,xp+xsize,yp+ysize); + for(int32_t j=0; jpushColors(rbuff,XBUFF_LEN,true); + OsWatchLoop(); + } + renderer->setAddrWindow(0,0,0,0); + free(out_buf); + } + } + } + } + free(mem); + } + fp.close(); + } +#endif // JPEG_PICTS +#endif // ESP32 + } } #endif From 6ab98e5e169c8844e123f368bbedc95a26b0a7c6 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Mon, 18 May 2020 09:45:17 -0300 Subject: [PATCH 3/4] Update Spanish Translation --- tasmota/language/es_ES.h | 52 ++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 40b98f766..de021791e 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.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 v8.1.0.1 + * Updated until v8.3.0.2 \*********************************************************************/ #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -79,7 +79,7 @@ #define D_DATA "Datos" #define D_DARKLIGHT "Oscuro" #define D_DEBUG "Debug" -#define D_DEWPOINT "Dew point" +#define D_DEWPOINT "Punto de Rocío" #define D_DISABLED "Deshabilitado" #define D_DISTANCE "Distancia" #define D_DNS_SERVER "Servidor DNS" @@ -98,8 +98,8 @@ #define D_FILE "Archivo" #define D_FLOW_RATE "Caudal" #define D_FREE_MEMORY "Memoria Libre" -#define D_PSR_MAX_MEMORY "PS-RAM Memory" -#define D_PSR_FREE_MEMORY "PS-RAM free Memory" +#define D_PSR_MAX_MEMORY "Memoria PS-RAM" +#define D_PSR_FREE_MEMORY "Memoria PS-RAM libre" #define D_FREQUENCY "Frecuencia" #define D_GAS "Gas" #define D_GATEWAY "Gateway" @@ -140,7 +140,7 @@ #define D_PROGRAM_SIZE "Tamaño Programa" #define D_PROJECT "Proyecto" #define D_RAIN "Lluvia" -#define D_RANGE "Range" +#define D_RANGE "Rango" #define D_RECEIVED "Recibido" #define D_RESTART "Reiniciar" #define D_RESTARTING "Reiniciando" @@ -302,7 +302,7 @@ #define D_OTHER_PARAMETERS "Otros parámetros" #define D_TEMPLATE "Plantilla" #define D_ACTIVATE "Activar" -#define D_DEVICE_NAME "Device Name" +#define D_DEVICE_NAME "Nombre de Dispositivo" #define D_WEB_ADMIN_PASSWORD "Clave Administrador Web" #define D_MQTT_ENABLE "Habilitar MQTT" #define D_FRIENDLY_NAME "Nombre Amigable" @@ -780,27 +780,27 @@ #define D_SCRIPT_UPLOAD_FILES "Cargar Archivos" //xsns_67_as3935.ino -#define D_AS3935_GAIN "gain:" -#define D_AS3935_ENERGY "energy:" -#define D_AS3935_DISTANCE "distance:" -#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_GAIN "Ganancia:" +#define D_AS3935_ENERGY "Energía:" +#define D_AS3935_DISTANCE "Distancia:" +#define D_AS3935_DISTURBER "Perturbancia:" #define D_AS3935_VRMS "µVrms:" -#define D_AS3935_APRX "aprx.:" -#define D_AS3935_AWAY "away" -#define D_AS3935_LIGHT "lightning" -#define D_AS3935_OUT "lightning out of range" -#define D_AS3935_NOT "distance not determined" -#define D_AS3935_ABOVE "lightning overhead" -#define D_AS3935_NOISE "noise detected" -#define D_AS3935_DISTDET "disturber detected" -#define D_AS3935_INTNOEV "Interrupt with no Event!" -#define D_AS3935_NOMESS "listening..." -#define D_AS3935_ON "On" -#define D_AS3935_OFF "Off" -#define D_AS3935_INDOORS "Indoors" -#define D_AS3935_OUTDOORS "Outdoors" -#define D_AS3935_CAL_FAIL "calibration failed" -#define D_AS3935_CAL_OK "calibration set to:" +#define D_AS3935_APRX "aprox.:" +#define D_AS3935_AWAY "lejos" +#define D_AS3935_LIGHT "Relámpagos" +#define D_AS3935_OUT "Relámpagos fuera de rango" +#define D_AS3935_NOT "Distancia no determinada" +#define D_AS3935_ABOVE "Relámpagos cercanos" +#define D_AS3935_NOISE "Ruido detectado" +#define D_AS3935_DISTDET "Perturbancia detectada" +#define D_AS3935_INTNOEV "Interrupción sin evento!" +#define D_AS3935_NOMESS "Escuchando..." +#define D_AS3935_ON "Encendido" +#define D_AS3935_OFF "Apagado" +#define D_AS3935_INDOORS "Dentro de casa" +#define D_AS3935_OUTDOORS "Al aire libre" +#define D_AS3935_CAL_FAIL "Falló calibración" +#define D_AS3935_CAL_OK "Calibración a:" //xsns_68_opentherm.ino #define D_SENSOR_BOILER_OT_RX "OpenTherm RX" From 769f69d049bad50c92bb755503ac2cc0d5d34915 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Mon, 18 May 2020 15:02:27 +0200 Subject: [PATCH 4/4] remove debug print --- tasmota/xdrv_13_display.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino index 2d0ef4f0f..d2466d051 100644 --- a/tasmota/xdrv_13_display.ino +++ b/tasmota/xdrv_13_display.ino @@ -1575,7 +1575,7 @@ void Draw_RGB_Bitmap(char *file,uint16_t xp, uint16_t yp) { uint16_t ysize; if (mem[0]==0xff && mem[1]==0xd8) { get_jpeg_size(mem, size, &xsize, &ysize); - Serial.printf(" x,y %d - %d\n",xsize, ysize ); + //Serial.printf(" x,y %d - %d\n",xsize, ysize ); if (xsize && ysize) { uint8_t *out_buf = (uint8_t *)heap_caps_malloc((xsize*ysize*3)+4, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); if (out_buf) {