From 66066188714f4f09a0a886b6006af1dfa0be463d Mon Sep 17 00:00:00 2001 From: sumotoy Date: Thu, 22 May 2014 22:00:08 +0200 Subject: [PATCH] first alpha version, still NOT 100% working --- TFT_ILI9163C.cpp | 461 +++++++++++++++++++++++++ TFT_ILI9163C.h | 248 +++++++++++++ examples/cube/cube.ino | 85 +++++ examples/graphicstest/graphicstest.ino | 336 ++++++++++++++++++ examples/minimal/minimal.ino | 21 ++ examples/test/test.ino | 94 +++++ keywords.txt | 9 + 7 files changed, 1254 insertions(+) create mode 100644 TFT_ILI9163C.cpp create mode 100644 TFT_ILI9163C.h create mode 100644 examples/cube/cube.ino create mode 100644 examples/graphicstest/graphicstest.ino create mode 100644 examples/minimal/minimal.ino create mode 100644 examples/test/test.ino create mode 100644 keywords.txt diff --git a/TFT_ILI9163C.cpp b/TFT_ILI9163C.cpp new file mode 100644 index 0000000..edb4032 --- /dev/null +++ b/TFT_ILI9163C.cpp @@ -0,0 +1,461 @@ +#include "TFT_ILI9163C.h" +#include +#include "pins_arduino.h" +#include "wiring_private.h" +#include + + +TFT_ILI9163C::TFT_ILI9163C(uint8_t cspin,uint8_t dcpin,uint8_t rstpin) : Adafruit_GFX(_TFTWIDTH,_TFTHEIGHT){ + _cs = cspin; + _rs = dcpin; + _rst = rstpin; + _sid = _sclk = 0; +} + +//constructor + +/* +TFT_ILI9163C::TFT_ILI9163C(uint8_t CS, uint8_t DC) : Adafruit_GFX(_TFTWIDTH, _TFTHEIGHT) { + _cs = CS; + _rs = DC; + _rst = 0; + _mosi = _sclk = 0; +} +*/ + +//Arduino Uno, Leonardo, Mega, Teensy 2.0, etc +#ifdef __AVR__ + +inline void TFT_ILI9163C::spiwrite(uint8_t c){ + SPDR = c; + while(!(SPSR & _BV(SPIF))); +} + +void TFT_ILI9163C::writecommand(uint8_t c){ + *rsport &= ~rspinmask;//low + *csport &= ~cspinmask;//low + spiwrite(c); + *csport |= cspinmask;//hi +} + +void TFT_ILI9163C::writedata(uint8_t c){ + *rsport |= rspinmask; + *csport &= ~cspinmask; + spiwrite(c); + *csport |= cspinmask; +} + +void TFT_ILI9163C::writedata16(uint16_t d){ + *rsport |= rspinmask; + *csport &= ~cspinmask; + spiwrite(d >> 8); + spiwrite(d); + *csport |= cspinmask; +} + +void TFT_ILI9163C::setBitrate(uint32_t n){ + 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); + } +} +#elif defined(__SAM3X8E__) +// Arduino Due + +inline void TFT_ILI9163C::spiwrite(uint8_t c){ + SPI.transfer(c); +} + +void TFT_ILI9163C::writecommand(uint8_t c){ + rsport->PIO_CODR |= rspinmask;//LO + csport->PIO_CODR |= cspinmask;//LO + spiwrite(c); + csport->PIO_SODR |= cspinmask;//HI +} + +void TFT_ILI9163C::writedata(uint8_t c){ + rsport->PIO_SODR |= rspinmask;//HI + csport->PIO_CODR |= cspinmask;//LO + spiwrite(c); + csport->PIO_SODR |= cspinmask;//HI +} + +void TFT_ILI9163C::writedata16(uint16_t d){ + rsport->PIO_SODR |= rspinmask;//HI + csport->PIO_CODR |= cspinmask;//LO + spiwrite(d >> 8); + spiwrite(d); + csport->PIO_SODR |= cspinmask;//HI +} + + +void TFT_ILI9163C::setBitrate(uint32_t n){ + uint32_t divider=1; + while (divider < 255) { + if (n >= 84000000 / divider) break; + divider = divider - 1; + } + SPI.setClockDivider(divider); +} +#elif defined(__MK20DX128__) || defined(__MK20DX256__) +//Teensy 3.0 & 3.1 + + inline void TFT_ILI9163C::spiwrite(uint8_t c){ + + } + +void TFT_ILI9163C::writecommand(uint8_t c){ + + #if defined(__DMASPI) + SPI0.PUSHR = c | (pcs_command << 16) | SPI_PUSHR_CTAS(0); + while (((SPI0.SR) & (15 << 12)) > (3 << 12)) ; // wait if FIFO full + #else + + #endif +} + +void TFT_ILI9163C::writedata(uint8_t c){ + #if defined(__DMASPI) + SPI0.PUSHR = c | (pcs_data << 16) | SPI_PUSHR_CTAS(0); + while (((SPI0.SR) & (15 << 12)) > (3 << 12)) ; // wait if FIFO full + #else + + #endif +} + +void TFT_ILI9163C::writedata16(uint16_t d){ + #if defined(__DMASPI) + SPI0.PUSHR = d | (pcs_data << 16) | SPI_PUSHR_CTAS(1); + while (((SPI0.SR) & (15 << 12)) > (3 << 12)) ; // wait if FIFO full + #else + + #endif + +} + +static bool spi_pin_is_cs(uint8_t pin){ + if (pin == 2 || pin == 6 || pin == 9) return true; + if (pin == 10 || pin == 15) return true; + if (pin >= 20 && pin <= 23) return true; + return false; +} + +static uint8_t spi_configure_cs_pin(uint8_t pin){ + switch (pin) { + case 10: CORE_PIN10_CONFIG = PORT_PCR_MUX(2); return 0x01; // PTC4 + case 2: CORE_PIN2_CONFIG = PORT_PCR_MUX(2); return 0x01; // PTD0 + case 9: CORE_PIN9_CONFIG = PORT_PCR_MUX(2); return 0x02; // PTC3 + case 6: CORE_PIN6_CONFIG = PORT_PCR_MUX(2); return 0x02; // PTD4 + case 20: CORE_PIN20_CONFIG = PORT_PCR_MUX(2); return 0x04; // PTD5 + case 23: CORE_PIN23_CONFIG = PORT_PCR_MUX(2); return 0x04; // PTC2 + case 21: CORE_PIN21_CONFIG = PORT_PCR_MUX(2); return 0x08; // PTD6 + case 22: CORE_PIN22_CONFIG = PORT_PCR_MUX(2); return 0x08; // PTC1 + case 15: CORE_PIN15_CONFIG = PORT_PCR_MUX(2); return 0x10; // PTC0 + } + return 0; +} + +void TFT_ILI9163C::setBitrate(uint32_t n){ + if (n >= 24000000) { + ctar = CTAR_24MHz; + } else if (n >= 16000000) { + ctar = CTAR_16MHz; + } else if (n >= 12000000) { + ctar = CTAR_12MHz; + } else if (n >= 8000000) { + ctar = CTAR_8MHz; + } else if (n >= 6000000) { + ctar = CTAR_6MHz; + } else { + ctar = CTAR_4MHz; + } + SIM_SCGC6 |= SIM_SCGC6_SPI0; + SPI0.MCR = SPI_MCR_MDIS | SPI_MCR_HALT; + SPI0.CTAR0 = ctar | SPI_CTAR_FMSZ(7); + SPI0.CTAR1 = ctar | SPI_CTAR_FMSZ(15); + SPI0.MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F) | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF; +} +#endif //#if defined(TEENSY3.x) + + +void TFT_ILI9163C::begin(void) { +#ifdef __AVR__ + pinMode(_rs, OUTPUT); + pinMode(_cs, OUTPUT); + csport = portOutputRegister(digitalPinToPort(_cs)); + rsport = portOutputRegister(digitalPinToPort(_rs)); + cspinmask = digitalPinToBitMask(_cs); + rspinmask = digitalPinToBitMask(_rs); + SPI.begin(); + SPI.setClockDivider(SPI_CLOCK_DIV4); // 4 MHz (half speed) + //Due defaults to 4mHz (clock divider setting of 21) + SPI.setBitOrder(MSBFIRST); + SPI.setDataMode(SPI_MODE0); + // toggle RST low to reset; CS low so it'll listen to us + *csport &= ~cspinmask; +#elif defined(__SAM3X8E__) + pinMode(_rs, OUTPUT); + pinMode(_cs, OUTPUT); + csport = digitalPinToPort(_cs); + rsport = digitalPinToPort(_rs); + cspinmask = digitalPinToBitMask(_cs); + rspinmask = digitalPinToBitMask(_rs); + SPI.begin(); + SPI.setClockDivider(21); // 4 MHz + //Due defaults to 4mHz (clock divider setting of 21), but we'll set it anyway + SPI.setBitOrder(MSBFIRST); + SPI.setDataMode(SPI_MODE0); + // toggle RST low to reset; CS low so it'll listen to us + csport ->PIO_CODR |= cspinmask; // Set control bits to LOW (idle) +#elif defined(__MK20DX128__) || defined(__MK20DX256__) + _sid = 11; + _sclk = 13; + if (spi_pin_is_cs(_cs) && spi_pin_is_cs(_rs) + && (_sid == 7 || _sid == 11) + && (_sclk == 13 || _sclk == 14) + && !(_cs == 2 && _rs == 10) && !(_rs == 2 && _cs == 10) + && !(_cs == 6 && _rs == 9) && !(_rs == 6 && _cs == 9) + && !(_cs == 20 && _rs == 23) && !(_rs == 20 && _cs == 23) + && !(_cs == 21 && _rs == 22) && !(_rs == 21 && _cs == 22)) { + if (_sclk == 13) { + CORE_PIN13_CONFIG = PORT_PCR_MUX(2) | PORT_PCR_DSE; + SPCR.setSCK(13); + } else { + CORE_PIN14_CONFIG = PORT_PCR_MUX(2); + SPCR.setSCK(14); + } + if (_sid == 11) { + CORE_PIN11_CONFIG = PORT_PCR_MUX(2); + SPCR.setMOSI(11); + } else { + CORE_PIN7_CONFIG = PORT_PCR_MUX(2); + SPCR.setMOSI(7); + } + ctar = CTAR_12MHz; + pcs_data = spi_configure_cs_pin(_cs); + pcs_command = pcs_data | spi_configure_cs_pin(_rs); + SIM_SCGC6 |= SIM_SCGC6_SPI0; + SPI0.MCR = SPI_MCR_MDIS | SPI_MCR_HALT; + SPI0.CTAR0 = ctar | SPI_CTAR_FMSZ(7); + SPI0.CTAR1 = ctar | SPI_CTAR_FMSZ(15); + SPI0.MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F) | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF; + } else { + //error + } +#endif + if (_rst != 0) { + pinMode(_rst, OUTPUT); + digitalWrite(_rst, HIGH); + delay(500); + digitalWrite(_rst, LOW); + delay(500); + digitalWrite(_rst, HIGH); + delay(500); + } + chipInit(); +} + + + +void TFT_ILI9163C::chipInit() { + writecommand(CMD_SWRESET);//software reset + delay(500); + writecommand(CMD_SLPOUT);//exit sleep + delay(50); + writecommand(CMD_PIXFMT);//Set Color Format + writedata(0x05); + delay(50); + writecommand(CMD_GAMMASET);//default gamma + writedata(0x04); + delay(10); + writecommand(CMD_DINVOF);//display inversion OFF + //writecommand(0xF2);//E0h & E1h Enable/Disable + //writedata(0x00); + writecommand(CMD_FRMCTR1);//Frame Rate Control (In normal mode/Full colors) + writedata(0x0C); + writedata(0x14); + delay(10); + writecommand(CMD_PWCTR1);//Set VRH1[4:0] & VC[2:0] for VCI1 & GVDD + writedata(0x0C); + writedata(0x05); + delay(10); + writecommand(CMD_PWCTR2);//Set BT[2:0] for AVDD & VCL & VGH & VGL + writedata(0x02); + delay(10); + writecommand(CMD_VCOMCTR1);//Set VMH[6:0] & VML[6:0] for VOMH & VCOML + writedata(0x29); + writedata(0x43); + writedata(0xC7); + writedata(0x40); + delay(10); + + writecommand(CMD_CLMADRS);//Set Column Address + writedata(0x00); + writedata(0X00); + writedata(0X00); + writedata(0X7F); + + writecommand(CMD_PGEADRS);//Set Page Address + writedata(0x00); + writedata(0X00); + writedata(0X00); + writedata(0X7F); + + writecommand(CMD_MADCTL);//Set Scanning Direction + writedata(0x08); //0C + + writecommand(CMD_SDRVDIR);//Set Source Output Direction + writedata(0x00); + + writecommand(CMD_GAMRSEL);//Enable Gamma bit + writedata(0x01); + + writecommand(CMD_PGAMMAC);//Positive Gamma Correction Setting + writedata(0x36);//p1 + writedata(0x29);//p2 + writedata(0x12);//p3 + writedata(0x22);//p4 + writedata(0x1C);//p5 + writedata(0x15);//p6 + writedata(0x42);//p7 + writedata(0xB7);//p8 + writedata(0x2F);//p9 + writedata(0x13);//p10 + writedata(0x12);//p11 + writedata(0x0A);//p12 + writedata(0x11);//p13 + writedata(0x0B);//p14 + writedata(0x06);//p15 + + writecommand(CMD_NGAMMAC);//Negative Gamma Correction Setting + writedata(0x09);//p1 + writedata(0x16);//p2 + writedata(0x2D);//p3 + writedata(0x0D);//p4 + writedata(0x13);//p5 + writedata(0x15);//p6 + writedata(0x40);//p7 + writedata(0x48);//p8 + writedata(0x53);//p9 + writedata(0x0C);//p10 + writedata(0x1D);//p11 + writedata(0x25);//p12 + writedata(0x2E);//p13 + writedata(0x34);//p14 + writedata(0x39);//p15 + + writecommand(CMD_DISPON);//display ON + writecommand(CMD_RAMWR);//Memory Write +} + +void TFT_ILI9163C::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { + writecommand(CMD_CLMADRS); // Column + writedata16(x0); + writedata16(x1); + + writecommand(CMD_PGEADRS); // Page + writedata16(y0); + writedata16(y1); + + writecommand(CMD_RAMWR); //Into RAM +} + + +void TFT_ILI9163C::pushColor(uint16_t color) { + writedata16(color); +} + +void TFT_ILI9163C::drawPixel(int16_t x, int16_t y, uint16_t color) { + if (boundaryCheck(x,y)) return; + if ((x < 0) || (y < 0)) return; + setAddrWindow(x,y,x+1,y+1); + writedata16(color); +} + + +void TFT_ILI9163C::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { + // Rudimentary clipping + if (boundaryCheck(x,y)) return; + if ((y+h-1) >= _height) h = _height-y; + setAddrWindow(x, y, x, y+h-1); + while (h--) { + writedata16(color); + } +} + +bool TFT_ILI9163C::boundaryCheck(int16_t x,int16_t y){ + if ((x >= _width) || (y >= _height)) return true; + return false; +} + +void TFT_ILI9163C::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { + // Rudimentary clipping + if (boundaryCheck(x,y)) return; + if ((x+w-1) >= _width) w = _width-x; + setAddrWindow(x, y, x+w-1, y); + while (w--) { + writedata16(color); + } +} + +void TFT_ILI9163C::fillScreen(uint16_t color) { + fillRect(0, 0, _width, _height, color); +} + +// fill a rectangle +void TFT_ILI9163C::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) { + if (boundaryCheck(x,y)) return; + if ((x + w - 1) >= _width) w = _width - x; + if ((y + h - 1) >= _height) h = _height - y; + setAddrWindow(x, y, x+w-1, y+h-1); + + for (y=h; y>0; y--) { + for (x=w; x>0; x--) { + writedata16(color); + } + } +} + + +// Pass 8-bit (each) R,G,B, get back 16-bit packed color +uint16_t TFT_ILI9163C::Color565(uint8_t r, uint8_t g, uint8_t b) { + return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); +} + + +void TFT_ILI9163C::setRotation(uint8_t m) { + writecommand(CMD_MADCTL); + rotation = m % 4; // can't be higher than 3 + switch (rotation) { + case 0: + writedata(DTA_MADCTL_MX | DTA_MADCTL_BGR); + _width = _TFTWIDTH; + _height = _TFTHEIGHT; + break; + case 1: + writedata(DTA_MADCTL_MV | DTA_MADCTL_BGR); + _width = _TFTHEIGHT; + _height = _TFTWIDTH; + break; + case 2: + writedata(DTA_MADCTL_MY | DTA_MADCTL_BGR); + _width = _TFTWIDTH; + _height = _TFTHEIGHT; + break; + case 3: + writedata(DTA_MADCTL_MV | DTA_MADCTL_MY | DTA_MADCTL_MX | DTA_MADCTL_BGR); + _width = _TFTHEIGHT; + _height = _TFTWIDTH; + break; + } +} + + +void TFT_ILI9163C::invertDisplay(boolean i) { + writecommand(i ? CMD_DINVON : CMD_DINVOF); +} diff --git a/TFT_ILI9163C.h b/TFT_ILI9163C.h new file mode 100644 index 0000000..5cbccb2 --- /dev/null +++ b/TFT_ILI9163C.h @@ -0,0 +1,248 @@ +/* + ILI9163C - A fast SPI driver for TFT that use Ilitek ILI9163C. + + Features: + - Very FAST!, expecially with Teensy 3.x where uses DMA SPI. + - It uses just 4 or 5 wires. + - Compatible at command level with Adafruit display series so it's easy to adapt existing code. + - It uses the standard Adafruit_GFX Library (you need to install). + + Background: + I got one of those displays from a chinese ebay seller but unfortunatly I cannot get + any working library so I decided to hack it. ILI9163C looks pretty similar to other + display driver but it uses it's own commands so it's tricky to work with it unlsess you + carefully fight with his gigantic and not so clever datasheet. + My display it's a 1.44"", 128x128 that suppose to substitute Nokia 5110 LCD and here's the + first confusion! Many sellers claim that it's compatible with Nokia 5110 (that use a philips + controller) but the only similarity it's the pin names since that this one it's color and + have totally different controller that's not compatible. + http://www.ebay.com/itm/Replace-Nokia-5110-LCD-1-44-Red-Serial-128X128-SPI-Color-TFT-LCD-Display-Module-/141196897388 + http://www.elecrow.com/144-128x-128-tft-lcd-with-spi-interface-p-855.html + Pay attention that ILI9163C can drive different resolutions and your display can be + 160*128 or whatever, also there's a strain of this display with a black PCB that a friend of mine + got some weeks ago and need some small changes in library to get working. + If you look at TFT_ILI9163C.h file you can add your modifications and let me know so I + can include for future versions. + + Code Optimizations: + The purpose of this library it's SPEED. I have tried to use hardware optimized calls + where was possible and results are quite good for most applications, actually nly filled circles + are still a bit slow. Many SPI call has been optimized by reduce un-needed triggers to RS and CS + lines. Of course it can be improved so feel free to add suggestions. + ------------------------------------------------------------------------------- + Copyright (c) 2014, .S.U.M.O.T.O.Y., coded by Max MC Costa. + + TFT_ILI9163C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TFT_ILI9163C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Foobar. If not, see . + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + This file needs the following Libraries: + + Adafruit_GFX by Adafruit: + https://github.com/adafruit/Adafruit-GFX-Library + Remember to update GFX library often to have more features with this library! + From this version I'm using my version of Adafruit_GFX library: + https://github.com/sumotoy/Adafruit-GFX-Library + It has faster char rendering and some small little optimizations but you can + choose one of the two freely since are both fully compatible. + '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + Special Thanks: + Thanks Adafruit for his Adafruit_GFX! + Thanks to Paul Stoffregen for his beautiful Teensy3 and DMA SPI. + + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Version: + 0.1a1: First release, compile correctly. Altrough not fully working! + + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + BugList of the current version: + + - This is an Alpha version and finally TFT reacts to code but I still have some + issue to fix so if you want to download remember that pixel addressing it's still + not complete and display rotation have several issues. + Actually no scroll commands (only in release will be included). +*/ +#ifndef _TFT_ILI9163CLIB_H_ +#define _TFT_ILI9163CLIB_H_ + +#if ARDUINO >= 100 + #include "Arduino.h" + #include "Print.h" +#else + #include "WProgram.h" +#endif + +#include + +//----- Define here witch display you own +#define __144_RED_PCB__//128x128 +//--------------------------------------- + +#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; +#endif +#ifdef __AVR__ + #include +#endif +#if defined(__MK20DX128__) || defined(__MK20DX256__) + #include "mk20dx128.h" + #include "core_pins.h" + #define __DMASPI + + #define CTAR_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0) | SPI_CTAR_DBR) + #define CTAR_16MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0) | SPI_CTAR_DBR) + #define CTAR_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0)) + #define CTAR_8MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0)) + #define CTAR_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1)) + #define CTAR_4MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1)) +#endif + +//ILI9163C versions------------------------ +#if defined(__144_RED_PCB__) + #define _TFTWIDTH 128//240 + #define _TFTHEIGHT 128//320 +#else + #define _TFTWIDTH 128//240 + #define _TFTHEIGHT 128//320 +#endif + +//ILI9163C registers----------------------- +#define CMD_NOP 0x00//Non operation +#define CMD_SWRESET 0x01//Soft Reset +#define CMD_RDDID 0x04//Read Display Identification Information +#define CMD_RDDST 0x09//Read Display Status +#define CMD_RDMODE 0x0A//Read Display power mode +#define CMD_RDMADCTL 0x0B//Read Display MADCTL +#define CMD_RDPIXFMT 0x0C//Read Display Pixel Format +#define CMD_RDIMMDE 0x0D//Read Display Image Mode +#define CMD_RDSNMDE 0x0E//Read Display Signal Mode +//#define CMD_RDSNMDE 0x0F//Read Display Signal Mode + +#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 +#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 0x34//Tearing Effect Line ON +#define CMD_TEFXLOF 0x35//Tearing Effect Line OFF +#define CMD_MADCTL 0x36//Memory Access Control + +#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_VCOMOFFS 0xC7//VCOM Offset Control + +#define CMD_WRID4VL 0xD3//Write ID4 Value + +#define CMD_NVMEMFC1 0xD5//NV Memory Function Controller(1) +#define CMD_NVMEMFC2 0xD6//NV Memory Function Controller(1) +#define CMD_NVMEMFC3 0xD7//NV Memory Function Controller(1) +#define CMD_RDID1 0xDA//Read ID1 +#define CMD_RDID2 0xDB//Read ID2 +#define CMD_RDID3 0xDC//Read ID3 +#define CMD_RDID4 0xDD//Read ID4 +#define CMD_PGAMMAC 0xE0//Positive Gamma Correction Setting +#define CMD_NGAMMAC 0xE1//Negative Gamma Correction Setting +#define CMD_GAMRSEL 0xF2//GAM_R_SEL + + +#define DTA_MADCTL_MX 0x40 +#define DTA_MADCTL_MY 0x80 +#define DTA_MADCTL_MV 0x20 +#define DTA_MADCTL_ML 0x10 +#define DTA_MADCTL_RGB 0x00 +#define DTA_MADCTL_BGR 0x08 +#define DTA_MADCTL_MH 0x04 + + +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); + void begin(void), + setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1), + pushColor(uint16_t color), + fillScreen(uint16_t color=0x0000), + drawPixel(int16_t x, int16_t y, uint16_t color), + 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), + fillRect(int16_t x, int16_t y, int16_t w, int16_t h,uint16_t color), + setRotation(uint8_t r), + invertDisplay(boolean i); + uint16_t Color565(uint8_t r, uint8_t g, uint8_t b); + void setBitrate(uint32_t n); + + private: + + uint8_t tabcolor; + void writecommand(uint8_t c); + void writedata(uint8_t d); + void writedata16(uint16_t d); + void chipInit(); + bool boundaryCheck(int16_t x,int16_t y); + #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__) + void spiwrite(uint8_t); + uint8_t _cs,_rs,_sid,_sclk,_rst; + uint8_t pcs_data, pcs_command; + uint32_t ctar; + volatile uint8_t *datapin, *clkpin, *cspin, *rspin; + #endif +}; +#endif \ No newline at end of file diff --git a/examples/cube/cube.ino b/examples/cube/cube.ino new file mode 100644 index 0000000..db18a86 --- /dev/null +++ b/examples/cube/cube.ino @@ -0,0 +1,85 @@ +#include +#include +#include + +#define __CS 10 +#define __DC 9 +#define __RST 14 + +// Color definitions +#define BLACK 0x0000 +#define BLUE 0x001F +#define RED 0xF800 +#define GREEN 0x07E0 +#define CYAN 0x07FF +#define MAGENTA 0xF81F +#define YELLOW 0xFFE0 +#define WHITE 0xFFFF + +float sin_d[] = { + 0,0.17,0.34,0.5,0.64,0.77,0.87,0.94,0.98,1,0.98,0.94, + 0.87,0.77,0.64,0.5,0.34,0.17,0,-0.17,-0.34,-0.5,-0.64, + -0.77,-0.87,-0.94,-0.98,-1,-0.98,-0.94,-0.87,-0.77, + -0.64,-0.5,-0.34,-0.17 }; +float cos_d[] = { + 1,0.98,0.94,0.87,0.77,0.64,0.5,0.34,0.17,0,-0.17,-0.34, + -0.5,-0.64,-0.77,-0.87,-0.94,-0.98,-1,-0.98,-0.94,-0.87, + -0.77,-0.64,-0.5,-0.34,-0.17,0,0.17,0.34,0.5,0.64,0.77, + 0.87,0.94,0.98}; +float d = 10; +float px[] = { + -d, d, d, -d, -d, d, d, -d }; +float py[] = { + -d, -d, d, d, -d, -d, d, d }; +float pz[] = { + -d, -d, -d, -d, d, d, d, d }; + +float p2x[] = { + 0,0,0,0,0,0,0,0}; +float p2y[] = { + 0,0,0,0,0,0,0,0}; + +int r[] = { + 0,0,0}; + + +TFT_ILI9163C tft = TFT_ILI9163C(__CS, __DC, __RST); + +void setup() { + tft.begin(); +} + +void loop(){ + tft.fillScreen(); + r[0]=r[0]+1; + r[1]=r[1]+1; + if (r[0] == 36) r[0] = 0; + if (r[1] == 36) r[1] = 0; + if (r[2] == 36) r[2] = 0; + for (int i=0;i<8;i++) + { + float px2 = px[i]; + float py2 = cos_d[r[0]]*py[i] - sin_d[r[0]]*pz[i]; + float pz2 = sin_d[r[0]]*py[i] + cos_d[r[0]]*pz[i]; + + float px3 = cos_d[r[1]]*px2 + sin_d[r[1]]*pz2; + float py3 = py2; + float pz3 = -sin_d[r[1]]*px2 + cos_d[r[1]]*pz2; + + float ax = cos_d[r[2]]*px3 - sin_d[r[2]]*py3; + float ay = sin_d[r[2]]*px3 + cos_d[r[2]]*py3; + float az = pz3-190; + + p2x[i] = ((tft.width())/2)+ax*500/az; + p2y[i] = ((tft.height())/2)+ay*500/az; + } + for (int i=0;i<3;i++) { + tft.drawLine(p2x[i],p2y[i],p2x[i+1],p2y[i+1],RED); + tft.drawLine(p2x[i+4],p2y[i+4],p2x[i+5],p2y[i+5],RED); + tft.drawLine(p2x[i],p2y[i],p2x[i+4],p2y[i+4],RED); + } + tft.drawLine(p2x[3],p2y[3],p2x[0],p2y[0],RED); + tft.drawLine(p2x[7],p2y[7],p2x[4],p2y[4],RED); + tft.drawLine(p2x[3],p2y[3],p2x[7],p2y[7],RED); + delay(50); +} diff --git a/examples/graphicstest/graphicstest.ino b/examples/graphicstest/graphicstest.ino new file mode 100644 index 0000000..23d0d4c --- /dev/null +++ b/examples/graphicstest/graphicstest.ino @@ -0,0 +1,336 @@ + +#include +#include +#include + +#if defined(__SAM3X8E__) +#undef __FlashStringHelper::F(string_literal) +#define F(string_literal) string_literal +#endif + +#define __CS 10 +#define __DC 9 +#define __RST 14 + +// Color definitions +#define BLACK 0x0000 +#define BLUE 0x001F +#define RED 0xF800 +#define GREEN 0x07E0 +#define CYAN 0x07FF +#define MAGENTA 0xF81F +#define YELLOW 0xFFE0 +#define WHITE 0xFFFF + +TFT_ILI9163C tft = TFT_ILI9163C(__CS, __DC, __RST); + +void setup() { + Serial.begin(9600); + //while (!Serial); + tft.setBitrate(24000000); + tft.begin(); + //tft.setBitrate(6000000); + + Serial.println(F("Benchmark Time (microseconds)")); + Serial.print(F("Screen fill ")); + Serial.println(testFillScreen()); + delay(500); + + Serial.print(F("Text ")); + Serial.println(testText()); + delay(3000); + + Serial.print(F("Lines ")); + Serial.println(testLines(CYAN)); + delay(500); + + Serial.print(F("Horiz/Vert Lines ")); + Serial.println(testFastLines(RED, BLUE)); + delay(500); + + Serial.print(F("Rectangles (outline) ")); + Serial.println(testRects(GREEN)); + delay(500); + + Serial.print(F("Rectangles (filled) ")); + Serial.println(testFilledRects(YELLOW,MAGENTA)); + delay(500); + + Serial.print(F("Circles (filled) ")); + Serial.println(testFilledCircles(10,MAGENTA)); + + Serial.print(F("Circles (outline) ")); + Serial.println(testCircles(10,WHITE)); + delay(500); + + Serial.print(F("Triangles (outline) ")); + Serial.println(testTriangles()); + delay(500); + + Serial.print(F("Triangles (filled) ")); + Serial.println(testFilledTriangles()); + delay(500); + + Serial.print(F("Rounded rects (outline) ")); + Serial.println(testRoundRects()); + delay(500); + + Serial.print(F("Rounded rects (filled) ")); + Serial.println(testFilledRoundRects()); + delay(500); + + Serial.println(F("Done!")); +} + +void loop(void) { + for(uint8_t rotation=0; rotation<4; rotation++) { + tft.setRotation(rotation); + testText(); + delay(2000); + } +} + + +unsigned long testFillScreen() { + unsigned long start = micros(); + tft.fillScreen(); + tft.fillScreen(RED); + tft.fillScreen(GREEN); + tft.fillScreen(BLUE); + tft.fillScreen(); + return micros() - start; +} + +unsigned long testText() { + tft.fillScreen(); + unsigned long start = micros(); + tft.setCursor(0, 0); + tft.setTextColor(WHITE); + tft.setTextSize(1); + tft.println("Hello World!"); + tft.setTextColor(YELLOW); + tft.setTextSize(2); + tft.println(1234.56); + tft.setTextColor(RED); + tft.setTextSize(3); + tft.println(0xDEAD, HEX); + tft.println(); + tft.setTextColor(GREEN); + tft.setTextSize(4); + tft.println("Hello"); + tft.setTextSize(2); + tft.println("I implore thee,"); + tft.setTextSize(1); + tft.println("my foonting turlingdromes."); + tft.println("And hooptiously drangle me"); + tft.println("with crinkly bindlewurdles,"); + tft.println("Or I will rend thee"); + tft.println("in the gobberwarts"); + tft.println("with my blurglecruncheon,"); + tft.println("see if I don't!"); + return micros() - start; +} + +unsigned long testLines(uint16_t color) { + unsigned long start, t; + int x1, y1, x2, y2, + w = tft.width(), + h = tft.height(); + + tft.fillScreen(); + + x1 = y1 = 0; + y2 = h - 1; + start = micros(); + for(x2=0; x20; i-=6) { + i2 = i / 2; + start = micros(); + 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); + } + + return t; +} + +unsigned long testFilledCircles(uint8_t radius, uint16_t color) { + unsigned long start; + int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2; + + tft.fillScreen(); + start = micros(); + for(x=radius; x10; i-=5) { + start = micros(); + tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + 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)); + } + + return t; +} + +unsigned long testRoundRects() { + unsigned long start; + int w, i, i2, + 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) { + i2 = i / 2; + tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.Color565(0, i, 0)); + } + + return micros() - start; +} \ No newline at end of file diff --git a/examples/minimal/minimal.ino b/examples/minimal/minimal.ino new file mode 100644 index 0000000..670cfc0 --- /dev/null +++ b/examples/minimal/minimal.ino @@ -0,0 +1,21 @@ +#include +#include +#include + +// Color definitions +#define BLACK 0x0000 +#define BLUE 0x001F +#define RED 0xF800 +#define GREEN 0x07E0 +#define CYAN 0x07FF +#define MAGENTA 0xF81F +#define YELLOW 0xFFE0 +#define WHITE 0xFFFF + +TFT_ILI9163C tft = TFT_ILI9163C(10, 9, 14); + +void setup() { +} + +void loop(void) { +} \ No newline at end of file diff --git a/examples/test/test.ino b/examples/test/test.ino new file mode 100644 index 0000000..be59d43 --- /dev/null +++ b/examples/test/test.ino @@ -0,0 +1,94 @@ +#include +#include +#include + +#define __CS 10 +#define __DC 9 +#define __RST 14 + +// Color definitions +#define BLACK 0x0000 +#define BLUE 0x001F +#define RED 0xF800 +#define GREEN 0x07E0 +#define CYAN 0x07FF +#define MAGENTA 0xF81F +#define YELLOW 0xFFE0 +#define WHITE 0xFFFF + +TFT_ILI9163C tft = TFT_ILI9163C(__CS, __DC, __RST); + +void setup() { + tft.begin(); +} + +void loop(){ + testLines(random(0x00ff,0xffff)); + delay(100); + testText(); + delay(500); +} + + +unsigned long testText() { + tft.fillScreen(); + unsigned long start = micros(); + tft.setCursor(0, 0); + tft.setTextColor(WHITE); + tft.setTextSize(1); + tft.println("Hello World!"); + tft.setTextColor(YELLOW); + tft.setTextSize(2); + tft.println(1234.56); + 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 testLines(uint16_t color) { + tft.fillScreen(); + unsigned long start, t; + int x1, y1, x2, y2, + w = tft.width(), + h = tft.height(); + tft.fillScreen(); + x1 = y1 = 0; + y2 = h - 1; + start = micros(); + for(x2=0; x2