This includes all known improvements from other people's spins on the Nokia library, including Alistair Popple's fix to the very poor contrast on newer LCD 6100 displays.

Fork of NokiaLCD by Iftekhar Choudhury

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 130
00012 #define NOKIALCD_HEIGHT 132
00013 #define NOKIALCD_FREQUENCY 1000000
00014 
00015 NokiaLCD::NokiaLCD(PinName mosi, PinName sclk, PinName cs, PinName rst, LCDType type, int contrast)
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     _rows = NOKIALCD_ROWS;
00027     _columns = NOKIALCD_COLS;
00028 
00029     //reset(contrast);
00030 }
00031 
00032 void NokiaLCD::reset(int contrast) {
00033 
00034     // setup the SPI interface and bring display out of reset
00035     _cs = 1;
00036     _rst = 0;
00037     _spi.format(9);
00038     _spi.frequency(NOKIALCD_FREQUENCY);
00039     wait_ms(1);
00040     _rst = 1;
00041     wait_ms(1);
00042 
00043     _cs = 0;
00044 
00045     switch (_type) {
00046         case LCD6100:
00047             command(0xCA); // display control
00048             data(0xC);
00049             data(32);
00050             data(0);
00051             command(0xBB);
00052             data(1);
00053             command(0xD1); // oscillator on
00054             command(0x94); // sleep out
00055             command(0x20); // power control
00056             data(0x0F);
00057             command(0xA7); // invert display
00058             command(0xBC); // data control
00059             data(0);
00060             data(1);
00061             data(4);
00062             command(0x81); // Voltage control
00063             data(contrast);// contrast setting: 0..63
00064             data(3);       // 3 resistance ratio
00065             wait_ms(10);    // allow power supply to stabilize
00066             command(0xAF);  // turn on the display
00067             break;
00068             
00069         case LCD6610:
00070             command(0xCA);    // display control
00071             data(0);
00072             data(32);
00073             data(0);
00074             command(0xBB);
00075             data(1);
00076             command(0xD1); // oscillator on
00077             command(0x94); // sleep out
00078             command(0x20); // power control
00079             data(0x0F);
00080             command(0xA7); // invert display
00081             command(0x81); // Voltage control
00082             data(contrast);// contrast setting: 0..63
00083             data(3);       // resistance ratio
00084             wait_ms(1);
00085             command(0xBC);
00086             data(0);
00087             data(0);
00088             data(2);
00089             command(0xAF);  // turn on the display
00090             break;
00091             
00092         case PCF8833:
00093             command(0x11);  // sleep out
00094             command(0x3A);  // column mode
00095             data(0x05);
00096             command(0x36);  // madctl
00097             data(0x60);     // vertical RAM, flip x
00098             command(0x25);  // setcon
00099             data(contrast);// contrast 0x30
00100             wait_ms(2);
00101             command(0x29);//DISPON
00102             command(0x03);//BSTRON
00103             break;
00104     }
00105 
00106     _cs = 1;
00107 
00108     cls();
00109 }
00110 
00111 void NokiaLCD::command(int value) {
00112     _spi.write(value & 0xFF);
00113 }
00114 
00115 void NokiaLCD::data(int value) {
00116     _spi.write(value | 0x100);
00117 }
00118 
00119 void NokiaLCD::_window(int x, int y, int width, int height) {
00120     int x1 = x + 0;
00121     int y1 = y + 0;
00122     int x2 = x1 + width - 1;
00123     int y2 = y1 + height - 1;
00124 
00125     switch (_type) {
00126         case LCD6100:
00127         case LCD6610:
00128             command(0x15); // column
00129             data(x1);
00130             data(x2);
00131             command(0x75); // row
00132             data(y1);
00133             data(y2);
00134             command(0x5C); // start write to ram
00135             break;
00136         case PCF8833:
00137             command(0x2A);  // column
00138             data(x1);
00139             data(x2);
00140             command(0x2B); // row
00141             data(y1);
00142             data(y2);
00143             command(0x2C); // start write to ram
00144             break;
00145     }
00146 }
00147 
00148 void NokiaLCD::_putp(int colour) {
00149     int gr = ((colour >> 20) & 0x0F)
00150              | ((colour >> 8 ) & 0xF0);
00151     int nb = ((colour >> 4 ) & 0x0F);
00152     data(nb);
00153     data(gr);
00154 }
00155 
00156 const unsigned char FONT8x8[97][8] = {
00157     0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00, // columns, rows, num_bytes_per_char
00158     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // space 0x20
00159     0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00, // !
00160     0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00, // "
00161     0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00, // #
00162     0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00, // $
00163     0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00, // %
00164     0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00, // &
00165     0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00, // '
00166     0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00, // (
00167     0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00, // )
00168     0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00, // *
00169     0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00, // +
00170     0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30, // ,
00171     0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00, // -
00172     0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00, // .
00173     0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00, // / (forward slash)
00174     0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00, // 0 0x30
00175     0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00, // 1
00176     0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00, // 2
00177     0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00, // 3
00178     0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00, // 4
00179     0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00, // 5
00180     0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00, // 6
00181     0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00, // 7
00182     0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00, // 8
00183     0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00, // 9
00184     0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00, // :
00185     0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30, // ;
00186     0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00, // <
00187     0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00, // =
00188     0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00, // >
00189     0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00, // ?
00190     0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00, // @ 0x40
00191     0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00, // A
00192     0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00, // B
00193     0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00, // C
00194     0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00, // D
00195     0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00, // E
00196     0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00, // F
00197     0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00, // G
00198     0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00, // H
00199     0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, // I
00200     0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00, // J
00201     0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00, // K
00202     0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00, // L
00203     0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00, // M
00204     0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00, // N
00205     0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00, // O
00206     0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00, // P 0x50
00207     0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00, // Q
00208     0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00, // R
00209     0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00, // S
00210     0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00, // T
00211     0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00, // U
00212     0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00, // V
00213     0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00, // W
00214     0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00, // X
00215     0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00, // Y
00216     0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00, // Z
00217     0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00, // [
00218     0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00, // \ (back slash)
00219     0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00, // ]
00220     0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00, // ^
00221     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF, // _
00222     0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00, // ` 0x60
00223     0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00, // a
00224     0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00, // b
00225     0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00, // c
00226     0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00, // d
00227     0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00, // e
00228     0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00, // f
00229     0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C, // g
00230     0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00, // h
00231     0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00, // i
00232     0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C, // j
00233     0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00, // k
00234     0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, // l
00235     0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00, // m
00236     0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00, // n
00237     0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00, // o
00238     0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78, // p
00239     0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F, // q
00240     0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00, // r
00241     0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00, // s
00242     0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00, // t
00243     0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00, // u
00244     0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00, // v
00245     0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00, // w
00246     0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00, // x
00247     0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C, // y
00248     0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00, // z
00249     0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00, // {
00250     0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00, // |
00251     0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00, // }
00252     0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00, // ~
00253     0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00
00254 }; // DEL
00255 
00256 void NokiaLCD::locate(int column, int row) {
00257     _column = column;
00258     _row = row;
00259 }
00260 
00261 void NokiaLCD::newline() {
00262     _column = 0;
00263     _row++;
00264     if (_row >= _rows) {
00265         _row = 0;
00266     }
00267 }
00268 
00269 int NokiaLCD::_putc(int value) {
00270     int x = _column * 8;  // FIXME: Char sizes
00271     int y = _row * 8;
00272     bitblit(x + 1, y + 1, 8, 8, (char*)&(FONT8x8[value - 0x1F][0]));
00273 
00274     _column++;
00275 
00276     if (_column >= NOKIALCD_COLS) {
00277         _row++;
00278         _column = 0;
00279     }
00280 
00281     if (_row >= NOKIALCD_ROWS) {
00282         _row = 0;
00283     }
00284 
00285     return value;
00286 }
00287 
00288 void NokiaLCD::cls() {
00289     fill(0, 0, NOKIALCD_WIDTH, NOKIALCD_HEIGHT, _background);
00290     _row = 0;
00291     _column = 0;
00292 }
00293 
00294 
00295 void NokiaLCD::window(int x, int y, int width, int height) {
00296     _cs = 0;
00297     _window(x, y, width, height);
00298     _cs = 1;
00299 }
00300 
00301 void NokiaLCD::putp(int colour) {
00302     _cs = 0;
00303     _putp(colour);
00304     _cs = 1;
00305 }
00306 
00307 void NokiaLCD::pixel(int x, int y, int colour) {
00308     _cs = 0;
00309     _window(x, y, 1, 1);
00310     _putp(colour);
00311     _cs = 1;
00312 }
00313 
00314 void NokiaLCD::fill(int x, int y, int width, int height, int colour) {
00315     _cs = 0;
00316     _window(x, y, width, height);
00317     switch (_type) {
00318         case LCD6100:
00319         case PCF8833:
00320             for (int i=0; i<width*height; i++) {
00321                 _putp(colour);
00322             }
00323             break;
00324         case LCD6610:
00325             for (int i=0; i<width*height/2; i++) {
00326                 int r4 = (colour >> (16 + 4)) & 0xF;
00327                 int g4 = (colour >> (8 + 4)) & 0xF;
00328                 int b4 = (colour >> (0 + 4)) & 0xF;
00329                 int d1 = (r4 << 4) | g4;
00330                 int d2 = (b4 << 4) | r4;
00331                 int d3 = (g4 << 4) | b4;
00332                 data(d1); 
00333                 data(d2);   
00334                 data(d3);
00335             }
00336             break;
00337     }
00338     _window(0, 0, NOKIALCD_WIDTH, NOKIALCD_HEIGHT);
00339     _cs = 1;
00340 }
00341 
00342 void NokiaLCD::circle(int x0, int y0, int r, int colour) {
00343     int draw_x0, draw_y0;
00344     int draw_x1, draw_y1;
00345     int draw_x2, draw_y2;
00346     int draw_x3, draw_y3;
00347     int draw_x4, draw_y4;
00348     int draw_x5, draw_y5;
00349     int draw_x6, draw_y6;
00350     int draw_x7, draw_y7;
00351     int xx, yy;
00352     int di;    
00353  
00354     _cs = 0;
00355     _window(x0, y0, 1, 1);
00356  
00357     if(r == 0)          /* no radius */
00358     {
00359         return;
00360     }
00361  
00362     draw_x0 = draw_x1 = x0;
00363     draw_y0 = draw_y1 = y0 + r;
00364     if(draw_y0 < NOKIALCD_HEIGHT)
00365     {
00366         _window(draw_x0, draw_y0, 1, 1);
00367         _putp(colour);     /* 90 degree */
00368     }
00369  
00370     draw_x2 = draw_x3 = x0;
00371     draw_y2 = draw_y3 = y0 - r;
00372     if(draw_y2 >= 0)
00373     {
00374         _window(draw_x2, draw_y2, 1, 1);
00375         _putp(colour);    /* 270 degree */
00376     }
00377     
00378     draw_x4 = draw_x6 = x0 + r;
00379     draw_y4 = draw_y6 = y0;
00380     if(draw_x4 < NOKIALCD_WIDTH)
00381     {
00382         _window(draw_x4, draw_y4, 1, 1);
00383         _putp(colour);     /* 0 degree */
00384     }    
00385     
00386     draw_x5 = draw_x7 = x0 - r;
00387     draw_y5 = draw_y7 = y0;
00388     if(draw_x5>=0)
00389     {
00390         _window(draw_x5, draw_y5, 1, 1);
00391         _putp(colour);     /* 90 degree */     /* 180 degree */
00392     }
00393         
00394     if(r == 1)
00395     {
00396         return;
00397     }    
00398     
00399     di = 3 - 2*r;
00400     xx = 0;
00401     yy = r;
00402     while(xx < yy)
00403     {
00404  
00405         if(di < 0)
00406         {
00407             di += 4*xx + 6;
00408         }
00409         else
00410         {
00411             di += 4*(xx - yy) + 10;
00412             yy--;
00413             draw_y0--;
00414             draw_y1--;
00415             draw_y2++;
00416             draw_y3++;
00417             draw_x4--;
00418             draw_x5++;
00419             draw_x6--;
00420             draw_x7++;
00421         }
00422         xx++;
00423         draw_x0++;
00424         draw_x1--;
00425         draw_x2++;
00426         draw_x3--;
00427         draw_y4++;
00428         draw_y5++;
00429         draw_y6--;
00430         draw_y7--;
00431  
00432         if( (draw_x0 <= NOKIALCD_WIDTH) && (draw_y0>=0) )
00433         {
00434             _window(draw_x0, draw_y0, 1, 1);
00435             _putp(colour);
00436         }
00437  
00438         if( (draw_x1 >= 0) && (draw_y1 >= 0) )
00439         {
00440             _window(draw_x1, draw_y1, 1, 1);
00441             _putp(colour);
00442         }
00443  
00444         if( (draw_x2 <= NOKIALCD_WIDTH) && (draw_y2 <= NOKIALCD_HEIGHT) )
00445         {
00446             _window(draw_x2, draw_y2, 1, 1);
00447             _putp(colour);
00448         }
00449  
00450         if( (draw_x3 >=0 ) && (draw_y3 <= NOKIALCD_HEIGHT) )
00451         {
00452             _window(draw_x3, draw_y3, 1, 1);
00453             _putp(colour);
00454         }
00455  
00456         if( (draw_x4 <= /*OLED_DISPLAY_HEIGHT*/NOKIALCD_WIDTH) && (draw_y4 >= 0) )
00457         {
00458             _window(draw_x4, draw_y4, 1, 1);
00459             _putp(colour);
00460         }
00461  
00462         if( (draw_x5 >= 0) && (draw_y5 >= 0) )
00463         {
00464             _window(draw_x5, draw_y5, 1, 1);
00465             _putp(colour);
00466         }
00467         if( (draw_x6 <= NOKIALCD_WIDTH) && (draw_y6 <= NOKIALCD_HEIGHT) )
00468         {
00469             _window(draw_x6, draw_y6, 1, 1);
00470             _putp(colour);
00471         }
00472         if( (draw_x7 >= 0) && (draw_y7 <= NOKIALCD_HEIGHT) )
00473         {
00474             _window(draw_x7, draw_y7, 1, 1);
00475             _putp(colour);
00476         }
00477     }
00478     _cs = 1;
00479     return;
00480 }
00481  
00482 void NokiaLCD::line(int x0, int y0, int x1, int y1, int colour) {
00483     int   dx = 0, dy = 0;
00484     int   dx_sym = 0, dy_sym = 0;
00485     int   dx_x2 = 0, dy_x2 = 0;
00486     int   di = 0;
00487  
00488     _cs = 0;            // Chipselect the LCD. 
00489  
00490     dx = x1-x0;
00491     dy = y1-y0;
00492  
00493  
00494     if(dx == 0)           /* vertical line */
00495     {
00496         for(int y=y0; y<y1; y++){
00497             _window(x0, y, 1, 1);
00498             _putp(colour);
00499         }
00500         return;
00501     }
00502  
00503     if(dx > 0)
00504     {
00505         dx_sym = 1;
00506     }
00507     else
00508     {
00509         dx_sym = -1;
00510     }
00511  
00512  
00513     if(dy == 0)           /* horizontal line */
00514     {
00515         for(int x=x0; x<x1; x++){
00516             _window(x, y0, 1, 1);
00517             _putp(colour);
00518         }
00519         return;
00520     }
00521  
00522  
00523     if(dy > 0)
00524     {
00525         dy_sym = 1;
00526     }
00527     else
00528     {
00529         dy_sym = -1;
00530     }
00531  
00532     dx = dx_sym*dx;
00533     dy = dy_sym*dy;
00534  
00535     dx_x2 = dx*2;
00536     dy_x2 = dy*2;
00537  
00538     if(dx >= dy)
00539     {
00540         di = dy_x2 - dx;
00541         while(x0 != x1)
00542         {
00543  
00544             _window(x0, y0, 1, 1);
00545             _putp(colour);
00546             x0 += dx_sym;
00547             if(di<0)
00548             {
00549                 di += dy_x2;
00550             }
00551             else
00552             {
00553                 di += dy_x2 - dx_x2;
00554                 y0 += dy_sym;
00555             }
00556         }
00557         _window(x0, y0, 1, 1);
00558         _putp(colour);
00559     }
00560     else
00561     {
00562         di = dx_x2 - dy;
00563         while(y0 != y1)
00564         {
00565             _window(x0, y0, 1, 1);
00566             _putp(colour);
00567             y0 += dy_sym;
00568             if(di < 0)
00569             {
00570                 di += dx_x2;
00571             }
00572             else
00573             {
00574                 di += dx_x2 - dy_x2;
00575                 x0 += dx_sym;
00576             }
00577         }
00578         _window(x0, y0, 1, 1);
00579         _putp(colour);
00580     }
00581     _cs = 1;
00582     return;
00583 }
00584 
00585 void NokiaLCD::blit(int x, int y, int width, int height, const int* colour) {
00586     _cs = 0;
00587     _window(x, y, width, height);
00588 
00589     switch (_type) {
00590         case LCD6100:
00591         case PCF8833:
00592             for (int i=0; i<width*height; i++) {
00593                  _putp(colour[i]);
00594              }
00595              break;
00596         case LCD6610:
00597             for (int i=0; i<width*height/2; i++) {
00598                 int r41 = (colour[i*2] >> (16 + 4)) & 0xF;
00599                 int g41 = (colour[i*2] >> (8 + 4)) & 0xF;
00600                 int b41 = (colour[i*2] >> (0 + 4)) & 0xF;
00601            
00602                 int r42 = (colour[i*2+1] >> (16 + 4)) & 0xF;
00603                 int g42 = (colour[i*2+1] >> (8 + 4)) & 0xF;
00604                 int b42 = (colour[i*2+1] >> (0 + 4)) & 0xF;   
00605                 int d1 = (r41 << 4) | g41;
00606                 int d2 = (b41 << 4) | r42;
00607                 int d3 = (g42 << 4) | b42;               
00608                    data(d1); 
00609                 data(d2); 
00610                 data(d3); 
00611             }
00612             break;
00613      }            
00614     _window(0, 0, NOKIALCD_WIDTH, NOKIALCD_HEIGHT);
00615     _cs = 1;
00616 }
00617 
00618 void NokiaLCD::bitblit(int x, int y, int width, int height, const char* bitstream) {
00619     _cs = 0;
00620     _window(x, y, width, height);
00621 
00622     switch (_type) {
00623         case LCD6100:
00624         case PCF8833:
00625             for (int i=0; i<height*width; i++) {
00626                 int byte = i / 8;
00627                 int bit = i % 8;
00628                 int colour = ((bitstream[byte] << bit) & 0x80) ? _foreground : _background;
00629                 _putp(colour);
00630             }
00631             break;
00632         case LCD6610:
00633             for(int i=0; i<height*width/2; i++) {
00634                 int byte1 = (i*2) / 8;
00635                 int bit1 = (i*2) % 8;   
00636                 int colour1 = ((bitstream[byte1] << bit1) & 0x80) ? _foreground : _background;
00637                 int byte2 = (i*2+1) / 8;
00638                 int bit2 = (i*2+1) % 8;   
00639                 int colour2 = ((bitstream[byte2] << bit2) & 0x80) ? _foreground : _background;
00640     
00641                 int r41 = (colour1 >> (16 + 4)) & 0xF;
00642                 int g41 = (colour1 >> (8 + 4)) & 0xF;
00643                 int b41 = (colour1 >> (0 + 4)) & 0xF;
00644            
00645                 int r42 = (colour2 >> (16 + 4)) & 0xF;
00646                 int g42 = (colour2 >> (8 + 4)) & 0xF;
00647                 int b42 = (colour2 >> (0 + 4)) & 0xF;   
00648                 int d1 = (r41 << 4) | g41;
00649                 int d2 = (b41 << 4) | r42;
00650                 int d3 = (g42 << 4) | b42;               
00651                    data(d1); 
00652                 data(d2); 
00653                 data(d3); 
00654             }
00655             break;
00656      }
00657     _window(0, 0, _width, _height);
00658     _cs = 1;
00659 }
00660 
00661 void NokiaLCD::foreground(int c) {
00662     _foreground = c;
00663 }
00664 
00665 void NokiaLCD::background(int c) {
00666     _background = c;
00667 }
00668 
00669 int NokiaLCD::width() {
00670     return NOKIALCD_WIDTH;
00671 }
00672 
00673 int NokiaLCD::height() {
00674     return NOKIALCD_HEIGHT;
00675 }
00676 
00677 int NokiaLCD::columns() {
00678     return NOKIALCD_COLS;
00679 }
00680 
00681 int NokiaLCD::rows() {
00682     return NOKIALCD_ROWS;
00683 }