Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: EthernetNetIf mbed
Diff: main.cpp
- Revision:
- 0:d6b0747774da
- Child:
- 1:c9dad7bc0795
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Nov 29 22:25:48 2010 +0000 @@ -0,0 +1,719 @@ +// ********************************************************************* +// +// Display driver for Solomon SSD2119 controller connected to mbed board +// with simple terminal program +// +// ** szdiditalsquare (eBay) display connected on SPI + control pins ** +// mbed SSD2219 (on szdigitalsquare board) +// p5 -mosi (28) SDA +// p6 -miso NC +// p7 -sck (26) SCL +// p8 -cs (19) CS +// p15-res (23) RESET +// p16-c/d (20) RS +// p17-rd (22) RD +// p18-wr (21) WR +// +// Pins PS0 - PS3 should be open on system board = 4bit SPI mode +// +// After sucessful init you'll see color bars on whole display and +// welcome message. Then you can start typing in your serial terminal +// and information will appear on the display +// +// 28.11.2010 port from CrystalFonts & Nokia LCD lib by Imrich Konkol +// 29.11.2010 ZX Spectrum SCR viewer added +// - to show test.scr from internal mbed drive type \\ at +// PC terminal prompt +// ********************************************************************* +#include "mbed.h" + + +// color definitions (H = half) +#define BLACK 0x0000 +#define HBLUE 0x0010 +#define BLUE 0x001F +#define HRED 0x8000 +#define RED 0xF800 +#define HGREEN 0x0400 +#define GREEN 0x07E0 +#define HCYAN 0x0410 +#define CYAN 0x07FF +#define HMAGENTA 0x8010 +#define MAGENTA 0xF81F +#define HYELLOW 0x8400 +#define YELLOW 0xFFE0 +#define HWHITE 0x8410 +#define WHITE 0xFFFF + +// Define Spectrum colors +static const uint16_t colors [15] = { + BLACK,HBLUE,HRED,HMAGENTA,HGREEN,HCYAN,HYELLOW,HWHITE,BLUE,RED,MAGENTA,GREEN,CYAN,YELLOW,WHITE +}; + +#define HRES 320 // X axis # of pixels +#define VRES 240 // Y axis # of pixels + +#define START_X 31 +#define START_Y 23 + +LocalFileSystem local("local"); + +SPI spi(p5, p6, p7); // mosi, miso, sclk +DigitalOut DCS(p8); // Display chip select +DigitalOut DRS(p15); // Display reset +DigitalOut DCD(p16); // Display command/data +DigitalOut DRD(p17); // Display read +DigitalOut DWR(p18); // Display write + +DigitalOut myled(LED1); + + +Serial pc(USBTX, USBRX); //debug info - see raw data being transferred back and forth as GBA is booting + +#define LCD_CACHE_SIZE 5 +/*----------------------------------------------------------------------------- + Global Variables +-----------------------------------------------------------------------------*/ +//static uint8_t LcdCache [ LCD_CACHE_SIZE ]; + +//static int LcdCacheIdx; +//static int LoWaterMark; +//static int HiWaterMark; +static uint16_t yy=0; +static uint16_t xx=0; + +// Essential display commands +/*************************************************/ +void write_command(uint16_t command) { + uint8_t raw; + + DRD = 1; + DCS = 0; + DCD = 0; + + raw = command; + //raw &= 0x00FF; // Keep bit9 low - means command + //printf("Raw data: %d\n",raw); + spi.write(raw); + + DWR = 1; + DCS = 1; +} + +/*************************************************/ + +//typedef unsigned char u8; +//typedef unsigned int u16; +void write_data(uint16_t value) { + uint8_t raw; + + DRD = 1; + DCD = 1; + DCS = 0; + + raw = (value)>>8; + // raw &= 0x00FF; // Keep bit9 high - means data + // raw |= 0x0100; + // printf("Raw data: %d\n",raw); + spi.write(raw); + + DCS = 1; + //wait_ms(1); + DCS = 0; + + raw = value; + // raw &= 0x00FF; // Keep bit9 high - means data + // raw |= 0x0100; + // printf("Raw data: %d\n",raw); + spi.write(raw); + + DCS = 1; +} + + +// Font generator +/*----------------------------------------------------------------------------- + Character generator + + This table defines the standard ASCII characters in a 5x7 dot format. +-----------------------------------------------------------------------------*/ +static const uint8_t FontLookup [][5] = { + { 0x00, 0x00, 0x00, 0x00, 0x00 }, // sp + { 0x00, 0x00, 0x2f, 0x00, 0x00 }, // ! + { 0x00, 0x07, 0x00, 0x07, 0x00 }, // " + { 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // # + { 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $ + { 0xc4, 0xc8, 0x10, 0x26, 0x46 }, // % + { 0x36, 0x49, 0x55, 0x22, 0x50 }, // & + { 0x00, 0x05, 0x03, 0x00, 0x00 }, // ' + { 0x00, 0x1c, 0x22, 0x41, 0x00 }, // ( + { 0x00, 0x41, 0x22, 0x1c, 0x00 }, // ) + { 0x14, 0x08, 0x3E, 0x08, 0x14 }, // * + { 0x08, 0x08, 0x3E, 0x08, 0x08 }, // + + { 0x00, 0x00, 0x50, 0x30, 0x00 }, // , + { 0x10, 0x10, 0x10, 0x10, 0x10 }, // - + { 0x00, 0x60, 0x60, 0x00, 0x00 }, // . + { 0x20, 0x10, 0x08, 0x04, 0x02 }, // / + { 0x3E, 0x51, 0x49, 0x45, 0x3E }, // 0 + { 0x00, 0x42, 0x7F, 0x40, 0x00 }, // 1 + { 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2 + { 0x21, 0x41, 0x45, 0x4B, 0x31 }, // 3 + { 0x18, 0x14, 0x12, 0x7F, 0x10 }, // 4 + { 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5 + { 0x3C, 0x4A, 0x49, 0x49, 0x30 }, // 6 + { 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7 + { 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8 + { 0x06, 0x49, 0x49, 0x29, 0x1E }, // 9 + { 0x00, 0x36, 0x36, 0x00, 0x00 }, // : + { 0x00, 0x56, 0x36, 0x00, 0x00 }, // ; + { 0x08, 0x14, 0x22, 0x41, 0x00 }, // < + { 0x14, 0x14, 0x14, 0x14, 0x14 }, // = + { 0x00, 0x41, 0x22, 0x14, 0x08 }, // > + { 0x02, 0x01, 0x51, 0x09, 0x06 }, // ? + { 0x32, 0x49, 0x59, 0x51, 0x3E }, // @ + { 0x7E, 0x11, 0x11, 0x11, 0x7E }, // A + { 0x7F, 0x49, 0x49, 0x49, 0x36 }, // B + { 0x3E, 0x41, 0x41, 0x41, 0x22 }, // C + { 0x7F, 0x41, 0x41, 0x22, 0x1C }, // D + { 0x7F, 0x49, 0x49, 0x49, 0x41 }, // E + { 0x7F, 0x09, 0x09, 0x09, 0x01 }, // F + { 0x3E, 0x41, 0x49, 0x49, 0x7A }, // G + { 0x7F, 0x08, 0x08, 0x08, 0x7F }, // H + { 0x00, 0x41, 0x7F, 0x41, 0x00 }, // I + { 0x20, 0x40, 0x41, 0x3F, 0x01 }, // J + { 0x7F, 0x08, 0x14, 0x22, 0x41 }, // K + { 0x7F, 0x40, 0x40, 0x40, 0x40 }, // L + { 0x7F, 0x02, 0x0C, 0x02, 0x7F }, // M + { 0x7F, 0x04, 0x08, 0x10, 0x7F }, // N + { 0x3E, 0x41, 0x41, 0x41, 0x3E }, // O + { 0x7F, 0x09, 0x09, 0x09, 0x06 }, // P + { 0x3E, 0x41, 0x51, 0x21, 0x5E }, // Q + { 0x7F, 0x09, 0x19, 0x29, 0x46 }, // R + { 0x46, 0x49, 0x49, 0x49, 0x31 }, // S + { 0x01, 0x01, 0x7F, 0x01, 0x01 }, // T + { 0x3F, 0x40, 0x40, 0x40, 0x3F }, // U + { 0x1F, 0x20, 0x40, 0x20, 0x1F }, // V + { 0x3F, 0x40, 0x38, 0x40, 0x3F }, // W + { 0x63, 0x14, 0x08, 0x14, 0x63 }, // X + { 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y + { 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z + { 0x00, 0x7F, 0x41, 0x41, 0x00 }, // [ + { 0x00, 0x06, 0x18, 0x60, 0x00 }, // backslash + { 0x00, 0x41, 0x41, 0x7F, 0x00 }, // ] + { 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^ + { 0x40, 0x40, 0x40, 0x40, 0x40 }, // _ + { 0x00, 0x01, 0x02, 0x04, 0x00 }, // ' + { 0x20, 0x54, 0x54, 0x54, 0x78 }, // a + { 0x7F, 0x48, 0x44, 0x44, 0x38 }, // b + { 0x38, 0x44, 0x44, 0x44, 0x20 }, // c + { 0x38, 0x44, 0x44, 0x48, 0x7F }, // d + { 0x38, 0x54, 0x54, 0x54, 0x18 }, // e + { 0x08, 0x7E, 0x09, 0x01, 0x02 }, // f + { 0x0C, 0x52, 0x52, 0x52, 0x3E }, // g + { 0x7F, 0x08, 0x04, 0x04, 0x78 }, // h + { 0x00, 0x44, 0x7D, 0x40, 0x00 }, // i + { 0x20, 0x40, 0x44, 0x3D, 0x00 }, // j + { 0x7F, 0x10, 0x28, 0x44, 0x00 }, // k + { 0x00, 0x41, 0x7F, 0x40, 0x00 }, // l + { 0x7C, 0x04, 0x18, 0x04, 0x78 }, // m + { 0x7C, 0x08, 0x04, 0x04, 0x78 }, // n + { 0x38, 0x44, 0x44, 0x44, 0x38 }, // o + { 0x7C, 0x14, 0x14, 0x14, 0x08 }, // p + { 0x08, 0x14, 0x14, 0x18, 0x7C }, // q + { 0x7C, 0x08, 0x04, 0x04, 0x08 }, // r + { 0x48, 0x54, 0x54, 0x54, 0x20 }, // s + { 0x04, 0x3F, 0x44, 0x40, 0x20 }, // t + { 0x3C, 0x40, 0x40, 0x20, 0x7C }, // u + { 0x1C, 0x20, 0x40, 0x20, 0x1C }, // v + { 0x3C, 0x40, 0x30, 0x40, 0x3C }, // w + { 0x44, 0x28, 0x10, 0x28, 0x44 }, // x + { 0x0C, 0x50, 0x50, 0x50, 0x3C }, // y + { 0x44, 0x64, 0x54, 0x4C, 0x44 }, // z + { 0x08, 0x36, 0x41, 0x41, 0x00 }, // { + { 0x00, 0x00, 0x7F, 0x00, 0x00 }, // | + { 0x00, 0x41, 0x41, 0x36, 0x08 }, // } + { 0x01, 0x02, 0x01, 0x02, 0x00 }, // ~ + { 0x3E, 0x5D, 0x55, 0x55, 0x3E }, // (c) + { 0x55, 0x2A, 0x55, 0x2A, 0x55 } // 55 +}; + +// Set X & Y axis of next pixel write +void LcdSetPenXY(uint16_t x, uint16_t y) { + write_command(0x004F); // RAM address set for Y axis + write_data(y); // Page 58 of SSD2119 datasheet + write_command(0x004E); // RAM address set for X axis + write_data(x); // Page 58 of SSD2119 datasheet + write_command(0x0022); // Return back to pixel write mode +} + + +/*----------------------------------------------------------------------------- + Name : LcdGotoXY + Description : Sets cursor location to xy location corresponding to basic + font size. + Argument(s) : x, y -> Coordinate for new cursor position. Range: 1,1..14,6 + Return value : None. +-----------------------------------------------------------------------------*/ +void LcdGotoXY ( uint8_t x, uint8_t y ) { + // uint16_t xx, yy; + xx = y * 8; + yy = x * 6; + //LcdCacheIdx = (x - 1) * HRES + (y - 1) * VRES; + LcdSetPenXY(xx,yy); +} + +typedef enum { + FONT_1X = 1, + FONT_2X = 2 + +} LcdFontSize; + +typedef enum { + PIXEL_OFF = 0, + PIXEL_ON = 1, + PIXEL_XOR = 2 + +} LcdPixelMode; + +/*----------------------------------------------------------------------------- + Name : LcdChr + Description : Displays a character at current cursor location + and increment cursor location. + Argument(s) : size -> Font size. See enum. + ch -> Character to write. + Return value : None. +-----------------------------------------------------------------------------*/ +void LcdChr ( uint8_t ch ) { + uint8_t i, j, c; + + if ( (ch < 0x20) || (ch > 0x7F) ) { + // Convert to a printable character. + ch = 0x80; + } + + //write_command(0x0022); + + for ( i = 0; i < 6; i++ ) { + if (i < 5) { + c = FontLookup[ch - 32][i]; + } else { + c = 0x00; // Space after each character + } + + for ( j = 0; j < 8; j++ ) { + if ( (c & 0x01) == 0x01 ) { + //printf("X"); + write_data(BLACK); + } else { + //printf("."); + write_data(WHITE); + } + //printf("\n"); + c >>= 1; + } + yy++; + write_command(0x004F); // RAM address set for Y axis + write_data(yy); // Page 58 of SSD2119 datasheet + write_command(0x0022); + } +} + +/*----------------------------------------------------------------------------- + Name : LcdStr + Description : Displays a character at current cursor location and increment + cursor location according to font size. + Argument(s) : size -> Font size. See enum. + dataPtr -> Pointer to null terminated ASCII string to display. + Return value : None. +-----------------------------------------------------------------------------*/ +void LcdStr ( char *dataPtr ) { + while ( *dataPtr ) { + LcdChr( *dataPtr++ ); + } +} + + +/*************************************************/ +void initialization() { + /* + SET_RD; + SET_WR; + SET_CS; + SET_CD; + PORTA=0x00; + PORTE=0x00; + + CLR_RESET; + delay(200); + SET_RESET; + delay(500); + */ + DRD = 1; + DWR = 1; + DCS = 1; + DCD = 1; + + DRS = 0; + wait_ms(200); + DRS = 1; + wait_ms(500); + + write_command(0x0028); // VCOM OTP + write_data(0x0006); // Page 55-56 of SSD2119 datasheet + + write_command(0x0000); // start Oscillator + write_data(0x0001); // Page 36 of SSD2119 datasheet + + write_command(0x0010); // Sleep mode + write_data(0x0000); // Page 49 of SSD2119 datasheet + + write_command(0x0001); // Driver Output Control + write_data(0x32EF); // Page 36-39 of SSD2119 datasheet + + write_command(0x0002); // LCD Driving Waveform Control + write_data(0x0600); // Page 40-42 of SSD2119 datasheet + + write_command(0x0003); // Power Control 1 + write_data(0x6A38); // Page 43-44 of SSD2119 datasheet + + write_command(0x0011); // Entry Mode + write_data(0x6870); // Page 50-52 of SSD2119 datasheet + + write_command(0x000F); // Gate Scan Position + write_data(0x0000); // Page 49 of SSD2119 datasheet + + write_command(0x000B); // Frame Cycle Control + write_data(0x5308); // Page 45 of SSD2119 datasheet + + write_command(0x000C); // Power Control 2 + write_data(0x0003); // Page 47 of SSD2119 datasheet + + write_command(0x000D); // Power Control 3 + write_data(0x000A); // Page 48 of SSD2119 datasheet + + write_command(0x000E); // Power Control 4 + write_data(0x2E00); // Page 48 of SSD2119 datasheet + + write_command(0x001E); // Power Control 5 + write_data(0x00BE); // Page 53 of SSD2119 datasheet + + write_command(0x0025); // Frame Frequency Control + write_data(0x8000); // Page 53 of SSD2119 datasheet + + write_command(0x0026); // Analog setting + write_data(0x7800); // Page 54 of SSD2119 datasheet + + write_command(0x004E); // Ram Address Set + write_data(0x0000); // Page 58 of SSD2119 datasheet + + write_command(0x004F); // Ram Address Set + write_data(0x0000); // Page 58 of SSD2119 datasheet + + write_command(0x0012); // Sleep mode + write_data(0x08D9); // Page 49 of SSD2119 datasheet + + // Gamma Control (R30h to R3Bh) -- Page 56 of SSD2119 datasheet + write_command(0x0030); + write_data(0x0000); + + write_command(0x0031); + write_data(0x0104); + + write_command(0x0032); + write_data(0x0100); + + write_command(0x0033); + write_data(0x0305); + + write_command(0x0034); + write_data(0x0505); + + write_command(0x0035); + write_data(0x0305); + + write_command(0x0036); + write_data(0x0707); + + write_command(0x0037); + write_data(0x0300); + + write_command(0x003A); + write_data(0x1200); + + write_command(0x003B); + write_data(0x0800); + + write_command(0x0007); // Display Control + write_data(0x0033); // Page 45 of SSD2119 datasheet + + wait_ms(150); + + write_command(0x0022); // RAM data write/read +} + +/*************************************************/ +void Display_Home() { + xx = 0; + yy = 0; + write_command(0x004E); // RAM address set + write_data(0x0000); // Page 58 of SSD2119 datasheet + write_command(0x004F); // RAM address set + write_data(0x0000); // Page 58 of SSD2119 datasheet + + write_command(0x0044); // Vertical RAM address position + write_data(0xEF00); // Page 57 of SSD2119 datasheet + write_command(0x0045); // Horizontal RAM address position + write_data(0x0000); // Page 57 of SSD2119 datasheet + write_command(0x0046); // Horizontal RAM address position + write_data(0x013F); // Page 57 of SSD2119 datasheet + + write_command(0x0022); // RAM data write/read +} + + +void display_rgb(unsigned int data) { + unsigned int i,j; + Display_Home(); + for (i=0;i<HRES;i++) { + for (j=0;j<VRES;j++) { + write_data(data); + } + } +} + +void LCD_test() { + //uint16_t i; + unsigned int i,j; + //bool b; + Display_Home(); + + printf("Disp home done.\n"); + for (i=0; i<HRES;i++) { + //b = 0; + for (j=0;j<VRES;j++) { + + /* + if (j < (VRES/2)) { + b = 0; + } else { + b = 1; + } + */ + //if (j == 120) b=1; + //b=1; + if (i>279)write_data(BLACK); + else if (i>259) write_data(BLUE); //{ if (b) { write_data(BLUE); } else { write_data(HBLUE); } } + else if (i>239) write_data(HBLUE); + else if (i>219) write_data(RED); //{ if (b) { write_data(RED); } else { write_data(HRED); } } + else if (i>199) write_data(HRED); + else if (i>179) write_data(MAGENTA); //{ if (b) { write_data(MAGENTA); } else { write_data(HMAGENTA); } } + else if (i>159) write_data(HMAGENTA); + else if (i>139) write_data(GREEN); //{ if (b) { write_data(GREEN); } else { write_data(HGREEN); } } + else if (i>119) write_data(HGREEN); + else if (i>99) write_data(CYAN); //{ if (b) { write_data(CYAN); } else { write_data(HCYAN); } } + else if (i>79) write_data(HCYAN); + else if (i>59) write_data(YELLOW); //{ if (b) { write_data(YELLOW); } else { write_data(HYELLOW); } } + else if (i>39) write_data(HYELLOW); + else if (i>19) write_data(WHITE); + else write_data(HWHITE); //{ if (b) { write_data(WHITE); } else { write_data(HWHITE); } } + } + //printf("Col = %d\n",i); + } +} + +void cls() { + // write_command(0x22); + display_rgb(WHITE); +} + +unsigned char cat(char *filename) { + char c; + unsigned int x,y; + + printf("Opening File...\n"); // Drive should be marked as removed + FILE *fp = fopen(filename, "r"); + if (!fp) { + printf("File %s could not be opened!\n",filename); + return(1); + } + cls(); + Display_Home(); + x = 0; + y = 0; + + while ( ( c=fgetc(fp) ) != EOF ) { + + LcdGotoXY(x,y); + + if (c == 13) { + y++; + x=0; + }; + if (c == 8) { + x--; + }; + + if (c > 31) LcdChr(c); + x++; + if (x>39) { + y++; + x=0; + if (y>39) y=0; + } + } + fclose(fp); + return(0); +} + + +unsigned char scr2lcd(char *scrfile) { + unsigned char c,a,ink,pap; + unsigned int x,y,i,j,k,l,m; + unsigned char screen[6912]; + + printf("Opening File...\n"); // Drive should be marked as removed + FILE *fp = fopen("/local/test.scr", "r"); + if (!fp) { + printf("File %s could not be opened!\n",scrfile); + return(1); + } + + //cls(); // Keep border, do not cls + Display_Home(); + x=START_X; + y=START_Y; + LcdSetPenXY(x,y); + + write_command(0x22); + + i=0; + while ( ( ( c = fgetc(fp) ) != EOF ) && (i<6912) ) { + screen[i] = c; + i++; + } + fclose(fp); + printf("Screen read done."); + + for (j=0;j<3;j++) { // Screen "third" + for (i=0;i<8;i++) { // Line in third + for (k=0;k<8;k++) { // Microline + for (l=32;l>0;l--) { // Byte + c = screen[j * 2048 + k * 256 + i * 32 + (l-1)]; + for (m=0;m<8;m++) { // Pixel + a = screen[6144+ j * 256 + i * 32 + (l-1)]; + ink = a & 0x07; + pap = (a >>=3) & 0x07; + if ( (a & 0x70) == 0x70 ) { // Bright1 + if ( ink != 0 ) ink = ink+8; + if ( pap != 0 ) pap = pap+8; + } + + if ( (c & 0x01) == 0x01 ) { + write_data(colors[ink]); + } else { + write_data(colors[pap]); + } + c >>= 1; + } + } + y++; + x=START_X; + LcdSetPenXY(x,y); + + } + } + } + + + return(0); +} + + +// Main loop starts here +int main() { + + uint8_t x,y; + char c,xc=' '; + //Configure the Fastest Baud Rate + pc.baud(115200); + + printf("Program start.\n"); + + // Setup the spi for 8 bit data, high steady state clock, + // second edge capture, with a 10 MHz clock rate + spi.format(8,3); // CPOL=1, CPHA=1 + spi.frequency(10000000); // SPI fastest possible + + printf("SPI initialized.\n"); + myled = 0; + + while (1) { + + initialization(); + + printf("Display initialized.\n"); + + LCD_test(); + + printf("Display test.\n"); + + wait(1.0); + + if (myled == 0) { + myled = 1; + } else { + myled = 0; + } + + Display_Home(); + LcdGotoXY(13,10); + LcdChr('H'); + LcdGotoXY(14,10); + LcdChr('e'); + LcdGotoXY(15,10); + LcdChr('l'); + LcdGotoXY(16,10); + LcdChr('l'); + LcdGotoXY(17,10); + LcdChr('o'); + + LcdStr(" World!"); + + LcdGotoXY(4,11); + LcdStr("Below you can see what you write"); + LcdGotoXY(12,12); + LcdStr("in your PC terminal"); + + wait(5.0); + + x = 0; + y = 13; + while (1) { + LcdGotoXY(x,y); + c = pc.getc(); + if (c == 13) { + y++; + x=0; + }; + if (c == 8) { + x--; + }; + + if (c > 31) { + LcdChr(c); + if ( (xc == '\\' ) && ( c == '\\' ) ) { + scr2lcd("test.scr"); + } + + xc = c; + } + x++; + if (x>39) { + y++; + x=0; + if (y>39) y=0; + } + } + } + +}