Library to support using the 2.8" TFT Touch Shield v1.0 - made by Seeed Studio - for Arduino This shield uses either the SPFD5408A or ST7781R display chip.
tft.cpp
- Committer:
- tj4shee
- Date:
- 2015-02-05
- Revision:
- 0:93976d4026d3
File content as of revision 0:93976d4026d3:
/* SPFD5408A or ST7781R TFT Library. 2015 Copyright (c) Bluegrass Digital Inc. Authors: TJ Forshee (with initializtion code from TFT vendor) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "tft.h" BusInOut lcd_data(D2, D3, D4, D5, D6, D7, D8, D9); DigitalOut CS_BIT(D10); DigitalOut RS_BIT(D11); DigitalOut WR_BIT(D12); DigitalOut RD_BIT(D13); void TFT::pushData(unsigned char data) { //lcd_data.output(); lcd_data.write(data); } unsigned char TFT::getData(void) { //unsigned char data=0; //delay(1); // data |= ((PIND&0xfc)>>2); // data |= ((PINB&0x03)<<6); wait(0.001); //lcd_data.input(); // ??????????? will this clear the inputs ? return lcd_data.read(); } void TFT::sendCommand(unsigned int index) { CS_LOW(); RS_LOW(); RD_HIGH(); WR_HIGH(); WR_LOW(); pushData(0); WR_HIGH(); WR_LOW(); pushData(index&0xff); WR_HIGH(); CS_HIGH(); } void TFT::sendData(unsigned int data) { CS_LOW(); RS_HIGH(); RD_HIGH(); WR_LOW(); pushData((data&0xff00)>>8); WR_HIGH(); WR_LOW(); pushData(data&0xff); WR_HIGH(); CS_HIGH(); } unsigned int TFT::readRegister(unsigned int index) { unsigned int data=0; CS_LOW(); RS_LOW(); RD_HIGH(); all_pin_output(); WR_LOW(); pushData(0); WR_HIGH(); WR_LOW(); pushData(index); WR_HIGH(); all_pin_input(); all_pin_low(); RS_HIGH(); RD_LOW(); data |= getData()<<8; RD_HIGH(); RD_LOW(); data |= getData(); RD_HIGH(); CS_HIGH(); all_pin_output(); return data; } void TFT::init (void) { //CS_OUTPUT; CS_HIGH(); //RD_OUTPUT; //WR_OUTPUT; //RS_OUTPUT; Tft.all_pin_output(); Tft.all_pin_low(); wait(0.1); IC_CODE = readRegister(0x0); if(IC_CODE == 0x5408) { sendCommand(0x0000); sendData(0x0001); wait(0.1); sendCommand(0x0001); sendData(0x0000); sendCommand(0x0002); sendData(0x0700); sendCommand(0x0003); sendData(0x1030); sendCommand(0x0004); sendData(0x0000); sendCommand(0x0008); sendData(0x0207); sendCommand(0x0009); sendData(0x0000); sendCommand(0x000A); sendData(0x0000); sendCommand(0x000C); sendData(0x0000); sendCommand(0x000D); sendData(0x0000); sendCommand(0x000F); sendData(0x0000); //power on sequence VGHVGL sendCommand(0x0010); sendData(0x0000); sendCommand(0x0011); sendData(0x0007); sendCommand(0x0012); sendData(0x0000); sendCommand(0x0013); sendData(0x0000); //vgh sendCommand(0x0010); sendData(0x1290); sendCommand(0x0011); sendData(0x0227); wait(0.1); //vregiout sendCommand(0x0012); sendData(0x001d); //0x001b wait(0.1); //vom amplitude sendCommand(0x0013); sendData(0x1500); wait(0.1); //vom H sendCommand(0x0029); sendData(0x0018); sendCommand(0x002B); sendData(0x000D); //gamma sendCommand(0x0030); sendData(0x0004); sendCommand(0x0031); sendData(0x0307); sendCommand(0x0032); sendData(0x0002);// 0006 sendCommand(0x0035); sendData(0x0206); sendCommand(0x0036); sendData(0x0408); sendCommand(0x0037); sendData(0x0507); sendCommand(0x0038); sendData(0x0204);//0200 sendCommand(0x0039); sendData(0x0707); sendCommand(0x003C); sendData(0x0405);// 0504 sendCommand(0x003D); sendData(0x0F02); //ram sendCommand(0x0050); sendData(0x0000); sendCommand(0x0051); sendData(0x00EF); sendCommand(0x0052); sendData(0x0000); sendCommand(0x0053); sendData(0x013F); sendCommand(0x0060); sendData(0xA700); sendCommand(0x0061); sendData(0x0001); sendCommand(0x006A); sendData(0x0000); // sendCommand(0x0080); sendData(0x0000); sendCommand(0x0081); sendData(0x0000); sendCommand(0x0082); sendData(0x0000); sendCommand(0x0083); sendData(0x0000); sendCommand(0x0084); sendData(0x0000); sendCommand(0x0085); sendData(0x0000); // sendCommand(0x0090); sendData(0x0010); sendCommand(0x0092); sendData(0x0600); sendCommand(0x0093); sendData(0x0003); sendCommand(0x0095); sendData(0x0110); sendCommand(0x0097); sendData(0x0000); sendCommand(0x0098); sendData(0x0000); sendCommand(0x0007); sendData(0x0133); sendCommand(0x0022);//Start to write to display RAM } else { sendCommand(0x0001); sendData(0x0100); sendCommand(0x0002); sendData(0x0700); sendCommand(0x0003); sendData(0x1030); sendCommand(0x0004); sendData(0x0000); sendCommand(0x0008); sendData(0x0302); sendCommand(0x000A); sendData(0x0000); sendCommand(0x000C); sendData(0x0000); sendCommand(0x000D); sendData(0x0000); sendCommand(0x000F); sendData(0x0000); wait(0.1); sendCommand(0x0030); sendData(0x0000); sendCommand(0x0031); sendData(0x0405); sendCommand(0x0032); sendData(0x0203); sendCommand(0x0035); sendData(0x0004); sendCommand(0x0036); sendData(0x0B07); sendCommand(0x0037); sendData(0x0000); sendCommand(0x0038); sendData(0x0405); sendCommand(0x0039); sendData(0x0203); sendCommand(0x003c); sendData(0x0004); sendCommand(0x003d); sendData(0x0B07); sendCommand(0x0020); sendData(0x0000); sendCommand(0x0021); sendData(0x0000); sendCommand(0x0050); sendData(0x0000); sendCommand(0x0051); sendData(0x00ef); sendCommand(0x0052); sendData(0x0000); sendCommand(0x0053); sendData(0x013f); wait(0.1); sendCommand(0x0060); sendData(0xa700); sendCommand(0x0061); sendData(0x0001); sendCommand(0x0090); sendData(0x003A); sendCommand(0x0095); sendData(0x021E); sendCommand(0x0080); sendData(0x0000); sendCommand(0x0081); sendData(0x0000); sendCommand(0x0082); sendData(0x0000); sendCommand(0x0083); sendData(0x0000); sendCommand(0x0084); sendData(0x0000); sendCommand(0x0085); sendData(0x0000); sendCommand(0x00FF); sendData(0x0001); sendCommand(0x00B0); sendData(0x140D); sendCommand(0x00FF); sendData(0x0000); wait(0.1); sendCommand(0x0007); sendData(0x0133); wait(0.05); //exit standby sendCommand(0x0010); sendData(0x14E0); wait(0.1); sendCommand(0x0007); sendData(0x0133); sendCommand(0x0022); } //paint screen black for(unsigned char i=0;i<2;i++) { for(unsigned int f=0;f<38400;f++) { sendData(BLACK); } } } void TFT::setOrientation(unsigned int HV)//horizontal or vertical { sendCommand(0x03); if(HV==1)//vertical { if(IC_CODE == 0x5408) { sendData(0x1038); } else { sendData(0x5038); } } else//horizontal { if(IC_CODE == 0x5408) { sendData(0x1030); } else { sendData(0x5030); } } sendCommand(0x0022); //Start to write to display RAM } unsigned int TFT::constrain(unsigned int val2chk, unsigned int lowval, unsigned int highval) { if (val2chk < lowval) return lowval; else if (val2chk > highval) return highval; else return val2chk; } void TFT::setXY(unsigned int poX, unsigned int poY) { poX = constrain(poX,MIN_X,MAX_X); //Limits the pixel range to 0 - 239 poY = constrain(poY,MIN_Y,MAX_Y); //Limits the pixel range to 0 - 319 /* Writing to GRAM beyond the range gives unpredictable results. The above code is to limit this. This might also slow down the writing to TFT. You can remove the above two lines of code, if you think your application code does not write beyond this range. This would speed up TFT writing. */ sendCommand(0x0020);//X sendData(poX); sendCommand(0x0021);//Y sendData(poY); sendCommand(0x0022);//Start to write to display RAM } void TFT::setPixel(unsigned int poX, unsigned int poY,unsigned int color) { setXY(poX,poY); sendData(color); } void TFT::drawCircle(int poX, int poY, int r,unsigned int color) { int x = -r, y = 0, err = 2-2*r, e2; do { setPixel(poX-x, poY+y,color); setPixel(poX+x, poY+y,color); setPixel(poX+x, poY-y,color); setPixel(poX-x, poY-y,color); e2 = err; if (e2 <= y) { err += ++y*2+1; if (-x == y && e2 <= x) e2 = 0; } if (e2 > x) err += ++x*2+1; } while (x <= 0); } void TFT::fillCircle(int poX, int poY, int r,unsigned int color) { int x = -r, y = 0, err = 2-2*r, e2; do { drawVerticalLine(poX-x,poY-y,2*y,color); drawVerticalLine(poX+x,poY-y,2*y,color); e2 = err; if (e2 <= y) { err += ++y*2+1; if (-x == y && e2 <= x) e2 = 0; } if (e2 > x) err += ++x*2+1; } while (x <= 0); } void TFT::drawLine(unsigned int x0,unsigned int y0,unsigned int x1,unsigned int y1,unsigned int color) { int dx = x1-x0; dx = abs(dx); int sx = x0<x1 ? 1 : -1; int dy = y1-y0; dy = -abs(dy); int sy = y0<y1 ? 1 : -1; int err = dx+dy, e2; /* error value e_xy */ for (;;) { setPixel(x0,y0,color); e2 = 2*err; if (e2 >= dy) { /* e_xy+e_x > 0 */ if (x0 == x1) break; err += dy; x0 += sx; } if (e2 <= dx) { /* e_xy+e_y < 0 */ if (y0 == y1) break; err += dx; y0 += sy; } } } void TFT::drawVerticalLine(unsigned int poX, unsigned int poY,unsigned int length,unsigned int color) { poX = constrain(poX,MIN_X,MAX_X); //Limits the pixel range to 0 - 239 poY = constrain(poY,MIN_Y,MAX_Y); //Limits the pixel range to 0 - 319 setXY(poX,poY); setOrientation(1); if(length+poY>MAX_Y) { length=MAX_Y-poY; } for(unsigned int i=0;i<length;i++) { sendData(color); } } void TFT::drawHorizontalLine(unsigned int poX, unsigned int poY,unsigned int length,unsigned int color) { poX = constrain(poX,MIN_X,MAX_X); //Limits the pixel range to 0 - 239 poY = constrain(poY,MIN_Y,MAX_Y); //Limits the pixel range to 0 - 319 setXY(poX,poY); setOrientation(0); if(length+poX>MAX_X) { length=MAX_X-poX; } for(unsigned int i=0;i<length;i++) { sendData(color); } } void TFT::drawRectangle(unsigned int poX, unsigned int poY, unsigned int length,unsigned int width,unsigned int color) { drawHorizontalLine(poX, poY, length, color); drawHorizontalLine(poX, poY+width, length, color); drawVerticalLine(poX, poY, width,color); drawVerticalLine(poX + length, poY, width,color); } void TFT::fillRectangle(unsigned int poX, unsigned int poY, unsigned int length, unsigned int width, unsigned int color) { for(unsigned int i=0;i<width;i++) { drawHorizontalLine(poX, poY+i, length, color); } } void TFT::drawChar(unsigned char ascii,unsigned int poX, unsigned int poY,unsigned int size, unsigned int fgcolor) { setXY(poX,poY); setOrientation(1); if((ascii < 0x20)||(ascii > 0x7e))//Unsupported char. { ascii = '?'; } for(unsigned char i=0;i<8;i++) { unsigned char temp = simpleFont[ascii-0x20][i]; for(unsigned char f=0;f<8;f++) { if((temp>>f)&0x01) { fillRectangle(poX+i*size, poY+f*size, size, size, fgcolor); } } } } void TFT::drawString(char *string,unsigned int poX, unsigned int poY,unsigned int size,unsigned int fgcolor) { while(*string) { drawChar(*string, poX, poY, size, fgcolor); *string++; if(poX < MAX_X) { poX+=8*size; // Move cursor right } } } unsigned char TFT::drawNumber(long long_num,unsigned int poX, unsigned int poY,unsigned int size,unsigned int fgcolor) { unsigned char char_buffer[10]=""; unsigned char i = 0; unsigned char f = 0; if (long_num < 0) { f=1; drawChar('-',poX, poY, size, fgcolor); long_num = -long_num; if(poX < MAX_X) { poX+=8*size; // Move cursor right } } else if (long_num == 0) { f=1; drawChar('0',poX, poY, size, fgcolor); if (poX < MAX_X) { poX+=8*size; // Move cursor right } return f; } while (long_num > 0) { char_buffer[i++] = long_num % 10; long_num /= 10; } f=f+i; for(; i > 0; i--) { drawChar('0'+ char_buffer[i - 1],poX, poY, size, fgcolor); if(poX < MAX_X) { poX+=8*size; // Move cursor right } } return f; } unsigned char TFT::drawFloat(float floatNumber,unsigned char decimal,unsigned int poX, unsigned int poY,unsigned int size,unsigned int fgcolor) { unsigned int temp=0; float decy=0.0; float rounding = 0.5; unsigned char f=0; if(floatNumber<0.0) { drawChar('-',poX, poY, size, fgcolor); floatNumber = -floatNumber; if(poX < MAX_X) { poX+=8*size; // Move cursor right } f =1; } for (unsigned char i=0; i<decimal; ++i) { rounding /= 10.0; } floatNumber += rounding; temp = (unsigned int)floatNumber; unsigned char howlong=drawNumber(temp,poX, poY, size, fgcolor); f += howlong; if((poX+8*size*howlong) < MAX_X) { poX+=8*size*howlong; // Move cursor right } if(decimal>0) { drawChar('.',poX, poY, size, fgcolor); if(poX < MAX_X) { poX+=8*size; // Move cursor right } f +=1; } decy = floatNumber-temp;//decimal part, for(unsigned char i=0;i<decimal;i++)//4 { decy *=10;// for the next decimal temp = decy;//get the decimal drawNumber(temp,poX, poY, size, fgcolor); floatNumber = -floatNumber; if(poX < MAX_X) { poX+=8*size; // Move cursor right } decy -= temp; } f +=decimal; return f; } unsigned char TFT::drawFloat(float floatNumber,unsigned int poX, unsigned int poY,unsigned int size,unsigned int fgcolor) { unsigned char decimal=2; unsigned int temp=0; float decy=0.0; float rounding = 0.5; unsigned char f=0; if(floatNumber<0.0) { drawChar('-',poX, poY, size, fgcolor); floatNumber = -floatNumber; if(poX < MAX_X) { poX+=8*size; // Move cursor right } f =1; } for (unsigned char i=0; i<decimal; ++i) { rounding /= 10.0; } floatNumber += rounding; temp = (unsigned int)floatNumber; unsigned char howlong=drawNumber(temp,poX, poY, size, fgcolor); f += howlong; if((poX+8*size*howlong) < MAX_X) { poX+=8*size*howlong; // Move cursor right } if(decimal>0) { drawChar('.',poX, poY, size, fgcolor); if(poX < MAX_X) { poX+=8*size; // Move cursor right } f +=1; } decy = floatNumber-temp;//decimal part, for(unsigned char i=0;i<decimal;i++)//4 { decy *=10;// for the next decimal temp = decy;//get the decimal drawNumber(temp,poX, poY, size, fgcolor); floatNumber = -floatNumber; if(poX < MAX_X) { poX+=8*size; // Move cursor right } decy -= temp; } f +=decimal; return f; } void TFT::all_pin_input(void) { //DDRD &=~ 0xfc; // 0b 1111 1100 //DDRB &=~ 0x03; // 0b 0000 0011 lcd_data.input(); } void TFT::all_pin_output(void) { //DDRD |= 0xfc; //DDRB |= 0x03; lcd_data.output(); } void TFT::all_pin_low(void) { //PORTD &=~ 0xfc; //PORTB &=~ 0x03; lcd_data.write(0); } void TFT::CS_HIGH(void) { CS_BIT.write(1); } void TFT::CS_LOW(void) { CS_BIT.write(0); } void TFT::RS_HIGH(void) { RS_BIT.write(1); } void TFT::RS_LOW(void) { RS_BIT.write(0); } void TFT::WR_HIGH(void) { WR_BIT.write(1); } void TFT::WR_LOW(void) { WR_BIT.write(0); } void TFT::WR_RISING(void) { WR_HIGH(); WR_LOW(); } void TFT::RD_HIGH(void) { RD_BIT.write(1); } void TFT::RD_LOW(void) { RD_BIT.write(0); } void TFT::RD_RISING(void) { RD_HIGH(); RD_LOW(); } TFT Tft=TFT();