This is the debugged version of this driver.

Dependencies:   mbed

main.cpp

Committer:
andrewcrussell
Date:
2013-11-21
Revision:
0:901166f03471

File content as of revision 0:901166f03471:

/***********************************************************************************/
/***** Newhaven NHD-5.7-640480WF-CTXL# Display Driver **********/
/***** for mbed (www.mbed,org) NXP LPC1768 32 bit ARM MCU ******/
/********* Adapted by Andrew C. Russell,  March 2011 ***********/

/************I hereby acknowledge and thank the following ******/
/***software authors whose code I have adapted and/or adopted***/
/*******************to create these drivers:- ******************/

//Curt Lagerstam - Newhaven Display International, LLC for the dispay initialization.
//James P Lynch - code adapted from his Nokia LCD display tutorial at
//http://www.sparkfun.com/tutorial/Nokia%206100%20LCD%20Display%20Driver.pdf
//Akifumi 'Tedd' Okano for assistance and adapting the .bmp display driver
/***********************************************************************************/

#include "mbed.h"
#include "font.h"
#include "stdlib.h"
#include "string.h"


/***********************************************************************************/
/********************************** Colors *****************************************/
/********* taken directly from http://web.njit.edu/~kevin/rgb.txt.html**************/
#define BLACK       0x000000
#define WHITE       0xFFFFFF
#define BLACK       0x000000
#define RED         0xFF0000
#define GREEN       0x00FF00
#define BLUE        0x0000FF
#define GREY        0xBEBEBE
#define DEEPINK     0xFF1493

#define PASET       0x2B
#define CASET       0x2A
#define DISON       0x29
#define DISOFF      0x28
#define DEEPSLEEP   0xE5
#define RAMWR       0x2C
#define RAMCT       0x3C
#define RESET       0x01
#define DISINV      0x21
#define DISNOR      0x20
#define NOP         0x00
#define XMAX        640
#define YMAX        480
#define TRUE        1

// Font sizes
#define SMALL 0
#define MEDIUM 1
#define LARGE 2

//---------------------------------------------------------
DigitalOut CS(p13);                         /* chip select the SSD1963 active LOW */
//DigitalOut RS(p14);                       /* reset  to SSD1963  - not used in this implementation*/
DigitalOut nWR(p15);                        /* write out to SSD1963 active LOW */
DigitalOut nRD(p16);                        /* read data from SSD1963 active LOW - but not used */
DigitalOut DC(p17);                         /* Data/Command Select: 1=Command,  0=Data); */
DigitalOut myled(LED1);                     /* for test purposes only - on the mbed module */

/* data bus I/O pins */
BusOut DB(p5,p6,p7,p8,p9,p10,p11,p12);    /* databus D0-D7 */
/* forward references */
unsigned int fill;
unsigned int radius;

//unsigned char FONT6x8[97][8];
//unsigned char FONT8x8[97][8];
//unsigned char FONT8x16[97][8];
unsigned char command;
unsigned char data1;
int DOWN;
int RIGHT;
void LCDSetXY(unsigned int x,unsigned int y);
void LCDClearScreen(void);
//void LCDSetXY(int x, int y);
void LCDSetPixel(unsigned int x, unsigned int y, unsigned int color);
void LCDSetLine(int x1, int y1, int x2, int y2, int color);
void LCDSetRect(unsigned int x0, unsigned  int y0, unsigned int x1, unsigned int y1, unsigned int fill, unsigned int color);
void LCDSetCircle(unsigned int x0, unsigned int y0, unsigned int radius, unsigned int color);
void LCDPutChar(char c, unsigned int x, unsigned int y, unsigned int size, unsigned int fcolor, unsigned int bcolor);
void LCDPutString (char *lcd_string, const char *font_style, unsigned char x, unsigned char y,
                   unsigned char fcolor, unsigned char bcolor);

//******************************************************************************
void Write_Command(unsigned char command) {
    CS=1; /* just to make sure */
    nRD = 1; /* make sure the RD is HIGH just to be sure */
    DC=0;
    nWR = 0;
    CS=0;
    DB=command;
    CS = 1;
    nWR = 1;

}
//;******************************************************************************
void Write_Data(unsigned char data1) {
    CS=1; /* just to make sure */
    nRD = 1;
    DC=1;
    nWR = 0;
    CS=0;
    DB=data1;//write(data1);
    CS = 1;
    nWR = 1;
}

//====================================================
void Command_Write(unsigned char REG,unsigned char VALUE) {
    Write_Command(REG);
    Write_Data(VALUE);
}
//======================================================
void SendData(unsigned long color) {
    Write_Data((color)>>16);        //red
    Write_Data((color)>>8);         //green
    Write_Data(color);              //blue
}
/********************************************************************************/
void WindowSet(unsigned int s_x,unsigned int e_x,unsigned int s_y,unsigned int e_y) {
    Write_Command(CASET);           //SET page address
    Write_Data((s_x)>>8);           //SET start page address=0
    Write_Data(s_x);
    Write_Data((e_x)>>8);           //SET end page address=639
    Write_Data(e_x);
    Write_Command(PASET);           //SET column address
    Write_Data((s_y)>>8);           //SET start column address=0
    Write_Data(s_y);
    Write_Data((e_y)>>8);           //SET end column address=479
    Write_Data(e_y);
}

/***************************************************************************/
/* this routine locates the screen pointer at position XY in the frame buffer */
void LCDSetXY(unsigned int x,unsigned int y) {
    Write_Command(CASET);           //SET page address
    Write_Data((x)>>8);             //SET start page address=0
    Write_Data(x);
    Write_Data((XMAX)>>8);          //SET end page address=XMAX
    Write_Data(XMAX);
    Write_Command(PASET);           //SET column address
    Write_Data((y)>>8);             //SET start column address=0
    Write_Data(y);
    Write_Data((YMAX)>>8);          //SET end column address=YMAX
    Write_Data(YMAX);
    Write_Command(RAMWR);           //ready to now start writing the data
                                    //when returnung to the caller
}

/***************************************************************************/
// initialize controller
void Init_SSD1963 (void) {

    Write_Command(0x01);            //Software Reset
    wait_ms(10);
    Write_Command(0x01);            //Software Reset
    wait_ms(10);
    Write_Command(0x01);            //Software Reset
    wait_ms(10);
    Command_Write(0xe0,0x01);       //START PLL
    wait_us(1);
    Command_Write(0xe0,0x03);    //LOCK PLL
    Write_Command(0xb0);         //SET LCD MODE  SET TFT 18Bits MODE
    Write_Data(0x0c);            //SET TFT MODE & hsync+Vsync+DEN MODE
    Write_Data(0x80);            //SET TFT MODE & hsync+Vsync+DEN MODE
    Write_Data(0x02);            //SET horizontal size=640-1 HightByte
    Write_Data(0x7f);            //SET horizontal size=640-1 LowByte
    Write_Data(0x01);            //SET vertical size=480-1 HightByte
    Write_Data(0xdf);            //SET vertical size=480-1 LowByte
    Write_Data(0x00);            //SET even/odd line RGB seq.=RGB
    Command_Write(0xf0,0x00);    //SET pixel data I/F format=8bit
    Command_Write(0x3a,0x60);    // SET R G B format = 6 6 6
    Write_Command(0xe6);         //SET PCLK freq=4.94MHz  ; pixel clock frequency
    Write_Data(0x02);
    Write_Data(0xff);
    Write_Data(0xff);
    Write_Command(0xb4);         //SET HBP,
    Write_Data(0x02);            //SET HSYNC Total=760
    Write_Data(0xf8);
    Write_Data(0x00);            //SET HBP 68
    Write_Data(0x44);
    Write_Data(0x0f);            //SET VBP 16=15+1
    Write_Data(0x00);            //SET Hsync pulse start position
    Write_Data(0x00);
    Write_Data(0x00);            //SET Hsync pulse subpixel start position
    Write_Command(0xb6);         //SET VBP,
    Write_Data(0x01);            //SET Vsync total
    Write_Data(0xf8);
    Write_Data(0x00);            //SET VBP=19
    Write_Data(0x13);
    Write_Data(0x07);            //SET Vsync pulse 8=7+1
    Write_Data(0x00);            //SET Vsync pulse start position
    Write_Data(0x00);
    Write_Command(0x2a);         //SET column address
    Write_Data(0x00);            //SET start column address=0
    Write_Data(0x00);
    Write_Data(0x02);            //SET end column address=639
    Write_Data(0x7f);
    Write_Command(0x2b);         //SET page address
    Write_Data(0x00);            //SET start page address=0
    Write_Data(0x00);
    Write_Data(0x01);            //SET end page address=479
    Write_Data(0xdf);
    Write_Command(0x29);         //SET display on
}

//========================== This section displays 4 blocks of colour =================================
void QUADS() {
    unsigned int i,j;
    WindowSet(0x0000,0x027f,0x0000,0x01df); /*this incorprates Write_Command*/
    Write_Command(RAMWR);  /* start writing the data to memory */
    for (j= 0 ;j<240;j++) {
        for (i=0;i<320;i++) {
            SendData(0x00FF00);             //GREEN
        }
        for (i=0;i<320;i++) {
            SendData(0xFF0000);             //RED
        }
    }
    for (j= 0 ;j<240;j++) {
        for (i=0;i<320;i++) {
            SendData(0xBEBEBE);             //GREY
        }
        for (i=0;i<320;i++) {
            SendData(0xFF1493);             //DEEP PINK
        }
    }
}
/********************************************************************************/
void clear_to_color(void) {
    int m,n;
    WindowSet(0,640,0,480); // 0-640 wide by 0-480 high
    Write_Command(RAMWR);
    for (m=0;m<480;m++) {
        for (n=0;n<640;n++) {
            SendData(BLUE);
        }
    }
}

/***************************************************************************/
/******* this routine lights up a single pixel to a specific colour ********/
void LCDSetPixel(unsigned int x,unsigned int y, unsigned int color) {
    Write_Command(CASET);           //SET page address
    Write_Data((x)>>8);             //SET start page address=0
    Write_Data(x);
    Write_Data((XMAX)>>8);          //SET end page address=XMAX
    Write_Data(XMAX);
    Write_Command(PASET);           //SET column address
    Write_Data((y)>>8);             //SET start column address=0
    Write_Data(y);
    Write_Data((YMAX)>>8);          //SET end column address=YMAX
    Write_Data(YMAX);
    Write_Command(RAMWR);           //ready to now start writing the data
    //when returnung to the caller
    SendData(color);
    Write_Command(NOP);
}
/***************************************************************************/
/*********This routine draws a line between 2 points on the screen**********/
void LCDSetLine(int x0, int y0, int x1, int y1, int color) {
    int dy = y1 - y0;
    int dx = x1 - x0;
    int stepx, stepy;
    if (dy < 0) {
        dy = -dy;
        stepy = -1;
    } else {
        stepy = 1;
    }
    if (dx < 0) {
        dx = -dx;
        stepx = -1;
    } else {
        stepx = 1;
    }
    dy <<= 1; // dy is now 2*dy
    dx <<= 1; // dx is now 2*dx
    LCDSetPixel(x0, y0, color);
    if (dx > dy) {
        int fraction = dy - (dx >> 1); // same as 2*dy - dx
        while (x0 != x1) {
            if (fraction >= 0) {
                y0 += stepy;
                fraction -= dx; // same as fraction -= 2*dx
            }
            x0 += stepx;
            fraction += dy; // same as fraction -= 2*dy
            LCDSetPixel(x0, y0, color);
        }
    } else {
        int fraction = dx - (dy >> 1);
        while (y0 != y1) {
            if (fraction >= 0) {
                x0 += stepx;
                fraction -= dy;
            }
            y0 += stepy;
            fraction += dx;
            LCDSetPixel(x0, y0, color);
        }
    }
}
/***************************************************************************/
/********** draw a rectangle, filled or not filled *************************/
void LCDSetRect(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, unsigned int fill, unsigned int color) {
    unsigned int xmin, xmax, ymin, ymax;
    int i;
//unsigned char FILL;
// check if the rectangle is to be filled
    if (fill == TRUE) {
// best way to create a filled rectangle is to define a drawing box
// and loop two pixels at a time
// calculate the min and max for x and y directions
        xmin = (x0 <= x1) ? x0 : x1;
        xmax = (x0 > x1) ? x0 : x1;
        ymin = (y0 <= y1) ? y0 : y1;
        ymax = (y0 > y1) ? y0 : y1;
        Write_Command(CASET);           //SET page address
        Write_Data((x0)>>8);             //SET start page address=0
        Write_Data(x0);
        Write_Data((x1)>>8);          //SET end page address=XMAX
        Write_Data(x1);
        Write_Command(PASET);           //SET column address
        Write_Data((y0)>>8);             //SET start column address=0
        Write_Data(y0);
        Write_Data((y1)>>8);          //SET end column address=YMAX
        Write_Data(y1);
        Write_Command(RAMWR);           //ready to now start writing the data
        for (i = 0; i < ((((xmax - xmin + 1) * (ymax - ymin + 1)) / 2) + 1); i++) {
            SendData(color);
        }
    } else {
        LCDSetLine(x0, y0, x1, y0, color);
        LCDSetLine(x0, y1, x1, y1, color);
        LCDSetLine(x0, y0, x0, y1, color);
        LCDSetLine(x1, y0, x1, y1, color);
    }
}

/***************************************************************************/
void LCDSetCircle(unsigned int x0, unsigned int y0, unsigned int radius, unsigned int color) {
    int f = 1 - radius;
    int ddF_x = 0;
    int ddF_y = -2 * radius;
    int x = 0;
    int y = radius;
    LCDSetPixel(x0, y0 + radius, color);
    LCDSetPixel(x0, y0 - radius, color);
    LCDSetPixel(x0 + radius, y0, color);
    LCDSetPixel(x0 - radius, y0, color);
    while (x < y) {
        if (f >= 0) {
            y--;
            ddF_y += 2;
            f += ddF_y;
        }
        x++;
        ddF_x += 2;
        f += ddF_x + 1;
        LCDSetPixel(x0 + x, y0 + y, color);
        LCDSetPixel(x0 - x, y0 + y, color);
        LCDSetPixel(x0 + x, y0 - y, color);
        LCDSetPixel(x0 - x, y0 - y, color);
        LCDSetPixel(x0 + y, y0 + x, color);
        LCDSetPixel(x0 - y, y0 + x, color);
        LCDSetPixel(x0 + y, y0 - x, color);
        LCDSetPixel(x0 - y, y0 - x, color);
    }
}
/***************************************************************************/
void LCDPutChar(char c, unsigned int x, unsigned int y, int size, unsigned int fColor, unsigned int bColor) {
    extern const unsigned char FONT6x8[97][8];
    extern const unsigned char FONT8x8[97][8];
    extern const unsigned char FONT8x16[97][16];
    int i,j;
    unsigned int nCols;
    unsigned int nRows;
    unsigned int nBytes;
    unsigned char PixelRow;
    unsigned char Mask;
    unsigned int Word0;
    unsigned int Word1;
    unsigned char *pFont;
    unsigned char *pChar;
    unsigned char *FontTable[] = {(unsigned char *)FONT6x8,
                                  (unsigned char *)FONT8x8,
                                  (unsigned char *)FONT8x16
                                 };
// get pointer to the beginning of the selected font table
    pFont = (unsigned char *)FontTable[size];
// get the nColumns, nRows and nBytes in the font table
    nCols = *pFont;
    nRows = *(pFont + 1);
    nBytes = *(pFont + 2);
// get pointer to the last byte of the desired character - i.e. last byte in the row
    pChar = pFont + (nBytes * (c - 0x1F)) + nBytes - 1;
// Row address set (command 0x2B) - x position on the LCD 
    Write_Command(PASET);
    Write_Data(x);
    Write_Data(x + nRows - 1);
// Column address set (command 0x2A) - y position on the LCD
    Write_Command(CASET);
    Write_Data(y); Write_Data(y);
    Write_Data(y + nCols - 1);
// Write Memory - get ready to start writing the character
    Write_Command(RAMWR);
// loop on each row, working backwards from top to bottom
    for (i = nRows - 1; i >= 0; i--) {
// copy pixel row from font table and then decrement row
        PixelRow = *pChar--;
// loop on each pixel in the row (left to right)
// Note: we do two pixels each loop
        Mask = 0x80;
        for (j = 0; j < nCols; j += 2) {
// if pixel bit set, use foreground color; else use the background color
// now get the pixel color for two successive pixels
            if ((PixelRow & Mask) == 0)
                Word0 = bColor;
            else
                Word0 = fColor;
            Mask = Mask >> 1;
            if ((PixelRow & Mask) == 0)
                Word1 = bColor;
            else
                Word1 = fColor;
            Mask = Mask >> 1;
// use this information to output three data bytes
            Write_Data((Word0 >> 4) & 0xFF);
            Write_Data(((Word0 & 0xF) << 4) | ((Word1 >> 8) & 0xF));
            Write_Data(Word1 & 0xFF);
        }
    }
// terminate the Write Memory command
    Write_Command(NOP);
}
// *************************************************************************************************




int main(void) {

    int h;
    Serial pc(USBTX, USBRX);
    wait_ms(10);
    Init_SSD1963();


    LCDSetXY(230,230);
    QUADS();
    clear_to_color();


    LCDSetXY(340,200);
    {
        for (h=0;h<200;h++)
            SendData(WHITE);
    }

    LCDSetXY(350,210);
    {
        for (h=0;h<200;h++)
            SendData(DEEPINK);
    }

    LCDSetPixel(400,300,BLACK);//working
    LCDSetPixel(405,305,DEEPINK);//working
    LCDSetLine(0,300,250,10,DEEPINK);//working
    LCDSetRect(100,100,250,250,1,DEEPINK);//working
    LCDSetRect(200,200,350,350,0,BLACK);//working
    LCDSetCircle(320,240,150,WHITE);//working
    LCDSetCircle(320,240,155,WHITE);//working
    LCDSetCircle(320,240,160,WHITE);//working
    LCDPutChar('E',10,10,1, WHITE, BLACK);
    //LCDPutStr("This guy is nuts", 115, 2, LARGE, BLACK, CYAN);
    Write_Command(NOP);

    while (1) {};
}