Very first step, talking successfully to ST7787

This commit is contained in:
Kristian Nielsen 2017-06-27 17:41:12 +02:00
parent 15dcc77909
commit 0835b336bd
7 changed files with 354 additions and 16 deletions

View File

@ -0,0 +1,116 @@
// Change the width and height if required (defined in portrait mode)
// or use the constructor to over-ride defaults
#ifndef TFT_WIDTH
#define TFT_WIDTH 240
#endif
#ifndef TFT_HEIGHT
#define TFT_HEIGHT 320
#endif
// Color definitions for backwards compatibility with old sketches
// use colour definitions like TFT_BLACK to make sketches more portable
#define ST7735_BLACK 0x0000 /* 0, 0, 0 */
#define ST7735_NAVY 0x000F /* 0, 0, 128 */
#define ST7735_DARKGREEN 0x03E0 /* 0, 128, 0 */
#define ST7735_DARKCYAN 0x03EF /* 0, 128, 128 */
#define ST7735_MAROON 0x7800 /* 128, 0, 0 */
#define ST7735_PURPLE 0x780F /* 128, 0, 128 */
#define ST7735_OLIVE 0x7BE0 /* 128, 128, 0 */
#define ST7735_LIGHTGREY 0xC618 /* 192, 192, 192 */
#define ST7735_DARKGREY 0x7BEF /* 128, 128, 128 */
#define ST7735_BLUE 0x001F /* 0, 0, 255 */
#define ST7735_GREEN 0x07E0 /* 0, 255, 0 */
#define ST7735_CYAN 0x07FF /* 0, 255, 255 */
#define ST7735_RED 0xF800 /* 255, 0, 0 */
#define ST7735_MAGENTA 0xF81F /* 255, 0, 255 */
#define ST7735_YELLOW 0xFFE0 /* 255, 255, 0 */
#define ST7735_WHITE 0xFFFF /* 255, 255, 255 */
#define ST7735_ORANGE 0xFD20 /* 255, 165, 0 */
#define ST7735_GREENYELLOW 0xAFE5 /* 173, 255, 47 */
#define ST7735_PINK 0xF81F
#define ILI9341_BLACK ST7735_BLACK
// Delay between some initialisation commands
#define TFT_INIT_DELAY 0x80
// Generic commands used by TFT_eSPI.cpp
#define TFT_NOP 0x00
#define TFT_SWRST 0x01
#define TFT_CASET 0x2A
#define TFT_PASET 0x2B
#define TFT_RAMWR 0x2C
#define TFT_RAMRD 0x2E
#define TFT_IDXRD 0x00 //0xDD // ILI9341 only, indexed control register read
#define TFT_MADCTL 0x36
#define TFT_MAD_MY 0x80
#define TFT_MAD_MX 0x40
#define TFT_MAD_MV 0x20
#define TFT_MAD_ML 0x10
#define TFT_MAD_BGR 0x08
#define TFT_MAD_MH 0x04
#define TFT_MAD_RGB 0x00
#define TFT_INVOFF 0x20
#define TFT_INVON 0x21
// ST7787 specific commands used in init
#define ST7787_NOP 0x00
#define ST7787_SWRESET 0x01
#define ST7787_RDDID 0x04
#define ST7787_RDDST 0x09
#define ST7787_SLPIN 0x10
#define ST7787_SLPOUT 0x11
#define ST7787_PTLON 0x12
#define ST7787_NORON 0x13
#define ST7787_INVOFF 0x20
#define ST7787_INVON 0x21
#define ST7787_DISPOFF 0x28
#define ST7787_DISPON 0x29
#define ST7787_CASET 0x2A
#define ST7787_RASET 0x2B // PASET
#define ST7787_RAMWR 0x2C
#define ST7787_RAMRD 0x2E
#define ST7787_PTLAR 0x30
#define ST7787_MADCTL 0x36
#define ST7787_COLMOD 0x3A
#define ST7787_FRMCTR1 0xB1
#define ST7787_FRMCTR2 0xB2
#define ST7787_FRMCTR3 0xB3
#define ST7787_INVCTR 0xB4
#define ST7787_DISSET5 0xB6
#define ST7787_VSYNCOUT 0xBC
#define ST7787_VSYNCIN 0xBD
#define ST7787_PWCTR1 0xC0
#define ST7787_PWCTR2 0xC1
#define ST7787_PWCTR3 0xC2
#define ST7787_PWCTR4 0xC3
#define ST7787_PWCTR5 0xC4
#define ST7787_VMCTR1 0xC5
#define ST7787_RDID1 0xDA
#define ST7787_RDID2 0xDB
#define ST7787_RDID3 0xDC
#define ST7787_GMCTRP1 0xE0
#define ST7787_GMCTRN1 0xE1
/* Timing delays from ST7787 datasheet (in nanoseconds). */
#define ST7787_T_CSS 60
#define ST7787_T_SCC 20
#define ST7787_T_CHW 40
#define ST7787_T_SHW 20
#define ST7787_T_SLW 20
#define ST7787_T_SHR 60
#define ST7787_T_SLR 60

37
TFT_Drivers/ST7787_Init.h Normal file
View File

@ -0,0 +1,37 @@
// This is the command sequence that initialises the ST7787 driver
//
// This setup information uses simple 8 bit SPI writecommand() and writedata() functions
//
// See ST7735_Setup.h file for an alternative format
{
/* Take the display out of sleep mode. */
writecommand(ST7787_SLPOUT);
/*
Wait for sleep-out command to complete.
Datasheet says 5 msec is enough before next command, but 120 msec is
needed before the display is fully out of sleep mode.
*/
delay(120);
/*
Select 16-bit 565 RGB pixel format (mode 5).
Same for RGB mode (but we don't use it).
*/
writecommand(ST7787_COLMOD);
writedata((13 << 4) | 5);
/* Disable external vsync. */
writecommand(ST7787_VSYNCOUT);
/* Turn on the display */
writecommand(ST7787_DISPON);
{
/* Debug: Read ID and status, to see if the basics are working. */
uint8_t buf[4];
docommand(ST7787_RDDID, NULL, 0, buf, 3);
Serial.print("RDDID: "); Serial.print(buf[0], HEX); Serial.print(" "); Serial.print(buf[1], HEX); Serial.print(" "); Serial.print(buf[2], HEX); Serial.print("\r\n");
docommand(ST7787_RDDST, NULL, 0, buf, 4);
Serial.print("RDDST: "); Serial.print(buf[0], HEX); Serial.print(" "); Serial.print(buf[1], HEX); Serial.print(" "); Serial.print(buf[2], HEX); Serial.print(" "); Serial.print(buf[3], HEX); Serial.print("\r\n");
for (;;) { }
}
}

View File

@ -0,0 +1,28 @@
// This is the command sequence that rotates the ST7735 driver coordinate frame
rotation = m % 4; // Limit the range of values to 0-3
writecommand(TFT_MADCTL);
switch (rotation) {
case 0:
writedata(TFT_MAD_RGB);
_width = TFT_WIDTH;
_height = TFT_HEIGHT;
break;
case 1:
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_RGB);
_width = TFT_HEIGHT;
_height = TFT_WIDTH;
break;
case 2:
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_RGB);
_width = TFT_WIDTH;
_height = TFT_HEIGHT;
break;
case 3:
writedata(TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_RGB);
_width = TFT_HEIGHT;
_height = TFT_WIDTH;
break;
}

View File

@ -24,7 +24,9 @@
//#include <limits.h>
//#include "pins_arduino.h"
//#include "wiring_private.h"
#ifndef ST7787_DRIVER
#include <SPI.h>
#endif
// If it is a 16bit serial display we must transfer 16 bits every time
#ifdef RPI_ILI9486_DRIVER
@ -90,6 +92,16 @@ TFT_eSPI::TFT_eSPI(int16_t w, int16_t h)
}
#endif
#ifdef TFT_DAT
digitalWrite(TFT_DAT, HIGH);
pinMode(TFT_DAT, OUTPUT);
#endif
#ifdef TFT_SCK
digitalWrite(TFT_SCK, LOW);
pinMode(TFT_SCK, OUTPUT);
#endif
_width = w; // Set by specific xxxxx_Defines.h file or by users sketch
_height = h; // Set by specific xxxxx_Defines.h file or by users sketch
rotation = 0;
@ -172,7 +184,17 @@ void TFT_eSPI::init(void)
SPI.pins(6, 7, 8, 0);
#endif
#ifdef TFT_DAT
cspinmask = (uint32_t) digitalPinToBitMask(TFT_CS);
#endif
#ifdef TFT_SCK
cspinmask = (uint32_t) digitalPinToBitMask(TFT_CS);
#endif
#ifndef ST7787_DRIVER
SPI.begin(); // This will set HMISO to input
#endif
#else
#if defined (TFT_MOSI) && !defined (TFT_SPI_OVERLAP)
SPI.begin(TFT_SCLK, TFT_MISO, TFT_MOSI, -1);
@ -185,6 +207,7 @@ void TFT_eSPI::init(void)
inTransaction = false;
locked = true;
#ifdef ST7787_DRIVER
#ifndef SUPPORT_TRANSACTIONS
SPI.setBitOrder(MSBFIRST);
@ -197,6 +220,7 @@ void TFT_eSPI::init(void)
locked = false; // Flag to stop repeat beginTransaction calls
#endif
#endif
#endif
// Set to output once again in case D6 (MISO) is used for CS
@ -249,6 +273,9 @@ void TFT_eSPI::init(void)
#elif defined (RPI_ILI9486_DRIVER)
#include "TFT_Drivers/RPI_ILI9486_Init.h"
#elif defined(ST7787_DRIVER)
#include "TFT_Drivers/ST7787_Init.h"
#endif
spi_end();
@ -281,6 +308,9 @@ void TFT_eSPI::setRotation(uint8_t m)
#elif defined (RPI_ILI9486_DRIVER)
#include "TFT_Drivers/RPI_ILI9486_Rotation.h"
#elif defined (ST7787_DRIVER)
#include "TFT_Drivers/ST7787_Rotation.h"
#endif
delayMicroseconds(10);
@ -338,20 +368,101 @@ void TFT_eSPI::spiwrite(uint8_t c)
}
void TFT_eSPI::docommand(uint8_t c, uint8_t *in, uint32_t in_len, uint8_t *out, uint32_t out_len)
{
uint32_t i;
uint32_t val;
DAT_O;
CS_L;
delay_ns(ST7787_T_CSS);
/* Write the command byte. */
/* First shift out the data/command bit ('0' for command). */
SCK_L;
DAT_L;
delay_ns(ST7787_T_SLW);
SCK_H;
delay_ns(ST7787_T_SHW);
/* Then shift out the bits, MSB-to-LSB. */
val = c;
for (i = 8; i; --i) {
SCK_L;
if ((val>>7) & 1)
DAT_H;
else
DAT_L;
val <<= 1;
delay_ns(ST7787_T_SLW);
SCK_H;
delay_ns(ST7787_T_SHW);
}
/* Write any command data. */
if (in_len) {
do {
val = *in++;
/* Data/command bit ('1' for data). */
SCK_L;
DAT_H;
delay_ns(ST7787_T_SLW);
SCK_H;
delay_ns(ST7787_T_SHW);
for (i = 8; i; --i) {
SCK_L;
if ((val>>7) & 1)
DAT_H;
else
DAT_L;
val <<= 1;
delay_ns(ST7787_T_SLW);
SCK_H;
delay_ns(ST7787_T_SHW);
}
} while (--in_len > 0);
}
DAT_I;
/* Read reply. */
if (out_len) {
/* Dummy bit (according to data sheet, data/command placeholder?). */
SCK_L;
delay_ns(ST7787_T_SLR);
SCK_H;
delay_ns(ST7787_T_SHR);
do {
val = 0;
for (i = 8; i; --i) {
SCK_L;
delay_ns(ST7787_T_SLR);
val = (val << 1);
if (DAT_V)
val = val | 1;
SCK_H;
delay_ns(ST7787_T_SHR);
}
*out++ = val;
} while (--out_len > 0);
}
SCK_L;
delay_ns(ST7787_T_SCC);
CS_H;
delay_ns(ST7787_T_CHW);
}
/***************************************************************************************
** Function name: writecommand
** Description: Send an 8 bit command to the TFT
***************************************************************************************/
void TFT_eSPI::writecommand(uint8_t c)
{
DC_C;
CS_L;
#ifdef SEND_16_BITS
SPI.transfer(0);
#endif
SPI.transfer(c);
CS_H;
DC_D;
docommand(c, NULL, 0, NULL, 0);
}
@ -361,12 +472,38 @@ void TFT_eSPI::writecommand(uint8_t c)
***************************************************************************************/
void TFT_eSPI::writedata(uint8_t c)
{
uint32_t i;
uint32_t val;
DAT_O;
CS_L;
#ifdef SEND_16_BITS
SPI.transfer(0);
#endif
SPI.transfer(c);
delay_ns(ST7787_T_CSS);
/* Data/command bit ('1' for data). */
val = c;
SCK_L;
DAT_H;
delay_ns(ST7787_T_SLW);
SCK_H;
delay_ns(ST7787_T_SHW);
for (i = 8; i; --i) {
SCK_L;
if ((val>>7) & 1)
DAT_H;
else
DAT_L;
val <<= 1;
delay_ns(ST7787_T_SLW);
SCK_H;
delay_ns(ST7787_T_SHW);
}
DAT_I;
delay_ns(ST7787_T_SCC);
CS_H;
delay_ns(ST7787_T_CHW);
}

View File

@ -120,6 +120,19 @@
#endif
#endif
#ifdef TFT_DAT
#define DAT_I pinMode(TFT_DAT, INPUT)
#define DAT_O pinMode(TFT_DAT, OUTPUT)
#define DAT_L digitalWrite(TFT_DAT, LOW)
#define DAT_H digitalWrite(TFT_DAT, HIGH)
#define DAT_V digitalRead(TFT_DAT)
#endif
#ifdef TFT_SCK
#define SCK_L digitalWrite(TFT_SCK, LOW)
#define SCK_H digitalWrite(TFT_SCK, HIGH)
#endif
#ifdef LOAD_GFXFF
// We can include all the free fonts and they will only be built into
// the sketch if they are used
@ -361,6 +374,7 @@ class TFT_eSPI : public Print {
setTextFont(uint8_t font),
#endif
spiwrite(uint8_t),
docommand(uint8_t c, uint8_t *in, uint32_t in_len, uint8_t *out, uint32_t out_len),
writecommand(uint8_t c),
writedata(uint8_t d),
commandList(const uint8_t *addr);
@ -458,6 +472,7 @@ inline void spi_end() __attribute__((always_inline));
*gfxFont;
#endif
void delay_ns(uint32_t d) { delayMicroseconds(1); /* ToDo */ }
};
#endif

View File

@ -14,15 +14,16 @@
// ##################################################################################
// Only define one driver, the other ones must be commented out
#define ILI9341_DRIVER
//#define ILI9341_DRIVER
//#define ST7735_DRIVER
//#define ILI9163_DRIVER
//#define S6D02A1_DRIVER
//#define RPI_ILI9486_DRIVER // 20MHz maximum SPI
#define ST7787_DRIVER
// For ST7735 and ILI9163 ONLY, define the pixel width and height in portrait orientation
//#define TFT_WIDTH 128
//#define TFT_HEIGHT 160
#define TFT_WIDTH 240
#define TFT_HEIGHT 320
//#define TFT_HEIGHT 128
// For ST7735 ONLY, define the type of display, originally this was based on the
@ -81,9 +82,11 @@
// For ModeMCU - 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_DC PIN_D3 // Data Command control pin
//#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
#define TFT_SCK PIN_D5
#define TFT_DAT PIN_D7
//#define TFT_WR PIN_D2 // Write strobe for modified Raspberry Pi TFT only

View File

@ -51,6 +51,8 @@
#include <TFT_Drivers/S6D02A1_Defines.h>
#elif defined (RPI_ILI9486_DRIVER)
#include <TFT_Drivers/RPI_ILI9486_Defines.h>
#elif defined (ST7787_DRIVER)
#include <TFT_Drivers/ST7787_Defines.h>
#endif
// These are the pins for all ESP8266 boards