From de588aabf9959f0f0468add8f298bb36b03c5e10 Mon Sep 17 00:00:00 2001 From: sumotoy Date: Tue, 9 Jun 2015 01:24:09 +0200 Subject: [PATCH] Many changes! Works in native SPI with Teensy LC, can use alt pin on Teensy's, fixed small bugs, works with more CPU, faster with DUE. --- TFT_ILI9163C.cpp | 887 +++++++++++++++---------- TFT_ILI9163C.h | 565 ++++++++-------- _settings/TFT_ILI9163C_registers.h | 54 ++ _settings/TFT_ILI9163C_settings.h | 159 +++++ examples/graphicstest/graphicstest.ino | 128 ++-- library.properties | 2 +- 6 files changed, 1094 insertions(+), 701 deletions(-) create mode 100644 _settings/TFT_ILI9163C_registers.h create mode 100644 _settings/TFT_ILI9163C_settings.h diff --git a/TFT_ILI9163C.cpp b/TFT_ILI9163C.cpp index 0837230..325be8c 100644 --- a/TFT_ILI9163C.cpp +++ b/TFT_ILI9163C.cpp @@ -4,161 +4,278 @@ #include "wiring_private.h" #include +#if defined(SPI_HAS_TRANSACTION) + static SPISettings ILI9163C_SPI; +#endif + //constructors -TFT_ILI9163C::TFT_ILI9163C(uint8_t cspin,uint8_t dcpin,uint8_t rstpin) : Adafruit_GFX(_TFTWIDTH,_TFTHEIGHT){ - _cs = cspin; - _rs = dcpin; - _rst = rstpin; - #if defined(__MK20DX128__) || defined(__MK20DX256__) - #else - _sid = _sclk = 0; - #endif -} +#if defined(__MK20DX128__) || defined(__MK20DX256__) + TFT_ILI9163C::TFT_ILI9163C(uint8_t cspin,uint8_t dcpin,uint8_t rstpin,uint8_t mosi,uint8_t sclk) : Adafruit_GFX(_TFTWIDTH,_TFTHEIGHT) + { + _cs = cspin; + _rs = dcpin; + _rst = rstpin; + _mosi = mosi; + _sclk = sclk; + } +#elif defined(__MKL26Z64__) + TFT_ILI9163C::TFT_ILI9163C(uint8_t cspin,uint8_t dcpin,uint8_t rstpin,bool useSPI1) : Adafruit_GFX(_TFTWIDTH,_TFTHEIGHT) + { + _cs = cspin; + _rs = dcpin; + _rst = rstpin; + _useSPI1 = useSPI1; + } +#else + TFT_ILI9163C::TFT_ILI9163C(uint8_t cspin,uint8_t dcpin,uint8_t rstpin) : Adafruit_GFX(_TFTWIDTH,_TFTHEIGHT) + { + _cs = cspin; + _rs = dcpin; + _rst = rstpin; + } +#endif -TFT_ILI9163C::TFT_ILI9163C(uint8_t CS, uint8_t DC) : Adafruit_GFX(_TFTWIDTH, _TFTHEIGHT) { - _cs = CS; - _rs = DC; - _rst = 0; - #if defined(__MK20DX128__) || defined(__MK20DX256__) - #else - _sid = _sclk = 0; - #endif -} //Arduino Uno, Leonardo, Mega, Teensy 2.0, etc -#ifdef __AVR__ +#if defined(__AVR__) -inline void TFT_ILI9163C::spiwrite(uint8_t c){ - SPDR = c; - while(!(SPSR & _BV(SPIF))); -} - -void TFT_ILI9163C::writecommand(uint8_t c){ - #ifdef SPI_HAS_TRANSACTION - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); - #endif - *rsport &= ~rspinmask;//low - *csport &= ~cspinmask;//low - spiwrite(c); - *csport |= cspinmask;//hi - #ifdef SPI_HAS_TRANSACTION - SPI.endTransaction(); - #endif -} - -void TFT_ILI9163C::writedata(uint8_t c){ - #ifdef SPI_HAS_TRANSACTION - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); - #endif - *rsport |= rspinmask; - *csport &= ~cspinmask; - spiwrite(c); - *csport |= cspinmask; - #ifdef SPI_HAS_TRANSACTION - SPI.endTransaction(); - #endif -} - -void TFT_ILI9163C::writedata16(uint16_t d){ - #ifdef SPI_HAS_TRANSACTION - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); - #endif - *rsport |= rspinmask; - *csport &= ~cspinmask; - spiwrite(d >> 8); - spiwrite(d); - *csport |= cspinmask; - #ifdef SPI_HAS_TRANSACTION - SPI.endTransaction(); - #endif -} - -void TFT_ILI9163C::setBitrate(uint32_t n){ - #if !defined (SPI_HAS_TRANSACTION) - if (n >= 8000000) { - SPI.setClockDivider(SPI_CLOCK_DIV2); - } else if (n >= 4000000) { - SPI.setClockDivider(SPI_CLOCK_DIV4); - } else if (n >= 2000000) { - SPI.setClockDivider(SPI_CLOCK_DIV8); - } else { - SPI.setClockDivider(SPI_CLOCK_DIV16); + inline void TFT_ILI9163C::spiwrite(uint8_t c) + { + SPDR = c; + while(!(SPSR & _BV(SPIF))); } - #endif -} -#elif defined(__SAM3X8E__) -// Arduino Due -inline void TFT_ILI9163C::spiwrite(uint8_t c){ - SPI.transfer(c); -} - -void TFT_ILI9163C::writecommand(uint8_t c){ - #ifdef SPI_HAS_TRANSACTION - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); - #endif - rsport->PIO_CODR |= rspinmask;//LO - csport->PIO_CODR |= cspinmask;//LO - spiwrite(c); - csport->PIO_SODR |= cspinmask;//HI - #ifdef SPI_HAS_TRANSACTION - SPI.endTransaction(); - #endif -} - -void TFT_ILI9163C::writedata(uint8_t c){ - #ifdef SPI_HAS_TRANSACTION - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); - #endif - rsport->PIO_SODR |= rspinmask;//HI - csport->PIO_CODR |= cspinmask;//LO - spiwrite(c); - csport->PIO_SODR |= cspinmask;//HI - #ifdef SPI_HAS_TRANSACTION - SPI.endTransaction(); - #endif -} - -void TFT_ILI9163C::writedata16(uint16_t d){ - #ifdef SPI_HAS_TRANSACTION - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); - #endif - rsport->PIO_SODR |= rspinmask;//HI - csport->PIO_CODR |= cspinmask;//LO - spiwrite(d >> 8); - spiwrite(d); - csport->PIO_SODR |= cspinmask;//HI - #ifdef SPI_HAS_TRANSACTION - SPI.endTransaction(); - #endif -} - - -void TFT_ILI9163C::setBitrate(uint32_t n){ - #if !defined (SPI_HAS_TRANSACTION) - uint32_t divider=1; - while (divider < 255) { - if (n >= 84000000 / divider) break; - divider = divider - 1; + void TFT_ILI9163C::writecommand(uint8_t c) + { + #if defined(SPI_HAS_TRANSACTION) + SPI.beginTransaction(ILI9163C_SPI); + #endif + *rsport &= ~rspinmask;//low + *csport &= ~cspinmask;//low + spiwrite(c); + *csport |= cspinmask;//hi + #if defined(SPI_HAS_TRANSACTION) + SPI.endTransaction(); + #endif } - SPI.setClockDivider(divider); - #endif -} -#elif defined(__MK20DX128__) || defined(__MK20DX256__) -//Teensy 3.0 & 3.1 -void TFT_ILI9163C::setBitrate(uint32_t n){ - //nop -} + void TFT_ILI9163C::writedata(uint8_t c) + { + #if defined(SPI_HAS_TRANSACTION) + SPI.beginTransaction(ILI9163C_SPI); + #endif + *rsport |= rspinmask;//hi + *csport &= ~cspinmask;//low + spiwrite(c); + *csport |= cspinmask;//hi + #if defined(SPI_HAS_TRANSACTION) + SPI.endTransaction(); + #endif + } + void TFT_ILI9163C::writedata16(uint16_t d) + { + #if defined(SPI_HAS_TRANSACTION) + SPI.beginTransaction(ILI9163C_SPI); + #endif + *rsport |= rspinmask;//hi + *csport &= ~cspinmask;//low + spiwrite(d >> 8); + spiwrite(d); + *csport |= cspinmask;//hi + #if defined(SPI_HAS_TRANSACTION) + SPI.endTransaction(); + #endif + } + + void TFT_ILI9163C::setBitrate(uint32_t n) + { + #if !defined (SPI_HAS_TRANSACTION) + if (n >= 8000000) { + SPI.setClockDivider(SPI_CLOCK_DIV2); + } else if (n >= 4000000) { + SPI.setClockDivider(SPI_CLOCK_DIV4); + } else if (n >= 2000000) { + SPI.setClockDivider(SPI_CLOCK_DIV8); + } else { + SPI.setClockDivider(SPI_CLOCK_DIV16); + } + #endif + } +#elif defined(__SAM3X8E__)// Arduino Due + inline void TFT_ILI9163C::spiwrite(uint8_t c) + { + SPI.transfer(c); + } + + void TFT_ILI9163C::writecommand(uint8_t c) + { + #if defined(SPI_HAS_TRANSACTION) + SPI.beginTransaction(ILI9163C_SPI); + #endif + rsport->PIO_CODR |= rspinmask;//LO + csport->PIO_CODR |= cspinmask;//LO + spiwrite(c); + csport->PIO_SODR |= cspinmask;//HI + #if defined(SPI_HAS_TRANSACTION) + SPI.endTransaction(); + #endif + } + + void TFT_ILI9163C::writedata(uint8_t c) + { + #if defined(SPI_HAS_TRANSACTION) + SPI.beginTransaction(ILI9163C_SPI); + #endif + rsport->PIO_SODR |= rspinmask;//HI + csport->PIO_CODR |= cspinmask;//LO + spiwrite(c); + csport->PIO_SODR |= cspinmask;//HI + #if defined(SPI_HAS_TRANSACTION) + SPI.endTransaction(); + #endif + } + + void TFT_ILI9163C::writedata16(uint16_t d) + { + #if defined(SPI_HAS_TRANSACTION) + SPI.beginTransaction(ILI9163C_SPI); + #endif + rsport->PIO_SODR |= rspinmask;//HI + csport->PIO_CODR |= cspinmask;//LO + spiwrite(d >> 8); + spiwrite(d); + csport->PIO_SODR |= cspinmask;//HI + #if defined(SPI_HAS_TRANSACTION) + SPI.endTransaction(); + #endif + } + + + void TFT_ILI9163C::setBitrate(uint32_t n) + { + #if !defined(SPI_HAS_TRANSACTION) + uint32_t divider = 1; + while (divider < 255) { + if (n >= 84000000 / divider) break; + divider = divider - 1; + } + SPI.setClockDivider(divider); + #endif + } +#elif defined(__MKL26Z64__)//Teensy LC (preliminary + + void TFT_ILI9163C::writecommand(uint8_t c) + { + SPI.beginTransaction(ILI9163C_SPI); + digitalWriteFast(_rs,LOW); + digitalWriteFast(_cs,LOW); + if (_useSPI1){ + SPI1.transfer(c); + } else { + SPI.transfer(c); + } + digitalWriteFast(_cs,HIGH); + SPI.endTransaction(); + } + + void TFT_ILI9163C::writedata(uint8_t c) + { + SPI.beginTransaction(ILI9163C_SPI); + digitalWriteFast(_rs,HIGH); + digitalWriteFast(_cs,LOW); + if (_useSPI1){ + SPI1.transfer(c); + } else { + SPI.transfer(c); + } + digitalWriteFast(_cs,HIGH); + SPI.endTransaction(); + } + + void TFT_ILI9163C::writedata16(uint16_t d) + { + SPI.beginTransaction(ILI9163C_SPI); + digitalWriteFast(_rs,HIGH); + digitalWriteFast(_cs,LOW); + if (_useSPI1){ + SPI1.transfer16(d); + } else { + SPI.transfer16(d); + } + digitalWriteFast(_cs,HIGH); + SPI.endTransaction(); + } + + void TFT_ILI9163C::setBitrate(uint32_t n) + { + //nop + } +#elif defined(__MK20DX128__) || defined(__MK20DX256__)//Teensy 3.0 & 3.1 + + void TFT_ILI9163C::setBitrate(uint32_t n) + { + //nop + } +#else + + void TFT_ILI9163C::writecommand(uint8_t c) + { + #if defined(SPI_HAS_TRANSACTION) + SPI.beginTransaction(ILI9163C_SPI); + #endif + digitalWrite(_rs,LOW); + digitalWrite(_cs,LOW); + SPI.transfer(c); + digitalWrite(_cs,HIGH); + #if defined(SPI_HAS_TRANSACTION) + SPI.endTransaction(); + #endif + } + + void TFT_ILI9163C::writedata(uint8_t c) + { + #if defined(SPI_HAS_TRANSACTION) + SPI.beginTransaction(ILI9163C_SPI); + #endif + digitalWrite(_rs,HIGH); + digitalWrite(_cs,LOW); + SPI.transfer(c); + digitalWrite(_cs,HIGH); + #if defined(SPI_HAS_TRANSACTION) + SPI.endTransaction(); + #endif + } + + void TFT_ILI9163C::writedata16(uint16_t d) + { + #if defined(SPI_HAS_TRANSACTION) + SPI.beginTransaction(ILI9163C_SPI); + #endif + digitalWrite(_rs,HIGH); + digitalWrite(_cs,LOW); + SPI.transfer(d >> 8); + SPI.transfer(d); + digitalWrite(_cs,HIGH); + #if defined(SPI_HAS_TRANSACTION) + SPI.endTransaction(); + #endif + } + + void TFT_ILI9163C::setBitrate(uint32_t n) + { + //nop + } #endif //#if defined(TEENSY3.x) -void TFT_ILI9163C::begin(void) { +void TFT_ILI9163C::begin(void) +{ sleep = 0; -#ifdef __AVR__ + +#if defined(__AVR__) pinMode(_rs, OUTPUT); pinMode(_cs, OUTPUT); csport = portOutputRegister(digitalPinToPort(_cs)); @@ -166,13 +283,14 @@ void TFT_ILI9163C::begin(void) { cspinmask = digitalPinToBitMask(_cs); rspinmask = digitalPinToBitMask(_rs); SPI.begin(); - #if !defined (SPI_HAS_TRANSACTION) - SPI.setClockDivider(SPI_CLOCK_DIV2); // 8 MHz - SPI.setBitOrder(MSBFIRST); - SPI.setDataMode(SPI_MODE0); + #if !defined(SPI_HAS_TRANSACTION) + SPI.setClockDivider(SPI_CLOCK_DIV2); // 8 MHz + SPI.setBitOrder(MSBFIRST); + SPI.setDataMode(SPI_MODE0); + #else + ILI9163C_SPI = SPISettings(8000000, MSBFIRST, SPI_MODE0); #endif - // toggle RST low to reset; CS low so it'll listen to us - *csport &= ~cspinmask; + *csport &= ~cspinmask;// toggle CS low so it'll listen to us #elif defined(__SAM3X8E__) pinMode(_rs, OUTPUT); pinMode(_cs, OUTPUT); @@ -181,14 +299,34 @@ void TFT_ILI9163C::begin(void) { cspinmask = digitalPinToBitMask(_cs); rspinmask = digitalPinToBitMask(_rs); SPI.begin(); - #if !defined (SPI_HAS_TRANSACTION) - SPI.setClockDivider(11); // 8 MHz - SPI.setBitOrder(MSBFIRST); - SPI.setDataMode(SPI_MODE0); + #if !defined(SPI_HAS_TRANSACTION) + SPI.setClockDivider(5); // 8 MHz + SPI.setBitOrder(MSBFIRST); + SPI.setDataMode(SPI_MODE0); + #else + ILI9163C_SPI = SPISettings(24000000, MSBFIRST, SPI_MODE0); #endif - // toggle RST low to reset; CS low so it'll listen to us - csport ->PIO_CODR |= cspinmask; // Set control bits to LOW (idle) + csport ->PIO_CODR |= cspinmask; // toggle CS low so it'll listen to us +#elif defined(__MKL26Z64__)//Teensy LC (preliminary) + pinMode(_rs, OUTPUT); + pinMode(_cs, OUTPUT); + + if (_useSPI1){ + ILI9163C_SPI = SPISettings(12000000, MSBFIRST, SPI_MODE0); + SPI1.begin(); + } else { + ILI9163C_SPI = SPISettings(24000000, MSBFIRST, SPI_MODE0); + SPI.begin(); + } + digitalWriteFast(_cs, LOW); #elif defined(__MK20DX128__) || defined(__MK20DX256__) + ILI9163C_SPI = SPISettings(30000000, MSBFIRST, SPI_MODE0); + if ((_mosi == 11 || _mosi == 7) && (_sclk == 13 || _sclk == 14)) { + SPI.setMOSI(_mosi); + SPI.setSCK(_sclk); + } else { + return; + } SPI.begin(); if (SPI.pinIsChipSelect(_cs, _rs)) { pcs_data = SPI.setCS(_cs); @@ -198,8 +336,20 @@ void TFT_ILI9163C::begin(void) { pcs_command = 0; return; } +#else//all the rest of possible boards + pinMode(_rs, OUTPUT); + pinMode(_cs, OUTPUT); + SPI.begin(); + #if !defined(SPI_HAS_TRANSACTION) + SPI.setClockDivider(4); + SPI.setBitOrder(MSBFIRST); + SPI.setDataMode(SPI_MODE0); + #else + ILI9163C_SPI = SPISettings(8000000, MSBFIRST, SPI_MODE0); + #endif + digitalWrite(_cs, LOW); #endif - if (_rst != 0) { + if (_rst != 255) { pinMode(_rst, OUTPUT); digitalWrite(_rst, HIGH); delay(500); @@ -229,180 +379,189 @@ void TFT_ILI9163C::begin(void) { 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 //XY exchange 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 */ - _Mactrl_Data = 0b00000000; - _colorspaceData = __COLORSPC;//start with default data; - chipInit(); + _Mactrl_Data = 0b00000000; + _colorspaceData = __COLORSPC;//start with default data; + chipInit(); } void TFT_ILI9163C::chipInit() { uint8_t i; - #if defined(__GAMMASET1) - const uint8_t pGammaSet[15]= {0x36,0x29,0x12,0x22,0x1C,0x15,0x42,0xB7,0x2F,0x13,0x12,0x0A,0x11,0x0B,0x06}; - const uint8_t nGammaSet[15]= {0x09,0x16,0x2D,0x0D,0x13,0x15,0x40,0x48,0x53,0x0C,0x1D,0x25,0x2E,0x34,0x39}; - #elif defined(__GAMMASET2) - const uint8_t pGammaSet[15]= {0x3F,0x21,0x12,0x22,0x1C,0x15,0x42,0xB7,0x2F,0x13,0x02,0x0A,0x01,0x00,0x00}; - const uint8_t nGammaSet[15]= {0x09,0x18,0x2D,0x0D,0x13,0x15,0x40,0x48,0x53,0x0C,0x1D,0x25,0x2E,0x24,0x29}; - #elif defined(__GAMMASET3) - const uint8_t pGammaSet[15]= {0x3F,0x26,0x23,0x30,0x28,0x10,0x55,0xB7,0x40,0x19,0x10,0x1E,0x02,0x01,0x00}; - //&const uint8_t nGammaSet[15]= {0x00,0x19,0x1C,0x0F,0x14,0x0F,0x2A,0x48,0x3F,0x06,0x1D,0x21,0x3D,0x3F,0x3F}; - const uint8_t nGammaSet[15]= {0x09,0x18,0x2D,0x0D,0x13,0x15,0x40,0x48,0x53,0x0C,0x1D,0x25,0x2E,0x24,0x29}; - #else - const uint8_t pGammaSet[15]= {0x3F,0x25,0x1C,0x1E,0x20,0x12,0x2A,0x90,0x24,0x11,0x00,0x00,0x00,0x00,0x00}; - const uint8_t nGammaSet[15]= {0x20,0x20,0x20,0x20,0x05,0x15,0x00,0xA7,0x3D,0x18,0x25,0x2A,0x2B,0x2B,0x3A}; - #endif - #if defined(__MK20DX128__) || defined(__MK20DX256__) - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); - writecommand_cont(CMD_SWRESET);//software reset - delay(500); - writecommand_cont(CMD_SLPOUT);//exit sleep - delay(5); - writecommand_cont(CMD_PIXFMT);//Set Color Format 16bit - writedata8_cont(0x05); - delay(5); - writecommand_cont(CMD_GAMMASET);//default gamma curve 3 - writedata8_cont(0x08);//0x04 - delay(1); - writecommand_cont(CMD_GAMRSEL);//Enable Gamma adj - writedata8_cont(0x01); - delay(1); - writecommand_cont(CMD_NORML); - - - writecommand_cont(CMD_DFUNCTR); - writedata8_cont(0b11111111);// - writedata8_cont(0b00000110);// - - writecommand_cont(CMD_PGAMMAC);//Positive Gamma Correction Setting - for (i=0;i<15;i++){ - writedata8_cont(pGammaSet[i]); - } - writecommand_cont(CMD_NGAMMAC);//Negative Gamma Correction Setting - for (i=0;i<15;i++){ - writedata8_cont(nGammaSet[i]); - } - - writecommand_cont(CMD_FRMCTR1);//Frame Rate Control (In normal mode/Full colors) - writedata8_cont(0x08);//0x0C//0x08 - writedata8_cont(0x02);//0x14//0x08 - delay(1); - - writecommand_cont(CMD_DINVCTR);//display inversion - writedata8_cont(0x07); - delay(1); - - writecommand_cont(CMD_PWCTR1);//Set VRH1[4:0] & VC[2:0] for VCI1 & GVDD - writedata8_cont(0x0A);//4.30 - 0x0A - writedata8_cont(0x02);//0x05 - delay(1); - - writecommand_cont(CMD_PWCTR2);//Set BT[2:0] for AVDD & VCL & VGH & VGL - writedata8_cont(0x02); - delay(1); - - writecommand_cont(CMD_VCOMCTR1);//Set VMH[6:0] & VML[6:0] for VOMH & VCOML - writedata8_cont(0x50);//0x50 - writedata8_cont(99);//0x5b - delay(1); - - writecommand_cont(CMD_VCOMOFFS); - writedata8_cont(0);//0x40 - delay(1); - - writecommand_cont(CMD_CLMADRS);//Set Column Address - writedata16_cont(0x00); - writedata16_cont(_GRAMWIDTH); - - writecommand_cont(CMD_PGEADRS);//Set Page Address - writedata16_cont(0x00); - writedata16_cont(_GRAMHEIGH); - // set scroll area (thanks Masuda) - writecommand_cont(CMD_VSCLLDEF); - writedata16_cont(__OFFSET); - writedata16_cont(_GRAMHEIGH - __OFFSET); - writedata16_last(0); + SPI.beginTransaction(ILI9163C_SPI); - endProc(); - colorSpace(_colorspaceData); - setRotation(0); - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); - writecommand_cont(CMD_DISPON);//display ON - delay(1); - writecommand_last(CMD_RAMWR);//Memory Write - SPI.endTransaction(); - delay(1); - #else - writecommand(CMD_SWRESET);//software reset - delay(500); - writecommand(CMD_SLPOUT);//exit sleep - delay(5); - writecommand(CMD_PIXFMT);//Set Color Format 16bit - writedata(0x05); - delay(5); - writecommand(CMD_GAMMASET);//default gamma curve 3 - writedata(0x04);//0x04 - delay(1); - writecommand(CMD_GAMRSEL);//Enable Gamma adj - writedata(0x01); - delay(1); - writecommand(CMD_NORML); + writecommand_cont(CMD_SWRESET);//software reset + delay(500); + + writecommand_cont(CMD_SLPOUT);//exit sleep + delay(5); + + writecommand_cont(CMD_PIXFMT);//Set Color Format 16bit + writedata8_cont(0x05); + delay(5); + + writecommand_cont(CMD_GAMMASET);//default gamma curve 3 + writedata8_cont(0x08);//0x04 + delay(1); + + writecommand_cont(CMD_GAMRSEL);//Enable Gamma adj + writedata8_cont(0x01); + delay(1); + + writecommand_cont(CMD_NORML); - writecommand(CMD_DFUNCTR); - writedata(0b11111111);// - writedata(0b00000110);// + writecommand_cont(CMD_DFUNCTR); + writedata8_cont(0b11111111);// + writedata8_cont(0b00000110);// - writecommand(CMD_PGAMMAC);//Positive Gamma Correction Setting - for (i=0;i<15;i++){ - writedata(pGammaSet[i]); - } - writecommand(CMD_NGAMMAC);//Negative Gamma Correction Setting - for (i=0;i<15;i++){ - writedata(nGammaSet[i]); - } - - writecommand(CMD_FRMCTR1);//Frame Rate Control (In normal mode/Full colors) - writedata(0x08);//0x0C//0x08 - writedata(0x02);//0x14//0x08 - delay(1); - writecommand(CMD_DINVCTR);//display inversion - writedata(0x07); - delay(1); - writecommand(CMD_PWCTR1);//Set VRH1[4:0] & VC[2:0] for VCI1 & GVDD - writedata(0x0A);//4.30 - 0x0A - writedata(0x02);//0x05 - delay(1); - writecommand(CMD_PWCTR2);//Set BT[2:0] for AVDD & VCL & VGH & VGL - writedata(0x02); - delay(1); - writecommand(CMD_VCOMCTR1);//Set VMH[6:0] & VML[6:0] for VOMH & VCOML - writedata(0x50);//0x50 - writedata(99);//0x5b - delay(1); - writecommand(CMD_VCOMOFFS); - writedata(0);//0x40 - delay(1); + writecommand_cont(CMD_PGAMMAC);//Positive Gamma Correction Setting + for (i=0;i<15;i++){ + writedata8_cont(pGammaSet[i]); + } + + writecommand_cont(CMD_NGAMMAC);//Negative Gamma Correction Setting + for (i=0;i<15;i++){ + writedata8_cont(nGammaSet[i]); + } + + writecommand_cont(CMD_FRMCTR1);//Frame Rate Control (In normal mode/Full colors) + writedata8_cont(0x08);//0x0C//0x08 + writedata8_cont(0x02);//0x14//0x08 + delay(1); + + writecommand_cont(CMD_DINVCTR);//display inversion + writedata8_cont(0x07); + delay(1); + + writecommand_cont(CMD_PWCTR1);//Set VRH1[4:0] & VC[2:0] for VCI1 & GVDD + writedata8_cont(0x0A);//4.30 - 0x0A + writedata8_cont(0x02);//0x05 + delay(1); + + writecommand_cont(CMD_PWCTR2);//Set BT[2:0] for AVDD & VCL & VGH & VGL + writedata8_cont(0x02); + delay(1); + + writecommand_cont(CMD_VCOMCTR1);//Set VMH[6:0] & VML[6:0] for VOMH & VCOML + writedata8_cont(0x50);//0x50 + writedata8_cont(99);//0x5b + delay(1); + + writecommand_cont(CMD_VCOMOFFS); + writedata8_cont(0);//0x40 + delay(1); - writecommand(CMD_CLMADRS);//Set Column Address - writedata16(0x00); - writedata16(_GRAMWIDTH); + writecommand_cont(CMD_CLMADRS);//Set Column Address + writedata16_cont(0x00); + writedata16_cont(_GRAMWIDTH); - writecommand(CMD_PGEADRS);//Set Page Address - writedata16(0X00); - writedata16(_GRAMHEIGH); - // set scroll area (thanks Masuda) - writecommand(CMD_VSCLLDEF); - writedata16(__OFFSET); - writedata16(_GRAMHEIGH - __OFFSET); - writedata16(0); - colorSpace(_colorspaceData); - setRotation(0); - writecommand(CMD_DISPON);//display ON - delay(1); - writecommand(CMD_RAMWR);//Memory Write + writecommand_cont(CMD_PGEADRS);//Set Page Address + writedata16_cont(0x00); + writedata16_cont(_GRAMHEIGH); + // set scroll area (thanks Masuda) + writecommand_cont(CMD_VSCLLDEF); + writedata16_cont(__OFFSET); + writedata16_cont(_GRAMHEIGH - __OFFSET); + writedata16_last(0); + + SPI.endTransaction(); + + colorSpace(_colorspaceData); + + setRotation(0); + + SPI.beginTransaction(ILI9163C_SPI); + + writecommand_cont(CMD_DISPON);//display ON + delay(1); + writecommand_last(CMD_RAMWR);//Memory Write + + SPI.endTransaction(); + delay(1); + #else + writecommand(CMD_SWRESET);//software reset + delay(500); + + writecommand(CMD_SLPOUT);//exit sleep + delay(5); + + writecommand(CMD_PIXFMT);//Set Color Format 16bit + writedata(0x05); + delay(5); + + writecommand(CMD_GAMMASET);//default gamma curve 3 + writedata(0x04);//0x04 + delay(1); + + writecommand(CMD_GAMRSEL);//Enable Gamma adj + writedata(0x01); + delay(1); + + writecommand(CMD_NORML); + + writecommand(CMD_DFUNCTR); + writedata(0b11111111);// + writedata(0b00000110);// - delay(1); + writecommand(CMD_PGAMMAC);//Positive Gamma Correction Setting + for (i=0;i<15;i++){ + writedata(pGammaSet[i]); + } + + writecommand(CMD_NGAMMAC);//Negative Gamma Correction Setting + for (i=0;i<15;i++){ + writedata(nGammaSet[i]); + } + + writecommand(CMD_FRMCTR1);//Frame Rate Control (In normal mode/Full colors) + writedata(0x08);//0x0C//0x08 + writedata(0x02);//0x14//0x08 + delay(1); + + writecommand(CMD_DINVCTR);//display inversion + writedata(0x07); + delay(1); + + writecommand(CMD_PWCTR1);//Set VRH1[4:0] & VC[2:0] for VCI1 & GVDD + writedata(0x0A);//4.30 - 0x0A + writedata(0x02);//0x05 + delay(1); + + writecommand(CMD_PWCTR2);//Set BT[2:0] for AVDD & VCL & VGH & VGL + writedata(0x02); + delay(1); + + writecommand(CMD_VCOMCTR1);//Set VMH[6:0] & VML[6:0] for VOMH & VCOML + writedata(0x50);//0x50 + writedata(99);//0x5b + delay(1); + + writecommand(CMD_VCOMOFFS); + writedata(0);//0x40 + delay(1); + + writecommand(CMD_CLMADRS);//Set Column Address + writedata16(0x00); + writedata16(_GRAMWIDTH); + + writecommand(CMD_PGEADRS);//Set Page Address + writedata16(0X00); + writedata16(_GRAMHEIGH); + // set scroll area (thanks Masuda) + writecommand(CMD_VSCLLDEF); + writedata16(__OFFSET); + writedata16(_GRAMHEIGH - __OFFSET); + writedata16(0); + + colorSpace(_colorspaceData); + + setRotation(0); + writecommand(CMD_DISPON);//display ON + delay(1); + writecommand(CMD_RAMWR);//Memory Write + + delay(1); #endif fillScreen(BLACK); } @@ -422,7 +581,7 @@ void TFT_ILI9163C::colorSpace(uint8_t cspace) { void TFT_ILI9163C::invertDisplay(boolean i) { #if defined(__MK20DX128__) || defined(__MK20DX256__) - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + SPI.beginTransaction(ILI9163C_SPI); writecommand_last(i ? CMD_DINVON : CMD_DINVOF); SPI.endTransaction(); #else @@ -433,17 +592,17 @@ void TFT_ILI9163C::invertDisplay(boolean i) { void TFT_ILI9163C::display(boolean onOff) { if (onOff){ #if defined(__MK20DX128__) || defined(__MK20DX256__) - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + SPI.beginTransaction(ILI9163C_SPI); writecommand_last(CMD_DISPON); - endProc(); + SPI.endTransaction(); #else writecommand(CMD_DISPON); #endif } else { #if defined(__MK20DX128__) || defined(__MK20DX256__) - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + SPI.beginTransaction(ILI9163C_SPI); writecommand_last(CMD_DISPOFF); - endProc(); + SPI.endTransaction(); #else writecommand(CMD_DISPOFF); #endif @@ -453,17 +612,17 @@ void TFT_ILI9163C::display(boolean onOff) { void TFT_ILI9163C::idleMode(boolean onOff) { if (onOff){ #if defined(__MK20DX128__) || defined(__MK20DX256__) - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + SPI.beginTransaction(ILI9163C_SPI); writecommand_last(CMD_IDLEON); - endProc(); + SPI.endTransaction(); #else writecommand(CMD_IDLEON); #endif } else { #if defined(__MK20DX128__) || defined(__MK20DX256__) - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + SPI.beginTransaction(ILI9163C_SPI); writecommand_last(CMD_IDLEOF); - endProc(); + SPI.endTransaction(); #else writecommand(CMD_IDLEOF); #endif @@ -475,9 +634,9 @@ void TFT_ILI9163C::sleepMode(boolean mode) { if (sleep == 1) return;//already sleeping sleep = 1; #if defined(__MK20DX128__) || defined(__MK20DX256__) - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + SPI.beginTransaction(ILI9163C_SPI); writecommand_last(CMD_SLPIN); - endProc(); + SPI.endTransaction(); #else writecommand(CMD_SLPIN); #endif @@ -486,9 +645,9 @@ void TFT_ILI9163C::sleepMode(boolean mode) { if (sleep == 0) return; //Already awake sleep = 0; #if defined(__MK20DX128__) || defined(__MK20DX256__) - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + SPI.beginTransaction(ILI9163C_SPI); writecommand_last(CMD_SLPOUT); - endProc(); + SPI.endTransaction(); #else writecommand(CMD_SLPOUT); #endif @@ -501,17 +660,17 @@ void TFT_ILI9163C::defineScrollArea(uint16_t tfa, uint16_t bfa){ int16_t vsa = _GRAMHEIGH - tfa - bfa; if (vsa >= 0) { #if defined(__MK20DX128__) || defined(__MK20DX256__) - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); - writecommand_cont(CMD_VSCLLDEF); - writedata16_cont(tfa); - writedata16_cont(vsa); - writedata16_last(bfa); - endProc(); + SPI.beginTransaction(ILI9163C_SPI); + writecommand_cont(CMD_VSCLLDEF); + writedata16_cont(tfa); + writedata16_cont(vsa); + writedata16_last(bfa); + SPI.endTransaction(); #else - writecommand(CMD_VSCLLDEF); - writedata16(tfa); - writedata16(vsa); - writedata16(bfa); + writecommand(CMD_VSCLLDEF); + writedata16(tfa); + writedata16(vsa); + writedata16(bfa); #endif } } @@ -519,10 +678,10 @@ void TFT_ILI9163C::defineScrollArea(uint16_t tfa, uint16_t bfa){ void TFT_ILI9163C::scroll(uint16_t adrs) { if (adrs <= _GRAMHEIGH) { #if defined(__MK20DX128__) || defined(__MK20DX256__) - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + SPI.beginTransaction(ILI9163C_SPI); writecommand_cont(CMD_VSSTADRS); writedata16_last(adrs + __OFFSET); - endProc(); + SPI.endTransaction(); #else writecommand(CMD_VSSTADRS); writedata16(adrs + __OFFSET); @@ -535,16 +694,14 @@ void TFT_ILI9163C::scroll(uint16_t adrs) { void TFT_ILI9163C::clearScreen(uint16_t color) { int px; #if defined(__MK20DX128__) || defined(__MK20DX256__) - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); - //writecommand_cont(CMD_RAMWR); + SPI.beginTransaction(ILI9163C_SPI); _setAddrWindow(0x00,0x00,_GRAMWIDTH,_GRAMHEIGH); for (px = 0;px < _GRAMSIZE; px++){ writedata16_cont(color); } writecommand_last(CMD_NOP); - endProc(); + SPI.endTransaction(); #else - //writecommand(CMD_RAMWR); setAddr(0x00,0x00,_GRAMWIDTH,_GRAMHEIGH);//go home for (px = 0;px < _GRAMSIZE; px++){ writedata16(color); @@ -568,16 +725,16 @@ void TFT_ILI9163C::pushData(uint16_t color) { void TFT_ILI9163C::endPushData() { #if defined(__MK20DX128__) || defined(__MK20DX256__) writecommand_last(CMD_NOP); - endProc(); + SPI.endTransaction(); #endif } void TFT_ILI9163C::pushColor(uint16_t color) { #if defined(__MK20DX128__) || defined(__MK20DX256__) - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + SPI.beginTransaction(ILI9163C_SPI); writedata16_last(color); - endProc(); + SPI.endTransaction(); #else writedata16(color); #endif @@ -585,7 +742,7 @@ void TFT_ILI9163C::pushColor(uint16_t color) { void TFT_ILI9163C::writeScreen24(const uint32_t *bitmap,uint16_t size) { uint16_t color; - int px; + uint16_t px; #if defined(__MK20DX128__) || defined(__MK20DX256__) writecommand_cont(CMD_RAMWR); for (px = 0;px < size; px++){//16384 @@ -593,7 +750,7 @@ void TFT_ILI9163C::writeScreen24(const uint32_t *bitmap,uint16_t size) { writedata16_cont(color); } _setAddrWindow(0x00,0x00,_GRAMWIDTH,_GRAMHEIGH);//home - endProc(); + SPI.endTransaction(); #else writecommand(CMD_RAMWR); for (px = 0;px < size; px++){ @@ -627,7 +784,7 @@ void TFT_ILI9163C::drawPixel(int16_t x, int16_t y, uint16_t color) { setAddr(x,y,x+1,y+1); #if defined(__MK20DX128__) || defined(__MK20DX256__) writedata16_last(color); - endProc(); + SPI.endTransaction(); #else writedata16(color); #endif @@ -635,13 +792,6 @@ void TFT_ILI9163C::drawPixel(int16_t x, int16_t y, uint16_t color) { -void TFT_ILI9163C::endProc(void){ - #if defined(__MK20DX128__) || defined(__MK20DX256__) - SPI.endTransaction(); - #endif -} - - void TFT_ILI9163C::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { // Rudimentary clipping if (boundaryCheck(x,y)) return; @@ -658,7 +808,9 @@ void TFT_ILI9163C::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color writedata16(color); #endif } - endProc(); + #if defined(SPI_HAS_TRANSACTION) + SPI.endTransaction(); + #endif } bool TFT_ILI9163C::boundaryCheck(int16_t x,int16_t y){ @@ -682,7 +834,9 @@ void TFT_ILI9163C::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color writedata16(color); #endif } - endProc(); + #if defined(SPI_HAS_TRANSACTION) + SPI.endTransaction(); + #endif } void TFT_ILI9163C::fillScreen(uint16_t color) { @@ -704,10 +858,12 @@ void TFT_ILI9163C::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t #endif } #if defined(__MK20DX128__) || defined(__MK20DX256__) - writedata16_last(color); + writedata16_last(color); #endif } - endProc(); + #if defined(SPI_HAS_TRANSACTION) + SPI.endTransaction(); + #endif } #if defined(__MK20DX128__) || defined(__MK20DX256__) @@ -753,7 +909,8 @@ void TFT_ILI9163C::drawLine(int16_t x0, int16_t y0,int16_t x1, int16_t y1, uint1 ystep = -1; } - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + SPI.beginTransaction(ILI9163C_SPI); + int16_t xbegin = x0; if (steep) { for (; x0<=x1; x0++) { @@ -798,7 +955,7 @@ void TFT_ILI9163C::drawLine(int16_t x0, int16_t y0,int16_t x1, int16_t y1, uint1 } void TFT_ILI9163C::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color){ - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + SPI.beginTransaction(ILI9163C_SPI); HLine(x, y, w, color); HLine(x, y+h-1, w, color); VLine(x, y, h, color); @@ -812,7 +969,7 @@ void TFT_ILI9163C::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t void TFT_ILI9163C::setAddr(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1){ #if defined(__MK20DX128__) || defined(__MK20DX256__) - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + SPI.beginTransaction(ILI9163C_SPI); _setAddrWindow(x0,y0,x1,y1); #else setAddrWindow(x0,y0,x1,y1); @@ -821,7 +978,7 @@ void TFT_ILI9163C::setAddr(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1){ void TFT_ILI9163C::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { #if defined(__MK20DX128__) || defined(__MK20DX256__) - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + SPI.beginTransaction(ILI9163C_SPI); _setAddrWindow(x0,y0,x1,y1); SPI.endTransaction(); #else @@ -894,10 +1051,10 @@ void TFT_ILI9163C::setRotation(uint8_t m) { } colorSpace(_colorspaceData); #if defined(__MK20DX128__) || defined(__MK20DX256__) - SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + SPI.beginTransaction(ILI9163C_SPI); writecommand_cont(CMD_MADCTL); writedata8_last(_Mactrl_Data); - endProc(); + SPI.endTransaction(); #else writecommand(CMD_MADCTL); writedata(_Mactrl_Data); diff --git a/TFT_ILI9163C.h b/TFT_ILI9163C.h index e147084..ebc5b6a 100644 --- a/TFT_ILI9163C.h +++ b/TFT_ILI9163C.h @@ -80,6 +80,8 @@ 0.7: Init correction.Clear Screen fix v3 (last time?) 0.75: SPI transactions for arduino's (beta) 0.8: Compatiblke with IDE 1.0.6 (teensyduino 1.20) and IDE 1.6.x (teensyduino 1.21b) + 0.9: Many changes! Now works with more CPU's, alternative pins for Teensy and Teensy LC + Works (in standard SPI) with Teensy LC. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ BugList of the current version: @@ -105,154 +107,47 @@ Done! #ifndef _TFT_ILI9163CLIB_H_ #define _TFT_ILI9163CLIB_H_ - +//defined(__MKL26Z64__) #include "Arduino.h" #include "Print.h" #include -//DID YOU HAVE A RED PCB, BLACk PCB or WHAT DISPLAY TYPE???????????? ---> SELECT HERE <---- -#define __144_RED_PCB__//128x128 -//#define __144_BLACK_PCB__//128x128 -//#define __22_RED_PCB__//240x320 -//--------------------------------------- +#include "_settings/TFT_ILI9163C_settings.h" -#if defined(__SAM3X8E__) - #include - #define PROGMEM - #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) - #define pgm_read_word(addr) (*(const unsigned short *)(addr)) - typedef unsigned char prog_uchar; - #define SPICLOCK 8000000 -#endif -#ifdef __AVR__ - #include - #define SPICLOCK 8000000 -#endif -#if defined(__MK20DX128__) || defined(__MK20DX256__) - #define SPICLOCK 30000000 +#if !defined(_ADAFRUIT_GFX_VARIANT) + #ifdef __AVR__ + #include + #elif defined(__SAM3X8E__) + #include + #define PROGMEM + #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) + #define pgm_read_word(addr) (*(const unsigned short *)(addr)) + typedef unsigned char prog_uchar; + #endif #endif -#if defined(__144_RED_PCB__) -/* -This display: -http://www.ebay.com/itm/Replace-Nokia-5110-LCD-1-44-Red-Serial-128X128-SPI-Color-TFT-LCD-Display-Module-/271422122271 -This particular display has a design error! The controller has 3 pins to configure to constrain -the memory and resolution to a fixed dimension (in that case 128x128) but they leaved those pins -configured for 128x160 so there was several pixel memory addressing problems. -I solved by setup several parameters that dinamically fix the resolution as needed so below -the parameters for this diplay. If you have a strain or a correct display (can happen with chinese) -you can copy those parameters and create setup for different displays. -*/ - #define _TFTWIDTH 128//the REAL W resolution of the TFT - #define _TFTHEIGHT 128//the REAL H resolution of the TFT - #define _GRAMWIDTH 128 - #define _GRAMHEIGH 160//160 - #define _GRAMSIZE _GRAMWIDTH * _GRAMHEIGH//*see note 1 - #define __COLORSPC 1// 1:GBR - 0:RGB - #define __GAMMASET3 //uncomment for another gamma - #define __OFFSET 32//*see note 2 - //Tested! -#elif defined (__144_BLACK_PCB__) - #define _TFTWIDTH 128//the REAL W resolution of the TFT - #define _TFTHEIGHT 128//the REAL H resolution of the TFT - #define _GRAMWIDTH 128 - #define _GRAMHEIGH 128 - #define _GRAMSIZE _GRAMWIDTH * _GRAMHEIGH//*see note 1 - #define __COLORSPC 1// 1:GBR - 0:RGB - #define __GAMMASET1 //uncomment for another gamma - #define __OFFSET 0 - //not tested -#elif defined (__22_RED_PCB__) -/* -Like this one: -http://www.ebay.it/itm/2-2-Serial-SPI-TFT-LCD-Display-Module-240x320-Chip-ILI9340C-PCB-Adapter-SD-Card-/281304733556 -Not tested! -*/ - #define _TFTWIDTH 240//the REAL W resolution of the TFT - #define _TFTHEIGHT 320//the REAL H resolution of the TFT - #define _GRAMWIDTH 240 - #define _GRAMHEIGH 320 - #define _GRAMSIZE _GRAMWIDTH * _GRAMHEIGH - #define __COLORSPC 1// 1:GBR - 0:RGB - #define __GAMMASET1 //uncomment for another gamma - #define __OFFSET 0 -#else - #define _TFTWIDTH 128//128 - #define _TFTHEIGHT 160//160 - #define _GRAMWIDTH 128 - #define _GRAMHEIGH 160 - #define _GRAMSIZE _GRAMWIDTH * _GRAMHEIGH - #define __COLORSPC 1// 1:GBR - 0:RGB - #define __GAMMASET1 - #define __OFFSET 0 -#endif -/* - Note 1: The __144_RED_PCB__ display has hardware addressing of 128 x 160 - but the tft resolution it's 128 x 128 so the dram should be set correctly - - Note 2: This is the offset between image in RAM and TFT. In that case 160 - 128 = 32; -*/ //--------- Keep out hands from here!------------- #define BLACK 0x0000 #define WHITE 0xFFFF -//ILI9163C registers----------------------- -#define CMD_NOP 0x00//Non operation -#define CMD_SWRESET 0x01//Soft Reset -#define CMD_SLPIN 0x10//Sleep ON -#define CMD_SLPOUT 0x11//Sleep OFF -#define CMD_PTLON 0x12//Partial Mode ON -#define CMD_NORML 0x13//Normal Display ON -#define CMD_DINVOF 0x20//Display Inversion OFF -#define CMD_DINVON 0x21//Display Inversion ON -#define CMD_GAMMASET 0x26//Gamma Set (0x01[1],0x02[2],0x04[3],0x08[4]) -#define CMD_DISPOFF 0x28//Display OFF -#define CMD_DISPON 0x29//Display ON -#define CMD_IDLEON 0x39//Idle Mode ON -#define CMD_IDLEOF 0x38//Idle Mode OFF -#define CMD_CLMADRS 0x2A//Column Address Set -#define CMD_PGEADRS 0x2B//Page Address Set +#include "_settings/TFT_ILI9163C_registers.h" -#define CMD_RAMWR 0x2C//Memory Write -#define CMD_RAMRD 0x2E//Memory Read -#define CMD_CLRSPACE 0x2D//Color Space : 4K/65K/262K -#define CMD_PARTAREA 0x30//Partial Area -#define CMD_VSCLLDEF 0x33//Vertical Scroll Definition -#define CMD_TEFXLON 0x35//Tearing Effect Line ON -#define CMD_TEFXLOF 0x34//Tearing Effect Line OFF -#define CMD_MADCTL 0x36//Memory Access Control -#define CMD_VSSTADRS 0x37//Vertical Scrolling Start address -#define CMD_PIXFMT 0x3A//Interface Pixel Format -#define CMD_FRMCTR1 0xB1//Frame Rate Control (In normal mode/Full colors) -#define CMD_FRMCTR2 0xB2//Frame Rate Control(In Idle mode/8-colors) -#define CMD_FRMCTR3 0xB3//Frame Rate Control(In Partial mode/full colors) -#define CMD_DINVCTR 0xB4//Display Inversion Control -#define CMD_RGBBLK 0xB5//RGB Interface Blanking Porch setting -#define CMD_DFUNCTR 0xB6//Display Fuction set 5 -#define CMD_SDRVDIR 0xB7//Source Driver Direction Control -#define CMD_GDRVDIR 0xB8//Gate Driver Direction Control - -#define CMD_PWCTR1 0xC0//Power_Control1 -#define CMD_PWCTR2 0xC1//Power_Control2 -#define CMD_PWCTR3 0xC2//Power_Control3 -#define CMD_PWCTR4 0xC3//Power_Control4 -#define CMD_PWCTR5 0xC4//Power_Control5 -#define CMD_VCOMCTR1 0xC5//VCOM_Control 1 -#define CMD_VCOMCTR2 0xC6//VCOM_Control 2 -#define CMD_VCOMOFFS 0xC7//VCOM Offset Control -#define CMD_PGAMMAC 0xE0//Positive Gamma Correction Setting -#define CMD_NGAMMAC 0xE1//Negative Gamma Correction Setting -#define CMD_GAMRSEL 0xF2//GAM_R_SEL class TFT_ILI9163C : public Adafruit_GFX { public: - TFT_ILI9163C(uint8_t cspin,uint8_t dcpin,uint8_t rstpin); - TFT_ILI9163C(uint8_t CS, uint8_t DC);//connect rst pin to VDD + #if defined(__MK20DX128__) || defined(__MK20DX256__) + TFT_ILI9163C(uint8_t cspin,uint8_t dcpin,uint8_t rstpin=255,uint8_t mosi=11,uint8_t sclk=13); + #elif defined(__MKL26Z64__) + TFT_ILI9163C(uint8_t cspin,uint8_t dcpin,uint8_t rstpin=255,bool useSPI1=false); + #else + TFT_ILI9163C(uint8_t cspin,uint8_t dcpin,uint8_t rstpin=255); + #endif + //TFT_ILI9163C(uint8_t CS, uint8_t DC);//connect rst pin to VDD void begin(void), setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1),//graphic Addressing @@ -264,8 +159,8 @@ class TFT_ILI9163C : public Adafruit_GFX { drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color), drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color), #if defined(__MK20DX128__) || defined(__MK20DX256__)//workaround to get more speed from Teensy - drawLine(int16_t x0, int16_t y0,int16_t x1, int16_t y1, uint16_t color), - drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color), + drawLine(int16_t x0, int16_t y0,int16_t x1, int16_t y1, uint16_t color), + drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color), #endif fillRect(int16_t x, int16_t y, int16_t w, int16_t h,uint16_t color), setRotation(uint8_t r), @@ -283,162 +178,274 @@ class TFT_ILI9163C : public Adafruit_GFX { //convert 24bit color into packet 16 bit one (credits for this are all mine) inline uint16_t Color24To565(int32_t color_) { return ((((color_ >> 16) & 0xFF) / 8) << 11) | ((((color_ >> 8) & 0xFF) / 4) << 5) | (((color_) & 0xFF) / 8);} void setBitrate(uint32_t n); + protected: + volatile uint8_t _Mactrl_Data;//container for the memory access control data + uint8_t _colorspaceData; + +/* inline void startTransaction(void){ + //__attribute__((always_inline)) { + #if defined(SPI_HAS_TRANSACTION) + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + #endif + #if defined(__AVR__) + *csport &= ~cspinmask;//low + #elif defined(__SAM3X8E__) + csport->PIO_CODR |= cspinmask;//LO + #elif defined(__MK20DX128__) || defined(__MK20DX256__) + //nop + #elif defined(__MKL26Z64__) + digitalWriteFast(_cs,LOW); + #else + digitalWrite(_cs,LOW); + #endif + } */ + +/* inline void stopTransaction(void){ + //__attribute__((always_inline)) { + #if defined(__AVR__) + *csport |= cspinmask;//hi + #elif defined(__SAM3X8E__) + csport->PIO_SODR |= cspinmask;//HI + #elif defined(__MK20DX128__) || defined(__MK20DX256__) + //nop + #elif defined(__MKL26Z64__) + digitalWriteFast(_cs,HIGH); + #else + digitalWrite(_cs,HIGH); + #endif + #if defined(SPI_HAS_TRANSACTION) + SPI.endTransaction(); + #endif + } + */ + #if defined(__AVR__) + void spiwrite(uint8_t); + volatile uint8_t *dataport, *clkport, *csport, *rsport; + uint8_t _cs,_rs,_rst; + uint8_t datapinmask, clkpinmask, cspinmask, rspinmask; + #elif defined(__SAM3X8E__) + void spiwrite(uint8_t); + Pio *dataport, *clkport, *csport, *rsport; + uint8_t _cs,_rs,_rst; + uint32_t datapinmask, clkpinmask, cspinmask, rspinmask; + #elif defined(__MKL26Z64__) + uint8_t _cs,_rs,_rst; + bool _useSPI1; + #elif defined(__MK20DX128__) || defined(__MK20DX256__) + uint8_t _cs, _rs, _rst; + uint8_t pcs_data, pcs_command; + uint8_t _miso, _mosi, _sclk; + + void _setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);//graphic Addressing for Teensy + + //Here's Paul Stoffregen magic in action... + void waitFifoNotFull(void) { + uint32_t sr; + uint32_t tmp __attribute__((unused)); + do { + #if ARDUINO >= 160 + sr = KINETISK_SPI0.SR; + #else + sr = SPI0.SR; + #endif + if (sr & 0xF0) tmp = SPI0_POPR; // drain RX FIFO + } while ((sr & (15 << 12)) > (3 << 12)); + } + + void waitFifoEmpty(void) { + uint32_t sr; + uint32_t tmp __attribute__((unused)); + do { + #if ARDUINO >= 160 + sr = KINETISK_SPI0.SR; + if (sr & 0xF0) tmp = KINETISK_SPI0.POPR; // drain RX FIFO + #else + sr = SPI0.SR; + if (sr & 0xF0) tmp = SPI0_POPR; // drain RX FIFO + #endif + } while ((sr & 0xF0F0) > 0); // wait both RX & TX empty + } + + #if !defined(__FORCECOMPAT_SPI)//faster + void waitTransmitComplete(void) + __attribute__((always_inline)) { + uint32_t tmp __attribute__((unused)); + #if ARDUINO >= 160 + while (!(KINETISK_SPI0.SR & SPI_SR_TCF)) ; // wait until final output done + #else + while (!(SPI0.SR & SPI_SR_TCF)) ; // wait until final output done + #endif + tmp = SPI0_POPR; // drain the final RX FIFO word + } + #else + void waitTransmitComplete(uint32_t mcr) + __attribute__((always_inline)) { + uint32_t tmp __attribute__((unused)); + #if ARDUINO >= 160 + while (1) { + uint32_t sr = KINETISK_SPI0.SR; + if (sr & SPI_SR_EOQF) break; // wait for last transmit + if (sr & 0xF0) tmp = KINETISK_SPI0.POPR; + } + KINETISK_SPI0.SR = SPI_SR_EOQF; + SPI0_MCR = mcr; + while (KINETISK_SPI0.SR & 0xF0) { + tmp = KINETISK_SPI0.POPR; + } + #else + while (1) { + uint32_t sr = SPI0.SR; + if (sr & SPI_SR_EOQF) break; // wait for last transmit + if (sr & 0xF0) tmp = SPI0_POPR; + } + SPI0.SR = SPI_SR_EOQF; + SPI0_MCR = mcr; + while (SPI0.SR & 0xF0) { + tmp = SPI0_POPR; + } + #endif + } + #endif + + void writecommand_cont(uint8_t c) + __attribute__((always_inline)) { + #if ARDUINO >= 160 + KINETISK_SPI0.PUSHR = c | (pcs_command << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT; + #else + SPI0.PUSHR = c | (pcs_command << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT; + #endif + waitFifoNotFull(); + } + + void writedata8_cont(uint8_t c) + __attribute__((always_inline)) { + #if ARDUINO >= 160 + KINETISK_SPI0.PUSHR = c | (pcs_data << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT; + #else + SPI0.PUSHR = c | (pcs_data << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT; + #endif + waitFifoNotFull(); + } + + void writedata16_cont(uint16_t d) + __attribute__((always_inline)) { + #if ARDUINO >= 160 + KINETISK_SPI0.PUSHR = d | (pcs_data << 16) | SPI_PUSHR_CTAS(1) | SPI_PUSHR_CONT; + #else + SPI0.PUSHR = d | (pcs_data << 16) | SPI_PUSHR_CTAS(1) | SPI_PUSHR_CONT; + #endif + waitFifoNotFull(); + } + + #if !defined(__FORCECOMPAT_SPI) + void writecommand_last(uint8_t c) + __attribute__((always_inline)) { + waitFifoEmpty(); + #if ARDUINO >= 160 + KINETISK_SPI0.SR = SPI_SR_TCF; + KINETISK_SPI0.PUSHR = c | (pcs_command << 16) | SPI_PUSHR_CTAS(0); + #else + SPI0.SR = SPI_SR_TCF; + SPI0.PUSHR = c | (pcs_command << 16) | SPI_PUSHR_CTAS(0); + #endif + waitTransmitComplete(); + } + + + void writedata8_last(uint8_t c) + __attribute__((always_inline)) { + waitFifoEmpty(); + #if ARDUINO >= 160 + KINETISK_SPI0.SR = SPI_SR_TCF; + KINETISK_SPI0.PUSHR = c | (pcs_data << 16) | SPI_PUSHR_CTAS(0); + #else + SPI0.SR = SPI_SR_TCF; + SPI0.PUSHR = c | (pcs_data << 16) | SPI_PUSHR_CTAS(0); + #endif + waitTransmitComplete(); + } + + void writedata16_last(uint16_t d) + __attribute__((always_inline)) { + waitFifoEmpty(); + #if ARDUINO >= 160 + KINETISK_SPI0.SR = SPI_SR_TCF; + KINETISK_SPI0.PUSHR = d | (pcs_data << 16) | SPI_PUSHR_CTAS(1); + #else + SPI0.SR = SPI_SR_TCF; + SPI0.PUSHR = d | (pcs_data << 16) | SPI_PUSHR_CTAS(1); + #endif + waitTransmitComplete(); + } + #else + void writecommand_last(uint8_t c) + __attribute__((always_inline)) { + uint32_t mcr = SPI0_MCR; + #if ARDUINO >= 160 + KINETISK_SPI0.PUSHR = c | (pcs_command << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_EOQ; + #else + SPI0.PUSHR = c | (pcs_command << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_EOQ; + #endif + waitTransmitComplete(mcr); + } + + + void writedata8_last(uint8_t c) + __attribute__((always_inline)) { + uint32_t mcr = SPI0_MCR; + #if ARDUINO >= 160 + KINETISK_SPI0.PUSHR = c | (pcs_data << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_EOQ; + #else + SPI0.PUSHR = c | (pcs_data << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_EOQ; + #endif + waitTransmitComplete(mcr); + } + + + void writedata16_last(uint16_t d) + __attribute__((always_inline)) { + uint32_t mcr = SPI0_MCR; + #if ARDUINO >= 160 + KINETISK_SPI0.PUSHR = d | (pcs_data << 16) | SPI_PUSHR_CTAS(1) | SPI_PUSHR_EOQ; + #else + SPI0.PUSHR = d | (pcs_data << 16) | SPI_PUSHR_CTAS(1) | SPI_PUSHR_EOQ; + #endif + waitTransmitComplete(mcr); + } + #endif + void HLine(int16_t x, int16_t y, int16_t w, uint16_t color) + __attribute__((always_inline)) { + _setAddrWindow(x, y, x+w-1, y); + do { writedata16_cont(color); } while (--w > 0); + } + + void VLine(int16_t x, int16_t y, int16_t h, uint16_t color) + __attribute__((always_inline)) { + _setAddrWindow(x, y, x, y+h-1); + do { writedata16_cont(color); } while (--h > 0); + } + + void Pixel(int16_t x, int16_t y, uint16_t color) + __attribute__((always_inline)) { + _setAddrWindow(x, y, x, y); + writedata16_cont(color); + } + #else + uint8_t _cs,_rs,_rst; + #endif + + #if !defined(__MK20DX128__) && !defined(__MK20DX256__) + void writecommand(uint8_t c); + void writedata(uint8_t d); + void writedata16(uint16_t d); + #endif private: - uint8_t _Mactrl_Data;//container for the memory access control data - uint8_t _colorspaceData; void colorSpace(uint8_t cspace); void setAddr(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); - void endProc(void); uint8_t sleep; - #if defined(__MK20DX128__) || defined(__MK20DX256__) - // - #else - void writecommand(uint8_t c); - void writedata(uint8_t d); - void writedata16(uint16_t d); - #endif void chipInit(); bool boundaryCheck(int16_t x,int16_t y); void homeAddress(); - #if defined(__AVR__) - void spiwrite(uint8_t); - volatile uint8_t *dataport, *clkport, *csport, *rsport; - uint8_t _cs,_rs,_sid,_sclk,_rst; - uint8_t datapinmask, clkpinmask, cspinmask, rspinmask; - #endif // #ifdef __AVR__ - - #if defined(__SAM3X8E__) - void spiwrite(uint8_t); - Pio *dataport, *clkport, *csport, *rsport; - uint8_t _cs,_rs,_sid,_sclk,_rst; - uint32_t datapinmask, clkpinmask, cspinmask, rspinmask; - #endif // #if defined(__SAM3X8E__) - - #if defined(__MK20DX128__) || defined(__MK20DX256__) - //Here's Paul Stoffregen magic in action... - uint8_t _cs, _rs, _rst; - uint8_t pcs_data, pcs_command; - - void _setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);//graphic Addressing for Teensy - - void waitFifoNotFull(void) { - uint32_t sr; - uint32_t tmp __attribute__((unused)); - do { - #if ARDUINO >= 160 - sr = KINETISK_SPI0.SR; - #else - sr = SPI0.SR; - #endif - if (sr & 0xF0) tmp = SPI0_POPR; // drain RX FIFO - } while ((sr & (15 << 12)) > (3 << 12)); - } - - void waitFifoEmpty(void) { - uint32_t sr; - uint32_t tmp __attribute__((unused)); - do { - #if ARDUINO >= 160 - sr = KINETISK_SPI0.SR; - #else - sr = SPI0.SR; - #endif - if (sr & 0xF0) tmp = SPI0_POPR; // drain RX FIFO - } while ((sr & 0xF0F0) > 0); // wait both RX & TX empty - } - - void waitTransmitComplete(void) __attribute__((always_inline)) { - uint32_t tmp __attribute__((unused)); - #if ARDUINO >= 160 - while (!(KINETISK_SPI0.SR & SPI_SR_TCF)) ; // wait until final output done - #else - while (!(SPI0.SR & SPI_SR_TCF)) ; // wait until final output done - #endif - tmp = SPI0_POPR; // drain the final RX FIFO word - } - - void writecommand_cont(uint8_t c) __attribute__((always_inline)) { - #if ARDUINO >= 160 - KINETISK_SPI0.PUSHR = c | (pcs_command << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT; - #else - SPI0.PUSHR = c | (pcs_command << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT; - #endif - waitFifoNotFull(); - } - - void writedata8_cont(uint8_t c) __attribute__((always_inline)) { - #if ARDUINO >= 160 - KINETISK_SPI0.PUSHR = c | (pcs_data << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT; - #else - SPI0.PUSHR = c | (pcs_data << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT; - #endif - waitFifoNotFull(); - } - - void writedata16_cont(uint16_t d) __attribute__((always_inline)) { - #if ARDUINO >= 160 - KINETISK_SPI0.PUSHR = d | (pcs_data << 16) | SPI_PUSHR_CTAS(1) | SPI_PUSHR_CONT; - #else - SPI0.PUSHR = d | (pcs_data << 16) | SPI_PUSHR_CTAS(1) | SPI_PUSHR_CONT; - #endif - waitFifoNotFull(); - } - - void writecommand_last(uint8_t c) __attribute__((always_inline)) { - waitFifoEmpty(); - #if ARDUINO >= 160 - KINETISK_SPI0.SR = SPI_SR_TCF; - KINETISK_SPI0.PUSHR = c | (pcs_command << 16) | SPI_PUSHR_CTAS(0); - #else - SPI0.SR = SPI_SR_TCF; - SPI0.PUSHR = c | (pcs_command << 16) | SPI_PUSHR_CTAS(0); - #endif - waitTransmitComplete(); - } - - void writedata8_last(uint8_t c) __attribute__((always_inline)) { - waitFifoEmpty(); - #if ARDUINO >= 160 - KINETISK_SPI0.SR = SPI_SR_TCF; - KINETISK_SPI0.PUSHR = c | (pcs_data << 16) | SPI_PUSHR_CTAS(0); - #else - SPI0.SR = SPI_SR_TCF; - SPI0.PUSHR = c | (pcs_data << 16) | SPI_PUSHR_CTAS(0); - #endif - waitTransmitComplete(); - } - - void writedata16_last(uint16_t d) __attribute__((always_inline)) { - waitFifoEmpty(); - #if ARDUINO >= 160 - KINETISK_SPI0.SR = SPI_SR_TCF; - KINETISK_SPI0.PUSHR = d | (pcs_data << 16) | SPI_PUSHR_CTAS(1); - #else - SPI0.SR = SPI_SR_TCF; - SPI0.PUSHR = d | (pcs_data << 16) | SPI_PUSHR_CTAS(1); - #endif - waitTransmitComplete(); - } - - void HLine(int16_t x, int16_t y, int16_t w, uint16_t color) __attribute__((always_inline)) { - _setAddrWindow(x, y, x+w-1, y); - //writecommand_cont(CMD_RAMWR);//not needed - do { writedata16_cont(color); } while (--w > 0); - } - - void Pixel(int16_t x, int16_t y, uint16_t color) __attribute__((always_inline)) { - _setAddrWindow(x, y, x, y); - //writecommand_cont(CMD_RAMWR);//not needed - writedata16_cont(color); - } - - void VLine(int16_t x, int16_t y, int16_t h, uint16_t color) __attribute__((always_inline)) { - _setAddrWindow(x, y, x, y+h-1); - //writecommand_cont(CMD_RAMWR);//not needed - do { writedata16_cont(color); } while (--h > 0); - } - #endif - }; #endif \ No newline at end of file diff --git a/_settings/TFT_ILI9163C_registers.h b/_settings/TFT_ILI9163C_registers.h new file mode 100644 index 0000000..d31e58a --- /dev/null +++ b/_settings/TFT_ILI9163C_registers.h @@ -0,0 +1,54 @@ +#ifndef _TFT_ILI9163C_REG_H_ +#define _TFT_ILI9163C_REG_H_ + + +//ILI9163C registers----------------------- +#define CMD_NOP 0x00//Non operation +#define CMD_SWRESET 0x01//Soft Reset +#define CMD_SLPIN 0x10//Sleep ON +#define CMD_SLPOUT 0x11//Sleep OFF +#define CMD_PTLON 0x12//Partial Mode ON +#define CMD_NORML 0x13//Normal Display ON +#define CMD_DINVOF 0x20//Display Inversion OFF +#define CMD_DINVON 0x21//Display Inversion ON +#define CMD_GAMMASET 0x26//Gamma Set (0x01[1],0x02[2],0x04[3],0x08[4]) +#define CMD_DISPOFF 0x28//Display OFF +#define CMD_DISPON 0x29//Display ON +#define CMD_IDLEON 0x39//Idle Mode ON +#define CMD_IDLEOF 0x38//Idle Mode OFF +#define CMD_CLMADRS 0x2A//Column Address Set +#define CMD_PGEADRS 0x2B//Page Address Set + +#define CMD_RAMWR 0x2C//Memory Write +#define CMD_RAMRD 0x2E//Memory Read +#define CMD_CLRSPACE 0x2D//Color Space : 4K/65K/262K +#define CMD_PARTAREA 0x30//Partial Area +#define CMD_VSCLLDEF 0x33//Vertical Scroll Definition +#define CMD_TEFXLON 0x35//Tearing Effect Line ON +#define CMD_TEFXLOF 0x34//Tearing Effect Line OFF +#define CMD_MADCTL 0x36//Memory Access Control +#define CMD_VSSTADRS 0x37//Vertical Scrolling Start address +#define CMD_PIXFMT 0x3A//Interface Pixel Format +#define CMD_FRMCTR1 0xB1//Frame Rate Control (In normal mode/Full colors) +#define CMD_FRMCTR2 0xB2//Frame Rate Control(In Idle mode/8-colors) +#define CMD_FRMCTR3 0xB3//Frame Rate Control(In Partial mode/full colors) +#define CMD_DINVCTR 0xB4//Display Inversion Control +#define CMD_RGBBLK 0xB5//RGB Interface Blanking Porch setting +#define CMD_DFUNCTR 0xB6//Display Fuction set 5 +#define CMD_SDRVDIR 0xB7//Source Driver Direction Control +#define CMD_GDRVDIR 0xB8//Gate Driver Direction Control + +#define CMD_PWCTR1 0xC0//Power_Control1 +#define CMD_PWCTR2 0xC1//Power_Control2 +#define CMD_PWCTR3 0xC2//Power_Control3 +#define CMD_PWCTR4 0xC3//Power_Control4 +#define CMD_PWCTR5 0xC4//Power_Control5 +#define CMD_VCOMCTR1 0xC5//VCOM_Control 1 +#define CMD_VCOMCTR2 0xC6//VCOM_Control 2 +#define CMD_VCOMOFFS 0xC7//VCOM Offset Control +#define CMD_PGAMMAC 0xE0//Positive Gamma Correction Setting +#define CMD_NGAMMAC 0xE1//Negative Gamma Correction Setting +#define CMD_GAMRSEL 0xF2//GAM_R_SEL + + +#endif \ No newline at end of file diff --git a/_settings/TFT_ILI9163C_settings.h b/_settings/TFT_ILI9163C_settings.h new file mode 100644 index 0000000..1111999 --- /dev/null +++ b/_settings/TFT_ILI9163C_settings.h @@ -0,0 +1,159 @@ +#ifndef _TFT_ILI9163C_USETT_H_ +#define _TFT_ILI9163C_USETT_H_ + + +//DID YOU HAVE A RED PCB, BLACk PCB or WHAT DISPLAY TYPE???????????? +// ---> SELECT HERE <---- +#define __144_RED_PCB__//128x128 +//#define __144_BLACK_PCB__//128x128 +//#define __22_RED_PCB__//240x320 +//--------------------------------------- + + +#if defined(__144_RED_PCB__) +/* +This display: +http://www.ebay.com/itm/Replace-Nokia-5110-LCD-1-44-Red-Serial-128X128-SPI-Color-TFT-LCD-Display-Module-/271422122271 +This particular display has a design error! The controller has 3 pins to configure to constrain +the memory and resolution to a fixed dimension (in that case 128x128) but they leaved those pins +configured for 128x160 so there was several pixel memory addressing problems. +I solved by setup several parameters that dinamically fix the resolution as needed so below +the parameters for this diplay. If you have a strain or a correct display (can happen with chinese) +you can copy those parameters and create setup for different displays. +*/ + #define _TFTWIDTH 128//the REAL W resolution of the TFT + #define _TFTHEIGHT 128//the REAL H resolution of the TFT + #define _GRAMWIDTH 128 + #define _GRAMHEIGH 160//160 + #define _GRAMSIZE _GRAMWIDTH * _GRAMHEIGH//*see note 1 + #define __COLORSPC 1// 1:GBR - 0:RGB + #define __GAMMASET3 //uncomment for another gamma + #define __OFFSET 32//*see note 2 + //Tested! +#elif defined (__144_BLACK_PCB__) + #define _TFTWIDTH 128//the REAL W resolution of the TFT + #define _TFTHEIGHT 128//the REAL H resolution of the TFT + #define _GRAMWIDTH 128 + #define _GRAMHEIGH 128 + #define _GRAMSIZE _GRAMWIDTH * _GRAMHEIGH//*see note 1 + #define __COLORSPC 1// 1:GBR - 0:RGB + #define __GAMMASET1 //uncomment for another gamma + #define __OFFSET 0 + //not tested +#elif defined (__22_RED_PCB__) +/* +Like this one: +http://www.ebay.it/itm/2-2-Serial-SPI-TFT-LCD-Display-Module-240x320-Chip-ILI9340C-PCB-Adapter-SD-Card-/281304733556 +Not tested! +*/ + #define _TFTWIDTH 240//the REAL W resolution of the TFT + #define _TFTHEIGHT 320//the REAL H resolution of the TFT + #define _GRAMWIDTH 240 + #define _GRAMHEIGH 320 + #define _GRAMSIZE _GRAMWIDTH * _GRAMHEIGH + #define __COLORSPC 1// 1:GBR - 0:RGB + #define __GAMMASET1 //uncomment for another gamma + #define __OFFSET 0 +#else + #define _TFTWIDTH 128//128 + #define _TFTHEIGHT 160//160 + #define _GRAMWIDTH 128 + #define _GRAMHEIGH 160 + #define _GRAMSIZE _GRAMWIDTH * _GRAMHEIGH + #define __COLORSPC 1// 1:GBR - 0:RGB + #define __GAMMASET1 + #define __OFFSET 0 +#endif + + #if defined(__GAMMASET1) + const uint8_t pGammaSet[15]= {0x36,0x29,0x12,0x22,0x1C,0x15,0x42,0xB7,0x2F,0x13,0x12,0x0A,0x11,0x0B,0x06}; + const uint8_t nGammaSet[15]= {0x09,0x16,0x2D,0x0D,0x13,0x15,0x40,0x48,0x53,0x0C,0x1D,0x25,0x2E,0x34,0x39}; + #elif defined(__GAMMASET2) + const uint8_t pGammaSet[15]= {0x3F,0x21,0x12,0x22,0x1C,0x15,0x42,0xB7,0x2F,0x13,0x02,0x0A,0x01,0x00,0x00}; + const uint8_t nGammaSet[15]= {0x09,0x18,0x2D,0x0D,0x13,0x15,0x40,0x48,0x53,0x0C,0x1D,0x25,0x2E,0x24,0x29}; + #elif defined(__GAMMASET3) + const uint8_t pGammaSet[15]= {0x3F,0x26,0x23,0x30,0x28,0x10,0x55,0xB7,0x40,0x19,0x10,0x1E,0x02,0x01,0x00}; + const uint8_t nGammaSet[15]= {0x09,0x18,0x2D,0x0D,0x13,0x15,0x40,0x48,0x53,0x0C,0x1D,0x25,0x2E,0x24,0x29}; + #else + const uint8_t pGammaSet[15]= {0x3F,0x25,0x1C,0x1E,0x20,0x12,0x2A,0x90,0x24,0x11,0x00,0x00,0x00,0x00,0x00}; + const uint8_t nGammaSet[15]= {0x20,0x20,0x20,0x20,0x05,0x15,0x00,0xA7,0x3D,0x18,0x25,0x2A,0x2B,0x2B,0x3A}; + #endif +/* + Note 1: The __144_RED_PCB__ display has hardware addressing of 128 x 160 + but the tft resolution it's 128 x 128 so the dram should be set correctly + + Note 2: This is the offset between image in RAM and TFT. In that case 160 - 128 = 32; +*/ +#endif + +/* +Benchmark Time (microseconds) +Screen fill 74697 +Text 4841 +Lines 16025 +Horiz/Vert Lines 5028 +Rectangles (outline) 4181 +Rectangles (filled) 91225 +Circles (filled) 14452 +Circles (outline) 16397 +Triangles (outline) 5069 +Triangles (filled) 30715 +Rounded rects (outline) 10382 +Rounded rects (filled) 99552 +Done! + +Benchmark Time (microseconds) +Screen fill 74697 +Text 4453 +Text2 16541 +Lines 16027 +Horiz/Vert Lines 5029 +Rectangles (outline) 4185 +Rectangles (filled) 91223 +Circles (filled) 14408 +Circles (outline) 15082 +Triangles (outline) 5067 +Triangles (filled) 17439 +Rounded rects (outline) 10023 +Rounded rects (filled) 99513 +Done! + + + +Benchmark Time (microseconds) +Screen fill 277415 +Text 11618 +Text2 36043 +Lines 58163 +Horiz/Vert Lines 18655 +Rectangles (outline) 15391 +Rectangles (filled) 338450 +Circles (filled) 53050 +Circles (outline) 39227 +Triangles (outline) 18302 +Triangles (filled) 64198 +Rounded rects (outline) 29676 +Rounded rects (filled) 368960 +Done! + + + +Benchmark Time (microseconds) +Screen fill 277422 +Text 13066 +Lines 58240 +Horiz/Vert Lines 18655 +Rectangles (outline) 15422 +Rectangles (filled) 339230 +Circles (filled) 53049 +Circles (outline) 43195 +Triangles (outline) 18350 +Triangles (filled) 113536 +Rounded rects (outline) 31470 +Rounded rects (filled) 369703 +Done! + + + + +*/ \ No newline at end of file diff --git a/examples/graphicstest/graphicstest.ino b/examples/graphicstest/graphicstest.ino index e5332be..5919520 100644 --- a/examples/graphicstest/graphicstest.ino +++ b/examples/graphicstest/graphicstest.ino @@ -16,7 +16,7 @@ #define GREEN 0x07E0 #define CYAN 0x07FF #define MAGENTA 0xF81F -#define YELLOW 0xFFE0 +#define YELLOW 0xFFE0 #define WHITE 0xFFFF /* @@ -33,15 +33,17 @@ You are using 4 wire SPI here, so: Teensy 3.x can use: 2,6,9,10,15,20,21,22,23 Arduino's 8 bit: any DUE: check arduino site -If you do not use reset, tie it to +3V3 +IMPORTANT!!! +If you do not use reset pin, tie it to +3V3!! Do not leave floating! */ TFT_ILI9163C tft = TFT_ILI9163C(__CS, __DC); void setup() { - Serial.begin(9600); - //while (!Serial); + Serial.begin(38400); + long unsigned debug_start = millis (); + while (!Serial && ((millis () - debug_start) <= 5000)) ; tft.begin(); Serial.println(F("Benchmark Time (microseconds)")); @@ -52,6 +54,10 @@ void setup() { Serial.print(F("Text ")); Serial.println(testText()); delay(3000); + + Serial.print(F("Text2 ")); + Serial.println(testText2()); + delay(3000); Serial.print(F("Lines ")); Serial.println(testLines(CYAN)); @@ -66,14 +72,14 @@ void setup() { delay(500); Serial.print(F("Rectangles (filled) ")); - Serial.println(testFilledRects(YELLOW,MAGENTA)); + Serial.println(testFilledRects(YELLOW, MAGENTA)); delay(500); Serial.print(F("Circles (filled) ")); - Serial.println(testFilledCircles(10,MAGENTA)); + Serial.println(testFilledCircles(10, MAGENTA)); Serial.print(F("Circles (outline) ")); - Serial.println(testCircles(10,WHITE)); + Serial.println(testCircles(10, WHITE)); delay(500); Serial.print(F("Triangles (outline) ")); @@ -96,7 +102,7 @@ void setup() { } void loop(void) { - for(uint8_t rotation=0; rotation<4; rotation++) { + for (uint8_t rotation = 0; rotation < 4; rotation++) { tft.setRotation(rotation); testText(); delay(2000); @@ -118,19 +124,29 @@ unsigned long testText() { tft.fillScreen(); unsigned long start = micros(); tft.setCursor(0, 0); - tft.setTextColor(WHITE); + tft.setTextColor(WHITE); tft.setTextSize(1); tft.println("Hello World!"); - tft.setTextColor(YELLOW); + tft.setTextColor(YELLOW); tft.setTextSize(2); tft.println(1234.56); - tft.setTextColor(RED); + tft.setTextColor(RED); tft.setTextSize(3); tft.println(0xDEAD, HEX); tft.println(); tft.setTextColor(GREEN); tft.setTextSize(4); tft.println("Hello"); + return micros() - start; + + +} + +unsigned long testText2() { + tft.fillScreen(); + unsigned long start = micros(); + tft.setCursor(0, 0); + tft.setTextColor(WHITE); tft.setTextSize(2); tft.println("I implore thee,"); tft.setTextSize(1); @@ -147,17 +163,17 @@ unsigned long testText() { unsigned long testLines(uint16_t color) { unsigned long start, t; int x1, y1, x2, y2, - w = tft.width(), - h = tft.height(); + w = tft.width(), + h = tft.height(); tft.fillScreen(); x1 = y1 = 0; y2 = h - 1; start = micros(); - for(x2=0; x20; i-=6) { + for (i = n; i > 0; i -= 6) { i2 = i / 2; start = micros(); - tft.fillRect(cx-i2, cy-i2, i, i, color1); + tft.fillRect(cx - i2, cy - i2, i, i, color1); t += micros() - start; // Outlines are not included in timing results - tft.drawRect(cx-i2, cy-i2, i, i, color2); + tft.drawRect(cx - i2, cy - i2, i, i, color2); } return t; @@ -250,8 +266,8 @@ unsigned long testFilledCircles(uint8_t radius, uint16_t color) { tft.fillScreen(); start = micros(); - for(x=radius; x10; i-=5) { + for (i = min(cx, cy); i > 10; i -= 5) { start = micros(); tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i, - tft.Color565(0, i, i)); + tft.Color565(0, i, i)); t += micros() - start; tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i, - tft.Color565(i, i, 0)); + tft.Color565(i, i, 0)); } return t; @@ -318,15 +334,15 @@ unsigned long testFilledTriangles() { unsigned long testRoundRects() { unsigned long start; int w, i, i2, - cx = (tft.width() / 2) - 1, - cy = (tft.height() / 2) - 1; + cx = (tft.width() / 2) - 1, + cy = (tft.height() / 2) - 1; tft.fillScreen(); w = min(tft.width(), tft.height()); start = micros(); - for(i=0; i20; i-=6) { + for (i = min(tft.width(), tft.height()); i > 20; i -= 6) { i2 = i / 2; - tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.Color565(0, i, 0)); + tft.fillRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.Color565(0, i, 0)); } return micros() - start; diff --git a/library.properties b/library.properties index 0cf15bf..0947fba 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=TFT_ILI9163C -version=0.8 +version=0.9 author=Max MC Costa maintainer=sumotoy sentence=A fast SPI driver for TFT drived by ILI9163C, fully SPI Transaction compatible and very fast with Teensy 3