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 9feb562..c1ab01e 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,12 +3036,12 @@ 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); DC_C; tft_Write_8(TFT_CASET2); @@ -3054,22 +3060,29 @@ 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_16(x1 | (x0 << 8)); + DC_C; tft_Write_8(TFT_PASET); + DC_D; tft_Write_16(y1 | (y0 << 8)); + 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 -#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; - y0+=rowstart; - y1+=rowstart; -#endif + #ifdef CGRAM_OFFSET + x0+=colstart; + x1+=colstart; + y0+=rowstart; + y1+=rowstart; + #endif // Temporary solution is to include the RP2040 optimised code here #if defined(ARDUINO_ARCH_RP2040) && !defined(TFT_PARALLEL_8BIT) @@ -3105,17 +3118,15 @@ void TFT_eSPI::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1) DC_D; #else - DC_C; tft_Write_8(TFT_CASET); DC_D; tft_Write_32C(x0, x1); DC_C; tft_Write_8(TFT_PASET); DC_D; tft_Write_32C(y0, y1); DC_C; tft_Write_8(TFT_RAMWR); DC_D; - //end_tft_write(); // Must be called after setWindow - #endif // RP2040 SPI #endif + //end_tft_write(); // Must be called after setWindow } @@ -3308,7 +3319,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 +3329,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_16(x | (x << 8)); + 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_16(y | (y << 8)); + 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 86a545f..a5cadeb 100644 --- a/User_Setup.h +++ b/User_Setup.h @@ -51,6 +51,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 fac8b8c..53a9383 100644 --- a/User_Setup_Select.h +++ b/User_Setup_Select.h @@ -86,6 +86,10 @@ //#include // Setup file for ESP32 and GC9A01 240 x 240 TFT +//#include // Setup file for ESP32 based WT32_SC01 from Seeed + +//#include // Setup file for ESP32/ESP8266 based SSD1351 128x128 1.5inch OLED display + //#include @@ -173,6 +177,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/User_Setups/Setup201_WT32_SC01.h b/User_Setups/Setup201_WT32_SC01.h new file mode 100644 index 0000000..80e9cdc --- /dev/null +++ b/User_Setups/Setup201_WT32_SC01.h @@ -0,0 +1,48 @@ +// USER DEFINED SETTINGS +// Set driver type, fonts to be loaded, pins used and SPI control method etc +// +// See the User_Setup_Select.h file if you wish to be able to define multiple +// setups and then easily select which setup file is used by the compiler. +// +// If this file is edited correctly then all the library example sketches should +// run without the need to make any more changes for a particular hardware setup! +// Note that some sketches are designed for a particular TFT pixel width/height + +// User defined setup +#define ST7796_DRIVER + +#define TFT_WIDTH 480 +#define TFT_HEIGHT 320 + +#define TFT_BACKLIGHT_ON HIGH + +#define USE_HSPI_PORT + +#define TFT_MISO 12 +#define TFT_MOSI 13 +#define TFT_SCLK 14 +#define TFT_CS 15 +#define TFT_DC 21 +#define TFT_RST 22 +#define TFT_BL 23 + + +#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH +#define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters +#define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters +#define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm +#define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-. +#define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-. +#define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts + +#define SMOOTH_FONT + +// SPI frequency for TFT writes +// #define SPI_FREQUENCY 10000000 +// #define SPI_FREQUENCY 20000000 +#define SPI_FREQUENCY 27000000 +// #define SPI_FREQUENCY 40000000 +// #define SPI_FREQUENCY 80000000 + +// Optional reduced SPI frequency for reading TFT +#define SPI_READ_FREQUENCY 20000000 diff --git a/User_Setups/Setup202_SSD1351_128.h b/User_Setups/Setup202_SSD1351_128.h new file mode 100644 index 0000000..947f4d3 --- /dev/null +++ b/User_Setups/Setup202_SSD1351_128.h @@ -0,0 +1,51 @@ +// See SetupX_Template.h for all options available + +#define SSD1351_DRIVER + + +#define TFT_WIDTH 128 +#define TFT_HEIGHT 128 + + +#define SSD1351_1DOT5_INCH_128 // For 128 x 128 display + +// Wiring: +// +-------------+------------+-------------------------------------------------------------------+ +// | Display PCB | TFT_eSPI | Info | +// +-------------+------------+-------------------------------------------------------------------+ +// | GND | GND (0V) | Common | +// | VCC | 5V or 3.3V | Better to power with 5V if display PCB supports it | +// | DIN | TFT_MOSI | SPI data | +// | SCK | TFT_SCLK | SPI clock | +// | DC | TFT_DC | Distinguish between a command or its data | +// | RST | TFT_RST | Hardware reset, can connect to MCU RST pin as well | +// | CS | TFT_CS | Chip select, Set to -1 if for manually use with multiple displays | +// +-------------+------------+-------------------------------------------------------------------+ +#if defined(ESP32) + #define TFT_MOSI 23 + #define TFT_SCLK 18 + #define TFT_DC 2 + #define TFT_RST 4 + #define TFT_CS 15 +#elif defined(ESP8266) +//#define TFT_MOSI PIN_D5 // Can't change +//#define TFT_SCLK PIN_D7 // Can't change + #define TFT_DC PIN_D3 + #define TFT_RST PIN_D4 + #define TFT_CS PIN_D8 +#endif + + +#define LOAD_GLCD // Original Adafruit 8 pixel font needs ~1820 bytes in FLASH +#define LOAD_FONT2 // Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters +#define LOAD_FONT4 // Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters +#define LOAD_FONT6 // Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm +#define LOAD_FONT7 // 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:. +#define LOAD_FONT8 // Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-. +//#define LOAD_FONT8N // Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT +#define LOAD_GFXFF // FreeFonts- 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts +#define SMOOTH_FONT + + +#define SPI_FREQUENCY 20000000 +//#define SPI_FREQUENCY 40000000 // Works after shielding the wires! 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