New release

New Teensy3.x code SPI Transaction, more examples
This commit is contained in:
sumotoy 2015-02-27 23:29:24 +01:00
parent dda4076397
commit aad2d7cd60
7 changed files with 1262 additions and 235 deletions

View file

@ -4,12 +4,16 @@
#include "wiring_private.h"
#include <SPI.h>
//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
}
@ -17,7 +21,10 @@ TFT_ILI9163C::TFT_ILI9163C(uint8_t CS, uint8_t DC) : Adafruit_GFX(_TFTWIDTH, _TF
_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,46 +138,20 @@ 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);
}
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
pcs_data = 0;
pcs_command = 0;
return;
}
#endif
if (_rst != 0) {
@ -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) {
#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) {
#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;
#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;
#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);
while (h--) {
writedata16(color);
#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;
#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);
while (w--) {
writedata16(color);
#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;
#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--) {
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,6 +623,42 @@ 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) {
#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_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);
@ -542,8 +689,44 @@ void TFT_ILI9163C::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t
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);
#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) {
#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
}
}
*/

View file

@ -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 <avr/pgmspace.h>
#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 _cs, _rs, _rst;
uint8_t pcs_data, pcs_command;
uint32_t ctar;
volatile uint8_t *datapin, *clkpin, *cspin, *rspin;
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

182
examples/bubbles/bubbles.h Normal file
View file

@ -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 <SPI.h>
#include <Adafruit_GFX.h>
#include <TFT_ILI9163C.h>
/*
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;
}
}

129
examples/clock/clock.ino Normal file
View file

@ -0,0 +1,129 @@
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <TFT_ILI9163C.h>
// 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);
}
}

61
examples/mood/mood.ino Normal file
View file

@ -0,0 +1,61 @@
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <TFT_ILI9163C.h>
#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;
}

View file

@ -0,0 +1,64 @@
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <TFT_ILI9163C.h>
// 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<NBINS;i++){
datax_[i] = random(0,1024);
}
//Print_Data();
verticalBarGraphs(datax_,5,127,0);
delay(50);
}
void verticalBarGraphs(uint16_t datax[],uint8_t barWidth,uint8_t barHeight,uint8_t vOrigin){//3,12,64,10
uint8_t startX;
uint16_t color;
uint8_t dataToWidth;
uint8_t div;
for (uint8_t i = 1; i <= NBINS-1; i++) {
startX = (i * 11);
//tft.drawRect((startX-1),vOrigin,barWidth,barHeight,WHITE);//container
dataToWidth = map(datax[i],0,1024,(barHeight-2),0);
uint8_t b = map(datax[i],0,1024,255,0);
uint8_t g = map(datax[i],0,1024,128,0);
uint8_t r = map(datax[i],0,1024,0,255);
div = (barHeight-2)/10;
color = ((b & 0xF8) << 8) | ((g & 0xFC) << 3) | (r >> 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)
}
}

View file

@ -0,0 +1,133 @@
//example adapted from somewhere but cannot remember!
//If the author recognize it drop me a note!
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <TFT_ILI9163C.h>
// 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<NBINS;i++){
t_b[i] = random(0,4096);
}
Print_Data();
delay(100);
}
void Draw_Table(void)
{
tft.drawFastVLine( 22, 0, 128, WHITE); // Draw a Scale
tft.drawFastHLine( 20, 0, 4, WHITE);
for ( int i = 10; i < 128; i += 10 ) {
tft.drawFastHLine( 20, i, 4, WHITE);
tft.setCursor( 0, i - 3);
//if ( i < 60 )
if ( i < 120 )
tft.print( i * 1.2,0);
else
tft.print(" dB");
}
tft.setCursor( 96, 1); // Digital display on right side
tft.print("T H D");
tft.setCursor( 96, 23);
tft.print("F R Q");
tft.setCursor( 96, 45);
tft.print("R M S");
}
void Print_Data(void)
{
float frequency = 0.0;
float total_thd = 0.0;
float voltag_ac = 0.0;
avrg_TmrF >>= 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( "...");
}
}