diff --git a/Adafruit_TFTLCD.cpp b/Adafruit_TFTLCD.cpp index f8bcfb1..af124c3 100644 --- a/Adafruit_TFTLCD.cpp +++ b/Adafruit_TFTLCD.cpp @@ -24,6 +24,7 @@ // LCD controller chip identifiers #define ID_932X 0 #define ID_7575 1 +#define ID_9341 2 #define ID_UNKNOWN 0xFF // Register names from Peter Barrett's Microtouch code @@ -88,6 +89,28 @@ #define HX8347G_ROWADDREND_LO 0x09 #define HX8347G_MEMACCESS 0x16 +#define ILI9341_SOFTRESET 0x01 +#define ILI9341_SLEEPIN 0x10 +#define ILI9341_SLEEPOUT 0x11 +#define ILI9341_NORMALDISP 0x13 +#define ILI9341_INVERTOFF 0x20 +#define ILI9341_INVERTON 0x21 +#define ILI9341_GAMMASET 0x26 +#define ILI9341_DISPLAYOFF 0x28 +#define ILI9341_DISPLAYON 0x29 +#define ILI9341_COLADDRSET 0x2A +#define ILI9341_PAGEADDRSET 0x2B +#define ILI9341_MEMORYWRITE 0x2C +#define ILI9341_PIXELFORMAT 0x3A +#define ILI9341_FRAMECONTROL 0xB1 +#define ILI9341_DISPLAYFUNC 0xB6 +#define ILI9341_ENTRYMODE 0xB7 +#define ILI9341_POWERCONTROL1 0xC0 +#define ILI9341_POWERCONTROL2 0xC1 +#define ILI9341_VCOMCONTROL1 0xC5 +#define ILI9341_VCOMCONTROL2 0xC7 +#define ILI9341_MEMCONTROL 0x36 + // Constructor for breakout board (configurable LCD control lines). // Can still use this w/shield, but parameters are ignored. Adafruit_TFTLCD::Adafruit_TFTLCD( @@ -103,9 +126,9 @@ Adafruit_TFTLCD::Adafruit_TFTLCD(void) : Adafruit_GFX(TFTWIDTH, TFTHEIGHT) { void Adafruit_TFTLCD::setup(uint8_t cs, uint8_t cd, uint8_t wr, uint8_t rd, uint8_t rst) { - #ifndef USE_ADAFRUIT_SHIELD_PINOUT +#ifndef USE_ADAFRUIT_SHIELD_PINOUT // Convert pin numbers to registers and bitmasks - _reset = reset; + _reset = rst; #ifdef __AVR__ csPort = portOutputRegister(digitalPinToPort(cs)); cdPort = portOutputRegister(digitalPinToPort(cd)); @@ -118,12 +141,6 @@ void Adafruit_TFTLCD::setup(uint8_t cs, uint8_t cd, uint8_t wr, uint8_t rd, uint wrPort = digitalPinToPort(wr); rdPort = digitalPinToPort(rd); #endif - #if defined(CORE_ADAX) || defined(CORE_MICROTOUCHX) - csPort = portOutputRegister(digitalPinToPort(cs)); - cdPort = portOutputRegister(digitalPinToPort(cd)); - wrPort = portOutputRegister(digitalPinToPort(wr)); - rdPort = portOutputRegister(digitalPinToPort(rd)); - #endif csPinSet = digitalPinToBitMask(cs); cdPinSet = digitalPinToBitMask(cd); @@ -146,12 +163,6 @@ void Adafruit_TFTLCD::setup(uint8_t cs, uint8_t cd, uint8_t wr, uint8_t rd, uint wrPort->PIO_SODR |= wrPinSet; rdPort->PIO_SODR |= rdPinSet; #endif - #ifdef __AVR__ - *csPort |= csPinSet; // Set all control bits to HIGH (idle) - *cdPort |= cdPinSet; // Signals are ACTIVE LOW - *wrPort |= wrPinSet; - *rdPort |= rdPinSet; - #endif #endif init(); @@ -311,6 +322,32 @@ void Adafruit_TFTLCD::begin(uint16_t id) { setRotation(rotation); setAddrWindow(0, 0, TFTWIDTH-1, TFTHEIGHT-1); + } else if (id == 0x9341) { + + uint16_t a, d; + driver = ID_9341; + CS_ACTIVE; + writeRegister8(ILI9341_SOFTRESET, 0); + delay(50); + writeRegister8(ILI9341_DISPLAYOFF, 0); + + writeRegister8(ILI9341_POWERCONTROL1, 0x23); + writeRegister8(ILI9341_POWERCONTROL2, 0x10); + writeRegister16(ILI9341_VCOMCONTROL1, 0x2B2B); + writeRegister8(ILI9341_VCOMCONTROL2, 0xC0); + writeRegister8(ILI9341_MEMCONTROL, 0x48); + writeRegister8(ILI9341_PIXELFORMAT, 0x55); + writeRegister16(ILI9341_FRAMECONTROL, 0x001B); + + writeRegister8(ILI9341_ENTRYMODE, 0x07); + /* writeRegister32(ILI9341_DISPLAYFUNC, 0x0A822700);*/ + + writeRegister8(ILI9341_SLEEPOUT, 0); + delay(150); + writeRegister8(ILI9341_DISPLAYON, 0); + delay(500); + setAddrWindow(0, 0, TFTWIDTH-1, TFTHEIGHT-1); + } else if(id == 0x7575) { uint8_t a, d; @@ -424,6 +461,18 @@ void Adafruit_TFTLCD::setAddrWindow(int x1, int y1, int x2, int y2) { writeRegisterPair(HX8347G_COLADDREND_HI , HX8347G_COLADDREND_LO , x2); writeRegisterPair(HX8347G_ROWADDREND_HI , HX8347G_ROWADDREND_LO , y2); + } else if (driver == ID_9341) { + uint32_t t; + + t = x1; + t <<= 16; + t |= x2; + writeRegister32(ILI9341_COLADDRSET, t); + t = y1; + t <<= 16; + t |= y2; + writeRegister32(ILI9341_PAGEADDRSET, t); + } CS_IDLE; } @@ -451,8 +500,14 @@ void Adafruit_TFTLCD::flood(uint16_t color, uint32_t len) { CS_ACTIVE; CD_COMMAND; - if(driver == ID_932X) write8(0x00); // High byte of GRAM register... - write8(0x22); // Write data to GRAM + if (driver == ID_9341) { + write8(0x2C); + } else if (driver == ID_932X) { + write8(0x00); // High byte of GRAM register... + write8(0x22); // Write data to GRAM + } else { + write8(0x22); // Write data to GRAM + } // Write first pixel normally, decrement counter by 1 CD_DATA; @@ -592,6 +647,9 @@ void Adafruit_TFTLCD::fillScreen(uint16_t color) { writeRegister16(0x0020, x); writeRegister16(0x0021, y); + } else if (driver == ID_9341) { + setAddrWindow(0, 0, _width - 1, _height - 1); + } else if(driver == ID_7575) { // For the 7575, there is no settable address pointer, instead the @@ -648,6 +706,13 @@ void Adafruit_TFTLCD::drawPixel(int16_t x, int16_t y, uint16_t color) { hi = color >> 8; lo = color; CD_COMMAND; write8(0x22); CD_DATA; write8(hi); write8(lo); + } else if (driver == ID_9341) { + setAddrWindow(x, y, 239, 319); + CS_ACTIVE; + CD_COMMAND; + write8(0x2C); + CD_DATA; + write8(color >> 8); write8(color); } CS_IDLE; } @@ -782,12 +847,31 @@ uint16_t Adafruit_TFTLCD::readPixel(int16_t x, int16_t y) { return (((uint16_t)r & B11111000) << 8) | (((uint16_t)g & B11111100) << 3) | ( b >> 3); - } else return 0; + } else if(driver == ID_9341) { + uint8_t hi, lo; + setReadDir(); // Set up LCD data port(s) for READ operations + CD_DATA; + read8(hi); + read8(lo); + setWriteDir(); // Restore LCD data port(s) to WRITE configuration + CS_IDLE; + return ((uint16_t)hi << 8) | lo; + } + return 0; } // Ditto with the read/write port directions, as above. uint16_t Adafruit_TFTLCD::readID(void) { + #if defined(CORE_MICROTOUCHX) + uint16_t id; + + id = readReg(0xD3); + if (id == 0x9341) { + return id; + } + #endif + uint8_t hi, lo; CS_ACTIVE; @@ -804,6 +888,28 @@ uint16_t Adafruit_TFTLCD::readID(void) { return (hi << 8) | lo; } +uint32_t Adafruit_TFTLCD::readReg(uint8_t r) { + uint32_t id = 0; + + #if defined(CORE_MICROTOUCHX) + // try reading register #4 + CS_ACTIVE; + CD_COMMAND; + write8(r); + setReadDir(); // Set up LCD data port(s) for READ operations + CD_DATA; + uint8_t a, b, c, d; + read8(a); + read8(b); + read8(c); + read8(d); + CS_IDLE; + setWriteDir(); // Restore LCD data port(s) to WRITE configuration + id = ((uint32_t)a << 24) | ((uint32_t)b << 16) | ((uint32_t)c << 8) | ((uint32_t)d << 0); + #endif + return id; +} + // Pass 8-bit (each) R,G,B, get back 16-bit packed color uint16_t Adafruit_TFTLCD::color565(uint8_t r, uint8_t g, uint8_t b) { return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); @@ -850,6 +956,12 @@ void Adafruit_TFTLCD::writeRegister16(uint16_t a, uint16_t d) { } #endif +#ifndef writeRegister32 +void Adafruit_TFTLCD::writeRegister32(uint8_t a, uint32_t d) { + writeRegister32inline(a, d); +} +#endif + #ifndef writeRegisterPair void Adafruit_TFTLCD::writeRegisterPair(uint8_t aH, uint8_t aL, uint16_t d) { writeRegisterPairInline(aH, aL, d); diff --git a/Adafruit_TFTLCD.h b/Adafruit_TFTLCD.h index 0a037d1..811b98e 100644 --- a/Adafruit_TFTLCD.h +++ b/Adafruit_TFTLCD.h @@ -25,6 +25,7 @@ class Adafruit_TFTLCD : public Adafruit_GFX { Adafruit_TFTLCD(uint8_t cs, uint8_t cd, uint8_t wr, uint8_t rd, uint8_t rst); Adafruit_TFTLCD(void); + void setup(uint8_t cs, uint8_t cd, uint8_t wr, uint8_t rd, uint8_t rst); void begin(uint16_t id = 0x9325); void drawPixel(int16_t x, int16_t y, uint16_t color); void drawFastHLine(int16_t x0, int16_t y0, int16_t w, uint16_t color); @@ -43,6 +44,8 @@ class Adafruit_TFTLCD : public Adafruit_GFX { readPixel(int16_t x, int16_t y), readID(void); + uint32_t readReg(uint8_t r); + private: void init(), @@ -63,6 +66,9 @@ class Adafruit_TFTLCD : public Adafruit_GFX { #ifndef writeRegister16 writeRegister16(uint16_t a, uint16_t d), #endif +#ifndef writeRegister32 + writeRegister32(uint16_t a, uint32_t d), +#endif #ifndef writeRegisterPair writeRegisterPair(uint8_t aH, uint8_t aL, uint16_t d), #endif @@ -89,13 +95,7 @@ class Adafruit_TFTLCD : public Adafruit_GFX { csPinUnset, cdPinUnset, wrPinUnset, rdPinUnset, _reset; #endif - #if defined(CORE_ADAX) || defined(CORE_MICROTOUCHX) - volatile uint8_t *csPort , *cdPort , *wrPort , *rdPort; - uint8_t csPinSet , cdPinSet , wrPinSet , rdPinSet , - csPinUnset, cdPinUnset, wrPinUnset, rdPinUnset, - _reset; - #endif - + #endif }; diff --git a/pin_magic.h b/pin_magic.h index 9be76dc..fccd1dc 100644 --- a/pin_magic.h +++ b/pin_magic.h @@ -197,6 +197,7 @@ #define setReadDir setReadDirInline #define writeRegister8 writeRegister8inline #define writeRegister16 writeRegister16inline + #define writeRegister32 writeRegister32inline #define writeRegisterPair writeRegisterPairInline #elif defined(__AVR_ATmega32U4__) @@ -280,6 +281,23 @@ #define setReadDir setReadDirInline #define writeRegister8 writeRegister8inline #define writeRegister16 writeRegister16inline + #define writeRegister32 writeRegister32inline + #define writeRegisterPair writeRegisterPairInline + +#elif defined(VARIANT_MICROTOUCHX) + + #define write8inline(d) do { PORTA_OUT = d; WR_STROBE; } while (0) + #define read8inline(result) do { RD_ACTIVE; DELAY13; result = PORTA_IN; RD_IDLE; } while (0) + #define setWriteDirInline() do { PORTA_DIR = 0xFF; } while (0) + #define setReadDirInline() do { PORTA_DIR = 0x00; } while (0) + + #define write8 write8inline + #define read8 read8inline + #define setWriteDir setWriteDirInline + #define setReadDir setReadDirInline + #define writeRegister8 writeRegister8inline + #define writeRegister16 writeRegister16inline + #define writeRegister32 writeRegister32inline #define writeRegisterPair writeRegisterPairInline #elif defined(__SAM3X8E__) @@ -395,7 +413,7 @@ #define CS_ACTIVE CS_PORT &= ~CS_MASK #define CS_IDLE CS_PORT |= CS_MASK -#elif defined(CORE_ADAX) +#elif defined(CORE_ADAX) || defined(CORE_MICROTOUCHX) #define RD_ACTIVE ((PORT_t*)rdPort)->OUTCLR = rdPinSet #define RD_IDLE ((PORT_t*)rdPort)->OUTSET = rdPinSet @@ -437,6 +455,16 @@ hi = (a) >> 8; lo = (a); CD_COMMAND; write8(hi); write8(lo); \ hi = (d) >> 8; lo = (d); CD_DATA ; write8(hi); write8(lo); } while (0) +// Set value of TFT register: 8-bit address, 32-bit value +// only used for ID_9341 +// See notes at top about macro expansion, hence hi & lo temp vars +#define writeRegister32inline(a, d) do { \ + CS_ACTIVE; CD_COMMAND;\ + write8(a);\ + CD_DATA;\ + write8(d >> 24); write8(d >> 16); write8(d >> 8); write8(d); \ + CS_IDLE; } while (0) + // Set value of 2 TFT registers: Two 8-bit addresses (hi & lo), 16-bit value #define writeRegisterPairInline(aH, aL, d) do { \ uint8_t hi = (d) >> 8, lo = (d); \