TFT_ILI9163C/TFT_ILI9163C.cpp

863 lines
21 KiB
C++
Raw Normal View History

#include "TFT_ILI9163C.h"
#include <limits.h>
#include "pins_arduino.h"
#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
}
TFT_ILI9163C::TFT_ILI9163C(uint8_t CS, uint8_t DC) : Adafruit_GFX(_TFTWIDTH, _TFTHEIGHT) {
_cs = CS;
_rs = DC;
_rst = 0;
#if defined(__MK20DX128__) || defined(__MK20DX256__)
#else
_sid = _sclk = 0;
#endif
}
//Arduino Uno, Leonardo, Mega, Teensy 2.0, etc
#ifdef __AVR__
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
void TFT_ILI9163C::setBitrate(uint32_t n){
//nop
}
#endif //#if defined(TEENSY3.x)
void TFT_ILI9163C::begin(void) {
sleep = 0;
#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_DIV2); // 8 MHz
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(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__)
SPI.begin();
if (SPI.pinIsChipSelect(_cs, _rs)) {
pcs_data = SPI.setCS(_cs);
pcs_command = pcs_data | SPI.setCS(_rs);
} else {
pcs_data = 0;
pcs_command = 0;
return;
}
#endif
if (_rst != 0) {
pinMode(_rst, OUTPUT);
digitalWrite(_rst, HIGH);
delay(500);
digitalWrite(_rst, LOW);
delay(500);
digitalWrite(_rst, HIGH);
delay(500);
}
2014-05-24 22:01:05 +00:00
/*
7) MY: 1(bottom to top), 0(top to bottom) Row Address Order
6) MX: 1(R to L), 0(L to R) Column Address Order
5) MV: 1(Exchanged), 0(normal) Row/Column exchange
4) ML: 1(bottom to top), 0(top to bottom) Vertical Refresh Order
3) RGB: 1(BGR), 0(RGB) Color Space
2) MH: 1(R to L), 0(L to R) Horizontal Refresh Order
1)
0)
MY, MX, MV, ML,RGB, MH, D1, D0
0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 //normal
1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 //Y-Mirror
0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 //X-Mirror
1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 //X-Y-Mirror
0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 //X-Y Exchange
1 | 0 | 1 | 0 | 1 | 0 | 0 | 0 //X-Y Exchange, Y-Mirror
0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 //XY exchange
1 | 1 | 1 | 0 | 1 | 0 | 0 | 0
*/
_Mactrl_Data = 0b00000000;
_colorspaceData = __COLORSPC;//start with default data;
chipInit();
}
void TFT_ILI9163C::chipInit() {
2015-02-28 03:13:38 +00:00
uint8_t i;
#if defined(__GAMMASET1)
const uint8_t pGammaSet[15]= {0x36,0x29,0x12,0x22,0x1C,0x15,0x42,0xB7,0x2F,0x13,0x12,0x0A,0x11,0x0B,0x06};
const uint8_t nGammaSet[15]= {0x09,0x16,0x2D,0x0D,0x13,0x15,0x40,0x48,0x53,0x0C,0x1D,0x25,0x2E,0x34,0x39};
2015-02-28 03:13:38 +00:00
#elif defined(__GAMMASET2)
const uint8_t pGammaSet[15]= {0x3F,0x21,0x12,0x22,0x1C,0x15,0x42,0xB7,0x2F,0x13,0x02,0x0A,0x01,0x00,0x00};
const uint8_t nGammaSet[15]= {0x09,0x18,0x2D,0x0D,0x13,0x15,0x40,0x48,0x53,0x0C,0x1D,0x25,0x2E,0x24,0x29};
#elif defined(__GAMMASET3)
const uint8_t pGammaSet[15]= {0x3F,0x26,0x23,0x30,0x28,0x10,0x55,0xB7,0x40,0x19,0x10,0x1E,0x02,0x01,0x00};
//&const uint8_t nGammaSet[15]= {0x00,0x19,0x1C,0x0F,0x14,0x0F,0x2A,0x48,0x3F,0x06,0x1D,0x21,0x3D,0x3F,0x3F};
const uint8_t nGammaSet[15]= {0x09,0x18,0x2D,0x0D,0x13,0x15,0x40,0x48,0x53,0x0C,0x1D,0x25,0x2E,0x24,0x29};
#else
const uint8_t pGammaSet[15]= {0x3F,0x25,0x1C,0x1E,0x20,0x12,0x2A,0x90,0x24,0x11,0x00,0x00,0x00,0x00,0x00};
const uint8_t nGammaSet[15]= {0x20,0x20,0x20,0x20,0x05,0x15,0x00,0xA7,0x3D,0x18,0x25,0x2A,0x2B,0x2B,0x3A};
#endif
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
writecommand_cont(CMD_SWRESET);//software reset
delay(500);
writecommand_cont(CMD_SLPOUT);//exit sleep
delay(5);
writecommand_cont(CMD_PIXFMT);//Set Color Format 16bit
writedata8_cont(0x05);
delay(5);
writecommand_cont(CMD_GAMMASET);//default gamma curve 3
2015-02-28 03:13:38 +00:00
writedata8_cont(0x08);//0x04
delay(1);
writecommand_cont(CMD_GAMRSEL);//Enable Gamma adj
writedata8_cont(0x01);
delay(1);
writecommand_cont(CMD_NORML);
2015-02-28 03:13:38 +00:00
writecommand_cont(CMD_DFUNCTR);
writedata8_cont(0b11111111);//
writedata8_cont(0b00000110);//
writecommand_cont(CMD_PGAMMAC);//Positive Gamma Correction Setting
2015-02-28 03:13:38 +00:00
for (i=0;i<15;i++){
writedata8_cont(pGammaSet[i]);
}
writecommand_cont(CMD_NGAMMAC);//Negative Gamma Correction Setting
2015-02-28 03:13:38 +00:00
for (i=0;i<15;i++){
writedata8_cont(nGammaSet[i]);
}
writecommand_cont(CMD_FRMCTR1);//Frame Rate Control (In normal mode/Full colors)
writedata8_cont(0x08);//0x0C//0x08
writedata8_cont(0x02);//0x14//0x08
delay(1);
writecommand_cont(CMD_DINVCTR);//display inversion
writedata8_cont(0x07);
delay(1);
writecommand_cont(CMD_PWCTR1);//Set VRH1[4:0] & VC[2:0] for VCI1 & GVDD
writedata8_cont(0x0A);//4.30 - 0x0A
writedata8_cont(0x02);//0x05
delay(1);
writecommand_cont(CMD_PWCTR2);//Set BT[2:0] for AVDD & VCL & VGH & VGL
writedata8_cont(0x02);
delay(1);
writecommand_cont(CMD_VCOMCTR1);//Set VMH[6:0] & VML[6:0] for VOMH & VCOML
writedata8_cont(0x50);//0x50
writedata8_cont(99);//0x5b
delay(1);
writecommand_cont(CMD_VCOMOFFS);
writedata8_cont(0);//0x40
delay(1);
writecommand_cont(CMD_CLMADRS);//Set Column Address
/*
writedata8_cont(0x00);
writedata8_cont(0X00);
writedata8_cont(0X00);
writedata8_cont(_GRAMWIDTH);
*/
writedata16_cont(0x00);
writedata16_cont(_GRAMWIDTH);
writecommand_cont(CMD_PGEADRS);//Set Page Address
/*
writedata8_cont(0x00);
writedata8_cont(0X00);
writedata8_cont(0X00);
writedata8_last(_GRAMHEIGH);
*/
writedata16_cont(0x00);
writedata16_last(_GRAMHEIGH);
2015-03-02 22:59:42 +00:00
endProc();
colorSpace(_colorspaceData);
setRotation(0);
SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
writecommand_cont(CMD_DISPON);//display ON
delay(1);
writecommand_last(CMD_RAMWR);//Memory Write
SPI.endTransaction();
delay(1);
#else
writecommand(CMD_SWRESET);//software reset
delay(500);
writecommand(CMD_SLPOUT);//exit sleep
2014-05-24 22:01:05 +00:00
delay(5);
writecommand(CMD_PIXFMT);//Set Color Format 16bit
writedata(0x05);
2014-05-24 22:01:05 +00:00
delay(5);
writecommand(CMD_GAMMASET);//default gamma curve 3
writedata(0x04);//0x04
2014-05-24 22:01:05 +00:00
delay(1);
writecommand(CMD_GAMRSEL);//Enable Gamma adj
writedata(0x01);
2014-05-24 22:01:05 +00:00
delay(1);
writecommand(CMD_NORML);
2014-05-24 22:01:05 +00:00
writecommand(CMD_DFUNCTR);
writedata(0b11111111);//
writedata(0b00000110);//
writecommand(CMD_PGAMMAC);//Positive Gamma Correction Setting
2015-02-28 03:13:38 +00:00
for (i=0;i<15;i++){
writedata(pGammaSet[i]);
}
writecommand(CMD_NGAMMAC);//Negative Gamma Correction Setting
2015-02-28 03:13:38 +00:00
for (i=0;i<15;i++){
writedata(nGammaSet[i]);
}
writecommand(CMD_FRMCTR1);//Frame Rate Control (In normal mode/Full colors)
writedata(0x08);//0x0C//0x08
writedata(0x02);//0x14//0x08
2014-05-24 22:01:05 +00:00
delay(1);
writecommand(CMD_DINVCTR);//display inversion
writedata(0x07);
2014-05-24 22:01:05 +00:00
delay(1);
writecommand(CMD_PWCTR1);//Set VRH1[4:0] & VC[2:0] for VCI1 & GVDD
writedata(0x0A);//4.30 - 0x0A
writedata(0x02);//0x05
2014-05-24 22:01:05 +00:00
delay(1);
writecommand(CMD_PWCTR2);//Set BT[2:0] for AVDD & VCL & VGH & VGL
writedata(0x02);
2014-05-24 22:01:05 +00:00
delay(1);
writecommand(CMD_VCOMCTR1);//Set VMH[6:0] & VML[6:0] for VOMH & VCOML
writedata(0x50);//0x50
writedata(99);//0x5b
2014-05-24 22:01:05 +00:00
delay(1);
writecommand(CMD_VCOMOFFS);
writedata(0);//0x40
2014-05-24 22:01:05 +00:00
delay(1);
writecommand(CMD_CLMADRS);//Set Column Address
//writedata(0x00);
//writedata(0X00);
//writedata(0X00);
//writedata(_GRAMWIDTH);
writedata16(0x00);
writedata16(_GRAMWIDTH);
writecommand(CMD_PGEADRS);//Set Page Address
//writedata(0x00);
//writedata(0X00);
//writedata(0X00);
//writedata(_GRAMHEIGH);
writedata16(0X00);
2015-03-02 22:59:42 +00:00
writedata16(_GRAMHEIGH);
2014-05-24 00:21:14 +00:00
2014-05-24 22:01:05 +00:00
colorSpace(_colorspaceData);
setRotation(0);
writecommand(CMD_DISPON);//display ON
2014-05-24 22:01:05 +00:00
delay(1);
writecommand(CMD_RAMWR);//Memory Write
2014-05-24 22:01:05 +00:00
delay(1);
#endif
fillScreen(BLACK);
2014-05-24 22:01:05 +00:00
}
/*
Colorspace selection:
0: RGB
1: GBR
*/
void TFT_ILI9163C::colorSpace(uint8_t cspace) {
if (cspace < 1){
bitClear(_Mactrl_Data,3);
} else {
bitSet(_Mactrl_Data,3);
}
}
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
}
void TFT_ILI9163C::display(boolean onOff) {
if (onOff){
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
writecommand_last(CMD_DISPON);
endProc();
#else
writecommand(CMD_DISPON);
#endif
} else {
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
writecommand_last(CMD_DISPOFF);
endProc();
#else
writecommand(CMD_DISPOFF);
#endif
}
}
void TFT_ILI9163C::sleepMode(boolean mode) {
if (mode){
if (sleep == 1) return;//already sleeping
sleep = 1;
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
writecommand_last(CMD_SLPIN);
endProc();
#else
writecommand(CMD_SLPIN);
#endif
delay(5);//needed
} else {
if (sleep == 0) return; //Already awake
sleep = 0;
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
writecommand_last(CMD_SLPOUT);
endProc();
#else
writecommand(CMD_SLPOUT);
#endif
delay(120);//needed
}
}
/*
void TFT_ILI9163C::defineScrollArea(uint16_t a,uint16_t c){
//0,2
uint16_t b;
if ((a+c) > _TFTWIDTH) return;
b = (_TFTWIDTH - (a+c));
SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
writecommand_cont(0x33);
if (rotation == 0 || rotation > 1){
writedata16_cont(a);
writedata16_cont(b);
writedata16_last(c);
} else {
writedata16_cont(a + __OFFSET);
writedata16_cont(b + __OFFSET);
writedata16_last(c + __OFFSET);
}
endProc();
setAddr(0x00,0x00,_GRAMWIDTH-1,_GRAMHEIGH-1);
setRotation(0);
}
*/
void TFT_ILI9163C::scroll(uint16_t adrs) {
2015-03-02 22:59:42 +00:00
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
writecommand_cont(CMD_VSSTADRS);
writedata16_last(adrs);
endProc();
#else
writecommand(CMD_VSSTADRS);
writedata16(adrs);
#endif
}
//corrected!
void TFT_ILI9163C::clearScreen(uint16_t color) {
2015-02-28 23:03:23 +00:00
int px;
#if defined(__MK20DX128__) || defined(__MK20DX256__)
2015-03-02 23:12:48 +00:00
//SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
setAddr(0x00,0x00,_GRAMWIDTH,_GRAMHEIGH);//go home
//writecommand_cont(CMD_RAMWR);//this was missed!
for (px = 0;px < _GRAMSIZE; px++){
writedata16_cont(color);
}
_setAddrWindow(0x00,0x00,_GRAMWIDTH,_GRAMHEIGH);//go home
writecommand_last(CMD_NOP);
2015-02-28 23:03:23 +00:00
endProc();
#else
2015-03-02 23:12:48 +00:00
setAddr(0x00,0x00,_GRAMWIDTH,_GRAMHEIGH);//go home
//writecommand(CMD_RAMWR);
2015-02-28 23:03:23 +00:00
for (px = 0;px < _GRAMSIZE; px++){
writedata16(color);
}
2015-03-02 23:12:48 +00:00
#endif
}
2015-03-02 22:59:42 +00:00
void TFT_ILI9163C::startPushData(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
setAddr(x0,y0,x1,y1);
}
void TFT_ILI9163C::pushData(uint16_t color) {
#if defined(__MK20DX128__) || defined(__MK20DX256__)
writedata16_cont(color);
#else
writedata16(color);
#endif
}
void TFT_ILI9163C::endPushData() {
#if defined(__MK20DX128__) || defined(__MK20DX256__)
writecommand_last(CMD_NOP);
endProc();
#endif
}
void TFT_ILI9163C::pushColor(uint16_t color) {
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
writedata16_last(color);
endProc();
#else
writedata16(color);
#endif
}
void TFT_ILI9163C::writeScreen24(const uint32_t *bitmap,uint16_t size) {
2015-02-28 03:13:38 +00:00
uint16_t color;
2015-02-28 23:03:23 +00:00
int px;
2015-02-28 03:13:38 +00:00
#if defined(__MK20DX128__) || defined(__MK20DX256__)
writecommand_cont(CMD_RAMWR);
2015-03-02 22:59:42 +00:00
for (px = 0;px < size; px++){//16384
2015-02-28 03:13:38 +00:00
color = Color24To565(bitmap[px]);
writedata16_cont(color);
}
2015-03-02 22:59:42 +00:00
_setAddrWindow(0x00,0x00,_GRAMWIDTH,_GRAMHEIGH);//home
2015-02-28 23:03:23 +00:00
endProc();
2015-02-28 03:13:38 +00:00
#else
writecommand(CMD_RAMWR);
2015-03-02 22:59:42 +00:00
for (px = 0;px < size; px++){
color = Color24To565(bitmap[px]);
writedata16(color);
}
2015-03-02 22:59:42 +00:00
homeAddress();
2015-02-28 03:13:38 +00:00
#endif
}
void TFT_ILI9163C::homeAddress() {
//setAddrWindow(0x00,0x00,_GRAMWIDTH-1,_GRAMHEIGH-1);
setAddrWindow(0x00,0x00,_GRAMWIDTH,_GRAMHEIGH);
}
2014-05-25 02:51:48 +00:00
void TFT_ILI9163C::setCursor(int16_t x, int16_t y) {
2014-05-25 02:51:48 +00:00
if (boundaryCheck(x,y)) return;
setAddrWindow(0x00,0x00,x,y);
cursor_x = x;
cursor_y = y;
}
2015-03-02 22:59:42 +00:00
void TFT_ILI9163C::drawPixel(int16_t x, int16_t y, uint16_t color) {
if (boundaryCheck(x,y)) return;
if ((x < 0) || (y < 0)) return;
2015-02-28 23:03:23 +00:00
setAddr(x,y,x+1,y+1);
#if defined(__MK20DX128__) || defined(__MK20DX256__)
writedata16_last(color);
2015-02-28 23:03:23 +00:00
endProc();
#else
writedata16(color);
#endif
2015-02-28 23:03:23 +00:00
}
void TFT_ILI9163C::setAddr(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1){
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
_setAddrWindow(x0,y0,x1,y1);
#else
setAddrWindow(x0,y0,x1,y1);
#endif
}
void TFT_ILI9163C::endProc(void){
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.endTransaction();
#endif
}
void TFT_ILI9163C::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) {
// Rudimentary clipping
if (boundaryCheck(x,y)) return;
2014-05-24 22:01:05 +00:00
if (((y + h) - 1) >= _height) h = _height-y;
2015-02-28 23:03:23 +00:00
setAddr(x,y,x,(y+h)-1);
while (h-- > 1) {
#if defined(__MK20DX128__) || defined(__MK20DX256__)
if (h == 0){
writedata16_last(color);
} else {
writedata16_cont(color);
}
#else
writedata16(color);
#endif
}
2015-02-28 23:03:23 +00:00
endProc();
}
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;
2014-05-24 22:01:05 +00:00
if (((x+w) - 1) >= _width) w = _width-x;
2015-02-28 23:03:23 +00:00
setAddr(x,y,(x+w)-1,y);
while (w-- > 1) {
#if defined(__MK20DX128__) || defined(__MK20DX256__)
if (w == 0){
writedata16_last(color);
} else {
writedata16_cont(color);
}
#else
writedata16(color);
#endif
}
2015-02-28 23:03:23 +00:00
endProc();
}
void TFT_ILI9163C::fillScreen(uint16_t color) {
clearScreen(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;
2014-05-24 22:01:05 +00:00
if (((x + w) - 1) >= _width) w = _width - x;
if (((y + h) - 1) >= _height) h = _height - y;
2015-02-28 23:03:23 +00:00
setAddr(x,y,(x+w)-1,(y+h)-1);
2014-05-24 22:01:05 +00:00
for (y = h;y > 0;y--) {
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
}
2015-02-28 23:03:23 +00:00
endProc();
}
#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
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));
2015-02-28 23:03:23 +00:00
_setAddrWindow(x0,y0,x1,y1);
SPI.endTransaction();
#else
writecommand(CMD_CLMADRS); // Column
if (rotation == 0 || rotation > 1){
writedata16(x0);
writedata16(x1);
} else {
writedata16(x0 + __OFFSET);
writedata16(x1 + __OFFSET);
}
writecommand(CMD_PGEADRS); // Page
if (rotation == 0){
writedata16(y0 + __OFFSET);
writedata16(y1 + __OFFSET);
} 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 || rotation > 1){
writedata16_cont(x0);
writedata16_cont(x1);
} else {
writedata16_cont(x0 + __OFFSET);
writedata16_cont(x1 + __OFFSET);
}
writecommand_cont(CMD_PGEADRS); // Page
if (rotation == 0){
writedata16_cont(y0 + __OFFSET);
writedata16_cont(y1 + __OFFSET);
} else {
writedata16_cont(y0);
writedata16_cont(y1);
}
writecommand_cont(CMD_RAMWR); //Into RAM
}
#endif
2014-05-24 22:01:05 +00:00
void TFT_ILI9163C::setRotation(uint8_t m) {
rotation = m % 4; // can't be higher than 3
switch (rotation) {
case 0:
2014-05-24 22:01:05 +00:00
_Mactrl_Data = 0b00001000;
_width = _TFTWIDTH;
_height = _TFTHEIGHT;//-__OFFSET;
break;
case 1:
2014-05-24 22:01:05 +00:00
_Mactrl_Data = 0b01101000;
_width = _TFTHEIGHT;//-__OFFSET;
_height = _TFTWIDTH;
break;
case 2:
2014-05-24 22:01:05 +00:00
_Mactrl_Data = 0b11001000;
_width = _TFTWIDTH;
_height = _TFTHEIGHT;//-__OFFSET;
break;
case 3:
2014-05-24 22:01:05 +00:00
_Mactrl_Data = 0b10101000;
_width = _TFTWIDTH;
_height = _TFTHEIGHT;//-__OFFSET;
break;
}
2014-05-24 22:01:05 +00:00
colorSpace(_colorspaceData);
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
writecommand_cont(CMD_MADCTL);
writedata8_last(_Mactrl_Data);
2015-03-02 22:59:42 +00:00
endProc();
#else
writecommand(CMD_MADCTL);
writedata(_Mactrl_Data);
#endif
}