Support ST7789 rotation offset and boards with no chip select

Other minor changes to tidy code up
Put back in ability to call init() multiple times in sketch
This commit is contained in:
Bodmer 2018-07-06 18:48:24 +01:00
parent 6c78430d9a
commit 51ed23af0f
12 changed files with 82 additions and 52 deletions

View File

@ -4,7 +4,7 @@
#define TFT_HEIGHT 480
// For Raspberry Pi ILI9486 only with a modified board to add a write strobe:
#ifdef TFT_WR
#if defined (TFT_WR) && defined (RPI_ILI9486_DRIVER)
#define RPI_WRITE_STROBE
#endif

View File

@ -42,7 +42,7 @@
writedata(0x80);
writedata(0x40);
writecommand(0xE0); // Positive Gamma Control
writecommand(0xE0); // Positive Gamma Control
writedata(0x00);
writedata(0x03);
writedata(0x09);

View File

@ -3,6 +3,7 @@
#define TFT_WIDTH 240
#define TFT_HEIGHT 240
#define CGRAM_OFFSET
// Delay between some initialisation commands
#define TFT_INIT_DELAY 0x80 // Not used unless commandlist invoked

View File

@ -2,6 +2,7 @@
// This is the command sequence that initialises the ST7789 driver
// Configure ST7789 display
{
static const uint8_t PROGMEM
st7789[] = {
@ -9,7 +10,7 @@ static const uint8_t PROGMEM
TFT_SWRST, TFT_INIT_DELAY, 150,
TFT_SLPOUT, TFT_INIT_DELAY, 255,
TFT_COLMOD, 1+TFT_INIT_DELAY, 0x55, 10,
TFT_MADCTL, 1, 0x00,
TFT_MADCTL, 1, TFT_MAD_RGB,
TFT_CASET, 4, 0x00, 0x00, 0x00, 0xF0,
TFT_PASET, 4, 0x00, 0x00, 0x00, 0xF0,
TFT_INVON, TFT_INIT_DELAY, 10,
@ -21,5 +22,3 @@ static const uint8_t PROGMEM
}
// End of ST7789 display configuration

View File

@ -4,23 +4,31 @@
rotation = m % 4;
switch (rotation) {
case 0: // Portrait
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_RGB);
_width = TFT_WIDTH;
_height = TFT_HEIGHT;
writedata(TFT_MAD_RGB);
_width = _init_width;
_height = _init_height;
colstart = 0;
rowstart = 0;
break;
case 1: // Landscape (Portrait + 90)
writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_RGB);
_width = TFT_HEIGHT;
_height = TFT_WIDTH;
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_RGB);
_width = _init_height;
_height = _init_width;
colstart = 0;
rowstart = 0;
break;
case 2: // Inverter portrait
writedata(TFT_MAD_RGB);
_width = TFT_WIDTH;
_height = TFT_HEIGHT;
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_RGB);
_width = _init_width;
_height = _init_height;
colstart = 0;
rowstart = 80;
break;
case 3: // Inverted landscape
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_RGB);
_width = TFT_HEIGHT;
_height = TFT_WIDTH;
writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_RGB);
_width = _init_height;
_height = _init_width;
colstart = 80;
rowstart = 0;
break;
}

View File

@ -48,7 +48,7 @@ void busDir(uint32_t mask, uint8_t mode);
inline void TFT_eSPI::spi_begin(void){
#if defined (SPI_HAS_TRANSACTION) && defined (SUPPORT_TRANSACTIONS) && !defined(ESP32_PARALLEL)
if (locked) {locked = false; SPI.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, SPI_MODE0));}
if (locked) {locked = false; SPI.beginTransaction(SPISettings(SPI_FREQUENCY, MSBFIRST, TFT_SPI_MODE));}
#endif
}
@ -117,12 +117,6 @@ TFT_eSPI::TFT_eSPI(int16_t w, int16_t h)
#endif
#ifdef ESP32_PARALLEL
// Create a data bus and Write line GPIO bit clear mask
//clr_mask = (1 << TFT_D0) | (1 << TFT_D1) | (1 << TFT_D2) | (1 << TFT_D3) | (1 << TFT_D4) | (1 << TFT_D5) | (1 << TFT_D6) | (1 << TFT_D7) | (1 << TFT_WR);
// Create a data bus GPIO bit direction mask
//dir_mask = (1 << TFT_D0) | (1 << TFT_D1) | (1 << TFT_D2) | (1 << TFT_D3) | (1 << TFT_D4) | (1 << TFT_D5) | (1 << TFT_D6) | (1 << TFT_D7);
// Create a bit set lookup table for data bus - wastes 1kbyte of RAM but speeds things up dramatically
for (int c = 0; c<256; c++)
@ -168,6 +162,8 @@ TFT_eSPI::TFT_eSPI(int16_t w, int16_t h)
locked = true; // ESP32 transaction mutex lock flags
inTransaction = false;
_booted = true;
addr_row = 0xFFFF;
addr_col = 0xFFFF;
@ -216,11 +212,13 @@ void TFT_eSPI::begin(uint8_t tc)
/***************************************************************************************
** Function name: init
** Function name: init (tc is tab colour for ST7735 displays only)
** Description: Reset, then initialise the TFT display registers
***************************************************************************************/
void TFT_eSPI::init(uint8_t tc)
{
if (_booted)
{
#if !defined (ESP32)
#ifdef TFT_CS
cspinmask = (uint32_t) digitalPinToBitMask(TFT_CS);
@ -241,7 +239,7 @@ void TFT_eSPI::init(uint8_t tc)
SPI.pins(6, 7, 8, 0);
#endif
SPI.begin(); // This will set HMISO to input
SPI.begin(); // This will set HMISO to input
#else
#if !defined(ESP32_PARALLEL)
#if defined (TFT_MOSI) && !defined (TFT_SPI_OVERLAP)
@ -252,15 +250,15 @@ void TFT_eSPI::init(uint8_t tc)
#endif
#endif
inTransaction = false;
locked = true;
inTransaction = false;
locked = true;
// SUPPORT_TRANSACTIONS is mandatory for ESP32 so the hal mutex is toggled
// so the code here is for ESP8266 only
#if !defined (SUPPORT_TRANSACTIONS) && defined (ESP8266)
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
SPI.setFrequency(SPI_FREQUENCY);
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(TFT_SPI_MODE);
SPI.setFrequency(SPI_FREQUENCY);
#endif
#if defined(ESP32_PARALLEL)
@ -278,11 +276,16 @@ void TFT_eSPI::init(uint8_t tc)
// Set to output once again in case D6 (MISO) is used for DC
#ifdef TFT_DC
digitalWrite(TFT_DC, HIGH); // Data/Command high = data mode
pinMode(TFT_DC, OUTPUT);
digitalWrite(TFT_DC, HIGH); // Data/Command high = data mode
pinMode(TFT_DC, OUTPUT);
#endif
_booted = false;
} // end of: if just _booted
// Toggle RST low to reset
spi_begin();
#ifdef TFT_RST
if (TFT_RST >= 0) {
digitalWrite(TFT_RST, HIGH);
@ -290,15 +293,14 @@ void TFT_eSPI::init(uint8_t tc)
digitalWrite(TFT_RST, LOW);
delay(20);
digitalWrite(TFT_RST, HIGH);
delay(150);
}
else writecommand(TFT_SWRST); // Software reset
#else
writecommand(TFT_SWRST); // Software reset
#endif
spi_begin();
writecommand(TFT_SWRST); // Software reset
spi_end();
delay(5); // Wait for software reset to complete
delay(150); // Wait for reset to complete
spi_begin();
@ -317,7 +319,7 @@ void TFT_eSPI::init(uint8_t tc)
#include "TFT_Drivers/S6D02A1_Init.h"
#elif defined (RPI_ILI9486_DRIVER)
#include "TFT_Drivers/RPI_ILI9486_Init.h"
#include "TFT_Drivers/ILI9486_Init.h"
#elif defined (ILI9486_DRIVER)
#include "TFT_Drivers/ILI9486_Init.h"
@ -338,6 +340,7 @@ void TFT_eSPI::init(uint8_t tc)
spi_end();
setRotation(rotation);
}
@ -364,7 +367,7 @@ void TFT_eSPI::setRotation(uint8_t m)
#include "TFT_Drivers/S6D02A1_Rotation.h"
#elif defined (RPI_ILI9486_DRIVER)
#include "TFT_Drivers/RPI_ILI9486_Rotation.h"
#include "TFT_Drivers/ILI9486_Rotation.h"
#elif defined (ILI9486_DRIVER)
#include "TFT_Drivers/ILI9486_Rotation.h"
@ -566,7 +569,7 @@ uint16_t TFT_eSPI::readPixel(int32_t x0, int32_t y0)
// Fetch the 16 bit BRG pixel
//uint16_t rgb = (readByte() << 8) | readByte();
#if defined (ILI9341_DRIVER) | defined (ILI9488_DRIVER) // Read 3 bytes
#if defined (ILI9341_DRIVER) | defined (ILI9488_DRIVER) // Read 3 bytes
// Read window pixel 24 bit RGB values and fill in LS bits
uint16_t rgb = ((readByte() & 0xF8) << 8) | ((readByte() & 0xFC) << 3) | (readByte() >> 3);
@ -578,7 +581,7 @@ uint16_t TFT_eSPI::readPixel(int32_t x0, int32_t y0)
return rgb;
#else // ILI9481 16 bit read
#else // ILI9481 16 bit read
// Fetch the 16 bit BRG pixel
uint16_t bgr = (readByte() << 8) | readByte();
@ -590,7 +593,7 @@ uint16_t TFT_eSPI::readPixel(int32_t x0, int32_t y0)
// Swap Red and Blue (could check MADCTL setting to see if this is needed)
return (bgr>>11) | (bgr<<11) | (bgr & 0x7E0);
#endif
#endif
#else // Not ESP32_PARALLEL
@ -2174,7 +2177,7 @@ void TFT_eSPI::drawChar(int32_t x, int32_t y, unsigned char c, uint32_t color, u
for (int8_t i = 0; i < 5; i++ ) column[i] = pgm_read_byte(font + (c * 5) + i);
column[5] = 0;
#if defined (ESP8266)
#if defined (ESP8266) && !defined (ILI9488_DRIVER)
color = (color >> 8) | (color << 8);
bg = (bg >> 8) | (bg << 8);
uint32_t spimask = ~((SPIMMOSI << SPILMOSI) | (SPIMMISO << SPILMISO));
@ -2197,7 +2200,7 @@ void TFT_eSPI::drawChar(int32_t x, int32_t y, unsigned char c, uint32_t color, u
SPI1CMD |= SPIBUSY;
while(SPI1CMD & SPIBUSY) {}
}
#else // for ESP32
#else // for ESP32 or ILI9488
for (int8_t j = 0; j < 8; j++) {
for (int8_t k = 0; k < 5; k++ ) {

View File

@ -30,6 +30,12 @@
#define SPI_FREQUENCY 20000000
#endif
#ifdef ST7789_DRIVER
#define TFT_SPI_MODE SPI_MODE3
#else
#define TFT_SPI_MODE SPI_MODE0
#endif
// If the frequency is not defined, set a default
#ifndef SPI_TOUCH_FREQUENCY
#define SPI_TOUCH_FREQUENCY 2500000
@ -214,12 +220,12 @@
#define tft_Write_8(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)C); WR_H
// Write 16 bits to TFT
#ifdef PSEUDO_8_BIT
#define tft_Write_16(C) WR_L;GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)(C >> 0)); WR_H
#else
#define tft_Write_16(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)(C >> 8)); WR_H; \
#ifdef PSEUDO_8_BIT
#define tft_Write_16(C) WR_L;GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)(C >> 0)); WR_H
#else
#define tft_Write_16(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)(C >> 8)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)(C >> 0)); WR_H
#endif
#endif
// 16 bit write with swapped bytes
#define tft_Write_16S(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (C >> 0)); WR_H; \
@ -238,6 +244,13 @@
//#define RD_H digitalWrite(TFT_WR, HIGH)
#endif
#elif defined (ILI9488_DRIVER) // 16 bit colour converted to 3 bytes for 24 bit RGB
#define tft_Write_8(C) SPI.transfer(C)
#define tft_Write_16(C) SPI.transfer(((C & 0xF800)>>8) | ((C & 0xF800)>>13)); \
SPI.transfer(((C & 0x07E0)>>3) | ((C & 0x07E0)>> 9)); \
SPI.transfer(((C & 0x001F)<<3) | ((C & 0x001F)>> 2))
#define tft_Write_32(C) SPI.write32(C)
#elif defined (RPI_ILI9486_DRIVER)
#define tft_Write_8(C) SPI.transfer(0); SPI.transfer(C)
#define tft_Write_16(C) SPI.write16(C)
@ -688,6 +701,8 @@ class TFT_eSPI : public Print {
bool _swapBytes; // Swap the byte order for TFT pushImage()
bool locked, inTransaction; // Transaction and mutex lock flags for ESP32
bool _booted;
int32_t _lastColor;
#ifdef LOAD_GFXFF

View File

@ -22,6 +22,7 @@
//#define RPI_ILI9486_DRIVER // 20MHz maximum SPI
//#define HX8357D_DRIVER
//#define ILI9481_DRIVER
//#define ILI9486_DRIVER
//#define ILI9488_DRIVER
//#define ST7789_DRIVER

View File

@ -69,7 +69,10 @@
#include <TFT_Drivers/S6D02A1_Defines.h>
#define TFT_DRIVER 0x6D02
#elif defined (RPI_ILI9486_DRIVER)
#include <TFT_Drivers/RPI_ILI9486_Defines.h>
#include <TFT_Drivers/ILI9486_Defines.h>
#define TFT_DRIVER 0x9486
#elif defined (ILI9486_DRIVER)
#include <TFT_Drivers/ILI9486_Defines.h>
#define TFT_DRIVER 0x9486
#elif defined (ILI9481_DRIVER)
#include <TFT_Drivers/ILI9481_Defines.h>

View File

@ -88,7 +88,7 @@
// ###### EDIT THE PIN NUMBERS IN THE LINES FOLLOWING TO SUIT YOUR ESP8266 SETUP ######
// For NodeMCU - use pin numbers in the form PIN_Dx where Dx is the NodeMCU pin designation
#define TFT_CS PIN_D8 // Chip select control pin D8
//#define TFT_CS PIN_D8 // Chip select control pin D8
#define TFT_DC PIN_D3 // Data Command control pin
#define TFT_RST PIN_D4 // Reset pin (could connect to NodeMCU RST, see next line)
//#define TFT_RST -1 // Set TFT_RST to -1 if the display RESET is connected to NodeMCU RST or 3.3V