October 15, 2013  
  by andyi
  
  
     
    
    
    
    
     
    
    
 | 
Here is the code I used for the Sainsmart 3.2 tft with SSD1289 controller.
I have stripped out everything else in case you wonder why there are so many switch statements with only one option.
As I said earlier it is based on UTFT (fonts stripped out to fit on 168). 
Pin defs:- 
MCU       GLCD
PC0-5 -> DB0-5
PB1   -> DB6
PB2   -> DB7
PD0-7 -> DB08-15
PB0   -> CS
PB3   -> RS
PB4   -> WR
PB5   -> RESET
other GLCD pins
GND    -> 0V
VCC    -> 5V
LEDA   -> 3.3V
RD     -> 3.3V
 
I have used 10K resistors from the MCU to level shift down to ~3.4V 
(also tried level shifting ICs but they take seem to be slower) 
// Sainsmart 3.2 tft lcd test script
#include <avr/pgmspace.h>
#include "../../code/libnerdkits/delay.h"
#include "lcdtest.h"
//#include <stdint.h>
//#include <math.h>
// MCU setup
void mcu_setup()
{
    // define pins
    // CS       - PB0
    // WR       - PB4
    // RS       - PB3
    // RESET    - PB5
    // RD       - tied high to 3.3v
    // ALE      - define for LATCHED 16 bit
    // SDA      - define for SERIAL
    // SCL      - define for SERIAL
    // switch off UART 
    UCSR0B=0;
    // define direction of all pins
    switch (display_transfer_mode)
    {
        case 16:
            DDRB |= 0x3F;
            DDRC |= 0x3F;
            DDRD |= 0xFF;
            break;
        // other modes not yet implemented
    }
    // set all pins low
    //PORTB &= ~(0x3F);
    //PORTC &= ~(0x3F);
    //PORTD &= 0x00;
    PORTB=0;
    PORTC=0;
    PORTD=0;
}
void initialise(byte orientation)
{
    orient=orientation;     // PORTRAIT or LANDSCAPE
    display_model=SSD1289;  // SSD1289, SSD1289_8 or SSD1289LATCHED for 3.2" or ST7735 for 1.8"
    switch (display_model)
    {
        case SSD1289:
            disp_x_size=239; 
            disp_y_size=319; 
            display_transfer_mode=16;
            break;
        //other models not implemented
    }
}
void setCS()
{
    PORTB|=(1<<PB0);
}
void clearCS()
{
    PORTB&=~(1<<PB0);
}
void setWR()
{
    PORTB|=(1<<PB4);
}
void clearWR()
{
    PORTB&=~(1<<PB4);
}
void setRS()
{
    PORTB|=(1<<PB3);
}
void clearRS()
{
    PORTB&=~(1<<PB3);
}
void setRESET()
{
    PORTB|=(1<<PB5);
}
void clearRESET()
{
    PORTB&=~(1<<PB5);
}
void lcd_write_bus(char VH, char VL, byte mode)
{
    switch (mode)
    {
        case 16:
            //       16 bit
            // clear port b,c,d data bits
            PORTB &= ~(0x06);
            PORTC &= ~(0x3F);
            PORTD = VH;
            PORTC |= (VL & 0x3F);
            PORTB |= (VL>>5)&0x06;
            // pulse WR low
            clearWR();delay_us(1);setWR(); // need 10us delay for voltage level shifters - only 1 us if 10k resistors used for level shifting instead
            break;
        // no other modes implemented
    }
}
void lcd_write_com(char VL)
{
    clearRS();
    lcd_write_bus(0x00,VL,display_transfer_mode);
}
void lcd_write_data(char VH, char VL)
{
    setRS();
    lcd_write_bus(VH, VL,display_transfer_mode);
}
void lcd_write_data2(char VL)
{
    setRS();
    lcd_write_bus(0x00,VL,display_transfer_mode);
}
void lcd_write_com_data(char com1, int dat1)
{
    lcd_write_com(com1);
    lcd_write_data(dat1>>8,dat1);
}
void setcolor(byte r, byte g, byte b)
{
    fch=((r&248)|g>>5);
    fcl=((g&28)<<3|b>>3);
}
void setcolor2(word color)
{
    fch=(byte)(color>>8);
    fcl=(byte)(color&0xFF);
}
word getcolor()
{
    return (fch<<8) | fcl;
}
void setbackcolor(byte r, byte g, byte b)
{
    bch=((r&248)|g>>5);
    bcl=((g&28)<<3|b>>3);
    _transparent=false;
}
void setbackcolor2(uint32_t color)
{
    if (color==VGA_TRANSPARENT)
        _transparent=true;
    else
    {
        bch=(byte)(color>>8);
        bcl=(byte)(color & 0xFF);
        _transparent=false;
    }
}
word getbackcolor()
{
    return (bch<<8) | bcl;
}
void setxy(word x1, word y1, word x2, word y2)
{
    if (orient==LANDSCAPE)
    {
        swap(word, x1, y1);
        swap(word, x2, y2)
        y1=disp_y_size-y1;
        y2=disp_y_size-y2;
        swap(word, y1, y2)
    }
    switch(display_model)
    {
        case SSD1289: 
            lcd_write_com_data(0x44,(x2<<8)+x1);
            lcd_write_com_data(0x45,y1);
            lcd_write_com_data(0x46,y2);
            lcd_write_com_data(0x4e,x1);
            lcd_write_com_data(0x4f,y1);
            lcd_write_com(0x22);
            break;
    }
}
void _fast_fill_16(int ch, int cl, long pix)
{
    long blocks;
    PORTD = ch;
    PORTB &= ~(0x06);
    PORTB |= ((cl>>5)&0x06);
    PORTC &= ~(0x3F);
    PORTC |= (cl & 0x3F);
    blocks = pix/16;
    int i;
    for (i=0; i<blocks; i++)
    {
        clearWR();delay_us(1);setWR();
        clearWR();delay_us(1);setWR();
        clearWR();delay_us(1);setWR();
        clearWR();delay_us(1);setWR();
        clearWR();delay_us(1);setWR();
        clearWR();delay_us(1);setWR();
        clearWR();delay_us(1);setWR();
        clearWR();delay_us(1);setWR();
        clearWR();delay_us(1);setWR();
        clearWR();delay_us(1);setWR();
        clearWR();delay_us(1);setWR();
        clearWR();delay_us(1);setWR();
        clearWR();delay_us(1);setWR();
        clearWR();delay_us(1);setWR();
        clearWR();delay_us(1);setWR();
        clearWR();delay_us(1);setWR();
    }
    if ((pix % 16) != 0)
        for (i=0; i<(pix % 16)+1; i++)
        {
            clearWR();delay_us(1);setWR();
        }
}
void clrxy()
{
    if (orient==PORTRAIT)
        setxy(0,0,disp_x_size,disp_y_size);
    else
        setxy(0,0,disp_y_size,disp_x_size);
}
void clrscr()
{
    clearCS();
    clrxy();
    setRS();
    _fast_fill_16(0,0,((disp_x_size+1)*(disp_y_size+1)));
    setCS();
}
void setpixel(word color)
{
    lcd_write_data((color>>8),(color&0xFF));    // rrrrrggggggbbbbb
}
void drawpixel(int x, int y)
{
    clearCS();
    setxy(x, y, x, y);
    setpixel((fch<<8)|fcl);
    setCS();
    clrxy();
}
void fillscr(word color)
{
    char ch, cl;
    ch=(byte)(color>>8);
    cl=(byte)(color & 0xFF);
    clearCS();
    clrxy();
    setRS();
    _fast_fill_16(ch,cl,((disp_x_size+1)*(disp_y_size+1)));
    setCS();
}
void fillscr2(byte r, byte g, byte b)
{
    word color = ((r&248)<<8 | (g&252)<<3 | (b&248)>>3);
    fillscr(color);
}
void drawhline(int x, int y, int l)
{
    if (l<0)
    {
        l = -l;
        x -= l;
    }
    clearCS();
    setxy(x, y, x+l, y);
    setRS();
    _fast_fill_16(fch,fcl,l);
    setCS();
    clrxy();
}
void drawvline(int x, int y, int l)
{
    if (l<0)
    {
        l = -l;
        y -= l;
    }
    clearCS();
    setxy(x, y, x, y+l);
    setRS();
    _fast_fill_16(fch,fcl,l);
    setCS();
    clrxy();
}
void drawline(int x1, int y1, int x2, int y2)
{
    if (y1==y2)
        drawhline(x1, y1, x2-x1);
    else if (x1==x2)
        drawvline(x1, y1, y2-y1);
    else
    {
        unsigned int    dx = (x2 > x1 ? x2 - x1 : x1 - x2);
        short           xstep =  x2 > x1 ? 1 : -1;
        unsigned int    dy = (y2 > y1 ? y2 - y1 : y1 - y2);
        short           ystep =  y2 > y1 ? 1 : -1;
        int             col = x1, row = y1;
        clearCS();
        if (dx < dy)
        {
            int t = - (dy >> 1);
            while (true)
            {
                setxy (col, row, col, row);
                lcd_write_data (fch, fcl);
                if (row == y2)
                    return;
                row += ystep;
                t += dx;
                if (t >= 0)
                {
                    col += xstep;
                    t   -= dy;
                }
            } 
        }
        else
        {
            int t = - (dx >> 1);
            while (true)
            {
                setxy (col, row, col, row);
                lcd_write_data (fch, fcl);
                if (col == x2)
                    return;
                col += xstep;
                t += dy;
                if (t >= 0)
                {
                    row += ystep;
                    t   -= dx;
                }
            } 
        }
        setCS();
    }
    clrxy();
}
void drawcircle(int x, int y, int radius)
{
    int f = 1 - radius;
    int ddF_x = 1;
    int ddF_y = -2 * radius;
    int x1 = 0;
    int y1 = radius;
    clearCS();
    setxy(x, y + radius, x, y + radius);
    lcd_write_data(fch,fcl);
    setxy(x, y - radius, x, y - radius);
    lcd_write_data(fch,fcl);
    setxy(x + radius, y, x + radius, y);
    lcd_write_data(fch,fcl);
    setxy(x - radius, y, x - radius, y);
    lcd_write_data(fch,fcl);
    while(x1 < y1)
    {
        if(f >= 0) 
        {
            y1--;
            ddF_y += 2;
            f += ddF_y;
        }
        x1++;
        ddF_x += 2;
        f += ddF_x;    
        setxy(x + x1, y + y1, x + x1, y + y1);
        lcd_write_data(fch,fcl);
        setxy(x - x1, y + y1, x - x1, y + y1);
        lcd_write_data(fch,fcl);
        setxy(x + x1, y - y1, x + x1, y - y1);
        lcd_write_data(fch,fcl);
        setxy(x - x1, y - y1, x - x1, y - y1);
        lcd_write_data(fch,fcl);
        setxy(x + y1, y + x1, x + y1, y + x1);
        lcd_write_data(fch,fcl);
        setxy(x - y1, y + x1, x - y1, y + x1);
        lcd_write_data(fch,fcl);
        setxy(x + y1, y - x1, x + y1, y - x1);
        lcd_write_data(fch,fcl);
        setxy(x - y1, y - x1, x - y1, y - x1);
        lcd_write_data(fch,fcl);
    }
    setCS();
    clrxy();
}
void fillcircle(int x, int y, int radius)
{
    int y1;
    int x1;
    for(y1=-radius; y1<=0; y1++) 
        for(x1=-radius; x1<=0; x1++)
            if(x1*x1+y1*y1 <= radius*radius) 
            {
                drawhline(x+x1, y+y1, 2*(-x1));
                drawhline(x+x1, y-y1, 2*(-x1));
                break;
            }
}
void drawrect(int x1, int y1, int x2, int y2)
{
    if (x1>x2)
    {
        swap(int, x1, x2);
    }
    if (y1>y2)
    {
        swap(int, y1, y2);
    }
    drawhline(x1, y1, x2-x1);
    drawhline(x1, y2, x2-x1);
    drawvline(x1, y1, y2-y1);
    drawvline(x2, y1, y2-y1);
}
void drawroundrect(int x1, int y1, int x2, int y2)
{
    if (x1>x2)
    {
        swap(int, x1, x2);
    }
    if (y1>y2)
    {
        swap(int, y1, y2);
    }
    if ((x2-x1)>4 && (y2-y1)>4)
    {
        drawpixel(x1+1,y1+1);
        drawpixel(x2-1,y1+1);
        drawpixel(x1+1,y2-1);
        drawpixel(x2-1,y2-1);
        drawhline(x1+2, y1, x2-x1-4);
        drawhline(x1+2, y2, x2-x1-4);
        drawvline(x1, y1+2, y2-y1-4);
        drawvline(x2, y1+2, y2-y1-4);
    }
}
void fillrect(int x1, int y1, int x2, int y2)
{
    if (x1>x2)
    {
        swap(int, x1, x2);
    }
    if (y1>y2)
    {
        swap(int, y1, y2);
    }
    clearCS();
    setxy(x1, y1, x2, y2);
    setRS();
    _fast_fill_16(fch,fcl,(((long)(x2-x1)+1)*((long)(y2-y1)+1)));
    setCS();
}
void fillroundrect(int x1, int y1, int x2, int y2)
{
    if (x1>x2)
    {
        swap(int, x1, x2);
    }
    if (y1>y2)
    {
        swap(int, y1, y2);
    }
    if ((x2-x1)>4 && (y2-y1)>4)
    {
        int i;
        for (i=0; i<((y2-y1)/2)+1; i++)
        {
            switch(i)
            {
            case 0:
                drawhline(x1+2, y1+i, x2-x1-4);
                drawhline(x1+2, y2-i, x2-x1-4);
                break;
            case 1:
                drawhline(x1+1, y1+i, x2-x1-2);
                drawhline(x1+1, y2-i, x2-x1-2);
                break;
            default:
                drawhline(x1, y1+i, x2-x1);
                drawhline(x1, y2-i, x2-x1);
            }
        }
    }
}
// lcd on
void lcdon()
{
    clearCS();
    setCS();
}
// LCD_Init
void lcd_init()
{
    setRESET();
    delay_ms(5);
    clearRESET();
    delay_ms(15);
    setRESET();
    delay_ms(15);
    clearCS();
    switch(display_model)
    {
        case SSD1289:
            lcd_write_com_data(0x00,0x0001);
            lcd_write_com_data(0x03,0xA8A4);
            lcd_write_com_data(0x0C,0x0000);
            lcd_write_com_data(0x0D,0x080C);
            lcd_write_com_data(0x0E,0x2B00);
            lcd_write_com_data(0x1E,0x00B7);
            lcd_write_com_data(0x01,0x2B3F);
            lcd_write_com_data(0x02,0x0600);
            lcd_write_com_data(0x10,0x0000);
            lcd_write_com_data(0x11,0x6070);
            lcd_write_com_data(0x05,0x0000);
            lcd_write_com_data(0x06,0x0000);
            lcd_write_com_data(0x16,0xEF1C);
            lcd_write_com_data(0x17,0x0003);
            lcd_write_com_data(0x07,0x0233);
            lcd_write_com_data(0x0B,0x0000);
            lcd_write_com_data(0x0F,0x0000);
            lcd_write_com_data(0x41,0x0000);
            lcd_write_com_data(0x42,0x0000);
            lcd_write_com_data(0x48,0x0000);
            lcd_write_com_data(0x49,0x013F);
            lcd_write_com_data(0x4A,0x0000);
            lcd_write_com_data(0x4B,0x0000);
            lcd_write_com_data(0x44,0xEF00);
            lcd_write_com_data(0x45,0x0000);
            lcd_write_com_data(0x46,0x013F);
            lcd_write_com_data(0x30,0x0707);
            lcd_write_com_data(0x31,0x0204);
            lcd_write_com_data(0x32,0x0204);
            lcd_write_com_data(0x33,0x0502);
            lcd_write_com_data(0x34,0x0507);
            lcd_write_com_data(0x35,0x0204);
            lcd_write_com_data(0x36,0x0204);
            lcd_write_com_data(0x37,0x0502);
            lcd_write_com_data(0x3A,0x0302);
            lcd_write_com_data(0x3B,0x0302);
            lcd_write_com_data(0x23,0x0000);
            lcd_write_com_data(0x24,0x0000);
            lcd_write_com_data(0x25,0x8000);
            lcd_write_com_data(0x4f,0x0000);
            lcd_write_com_data(0x4e,0x0000);
            lcd_write_com(0x22);
            break;
    }
    setCS();
    setcolor(255,255,255);
    setbackcolor(0,0,0);
    cfont.font=0;
    _transparent=false;
}
// Main
int main()
{
    // initialise variables
    initialise(PORTRAIT);
    // set up MCU
    mcu_setup();
    // lcd on is not strictly necessary for SSD1289
    lcdon();
    // lcd_init produces a fuzzy coloured screen if it works
    lcd_init();
    // some example drawing
    clrscr();
    fillscr(VGA_YELLOW);
    delay_ms(500);
    fillscr(VGA_BLUE);
    setcolor2(VGA_RED);
    fillcircle(100,150, 50);
    setcolor(0,255,0);
    drawcircle(100,200,50);
    drawrect(60,270,100,300);
    fillrect(120,270,180,300);
    drawroundrect(60,60,120,10);
    fillroundrect(130,60,200,10);
    setcolor2(VGA_SILVER);
    drawline(1,1,239,319);
    drawpixel(130,280);
    drawpixel(131,280);
    drawpixel(132,280);
    drawpixel(130,281);
    drawpixel(131,281);
    drawpixel(132,281);
    drawpixel(130,282);
    drawpixel(131,282);
    drawpixel(132,282);
    return 0;
}
  |