Andrew R
/
Display_Drver_Andrew_1
This is the debugged version of this driver.
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) {}; }