Added Patches for Display Quality

Dependents:   GPS_System_with_Google_Maps

Fork of NokiaLCD by Don DeGregori

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NokiaLCD.cpp Source File

NokiaLCD.cpp

00001 /* mbed Nokia LCD Library
00002  * Copyright (c) 2007-2010, sford
00003  */
00004 
00005 #include "NokiaLCD.h"
00006 
00007 #include "mbed.h"
00008 
00009 #define NOKIALCD_ROWS 16
00010 #define NOKIALCD_COLS 16
00011 #define NOKIALCD_WIDTH 132
00012 #define NOKIALCD_HEIGHT 132
00013 #define NOKIALCD_FREQUENCY 5000000
00014 
00015 NokiaLCD::NokiaLCD(PinName mosi, PinName sclk, PinName cs, PinName rst, LCDType type)
00016         : _spi(mosi, NC, sclk)
00017         , _rst(rst)
00018         , _cs(cs) {
00019 
00020     _type = type;
00021 
00022     _row = 0;
00023     _column = 0;
00024     _foreground = 0x00FFFFFF;
00025     _background = 0x00000000;
00026 
00027     reset();
00028 }
00029 
00030 void NokiaLCD::reset() {
00031 
00032     // setup the SPI interface and bring display out of reset
00033     _cs = 1;
00034     _rst = 0;
00035     _spi.format(9);
00036     _spi.frequency(NOKIALCD_FREQUENCY);
00037     wait_ms(1);
00038     _rst = 1;
00039     wait_ms(1);
00040 
00041     _cs = 0;
00042 
00043     switch (_type) {
00044         case LCD6100:
00045             command(0xCA); // display control
00046             data(0);
00047             data(32);
00048             data(0);
00049             command(0xBB);
00050             data(1);
00051             command(0xD1); // oscillator on
00052             command(0x94); // sleep out
00053             command(0x20); // power control
00054             data(0x0F);
00055             command(0xA7); // invert display
00056             command(0x81); // Voltage control
00057             data(39);      // contrast setting: 0..63
00058             data(3);       // resistance ratio
00059             wait_ms(1);
00060             command(0xBC);
00061             data(0);
00062             data(1);
00063             data(4);
00064             command(0xAF);  // turn on the display
00065             break;
00066             
00067         case LCD6610:
00068             command(0xCA);    // display control
00069             data(0);
00070             data(32);
00071             data(0);
00072             command(0xBB);
00073             data(1);
00074             command(0xD1); // oscillator on
00075             command(0x94); // sleep out
00076             command(0x20); // power control
00077             data(0x0F);
00078             command(0xA7); // invert display
00079             command(0x81); // Voltage control
00080             data(39);      // contrast setting: 0..63
00081             data(3);       // resistance ratio
00082             wait_ms(1);
00083             command(0xBC);
00084             data(0);
00085             data(0);
00086             data(2);
00087             command(0xAF);  // turn on the display
00088             break;
00089             
00090         case PCF8833:
00091             command(0x11);  // sleep out
00092             command(0x3A);  // column mode
00093             data(0x05);
00094             command(0x36);  // madctl
00095             data(0xC0);     // vertical RAM, flip x
00096             command(0x25);  // setcon
00097             data(0x30);// contrast 0x30
00098             wait_ms(2);
00099             command(0x29);//DISPON
00100             command(0x03);//BSTRON
00101             //command(0x21);//INVERT COLOR
00102             break;
00103     }
00104 
00105     _cs = 1;
00106 
00107     cls();
00108 }
00109 
00110 void NokiaLCD::command(int value) {
00111     _spi.write(value & 0xFF);
00112 }
00113 
00114 void NokiaLCD::data(int value) {
00115     _spi.write(value | 0x100);
00116 }
00117 
00118 void NokiaLCD::_window(int x, int y, int width, int height) {
00119     int x1 = x + 0;
00120     int y1 = y + 0;
00121     int x2 = x1 + width-1;
00122     int y2 = y1 + height-1;
00123 
00124     switch (_type) {
00125         case LCD6100:
00126         case LCD6610:
00127             command(0x15); // column
00128             data(x1);
00129             data(x2);
00130             command(0x75); // row
00131             data(y1);
00132             data(y2);
00133             command(0x5C); // start write to ram
00134             break;
00135         case PCF8833:
00136             command(0x2A);  // column
00137             data(x1);
00138             data(x2);
00139             command(0x2B); // row
00140             data(y1);
00141             data(y2);
00142             command(0x2C); // start write to ram
00143             break;
00144     }
00145 }
00146 
00147 void NokiaLCD::_putp(int colour) {
00148     /*int gr = ((colour >> 20) & 0x0F)
00149              | ((colour >> 8 ) & 0xF0);
00150     int nb = ((colour >> 4 ) & 0x0F);
00151     data(nb);
00152     data(gr);*/
00153     // USE 24Bit RGB, and shift to 565
00154     //    [R7R6R5R4R3R2R1R0][G7G6G5G4G3G2G1G0][B7B6B5B4B3B2B1B0]
00155     /*
00156     int rg = ((colour      ) & 0xF8)  //  [B7B6B5B4B3______]
00157            | ((colour >> 13) & 0x07); //  [__________G7G6G5] 
00158     int gb = ((colour >> 19 ) & 0x1F) //  [______R7R6R5R4R3]
00159            | ((colour >> 5 ) & 0xE0); //  [G4G3G2__________]
00160     data(rg);
00161     data(gb);
00162     */
00163     int r5=(colour >> 19) & 0x1F;
00164     int g6=(colour >> 10) & 0x3F; 
00165     int b5=(colour >> 3) & 0x1F;
00166     int rg=(r5 << 3) | (g6 >> 3);
00167     int gb=((g6 << 2) & 0xE0)| b5; 
00168     data(rg); 
00169     data(gb);
00170 }
00171 
00172 const unsigned char FONT8x8[97][8] = {
00173     0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00, // columns, rows, num_bytes_per_char
00174     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // space 0x20
00175     0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00, // !
00176     0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00, // "
00177     0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00, // #
00178     0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00, // $
00179     0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00, // %
00180     0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00, // &
00181     0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00, // '
00182     0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00, // (
00183     0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00, // )
00184     0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00, // *
00185     0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00, // +
00186     0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30, // ,
00187     0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00, // -
00188     0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00, // .
00189     0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00, // / (forward slash)
00190     0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00, // 0 0x30
00191     0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00, // 1
00192     0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00, // 2
00193     0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00, // 3
00194     0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00, // 4
00195     0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00, // 5
00196     0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00, // 6
00197     0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00, // 7
00198     0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00, // 8
00199     0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00, // 9
00200     0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00, // :
00201     0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30, // ;
00202     0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00, // <
00203     0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00, // =
00204     0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00, // >
00205     0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00, // ?
00206     0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00, // @ 0x40
00207     0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00, // A
00208     0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00, // B
00209     0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00, // C
00210     0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00, // D
00211     0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00, // E
00212     0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00, // F
00213     0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00, // G
00214     0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00, // H
00215     0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, // I
00216     0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00, // J
00217     0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00, // K
00218     0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00, // L
00219     0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00, // M
00220     0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00, // N
00221     0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00, // O
00222     0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00, // P 0x50
00223     0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00, // Q
00224     0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00, // R
00225     0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00, // S
00226     0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00, // T
00227     0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00, // U
00228     0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00, // V
00229     0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00, // W
00230     0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00, // X
00231     0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00, // Y
00232     0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00, // Z
00233     0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00, // [
00234     0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00, // \ (back slash)
00235     0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00, // ]
00236     0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00, // ^
00237     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF, // _
00238     0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00, // ` 0x60
00239     0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00, // a
00240     0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00, // b
00241     0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00, // c
00242     0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00, // d
00243     0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00, // e
00244     0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00, // f
00245     0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C, // g
00246     0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00, // h
00247     0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00, // i
00248     0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C, // j
00249     0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00, // k
00250     0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, // l
00251     0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00, // m
00252     0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00, // n
00253     0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00, // o
00254     0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78, // p
00255     0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F, // q
00256     0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00, // r
00257     0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00, // s
00258     0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00, // t
00259     0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00, // u
00260     0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00, // v
00261     0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00, // w
00262     0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00, // x
00263     0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C, // y
00264     0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00, // z
00265     0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00, // {
00266     0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00, // |
00267     0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00, // }
00268     0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00, // ~
00269     0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00
00270 }; // DEL
00271 
00272 void NokiaLCD::locate(int column, int row) {
00273     _column = column;
00274     _row = row;
00275 }
00276 
00277 void NokiaLCD::newline() {
00278     _column = 0;
00279     _row++;
00280     if (_row >= _rows) {
00281         _row = 0;
00282     }
00283 }
00284 
00285 int NokiaLCD::_putc(int value) {
00286     int x = _column * 8;  // FIXME: Char sizes
00287     int y = _row * 8;
00288     bitblit(x + 1, y + 1, 8, 8, (char*)&(FONT8x8[value - 0x1F][0]));
00289 
00290     _column++;
00291 
00292     if (_column >= NOKIALCD_COLS) {
00293         _row++;
00294         _column = 0;
00295     }
00296 
00297     if (_row >= NOKIALCD_ROWS) {
00298         _row = 0;
00299     }
00300 
00301     return value;
00302 }
00303 
00304 void NokiaLCD::cls() {
00305     fill(0, 0, NOKIALCD_WIDTH, NOKIALCD_HEIGHT, _background);
00306     _row = 0;
00307     _column = 0;
00308 }
00309 
00310 
00311 void NokiaLCD::window(int x, int y, int width, int height) {
00312     _cs = 0;
00313     _window(x, y, width, height);
00314     _cs = 1;
00315 }
00316 
00317 void NokiaLCD::putp(int colour) {
00318     _cs = 0;
00319     _putp(colour);
00320     _cs = 1;
00321 }
00322 
00323 void NokiaLCD::pixel(int x, int y, int colour) {
00324     _cs = 0;
00325     _window(x, y, 1, 1);
00326      switch (_type) {
00327         case LCD6100:
00328         case PCF8833:
00329            
00330                 _putp(colour);
00331             
00332             break;
00333         case LCD6610:
00334            
00335                 int r4 = (colour >> (16 + 4)) & 0xF;
00336                 int g4 = (colour >> (8 + 4)) & 0xF;
00337                 int b4 = (colour >> (0 + 4)) & 0xF;
00338                 int d1 = (r4 << 4) | g4;
00339                 int d2 = (b4 << 4) | r4;
00340                 int d3 = (g4 << 4) | b4;
00341                 data(d1); 
00342                 data(d2);   
00343                 data(d3);
00344             
00345             break;
00346             }
00347     _cs = 1;
00348 }
00349 
00350 void NokiaLCD::fill(int x, int y, int width, int height, int colour) {
00351     _cs = 0;
00352     _window(x, y, width, height);
00353     switch (_type) {
00354         case LCD6100:
00355         case PCF8833:
00356             for (int i=0; i<width*height; i++) {
00357                 _putp(colour);
00358             }
00359             break;
00360         case LCD6610:
00361             for (int i=0; i<width*height/2; i++) {
00362                 int r4 = (colour >> (16 + 4)) & 0xF;
00363                 int g4 = (colour >> (8 + 4)) & 0xF;
00364                 int b4 = (colour >> (0 + 4)) & 0xF;
00365                 int d1 = (r4 << 4) | g4;
00366                 int d2 = (b4 << 4) | r4;
00367                 int d3 = (g4 << 4) | b4;
00368                 data(d1); 
00369                 data(d2);   
00370                 data(d3);
00371             }
00372             break;
00373     }
00374     _window(0, 0, NOKIALCD_WIDTH, NOKIALCD_HEIGHT);
00375     _cs = 1;
00376 }
00377 
00378 void NokiaLCD::blit(int x, int y, int width, int height, const int* colour) {
00379     _cs = 0;
00380     _window(x, y, width, height);
00381 
00382     switch (_type) {
00383         case LCD6100:
00384         case PCF8833:
00385             for (int i=0; i<width*height; i++) {
00386                  _putp(colour[i]);
00387              }
00388              break;
00389         case LCD6610:
00390             for (int i=0; i<width*height/2; i++) {
00391                 int r41 = (colour[i*2] >> (16 + 4)) & 0xF;
00392                 int g41 = (colour[i*2] >> (8 + 4)) & 0xF;
00393                 int b41 = (colour[i*2] >> (0 + 4)) & 0xF;
00394            
00395                 int r42 = (colour[i*2+1] >> (16 + 4)) & 0xF;
00396                 int g42 = (colour[i*2+1] >> (8 + 4)) & 0xF;
00397                 int b42 = (colour[i*2+1] >> (0 + 4)) & 0xF;   
00398                 int d1 = (r41 << 4) | g41;
00399                 int d2 = (b41 << 4) | r42;
00400                 int d3 = (g42 << 4) | b42;               
00401                    data(d1); 
00402                 data(d2); 
00403                 data(d3); 
00404             }
00405             break;
00406      }            
00407     _window(0, 0, NOKIALCD_WIDTH, NOKIALCD_HEIGHT);
00408     _cs = 1;
00409 }
00410 
00411 void NokiaLCD::bitblit(int x, int y, int width, int height, const char* bitstream) {
00412     _cs = 0;
00413     _window(x, y, width, height);
00414 
00415     switch (_type) {
00416         case LCD6100:
00417         case PCF8833:
00418             for (int i=0; i<height*width; i++) {
00419                 int byte = i / 8;
00420                 int bit = i % 8;
00421                 int colour = ((bitstream[byte] << bit) & 0x80) ? _foreground : _background;
00422                 _putp(colour);
00423             }
00424             break;
00425         case LCD6610:
00426             for(int i=0; i<height*width/2; i++) {
00427                 int byte1 = (i*2) / 8;
00428                 int bit1 = (i*2) % 8;   
00429                 int colour1 = ((bitstream[byte1] << bit1) & 0x80) ? _foreground : _background;
00430                 int byte2 = (i*2+1) / 8;
00431                 int bit2 = (i*2+1) % 8;   
00432                 int colour2 = ((bitstream[byte2] << bit2) & 0x80) ? _foreground : _background;
00433     
00434                 int r41 = (colour1 >> (16 + 4)) & 0xF;
00435                 int g41 = (colour1 >> (8 + 4)) & 0xF;
00436                 int b41 = (colour1 >> (0 + 4)) & 0xF;
00437            
00438                 int r42 = (colour2 >> (16 + 4)) & 0xF;
00439                 int g42 = (colour2 >> (8 + 4)) & 0xF;
00440                 int b42 = (colour2 >> (0 + 4)) & 0xF;   
00441                 int d1 = (r41 << 4) | g41;
00442                 int d2 = (b41 << 4) | r42;
00443                 int d3 = (g42 << 4) | b42;               
00444                    data(d1); 
00445                 data(d2); 
00446                 data(d3); 
00447             }
00448             break;
00449      }
00450     _window(0, 0, _width, _height);
00451     _cs = 1;
00452 }
00453 
00454 void NokiaLCD::foreground(int c) {
00455     _foreground = c;
00456 }
00457 
00458 void NokiaLCD::background(int c) {
00459     _background = c;
00460 }
00461 
00462 int NokiaLCD::width() {
00463     return NOKIALCD_WIDTH;
00464 }
00465 
00466 int NokiaLCD::height() {
00467     return NOKIALCD_HEIGHT;
00468 }
00469 
00470 int NokiaLCD::columns() {
00471     return NOKIALCD_COLS;
00472 }
00473 
00474 int NokiaLCD::rows() {
00475     return NOKIALCD_ROWS;
00476 }