From 671ba214b74e9f8e2de74f40a2ae1e7e7db305d0 Mon Sep 17 00:00:00 2001 From: Johan Cronje Date: Tue, 24 Oct 2017 17:23:59 -0700 Subject: [PATCH 1/3] Adafruit_ILI9341 changes --- library.json | 2 +- library.properties | 2 +- src/TFT_22_ILI9225.cpp | 1316 ++++++++++++++++++++++------------------ src/TFT_22_ILI9225.h | 466 +++++++------- 4 files changed, 995 insertions(+), 791 deletions(-) diff --git a/library.json b/library.json index 5f2f85c..a8567a6 100644 --- a/library.json +++ b/library.json @@ -9,7 +9,7 @@ "authors": { "name": "Nkawu" }, - "version": "1.2.4", + "version": "1.2.6", "frameworks": "arduino", "platforms": "*" } diff --git a/library.properties b/library.properties index 71aeea3..d8f5008 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=TFT_22_ILI9225 -version=1.2.4 +version=1.2.6 author=Nkawu maintainer=Nkawu sentence=ILI9225 2.2" 176x220 TFT LCD shield diff --git a/src/TFT_22_ILI9225.cpp b/src/TFT_22_ILI9225.cpp index 72563c1..6db58cd 100644 --- a/src/TFT_22_ILI9225.cpp +++ b/src/TFT_22_ILI9225.cpp @@ -1,719 +1,869 @@ #include "TFT_22_ILI9225.h" -#include +#ifndef ARDUINO_STM32_FEATHER + #include "pins_arduino.h" + #ifndef RASPI + #include "wiring_private.h" + #endif +#endif #include -#include -// If the SPI library has transaction support, these functions -// establish settings and protect from interference from other -// libraries. Otherwise, they simply do nothing. +// Control pins + +#ifdef USE_FAST_PINIO + #define SPI_DC_HIGH() *dcport |= dcpinmask + #define SPI_DC_LOW() *dcport &= ~dcpinmask + #define SPI_CS_HIGH() *csport |= cspinmask + #define SPI_CS_LOW() *csport &= ~cspinmask +#else + #define SPI_DC_HIGH() digitalWrite(_rs, HIGH) + #define SPI_DC_LOW() digitalWrite(_rs, LOW) + #define SPI_CS_HIGH() digitalWrite(_cs, HIGH) + #define SPI_CS_LOW() digitalWrite(_cs, LOW) +#endif + +// Software SPI Macros + +#ifdef USE_FAST_PINIO + #define SSPI_MOSI_HIGH() *mosiport |= mosipinmask + #define SSPI_MOSI_LOW() *mosiport &= ~mosipinmask + #define SSPI_SCK_HIGH() *clkport |= clkpinmask + #define SSPI_SCK_LOW() *clkport &= ~clkpinmask +#else + #define SSPI_MOSI_HIGH() digitalWrite(_sdi, HIGH) + #define SSPI_MOSI_LOW() digitalWrite(_sdi, LOW) + #define SSPI_SCK_HIGH() digitalWrite(_clk, HIGH) + #define SSPI_SCK_LOW() digitalWrite(_clk, LOW) +#endif + +// #define SSPI_BEGIN_TRANSACTION() +// #define SSPI_END_TRANSACTION() +// #define SSPI_WRITE(v) _spiWrite(v) +// #define SSPI_WRITE16(s) SSPI_WRITE((s) >> 8); SSPI_WRITE(s) +// #define SSPI_WRITE32(l) SSPI_WRITE((l) >> 24); SSPI_WRITE((l) >> 16); SSPI_WRITE((l) >> 8); SSPI_WRITE(l) +// #define SSPI_WRITE_PIXELS(c,l) for(uint32_t i=0; i<(l); i+=2){ SSPI_WRITE(((uint8_t*)(c))[i+1]); SSPI_WRITE(((uint8_t*)(c))[i]); } + +// Hardware SPI Macros + +#ifndef ESP32 + #define SPI_OBJECT SPI +#else + #define SPI_OBJECT _spi +#endif + +#if defined (__AVR__) || defined(TEENSYDUINO) || defined(ARDUINO_ARCH_STM32F1) + #define HSPI_SET_CLOCK() SPI_OBJECT.setClockDivider(SPI_CLOCK_DIV2); +#elif defined (__arm__) + #define HSPI_SET_CLOCK() SPI_OBJECT.setClockDivider(11); +#elif defined(ESP8266) || defined(ESP32) + #define HSPI_SET_CLOCK() SPI_OBJECT.setFrequency(SPI_DEFAULT_FREQ); +#elif defined(RASPI) + #define HSPI_SET_CLOCK() SPI_OBJECT.setClock(SPI_DEFAULT_FREQ); +#elif defined(ARDUINO_ARCH_STM32F1) + #define HSPI_SET_CLOCK() SPI_OBJECT.setClock(SPI_DEFAULT_FREQ); +#else + #define HSPI_SET_CLOCK() +#endif + #ifdef SPI_HAS_TRANSACTION -static inline void spi_begin(void) __attribute__((always_inline)); -static inline void spi_begin(void) { - SPI.beginTransaction(SPISettings(24000000, MSBFIRST, SPI_MODE0)); -} -static inline void spi_end(void) __attribute__((always_inline)); -static inline void spi_end(void) { - SPI.endTransaction(); -} + #define HSPI_BEGIN_TRANSACTION() SPI_OBJECT.beginTransaction(SPISettings(SPI_DEFAULT_FREQ, MSBFIRST, SPI_MODE0)) + #define HSPI_END_TRANSACTION() SPI_OBJECT.endTransaction() +#else + #define HSPI_BEGIN_TRANSACTION() HSPI_SET_CLOCK(); SPI_OBJECT.setBitOrder(MSBFIRST); SPI_OBJECT.setDataMode(SPI_MODE0) + #define HSPI_END_TRANSACTION() +#endif + +#ifdef ESP32 + #define SPI_HAS_WRITE_PIXELS +#endif +#if defined(ESP8266) || defined(ESP32) + // Optimized SPI (ESP8266 and ESP32) + // #define HSPI_READ() SPI_OBJECT.transfer(0) + #define HSPI_WRITE(b) SPI_OBJECT.write(b) + // #define HSPI_WRITE16(s) SPI_OBJECT.write16(s) + // #define HSPI_WRITE32(l) SPI_OBJECT.write32(l) + #ifdef SPI_HAS_WRITE_PIXELS + #define SPI_MAX_PIXELS_AT_ONCE 32 + // #define HSPI_WRITE_PIXELS(c,l) SPI_OBJECT.writePixels(c,l) + #else + // #define HSPI_WRITE_PIXELS(c,l) for(uint32_t i=0; i<((l)/2); i++){ SPI_WRITE16(((uint16_t*)(c))[i]); } + #endif +#else + // Standard Byte-by-Byte SPI + + #if defined (__AVR__) || defined(TEENSYDUINO) + static inline uint8_t _avr_spi_read(void) __attribute__((always_inline)); + static inline uint8_t _avr_spi_read(void) { + uint8_t r = 0; + SPDR = r; + while(!(SPSR & _BV(SPIF))); + r = SPDR; + return r; + } + #define HSPI_WRITE(b) {SPDR = (b); while(!(SPSR & _BV(SPIF)));} + // #define HSPI_READ() _avr_spi_read() + #else + #define HSPI_WRITE(b) SPI_OBJECT.transfer((uint8_t)(b)) + // #define HSPI_READ() HSPI_WRITE(0) + #endif + // #define HSPI_WRITE16(s) HSPI_WRITE((s) >> 8); HSPI_WRITE(s) + // #define HSPI_WRITE32(l) HSPI_WRITE((l) >> 24); HSPI_WRITE((l) >> 16); HSPI_WRITE((l) >> 8); HSPI_WRITE(l) + // #define HSPI_WRITE_PIXELS(c,l) for(uint32_t i=0; i<(l); i+=2){ HSPI_WRITE(((uint8_t*)(c))[i+1]); HSPI_WRITE(((uint8_t*)(c))[i]); } +#endif + +// Final SPI Macros + +#if defined (ARDUINO_ARCH_ARC32) + #define SPI_DEFAULT_FREQ 16000000 +#elif defined (__AVR__) || defined(TEENSYDUINO) + #define SPI_DEFAULT_FREQ 8000000 +#elif defined(ESP8266) || defined(ESP32) + #define SPI_DEFAULT_FREQ 40000000 +#elif defined(RASPI) + #define SPI_DEFAULT_FREQ 80000000 +#elif defined(ARDUINO_ARCH_STM32F1) + #define SPI_DEFAULT_FREQ 36000000 #else -#define spi_begin() -#define spi_end() + #define SPI_DEFAULT_FREQ 24000000 #endif +#define SPI_BEGIN() if(_clk < 0){SPI_OBJECT.begin();} +#define SPI_BEGIN_TRANSACTION() if(_clk < 0){HSPI_BEGIN_TRANSACTION();} +#define SPI_END_TRANSACTION() if(_clk < 0){HSPI_END_TRANSACTION();} +// #define SPI_WRITE16(s) if(_clk < 0){HSPI_WRITE16(s);}else{SSPI_WRITE16(s);} +// #define SPI_WRITE32(l) if(_clk < 0){HSPI_WRITE32(l);}else{SSPI_WRITE32(l);} +// #define SPI_WRITE_PIXELS(c,l) if(_clk < 0){HSPI_WRITE_PIXELS(c,l);}else{SSPI_WRITE_PIXELS(c,l);} + // Constructor when using software SPI. All output pins are configurable. -TFT_22_ILI9225::TFT_22_ILI9225(uint8_t rst, uint8_t rs, uint8_t cs, uint8_t sdi, uint8_t clk, uint8_t led) { - _rst = rst; - _rs = rs; - _cs = cs; - _sdi = sdi; - _clk = clk; - _led = led; - _brightness = 255; // Set to maximum brightness - hwSPI = false; - checkSPI = true; +TFT_22_ILI9225::TFT_22_ILI9225(int8_t rst, int8_t rs, int8_t cs, int8_t sdi, int8_t clk, int8_t led) { + _rst = rst; + _rs = rs; + _cs = cs; + _sdi = sdi; + _clk = clk; + _led = led; + _brightness = 255; // Set to maximum brightness + hwSPI = false; + checkSPI = true; +#ifdef USE_FAST_PINIO + csport = portOutputRegister(digitalPinToPort(_cs)); + cspinmask = digitalPinToBitMask(_cs); + dcport = portOutputRegister(digitalPinToPort(_rs)); + dcpinmask = digitalPinToBitMask(_rs); + clkport = portOutputRegister(digitalPinToPort(_clk)); + clkpinmask = digitalPinToBitMask(_clk); + mosiport = portOutputRegister(digitalPinToPort(_sdi)); + mosipinmask = digitalPinToBitMask(_sdi); +#endif } // Constructor when using software SPI. All output pins are configurable. Adds backlight brightness 0-255 -TFT_22_ILI9225::TFT_22_ILI9225(uint8_t rst, uint8_t rs, uint8_t cs, uint8_t sdi, uint8_t clk, uint8_t led, uint8_t brightness) { - _rst = rst; - _rs = rs; - _cs = cs; - _sdi = sdi; - _clk = clk; - _led = led; - _brightness = brightness; - hwSPI = false; - checkSPI = true; +TFT_22_ILI9225::TFT_22_ILI9225(int8_t rst, int8_t rs, int8_t cs, int8_t sdi, int8_t clk, int8_t led, uint8_t brightness) { + _rst = rst; + _rs = rs; + _cs = cs; + _sdi = sdi; + _clk = clk; + _led = led; + _brightness = brightness; + hwSPI = false; + checkSPI = true; +#ifdef USE_FAST_PINIO + csport = portOutputRegister(digitalPinToPort(_cs)); + cspinmask = digitalPinToBitMask(_cs); + dcport = portOutputRegister(digitalPinToPort(_rs)); + dcpinmask = digitalPinToBitMask(_rs); + clkport = portOutputRegister(digitalPinToPort(_clk)); + clkpinmask = digitalPinToBitMask(_clk); + mosiport = portOutputRegister(digitalPinToPort(_sdi)); + mosipinmask = digitalPinToBitMask(_sdi); +#endif } // Constructor when using hardware SPI. Faster, but must use SPI pins // specific to each board type (e.g. 11,13 for Uno, 51,52 for Mega, etc.) -TFT_22_ILI9225::TFT_22_ILI9225(uint8_t rst, uint8_t rs, uint8_t cs, uint8_t led) { - _rst = rst; - _rs = rs; - _cs = cs; - _sdi = _clk = 0; - _led = led; - _brightness = 255; // Set to maximum brightness - hwSPI = true; - checkSPI = true; +TFT_22_ILI9225::TFT_22_ILI9225(int8_t rst, int8_t rs, int8_t cs, int8_t led) { + _rst = rst; + _rs = rs; + _cs = cs; + _sdi = _clk = -1; + _led = led; + _brightness = 255; // Set to maximum brightness + hwSPI = true; + checkSPI = true; +#ifdef USE_FAST_PINIO + csport = portOutputRegister(digitalPinToPort(_cs)); + cspinmask = digitalPinToBitMask(_cs); + dcport = portOutputRegister(digitalPinToPort(_rs)); + dcpinmask = digitalPinToBitMask(_rs); + clkport = 0; + clkpinmask = 0; + mosiport = 0; + mosipinmask = 0; +#endif } // Constructor when using hardware SPI. Faster, but must use SPI pins // specific to each board type (e.g. 11,13 for Uno, 51,52 for Mega, etc.) // Adds backlight brightness 0-255 -TFT_22_ILI9225::TFT_22_ILI9225(uint8_t rst, uint8_t rs, uint8_t cs, uint8_t led, uint8_t brightness) { - _rst = rst; - _rs = rs; - _cs = cs; - _sdi = _clk = 0; - _led = led; - _brightness = brightness; - hwSPI = true; - checkSPI = true; -} - -void TFT_22_ILI9225::_spiwrite(uint8_t c) { - if (hwSPI) { - SPDR = c; - while(!(SPSR & _BV(SPIF))); - } else { - // Fast SPI bitbang swiped from LPD8806 library - for(uint8_t bit = 0x80; bit; bit >>= 1) { - if(c & bit) { - //digitalWrite(_sdi, HIGH); - *mosiport |= mosipinmask; - } else { - //digitalWrite(_sdi, LOW); - *mosiport &= ~mosipinmask; - } - //digitalWrite(_clk, HIGH); - *clkport |= clkpinmask; - //digitalWrite(_clk, LOW); - *clkport &= ~clkpinmask; - } - } +TFT_22_ILI9225::TFT_22_ILI9225(int8_t rst, int8_t rs, int8_t cs, int8_t led, uint8_t brightness) { + _rst = rst; + _rs = rs; + _cs = cs; + _sdi = _clk = 0; + _led = led; + _brightness = brightness; + hwSPI = true; + checkSPI = true; +#ifdef USE_FAST_PINIO + csport = portOutputRegister(digitalPinToPort(_cs)); + cspinmask = digitalPinToBitMask(_cs); + dcport = portOutputRegister(digitalPinToPort(_rs)); + dcpinmask = digitalPinToBitMask(_rs); + clkport = 0; + clkpinmask = 0; + mosiport = 0; + mosipinmask = 0; +#endif } -void TFT_22_ILI9225::_writecommand(uint8_t c) { - *dcport &= ~dcpinmask; - *csport &= ~cspinmask; - _spiwrite(c); - *csport |= cspinmask; -} -void TFT_22_ILI9225::_writedata(uint8_t c) { - *dcport |= dcpinmask; - *csport &= ~cspinmask; - _spiwrite(c); - *csport |= cspinmask; -} +#ifdef ESP32 +void TFT_22_ILI9225::begin(SPIClass &spi) {} + _spi = spi; +#else +void TFT_22_ILI9225::begin() { +#endif -void TFT_22_ILI9225::_orientCoordinates(uint16_t &x1, uint16_t &y1) { + // Set up reset pin + if (_rst > 0) { + pinMode(_rst, OUTPUT); + digitalWrite(_rst, LOW); + } + // Set up backlight pin, turn off initially + if (_led > 0) { + pinMode(_led, OUTPUT); + setBacklight(false); + } - switch (_orientation) { - case 0: // ok - break; - case 1: // ok - y1 = _maxY - y1 - 1; - _swap(x1, y1); - break; - case 2: // ok - x1 = _maxX - x1 - 1; - y1 = _maxY - y1 - 1; - break; - case 3: // ok - x1 = _maxX - x1 - 1; - _swap(x1, y1); - break; - } -} + // Control pins + pinMode(_rs, OUTPUT); + digitalWrite(_rs, LOW); + pinMode(_cs, OUTPUT); + digitalWrite(_cs, HIGH); + // Software SPI + if(_clk >= 0){ + pinMode(_sdi, OUTPUT); + digitalWrite(_sdi, LOW); + pinMode(_clk, OUTPUT); + digitalWrite(_clk, HIGH); + } -void TFT_22_ILI9225::_setWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { - _orientCoordinates(x0, y0); - _orientCoordinates(x1, y1); + // Hardware SPI + SPI_BEGIN(); - if (x1 0) { + digitalWrite(_rst, HIGH); // Pull the reset pin high to release the ILI9225C from the reset status + delay(1); + digitalWrite(_rst, LOW); // Pull the reset pin low to reset ILI9225 + delay(10); + digitalWrite(_rst, HIGH); // Pull the reset pin high to release the ILI9225C from the reset status + delay(50); + } - if (hwSPI) spi_begin(); + /* Start Initial Sequence */ - _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR1,x1); - _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR2,x0); + /* Set SS bit and direction output from S528 to S1 */ + startWrite(); + _writeRegister(ILI9225_POWER_CTRL1, 0x0000); // Set SAP,DSTB,STB + _writeRegister(ILI9225_POWER_CTRL2, 0x0000); // Set APON,PON,AON,VCI1EN,VC + _writeRegister(ILI9225_POWER_CTRL3, 0x0000); // Set BT,DC1,DC2,DC3 + _writeRegister(ILI9225_POWER_CTRL4, 0x0000); // Set GVDD + _writeRegister(ILI9225_POWER_CTRL5, 0x0000); // Set VCOMH/VCOML voltage + endWrite(); + delay(40); + + // Power-on sequence + startWrite(); + _writeRegister(ILI9225_POWER_CTRL2, 0x0018); // Set APON,PON,AON,VCI1EN,VC + _writeRegister(ILI9225_POWER_CTRL3, 0x6121); // Set BT,DC1,DC2,DC3 + _writeRegister(ILI9225_POWER_CTRL4, 0x006F); // Set GVDD /*007F 0088 */ + _writeRegister(ILI9225_POWER_CTRL5, 0x495F); // Set VCOMH/VCOML voltage + _writeRegister(ILI9225_POWER_CTRL1, 0x0800); // Set SAP,DSTB,STB + endWrite(); + delay(10); + startWrite(); + _writeRegister(ILI9225_POWER_CTRL2, 0x103B); // Set APON,PON,AON,VCI1EN,VC + endWrite(); + delay(50); + + startWrite(); + _writeRegister(ILI9225_DRIVER_OUTPUT_CTRL, 0x011C); // set the display line number and display direction + _writeRegister(ILI9225_LCD_AC_DRIVING_CTRL, 0x0100); // set 1 line inversion + _writeRegister(ILI9225_ENTRY_MODE, 0x1030); // set GRAM write direction and BGR=1. + _writeRegister(ILI9225_DISP_CTRL1, 0x0000); // Display off + _writeRegister(ILI9225_BLANK_PERIOD_CTRL1, 0x0808); // set the back porch and front porch + _writeRegister(ILI9225_FRAME_CYCLE_CTRL, 0x1100); // set the clocks number per line + _writeRegister(ILI9225_INTERFACE_CTRL, 0x0000); // CPU interface + _writeRegister(ILI9225_OSC_CTRL, 0x0D01); // Set Osc /*0e01*/ + _writeRegister(ILI9225_VCI_RECYCLING, 0x0020); // Set VCI recycling + _writeRegister(ILI9225_RAM_ADDR_SET1, 0x0000); // RAM Address + _writeRegister(ILI9225_RAM_ADDR_SET2, 0x0000); // RAM Address + + /* Set GRAM area */ + _writeRegister(ILI9225_GATE_SCAN_CTRL, 0x0000); + _writeRegister(ILI9225_VERTICAL_SCROLL_CTRL1, 0x00DB); + _writeRegister(ILI9225_VERTICAL_SCROLL_CTRL2, 0x0000); + _writeRegister(ILI9225_VERTICAL_SCROLL_CTRL3, 0x0000); + _writeRegister(ILI9225_PARTIAL_DRIVING_POS1, 0x00DB); + _writeRegister(ILI9225_PARTIAL_DRIVING_POS2, 0x0000); + _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR1, 0x00AF); + _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR2, 0x0000); + _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR1, 0x00DB); + _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR2, 0x0000); + + /* Set GAMMA curve */ + _writeRegister(ILI9225_GAMMA_CTRL1, 0x0000); + _writeRegister(ILI9225_GAMMA_CTRL2, 0x0808); + _writeRegister(ILI9225_GAMMA_CTRL3, 0x080A); + _writeRegister(ILI9225_GAMMA_CTRL4, 0x000A); + _writeRegister(ILI9225_GAMMA_CTRL5, 0x0A08); + _writeRegister(ILI9225_GAMMA_CTRL6, 0x0808); + _writeRegister(ILI9225_GAMMA_CTRL7, 0x0000); + _writeRegister(ILI9225_GAMMA_CTRL8, 0x0A00); + _writeRegister(ILI9225_GAMMA_CTRL9, 0x0710); + _writeRegister(ILI9225_GAMMA_CTRL10, 0x0710); + + _writeRegister(ILI9225_DISP_CTRL1, 0x0012); + endWrite(); + delay(50); + startWrite(); + _writeRegister(ILI9225_DISP_CTRL1, 0x1017); + endWrite(); + + // Turn on backlight + setBacklight(true); + setOrientation(0); + + // Initialize variables + setBackgroundColor( COLOR_BLACK ); + + clear(); +} + + +void TFT_22_ILI9225::_spiWrite(uint8_t b) { + if(_clk < 0){ + HSPI_WRITE(b); + return; + } + // Fast SPI bitbang swiped from LPD8806 library + for(uint8_t bit = 0x80; bit; bit >>= 1){ + if((b) & bit){ + SSPI_MOSI_HIGH(); + } else { + SSPI_MOSI_LOW(); + } + SSPI_SCK_HIGH(); + SSPI_SCK_LOW(); + } +} - _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR1,y1); - _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR2,y0); - _writeRegister(ILI9225_RAM_ADDR_SET1,x0); - _writeRegister(ILI9225_RAM_ADDR_SET2,y0); +void TFT_22_ILI9225::_spiWriteCommand(uint8_t c) { + SPI_DC_LOW(); + SPI_CS_LOW(); + _spiWrite(c); + SPI_CS_HIGH(); +} - _writeCommand(0x00, 0x22); - if (hwSPI) spi_end(); +void TFT_22_ILI9225::_spiWriteData(uint8_t c) { + SPI_DC_HIGH(); + SPI_CS_LOW(); + _spiWrite(c); + SPI_CS_HIGH(); } +void TFT_22_ILI9225::_orientCoordinates(uint16_t &x1, uint16_t &y1) { -void TFT_22_ILI9225::begin() { - - // Set up reset pin - if (_rst > 0) { - pinMode(_rst, OUTPUT); - digitalWrite(_rst, LOW); + switch (_orientation) { + case 0: // ok + break; + case 1: // ok + y1 = _maxY - y1 - 1; + _swap(x1, y1); + break; + case 2: // ok + x1 = _maxX - x1 - 1; + y1 = _maxY - y1 - 1; + break; + case 3: // ok + x1 = _maxX - x1 - 1; + _swap(x1, y1); + break; } - // Set up backlight pin, turn off initially - if (_led > 0) { - pinMode(_led, OUTPUT); - setBacklight(false); - } +} - pinMode(_rs, OUTPUT); - pinMode(_cs, OUTPUT); - csport = portOutputRegister(digitalPinToPort(_cs)); - cspinmask = digitalPinToBitMask(_cs); - dcport = portOutputRegister(digitalPinToPort(_rs)); - dcpinmask = digitalPinToBitMask(_rs); +void TFT_22_ILI9225::_setWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { + _orientCoordinates(x0, y0); + _orientCoordinates(x1, y1); - if(hwSPI) { // Using hardware SPI - SPI.begin(); - } else { - pinMode(_clk, OUTPUT); - pinMode(_sdi, OUTPUT); + if (x1 0) { - digitalWrite(_rst, HIGH); // Pull the reset pin high to release the ILI9225C from the reset status - delay(1); - digitalWrite(_rst, LOW); // Pull the reset pin low to reset ILI9225 - delay(10); - digitalWrite(_rst, HIGH); // Pull the reset pin high to release the ILI9225C from the reset status - delay(50); - } + _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR1,x1); + _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR2,x0); - /* Start Initial Sequence */ + _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR1,y1); + _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR2,y0); - /* Set SS bit and direction output from S528 to S1 */ - if (hwSPI) spi_begin(); - _writeRegister(ILI9225_POWER_CTRL1, 0x0000); // Set SAP,DSTB,STB - _writeRegister(ILI9225_POWER_CTRL2, 0x0000); // Set APON,PON,AON,VCI1EN,VC - _writeRegister(ILI9225_POWER_CTRL3, 0x0000); // Set BT,DC1,DC2,DC3 - _writeRegister(ILI9225_POWER_CTRL4, 0x0000); // Set GVDD - _writeRegister(ILI9225_POWER_CTRL5, 0x0000); // Set VCOMH/VCOML voltage - if (hwSPI) spi_end(); - delay(40); - - // Power-on sequence - if (hwSPI) spi_begin(); - _writeRegister(ILI9225_POWER_CTRL2, 0x0018); // Set APON,PON,AON,VCI1EN,VC - _writeRegister(ILI9225_POWER_CTRL3, 0x6121); // Set BT,DC1,DC2,DC3 - _writeRegister(ILI9225_POWER_CTRL4, 0x006F); // Set GVDD /*007F 0088 */ - _writeRegister(ILI9225_POWER_CTRL5, 0x495F); // Set VCOMH/VCOML voltage - _writeRegister(ILI9225_POWER_CTRL1, 0x0800); // Set SAP,DSTB,STB - if (hwSPI) spi_end(); - delay(10); - if (hwSPI) spi_begin(); - _writeRegister(ILI9225_POWER_CTRL2, 0x103B); // Set APON,PON,AON,VCI1EN,VC - if (hwSPI) spi_end(); - delay(50); - - if (hwSPI) spi_begin(); - _writeRegister(ILI9225_DRIVER_OUTPUT_CTRL, 0x011C); // set the display line number and display direction - _writeRegister(ILI9225_LCD_AC_DRIVING_CTRL, 0x0100); // set 1 line inversion - _writeRegister(ILI9225_ENTRY_MODE, 0x1030); // set GRAM write direction and BGR=1. - _writeRegister(ILI9225_DISP_CTRL1, 0x0000); // Display off - _writeRegister(ILI9225_BLANK_PERIOD_CTRL1, 0x0808); // set the back porch and front porch - _writeRegister(ILI9225_FRAME_CYCLE_CTRL, 0x1100); // set the clocks number per line - _writeRegister(ILI9225_INTERFACE_CTRL, 0x0000); // CPU interface - _writeRegister(ILI9225_OSC_CTRL, 0x0D01); // Set Osc /*0e01*/ - _writeRegister(ILI9225_VCI_RECYCLING, 0x0020); // Set VCI recycling - _writeRegister(ILI9225_RAM_ADDR_SET1, 0x0000); // RAM Address - _writeRegister(ILI9225_RAM_ADDR_SET2, 0x0000); // RAM Address - - /* Set GRAM area */ - _writeRegister(ILI9225_GATE_SCAN_CTRL, 0x0000); - _writeRegister(ILI9225_VERTICAL_SCROLL_CTRL1, 0x00DB); - _writeRegister(ILI9225_VERTICAL_SCROLL_CTRL2, 0x0000); - _writeRegister(ILI9225_VERTICAL_SCROLL_CTRL3, 0x0000); - _writeRegister(ILI9225_PARTIAL_DRIVING_POS1, 0x00DB); - _writeRegister(ILI9225_PARTIAL_DRIVING_POS2, 0x0000); - _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR1, 0x00AF); - _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR2, 0x0000); - _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR1, 0x00DB); - _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR2, 0x0000); - - /* Set GAMMA curve */ - _writeRegister(ILI9225_GAMMA_CTRL1, 0x0000); - _writeRegister(ILI9225_GAMMA_CTRL2, 0x0808); - _writeRegister(ILI9225_GAMMA_CTRL3, 0x080A); - _writeRegister(ILI9225_GAMMA_CTRL4, 0x000A); - _writeRegister(ILI9225_GAMMA_CTRL5, 0x0A08); - _writeRegister(ILI9225_GAMMA_CTRL6, 0x0808); - _writeRegister(ILI9225_GAMMA_CTRL7, 0x0000); - _writeRegister(ILI9225_GAMMA_CTRL8, 0x0A00); - _writeRegister(ILI9225_GAMMA_CTRL9, 0x0710); - _writeRegister(ILI9225_GAMMA_CTRL10, 0x0710); - - _writeRegister(ILI9225_DISP_CTRL1, 0x0012); - if (hwSPI) spi_end(); - delay(50); - if (hwSPI) spi_begin(); - _writeRegister(ILI9225_DISP_CTRL1, 0x1017); - if (hwSPI) spi_end(); - - // Turn on backlight - setBacklight(true); - setOrientation(0); - - // Initialize variables - setBackgroundColor( COLOR_BLACK ); - - clear(); + _writeRegister(ILI9225_RAM_ADDR_SET1,x0); + _writeRegister(ILI9225_RAM_ADDR_SET2,y0); + + _writeCommand(0x00, 0x22); + + endWrite(); } void TFT_22_ILI9225::clear() { - uint8_t old = _orientation; - setOrientation(0); - fillRectangle(0, 0, _maxX - 1, _maxY - 1, COLOR_BLACK); - setOrientation(old); - delay(10); + uint8_t old = _orientation; + setOrientation(0); + fillRectangle(0, 0, _maxX - 1, _maxY - 1, COLOR_BLACK); + setOrientation(old); + delay(10); } void TFT_22_ILI9225::invert(boolean flag) { - if (hwSPI) spi_begin(); - _writeCommand(0x00, flag ? ILI9225C_INVON : ILI9225C_INVOFF); - if (hwSPI) spi_end(); + startWrite(); + _writeCommand(0x00, flag ? ILI9225C_INVON : ILI9225C_INVOFF); + endWrite(); } void TFT_22_ILI9225::setBacklight(boolean flag) { - blState = flag; - if (_led) analogWrite(_led, blState ? _brightness : 0); + blState = flag; + if (_led) analogWrite(_led, blState ? _brightness : 0); } void TFT_22_ILI9225::setBacklightBrightness(uint8_t brightness) { - _brightness = brightness; - setBacklight(blState); + _brightness = brightness; + setBacklight(blState); } void TFT_22_ILI9225::setDisplay(boolean flag) { - if (flag) { - if (hwSPI) spi_begin(); - _writeRegister(0x00ff, 0x0000); - _writeRegister(ILI9225_POWER_CTRL1, 0x0000); - if (hwSPI) spi_end(); - delay(50); - if (hwSPI) spi_begin(); - _writeRegister(ILI9225_DISP_CTRL1, 0x1017); - if (hwSPI) spi_end(); - delay(200); - } else { - if (hwSPI) spi_begin(); - _writeRegister(0x00ff, 0x0000); - _writeRegister(ILI9225_DISP_CTRL1, 0x0000); - if (hwSPI) spi_end(); - delay(50); - if (hwSPI) spi_begin(); - _writeRegister(ILI9225_POWER_CTRL1, 0x0003); - if (hwSPI) spi_end(); - delay(200); - } + if (flag) { + startWrite(); + _writeRegister(0x00ff, 0x0000); + _writeRegister(ILI9225_POWER_CTRL1, 0x0000); + endWrite(); + delay(50); + startWrite(); + _writeRegister(ILI9225_DISP_CTRL1, 0x1017); + endWrite(); + delay(200); + } else { + startWrite(); + _writeRegister(0x00ff, 0x0000); + _writeRegister(ILI9225_DISP_CTRL1, 0x0000); + endWrite(); + delay(50); + startWrite(); + _writeRegister(ILI9225_POWER_CTRL1, 0x0003); + endWrite(); + delay(200); + } } void TFT_22_ILI9225::setOrientation(uint8_t orientation) { - _orientation = orientation % 4; - - switch (_orientation) { - case 0: - _maxX = ILI9225_LCD_WIDTH; - _maxY = ILI9225_LCD_HEIGHT; - break; - case 1: - _maxX = ILI9225_LCD_HEIGHT; - _maxY = ILI9225_LCD_WIDTH; - break; - case 2: - _maxX = ILI9225_LCD_WIDTH; - _maxY = ILI9225_LCD_HEIGHT; - break; - case 3: - _maxX = ILI9225_LCD_HEIGHT; - _maxY = ILI9225_LCD_WIDTH; - break; - } + _orientation = orientation % 4; + + switch (_orientation) { + case 0: + _maxX = ILI9225_LCD_WIDTH; + _maxY = ILI9225_LCD_HEIGHT; + break; + case 1: + _maxX = ILI9225_LCD_HEIGHT; + _maxY = ILI9225_LCD_WIDTH; + break; + case 2: + _maxX = ILI9225_LCD_WIDTH; + _maxY = ILI9225_LCD_HEIGHT; + break; + case 3: + _maxX = ILI9225_LCD_HEIGHT; + _maxY = ILI9225_LCD_WIDTH; + break; + } } uint8_t TFT_22_ILI9225::getOrientation() { - return _orientation; + return _orientation; } void TFT_22_ILI9225::drawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) { - if (hwSPI) spi_begin(); + startWrite(); checkSPI = false; - drawLine(x1, y1, x1, y2, color); - drawLine(x1, y1, x2, y1, color); - drawLine(x1, y2, x2, y2, color); - drawLine(x2, y1, x2, y2, color); + drawLine(x1, y1, x1, y2, color); + drawLine(x1, y1, x2, y1, color); + drawLine(x1, y2, x2, y2, color); + drawLine(x2, y1, x2, y2, color); checkSPI = true; - if (hwSPI) spi_end(); + endWrite(); } void TFT_22_ILI9225::fillRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) { - _setWindow(x1, y1, x2, y2); + _setWindow(x1, y1, x2, y2); - if (hwSPI) spi_begin(); - for(uint16_t t=(y2 - y1 + 1) * (x2 - x1 + 1); t > 0; t--) - _writeData(color >> 8, color); - if (hwSPI) spi_end(); + startWrite(); + for(uint16_t t=(y2 - y1 + 1) * (x2 - x1 + 1); t > 0; t--) + _writeData(color >> 8, color); + endWrite(); } void TFT_22_ILI9225::drawCircle(uint16_t x0, uint16_t y0, uint16_t r, uint16_t color) { - int16_t f = 1 - r; - int16_t ddF_x = 1; - int16_t ddF_y = -2 * r; - int16_t x = 0; - int16_t y = r; + int16_t f = 1 - r; + int16_t ddF_x = 1; + int16_t ddF_y = -2 * r; + int16_t x = 0; + int16_t y = r; - if (hwSPI) spi_begin(); + startWrite(); checkSPI = false; - drawPixel(x0, y0 + r, color); - drawPixel(x0, y0- r, color); - drawPixel(x0 + r, y0, color); - drawPixel(x0 - r, y0, color); - - while (x= 0) { - y--; - ddF_y += 2; - f += ddF_y; - } - x++; - ddF_x += 2; - f += ddF_x; - - drawPixel(x0 + x, y0 + y, color); - drawPixel(x0 - x, y0 + y, color); - drawPixel(x0 + x, y0 - y, color); - drawPixel(x0 - x, y0 - y, color); - drawPixel(x0 + y, y0 + x, color); - drawPixel(x0 - y, y0 + x, color); - drawPixel(x0 + y, y0 - x, color); - drawPixel(x0 - y, y0 - x, color); - } + drawPixel(x0, y0 + r, color); + drawPixel(x0, y0- r, color); + drawPixel(x0 + r, y0, color); + drawPixel(x0 - r, y0, color); + + while (x= 0) { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x; + + drawPixel(x0 + x, y0 + y, color); + drawPixel(x0 - x, y0 + y, color); + drawPixel(x0 + x, y0 - y, color); + drawPixel(x0 - x, y0 - y, color); + drawPixel(x0 + y, y0 + x, color); + drawPixel(x0 - y, y0 + x, color); + drawPixel(x0 + y, y0 - x, color); + drawPixel(x0 - y, y0 - x, color); + } checkSPI = true; - if (hwSPI) spi_end(); + endWrite(); } void TFT_22_ILI9225::fillCircle(uint8_t x0, uint8_t y0, uint8_t radius, uint16_t color) { - int16_t f = 1 - radius; - int16_t ddF_x = 1; - int16_t ddF_y = -2 * radius; - int16_t x = 0; - int16_t y = radius; + int16_t f = 1 - radius; + int16_t ddF_x = 1; + int16_t ddF_y = -2 * radius; + int16_t x = 0; + int16_t y = radius; - if (hwSPI) spi_begin(); + startWrite(); checkSPI = false; - while (x= 0) { - y--; - ddF_y += 2; - f += ddF_y; - } - x++; - ddF_x += 2; - f += ddF_x; - - drawLine(x0 + x, y0 + y, x0 - x, y0 + y, color); // bottom - drawLine(x0 + x, y0 - y, x0 - x, y0 - y, color); // top - drawLine(x0 + y, y0 - x, x0 + y, y0 + x, color); // right - drawLine(x0 - y, y0 - x, x0 - y, y0 + x, color); // left - } + while (x= 0) { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x; + + drawLine(x0 + x, y0 + y, x0 - x, y0 + y, color); // bottom + drawLine(x0 + x, y0 - y, x0 - x, y0 - y, color); // top + drawLine(x0 + y, y0 - x, x0 + y, y0 + x, color); // right + drawLine(x0 - y, y0 - x, x0 - y, y0 + x, color); // left + } checkSPI = true; - if (hwSPI) spi_end(); - fillRectangle(x0-x, y0-y, x0+x, y0+y, color); + endWrite(); + fillRectangle(x0-x, y0-y, x0+x, y0+y, color); } void TFT_22_ILI9225::drawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) { - // Classic Bresenham algorithm - int16_t steep = abs(y2 - y1) > abs(x2 - x1); - int16_t dx, dy; + // Classic Bresenham algorithm + int16_t steep = abs(y2 - y1) > abs(x2 - x1); + int16_t dx, dy; - if (steep) { - _swap(x1, y1); - _swap(x2, y2); - } - - if (x1 > x2) { - _swap(x1, x2); - _swap(y1, y2); - } + if (steep) { + _swap(x1, y1); + _swap(x2, y2); + } - dx = x2 - x1; - dy = abs(y2 - y1); + if (x1 > x2) { + _swap(x1, x2); + _swap(y1, y2); + } - int16_t err = dx / 2; - int16_t ystep; + dx = x2 - x1; + dy = abs(y2 - y1); - if (y1 < y2) ystep = 1; - else ystep = -1; + int16_t err = dx / 2; + int16_t ystep; + if (y1 < y2) ystep = 1; + else ystep = -1; bool inTrans = checkSPI; - if (hwSPI && checkSPI) spi_begin(); + if (checkSPI) startWrite(); if (inTrans) checkSPI = false; - for (; x1<=x2; x1++) { - if (steep) drawPixel(y1, x1, color); - else drawPixel(x1, y1, color); - - err -= dy; - if (err < 0) { - y1 += ystep; - err += dx; - } - } - if (hwSPI && checkSPI) spi_end(); + for (; x1<=x2; x1++) { + if (steep) drawPixel(y1, x1, color); + else drawPixel(x1, y1, color); + + err -= dy; + if (err < 0) { + y1 += ystep; + err += dx; + } + } + if (checkSPI) endWrite(); if (inTrans) checkSPI = true; } void TFT_22_ILI9225::drawPixel(uint16_t x1, uint16_t y1, uint16_t color) { - if((x1 >= _maxX) || (y1 >= _maxY)) return; + if((x1 >= _maxX) || (y1 >= _maxY)) return; - _setWindow(x1, y1, x1+1, y1+1); - _orientCoordinates(x1, y1); - if (hwSPI && checkSPI) spi_begin(); - _writeData(color >> 8, color); - if (hwSPI && checkSPI) spi_end(); + _setWindow(x1, y1, x1+1, y1+1); + _orientCoordinates(x1, y1); + if (checkSPI) startWrite(); + _writeData(color >> 8, color); + if (checkSPI) endWrite(); } uint16_t TFT_22_ILI9225::maxX() { - return _maxX; + return _maxX; } uint16_t TFT_22_ILI9225::maxY() { - return _maxY; + return _maxY; } uint16_t TFT_22_ILI9225::setColor(uint8_t red8, uint8_t green8, uint8_t blue8) { - // rgb16 = red5 green6 blue5 - return (red8 >> 3) << 11 | (green8 >> 2) << 5 | (blue8 >> 3); + // rgb16 = red5 green6 blue5 + return (red8 >> 3) << 11 | (green8 >> 2) << 5 | (blue8 >> 3); } void TFT_22_ILI9225::splitColor(uint16_t rgb, uint8_t &red, uint8_t &green, uint8_t &blue) { - // rgb16 = red5 green6 blue5 - red = (rgb & 0b1111100000000000) >> 11 << 3; - green = (rgb & 0b0000011111100000) >> 5 << 2; - blue = (rgb & 0b0000000000011111) << 3; + // rgb16 = red5 green6 blue5 + red = (rgb & 0b1111100000000000) >> 11 << 3; + green = (rgb & 0b0000011111100000) >> 5 << 2; + blue = (rgb & 0b0000000000011111) << 3; } void TFT_22_ILI9225::_swap(uint16_t &a, uint16_t &b) { - uint16_t w = a; - a = b; - b = w; + uint16_t w = a; + a = b; + b = w; } // Utilities void TFT_22_ILI9225::_writeCommand(uint8_t HI, uint8_t LO) { - _writecommand(HI); - _writecommand(LO); + _spiWriteCommand(HI); + _spiWriteCommand(LO); } void TFT_22_ILI9225::_writeData(uint8_t HI, uint8_t LO) { - _writedata(HI); - _writedata(LO); + _spiWriteData(HI); + _spiWriteData(LO); } void TFT_22_ILI9225::_writeRegister(uint16_t reg, uint16_t data) { - _writeCommand(reg >> 8, reg & 255); - _writeData(data >> 8, data & 255); + _writeCommand(reg >> 8, reg & 255); + _writeData(data >> 8, data & 255); } void TFT_22_ILI9225::drawTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, uint16_t color) { - if (hwSPI) spi_begin(); + startWrite(); checkSPI = false; - drawLine(x1, y1, x2, y2, color); - drawLine(x2, y2, x3, y3, color); - drawLine(x3, y3, x1, y1, color); + drawLine(x1, y1, x2, y2, color); + drawLine(x2, y2, x3, y3, color); + drawLine(x3, y3, x1, y1, color); checkSPI = true; - if (hwSPI) spi_end(); + endWrite(); } void TFT_22_ILI9225::fillTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, uint16_t color) { - uint16_t a, b, y, last; + uint16_t a, b, y, last; - // Sort coordinates by Y order (y3 >= y2 >= y1) - if (y1 > y2) { - _swap(y1, y2); _swap(x1, x2); - } - if (y2 > y3) { - _swap(y3, y2); _swap(x3, x2); - } - if (y1 > y2) { - _swap(y1, y2); _swap(x1, x2); - } + // Sort coordinates by Y order (y3 >= y2 >= y1) + if (y1 > y2) { + _swap(y1, y2); _swap(x1, x2); + } + if (y2 > y3) { + _swap(y3, y2); _swap(x3, x2); + } + if (y1 > y2) { + _swap(y1, y2); _swap(x1, x2); + } - if (hwSPI) spi_begin(); + startWrite(); checkSPI = false; - if (y1 == y3) { // Handle awkward all-on-same-line case as its own thing - a = b = x1; - if (x2 < a) a = x2; - else if (x2 > b) b = x2; - if (x3 < a) a = x3; - else if (x3 > b) b = x3; - drawLine(a, y1, b, y1, color); - return; - } - - uint16_t dx11 = x2 - x1, - dy11 = y2 - y1, - dx12 = x3 - x1, - dy12 = y3 - y1, - dx22 = x3 - x2, - dy22 = y3 - y2, - sa = 0, - sb = 0; - - // For upper part of triangle, find scanline crossings for segments - // 0-1 and 0-2. If y2=y3 (flat-bottomed triangle), the scanline y2 - // is included here (and second loop will be skipped, avoiding a /0 - // error there), otherwise scanline y2 is skipped here and handled - // in the second loop...which also avoids a /0 error here if y1=y2 - // (flat-topped triangle). - if (y2 == y3) last = y2; // Include y2 scanline - else last = y2 - 1; // Skip it - - for (y = y1; y <= last; y++) { - a = x1 + sa / dy11; - b = x1 + sb / dy12; - sa += dx11; - sb += dx12; - /* longhand: - a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); - b = x1 + (x3 - x1) * (y - y1) / (y3 - y1); - */ - if (a > b) _swap(a,b); - drawLine(a, y, b, y, color); - } - - // For lower part of triangle, find scanline crossings for segments - // 0-2 and 1-2. This loop is skipped if y2=y3. - sa = dx22 * (y - y2); - sb = dx12 * (y - y1); - for (; y<=y3; y++) { - a = x2 + sa / dy22; - b = x1 + sb / dy12; - sa += dx22; - sb += dx12; - /* longhand: - a = x2 + (x3 - x2) * (y - y2) / (y3 - y2); - b = x1 + (x3 - x1) * (y - y1) / (y3 - y1); - */ - if (a > b) _swap(a,b); - drawLine(a, y, b, y, color); - } + if (y1 == y3) { // Handle awkward all-on-same-line case as its own thing + a = b = x1; + if (x2 < a) a = x2; + else if (x2 > b) b = x2; + if (x3 < a) a = x3; + else if (x3 > b) b = x3; + drawLine(a, y1, b, y1, color); + return; + } + + uint16_t dx11 = x2 - x1, + dy11 = y2 - y1, + dx12 = x3 - x1, + dy12 = y3 - y1, + dx22 = x3 - x2, + dy22 = y3 - y2, + sa = 0, + sb = 0; + + // For upper part of triangle, find scanline crossings for segments + // 0-1 and 0-2. If y2=y3 (flat-bottomed triangle), the scanline y2 + // is included here (and second loop will be skipped, avoiding a /0 + // error there), otherwise scanline y2 is skipped here and handled + // in the second loop...which also avoids a /0 error here if y1=y2 + // (flat-topped triangle). + if (y2 == y3) last = y2; // Include y2 scanline + else last = y2 - 1; // Skip it + + for (y = y1; y <= last; y++) { + a = x1 + sa / dy11; + b = x1 + sb / dy12; + sa += dx11; + sb += dx12; + /* longhand: + a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); + b = x1 + (x3 - x1) * (y - y1) / (y3 - y1); + */ + if (a > b) _swap(a,b); + drawLine(a, y, b, y, color); + } + + // For lower part of triangle, find scanline crossings for segments + // 0-2 and 1-2. This loop is skipped if y2=y3. + sa = dx22 * (y - y2); + sb = dx12 * (y - y1); + for (; y<=y3; y++) { + a = x2 + sa / dy22; + b = x1 + sb / dy12; + sa += dx22; + sb += dx12; + /* longhand: + a = x2 + (x3 - x2) * (y - y2) / (y3 - y2); + b = x1 + (x3 - x1) * (y - y1) / (y3 - y1); + */ + if (a > b) _swap(a,b); + drawLine(a, y, b, y, color); + } checkSPI = true; - if (hwSPI) spi_end(); + endWrite(); } void TFT_22_ILI9225::setBackgroundColor(uint16_t color) { - _bgColor = color; + _bgColor = color; } void TFT_22_ILI9225::setFont(uint8_t* font) { - cfont.font = font; - cfont.width = readFontByte(0); - cfont.height = readFontByte(1); - cfont.offset = readFontByte(2); - cfont.numchars = readFontByte(3); - cfont.nbrows = cfont.height / 8; + cfont.font = font; + cfont.width = readFontByte(0); + cfont.height = readFontByte(1); + cfont.offset = readFontByte(2); + cfont.numchars = readFontByte(3); + cfont.nbrows = cfont.height / 8; - if (cfont.height % 8) cfont.nbrows++; // Set number of bytes used by height of font in multiples of 8 + if (cfont.height % 8) cfont.nbrows++; // Set number of bytes used by height of font in multiples of 8 } void TFT_22_ILI9225::drawText(uint16_t x, uint16_t y, String s, uint16_t color) { - uint16_t currx = x; + uint16_t currx = x; - // Print every character in string - for (uint8_t k = 0; k < s.length(); k++) { - currx += drawChar(currx, y, s.charAt(k), color) + 1; - } + // Print every character in string + for (uint8_t k = 0; k < s.length(); k++) { + currx += drawChar(currx, y, s.charAt(k), color) + 1; + } } uint16_t TFT_22_ILI9225::drawChar(uint16_t x, uint16_t y, uint16_t ch, uint16_t color) { - uint8_t charData, charWidth; - uint8_t h, i, j; - uint16_t charOffset; + uint8_t charData, charWidth; + uint8_t h, i, j; + uint16_t charOffset; - charOffset = (cfont.width * cfont.nbrows) + 1; // bytes used by each character - charOffset = (charOffset * (ch - cfont.offset)) + FONT_HEADER_SIZE; // char offset (add 4 for font header) - charWidth = readFontByte(charOffset); // get font width from 1st byte - charOffset++; // increment pointer to first character data byte + charOffset = (cfont.width * cfont.nbrows) + 1; // bytes used by each character + charOffset = (charOffset * (ch - cfont.offset)) + FONT_HEADER_SIZE; // char offset (add 4 for font header) + charWidth = readFontByte(charOffset); // get font width from 1st byte + charOffset++; // increment pointer to first character data byte - if (hwSPI) spi_begin(); + startWrite(); checkSPI = false; - for (i = 0; i <= charWidth; i++) { // each font "column" (+1 blank column for spacing) - h = 0; // keep track of char height - for (j = 0; j < cfont.nbrows; j++) { // each column byte - if (i == charWidth) charData = (uint8_t)0x0; // Insert blank column - else charData = readFontByte(charOffset); - charOffset++; - - // Process every row in font character - for (uint8_t k = 0; k < 8; k++) { - if (h >= cfont.height ) break; // No need to process excess bits - if (bitRead(charData, k)) drawPixel(x + i, y + (j * 8) + k, color); - else drawPixel(x + i, y + (j * 8) + k, _bgColor); - h++; - }; - }; - }; + for (i = 0; i <= charWidth; i++) { // each font "column" (+1 blank column for spacing) + h = 0; // keep track of char height + for (j = 0; j < cfont.nbrows; j++) { // each column byte + if (i == charWidth) charData = (uint8_t)0x0; // Insert blank column + else charData = readFontByte(charOffset); + charOffset++; + + // Process every row in font character + for (uint8_t k = 0; k < 8; k++) { + if (h >= cfont.height ) break; // No need to process excess bits + if (bitRead(charData, k)) drawPixel(x + i, y + (j * 8) + k, color); + else drawPixel(x + i, y + (j * 8) + k, _bgColor); + h++; + }; + }; + }; checkSPI = true; - if (hwSPI) spi_end(); + endWrite(); - return charWidth; + return charWidth; } // Draw a 1-bit image (bitmap) at the specified (x,y) position from the @@ -722,20 +872,20 @@ uint16_t TFT_22_ILI9225::drawChar(uint16_t x, uint16_t y, uint16_t ch, uint16_t void TFT_22_ILI9225::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) { - int16_t i, j, byteWidth = (w + 7) / 8; - uint8_t byte = 0; + int16_t i, j, byteWidth = (w + 7) / 8; + uint8_t byte = 0; - if (hwSPI) spi_begin(); + startWrite(); checkSPI = false; - for (j = 0; j < h; j++) { - for (i = 0; i < w; i++) { - if (i & 7) byte <<= 1; - else byte = pgm_read_byte(bitmap + j * byteWidth + i / 8); - if (byte & 0x80) drawPixel(x + i, y + j, color); - } - } + for (j = 0; j < h; j++) { + for (i = 0; i < w; i++) { + if (i & 7) byte <<= 1; + else byte = pgm_read_byte(bitmap + j * byteWidth + i / 8); + if (byte & 0x80) drawPixel(x + i, y + j, color); + } + } checkSPI = true; - if (hwSPI) spi_end(); + endWrite(); } // Draw a 1-bit image (bitmap) at the specified (x,y) position from the @@ -744,62 +894,62 @@ const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) { void TFT_22_ILI9225::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg) { - int16_t i, j, byteWidth = (w + 7) / 8; - uint8_t byte; + int16_t i, j, byteWidth = (w + 7) / 8; + uint8_t byte; - if (hwSPI) spi_begin(); + startWrite(); checkSPI = false; - for (j = 0; j < h; j++) { - for (i = 0; i < w; i++ ) { - if (i & 7) byte <<= 1; - else byte = pgm_read_byte(bitmap + j * byteWidth + i / 8); - if (byte & 0x80) drawPixel(x + i, y + j, color); - else drawPixel(x + i, y + j, bg); - } - } + for (j = 0; j < h; j++) { + for (i = 0; i < w; i++ ) { + if (i & 7) byte <<= 1; + else byte = pgm_read_byte(bitmap + j * byteWidth + i / 8); + if (byte & 0x80) drawPixel(x + i, y + j, color); + else drawPixel(x + i, y + j, bg); + } + } checkSPI = true; - if (hwSPI) spi_end(); + endWrite(); } // drawBitmap() variant for RAM-resident (not PROGMEM) bitmaps. void TFT_22_ILI9225::drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) { - int16_t i, j, byteWidth = (w + 7) / 8; - uint8_t byte; + int16_t i, j, byteWidth = (w + 7) / 8; + uint8_t byte; - if (hwSPI) spi_begin(); + startWrite(); checkSPI = false; - for(j = 0; j < h; j++) { - for(i = 0; i < w; i++) { - if (i & 7) byte <<= 1; - else byte = bitmap[j * byteWidth + i / 8]; - if (byte & 0x80) drawPixel(x + i, y + j, color); - } - } + for(j = 0; j < h; j++) { + for(i = 0; i < w; i++) { + if (i & 7) byte <<= 1; + else byte = bitmap[j * byteWidth + i / 8]; + if (byte & 0x80) drawPixel(x + i, y + j, color); + } + } checkSPI = true; - if (hwSPI) spi_end(); + endWrite(); } // drawBitmap() variant w/background for RAM-resident (not PROGMEM) bitmaps. void TFT_22_ILI9225::drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg) { - int16_t i, j, byteWidth = (w + 7) / 8; - uint8_t byte; + int16_t i, j, byteWidth = (w + 7) / 8; + uint8_t byte; - if (hwSPI) spi_begin(); + startWrite(); checkSPI = false; - for (j = 0; j < h; j++) { - for (i = 0; i < w; i++ ) { - if (i & 7) byte <<= 1; - else byte = bitmap[j * byteWidth + i / 8]; - if (byte & 0x80) drawPixel(x + i, y + j, color); - else drawPixel(x + i, y + j, bg); - } - } + for (j = 0; j < h; j++) { + for (i = 0; i < w; i++ ) { + if (i & 7) byte <<= 1; + else byte = bitmap[j * byteWidth + i / 8]; + if (byte & 0x80) drawPixel(x + i, y + j, color); + else drawPixel(x + i, y + j, bg); + } + } checkSPI = true; - if (hwSPI) spi_end(); + endWrite(); } //Draw XBitMap Files (*.xbm), exported from GIMP, @@ -808,18 +958,30 @@ uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg) { void TFT_22_ILI9225::drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) { - int16_t i, j, byteWidth = (w + 7) / 8; - uint8_t byte; + int16_t i, j, byteWidth = (w + 7) / 8; + uint8_t byte; - if (hwSPI) spi_begin(); + startWrite(); checkSPI = false; - for (j = 0; j < h; j++) { - for (i = 0; i < w; i++ ) { - if (i & 7) byte >>= 1; - else byte = pgm_read_byte(bitmap + j * byteWidth + i / 8); - if (byte & 0x01) drawPixel(x + i, y + j, color); - } - } + for (j = 0; j < h; j++) { + for (i = 0; i < w; i++ ) { + if (i & 7) byte >>= 1; + else byte = pgm_read_byte(bitmap + j * byteWidth + i / 8); + if (byte & 0x01) drawPixel(x + i, y + j, color); + } + } checkSPI = true; - if (hwSPI) spi_end(); + endWrite(); +} + + +void TFT_22_ILI9225::startWrite(void){ + SPI_BEGIN_TRANSACTION(); + // SPI_CS_LOW(); +} + + +void TFT_22_ILI9225::endWrite(void){ + // SPI_CS_HIGH(); + SPI_END_TRANSACTION(); } diff --git a/src/TFT_22_ILI9225.h b/src/TFT_22_ILI9225.h index 0c6a556..ee5fdc0 100644 --- a/src/TFT_22_ILI9225.h +++ b/src/TFT_22_ILI9225.h @@ -6,7 +6,14 @@ #else #include "WProgram.h" #endif -#include +#include + +#if defined(ARDUINO_STM32_FEATHER) +typedef volatile uint32 RwReg; +#endif +#if defined(ARDUINO_FEATHER52) +typedef volatile uint32_t RwReg; +#endif /* ILI9225 screen size */ #define ILI9225_LCD_WIDTH 176 @@ -15,18 +22,18 @@ /* ILI9225 LCD Registers */ #define ILI9225_DRIVER_OUTPUT_CTRL (0x01u) // Driver Output Control #define ILI9225_LCD_AC_DRIVING_CTRL (0x02u) // LCD AC Driving Control -#define ILI9225_ENTRY_MODE (0x03u) // Entry Mode -#define ILI9225_DISP_CTRL1 (0x07u) // Display Control 1 +#define ILI9225_ENTRY_MODE (0x03u) // Entry Mode +#define ILI9225_DISP_CTRL1 (0x07u) // Display Control 1 #define ILI9225_BLANK_PERIOD_CTRL1 (0x08u) // Blank Period Control #define ILI9225_FRAME_CYCLE_CTRL (0x0Bu) // Frame Cycle Control #define ILI9225_INTERFACE_CTRL (0x0Cu) // Interface Control -#define ILI9225_OSC_CTRL (0x0Fu) // Osc Control -#define ILI9225_POWER_CTRL1 (0x10u) // Power Control 1 -#define ILI9225_POWER_CTRL2 (0x11u) // Power Control 2 -#define ILI9225_POWER_CTRL3 (0x12u) // Power Control 3 -#define ILI9225_POWER_CTRL4 (0x13u) // Power Control 4 -#define ILI9225_POWER_CTRL5 (0x14u) // Power Control 5 -#define ILI9225_VCI_RECYCLING (0x15u) // VCI Recycling +#define ILI9225_OSC_CTRL (0x0Fu) // Osc Control +#define ILI9225_POWER_CTRL1 (0x10u) // Power Control 1 +#define ILI9225_POWER_CTRL2 (0x11u) // Power Control 2 +#define ILI9225_POWER_CTRL3 (0x12u) // Power Control 3 +#define ILI9225_POWER_CTRL4 (0x13u) // Power Control 4 +#define ILI9225_POWER_CTRL5 (0x14u) // Power Control 5 +#define ILI9225_VCI_RECYCLING (0x15u) // VCI Recycling #define ILI9225_RAM_ADDR_SET1 (0x20u) // Horizontal GRAM Address Set #define ILI9225_RAM_ADDR_SET2 (0x21u) // Vertical GRAM Address Set #define ILI9225_GRAM_DATA_REG (0x22u) // GRAM Data Register @@ -37,17 +44,17 @@ #define ILI9225_PARTIAL_DRIVING_POS1 (0x34u) // Partial Driving Position 1 Register #define ILI9225_PARTIAL_DRIVING_POS2 (0x35u) // Partial Driving Position 2 Register #define ILI9225_HORIZONTAL_WINDOW_ADDR1 (0x36u) // Horizontal Address Start Position -#define ILI9225_HORIZONTAL_WINDOW_ADDR2 (0x37u) // Horizontal Address End Position +#define ILI9225_HORIZONTAL_WINDOW_ADDR2 (0x37u) // Horizontal Address End Position #define ILI9225_VERTICAL_WINDOW_ADDR1 (0x38u) // Vertical Address Start Position #define ILI9225_VERTICAL_WINDOW_ADDR2 (0x39u) // Vertical Address End Position -#define ILI9225_GAMMA_CTRL1 (0x50u) // Gamma Control 1 +#define ILI9225_GAMMA_CTRL1 (0x50u) // Gamma Control 1 #define ILI9225_GAMMA_CTRL2 (0x51u) // Gamma Control 2 -#define ILI9225_GAMMA_CTRL3 (0x52u) // Gamma Control 3 -#define ILI9225_GAMMA_CTRL4 (0x53u) // Gamma Control 4 -#define ILI9225_GAMMA_CTRL5 (0x54u) // Gamma Control 5 -#define ILI9225_GAMMA_CTRL6 (0x55u) // Gamma Control 6 -#define ILI9225_GAMMA_CTRL7 (0x56u) // Gamma Control 7 -#define ILI9225_GAMMA_CTRL8 (0x57u) // Gamma Control 8 +#define ILI9225_GAMMA_CTRL3 (0x52u) // Gamma Control 3 +#define ILI9225_GAMMA_CTRL4 (0x53u) // Gamma Control 4 +#define ILI9225_GAMMA_CTRL5 (0x54u) // Gamma Control 5 +#define ILI9225_GAMMA_CTRL6 (0x55u) // Gamma Control 6 +#define ILI9225_GAMMA_CTRL7 (0x56u) // Gamma Control 7 +#define ILI9225_GAMMA_CTRL8 (0x57u) // Gamma Control 8 #define ILI9225_GAMMA_CTRL9 (0x58u) // Gamma Control 9 #define ILI9225_GAMMA_CTRL10 (0x59u) // Gamma Control 10 @@ -108,211 +115,246 @@ extern uint8_t Trebuchet_MS16x21[]; struct _currentFont { - uint8_t* font; - uint8_t width; - uint8_t height; - uint8_t offset; - uint8_t numchars; - uint8_t nbrows; + uint8_t* font; + uint8_t width; + uint8_t height; + uint8_t offset; + uint8_t numchars; + uint8_t nbrows; }; +#if defined (ARDUINO_STM32_FEATHER) + #undef USE_FAST_PINIO +#elif defined (__AVR__) || defined(TEENSYDUINO) || defined(ESP8266) || defined (ESP32) || defined(__arm__) + #define USE_FAST_PINIO +#endif + /// Main and core class class TFT_22_ILI9225 { - public: - - TFT_22_ILI9225(uint8_t RST, uint8_t RS, uint8_t CS, uint8_t SDI, uint8_t CLK, uint8_t LED); - TFT_22_ILI9225(uint8_t RST, uint8_t RS, uint8_t CS, uint8_t LED); - TFT_22_ILI9225(uint8_t RST, uint8_t RS, uint8_t CS, uint8_t SDI, uint8_t CLK, uint8_t LED, uint8_t brightness); - TFT_22_ILI9225(uint8_t RST, uint8_t RS, uint8_t CS, uint8_t LED, uint8_t brightness); - - /// Initialization - void begin(void); - - /// Clear the screen - void clear(void); - - /// Invert screen - /// @param flag true to invert, false for normal screen - void invert(boolean flag); - - /// Switch backlight on or off - /// @param flag true=on, false=off - void setBacklight(boolean flag); - - /// Set backlight brightness - /// @param brightness sets backlight brightness 0-255 - void setBacklightBrightness(uint8_t brightness); - - /// Switch display on or off - /// @param flag true=on, false=off - void setDisplay(boolean flag); - - /// Set orientation - /// @param orientation orientation, 0=portrait, 1=right rotated landscape, 2=reverse portrait, 3=left rotated landscape - void setOrientation(uint8_t orientation); - - /// Get orientation - /// @return orientation orientation, 0=portrait, 1=right rotated landscape, 2=reverse portrait, 3=left rotated landscape - uint8_t getOrientation(void); - - /// Font size, x-axis - /// @return horizontal size of current font, in pixels - // uint8_t fontX(void); - - /// Font size, y-axis - /// @return vertical size of current font, in pixels - // uint8_t fontY(void); - - /// Screen size, x-axis - /// @return horizontal size of the screen, in pixels - /// @note 240 means 240 pixels and thus 0..239 coordinates (decimal) - uint16_t maxX(void); - - /// Screen size, y-axis - /// @return vertical size of the screen, in pixels - /// @note 220 means 220 pixels and thus 0..219 coordinates (decimal) - uint16_t maxY(void); - - /// Draw circle - /// @param x0 center, point coordinate, x-axis - /// @param y0 center, point coordinate, y-axis - /// @param radius radius - /// @param color 16-bit color - void drawCircle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t color); - - /// Draw solid circle - /// @param x0 center, point coordinate, x-axis - /// @param y0 center, point coordinate, y-axis - /// @param radius radius - /// @param color 16-bit color - void fillCircle(uint8_t x0, uint8_t y0, uint8_t radius, uint16_t color); - - /// Set background color - /// @param color background color, default=black - void setBackgroundColor(uint16_t color = COLOR_BLACK); - - /// Draw line, rectangle coordinates - /// @param x1 top left coordinate, x-axis - /// @param y1 top left coordinate, y-axis - /// @param x2 bottom right coordinate, x-axis - /// @param y2 bottom right coordinate, y-axis - /// @param color 16-bit color - void drawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color); - - /// Draw rectangle, rectangle coordinates - /// @param x1 top left coordinate, x-axis - /// @param y1 top left coordinate, y-axis - /// @param x2 bottom right coordinate, x-axis - /// @param y2 bottom right coordinate, y-axis - /// @param color 16-bit color - void drawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color); - - /// Draw solid rectangle, rectangle coordinates - /// @param x1 top left coordinate, x-axis - /// @param y1 top left coordinate, y-axis - /// @param x2 bottom right coordinate, x-axis - /// @param y2 bottom right coordinate, y-axis - /// @param color 16-bit color - void fillRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color); - - /// Draw pixel - /// @param x1 point coordinate, x-axis - /// @param y1 point coordinate, y-axis - /// @param color 16-bit color - void drawPixel(uint16_t x1, uint16_t y1, uint16_t color); - - /// Draw ASCII Text (pixel coordinates) - /// @param x point coordinate, x-axis - /// @param y point coordinate, y-axis - /// @param s text string - /// @param color 16-bit color, default=white - void drawText(uint16_t x, uint16_t y, String s, uint16_t color = COLOR_WHITE); - - /// Calculate 16-bit color from 8-bit Red-Green-Blue components - /// @param red red component, 0x00..0xff - /// @param green green component, 0x00..0xff - /// @param blue blue component, 0x00..0xff - /// @return 16-bit color - uint16_t setColor(uint8_t red, uint8_t green, uint8_t blue); - - /// Calculate 8-bit Red-Green-Blue components from 16-bit color - /// @param rgb 16-bit color - /// @param red red component, 0x00..0xff - /// @param green green component, 0x00..0xff - /// @param blue blue component, 0x00..0xff - void splitColor(uint16_t rgb, uint8_t &red, uint8_t &green, uint8_t &blue); - - /// Draw triangle, triangle coordinates - /// @param x1 corner 1 coordinate, x-axis - /// @param y1 corner 1 coordinate, y-axis - /// @param x2 corner 2 coordinate, x-axis - /// @param y2 corner 2 coordinate, y-axis - /// @param x3 corner 3 coordinate, x-axis - /// @param y3 corner 3 coordinate, y-axis - /// @param color 16-bit color - void drawTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, uint16_t color); - - /// Draw solid triangle, triangle coordinates - /// @param x1 corner 1 coordinate, x-axis - /// @param y1 corner 1 coordinate, y-axis - /// @param x2 corner 2 coordinate, x-axis - /// @param y2 corner 2 coordinate, y-axis - /// @param x3 corner 3 coordinate, x-axis - /// @param y3 corner 3 coordinate, y-axis - /// @param color 16-bit color - void fillTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, uint16_t color); - - /// Set current font - /// @param font Font name - void setFont(uint8_t* font); - - /// Draw single character (pixel coordinates) - /// @param x point coordinate, x-axis - /// @param y point coordinate, y-axis - /// @param ch ASCII character - /// @param color 16-bit color, default=white - uint16_t drawChar(uint16_t x, uint16_t y, uint16_t ch, uint16_t color = COLOR_WHITE); - - /// Draw bitmap - /// @param x point coordinate, x-axis - /// @param y point coordinate, y-axis - /// @param bitmap - /// @param w width - /// @param h height - /// @param color 16-bit color, default=white - /// @param bg 16-bit color, background - void drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color); - void drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg); - void drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color); - void drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg); - - void drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color); - - private: - - void _spiwrite(uint8_t); - void _writecommand(uint8_t c); - void _writedata(uint8_t d); - - void _swap(uint16_t &a, uint16_t &b); - void _setWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); - void _orientCoordinates(uint16_t &x1, uint16_t &y1); - void _writeRegister(uint16_t reg, uint16_t data); - void _writeData(uint8_t HI, uint8_t LO); - void _writeCommand(uint8_t HI, uint8_t LO); - - uint16_t _maxX, _maxY, _bgColor; + public: + + TFT_22_ILI9225(int8_t RST, int8_t RS, int8_t CS, int8_t SDI, int8_t CLK, int8_t LED); + TFT_22_ILI9225(int8_t RST, int8_t RS, int8_t CS, int8_t LED); + TFT_22_ILI9225(int8_t RST, int8_t RS, int8_t CS, int8_t SDI, int8_t CLK, int8_t LED, uint8_t brightness); + TFT_22_ILI9225(int8_t RST, int8_t RS, int8_t CS, int8_t LED, uint8_t brightness); + /// Initialization +#ifdef ESP32 + void begin(SPIClass &spi) +#else + void begin(void); +#endif + + /// Clear the screen + void clear(void); + + /// Invert screen + /// @param flag true to invert, false for normal screen + void invert(boolean flag); + + /// Switch backlight on or off + /// @param flag true=on, false=off + void setBacklight(boolean flag); + + /// Set backlight brightness + /// @param brightness sets backlight brightness 0-255 + void setBacklightBrightness(uint8_t brightness); + + /// Switch display on or off + /// @param flag true=on, false=off + void setDisplay(boolean flag); + + /// Set orientation + /// @param orientation orientation, 0=portrait, 1=right rotated landscape, 2=reverse portrait, 3=left rotated landscape + void setOrientation(uint8_t orientation); + + /// Get orientation + /// @return orientation orientation, 0=portrait, 1=right rotated landscape, 2=reverse portrait, 3=left rotated landscape + uint8_t getOrientation(void); + + /// Font size, x-axis + /// @return horizontal size of current font, in pixels + // uint8_t fontX(void); + + /// Font size, y-axis + /// @return vertical size of current font, in pixels + // uint8_t fontY(void); + + /// Screen size, x-axis + /// @return horizontal size of the screen, in pixels + /// @note 240 means 240 pixels and thus 0..239 coordinates (decimal) + uint16_t maxX(void); + + /// Screen size, y-axis + /// @return vertical size of the screen, in pixels + /// @note 220 means 220 pixels and thus 0..219 coordinates (decimal) + uint16_t maxY(void); + + /// Draw circle + /// @param x0 center, point coordinate, x-axis + /// @param y0 center, point coordinate, y-axis + /// @param radius radius + /// @param color 16-bit color + void drawCircle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t color); + + /// Draw solid circle + /// @param x0 center, point coordinate, x-axis + /// @param y0 center, point coordinate, y-axis + /// @param radius radius + /// @param color 16-bit color + void fillCircle(uint8_t x0, uint8_t y0, uint8_t radius, uint16_t color); + + /// Set background color + /// @param color background color, default=black + void setBackgroundColor(uint16_t color = COLOR_BLACK); + + /// Draw line, rectangle coordinates + /// @param x1 top left coordinate, x-axis + /// @param y1 top left coordinate, y-axis + /// @param x2 bottom right coordinate, x-axis + /// @param y2 bottom right coordinate, y-axis + /// @param color 16-bit color + void drawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color); + + /// Draw rectangle, rectangle coordinates + /// @param x1 top left coordinate, x-axis + /// @param y1 top left coordinate, y-axis + /// @param x2 bottom right coordinate, x-axis + /// @param y2 bottom right coordinate, y-axis + /// @param color 16-bit color + void drawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color); + + /// Draw solid rectangle, rectangle coordinates + /// @param x1 top left coordinate, x-axis + /// @param y1 top left coordinate, y-axis + /// @param x2 bottom right coordinate, x-axis + /// @param y2 bottom right coordinate, y-axis + /// @param color 16-bit color + void fillRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color); + + /// Draw pixel + /// @param x1 point coordinate, x-axis + /// @param y1 point coordinate, y-axis + /// @param color 16-bit color + void drawPixel(uint16_t x1, uint16_t y1, uint16_t color); + + /// Draw ASCII Text (pixel coordinates) + /// @param x point coordinate, x-axis + /// @param y point coordinate, y-axis + /// @param s text string + /// @param color 16-bit color, default=white + void drawText(uint16_t x, uint16_t y, String s, uint16_t color = COLOR_WHITE); + + /// Calculate 16-bit color from 8-bit Red-Green-Blue components + /// @param red red component, 0x00..0xff + /// @param green green component, 0x00..0xff + /// @param blue blue component, 0x00..0xff + /// @return 16-bit color + uint16_t setColor(uint8_t red, uint8_t green, uint8_t blue); + + /// Calculate 8-bit Red-Green-Blue components from 16-bit color + /// @param rgb 16-bit color + /// @param red red component, 0x00..0xff + /// @param green green component, 0x00..0xff + /// @param blue blue component, 0x00..0xff + void splitColor(uint16_t rgb, uint8_t &red, uint8_t &green, uint8_t &blue); + + /// Draw triangle, triangle coordinates + /// @param x1 corner 1 coordinate, x-axis + /// @param y1 corner 1 coordinate, y-axis + /// @param x2 corner 2 coordinate, x-axis + /// @param y2 corner 2 coordinate, y-axis + /// @param x3 corner 3 coordinate, x-axis + /// @param y3 corner 3 coordinate, y-axis + /// @param color 16-bit color + void drawTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, uint16_t color); + + /// Draw solid triangle, triangle coordinates + /// @param x1 corner 1 coordinate, x-axis + /// @param y1 corner 1 coordinate, y-axis + /// @param x2 corner 2 coordinate, x-axis + /// @param y2 corner 2 coordinate, y-axis + /// @param x3 corner 3 coordinate, x-axis + /// @param y3 corner 3 coordinate, y-axis + /// @param color 16-bit color + void fillTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, uint16_t color); + + /// Set current font + /// @param font Font name + void setFont(uint8_t* font); + + /// Draw single character (pixel coordinates) + /// @param x point coordinate, x-axis + /// @param y point coordinate, y-axis + /// @param ch ASCII character + /// @param color 16-bit color, default=white + uint16_t drawChar(uint16_t x, uint16_t y, uint16_t ch, uint16_t color = COLOR_WHITE); + + /// Draw bitmap + /// @param x point coordinate, x-axis + /// @param y point coordinate, y-axis + /// @param bitmap + /// @param w width + /// @param h height + /// @param color 16-bit color, default=white + /// @param bg 16-bit color, background + void drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color); + void drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg); + void drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color); + void drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg); + + void drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color); + + void startWrite(void); + void endWrite(void); + + private: + + void _spiWrite(uint8_t v); + void _spiWriteCommand(uint8_t c); + void _spiWriteData(uint8_t d); + + void _swap(uint16_t &a, uint16_t &b); + void _setWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); + void _orientCoordinates(uint16_t &x1, uint16_t &y1); + void _writeRegister(uint16_t reg, uint16_t data); + void _writeData(uint8_t HI, uint8_t LO); + void _writeCommand(uint8_t HI, uint8_t LO); + + uint16_t _maxX, _maxY, _bgColor; + +#if defined (__AVR__) || defined(TEENSYDUINO) + int8_t _rst, _rs, _cs, _sdi, _clk, _led; + #ifdef USE_FAST_PINIO volatile uint8_t *mosiport, *clkport, *dcport, *rsport, *csport; - uint8_t _rst, _rs, _cs, _sdi, _clk, _led, - _orientation, _brightness; uint8_t mosipinmask, clkpinmask, cspinmask, dcpinmask; + #endif +#elif defined (__arm__) + int32_t _rst, _rs, _cs, _sdi, _clk, _led; + #ifdef USE_FAST_PINIO + volatile RwReg *mosiport, *clkport, *dcport, *rsport, *csport; + uint32_t mosipinmask, clkpinmask, cspinmask, dcpinmask; + #endif +#elif defined (ESP8266) || defined (ESP32) + int8_t _rst, _rs, _cs, _sdi, _clk, _led; + #ifdef USE_FAST_PINIO + volatile uint32_t *mosiport, *clkport, *dcport, *rsport, *csport; + uint32_t mosipinmask, clkpinmask, cspinmask, dcpinmask; + #endif +#else + int8_t _rst, _rs, _cs, _sdi, _clk, _led; +#endif + + uint8_t _orientation, _brightness; - boolean hwSPI, checkSPI, blState; + bool hwSPI, checkSPI, blState; - _currentFont cfont; + _currentFont cfont; +#ifdef ESP32 + SPIClass _spi; +#endif }; #endif From 518a3769e4af4fa267fd353d7ececab210eceeca Mon Sep 17 00:00:00 2001 From: Johan Cronje Date: Wed, 25 Oct 2017 12:09:12 -0700 Subject: [PATCH 2/3] Bug fixes --- src/TFT_22_ILI9225.cpp | 74 +++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 47 deletions(-) diff --git a/src/TFT_22_ILI9225.cpp b/src/TFT_22_ILI9225.cpp index 6db58cd..53dcd7d 100644 --- a/src/TFT_22_ILI9225.cpp +++ b/src/TFT_22_ILI9225.cpp @@ -144,16 +144,6 @@ TFT_22_ILI9225::TFT_22_ILI9225(int8_t rst, int8_t rs, int8_t cs, int8_t sdi, int _brightness = 255; // Set to maximum brightness hwSPI = false; checkSPI = true; -#ifdef USE_FAST_PINIO - csport = portOutputRegister(digitalPinToPort(_cs)); - cspinmask = digitalPinToBitMask(_cs); - dcport = portOutputRegister(digitalPinToPort(_rs)); - dcpinmask = digitalPinToBitMask(_rs); - clkport = portOutputRegister(digitalPinToPort(_clk)); - clkpinmask = digitalPinToBitMask(_clk); - mosiport = portOutputRegister(digitalPinToPort(_sdi)); - mosipinmask = digitalPinToBitMask(_sdi); -#endif } // Constructor when using software SPI. All output pins are configurable. Adds backlight brightness 0-255 @@ -167,16 +157,6 @@ TFT_22_ILI9225::TFT_22_ILI9225(int8_t rst, int8_t rs, int8_t cs, int8_t sdi, int _brightness = brightness; hwSPI = false; checkSPI = true; -#ifdef USE_FAST_PINIO - csport = portOutputRegister(digitalPinToPort(_cs)); - cspinmask = digitalPinToBitMask(_cs); - dcport = portOutputRegister(digitalPinToPort(_rs)); - dcpinmask = digitalPinToBitMask(_rs); - clkport = portOutputRegister(digitalPinToPort(_clk)); - clkpinmask = digitalPinToBitMask(_clk); - mosiport = portOutputRegister(digitalPinToPort(_sdi)); - mosipinmask = digitalPinToBitMask(_sdi); -#endif } // Constructor when using hardware SPI. Faster, but must use SPI pins @@ -190,16 +170,6 @@ TFT_22_ILI9225::TFT_22_ILI9225(int8_t rst, int8_t rs, int8_t cs, int8_t led) { _brightness = 255; // Set to maximum brightness hwSPI = true; checkSPI = true; -#ifdef USE_FAST_PINIO - csport = portOutputRegister(digitalPinToPort(_cs)); - cspinmask = digitalPinToBitMask(_cs); - dcport = portOutputRegister(digitalPinToPort(_rs)); - dcpinmask = digitalPinToBitMask(_rs); - clkport = 0; - clkpinmask = 0; - mosiport = 0; - mosipinmask = 0; -#endif } // Constructor when using hardware SPI. Faster, but must use SPI pins @@ -209,31 +179,21 @@ TFT_22_ILI9225::TFT_22_ILI9225(int8_t rst, int8_t rs, int8_t cs, int8_t led, uin _rst = rst; _rs = rs; _cs = cs; - _sdi = _clk = 0; + _sdi = _clk = -1; _led = led; _brightness = brightness; hwSPI = true; checkSPI = true; -#ifdef USE_FAST_PINIO - csport = portOutputRegister(digitalPinToPort(_cs)); - cspinmask = digitalPinToBitMask(_cs); - dcport = portOutputRegister(digitalPinToPort(_rs)); - dcpinmask = digitalPinToBitMask(_rs); - clkport = 0; - clkpinmask = 0; - mosiport = 0; - mosipinmask = 0; -#endif } - + #ifdef ESP32 -void TFT_22_ILI9225::begin(SPIClass &spi) {} +void TFT_22_ILI9225::begin(SPIClass &spi) _spi = spi; #else -void TFT_22_ILI9225::begin() { +void TFT_22_ILI9225::begin() #endif - +{ // Set up reset pin if (_rst > 0) { pinMode(_rst, OUTPUT); @@ -251,12 +211,32 @@ void TFT_22_ILI9225::begin() { pinMode(_cs, OUTPUT); digitalWrite(_cs, HIGH); +#ifdef USE_FAST_PINIO + csport = portOutputRegister(digitalPinToPort(_cs)); + cspinmask = digitalPinToBitMask(_cs); + dcport = portOutputRegister(digitalPinToPort(_rs)); + dcpinmask = digitalPinToBitMask(_rs); +#endif + // Software SPI if(_clk >= 0){ pinMode(_sdi, OUTPUT); digitalWrite(_sdi, LOW); pinMode(_clk, OUTPUT); digitalWrite(_clk, HIGH); +#ifdef USE_FAST_PINIO + clkport = portOutputRegister(digitalPinToPort(_clk)); + clkpinmask = digitalPinToBitMask(_clk); + mosiport = portOutputRegister(digitalPinToPort(_sdi)); + mosipinmask = digitalPinToBitMask(_sdi); + SSPI_SCK_LOW(); + SSPI_MOSI_LOW(); + } else { + clkport = 0; + clkpinmask = 0; + mosiport = 0; + mosipinmask = 0; +#endif } // Hardware SPI @@ -977,11 +957,11 @@ const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) { void TFT_22_ILI9225::startWrite(void){ SPI_BEGIN_TRANSACTION(); - // SPI_CS_LOW(); + SPI_CS_LOW(); } void TFT_22_ILI9225::endWrite(void){ - // SPI_CS_HIGH(); + SPI_CS_HIGH(); SPI_END_TRANSACTION(); } From 5b422dc326c3d3583326cdc92ec1a9623587fb82 Mon Sep 17 00:00:00 2001 From: Johan Cronje Date: Fri, 27 Oct 2017 11:45:10 -0700 Subject: [PATCH 3/3] Updated readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 51c3e9f..3078b5c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ TFT_22_ILI9225 ============== -**Version 1.2.4, released 2017-10-23, adds support for all platforms.** +**Version 1.2.6, released 2017-10-27, adds support for all platforms.** **Version 1.2.3, released 2017-10-22, adds backlight brightness control.** Credit: [miro1360](https://github.com/miro1360)