Maiskolben/TFT_ILI9163C/TFT_ILI9163C.cpp

1115 lines
25 KiB
C++

#include "TFT_ILI9163C.h"
#include <limits.h>
#include "pins_arduino.h"
#include "wiring_private.h"
#include <SPI.h>
#if defined(SPI_HAS_TRANSACTION)
static SPISettings ILI9163C_SPI;
#endif
//constructors
#if defined(__MK20DX128__) || defined(__MK20DX256__)
TFT_ILI9163C::TFT_ILI9163C(uint8_t cspin,uint8_t dcpin,uint8_t rstpin,uint8_t mosi,uint8_t sclk) : Adafruit_GFX(_TFTWIDTH,_TFTHEIGHT)
{
_cs = cspin;
_rs = dcpin;
_rst = rstpin;
_mosi = mosi;
_sclk = sclk;
}
#elif defined(__MKL26Z64__)
TFT_ILI9163C::TFT_ILI9163C(uint8_t cspin,uint8_t dcpin,uint8_t rstpin,uint8_t mosi,uint8_t sclk) : Adafruit_GFX(_TFTWIDTH,_TFTHEIGHT)
{
_cs = cspin;
_rs = dcpin;
_rst = rstpin;
_mosi = mosi;
_sclk = sclk;
_useSPI1 = false;
if ((_mosi == 0 || _mosi == 21) && (_sclk == 20)) _useSPI1 = true;
}
#else
TFT_ILI9163C::TFT_ILI9163C(uint8_t cspin,uint8_t dcpin,uint8_t rstpin) : Adafruit_GFX(_TFTWIDTH,_TFTHEIGHT)
{
_cs = cspin;
_rs = dcpin;
_rst = rstpin;
}
#endif
//Arduino Uno, Leonardo, Mega, Teensy 2.0, etc
#if defined(__AVR__)
inline void TFT_ILI9163C::spiwrite(uint8_t c)
{
SPDR = c;
while(!(SPSR & _BV(SPIF)));
}
void TFT_ILI9163C::writecommand(uint8_t c)
{
#if defined(SPI_HAS_TRANSACTION)
SPI.beginTransaction(ILI9163C_SPI);
#endif
*rsport &= ~rspinmask;//low
*csport &= ~cspinmask;//low
spiwrite(c);
*csport |= cspinmask;//hi
#if defined(SPI_HAS_TRANSACTION)
SPI.endTransaction();
#endif
}
void TFT_ILI9163C::writedata(uint8_t c)
{
#if defined(SPI_HAS_TRANSACTION)
SPI.beginTransaction(ILI9163C_SPI);
#endif
*rsport |= rspinmask;//hi
*csport &= ~cspinmask;//low
spiwrite(c);
*csport |= cspinmask;//hi
#if defined(SPI_HAS_TRANSACTION)
SPI.endTransaction();
#endif
}
void TFT_ILI9163C::writedata16(uint16_t d)
{
#if defined(SPI_HAS_TRANSACTION)
SPI.beginTransaction(ILI9163C_SPI);
#endif
*rsport |= rspinmask;//hi
*csport &= ~cspinmask;//low
spiwrite(d >> 8);
spiwrite(d);
*csport |= cspinmask;//hi
#if defined(SPI_HAS_TRANSACTION)
SPI.endTransaction();
#endif
}
void TFT_ILI9163C::setBitrate(uint32_t n)
{
#if !defined (SPI_HAS_TRANSACTION)
if (n >= 8000000) {
SPI.setClockDivider(SPI_CLOCK_DIV2);
} else if (n >= 4000000) {
SPI.setClockDivider(SPI_CLOCK_DIV4);
} else if (n >= 2000000) {
SPI.setClockDivider(SPI_CLOCK_DIV8);
} else {
SPI.setClockDivider(SPI_CLOCK_DIV16);
}
#endif
}
#elif defined(__SAM3X8E__)// Arduino Due
inline void TFT_ILI9163C::spiwrite(uint8_t c)
{
SPI.transfer(c);
}
void TFT_ILI9163C::writecommand(uint8_t c)
{
#if defined(SPI_HAS_TRANSACTION)
SPI.beginTransaction(ILI9163C_SPI);
#endif
rsport->PIO_CODR |= rspinmask;//LO
csport->PIO_CODR |= cspinmask;//LO
spiwrite(c);
csport->PIO_SODR |= cspinmask;//HI
#if defined(SPI_HAS_TRANSACTION)
SPI.endTransaction();
#endif
}
void TFT_ILI9163C::writedata(uint8_t c)
{
#if defined(SPI_HAS_TRANSACTION)
SPI.beginTransaction(ILI9163C_SPI);
#endif
rsport->PIO_SODR |= rspinmask;//HI
csport->PIO_CODR |= cspinmask;//LO
spiwrite(c);
csport->PIO_SODR |= cspinmask;//HI
#if defined(SPI_HAS_TRANSACTION)
SPI.endTransaction();
#endif
}
void TFT_ILI9163C::writedata16(uint16_t d)
{
#if defined(SPI_HAS_TRANSACTION)
SPI.beginTransaction(ILI9163C_SPI);
#endif
rsport->PIO_SODR |= rspinmask;//HI
csport->PIO_CODR |= cspinmask;//LO
spiwrite(d >> 8);
spiwrite(d);
csport->PIO_SODR |= cspinmask;//HI
#if defined(SPI_HAS_TRANSACTION)
SPI.endTransaction();
#endif
}
void TFT_ILI9163C::setBitrate(uint32_t n)
{
#if !defined(SPI_HAS_TRANSACTION)
uint32_t divider = 1;
while (divider < 255) {
if (n >= 84000000 / divider) break;
divider = divider - 1;
}
SPI.setClockDivider(divider);
#endif
}
#elif defined(__MKL26Z64__)//Teensy LC (preliminary
void TFT_ILI9163C::writecommand(uint8_t c)
{
if (_useSPI1){
SPI1.beginTransaction(ILI9163C_SPI);
digitalWriteFast(_rs,LOW);
digitalWriteFast(_cs,LOW);
SPI1.transfer(c);
digitalWriteFast(_cs,HIGH);
SPI1.endTransaction();
} else {
SPI.beginTransaction(ILI9163C_SPI);
digitalWriteFast(_rs,LOW);
digitalWriteFast(_cs,LOW);
SPI.transfer(c);
digitalWriteFast(_cs,HIGH);
SPI.endTransaction();
}
}
void TFT_ILI9163C::writedata(uint8_t c)
{
if (_useSPI1){
SPI1.beginTransaction(ILI9163C_SPI);
digitalWriteFast(_rs,HIGH);
digitalWriteFast(_cs,LOW);
SPI1.transfer(c);
digitalWriteFast(_cs,HIGH);
SPI1.endTransaction();
} else {
SPI.beginTransaction(ILI9163C_SPI);
digitalWriteFast(_rs,HIGH);
digitalWriteFast(_cs,LOW);
SPI.transfer(c);
digitalWriteFast(_cs,HIGH);
SPI.endTransaction();
}
}
void TFT_ILI9163C::writedata16(uint16_t d)
{
if (_useSPI1){
SPI1.beginTransaction(ILI9163C_SPI);
digitalWriteFast(_rs,HIGH);
digitalWriteFast(_cs,LOW);
SPI1.transfer16(d);
digitalWriteFast(_cs,HIGH);
SPI1.endTransaction();
} else {
SPI.beginTransaction(ILI9163C_SPI);
digitalWriteFast(_rs,HIGH);
digitalWriteFast(_cs,LOW);
SPI.transfer16(d);
digitalWriteFast(_cs,HIGH);
SPI.endTransaction();
}
}
void TFT_ILI9163C::setBitrate(uint32_t n)
{
//nop
}
#elif defined(__MK20DX128__) || defined(__MK20DX256__)//Teensy 3.0 & 3.1
void TFT_ILI9163C::setBitrate(uint32_t n)
{
//nop
}
#else
void TFT_ILI9163C::writecommand(uint8_t c)
{
#if defined(SPI_HAS_TRANSACTION)
SPI.beginTransaction(ILI9163C_SPI);
#endif
digitalWrite(_rs,LOW);
digitalWrite(_cs,LOW);
SPI.transfer(c);
digitalWrite(_cs,HIGH);
#if defined(SPI_HAS_TRANSACTION)
SPI.endTransaction();
#endif
}
void TFT_ILI9163C::writedata(uint8_t c)
{
#if defined(SPI_HAS_TRANSACTION)
SPI.beginTransaction(ILI9163C_SPI);
#endif
digitalWrite(_rs,HIGH);
digitalWrite(_cs,LOW);
SPI.transfer(c);
digitalWrite(_cs,HIGH);
#if defined(SPI_HAS_TRANSACTION)
SPI.endTransaction();
#endif
}
void TFT_ILI9163C::writedata16(uint16_t d)
{
#if defined(SPI_HAS_TRANSACTION)
SPI.beginTransaction(ILI9163C_SPI);
#endif
digitalWrite(_rs,HIGH);
digitalWrite(_cs,LOW);
SPI.transfer(d >> 8);
SPI.transfer(d);
digitalWrite(_cs,HIGH);
#if defined(SPI_HAS_TRANSACTION)
SPI.endTransaction();
#endif
}
void TFT_ILI9163C::setBitrate(uint32_t n)
{
//nop
}
#endif //#if defined(TEENSY3.x)
void TFT_ILI9163C::begin(void)
{
sleep = 0;
_initError = 0b00000000;
#if defined(__AVR__)
pinMode(_rs, OUTPUT);
pinMode(_cs, OUTPUT);
csport = portOutputRegister(digitalPinToPort(_cs));
rsport = portOutputRegister(digitalPinToPort(_rs));
cspinmask = digitalPinToBitMask(_cs);
rspinmask = digitalPinToBitMask(_rs);
SPI.begin();
#if !defined(SPI_HAS_TRANSACTION)
SPI.setClockDivider(SPI_CLOCK_DIV2); // 8 MHz
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
#else
ILI9163C_SPI = SPISettings(8000000, MSBFIRST, SPI_MODE0);
#endif
*csport &= ~cspinmask;// toggle CS low so it'll listen to us
#elif defined(__SAM3X8E__)
pinMode(_rs, OUTPUT);
pinMode(_cs, OUTPUT);
csport = digitalPinToPort(_cs);
rsport = digitalPinToPort(_rs);
cspinmask = digitalPinToBitMask(_cs);
rspinmask = digitalPinToBitMask(_rs);
SPI.begin();
#if !defined(SPI_HAS_TRANSACTION)
SPI.setClockDivider(5); // 8 MHz
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
#else
ILI9163C_SPI = SPISettings(24000000, MSBFIRST, SPI_MODE0);
#endif
csport ->PIO_CODR |= cspinmask; // toggle CS low so it'll listen to us
#elif defined(__MKL26Z64__)//Teensy LC (preliminary)
pinMode(_rs, OUTPUT);
pinMode(_cs, OUTPUT);
if (_useSPI1){
if ((_mosi == 0 || _mosi == 21) && (_sclk == 20)) {//identify alternate SPI channel 1 (24Mhz)
ILI9163C_SPI = SPISettings(24000000, MSBFIRST, SPI_MODE0);
SPI1.setMOSI(_mosi);
SPI1.setSCK(_sclk);
SPI1.begin();
_useSPI1 = true; //confirm
} else {
bitSet(_initError,0);
return;
}
if (!SPI.pinIsChipSelect(_cs)) {//ERROR
bitSet(_initError,1);
return;
}
} else {
if ((_mosi == 11 || _mosi == 7) && (_sclk == 13 || _sclk == 14)) {//valid SPI pins?
ILI9163C_SPI = SPISettings(12000000, MSBFIRST, SPI_MODE0);
SPI.setMOSI(_mosi);
SPI.setSCK(_sclk);
SPI.begin();
_useSPI1 = false; //confirm
} else {
bitSet(_initError,0);
return;
}
if (!SPI.pinIsChipSelect(_cs)) {//ERROR
bitSet(_initError,1);
return;
}
}
digitalWriteFast(_cs, LOW);
#elif defined(__MK20DX128__) || defined(__MK20DX256__)
ILI9163C_SPI = SPISettings(30000000, MSBFIRST, SPI_MODE0);
if ((_mosi == 11 || _mosi == 7) && (_sclk == 13 || _sclk == 14)) {
SPI.setMOSI(_mosi);
SPI.setSCK(_sclk);
} else {
bitSet(_initError,0);
return;
}
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;
bitSet(_initError,1);
return;
}
#else//all the rest of possible boards
pinMode(_rs, OUTPUT);
pinMode(_cs, OUTPUT);
SPI.begin();
#if !defined(SPI_HAS_TRANSACTION)
SPI.setClockDivider(4);
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
#else
ILI9163C_SPI = SPISettings(8000000, MSBFIRST, SPI_MODE0);
#endif
digitalWrite(_cs, LOW);
#endif
if (_rst != 255) {
pinMode(_rst, OUTPUT);
digitalWrite(_rst, HIGH);
delay(500);
digitalWrite(_rst, LOW);
delay(500);
digitalWrite(_rst, HIGH);
delay(500);
}
/*
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();
}
uint8_t TFT_ILI9163C::errorCode(void)
{
return _initError;
}
void TFT_ILI9163C::chipInit() {
uint8_t i;
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(ILI9163C_SPI);
writecommand_cont(CMD_SWRESET);//software reset
delay(500);
writecommand_cont(CMD_SLPOUT);//exit sleep
delay(5);
writecommand_cont(CMD_PIXFMT);//Set Color Format 16bit
writedata8_cont(0x05);
delay(5);
writecommand_cont(CMD_GAMMASET);//default gamma curve 3
writedata8_cont(0x08);//0x04
delay(1);
writecommand_cont(CMD_GAMRSEL);//Enable Gamma adj
writedata8_cont(0x01);
delay(1);
writecommand_cont(CMD_NORML);
writecommand_cont(CMD_DFUNCTR);
writedata8_cont(0b11111111);//
writedata8_cont(0b00000110);//
writecommand_cont(CMD_PGAMMAC);//Positive Gamma Correction Setting
for (i=0;i<15;i++){
writedata8_cont(pGammaSet[i]);
}
writecommand_cont(CMD_NGAMMAC);//Negative Gamma Correction Setting
for (i=0;i<15;i++){
writedata8_cont(nGammaSet[i]);
}
writecommand_cont(CMD_FRMCTR1);//Frame Rate Control (In normal mode/Full colors)
writedata8_cont(0x08);//0x0C//0x08
writedata8_cont(0x02);//0x14//0x08
delay(1);
writecommand_cont(CMD_DINVCTR);//display inversion
writedata8_cont(0x07);
delay(1);
writecommand_cont(CMD_PWCTR1);//Set VRH1[4:0] & VC[2:0] for VCI1 & GVDD
writedata8_cont(0x0A);//4.30 - 0x0A
writedata8_cont(0x02);//0x05
delay(1);
writecommand_cont(CMD_PWCTR2);//Set BT[2:0] for AVDD & VCL & VGH & VGL
writedata8_cont(0x02);
delay(1);
writecommand_cont(CMD_VCOMCTR1);//Set VMH[6:0] & VML[6:0] for VOMH & VCOML
writedata8_cont(0x50);//0x50
writedata8_cont(99);//0x5b
delay(1);
writecommand_cont(CMD_VCOMOFFS);
writedata8_cont(0);//0x40
delay(1);
writecommand_cont(CMD_CLMADRS);//Set Column Address
writedata16_cont(0x00);
writedata16_cont(_GRAMWIDTH);
writecommand_cont(CMD_PGEADRS);//Set Page Address
writedata16_cont(0x00);
writedata16_cont(_GRAMHEIGH);
// set scroll area (thanks Masuda)
writecommand_cont(CMD_VSCLLDEF);
writedata16_cont(__OFFSET);
writedata16_cont(_GRAMHEIGH - __OFFSET);
writedata16_last(0);
SPI.endTransaction();
colorSpace(_colorspaceData);
setRotation(0);
SPI.beginTransaction(ILI9163C_SPI);
writecommand_cont(CMD_DISPON);//display ON
delay(1);
writecommand_last(CMD_RAMWR);//Memory Write
SPI.endTransaction();
delay(1);
#else
writecommand(CMD_SWRESET);//software reset
delay(500);
writecommand(CMD_SLPOUT);//exit sleep
delay(5);
writecommand(CMD_PIXFMT);//Set Color Format 16bit
writedata(0x05);
delay(5);
writecommand(CMD_GAMMASET);//default gamma curve 3
writedata(0x04);//0x04
delay(1);
writecommand(CMD_GAMRSEL);//Enable Gamma adj
writedata(0x01);
delay(1);
writecommand(CMD_NORML);
writecommand(CMD_DFUNCTR);
writedata(0b11111111);//
writedata(0b00000110);//
writecommand(CMD_PGAMMAC);//Positive Gamma Correction Setting
for (i=0;i<15;i++){
writedata(pGammaSet[i]);
}
writecommand(CMD_NGAMMAC);//Negative Gamma Correction Setting
for (i=0;i<15;i++){
writedata(nGammaSet[i]);
}
writecommand(CMD_FRMCTR1);//Frame Rate Control (In normal mode/Full colors)
writedata(0x08);//0x0C//0x08
writedata(0x02);//0x14//0x08
delay(1);
writecommand(CMD_DINVCTR);//display inversion
writedata(0x07);
delay(1);
writecommand(CMD_PWCTR1);//Set VRH1[4:0] & VC[2:0] for VCI1 & GVDD
writedata(0x0A);//4.30 - 0x0A
writedata(0x02);//0x05
delay(1);
writecommand(CMD_PWCTR2);//Set BT[2:0] for AVDD & VCL & VGH & VGL
writedata(0x02);
delay(1);
writecommand(CMD_VCOMCTR1);//Set VMH[6:0] & VML[6:0] for VOMH & VCOML
writedata(0x50);//0x50
writedata(99);//0x5b
delay(1);
writecommand(CMD_VCOMOFFS);
writedata(0);//0x40
delay(1);
writecommand(CMD_CLMADRS);//Set Column Address
writedata16(0x00);
writedata16(_GRAMWIDTH);
writecommand(CMD_PGEADRS);//Set Page Address
writedata16(0X00);
writedata16(_GRAMHEIGH);
// set scroll area (thanks Masuda)
writecommand(CMD_VSCLLDEF);
writedata16(__OFFSET);
writedata16(_GRAMHEIGH - __OFFSET);
writedata16(0);
colorSpace(_colorspaceData);
setRotation(0);
writecommand(CMD_DISPON);//display ON
delay(1);
writecommand(CMD_RAMWR);//Memory Write
delay(1);
#endif
fillScreen(BLACK);
}
/*
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(ILI9163C_SPI);
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(ILI9163C_SPI);
writecommand_last(CMD_DISPON);
SPI.endTransaction();
#else
writecommand(CMD_DISPON);
#endif
} else {
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(ILI9163C_SPI);
writecommand_last(CMD_DISPOFF);
SPI.endTransaction();
#else
writecommand(CMD_DISPOFF);
#endif
}
}
void TFT_ILI9163C::idleMode(boolean onOff) {
if (onOff){
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(ILI9163C_SPI);
writecommand_last(CMD_IDLEON);
SPI.endTransaction();
#else
writecommand(CMD_IDLEON);
#endif
} else {
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(ILI9163C_SPI);
writecommand_last(CMD_IDLEOF);
SPI.endTransaction();
#else
writecommand(CMD_IDLEOF);
#endif
}
}
void TFT_ILI9163C::sleepMode(boolean mode) {
if (mode){
if (sleep == 1) return;//already sleeping
sleep = 1;
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(ILI9163C_SPI);
writecommand_last(CMD_SLPIN);
SPI.endTransaction();
#else
writecommand(CMD_SLPIN);
#endif
delay(5);//needed
} else {
if (sleep == 0) return; //Already awake
sleep = 0;
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(ILI9163C_SPI);
writecommand_last(CMD_SLPOUT);
SPI.endTransaction();
#else
writecommand(CMD_SLPOUT);
#endif
delay(120);//needed
}
}
void TFT_ILI9163C::defineScrollArea(uint16_t tfa, uint16_t bfa){
tfa += __OFFSET;
int16_t vsa = _GRAMHEIGH - tfa - bfa;
if (vsa >= 0) {
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(ILI9163C_SPI);
writecommand_cont(CMD_VSCLLDEF);
writedata16_cont(tfa);
writedata16_cont(vsa);
writedata16_last(bfa);
SPI.endTransaction();
#else
writecommand(CMD_VSCLLDEF);
writedata16(tfa);
writedata16(vsa);
writedata16(bfa);
#endif
}
}
void TFT_ILI9163C::scroll(uint16_t adrs) {
if (adrs <= _GRAMHEIGH) {
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(ILI9163C_SPI);
writecommand_cont(CMD_VSSTADRS);
writedata16_last(adrs + __OFFSET);
SPI.endTransaction();
#else
writecommand(CMD_VSSTADRS);
writedata16(adrs + __OFFSET);
#endif
}
}
//corrected! v3
void TFT_ILI9163C::clearScreen(uint16_t color) {
int px;
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(ILI9163C_SPI);
_setAddrWindow(0x00,0x00,_GRAMWIDTH,_GRAMHEIGH);
for (px = 0;px < _GRAMSIZE; px++){
writedata16_cont(color);
}
writecommand_last(CMD_NOP);
SPI.endTransaction();
#else
setAddr(0x00,0x00,_GRAMWIDTH,_GRAMHEIGH);//go home
for (px = 0;px < _GRAMSIZE; px++){
writedata16(color);
}
#endif
}
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);
SPI.endTransaction();
#endif
}
void TFT_ILI9163C::pushColor(uint16_t color) {
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(ILI9163C_SPI);
writedata16_last(color);
SPI.endTransaction();
#else
writedata16(color);
#endif
}
void TFT_ILI9163C::writeScreen24(const uint32_t *bitmap,uint16_t size) {
uint16_t color;
uint16_t px;
#if defined(__MK20DX128__) || defined(__MK20DX256__)
writecommand_cont(CMD_RAMWR);
for (px = 0;px < size; px++){//16384
color = Color24To565(bitmap[px]);
writedata16_cont(color);
}
_setAddrWindow(0x00,0x00,_GRAMWIDTH,_GRAMHEIGH);//home
SPI.endTransaction();
#else
writecommand(CMD_RAMWR);
for (px = 0;px < size; px++){
color = Color24To565(bitmap[px]);
writedata16(color);
}
homeAddress();
#endif
}
void TFT_ILI9163C::homeAddress() {
setAddrWindow(0x00,0x00,_GRAMWIDTH,_GRAMHEIGH);
}
void TFT_ILI9163C::setCursor(int16_t x, int16_t y) {
if (boundaryCheck(x,y)) return;
setAddrWindow(0x00,0x00,x,y);
cursor_x = x;
cursor_y = y;
}
void TFT_ILI9163C::drawPixel(int16_t x, int16_t y, uint16_t color) {
if (boundaryCheck(x,y)) return;
if ((x < 0) || (y < 0)) return;
setAddr(x,y,x+1,y+1);
#if defined(__MK20DX128__) || defined(__MK20DX256__)
writedata16_last(color);
SPI.endTransaction();
#else
writedata16(color);
#endif
}
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;
setAddr(x,y,x,(y+h)-1);
while (h-- > 0) {
#if defined(__MK20DX128__) || defined(__MK20DX256__)
if (h == 0){
writedata16_last(color);
} else {
writedata16_cont(color);
}
#else
writedata16(color);
#endif
}
#if defined(SPI_HAS_TRANSACTION)
SPI.endTransaction();
#endif
}
bool TFT_ILI9163C::boundaryCheck(int16_t x,int16_t y){
if ((x >= _width) || (y >= _height)) return true;
return false;
}
void TFT_ILI9163C::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) {
// Rudimentary clipping
if (boundaryCheck(x,y)) return;
if (((x+w) - 1) >= _width) w = _width-x;
setAddr(x,y,(x+w)-1,y);
while (w-- > 0) {
#if defined(__MK20DX128__) || defined(__MK20DX256__)
if (w == 0){
writedata16_last(color);
} else {
writedata16_cont(color);
}
#else
writedata16(color);
#endif
}
#if defined(SPI_HAS_TRANSACTION)
SPI.endTransaction();
#endif
}
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;
if (((x + w) - 1) >= _width) w = _width - x;
if (((y + h) - 1) >= _height) h = _height - y;
setAddr(x,y,(x+w)-1,(y+h)-1);
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);
#else
writedata16(color);
#endif
}
#if defined(SPI_HAS_TRANSACTION)
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(ILI9163C_SPI);
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(ILI9163C_SPI);
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::setAddr(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1){
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(ILI9163C_SPI);
_setAddrWindow(x0,y0,x1,y1);
#else
setAddrWindow(x0,y0,x1,y1);
#endif
}
void TFT_ILI9163C::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(ILI9163C_SPI);
_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
void TFT_ILI9163C::setRotation(uint8_t m) {
rotation = m % 4; // can't be higher than 3
switch (rotation) {
case 0:
_Mactrl_Data = 0b00001000;
_width = _TFTWIDTH;
_height = _TFTHEIGHT;//-__OFFSET;
break;
case 1:
_Mactrl_Data = 0b01101000;
_width = _TFTHEIGHT;//-__OFFSET;
_height = _TFTWIDTH;
break;
case 2:
_Mactrl_Data = 0b11001000;
_width = _TFTWIDTH;
_height = _TFTHEIGHT;//-__OFFSET;
break;
case 3:
_Mactrl_Data = 0b10101000;
_width = _TFTWIDTH;
_height = _TFTHEIGHT;//-__OFFSET;
break;
}
colorSpace(_colorspaceData);
#if defined(__MK20DX128__) || defined(__MK20DX256__)
SPI.beginTransaction(ILI9163C_SPI);
writecommand_cont(CMD_MADCTL);
writedata8_last(_Mactrl_Data);
SPI.endTransaction();
#else
writecommand(CMD_MADCTL);
writedata(_Mactrl_Data);
#endif
}