From 67c1831a100353e123a58995c4b3113bda59a6f1 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Tue, 2 Mar 2021 19:34:18 +0100 Subject: [PATCH] ili9341/2 software configurable --- .../src/renderer.cpp | 3 ++ .../Display_Renderer-gemu-1.0/src/renderer.h | 1 + .../ILI9341-gemu-1.0/ILI9341_2.cpp | 22 ++++++++ lib/lib_display/ILI9341-gemu-1.0/ILI9341_2.h | 1 + tasmota/settings.h | 16 +++++- tasmota/tasmota_template.h | 4 +- tasmota/xdrv_13_display.ino | 34 +++++++++--- tasmota/xdsp_04_ili9341.ino | 53 ++++++++----------- 8 files changed, 91 insertions(+), 43 deletions(-) diff --git a/lib/lib_display/Display_Renderer-gemu-1.0/src/renderer.cpp b/lib/lib_display/Display_Renderer-gemu-1.0/src/renderer.cpp index 641645ef1..e63f3d673 100644 --- a/lib/lib_display/Display_Renderer-gemu-1.0/src/renderer.cpp +++ b/lib/lib_display/Display_Renderer-gemu-1.0/src/renderer.cpp @@ -549,6 +549,9 @@ void Renderer::setDrawMode(uint8_t mode) { void Renderer::invertDisplay(boolean i) { } +void Renderer::reverseDisplay(boolean i) { +} + void Renderer::setScrollMargins(uint16_t top, uint16_t bottom) { } diff --git a/lib/lib_display/Display_Renderer-gemu-1.0/src/renderer.h b/lib/lib_display/Display_Renderer-gemu-1.0/src/renderer.h index 507267d37..86aa98025 100644 --- a/lib/lib_display/Display_Renderer-gemu-1.0/src/renderer.h +++ b/lib/lib_display/Display_Renderer-gemu-1.0/src/renderer.h @@ -38,6 +38,7 @@ public: virtual void pushColors(uint16_t *data, uint16_t len, boolean first); virtual void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); virtual void invertDisplay(boolean i); + virtual void reverseDisplay(boolean i); virtual void setScrollMargins(uint16_t top, uint16_t bottom); virtual void scrollTo(uint16_t y); void setDrawMode(uint8_t mode); diff --git a/lib/lib_display/ILI9341-gemu-1.0/ILI9341_2.cpp b/lib/lib_display/ILI9341-gemu-1.0/ILI9341_2.cpp index eb6e3a277..a006d0e52 100644 --- a/lib/lib_display/ILI9341-gemu-1.0/ILI9341_2.cpp +++ b/lib/lib_display/ILI9341-gemu-1.0/ILI9341_2.cpp @@ -568,6 +568,28 @@ void ILI9341_2::invertDisplay(boolean i) { SPI_END_TRANSACTION(); } +void ILI9341_2::reverseDisplay(boolean i) { + SPI_BEGIN_TRANSACTION(); + ILI9341_2_CS_LOW + if (i) { + writecmd(ILI9341_2_FRMCTR1); + spiwrite(0x00); + spiwrite(0x13); + writecmd(ILI9341_2_MADCTL); + spiwrite(0x01); + spiwrite(0x08); + } else { + writecmd(ILI9341_2_FRMCTR1); + spiwrite(0x00); + spiwrite(0x18); + writecmd(ILI9341_2_MADCTL); + spiwrite(0x01); + spiwrite(0x48); + } + ILI9341_2_CS_HIGH + SPI_END_TRANSACTION(); +} + void ili9342_dimm(uint8_t dim); // dimmer 0-100 diff --git a/lib/lib_display/ILI9341-gemu-1.0/ILI9341_2.h b/lib/lib_display/ILI9341-gemu-1.0/ILI9341_2.h index 8c1874329..88843016c 100644 --- a/lib/lib_display/ILI9341-gemu-1.0/ILI9341_2.h +++ b/lib/lib_display/ILI9341-gemu-1.0/ILI9341_2.h @@ -138,6 +138,7 @@ class ILI9341_2 : public Renderer { void dim(uint8_t dim); void pushColors(uint16_t *data, uint16_t len, boolean first); void invertDisplay(boolean i); + void reverseDisplay(boolean i); void spiwrite(uint8_t c); void spiwrite16(uint16_t c); void spiwrite32(uint32_t c); diff --git a/tasmota/settings.h b/tasmota/settings.h index cb70f0a27..c4c1d0467 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -327,6 +327,18 @@ typedef struct { uint8_t dpid = 0; } TuyaFnidDpidMap; +typedef union { + uint8_t data; + struct { + uint8_t ilimode : 3; + uint8_t Invert : 1; + uint8_t spare2 : 1; + uint8_t spare3 : 1; + uint8_t spare4 : 1; + uint8_t spare5 : 1; + }; +} DisplayOptions; + const uint32_t settings_text_size = 699; // Settings.text_pool[size] = Settings.display_model (2D2) - Settings.text_pool (017) const uint8_t MAX_TUYA_FUNCTIONS = 16; @@ -355,7 +367,6 @@ struct { uint8_t text_pool_290[66]; // 290 // End of single char array of 698 chars max **************** - uint8_t display_model; // 2D2 uint8_t display_mode; // 2D3 uint8_t display_refresh; // 2D4 @@ -375,8 +386,9 @@ struct { uint8_t param[PARAM8_SIZE]; // 2FC SetOption32 .. SetOption49 int16_t toffset[2]; // 30E uint8_t display_font; // 312 + DisplayOptions display_options; // 313 - uint8_t free_313[44]; // 313 + uint8_t free_314[43]; // 314 uint8_t tuyamcu_topic; // 33F Manage tuyaSend topic. ex_energy_power_delta on 6.6.0.20, replaced on 8.5.0.1 uint16_t domoticz_update_timer; // 340 diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 4465baea4..c61329260 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -2630,7 +2630,7 @@ const mytmplt kModules[] PROGMEM = { AGPIO(GPIO_USER), // 2 IO GPIO2, SPKR_DATA AGPIO(GPIO_USER), // 3 IO RXD0 GPIO3, U0RXD AGPIO(GPIO_SDCARD_CS), // 4 IO GPIO4, SPI_CS_CARD - 0, // 5 IO GPIO5, SPI_CS_LCD + AGPIO(GPIO_ILI9341_CS), // 5 IO GPIO5, SPI_CS_LCD // 6 IO GPIO6, Flash CLK // 7 IO GPIO7, Flash D0 // 8 IO GPIO8, Flash D1 @@ -2640,7 +2640,7 @@ const mytmplt kModules[] PROGMEM = { 0, // 12 (I)O GPIO12, SPKR_CLK AGPIO(GPIO_USER), // 13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER AGPIO(GPIO_USER), // 14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2 - 0, // 15 (I)O GPIO15, SPI_DC_LCD + AGPIO(GPIO_ILI9341_DC), // 15 (I)O GPIO15, SPI_DC_LCD 0, // 16 IO GPIO16, PSRAM_CS 0, // 17 IO GPIO17, PSRAM_CLK AGPIO(GPIO_SPI_CLK), // 18 IO GPIO18, SPI_CLK diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino index c056f3570..1d319750b 100755 --- a/tasmota/xdrv_13_display.ino +++ b/tasmota/xdrv_13_display.ino @@ -82,7 +82,8 @@ const uint8_t DISPLAY_LOG_ROWS = 32; // Number of lines in display log #define D_CMND_DISP_SETLED "SetLED" #define D_CMND_DISP_BUTTONS "Buttons" #define D_CMND_DISP_SCROLLTEXT "ScrollText" - +#define D_CMND_DISP_ILIMODE "ILIMode" +#define D_CMND_DISP_ILIINVERT "Invert" enum XdspFunctions { FUNC_DISPLAY_INIT_DRIVER, FUNC_DISPLAY_INIT, FUNC_DISPLAY_EVERY_50_MSECOND, FUNC_DISPLAY_EVERY_SECOND, @@ -114,7 +115,7 @@ const char kDisplayCommands[] PROGMEM = D_PRFX_DISPLAY "|" // Prefix "|" D_CMND_DISP_CLEAR "|" D_CMND_DISP_NUMBER "|" D_CMND_DISP_FLOAT "|" D_CMND_DISP_NUMBERNC "|" D_CMND_DISP_FLOATNC "|" D_CMND_DISP_BRIGHTNESS "|" D_CMND_DISP_RAW "|" D_CMND_DISP_LEVEL "|" D_CMND_DISP_SEVENSEG_TEXT "|" D_CMND_DISP_SEVENSEG_TEXTNC "|" D_CMND_DISP_SCROLLDELAY "|" D_CMND_DISP_CLOCK "|" D_CMND_DISP_TEXTNC "|" D_CMND_DISP_SETLEDS "|" D_CMND_DISP_SETLED "|" - D_CMND_DISP_BUTTONS "|" D_CMND_DISP_SCROLLTEXT + D_CMND_DISP_BUTTONS "|" D_CMND_DISP_SCROLLTEXT "|" D_CMND_DISP_ILIMODE "|" D_CMND_DISP_ILIINVERT ; void (* const DisplayCommand[])(void) PROGMEM = { @@ -127,7 +128,7 @@ void (* const DisplayCommand[])(void) PROGMEM = { , &CmndDisplayClear, &CmndDisplayNumber, &CmndDisplayFloat, &CmndDisplayNumberNC, &CmndDisplayFloatNC, &CmndDisplayBrightness, &CmndDisplayRaw, &CmndDisplayLevel, &CmndDisplaySevensegText, &CmndDisplaySevensegTextNC, &CmndDisplayScrollDelay, &CmndDisplayClock, &CmndDisplayTextNC, &CmndDisplaySetLEDs, &CmndDisplaySetLED, - &CmndDisplayButtons, &CmndDisplayScrollText + &CmndDisplayButtons, &CmndDisplayScrollText, &CmndDisplayILIMOde , &CmndDisplayILIInvert }; char *dsp_str; @@ -1927,10 +1928,29 @@ void CmndDisplayFont(void) ResponseCmndNumber(Settings.display_font); } + +void CmndDisplayILIMOde(void) +{ + if ((XdrvMailbox.payload >= 1) && (XdrvMailbox.payload < 16)) { + Settings.display_options.ilimode = XdrvMailbox.payload; + TasmotaGlobal.restart_flag = 2; + } + ResponseCmndNumber(Settings.display_options.ilimode); +} + +void CmndDisplayILIInvert(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { + Settings.display_options.Invert = XdrvMailbox.payload; + if (renderer) renderer->invertDisplay(Settings.display_options.Invert); + } + ResponseCmndNumber(Settings.display_options.Invert); +} + void CmndDisplayRotate(void) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 4)) { - if (Settings.display_rotate != XdrvMailbox.payload) { + if ((Settings.display_rotate) != XdrvMailbox.payload) { /* // Needs font info regarding height and width if ((Settings.display_rotate &1) != (XdrvMailbox.payload &1)) { @@ -2041,6 +2061,7 @@ char ppath[16]; } #endif + #ifdef ESP32 #ifdef JPEG_PICTS #include "img_converters.h" @@ -2672,7 +2693,7 @@ uint8_t rbutt=0; uint8_t vbutt=0; - if (touchp->touched()) { + if (touchp->touched()) { // did find a hit #if defined(USE_FT5206) pLoc = touchp->getPoint(0); @@ -2681,8 +2702,6 @@ uint8_t vbutt=0; #endif if (renderer) { - rotconvert(&pLoc.x, &pLoc.y); - #ifdef USE_M5STACK_CORE2 // handle 3 built in touch buttons uint16_t xcenter = 80; @@ -2703,6 +2722,7 @@ uint8_t vbutt=0; } #endif + rotconvert(&pLoc.x, &pLoc.y); // AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("touch after convert %d - %d"), pLoc.x, pLoc.y); // now must compare with defined buttons diff --git a/tasmota/xdsp_04_ili9341.ino b/tasmota/xdsp_04_ili9341.ino index b5c36d1e4..a8f2ce402 100644 --- a/tasmota/xdsp_04_ili9341.ino +++ b/tasmota/xdsp_04_ili9341.ino @@ -19,7 +19,7 @@ #ifdef USE_SPI #ifdef USE_DISPLAY -#if (defined(USE_DISPLAY_ILI9341) || defined(USE_DISPLAY_ILI9342)) +#ifdef USE_DISPLAY_ILI9341 #define XDSP_04 4 @@ -37,21 +37,22 @@ uint8_t ili9342_ctouch_counter = 0; uint8_t ili9342_ctouch_counter = 0; #endif // USE_FT5206 + bool tft_init_done = false; +#define ILI9341_ID 1 +#define ILI9342_ID 2 + +//Settings.display_options.ilimode = ILI9341_ID; /*********************************************************************************************/ void ILI9341_InitDriver() { -#if (defined(USE_M5STACK_CORE2) || defined(USE_M5STACK_CORE_BASIC)) - if (TasmotaGlobal.spi_enabled) { -#else // There are displays without CS if (PinUsed(GPIO_ILI9341_CS) || PinUsed(GPIO_ILI9341_DC) && (TasmotaGlobal.spi_enabled || TasmotaGlobal.soft_spi_enabled)) { -#endif Settings.display_model = XDSP_04; @@ -65,35 +66,25 @@ void ILI9341_InitDriver() // disable screen buffer buffer = NULL; -#ifdef USE_DISPLAY_ILI9341 - uint8_t dtype = 1; -#else - uint8_t dtype = 3; // sign ili9342 with variable spi pins -#endif // USE_DISPLAY_ILI9341 + if (!Settings.display_options.ilimode) { + Settings.display_options.ilimode = ILI9341_ID; + } // default colors fg_color = ILI9341_WHITE; bg_color = ILI9341_BLACK; -#ifdef USE_M5STACK_CORE2 - // fixed pins on m5stack core2 - ili9341_2 = new ILI9341_2(5, -2, 15, -2); -#elif defined(USE_M5STACK_CORE_BASIC) - // int8_t cs, int8_t res, int8_t dc, int8_t bp) - ili9341_2 = new ILI9341_2(14, 33, 27, 32); -#else // check for special case with 2 SPI busses (ESP32 bitcoin) if (TasmotaGlobal.soft_spi_enabled) { // Init renderer, may use hardware spi, however we use SSPI defintion because SD card uses SPI definition (2 spi busses) if (PinUsed(GPIO_SSPI_MOSI) && PinUsed(GPIO_SSPI_MISO) && PinUsed(GPIO_SSPI_SCLK)) { - ili9341_2 = new ILI9341_2(Pin(GPIO_ILI9341_CS), Pin(GPIO_SSPI_MOSI), Pin(GPIO_SSPI_MISO), Pin(GPIO_SSPI_SCLK), Pin(GPIO_OLED_RESET), Pin(GPIO_ILI9341_DC), Pin(GPIO_BACKLIGHT), 2, dtype); + ili9341_2 = new ILI9341_2(Pin(GPIO_ILI9341_CS), Pin(GPIO_SSPI_MOSI), Pin(GPIO_SSPI_MISO), Pin(GPIO_SSPI_SCLK), Pin(GPIO_OLED_RESET), Pin(GPIO_ILI9341_DC), Pin(GPIO_BACKLIGHT), 2, Settings.display_options.ilimode & 3); } } else if (TasmotaGlobal.spi_enabled) { if (PinUsed(GPIO_ILI9341_DC)) { - ili9341_2 = new ILI9341_2(Pin(GPIO_ILI9341_CS), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_CLK), Pin(GPIO_OLED_RESET), Pin(GPIO_ILI9341_DC), Pin(GPIO_BACKLIGHT), 1, dtype); + ili9341_2 = new ILI9341_2(Pin(GPIO_ILI9341_CS), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_CLK), Pin(GPIO_OLED_RESET), Pin(GPIO_ILI9341_DC), Pin(GPIO_BACKLIGHT), 1, Settings.display_options.ilimode & 3); } } -#endif // USE_M5STACK_CORE2 if (ili9341_2 == nullptr) { AddLog(LOG_LEVEL_INFO, PSTR("DSP: ILI934x invalid GPIOs")); @@ -102,19 +93,20 @@ void ILI9341_InitDriver() ili9341_2->init(Settings.display_width, Settings.display_height); renderer = ili9341_2; + renderer->DisplayInit(DISPLAY_INIT_MODE, Settings.display_size, Settings.display_rotate, Settings.display_font); renderer->dim(Settings.display_dimmer); + if (Settings.display_options.ilimode & 4) { + renderer->reverseDisplay(1); + } + #ifdef SHOW_SPLASH // Welcome text renderer->setTextFont(2); renderer->setTextSize(1); renderer->setTextColor(ILI9341_WHITE, ILI9341_BLACK); -#ifdef USE_DISPLAY_ILI9341 - renderer->DrawStringAt(50, (Settings.display_height/2)-12, "ILI9341 TFT!", ILI9341_WHITE, 0); -#else - renderer->DrawStringAt(50, (Settings.display_height/2)-12, "ILI9342 TFT!", ILI9341_WHITE, 0); -#endif + renderer->DrawStringAt(50, (Settings.display_height/2)-12, (Settings.display_options.ilimode & 3)==ILI9341_ID?"ILI9341 TFT!":"ILI9342 TFT!", ILI9341_WHITE, 0); delay(1000); #endif // SHOW_SPLASH @@ -140,18 +132,15 @@ void ILI9341_InitDriver() #endif // ESP32 #ifdef USE_XPT2046 - Touch_Init(Pin(GPIO_XPT2046_CS)); + Touch_Init(Pin(GPIO_XPT2046_CS)); #endif tft_init_done = true; -#ifdef USE_DISPLAY_ILI9341 AddLog(LOG_LEVEL_INFO, PSTR("DSP: ILI9341")); -#else - AddLog(LOG_LEVEL_INFO, PSTR("DSP: ILI9342")); -#endif } } + void core2_disp_pwr(uint8_t on); void core2_disp_dim(uint8_t dim); @@ -235,7 +224,6 @@ ili9342_ctouch_counter++; if (2 == ili9342_ctouch_counter) { // every 100 ms should be enough ili9342_ctouch_counter = 0; - Touch_Check(TS_RotConvert); } } @@ -243,6 +231,7 @@ ili9342_ctouch_counter++; #endif // USE_FT5206 + #ifdef USE_DISPLAY_MODES1TO5 #define TFT_TOP 16 @@ -274,7 +263,7 @@ bool Ili9341Header(void) { void Ili9341InitMode(void) { // renderer->setRotation(Settings.display_rotate); // 0 #ifdef USE_DISPLAY_ILI9341 - renderer->invertDisplay(0); +// renderer->invertDisplay(0); #endif renderer->fillScreen(ILI9341_BLACK); renderer->setTextWrap(false); // Allow text to run off edges