From e1161c17f4102f3ea3a04e52b2d8d9319236a08f Mon Sep 17 00:00:00 2001 From: arduino12 Date: Mon, 26 Apr 2021 20:40:18 +0300 Subject: [PATCH] Add support for SSD1351! (128*128 OLED) TODO: Implement read functions as well.. --- Processors/TFT_eSPI_ESP32.h | 8 ++++++- README.md | 1 + TFT_Drivers/SSD1351_Defines.h | 28 ++++++++++++++++++++++ TFT_Drivers/SSD1351_Init.h | 35 +++++++++++++++++++++++++++ TFT_Drivers/SSD1351_Rotation.h | 34 +++++++++++++++++++++++++++ TFT_eSPI.cpp | 43 +++++++++++++++++++++++++++------- User_Setup.h | 1 + User_Setup_Select.h | 3 +++ library.json | 4 ++-- library.properties | 2 +- 10 files changed, 147 insertions(+), 12 deletions(-) create mode 100644 TFT_Drivers/SSD1351_Defines.h create mode 100644 TFT_Drivers/SSD1351_Init.h create mode 100644 TFT_Drivers/SSD1351_Rotation.h diff --git a/Processors/TFT_eSPI_ESP32.h b/Processors/TFT_eSPI_ESP32.h index 0332845..7a16ee1 100644 --- a/Processors/TFT_eSPI_ESP32.h +++ b/Processors/TFT_eSPI_ESP32.h @@ -454,7 +454,13 @@ #define tft_Write_32(C) TFT_WRITE_BITS(C, 32) // Write two address coordinates - #define tft_Write_32C(C,D) TFT_WRITE_BITS((uint16_t)((D)<<8 | (D)>>8)<<16 | (uint16_t)((C)<<8 | (C)>>8), 32) + #define tft_Write_16C(C,D) TFT_WRITE_BITS((uint16_t)(D)<<8 | (C), 16) + + // Write same value twice + #define tft_Write_16D(C) TFT_WRITE_BITS((uint16_t)(C)<<8 | (C), 16) + + // Write two address coordinates + #define tft_Write_32C(C,D) TFT_WRITE_BITS((uint16_t)((D)<<8 | (D)>>8)<<16 | (uint16_t)((C)<<8 | (C)>>8), 32) // Write same value twice #define tft_Write_32D(C) TFT_WRITE_BITS((uint16_t)((C)<<8 | (C)>>8)<<16 | (uint16_t)((C)<<8 | (C)>>8), 32) diff --git a/README.md b/README.md index 8db03b1..9c3f4b8 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ Displays using the following controllers are supported: * ILI9488 * HX8357D * S6D02A1 +* SSD1351 * SSD1963 * ST7735 * ST7789 diff --git a/TFT_Drivers/SSD1351_Defines.h b/TFT_Drivers/SSD1351_Defines.h new file mode 100644 index 0000000..f02b80d --- /dev/null +++ b/TFT_Drivers/SSD1351_Defines.h @@ -0,0 +1,28 @@ +#ifndef TFT_WIDTH + #define TFT_WIDTH 128 +#endif +#ifndef TFT_HEIGHT + #define TFT_HEIGHT 128 +#endif + +#ifndef tft_Write_16D + #define tft_Write_16C(C) tft_Write_8(C); tft_Write_8(C); +#endif + +#ifndef tft_Write_16C + #define tft_Write_16C(C,D) tft_Write_8(C); tft_Write_8(D); +#endif + +// Delay between some initialisation commands +#define TFT_INIT_DELAY 0x80 + +// Generic commands used by TFT_eSPI.cpp +#define TFT_NOP 0x00 +#define TFT_SWRST TFT_NOP +#define TFT_CASET 0x15 // SETCOLUMN +#define TFT_PASET 0x75 // SETROW +#define TFT_RAMWR 0x5C // WRITERAM +#define TFT_RAMRD 0x5D // READRAM +#define TFT_IDXRD TFT_NOP +#define TFT_INVOFF 0xA6 // NORMALDISPLAY +#define TFT_INVON 0xA7 // INVERTDISPLAY diff --git a/TFT_Drivers/SSD1351_Init.h b/TFT_Drivers/SSD1351_Init.h new file mode 100644 index 0000000..2b5cff7 --- /dev/null +++ b/TFT_Drivers/SSD1351_Init.h @@ -0,0 +1,35 @@ +{ + writecommand(0xFD); // COMMANDLOCK + writedata(0x12); + writecommand(0xFD); // COMMANDLOCK + writedata(0xB1); + writecommand(0xAE); // DISPLAYOFF + writecommand(0xB3); // CLOCKDIV + writedata(0xF1); + writecommand(0xCA); // MUXRATIO + writedata(127); + writecommand(0xA2); // DISPLAYOFFSET + writedata(0x00); + writecommand(0xB5); // SETGPIO + writedata(0x00); + writecommand(0xAB); // FUNCTIONSELECT + writedata(0x01); + writecommand(0xB1); // PRECHARGE + writedata(0x32); + writecommand(0xBE); // VCOMH + writedata(0x05); + writecommand(0xA6); // NORMALDISPLAY + writecommand(0xC1); // CONTRASTABC + writedata(0xC8); + writedata(0x80); + writedata(0xC8); + writecommand(0xC7); // CONTRASTMASTER + writedata(0x0F); + writecommand(0xB4); // SETVSL + writedata(0xA0); + writedata(0xB5); + writedata(0x55); + writecommand(0xB6); // PRECHARGE2 + writedata(0x01); + writecommand(0xAF); // DISPLAYON +} diff --git a/TFT_Drivers/SSD1351_Rotation.h b/TFT_Drivers/SSD1351_Rotation.h new file mode 100644 index 0000000..f500f6d --- /dev/null +++ b/TFT_Drivers/SSD1351_Rotation.h @@ -0,0 +1,34 @@ + +// This is the command sequence that rotates the SSD1351 driver coordinate frame + + rotation = m % 4; // Limit the range of values to 0-3 + + uint8_t madctl = 0x64; + + switch (rotation) { + case 0: + madctl |= 0x10; + _width = _init_width; + _height = _init_height; + break; + case 1: + madctl |= 0x13; + _width = _init_height; + _height = _init_width; + break; + case 2: + madctl |= 0x02; + _width = _init_width; + _height = _init_height; + break; + case 3: + madctl |= 0x01; + _width = _init_height; + _height = _init_width; + break; + } + + writecommand(0xA0); // SETREMAP + writedata(madctl); + writecommand(0xA1); // STARTLINE + writedata(rotation < 2 ? TFT_HEIGHT : 0); diff --git a/TFT_eSPI.cpp b/TFT_eSPI.cpp index 1164b51..8f251d8 100644 --- a/TFT_eSPI.cpp +++ b/TFT_eSPI.cpp @@ -644,6 +644,9 @@ void TFT_eSPI::init(uint8_t tc) #elif defined (ST7789_2_DRIVER) #include "TFT_Drivers/ST7789_2_Init.h" +#elif defined (SSD1351_DRIVER) + #include "TFT_Drivers/SSD1351_Init.h" + #elif defined (SSD1963_DRIVER) #include "TFT_Drivers/SSD1963_Init.h" @@ -729,6 +732,9 @@ void TFT_eSPI::setRotation(uint8_t m) #elif defined (ST7789_2_DRIVER) #include "TFT_Drivers/ST7789_2_Rotation.h" +#elif defined (SSD1351_DRIVER) + #include "TFT_Drivers/SSD1351_Rotation.h" + #elif defined (SSD1963_DRIVER) #include "TFT_Drivers/SSD1963_Rotation.h" @@ -3030,11 +3036,10 @@ void TFT_eSPI::setAddrWindow(int32_t x0, int32_t y0, int32_t w, int32_t h) void TFT_eSPI::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1) { //begin_tft_write(); // Must be called before setWindow -#if defined (ILI9225_DRIVER) - if (rotation & 0x01) { swap_coord(x0, y0); swap_coord(x1, y1); } - addr_row = 0xFFFF; addr_col = 0xFFFF; +#if defined (ILI9225_DRIVER) + if (rotation & 0x01) { swap_coord(x0, y0); swap_coord(x1, y1); } DC_C; tft_Write_8(TFT_CASET1); DC_D; tft_Write_16(x0); @@ -3054,16 +3059,24 @@ void TFT_eSPI::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1) // write to RAM DC_C; tft_Write_8(TFT_RAMWR); DC_D; +#elif defined (SSD1351_DRIVER) + if (rotation & 1) { + swap_coord(x0, y0); + swap_coord(x1, y1); + } -#else // Not ILI9225 + DC_C; tft_Write_8(TFT_CASET); + DC_D; tft_Write_16C(x0, x1); + DC_C; tft_Write_8(TFT_PASET); + DC_D; tft_Write_16C(y0, y1); + DC_C; tft_Write_8(TFT_RAMWR); + DC_D; +#else #if defined (SSD1963_DRIVER) if ((rotation & 0x1) == 0) { swap_coord(x0, y0); swap_coord(x1, y1); } #endif - addr_row = 0xFFFF; - addr_col = 0xFFFF; - #ifdef CGRAM_OFFSET x0+=colstart; x1+=colstart; @@ -3308,7 +3321,7 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color) #else -#if defined (SSD1963_DRIVER) +#if defined (SSD1351_DRIVER) || defined (SSD1963_DRIVER) if ((rotation & 0x1) == 0) { swap_coord(x, y); } #endif @@ -3318,6 +3331,20 @@ void TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color) DC_D; tft_Write_32D(x); DC_C; tft_Write_8(TFT_PASET); DC_D; tft_Write_32D(y); +#elif defined (SSD1351_DRIVER) + // No need to send x if it has not changed (speeds things up) + if (addr_col != x) { + DC_C; tft_Write_8(TFT_CASET); + DC_D; tft_Write_16D(x); + addr_col = x; + } + + // No need to send y if it has not changed (speeds things up) + if (addr_row != y) { + DC_C; tft_Write_8(TFT_PASET); + DC_D; tft_Write_16D(y); + addr_row = y; + } #else // No need to send x if it has not changed (speeds things up) if (addr_col != x) { diff --git a/User_Setup.h b/User_Setup.h index cb5bda3..53889b8 100644 --- a/User_Setup.h +++ b/User_Setup.h @@ -50,6 +50,7 @@ //#define R61581_DRIVER //#define RM68140_DRIVER //#define ST7796_DRIVER +//#define SSD1351_DRIVER //#define SSD1963_480_DRIVER //#define SSD1963_800_DRIVER //#define SSD1963_800ALT_DRIVER diff --git a/User_Setup_Select.h b/User_Setup_Select.h index 87461ad..f67a19a 100644 --- a/User_Setup_Select.h +++ b/User_Setup_Select.h @@ -175,6 +175,9 @@ #elif defined (RM68140_DRIVER) #include "TFT_Drivers/RM68140_Defines.h" #define TFT_DRIVER 0x6814 +#elif defined (SSD1351_DRIVER) + #include "TFT_Drivers/SSD1351_Defines.h" + #define TFT_DRIVER 0x1351 #elif defined (SSD1963_480_DRIVER) #include "TFT_Drivers/SSD1963_Defines.h" #define TFT_DRIVER 0x1963 diff --git a/library.json b/library.json index 6cd8b14..daa221a 100644 --- a/library.json +++ b/library.json @@ -1,7 +1,7 @@ { "name": "TFT_eSPI", - "version": "2.3.66", - "keywords": "Arduino, tft, ePaper, display, Pico, RP2040, STM32, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9481, ILI9486, ILI9488, ST7789, RM68140, SSD1963, ILI9225, HX8357D", + "version": "2.3.67", + "keywords": "Arduino, tft, ePaper, display, Pico, RP2040, STM32, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9481, ILI9486, ILI9488, ST7789, RM68140, SSD1351, SSD1963, ILI9225, HX8357D", "description": "A TFT and ePaper SPI graphics library with optimisation for Raspberry Pi Pico, ESP8266, ESP32 and STM32", "repository": { diff --git a/library.properties b/library.properties index 3e16fc0..d05d070 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=TFT_eSPI -version=2.3.66 +version=2.3.67 author=Bodmer maintainer=Bodmer sentence=TFT graphics library for Arduino processors with performance optimisation for RP2040, STM32, ESP8266 and ESP32