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.

Revision:
0:93976d4026d3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tft.cpp	Thu Feb 05 19:39:58 2015 +0000
@@ -0,0 +1,798 @@
+/*
+ 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();
\ No newline at end of file