diff --git a/Adafruit_TFTLCD.cpp b/Adafruit_TFTLCD.cpp index ee7693f..9e48e5c 100644 --- a/Adafruit_TFTLCD.cpp +++ b/Adafruit_TFTLCD.cpp @@ -18,11 +18,11 @@ #include "Adafruit_TFTLCD.h" #include "pin_magic.h" -//#define TFTWIDTH 320 -//#define TFTHEIGHT 480 +#define TFTWIDTH 320 +#define TFTHEIGHT 480 -#define TFTWIDTH 240 -#define TFTHEIGHT 320 +// #define TFTWIDTH 240 +// #define TFTHEIGHT 320 // LCD controller chip identifiers #define ID_932X 0 @@ -73,6 +73,12 @@ Adafruit_TFTLCD::Adafruit_TFTLCD( cdPort->PIO_SODR |= cdPinSet; // Signals are ACTIVE LOW wrPort->PIO_SODR |= wrPinSet; rdPort->PIO_SODR |= rdPinSet; + #endif + #if defined(ESP32) + GPIO.out_w1ts |= csPinSet; // Set all control bits to HIGH (idle) + GPIO.out_w1ts |= cdPinSet; // Signals are ACTIVE LOW + GPIO.out_w1ts |= wrPinSet; + GPIO.out_w1ts |= rdPinSet; #endif pinMode(cs, OUTPUT); // Enable outputs pinMode(cd, OUTPUT); @@ -144,7 +150,7 @@ static const uint8_t HX8347G_regValues[] PROGMEM = { 0x1A , 0x02, 0x24 , 0x61, 0x25 , 0x5C, - + 0x18 , 0x36, 0x19 , 0x01, 0x1F , 0x88, @@ -190,7 +196,7 @@ static const uint8_t HX8357D_regValues[] PROGMEM = { HX8357_TEARLINE, 2, 0x00, 0x02, HX8357_SLPOUT, 0, TFTLCD_DELAY, 150, - HX8357_DISPON, 0, + HX8357_DISPON, 0, TFTLCD_DELAY, 50, }; @@ -285,7 +291,7 @@ void Adafruit_TFTLCD::begin(uint16_t id) { writeRegister8(ILI9341_MEMCONTROL, ILI9341_MADCTL_MY | ILI9341_MADCTL_BGR); writeRegister8(ILI9341_PIXELFORMAT, 0x55); writeRegister16(ILI9341_FRAMECONTROL, 0x001B); - + writeRegister8(ILI9341_ENTRYMODE, 0x07); /* writeRegister32(ILI9341_DISPLAYFUNC, 0x0A822700);*/ @@ -322,7 +328,7 @@ void Adafruit_TFTLCD::begin(uint16_t id) { } } return; - + } else if(id == 0x7575) { uint8_t a, d; @@ -570,7 +576,7 @@ void Adafruit_TFTLCD::drawFastVLine(int16_t x, int16_t y, int16_t length, else setLR(); } -void Adafruit_TFTLCD::fillRect(int16_t x1, int16_t y1, int16_t w, int16_t h, +void Adafruit_TFTLCD::fillRect(int16_t x1, int16_t y1, int16_t w, int16_t h, uint16_t fillcolor) { int16_t x2, y2; @@ -602,7 +608,7 @@ void Adafruit_TFTLCD::fillRect(int16_t x1, int16_t y1, int16_t w, int16_t h, } void Adafruit_TFTLCD::fillScreen(uint16_t color) { - + if(driver == ID_932X) { // For the 932X, a full-screen address window is already the default @@ -679,9 +685,9 @@ void Adafruit_TFTLCD::drawPixel(int16_t x, int16_t y, uint16_t color) { } else if ((driver == ID_9341) || (driver == ID_HX8357D)) { setAddrWindow(x, y, _width-1, _height-1); CS_ACTIVE; - CD_COMMAND; + CD_COMMAND; write8(0x2C); - CD_DATA; + CD_DATA; write8(color >> 8); write8(color); } @@ -753,7 +759,7 @@ void Adafruit_TFTLCD::setRotation(uint8_t x) { setLR(); // CS_IDLE happens here } - if (driver == ID_9341) { + if (driver == ID_9341) { // MEME, HX8357D uses same registers as 9341 but different values uint16_t t; @@ -775,11 +781,11 @@ void Adafruit_TFTLCD::setRotation(uint8_t x) { // For 9341, init default full-screen address window: setAddrWindow(0, 0, _width - 1, _height - 1); // CS_IDLE happens here } - - if (driver == ID_HX8357D) { + + if (driver == ID_HX8357D) { // MEME, HX8357D uses same registers as 9341 but different values uint16_t t; - + switch (rotation) { case 2: t = HX8357B_MADCTL_RGB; @@ -902,7 +908,7 @@ uint16_t Adafruit_TFTLCD::readID(void) { */ writeRegister24(HX8357D_SETC, 0xFF8357); delay(300); - //Serial.println(readReg(0xD0), HEX); + // Serial.println(readReg(0xD0), HEX); if (readReg(0xD0) == 0x990000) { return 0x8357; } @@ -948,8 +954,8 @@ uint32_t Adafruit_TFTLCD::readReg(uint8_t r) { CS_IDLE; setWriteDir(); // Restore LCD data port(s) to WRITE configuration - //Serial.print("Read $"); Serial.print(r, HEX); - //Serial.print(":\t0x"); Serial.println(id, HEX); + // Serial.print("Read $"); Serial.print(r, HEX); + // Serial.print(":\t0x"); Serial.println(id, HEX); return id; } diff --git a/Adafruit_TFTLCD.h b/Adafruit_TFTLCD.h index b6067e5..fbf3a11 100644 --- a/Adafruit_TFTLCD.h +++ b/Adafruit_TFTLCD.h @@ -93,7 +93,13 @@ class Adafruit_TFTLCD : public Adafruit_GFX { csPinUnset, cdPinUnset, wrPinUnset, rdPinUnset, _reset; #endif - + #if defined(ESP32) + gpio_config_t io_conf; + uint32_t csPinSet , cdPinSet , wrPinSet , rdPinSet , + csPinUnset, cdPinUnset, wrPinUnset, rdPinUnset, + _reset; + #endif + #endif }; diff --git a/README.txt b/README.txt index 85e3032..5820691 100644 --- a/README.txt +++ b/README.txt @@ -1,21 +1,17 @@ -This is a library for the Adafruit 2.8" TFT display. -This library works with the Adafruit 2.8" TFT Breakout w/SD card - ----> http://www.adafruit.com/products/335 -as well as Adafruit TFT Touch Shield - ----> http://www.adafruit.com/products/376 - -Check out the links above for our tutorials and wiring diagrams. -These displays use 8-bit parallel to communicate, 12 or 13 pins are required -to interface (RST is optional). -Adafruit invests time and resources providing this open source code, -please support Adafruit and open-source hardware by purchasing -products from Adafruit! +I added esp32 support for the 8-bit interface on the Adafruit TFT breakout board, NOT the Adafruit TFT shield. -Written by Limor Fried/Ladyada for Adafruit Industries. -MIT license, all text above must be included in any redistribution +The pins used are hardcoded due to the use of bitmasks. I hope someone will have use of it. +Depending on your esp32 breakout board the locations of the pins used will differ. -To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder Adafruit_TFTLCD. Check that the Adafruit_TFTLCD folder contains Adafruit_TFTLCD.cpp and Adafruit_TFTLCD. +Pins: -Place the Adafruit_TFT library folder your /libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE +D0 - Gpio 2 +D1 - Gpio 3 +D2 - Gpio 4 +D3 - Gpio 5 +D4 - Gpio 15 +D5 - Gpio 16 +D6 - Gpio 17 +D7 - Gpio 18 -Also requires the Adafruit_GFX library for Arduino. https://github.com/adafruit/Adafruit-GFX-Library +The control pins (CS, CD, WR, RD, RST) are free to choose. \ No newline at end of file diff --git a/pin_magic.h b/pin_magic.h index 443dc91..e9562e3 100644 --- a/pin_magic.h +++ b/pin_magic.h @@ -54,13 +54,29 @@ // This code burns 7 cycles (437.5 nS) doing nothing; the RJMPs are // equivalent to two NOPs each, final NOP burns the 7th cycle, and the // last line is a radioactive mutant emoticon. -#define DELAY7 \ - asm volatile( \ - "rjmp .+0" "\n\t" \ - "rjmp .+0" "\n\t" \ - "rjmp .+0" "\n\t" \ - "nop" "\n" \ - ::); +#if !defined(ESP32) + #define DELAY7 \ + asm volatile( \ + "rjmp .+0" "\n\t" \ + "rjmp .+0" "\n\t" \ + "rjmp .+0" "\n\t" \ + "nop" "\n" \ + ::); +#else + #define DELAY7 \ + asm volatile( \ + "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" \ + "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" \ + "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" \ + "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" \ + "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" \ + "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" \ + "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" \ + "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" \ + "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" \ + "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" \ + "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n" "nop" "\n"); +#endif #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328__) || defined(__AVR_ATmega8__) @@ -129,7 +145,7 @@ // why only certain cases are inlined for each board. #define write8 write8inline -#elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) +#elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) // Arduino Mega, ADK, etc. @@ -261,7 +277,7 @@ #ifdef USE_ADAFRUIT_SHIELD_PINOUT - #define RD_PORT PIOA /*pin A0 */ + #define RD_PORT PIOA /*pin A0 */ #define WR_PORT PIOA /*pin A1 */ #define CD_PORT PIOA /*pin A2 */ #define CS_PORT PIOA /*pin A3 */ @@ -279,7 +295,7 @@ PIO_Clear(PIOB, (((~d) & 0x20)<<(27-5))); \ WR_STROBE; } - #define read8inline(result) { \ + #define read8inline(result) { \ RD_ACTIVE; \ delayMicroseconds(1); \ result = (((PIOC->PIO_PDSR & (1<<23)) >> (23-7)) | ((PIOC->PIO_PDSR & (1<<24)) >> (24-6)) | \ @@ -334,10 +350,10 @@ // When using the TFT breakout board, control pins are configurable. #define RD_ACTIVE rdPort->PIO_CODR |= rdPinSet //PIO_Clear(rdPort, rdPinSet) - #define RD_IDLE rdPort->PIO_SODR |= rdPinSet //PIO_Set(rdPort, rdPinSet) + #define RD_IDLE rdPort->PIO_SODR |= rdPinSet //PIO_Set(rdPort, rdPinSet) #define WR_ACTIVE wrPort->PIO_CODR |= wrPinSet //PIO_Clear(wrPort, wrPinSet) #define WR_IDLE wrPort->PIO_SODR |= wrPinSet //PIO_Set(wrPort, wrPinSet) - #define CD_COMMAND cdPort->PIO_CODR |= cdPinSet //PIO_Clear(cdPort, cdPinSet) + #define CD_COMMAND cdPort->PIO_CODR |= cdPinSet //PIO_Clear(cdPort, cdPinSet) #define CD_DATA cdPort->PIO_SODR |= cdPinSet //PIO_Set(cdPort, cdPinSet) #define CS_ACTIVE csPort->PIO_CODR |= csPinSet //PIO_Clear(csPort, csPinSet) #define CS_IDLE csPort->PIO_SODR |= csPinSet //PIO_Set(csPort, csPinSet) @@ -345,13 +361,67 @@ #endif +#elif defined(ESP32) //ESP32 with breakoutboard + + #ifdef USE_ADAFRUIT_SHIELD_PINOUT + #error "ESP32 support only for the adafruit TFT breakout" + #else + + #define write8inline(d) { \ + GPIO.out_w1tc = (((~d) & 0xF) << 2); \ + GPIO.out_w1tc = (((~d) & 0xF0) << 11); \ + GPIO.out_w1ts = (((d) & 0xF) << 2); \ + GPIO.out_w1ts = (((d) & 0xF0) << 11); \ + WR_STROBE; } //NOTE: Set data to correct indexes in out_w1ts register + + #define read8inline(result) { \ + RD_ACTIVE; \ + DELAY7; \ + result |= ((GPIO.in & 0b00000000000000000000000000111100) >> 2); \ + result |= ((GPIO.in & 0b00000000000001111000000000000000) >> 11); \ + RD_IDLE; } //NOTE: Checked and is correct + + #define setWriteDirInline() { \ + io_conf.intr_type = GPIO_INTR_DISABLE; \ + io_conf.mode = GPIO_MODE_OUTPUT; \ + io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; \ + io_conf.pull_up_en = GPIO_PULLUP_DISABLE; \ + io_conf.pin_bit_mask = ((1ULL << 2) | (1ULL << 3) | (1ULL << 4) | (1ULL << 5) | (1ULL << 15) | (1ULL << 16) | (1ULL << 17) | (1ULL << 18)); \ + gpio_config(&io_conf);} + + + #define setReadDirInline() { \ + io_conf.intr_type = GPIO_INTR_DISABLE; \ + io_conf.mode = GPIO_MODE_INPUT; \ + io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; \ + io_conf.pull_up_en = GPIO_PULLUP_DISABLE; \ + io_conf.pin_bit_mask = ((1ULL << 2) | (1ULL << 3) | (1ULL << 4) | (1ULL << 5) | (1ULL << 15) | (1ULL << 16) | (1ULL << 17) | (1ULL << 18)); \ + gpio_config(&io_conf);} + + // When using the TFT breakout board, control pins are configurable. + #define RD_ACTIVE GPIO.out_w1tc |= rdPinSet + #define RD_IDLE GPIO.out_w1ts |= rdPinSet + #define WR_ACTIVE GPIO.out_w1tc |= wrPinSet + #define WR_IDLE GPIO.out_w1ts |= wrPinSet + #define CD_COMMAND GPIO.out_w1tc |= cdPinSet + #define CD_DATA GPIO.out_w1ts |= cdPinSet + #define CS_ACTIVE GPIO.out_w1tc |= csPinSet + #define CS_IDLE GPIO.out_w1ts |= csPinSet + + #endif + + // #define write8 write8inline + // #define read8 read8inline + // #define setWriteDir setWriteDirInline + // #define setReadDir setReadDirInline + #else #error "Board type unsupported / not recognized" #endif -#if !defined(__SAM3X8E__) +#if !defined(__SAM3X8E__) && !defined(ESP32) // Stuff common to all Arduino AVR board types: #ifdef USE_ADAFRUIT_SHIELD_PINOUT