Library files for using Seeed Studio TFT Touch Shield for Arduino (ST7781R controller) together with ELMICRO TestBed for mbed. Featuring a short example program of how to calibrate the touch screen. Some basic drawing functions are also included (circle, rectangle, lines, text).

Dependencies:   mbed

TFT.cpp

Committer:
elmicro
Date:
2012-06-28
Revision:
0:db0d63650413

File content as of revision 0:db0d63650413:

#include "TFT.h" 
#include "shortcuts.h"
#include "touch.h"

unsigned char DispDir=0;


/* ===================================================================
    routine:    CtrlOutput
    purpose:    Sets mbed's I/Os to act as RS, RD, RW, CS output
    parameters: none
    returns:    nothing    
    date:       2012-06-27
    author:     Stefan Guenther
                Elektronikladen | ELMICRO
  -------------------------------------------------------------------*/
void CtrlOutput(void)
{
    LPC_GPIO0->FIODIR |= BIT15+BIT16+BIT17+BIT18;
}


/* ===================================================================
    routine:    PinOutput
    purpose:    Sets mbed's I/Os to act as 8 bit data output
    parameters: none
    returns:    nothing    
    date:       2012-06-27
    author:     Stefan Guenther
                Elektronikladen | ELMICRO
  -------------------------------------------------------------------*/
void PinOutput(void)
{
    LPC_GPIO0->FIODIR |= BIT0+BIT1;
    LPC_GPIO2->FIODIR |= BIT0+BIT1+BIT2+BIT3+BIT4+BIT5;    
}


/* ===================================================================
    routine:    PinInput
    purpose:    Sets mbed's I/Os to act as 8 bit data input
    parameters: none
    returns:    nothing    
    date:       2012-06-27
    author:     Stefan Guenther
                Elektronikladen | ELMICRO
  -------------------------------------------------------------------*/
void PinInput(void)
{
    LPC_GPIO0->FIODIR &= ~(BIT0+BIT1);
    LPC_GPIO2->FIODIR &= ~(BIT0+BIT1+BIT2+BIT3+BIT4+BIT5);    
}

/* ===================================================================
    routine:    PinLow
    purpose:    Sets 8 bit data output to 0x00 (all outputs low)
    parameters: none
    returns:    nothing    
    date:       2012-06-27
    author:     Stefan Guenther
                Elektronikladen | ELMICRO
  -------------------------------------------------------------------*/
void PinLow(void)
{
    LPC_GPIO0->FIOCLR = BIT0+BIT1;
    LPC_GPIO2->FIOCLR = BIT0+BIT1+BIT2+BIT3+BIT4+BIT5;    
}

/* ===================================================================
    routine:    PinHigh
    purpose:    Sets 8 bit data output to 0xff (all outputs high)
    parameters: none
    returns:    nothing    
    date:       2012-06-27
    author:     Stefan Guenther
                Elektronikladen | ELMICRO
  -------------------------------------------------------------------*/
void PinHigh(void)
{
    LPC_GPIO0->FIOSET = BIT0+BIT1;
    LPC_GPIO2->FIOSET = BIT0+BIT1+BIT2+BIT3+BIT4+BIT5;    
}

/* ===================================================================
    routine:    PushData
    purpose:    Sets the 8 data outputs corresponding to data byte
                which shall be transmitted to LCD
    parameters: <data>      byte of data for TX
    returns:    nothing    
    date:       2012-06-27
    author:     Stefan Guenther
                Elektronikladen | ELMICRO
  -------------------------------------------------------------------*/
void PushData(unsigned char data)
{
    LPC_GPIO0->FIOCLR = 0x03;                   //set all outputs low
    LPC_GPIO2->FIOCLR = 0x3f;
    //as the outputs are not in order and are splittet onto two ports,
    //the data byte has to be read bit-by-bit and each bit has to set
    //a different output pin
    LPC_GPIO0->FIOSET = data&BIT0 | (data&BIT2)>>1;
    LPC_GPIO2->FIOSET = (data&BIT6) >> 6 | (data&BIT5) >> 4 | (data&BIT7) >> 5 
                      | (data&BIT4) >> 1 | (data&BIT3) << 1 | (data&BIT1) << 4;                      
}

/* NOT YET TESTED */
unsigned char GetData(void)
{
    unsigned char data = 0;
    wait(0.001);
    data  = (LPC_GPIO0->FIOPIN&BIT0)      | (LPC_GPIO0->FIOPIN&BIT2) >> 1;
    data |= (LPC_GPIO2->FIOPIN&BIT6) >> 6 | (LPC_GPIO2->FIOPIN&BIT5) >> 4 
          | (LPC_GPIO2->FIOPIN&BIT7) >> 5 | (LPC_GPIO2->FIOPIN&BIT4) >> 1
          | (LPC_GPIO2->FIOPIN&BIT3) << 1 | (LPC_GPIO2->FIOPIN&BIT2) << 3;
    return data;    
}

/* ===================================================================
    routine:    SendCommand
    purpose:    Transmits a command code to the LCD controller
    parameters: <command>   command byte
    returns:    nothing        
    note:       Each transmit to the LCD controller has to be 16 bits
                wide, which results in 2 bytes per message.
                Commands are only 8 bits wide, so the upper bits
                have to be all zero
    date:       2012-06-27
    author:     Stefan Guenther
                Elektronikladen | ELMICRO
  -------------------------------------------------------------------*/
void SendCommand(unsigned char command)
{
    LPC_GPIO0->FIOCLR = BIT16+BIT18;        //CS and RS low
    LPC_GPIO0->FIOSET = BIT17+BIT15;        //RD and WR high    
    LPC_GPIO0->FIOCLR = BIT17;              //WR low
    PushData(0);                            //commands have only 8 bits
    LPC_GPIO0->FIOSET = BIT17;              //WR high    
    for(int x=0; x<3; x++);                 //wait
    
    LPC_GPIO0->FIOCLR = BIT17;              //WR low
    PushData(command);
    LPC_GPIO0->FIOSET = BIT17;              //WR high
    LPC_GPIO0->FIOSET = BIT16;              //CS high    
}

/* ===================================================================
    routine:    SendData
    purpose:    Transmits 16 data bits to the LCD controller
    parameters: <data>   data value
    returns:    nothing        
    note:       Transmit has to be splitted into 2 transfers
                as interface is only 8 bits wide
    date:       2012-06-27
    author:     Stefan Guenther
                Elektronikladen | ELMICRO
  -------------------------------------------------------------------*/
void SendData(unsigned int data)
{
    LPC_GPIO0->FIOCLR = BIT16;              //CS low
    LPC_GPIO0->FIOSET = BIT18+BIT15;        //RD and RS high    
    LPC_GPIO0->FIOCLR = BIT17;              //WR low
    PushData((data&0xff00)>>8);             //send first byte
    LPC_GPIO0->FIOSET = BIT17;              //WR high    
    for(int x=0; x<3; x++);                 //wait
    
    LPC_GPIO0->FIOCLR = BIT17;              //WR low
    PushData(data&0xff);
    LPC_GPIO0->FIOSET = BIT17;              //WR high
    LPC_GPIO0->FIOSET = BIT16;              //CS high        
}


/* NOT YET TESTED */
unsigned int ReadRegister(unsigned int reg)
{
    unsigned int data=0;
    
    LPC_GPIO0->FIOCLR = BIT16+BIT18;        //CS and RS low
    LPC_GPIO0->FIOSET = BIT15;              //RD high       
    PinOutput();
    LPC_GPIO0->FIOCLR = BIT17;              //WR low
    PushData(0);
    LPC_GPIO0->FIOSET = BIT17;              //WR high
    LPC_GPIO0->FIOCLR = BIT17;              //WR low    
    PushData(reg);
    LPC_GPIO0->FIOSET = BIT17;              //WR high
    PinInput();
    PinLow();                               /* ?Necessary? */
    LPC_GPIO0->FIOSET = BIT18;              //RS high
    LPC_GPIO0->FIOCLR = BIT15;              //RD low 
    LPC_GPIO0->FIOSET = BIT15;              //RD high
    data = GetData();
    LPC_GPIO0->FIOSET = BIT16;              //CS high        
    PinOutput();
    return data;    
}


void ClearScreen(unsigned int color)
{
   for(unsigned char i=0;i<2;i++)
    {
        for(unsigned int f=0;f<38400;f++)
        {
            SendData(color);                //black
        }
    } 
}


void Init(void)
{
    /* PRELOAD TFTData STRUCTURE WITH PRESET/DEFAULT VALUES */    
    TFTData.XRes    = TFTRESX;                      
    TFTData.YRes    = TFTRESY;
    TFTData.Xmin    = 1250;                 //should be calculated
    TFTData.Xmax    = 2800;                 //for each device!
    TFTData.Ymin    = 900;
    TFTData.Ymax    = 3100;
    TFTData.Xscale  = 6875;
    TFTData.Yscale  = 6875;
    DispDir         = LEFT2RIGHT;
    
    /* SETUP MBED FOR CONNECTION WITH TFT */
    CtrlOutput();                           //CS, RD, WR, RS as output
    PinOutput();                            //8-bit parallel bus
    PinLow();                               //all output pins are low
    
    /* INITIALIZATION SEQUENCE */
    wait(0.1);        
    
    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.100);

    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.100);

    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.100);
    
    SendCommand(0x0007);
    SendData(0x0133);
    
    /* WAKEUP TFT FROM STANDBY */
    SendCommand(0x0010);
    SendData(0x14E0);
    wait(0.100);
    
    SendCommand(0x0007);
    SendData(0x0133);    
    SendCommand(0x0022);
    
    /* CLS */
    for(unsigned char i=0;i<2;i++)
    {
        for(unsigned int f=0;f<38400;f++)
        {
            SendData(0);                //black
        }
    }  
}


/* ===================================================================
    routine:    SetOrientation
    purpose:    Sets the direction in which the X/Y-position counter
                autoincrements (used by DrawRectangle)
    parameters: <layout>   direction control
    returns:    nothing            
    date:       2012-06-27
    author:     Seeed Studio
    co-author:  Stefan Guenther
                Elektronikladen | ELMICRO
  -------------------------------------------------------------------*/
void SetOrientation(unsigned char layout)
{
    SendCommand(0x03);
    SendData((layout==1)?(0x5038):(0x5030));
    SendCommand(0x0022);
}


void SetDirection(unsigned char dir)
{
    DispDir = dir;
}


/* ===================================================================
    routine:    SetXY
    purpose:    Sets virtual "cursor" to specific pixel
    parameters: <posX, posY> 
    returns:    nothing            
    note:       In fact, this tells the LCD controller the next
                SRAM address to use for the following color value
    date:       2012-06-27
    author:     Seeed Studio
    co-author:  Stefan Guenther
                Elektronikladen | ELMICRO
  -------------------------------------------------------------------*/
void SetXY(unsigned int posX, unsigned int posY)
{
    SendCommand(0x20);        //set X
    SendData(posX);
    SendCommand(0x21);        //set Y
    SendData(posY);
    SendCommand(0x22);        //start command for writing into display SRAM
}


/* ===================================================================
    routine:    SetPixel
    purpose:    Colors a single pixel
    parameters: <posX, posY, color> 
    returns:    nothing            
    note:       The most basic function for displaying content onto
                the TFT display    
    date:       2012-06-27
    author:     Seeed Studio
    co-author:  Stefan Guenther
                Elektronikladen | ELMICRO
  -------------------------------------------------------------------*/
void SetPixel(unsigned int posX, unsigned int posY, unsigned int color)
{
    SetXY(posX, posY);
    SendData(color);
}