From aad2d7cd607baf5e12b3d23adeaa8858ffee7bf9 Mon Sep 17 00:00:00 2001 From: sumotoy Date: Fri, 27 Feb 2015 23:29:24 +0100 Subject: [PATCH] New release New Teensy3.x code SPI Transaction, more examples --- TFT_ILI9163C.cpp | 782 +++++++++++++------ TFT_ILI9163C.h | 146 +++- examples/bubbles/bubbles.h | 182 +++++ examples/clock/clock.ino | 129 +++ examples/mood/mood.ino | 61 ++ examples/simpleBars/simpleBars.ino | 64 ++ examples/vertical_Gauges/vertical_gauges.ino | 133 ++++ 7 files changed, 1262 insertions(+), 235 deletions(-) create mode 100644 examples/bubbles/bubbles.h create mode 100644 examples/clock/clock.ino create mode 100644 examples/mood/mood.ino create mode 100644 examples/simpleBars/simpleBars.ino create mode 100644 examples/vertical_Gauges/vertical_gauges.ino diff --git a/TFT_ILI9163C.cpp b/TFT_ILI9163C.cpp index 1866072..ceff6a4 100644 --- a/TFT_ILI9163C.cpp +++ b/TFT_ILI9163C.cpp @@ -4,20 +4,27 @@ #include "wiring_private.h" #include + //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 } TFT_ILI9163C::TFT_ILI9163C(uint8_t CS, uint8_t DC) : Adafruit_GFX(_TFTWIDTH, _TFTHEIGHT) { - _cs = CS; - _rs = DC; - _rst = 0; - _sid = _sclk = 0; + _cs = CS; + _rs = DC; + _rst = 0; + #if defined(__MK20DX128__) || defined(__MK20DX256__) + #else + _sid = _sclk = 0; + #endif } //Arduino Uno, Leonardo, Mega, Teensy 2.0, etc @@ -102,77 +109,10 @@ void TFT_ILI9163C::setBitrate(uint32_t n){ #elif defined(__MK20DX128__) || defined(__MK20DX256__) //Teensy 3.0 & 3.1 -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; + //nop } + #endif //#if defined(TEENSY3.x) @@ -185,8 +125,7 @@ void TFT_ILI9163C::begin(void) { 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.setClockDivider(SPI_CLOCK_DIV2); // 8 MHz SPI.setBitOrder(MSBFIRST); SPI.setDataMode(SPI_MODE0); // toggle RST low to reset; CS low so it'll listen to us @@ -199,47 +138,21 @@ void TFT_ILI9163C::begin(void) { 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.setClockDivider(11); // 8 MHz 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); + SPI.begin(); + if (SPI.pinIsChipSelect(_cs, _rs)) { + pcs_data = SPI.setCS(_cs); + pcs_command = pcs_data | SPI.setCS(_rs); } else { - CORE_PIN14_CONFIG = PORT_PCR_MUX(2); - SPCR.setSCK(14); + pcs_data = 0; + pcs_command = 0; + return; } - 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); @@ -279,6 +192,92 @@ void TFT_ILI9163C::begin(void) { void TFT_ILI9163C::chipInit() { + #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}; + #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(0x04);//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 (uint8_t i=0;i<15;i++){ + writedata8_cont(pGammaSet[i]); + } + writecommand_cont(CMD_NGAMMAC);//Negative Gamma Correction Setting + for (uint8_t 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 + writedata8_cont(0x00); + writedata8_cont(0X00); + writedata8_cont(0X00); + writedata8_cont(_GRAMWIDTH); + + writecommand_cont(CMD_PGEADRS);//Set Page Address + writedata8_cont(0x00); + writedata8_cont(0X00); + writedata8_cont(0X00); + writedata8_last(_GRAMHEIGH); + SPI.endTransaction(); + 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 @@ -299,74 +298,13 @@ void TFT_ILI9163C::chipInit() { writedata(0b00000110);// writecommand(CMD_PGAMMAC);//Positive Gamma Correction Setting - #if defined(__GAMMASET1) - 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 - #else - writedata(0x3F);//p1 - writedata(0x25);//p2 - writedata(0x1C);//p3 - writedata(0x1E);//p4 - writedata(0x20);//p5 - writedata(0x12);//p6 - writedata(0x2A);//p7 - writedata(0x90);//p8 - writedata(0x24);//p9 - writedata(0x11);//p10 - writedata(0x00);//p11 - writedata(0x00);//p12 - writedata(0x00);//p13 - writedata(0x00);//p14 - writedata(0x00);//p15 - #endif - + for (uint8_t i=0;i<15;i++){ + writedata(pGammaSet[i]); + } writecommand(CMD_NGAMMAC);//Negative Gamma Correction Setting - #if defined(__GAMMASET1) - 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 - #else - writedata(0x20);//p1 - writedata(0x20);//p2 - writedata(0x20);//p3 - writedata(0x20);//p4 - writedata(0x05);//p5 - writedata(0x15);//p6 - writedata(0x00);//p7 - writedata(0xA7);//p8 - writedata(0x3D);//p9 - writedata(0x18);//p10 - writedata(0x25);//p11 - writedata(0x2A);//p12 - writedata(0x2B);//p13 - writedata(0x2B);//p14 - writedata(0x3A);//p15 - #endif + for (uint8_t i=0;i<15;i++){ + writedata(nGammaSet[i]); + } writecommand(CMD_FRMCTR1);//Frame Rate Control (In normal mode/Full colors) writedata(0x08);//0x0C//0x08 @@ -409,6 +347,7 @@ void TFT_ILI9163C::chipInit() { writecommand(CMD_RAMWR);//Memory Write delay(1); + #endif fillScreen(BLACK); } @@ -427,10 +366,20 @@ void TFT_ILI9163C::colorSpace(uint8_t cspace) { void TFT_ILI9163C::clearScreen(uint16_t color) { - homeAddress(); - for (int px=0;px < _GRAMSIZE; px++){ + #if defined(__MK20DX128__) || defined(__MK20DX256__) + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + _setAddrWindow(0x00,0x00,_GRAMWIDTH-1,_GRAMHEIGH-1); + for (int px = 0;px < _GRAMSIZE-1; px++){ + writedata16_cont(color); + } + writedata16_last(color); + SPI.endTransaction(); + #else + homeAddress(); + for (int px = 0;px < _GRAMSIZE; px++){ writedata16(color); } + #endif } void TFT_ILI9163C::homeAddress() { @@ -449,14 +398,30 @@ void TFT_ILI9163C::setCursor(int16_t x, int16_t y) { void TFT_ILI9163C::pushColor(uint16_t color) { - writedata16(color); + #if defined(__MK20DX128__) || defined(__MK20DX256__) + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + writedata16_last(color); + SPI.endTransaction(); + #else + writedata16(color); + #endif } 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); + + #if defined(__MK20DX128__) || defined(__MK20DX256__) + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + _setAddrWindow(x,y,x+1,y+1); + //setAddr(x, y, x, y);// + //writecommand_cont(CMD_RAMWR);//not needed + writedata16_last(color); + SPI.endTransaction(); + #else + setAddrWindow(x,y,x+1,y+1); + writedata16(color); + #endif } @@ -464,10 +429,27 @@ 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); + + #if defined(__MK20DX128__) || defined(__MK20DX256__) + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + _setAddrWindow(x,y,x,(y+h)-1); + #else + setAddrWindow(x,y,x,(y+h)-1); + #endif + while (h-- > 1) { + #if defined(__MK20DX128__) || defined(__MK20DX256__) + if (h == 0){ + writedata16_last(color); + } else { + writedata16_cont(color); + } + #else + writedata16(color); + #endif } + #if defined(__MK20DX128__) || defined(__MK20DX256__) + SPI.endTransaction(); + #endif } bool TFT_ILI9163C::boundaryCheck(int16_t x,int16_t y){ @@ -479,10 +461,26 @@ 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); + #if defined(__MK20DX128__) || defined(__MK20DX256__) + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + _setAddrWindow(x,y,(x+w)-1,y); + #else + setAddrWindow(x,y,(x+w)-1,y); + #endif + while (w-- > 1) { + #if defined(__MK20DX128__) || defined(__MK20DX256__) + if (w == 0){ + writedata16_last(color); + } else { + writedata16_cont(color); + } + #else + writedata16(color); + #endif } + #if defined(__MK20DX128__) || defined(__MK20DX256__) + SPI.endTransaction(); + #endif } void TFT_ILI9163C::fillScreen(uint16_t color) { @@ -494,15 +492,128 @@ void TFT_ILI9163C::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t 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); - + #if defined(__MK20DX128__) || defined(__MK20DX256__) + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + _setAddrWindow(x,y,(x+w)-1,(y+h)-1); + #else + setAddrWindow(x,y,(x+w)-1,(y+h)-1); + #endif for (y = h;y > 0;y--) { - for (x = w;x > 0;x--) { - writedata16(color); + for (x = w;x > 1;x--) { + #if defined(__MK20DX128__) || defined(__MK20DX256__) + writedata16_cont(color); + #else + writedata16(color); + #endif } + #if defined(__MK20DX128__) || defined(__MK20DX256__) + writedata16_last(color); + #endif } + #if defined(__MK20DX128__) || defined(__MK20DX256__) + SPI.endTransaction(); + #endif } +#if defined(__MK20DX128__) || defined(__MK20DX256__) +void TFT_ILI9163C::drawLine(int16_t x0, int16_t y0,int16_t x1, int16_t y1, uint16_t color){ + if (y0 == y1) { + if (x1 > x0) { + drawFastHLine(x0, y0, x1 - x0 + 1, color); + } else if (x1 < x0) { + drawFastHLine(x1, y0, x0 - x1 + 1, color); + } else { + drawPixel(x0, y0, color); + } + return; + } else if (x0 == x1) { + if (y1 > y0) { + drawFastVLine(x0, y0, y1 - y0 + 1, color); + } else { + drawFastVLine(x0, y1, y0 - y1 + 1, color); + } + return; + } + + bool steep = abs(y1 - y0) > abs(x1 - x0); + if (steep) { + swap(x0, y0); + swap(x1, y1); + } + if (x0 > x1) { + swap(x0, x1); + swap(y0, y1); + } + + int16_t dx, dy; + dx = x1 - x0; + dy = abs(y1 - y0); + + int16_t err = dx / 2; + int16_t ystep; + + if (y0 < y1) { + ystep = 1; + } else { + ystep = -1; + } + + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + int16_t xbegin = x0; + if (steep) { + for (; x0<=x1; x0++) { + err -= dy; + if (err < 0) { + int16_t len = x0 - xbegin; + if (len) { + VLine(y0, xbegin, len + 1, color); + } else { + Pixel(y0, x0, color); + } + xbegin = x0 + 1; + y0 += ystep; + err += dx; + } + } + if (x0 > xbegin + 1) { + VLine(y0, xbegin, x0 - xbegin, color); + } + + } else { + for (; x0<=x1; x0++) { + err -= dy; + if (err < 0) { + int16_t len = x0 - xbegin; + if (len) { + HLine(xbegin, y0, len + 1, color); + } else { + Pixel(x0, y0, color); + } + xbegin = x0 + 1; + y0 += ystep; + err += dx; + } + } + if (x0 > xbegin + 1) { + HLine(xbegin, y0, x0 - xbegin, color); + } + } + writecommand_last(CMD_NOP); + SPI.endTransaction(); +} + +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)); + HLine(x, y, w, color); + HLine(x, y+h-1, w, color); + VLine(x, y, h, color); + VLine(x+w-1, y, h, color); + writecommand_last(CMD_NOP); + SPI.endTransaction(); +} + + +#endif // Pass 8-bit (each) R,G,B, get back 16-bit packed color @@ -512,38 +623,110 @@ uint16_t TFT_ILI9163C::Color565(uint8_t r, uint8_t g, uint8_t b) { void TFT_ILI9163C::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { - writecommand(CMD_CLMADRS); // Column - if (rotation == 0){ - writedata16(x0); - writedata16(x1); - } else if (rotation == 1){ - writedata16(x0 + __OFFSET); - writedata16(x1 + __OFFSET); - } else if (rotation == 2){ - writedata16(x0); - writedata16(x1); - } else { - writedata16(x0); - writedata16(x1); - } + #if defined(__MK20DX128__) || defined(__MK20DX256__) + + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + writecommand_cont(CMD_CLMADRS); // Column + if (rotation == 0){ + writedata16_cont(x0); + writedata16_cont(x1); + } else if (rotation == 1){ + writedata16_cont(x0 + __OFFSET); + writedata16_cont(x1 + __OFFSET); + } else if (rotation == 2){ + writedata16_cont(x0); + writedata16_cont(x1); + } else { + writedata16_cont(x0); + writedata16_cont(x1); + } - writecommand(CMD_PGEADRS); // Page - if (rotation == 0){ - writedata16(y0 + __OFFSET); - writedata16(y1 + __OFFSET); - } else if (rotation == 1){ - writedata16(y0); - writedata16(y1); - } else if (rotation == 2){ - writedata16(y0); - writedata16(y1); - } else { - writedata16(y0); - writedata16(y1); - } - writecommand(CMD_RAMWR); //Into RAM + writecommand_cont(CMD_PGEADRS); // Page + if (rotation == 0){ + writedata16_cont(y0 + __OFFSET); + writedata16_cont(y1 + __OFFSET); + } else if (rotation == 1){ + writedata16_cont(y0); + writedata16_cont(y1); + } else if (rotation == 2){ + writedata16_cont(y0); + writedata16_cont(y1); + } else { + writedata16_cont(y0); + writedata16_cont(y1); + } + writecommand_last(CMD_RAMWR); //Into RAM + SPI.endTransaction(); + + #else + writecommand(CMD_CLMADRS); // Column + if (rotation == 0){ + writedata16(x0); + writedata16(x1); + } else if (rotation == 1){ + writedata16(x0 + __OFFSET); + writedata16(x1 + __OFFSET); + } else if (rotation == 2){ + writedata16(x0); + writedata16(x1); + } else { + writedata16(x0); + writedata16(x1); + } + + writecommand(CMD_PGEADRS); // Page + if (rotation == 0){ + writedata16(y0 + __OFFSET); + writedata16(y1 + __OFFSET); + } else if (rotation == 1){ + writedata16(y0); + writedata16(y1); + } else if (rotation == 2){ + writedata16(y0); + writedata16(y1); + } else { + writedata16(y0); + writedata16(y1); + } + writecommand(CMD_RAMWR); //Into RAM + #endif } +#if defined(__MK20DX128__) || defined(__MK20DX256__) +void TFT_ILI9163C::_setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { + writecommand_cont(CMD_CLMADRS); // Column + if (rotation == 0){ + writedata16_cont(x0); + writedata16_cont(x1); + } else if (rotation == 1){ + writedata16_cont(x0 + __OFFSET); + writedata16_cont(x1 + __OFFSET); + } else if (rotation == 2){ + writedata16_cont(x0); + writedata16_cont(x1); + } else { + writedata16_cont(x0); + writedata16_cont(x1); + } + + writecommand_cont(CMD_PGEADRS); // Page + if (rotation == 0){ + writedata16_cont(y0 + __OFFSET); + writedata16_cont(y1 + __OFFSET); + } else if (rotation == 1){ + writedata16_cont(y0); + writedata16_cont(y1); + } else if (rotation == 2){ + writedata16_cont(y0); + writedata16_cont(y1); + } else { + writedata16_cont(y0); + writedata16_cont(y1); + } + writecommand_cont(CMD_RAMWR); //Into RAM + +} +#endif void TFT_ILI9163C::setRotation(uint8_t m) { rotation = m % 4; // can't be higher than 3 @@ -570,11 +753,164 @@ void TFT_ILI9163C::setRotation(uint8_t m) { break; } colorSpace(_colorspaceData); - writecommand(CMD_MADCTL); - writedata(_Mactrl_Data); + #if defined(__MK20DX128__) || defined(__MK20DX256__) + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + writecommand_cont(CMD_MADCTL); + writedata8_last(_Mactrl_Data); + SPI.endTransaction(); + #else + writecommand(CMD_MADCTL); + writedata(_Mactrl_Data); + #endif } void TFT_ILI9163C::invertDisplay(boolean i) { - writecommand(i ? CMD_DINVON : CMD_DINVOF); + #if defined(__MK20DX128__) || defined(__MK20DX256__) + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + writecommand_last(i ? CMD_DINVON : CMD_DINVOF); + SPI.endTransaction(); + #else + writecommand(i ? CMD_DINVON : CMD_DINVOF); + #endif } + + +/* +// Draw a character +void TFT_ILI9163C::drawChar(int16_t x, int16_t y, unsigned char c, uint16_t fgcolor, uint16_t bgcolor, uint8_t size){ + if((x >= _width) || // Clip right + (y >= _height) || // Clip bottom + ((x + 6 * size - 1) < 0) || // Clip left TODO: is this correct? + ((y + 8 * size - 1) < 0)) // Clip top TODO: is this correct? + return; + + if (fgcolor == bgcolor) { + // This transparent approach is only about 20% faster + if (size == 1) { + uint8_t mask = 0x01; + int16_t xoff, yoff; + for (yoff=0; yoff < 8; yoff++) { + uint8_t line = 0; + for (xoff=0; xoff < 5; xoff++) { + if (font[c * 5 + xoff] & mask) line |= 1; + line <<= 1; + } + line >>= 1; + xoff = 0; + while (line) { + if (line == 0x1F) { + drawFastHLine(x + xoff, y + yoff, 5, fgcolor); + break; + } else if (line == 0x1E) { + drawFastHLine(x + xoff, y + yoff, 4, fgcolor); + break; + } else if ((line & 0x1C) == 0x1C) { + drawFastHLine(x + xoff, y + yoff, 3, fgcolor); + line <<= 4; + xoff += 4; + } else if ((line & 0x18) == 0x18) { + drawFastHLine(x + xoff, y + yoff, 2, fgcolor); + line <<= 3; + xoff += 3; + } else if ((line & 0x10) == 0x10) { + drawPixel(x + xoff, y + yoff, fgcolor); + line <<= 2; + xoff += 2; + } else { + line <<= 1; + xoff += 1; + } + } + mask = mask << 1; + } + } else { + uint8_t mask = 0x01; + int16_t xoff, yoff; + for (yoff=0; yoff < 8; yoff++) { + uint8_t line = 0; + for (xoff=0; xoff < 5; xoff++) { + if (font[c * 5 + xoff] & mask) line |= 1; + line <<= 1; + } + line >>= 1; + xoff = 0; + while (line) { + if (line == 0x1F) { + fillRect(x + xoff * size, y + yoff * size, + 5 * size, size, fgcolor); + break; + } else if (line == 0x1E) { + fillRect(x + xoff * size, y + yoff * size, + 4 * size, size, fgcolor); + break; + } else if ((line & 0x1C) == 0x1C) { + fillRect(x + xoff * size, y + yoff * size, + 3 * size, size, fgcolor); + line <<= 4; + xoff += 4; + } else if ((line & 0x18) == 0x18) { + fillRect(x + xoff * size, y + yoff * size, + 2 * size, size, fgcolor); + line <<= 3; + xoff += 3; + } else if ((line & 0x10) == 0x10) { + fillRect(x + xoff * size, y + yoff * size, + size, size, fgcolor); + line <<= 2; + xoff += 2; + } else { + line <<= 1; + xoff += 1; + } + } + mask = mask << 1; + } + } + } else { + // This solid background approach is about 5 time faster + #if defined(__MK20DX128__) || defined(__MK20DX256__) + SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0)); + _setAddrWindow(x, y, x + 6 * size - 1, y + 8 * size - 1); + //writecommand_cont(ILI9341_RAMWR); + #else + setAddrWindow(x, y, x + 6 * size - 1, y + 8 * size - 1); + #endif + uint8_t xr, yr; + uint8_t mask = 0x01; + uint16_t color; + for (y=0; y < 8; y++) { + for (yr=0; yr < size; yr++) { + for (x=0; x < 5; x++) { + if (font[c * 5 + x] & mask) { + color = fgcolor; + } else { + color = bgcolor; + } + for (xr=0; xr < size; xr++) { + #if defined(__MK20DX128__) || defined(__MK20DX256__) + writedata16_cont(color); + #else + writedata16(color); + #endif + } + } + for (xr=0; xr < size; xr++) { + #if defined(__MK20DX128__) || defined(__MK20DX256__) + writedata16_cont(bgcolor); + #else + writedata16(bgcolor); + #endif + } + } + mask = mask << 1; + } + #if defined(__MK20DX128__) || defined(__MK20DX256__) + writecommand_last(CMD_NOP); + SPI.endTransaction(); + #else + writecommand(CMD_NOP); + #endif + } +} +*/ \ No newline at end of file diff --git a/TFT_ILI9163C.h b/TFT_ILI9163C.h index f94c594..c1df30e 100644 --- a/TFT_ILI9163C.h +++ b/TFT_ILI9163C.h @@ -68,10 +68,29 @@ 0.2b3: Added 2.2" Red PCB parameters 0.2b4: Bug fixes, added colorSpace (for future send image) 0.2b5: Cleaning + 0.3b1: Complete rework on Teensy SPI based on Paul Stoffregen work + SPI transaction,added BLACK TAG 2.2 display +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ BugList of the current version: - Actually no scroll commands (only in release will be included). + + +Here's the speed test between 0.2b5 and 0.3b1 on Teensy3.1 +------------------------------------------------------------------------ +Lines 17024 16115 BETTER +Horiz/Vert Lines 5360 5080 BETTER +Rectangles (outline) 4384 4217 BETTER +Rectangles (filled) 96315 91265 BETTER +Circles (filled) 16053 15829 LITTLE BETTER +Circles (outline) 11540 20320 WORST! +Triangles (outline) 5359 5143 BETTER +Triangles (filled) 19088 18741 BETTER +Rounded rects (outline) 8681 12498 LITTLE WORST +Rounded rects (filled) 105453 100213 BETTER +Done! + + */ #ifndef _TFT_ILI9163CLIB_H_ #define _TFT_ILI9163CLIB_H_ @@ -87,6 +106,7 @@ //----- Define here witch display you own #define __144_RED_PCB__//128x128 +//#define __144_BLACK_PCB__//128x128 //#define __22_RED_PCB__//240x320 //--------------------------------------- @@ -101,13 +121,7 @@ #include #endif #if defined(__MK20DX128__) || defined(__MK20DX256__) - #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)) + #define SPICLOCK 30000000 #endif //ILI9163C versions------------------------ @@ -118,7 +132,7 @@ http://www.ebay.com/itm/Replace-Nokia-5110-LCD-1-44-Red-Serial-128X128-SPI-Color 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 needit so below +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. */ @@ -131,6 +145,16 @@ you can copy those parameters and create setup for different displays. #define __GAMMASET1 //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: @@ -231,6 +255,11 @@ class TFT_ILI9163C : public Adafruit_GFX { 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), + #if defined(__MK20DX128__) || defined(__MK20DX256__) + 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 + //drawChar(int16_t x, int16_t y, unsigned char c, uint16_t fgcolor, uint16_t bgcolor, uint8_t size), fillRect(int16_t x, int16_t y, int16_t w, int16_t h,uint16_t color), setRotation(uint8_t r), invertDisplay(boolean i); @@ -241,9 +270,12 @@ class TFT_ILI9163C : public Adafruit_GFX { uint8_t _Mactrl_Data;//container for the memory access control data uint8_t _colorspaceData; void colorSpace(uint8_t cspace); + #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(); @@ -262,10 +294,100 @@ class TFT_ILI9163C : public Adafruit_GFX { #endif // #if defined(__SAM3X8E__) #if defined(__MK20DX128__) || defined(__MK20DX256__) - uint8_t _cs,_rs,_sid,_sclk,_rst; - uint8_t pcs_data, pcs_command; - uint32_t ctar; - volatile uint8_t *datapin, *clkpin, *cspin, *rspin; + 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 + +/* void setAddr(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) __attribute__((always_inline)) { + writecommand_cont(CMD_CLMADRS); // Column addr set + writedata16_cont(x0); // XSTART + writedata16_cont(x1); // XEND + writecommand_cont(CMD_PGEADRS); // Row addr set + writedata16_cont(y0); // YSTART + writedata16_cont(y1); // YEND + } */ + + void waitFifoNotFull(void) { + uint32_t sr; + uint32_t tmp __attribute__((unused)); + do { + sr = SPI0.SR; + 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 { + sr = SPI0.SR; + 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)); + while (!(SPI0.SR & SPI_SR_TCF)) ; // wait until final output done + tmp = SPI0_POPR; // drain the final RX FIFO word + } + + void writecommand_cont(uint8_t c) __attribute__((always_inline)) { + SPI0.PUSHR = c | (pcs_command << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT; + waitFifoNotFull(); + } + + void writecommand_last(uint8_t c) __attribute__((always_inline)) { + waitFifoEmpty(); + SPI0.SR = SPI_SR_TCF; + SPI0.PUSHR = c | (pcs_command << 16) | SPI_PUSHR_CTAS(0); + waitTransmitComplete(); + } + + void writedata8_cont(uint8_t c) __attribute__((always_inline)) { + SPI0.PUSHR = c | (pcs_data << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT; + waitFifoNotFull(); + } + + void writedata8_last(uint8_t c) __attribute__((always_inline)) { + waitFifoEmpty(); + SPI0.SR = SPI_SR_TCF; + SPI0.PUSHR = c | (pcs_data << 16) | SPI_PUSHR_CTAS(0); + waitTransmitComplete(); + } + + void writedata16_cont(uint16_t d) __attribute__((always_inline)) { + SPI0.PUSHR = d | (pcs_data << 16) | SPI_PUSHR_CTAS(1) | SPI_PUSHR_CONT; + waitFifoNotFull(); + } + + void writedata16_last(uint16_t d) __attribute__((always_inline)) { + waitFifoEmpty(); + SPI0.SR = SPI_SR_TCF; + SPI0.PUSHR = d | (pcs_data << 16) | SPI_PUSHR_CTAS(1); + 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/examples/bubbles/bubbles.h b/examples/bubbles/bubbles.h new file mode 100644 index 0000000..88b7d12 --- /dev/null +++ b/examples/bubbles/bubbles.h @@ -0,0 +1,182 @@ +/* + This example was adapted from ugfx http://ugfx.org + It's a great example of many 2d objects in a 3d space (matrix transformations) + and show the capabilities of RA8875 chip. + Tested and worked with: + Teensy3,Teensy3.1,Arduino UNO,Arduino YUN,Arduino Leonardo,Stellaris + Works with Arduino 1.0.6 IDE, Arduino 1.5.8 IDE, Energia 0013 IDE +*/ +#ifdef __AVR__ +#define sinf sin +#endif + +#define BLACK 0x0000 +#define BLUE 0x001F +#define RED 0xF800 +#define GREEN 0x07E0 +#define CYAN 0x07FF +#define MAGENTA 0xF81F +#define YELLOW 0xFFE0 +#define WHITE 0xFFFF +#define NDOTS 512 // Number of dots 512 +#define SCALE 4096//4096 +#define INCREMENT 512//512 +#define PI2 6.283185307179586476925286766559 +#define RED_COLORS (32) +#define GREEN_COLORS (64) +#define BLUE_COLORS (32) + +#include +#include +#include + +/* +Teensy3.x and Arduino's +You are using 4 wire SPI here, so: + MOSI: 11//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site) + MISO: 12//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site) + SCK: 13//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site) + the rest of pin below: + */ +TFT_ILI9163C tft = TFT_ILI9163C(10, 9); + +int16_t sine[SCALE+(SCALE/4)]; +int16_t *cosi = &sine[SCALE/4]; +int16_t angleX = 0, angleY = 0, angleZ = 0; +int16_t speedX = 0, speedY = 0, speedZ = 0; + +int16_t xyz[3][NDOTS]; +uint16_t col[NDOTS]; +int pass = 0; + + +void initialize (void){ + uint16_t i; + /* if you change the SCALE*1.25 back to SCALE, the program will + * occassionally overrun the cosi array -- however this actually + * produces some interesting effects as the BUBBLES LOSE CONTROL!!!! + */ + for (i = 0; i < SCALE+(SCALE/4); i++) + //sine[i] = (-SCALE/2) + (int)(sinf(PI2 * i / SCALE) * sinf(PI2 * i / SCALE) * SCALE); + sine[i] = (int)(sinf(PI2 * i / SCALE) * SCALE); +} + +void setup() +{ + + tft.begin(); + + initialize(); +} + + + +void matrix (int16_t xyz[3][NDOTS], uint16_t col[NDOTS]){ + static uint32_t t = 0; + int16_t x = -SCALE, y = -SCALE; + uint16_t i, s, d; + uint8_t red,grn,blu; + + for (i = 0; i < NDOTS; i++) + { + xyz[0][i] = x; + xyz[1][i] = y; + + d = sqrt(x * x + y * y); /* originally a fastsqrt() call */ + s = sine[(t * 30) % SCALE] + SCALE; + + xyz[2][i] = sine[(d + s) % SCALE] * sine[(t * 10) % SCALE] / SCALE / 2; + + red = (cosi[xyz[2][i] + SCALE / 2] + SCALE) * (RED_COLORS - 1) / SCALE / 2; + grn = (cosi[(xyz[2][i] + SCALE / 2 + 2 * SCALE / 3) % SCALE] + SCALE) * (GREEN_COLORS - 1) / SCALE / 2; + blu = (cosi[(xyz[2][i] + SCALE / 2 + SCALE / 3) % SCALE] + SCALE) * (BLUE_COLORS - 1) / SCALE / 2; + col[i] = ((red << 11) + (grn << 5) + blu); + x += INCREMENT; + if (x >= SCALE) x = -SCALE, y += INCREMENT; + } + t++; +} + +void rotate (int16_t xyz[3][NDOTS], uint16_t angleX, uint16_t angleY, uint16_t angleZ){ + uint16_t i; + int16_t tmpX, tmpY; + int16_t sinx = sine[angleX], cosx = cosi[angleX]; + int16_t siny = sine[angleY], cosy = cosi[angleY]; + int16_t sinz = sine[angleZ], cosz = cosi[angleZ]; + + for (i = 0; i < NDOTS; i++) + { + tmpX = (xyz[0][i] * cosx - xyz[2][i] * sinx) / SCALE; + xyz[2][i] = (xyz[0][i] * sinx + xyz[2][i] * cosx) / SCALE; + xyz[0][i] = tmpX; + tmpY = (xyz[1][i] * cosy - xyz[2][i] * siny) / SCALE; + xyz[2][i] = (xyz[1][i] * siny + xyz[2][i] * cosy) / SCALE; + xyz[1][i] = tmpY; + tmpX = (xyz[0][i] * cosz - xyz[1][i] * sinz) / SCALE; + xyz[1][i] = (xyz[0][i] * sinz + xyz[1][i] * cosz) / SCALE; + xyz[0][i] = tmpX; + } +} + + +void draw(int16_t xyz[3][NDOTS], uint16_t col[NDOTS]){ + static uint16_t oldProjX[NDOTS] = { 0 }; + static uint16_t oldProjY[NDOTS] = { 0 }; + static uint8_t oldDotSize[NDOTS] = { 0 }; + uint16_t i, projX, projY, projZ, dotSize; + + for (i = 0; i < NDOTS; i++) + { + projZ = SCALE - (xyz[2][i] + SCALE) / 4; + projX = tft.width() / 2 + (xyz[0][i] * projZ / SCALE) / 25; + projY = tft.height() / 2 + (xyz[1][i] * projZ / SCALE) / 25; + dotSize = 3 - (xyz[2][i] + SCALE) * 2 / SCALE; + + tft.drawCircle (oldProjX[i], oldProjY[i], oldDotSize[i], BLACK); + + if (projX > dotSize && projY > dotSize && projX < tft.width() - dotSize && projY < tft.height() - dotSize) + { + tft.drawCircle (projX, projY, dotSize, col[i]); + oldProjX[i] = projX; + oldProjY[i] = projY; + oldDotSize[i] = dotSize; + } + } +} + +void loop() +{ + matrix(xyz, col); + rotate(xyz, angleX, angleY, angleZ); + draw(xyz, col); + + angleX += speedX; + angleY += speedY; + angleZ += speedZ; + + if (pass > 400) speedY = 1; + if (pass > 800) speedX = 1; + if (pass > 1200) speedZ = 1; + pass++; + + if (angleX >= SCALE) { + angleX -= SCALE; + } + else if (angleX < 0) { + angleX += SCALE; + } + + if (angleY >= SCALE) { + angleY -= SCALE; + } + else if (angleY < 0) { + angleY += SCALE; + } + + if (angleZ >= SCALE) { + angleZ -= SCALE; + } + else if (angleZ < 0) { + angleZ += SCALE; + } +} diff --git a/examples/clock/clock.ino b/examples/clock/clock.ino new file mode 100644 index 0000000..5600bcf --- /dev/null +++ b/examples/clock/clock.ino @@ -0,0 +1,129 @@ +#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 + +#define __CS 10 +#define __DC 9 + +/* +Teensy 3.x can use: 2,6,9,10,15,20,21,22,23 +Arduino's 8 bit: any +DUE: check site +*/ + + +TFT_ILI9163C tft = TFT_ILI9163C(__CS, __DC); + +uint16_t ccenterx,ccentery;//center x,y of the clock +const uint16_t cradius = 63;//radius of the clock +const float scosConst = 0.0174532925; +float sx = 0, sy = 1, mx = 1, my = 0, hx = -1, hy = 0; +float sdeg=0, mdeg=0, hdeg=0; +uint16_t osx,osy,omx,omy,ohx,ohy; +uint16_t x0 = 0, x1 = 0, yy0 = 0, yy1 = 0; +uint32_t targetTime = 0;// for next 1 second timeout +uint8_t hh,mm,ss; //containers for current time + + +void drawClockFace(){ + tft.fillCircle(ccenterx, ccentery, cradius, BLUE); + tft.fillCircle(ccenterx, ccentery, cradius-4, BLACK); + // Draw 12 lines + for(int i = 0; i<360; i+= 30) { + sx = cos((i-90)*scosConst); + sy = sin((i-90)*scosConst); + x0 = sx*(cradius-4)+ccenterx; + yy0 = sy*(cradius-4)+ccentery; + x1 = sx*(cradius-11)+ccenterx; + yy1 = sy*(cradius-11)+ccentery; + tft.drawLine(x0, yy0, x1, yy1, BLUE); + } +} + +static uint8_t conv2d(const char* p) { + uint8_t v = 0; + if ('0' <= *p && *p <= '9') v = *p - '0'; + return 10 * v + *++p - '0'; +} + +void setup(void) { + tft.begin(); + + tft.setTextColor(WHITE, BLACK); + ccenterx = tft.width()/2; + ccentery = tft.height()/2; + osx = ccenterx; + osy = ccentery; + omx = ccenterx; + omy = ccentery; + ohx = ccenterx; + ohy = ccentery; + drawClockFace();// Draw clock face + //get current time from compiler + hh = conv2d(__TIME__); + mm = conv2d(__TIME__+3); + ss = conv2d(__TIME__+6); + targetTime = millis() + 1000; +} + +void drawClockHands(uint8_t h,uint8_t m,uint8_t s){ + // Pre-compute hand degrees, x & y coords for a fast screen update + sdeg = s * 6; // 0-59 -> 0-354 + mdeg = m * 6 + sdeg * 0.01666667; // 0-59 -> 0-360 - includes seconds + hdeg = h * 30 + mdeg * 0.0833333; // 0-11 -> 0-360 - includes minutes and seconds + hx = cos((hdeg-90)*scosConst); + hy = sin((hdeg-90)*scosConst); + mx = cos((mdeg-90)*scosConst); + my = sin((mdeg-90)*scosConst); + sx = cos((sdeg-90)*scosConst); + sy = sin((sdeg-90)*scosConst); + + // Erase just old hand positions + tft.drawLine(ohx, ohy, ccenterx+1, ccentery+1, BLACK); + tft.drawLine(omx, omy, ccenterx+1, ccentery+1, BLACK); + tft.drawLine(osx, osy, ccenterx+1, ccentery+1, BLACK); + // Draw new hand positions + tft.drawLine(hx*(cradius-28)+ccenterx+1, hy*(cradius-28)+ccentery+1, ccenterx+1, ccentery+1, WHITE); + tft.drawLine(mx*(cradius-17)+ccenterx+1, my*(cradius-17)+ccentery+1, ccenterx+1, ccentery+1, WHITE); + tft.drawLine(sx*(cradius-14)+ccenterx+1, sy*(cradius-14)+ccentery+1, ccenterx+1, ccentery+1, RED); + tft.fillCircle(ccenterx+1, ccentery+1, 3, RED); + + // Update old x&y coords + osx = sx*(cradius-14)+ccenterx+1; + osy = sy*(cradius-14)+ccentery+1; + omx = mx*(cradius-17)+ccenterx+1; + omy = my*(cradius-17)+ccentery+1; + ohx = hx*(cradius-28)+ccenterx+1; + ohy = hy*(cradius-28)+ccentery+1; +} + + +void loop() { + if (targetTime < millis()) { + targetTime = millis()+1000; + ss++; + if (ss == 60) { + ss = 0; + mm++; + if(mm > 59) { + mm = 0; + hh++; + if (hh > 23) hh = 0; + } + } + drawClockHands(hh,mm,ss); + + } +} + + diff --git a/examples/mood/mood.ino b/examples/mood/mood.ino new file mode 100644 index 0000000..caf10de --- /dev/null +++ b/examples/mood/mood.ino @@ -0,0 +1,61 @@ +#include +#include +#include + + +#define BLACK 0x0000 +#define BLUE 0x001F +#define RED 0xF800 +#define GREEN 0x07E0 +#define CYAN 0x07FF +#define MAGENTA 0xF81F +#define YELLOW 0xFFE0 +#define WHITE 0xFFFF +#define TRANSPARENT -1 +/* +Teensy3.x and Arduino's +You are using 4 wire SPI here, so: + MOSI: 11//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site) + MISO: 12//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site) + SCK: 13//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site) + the rest of pin below: + */ +#define __CS 10 +#define __DC 9 +/* +Teensy 3.x can use: 2,6,9,10,15,20,21,22,23 +Arduino's 8 bit: any +DUE: check arduino site +*/ + + +TFT_ILI9163C tft = TFT_ILI9163C(__CS, __DC); + + +float angle; + +void setup() +{ + tft.begin(); + +} + +// Translate a hue "angle" -120 to 120 degrees (ie -2PI/3 to 2PI/3) to +// a 6-bit R channel value +// +// This is very slow on a microcontroller, not a great example! +inline int angle_to_channel(float a) { + if (a < -PI) a += 2*PI; + if (a < -2*PI/3 || a > 2*PI/3) return 0; + float f_channel = cos(a*3/4); // remap 120-degree 0-1.0 to 90 ?? + return ceil(f_channel * 255);//63 +} + +void loop() { + uint16_t clr = (((angle_to_channel(angle-4*PI/3)>>1) & 0xF8) << 8) | (((angle_to_channel(angle-2*PI/3)) & 0xFC) << 3) | ((angle_to_channel(angle)>>1) >> 3); + tft.fillScreen(clr); + + angle += 0.01; + if(angle > PI) + angle -= 2*PI; +} \ No newline at end of file diff --git a/examples/simpleBars/simpleBars.ino b/examples/simpleBars/simpleBars.ino new file mode 100644 index 0000000..d183f9d --- /dev/null +++ b/examples/simpleBars/simpleBars.ino @@ -0,0 +1,64 @@ +#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 + +#define NBINS 12 +const uint8_t bar_Width = 3; + +uint32_t avrg_TmrF = 0; +uint16_t t_b[NBINS]; + +uint16_t datax_[NBINS]; + +TFT_ILI9163C tft = TFT_ILI9163C(10, 9); + +void setup(void) { + Serial.begin(38400); + //while(!Serial); + tft.begin(); + tft.setRotation(1); + tft.fillScreen(BLACK); + tft.setTextWrap(true); + tft.setTextColor(WHITE, BLACK); + tft.setCursor(0,0); +} + + +void loop(){ + for (int i=0;i> 3); + tft.fillRect(startX,(vOrigin+1),(bar_Width+3),dataToWidth,BLACK);//mask ok + tft.fillRect(startX,(dataToWidth+vOrigin)+1,(bar_Width+3),((barHeight-2)-dataToWidth),color);//fillRect(X,Y,width,height,color) + } +} diff --git a/examples/vertical_Gauges/vertical_gauges.ino b/examples/vertical_Gauges/vertical_gauges.ino new file mode 100644 index 0000000..fe50bf7 --- /dev/null +++ b/examples/vertical_Gauges/vertical_gauges.ino @@ -0,0 +1,133 @@ +//example adapted from somewhere but cannot remember! +//If the author recognize it drop me a note! + +#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 + +#define NBINS 8 +const uint8_t bar_Width = 7; +uint32_t avrg_TmrF = 0; +uint16_t t_b[NBINS]; + +TFT_ILI9163C tft = TFT_ILI9163C(10, 9); + + +void setup(void) { + Serial.begin(38400); + tft.begin(); + tft.setRotation(1); + tft.fillScreen(BLACK); + tft.setTextWrap(true); + tft.setTextColor(WHITE,BLACK); + tft.setCursor(0,0); + Draw_Table(); +} + + +void loop(){ + for (int i=0;i>= 4; + if (avrg_TmrF != 0) frequency = (8.0 * 16000000.0) / avrg_TmrF; + avrg_TmrF = 0; + //--------------------- FREQ --------------- + tft.setCursor(96,33); + if (frequency < 99) { + tft.print(frequency,2); + } + else{ + tft.print("..."); + } + +/*THD: Total Harmonic Distortion. The harmonic distortion characterises the ratio of the sum of the +harmonics to the fundamental signal. Normally there are the first 6 harmonics used for the +characterisation. +THD = 20 * log (SQRT (SUM (SQR ([Harmonics]))) / [Fundamental])*/ +// ---------------- Vertical VU's ------------------------------------------ + uint32_t total1 = 0; // ALL + uint32_t total2 = 0; // All, Except Fundamental (1). + uint16_t fnd = 0; // Fundamental + + for (int i = 1; i < NBINS; i++) { + int st1 = (i * 10) + 15; // k = 70 / (NBINS -1) + tft.drawRect((st1-1),0,bar_Width,128,WHITE); // Volume + uint32_t vremn1 = t_b[i] >> 4; // V(i) / updt_Rate + uint32_t vremn2 = vremn1 * vremn1; // V(i) ^ 2. + total1 += vremn2; // Total1 = V1^2 + V2^2 + V3^2 + V4^2 + V5^2 + if (i != 1) + total2 += vremn2; // Total2 = V2^2 + V3^2 + V4^2 + V5^2 + else + fnd = vremn1; // Fundamental = V1 + vremn2 = 20 * log10(vremn1+1); // !!! +1 MUST, + int st2 = map(vremn2,0,73,(128-2),0); // 73 dB + tft.fillRect(st1,1,(bar_Width-2),st2,BLACK); // Empty + tft.fillRect(st1,(st2 + 2),(bar_Width-2),(128-2-st2),GREEN); // Fill Up + t_b[i] = 0; +} + + voltag_ac = sqrt(total1) / 20.27; // Hardware Calibration Coefficient /0.39752907 + //-------------RMS-------------------- + tft.setCursor(96,55); + if (voltag_ac < 999) { + tft.print(voltag_ac,1); + } + else{ + tft.print( "..."); + } + + total_thd = 100.0 * sqrt(total2) / fnd; + //-------------THD ------------------------ + tft.setCursor(96,11); + if (total_thd < 9) { + tft.print(total_thd,3); + } + else{ + tft.print( "..."); + } +} \ No newline at end of file