LS020.h is a MobileLCD library for the LS020 display (used in GSM Siemens S65 family). Resolution 176x132

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LS020LCD.cpp Source File

LS020LCD.cpp

00001 /* mbed LS020 Library, for driving the LCD display LS020 from SHARP used in 
00002  * GSM S65 Siemens
00003  *
00004  * Copyright (c) 2010, Wim De Roeve, thanks to Christian Kranz research
00005  *
00006  * Permission is hereby granted, free of charge, to any person obtaining a copy
00007  * of this software and associated documentation files (the "Software"), to deal
00008  * in the Software without restriction, including without limitation the rights
00009  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00010  * copies of the Software, and to permit persons to whom the Software is
00011  * furnished to do so, subject to the following conditions:
00012  *
00013  * The above copyright notice and this permission notice shall be included in
00014  * all copies or substantial portions of the Software.
00015  *
00016  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00019  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00020  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00021  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00022  * THE SOFTWARE.
00023  */
00024 
00025 #include "LS020LCD.h"
00026 #include "mbed.h"
00027 
00028 #include "fonts/font_6x8.h"
00029 #include "fonts/font_8x8.h"
00030 #include "fonts/font_8x12.h"
00031 #include "fonts/font_clock.h"
00032 
00033 #define TINYFONT                       (0)   //6x8
00034 #define TINYFONT_NAME                  font0
00035 #define TINYFONT_START                 FONT0_START
00036 #define TINYFONT_WIDTH                 FONT0_WIDTH
00037 #define TINYFONT_HEIGHT                FONT0_HEIGHT
00038 #define SMALLFONT                      (1)  //8x8
00039 #define SMALLFONT_NAME                 font1
00040 #define SMALLFONT_START                FONT1_START
00041 #define SMALLFONT_WIDTH                FONT1_WIDTH
00042 #define SMALLFONT_HEIGHT               FONT1_HEIGHT
00043 #define NORMALFONT                     (2)  //8x12
00044 #define NORMALFONT_NAME                font2
00045 #define NORMALFONT_START               FONT2_START
00046 #define NORMALFONT_WIDTH               FONT2_WIDTH
00047 #define NORMALFONT_HEIGHT              FONT2_HEIGHT
00048 #define TIMEFONT                       (3)  //Clock
00049 #define TIMEFONT_NAME                  font3
00050 #define TIMEFONT_START                 FONT3_START
00051 #define TIMEFONT_WIDTH                 FONT3_WIDTH
00052 #define TIMEFONT_HEIGHT                FONT3_HEIGHT
00053 
00054 // colors in 8 bit mode BGR off   RRRGGGBB
00055 #define BLACK  0x00
00056 #define WHITE  0xFF
00057 #define RED    0xE0
00058 #define GREEN  0x1C
00059 #define BLUE   0x03
00060 
00061 using namespace mbed;
00062 
00063 unsigned int checkbit(const unsigned long *data, unsigned int nr);
00064 
00065 
00066 LS020LCD::LS020LCD(PinName mosi, PinName miso, PinName clk, PinName cs, PinName rst, PinName rs)
00067         : _spi(mosi, miso, clk)
00068         , _rst(rst)
00069         , _cs(cs)
00070         , _rs(rs) {
00071     _rotate=false;
00072     _mirror=false;
00073     reset();
00074 }
00075 
00076 void LS020LCD::write_cmdRG(uint8_t reg, uint8_t param) {
00077     _rs = 1; //cmd
00078     _cs = 0;
00079     _spi.write(reg);
00080     _spi.write(param);
00081     _cs = 1;
00082 }
00083 
00084 void LS020LCD::write_cmd8(uint8_t cmd8) {
00085     _rs = 1; //cmd
00086     _cs = 0;
00087     _spi.write(cmd8);
00088     _cs = 1;
00089 }
00090 
00091 void LS020LCD::write_cmd16(uint16_t cmd16) {
00092     _rs = 1; //cmd
00093     _cs = 0;
00094     _spi.write((cmd16>>8)&0xFF);
00095     _spi.write(cmd16&0xFF);
00096     _cs = 1;
00097 }
00098 
00099 void LS020LCD::write_data8(char data) {
00100     _rs = 0; //data
00101     _cs = 0;
00102     _spi.write(data);
00103     _cs = 1;
00104 }
00105 
00106 void LS020LCD::write_data16(uint16_t cmd16) {
00107     _rs = 0; //data
00108     _cs = 0;
00109     _spi.write((cmd16>>8)&0xFF);
00110     _spi.write(cmd16&0xFF);
00111     _cs = 1;
00112 }
00113 
00114 void LS020LCD::draw(uint16_t cmd16) {
00115     _spi.write((cmd16>>8)&0xFF);
00116     _spi.write(cmd16&0xFF);
00117 }
00118 
00119 void LS020LCD::drawstop(void) {
00120     _cs = 1;
00121 }
00122 
00123 
00124 void LS020LCD::drawstart(void) {
00125     _rs = 0; //data
00126     _cs = 0;
00127 }
00128 
00129 void LS020LCD::locate(int column, int row) {
00130     _row = row;
00131     _column = column;
00132 }
00133 
00134 void LS020LCD::newline() {
00135     _column = 0;
00136     _row++;
00137     if (_row >= _rows) {
00138         _row = 0;
00139     }
00140 }
00141 
00142 int LS020LCD::columns() {
00143     return _columns;
00144 }
00145 
00146 int LS020LCD::rows() {
00147     return _rows;
00148 }
00149 
00150 // ***************** Init and reset
00151 
00152 void LS020LCD::orientation(bool rotate, bool mirror) {
00153     _rotate=rotate;
00154     _mirror=mirror;
00155 
00156     if (_rotate==0) {  //default = 176 x 132
00157         _width=132;
00158         _height=176;
00159     } else {          //132 x 176
00160         _width=176;
00161         _height=132;
00162     }
00163 }
00164 
00165 void LS020LCD::reset(void) {
00166 
00167     const unsigned char init_array_0[20]={
00168         0xEF, 0x00, 0xEE, 0x04, 0x1B, 0x04, 0xFE, 0xFE,
00169         0xFE, 0xFE, 0xEF, 0x90, 0x4A, 0x04, 0x7F, 0x3F,
00170         0xEE, 0x04, 0x43, 0x06
00171     };
00172 
00173     const unsigned char init_array_1[46]= {
00174         0xEF, 0x90, 0x09, 0x83, 0x08, 0x00, 0x0B, 0xAF,
00175         0x0A, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00,
00176         0xEF, 0x00, 0xEE, 0x0C, 0xEF, 0x90, 0x00, 0x80,
00177         0xEF, 0xB0, 0x49, 0x02, 0xEF, 0x00, 0x7F, 0x01,
00178         0xE1, 0x81, 0xE2, 0x02, 0xE2, 0x76, 0xE1, 0x83,
00179         0x80, 0x01, 0xEF, 0x90, 0x00, 0x00
00180     };
00181 
00182     int i;
00183 
00184     // Setup the spi for 8 bit data, high steady state clock,
00185     // second edge capture, with a 8MHz clock rate
00186 
00187     _spi.format(8,3);
00188     _spi.frequency(8000000);
00189 
00190     //reset
00191     _cs = 1;
00192     _rs = 1;
00193     _rst= 0;
00194 
00195     wait_ms(50);
00196 
00197     _rst = 1;
00198     wait_ms(50);
00199     _cs = 0;
00200 
00201     write_cmd16(0xFDFD);
00202     write_cmd16(0xFDFD);
00203 
00204     wait_ms(68);
00205 
00206     //init part 1
00207     for (i=0;i<20;i++) {
00208         write_cmd8(init_array_0[i]);
00209     }
00210 
00211     //important: wait 10ms
00212     wait_ms(10);
00213 
00214     //init part 2
00215     for (i=0;i<46;i++) {
00216         write_cmd8(init_array_1[i]);
00217     }
00218 
00219     orientation(_rotate,_mirror);
00220     set_window(0, 0, (_width-1), (_height-1));
00221     
00222     _foreground=BLACK;
00223     _background=WHITE;
00224     _row=0;
00225     _column=0;
00226     _font=1;
00227     
00228     cls();
00229 
00230     return;
00231 
00232 };
00233 
00234 // *****************  MODE settings
00235 
00236 void LS020LCD::set_8bit_mode(char BGR) {
00237     // BGR=0 - disabled, BGR=1 - enabled.
00238     write_cmd16(0xE800+(BGR&0x01)*0x40);
00239 }
00240 
00241 void LS020LCD::set_16bit_mode(void) {
00242     write_cmd16(0xE80F);
00243 }
00244 
00245 void LS020LCD::set_8_color_mode(void) {
00246     write_cmd16(0x0401);
00247     write_cmd16(0x0000);
00248 }
00249 
00250 void LS020LCD::set_65k_color_mode(void) {
00251     write_cmd16(0x0400);
00252     write_cmd16(0x0000);
00253 }
00254 
00255 void LS020LCD::foreground(unsigned int color) {
00256     _foreground = color;
00257 }
00258 
00259 void LS020LCD::background(unsigned int color) {
00260     _background = color;
00261 }
00262 
00263 // ****************
00264 
00265 void LS020LCD::set_cursor(unsigned int x, unsigned int y) {
00266     write_cmd16(0xEF90);
00267 
00268     if (_rotate) {
00269         if (_mirror) {
00270             write_cmdRG(0x06, (_width-1)-x);  //set x cursor pos
00271             write_cmdRG(0x07, (_height-1)-y); //set y cursor pos
00272         } else {
00273             write_cmdRG(0x06, x);             //set x cursor pos
00274             write_cmdRG(0x07, y);             //set y cursor pos
00275         }
00276     } else {
00277         if (_mirror) {
00278             write_cmdRG(0x06, (_height-1)-y); //set y cursor pos
00279             write_cmdRG(0x07, x);             //set x cursor pos
00280         } else {
00281             write_cmdRG(0x06, y);             //set y cursor pos
00282             write_cmdRG(0x07, (_width-1)-x);  //set x cursor pos
00283         }
00284     }
00285 }
00286 
00287 void LS020LCD::set_window(char x0, char y0, char x1,char y1) {
00288      write_cmd16(0x0500);// Set Direction
00289      write_cmd16(0x0A00+x0);
00290      write_cmd16(0x0B00+x1);
00291      write_cmd16(0x0800+y0);
00292      write_cmd16(0x0900+y1);
00293 
00294    /*
00295      write_cmd16(0xEF90);
00296    
00297     if (_rotate) {
00298         if (_mirror) {
00299             write_cmdRG(0x08, (_width-1)-x0);  //set x0
00300             write_cmdRG(0x09, (_width-1)-x1);  //set x1
00301             write_cmdRG(0x0A, (_height-1)-y0); //set y0
00302             write_cmdRG(0x0B, (_height-1)-y1); //set y1
00303         } else {
00304             write_cmdRG(0x08, x0);                //set x0
00305             write_cmdRG(0x09, x1);                //set x1
00306             write_cmdRG(0x0A, y0);                //set y0
00307             write_cmdRG(0x0B, y1);                //set y1
00308         }
00309     } else {
00310         if (_mirror) {
00311             write_cmdRG(0x08, (_height-1)-y0); //set y0
00312             write_cmdRG(0x09, (_height-1)-y1); //set y1
00313             write_cmdRG(0x0A, x0);                //set x0
00314             write_cmdRG(0x0B, x1);                //set x1
00315         } else {
00316             write_cmdRG(0x08, y0);                //set y0
00317             write_cmdRG(0x09, y1);                //set y1
00318             write_cmdRG(0x0A, (_width-1)-x0);  //set x0
00319             write_cmdRG(0x0B, (_width-1)-x1);  //set x1
00320         }
00321     }
00322 
00323     //set cursor
00324     set_cursor(x0, y0);*/
00325 
00326 }
00327 
00328 unsigned int LS020LCD::putc(unsigned int x, unsigned int y, unsigned int c, unsigned int size,unsigned int font, unsigned int color, unsigned int bgcolor) {
00329     unsigned int ret, i, j, width, height, w, h, wh;
00330     const unsigned long *ptr;
00331 
00332     switch (font) {
00333         case TINYFONT:
00334             c     -= TINYFONT_START;
00335             ptr    = (const unsigned long*)&TINYFONT_NAME[c*(TINYFONT_WIDTH*TINYFONT_HEIGHT/8)];
00336             width  = TINYFONT_WIDTH;
00337             height = TINYFONT_HEIGHT;
00338             break;
00339         case SMALLFONT:
00340             c     -= SMALLFONT_START;
00341             ptr    = (const unsigned long*)&SMALLFONT_NAME[c*(SMALLFONT_WIDTH*SMALLFONT_HEIGHT/8)];
00342             width  = SMALLFONT_WIDTH;
00343             height = SMALLFONT_HEIGHT;
00344             break;
00345         case NORMALFONT:
00346             c     -= NORMALFONT_START;
00347             ptr    = (const unsigned long*)&NORMALFONT_NAME[c*(NORMALFONT_WIDTH*NORMALFONT_HEIGHT/8)];
00348             width  = NORMALFONT_WIDTH;
00349             height = NORMALFONT_HEIGHT;
00350             break;
00351         case TIMEFONT:
00352             c     -= TIMEFONT_START;
00353             ptr    = (const unsigned long*)&TIMEFONT_NAME[c*(TIMEFONT_WIDTH*TIMEFONT_HEIGHT/8)];
00354             width  = TIMEFONT_WIDTH;
00355             height = TIMEFONT_HEIGHT;
00356             break;
00357     }
00358 
00359     ret = x+(width*size);
00360     if (ret > _width) {
00361         return _width+1;
00362     }
00363 
00364     if (size <= 1) {
00365         set_window(x, y, x+(+width-1), y+(height-1));
00366         drawstart();
00367 
00368         unsigned long data, mask;
00369         for (wh=(width*height)/32; wh!=0; wh--) {
00370             data = *ptr++;
00371             //data = ((data&0xFF000000UL)>>24)|((data&0x00FF0000UL)>>8)|((data&0x0000FF00UL)<<8)|((data&0x000000FFUL)<<24); //swap32
00372             for (mask=0x80000000UL; mask!=0UL; mask>>=1) {
00373                 if (data & mask) {
00374                     draw(color);
00375                 } else {
00376                     draw(bgcolor);
00377                 }
00378             }
00379         }
00380 
00381         drawstop();
00382     } else {
00383         set_window(x, y, x+(width*size)-1, y+(height*size)-1);
00384         drawstart();
00385 
00386         unsigned int bit;
00387         wh = (width*height);
00388         for (h=0; h<wh; h+=width) {
00389             for (i=size; i!=0; i--) {
00390                 bit = h;
00391                 for (w=0; w<width; w++) {
00392                     if (checkbit(ptr, bit++)) {
00393                         for (j=size; j!=0; j--) {
00394                             draw(color);
00395                         }
00396                     } else {
00397                         for (j=size; j!=0; j--) {
00398                             draw(bgcolor);
00399                         }
00400                     }
00401                 }
00402             }
00403         }
00404 
00405         drawstop();
00406     }
00407 
00408     return ret;
00409 }
00410 
00411 
00412 void LS020LCD::fillrectangle(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, unsigned int color) {
00413     unsigned int wh, tmp;
00414 
00415     if (x0 > x1) {
00416         tmp = x0;
00417         x0  = x1;
00418         x1  = tmp;
00419     }
00420     if (y0 > y1) {
00421         tmp = y0;
00422         y0  = y1;
00423         y1  = tmp;
00424     }
00425 
00426     if ((x1 >= _width) ||
00427             (y1 >= _height)) {
00428         return;
00429     }
00430 
00431     set_window(x0, y0, x1, y1);
00432 
00433     drawstart();
00434     for (wh=((1+(x1-x0))*(1+(y1-y0))); wh!=0; wh--) {
00435         draw(color);
00436     }
00437     drawstop();
00438 
00439     return;
00440 }
00441 
00442 void LS020LCD::drawpixel(unsigned int x, unsigned int y, unsigned int color) {
00443     if ((x >= _width) ||
00444             (y >= _height)) {
00445         return;
00446     }
00447     set_cursor(x, y);
00448     drawstart();
00449     draw(color);
00450     drawstop();
00451 
00452     return;
00453 }
00454 
00455 void LS020LCD::drawline(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, unsigned int color) {
00456     int dx, dy, dx2, dy2, stepx, stepy, err;
00457 
00458     if ((x0 == x1) ||
00459             (y0 == y1)) { //horizontal or vertical line
00460         fillrectangle(x0, y0, x1, y1, color);
00461     } else {
00462         //calculate direction
00463         dx = x1 - x0;
00464         dy = y1 - y0;
00465         if (dx < 0) {
00466             dx = -dx;
00467             stepx = -1;
00468         } else {
00469             stepx = +1;
00470         }
00471         if (dy < 0) {
00472             dy = -dy;
00473             stepy = -1;
00474         } else {
00475             stepy = +1;
00476         }
00477         dx2 = dx << 1;
00478         dy2 = dy << 1;
00479         //draw line
00480         set_window(0, 0, (_width-1), (_height-1));
00481         drawpixel(x0, y0, color);
00482         if (dx > dy) {
00483             err = dy2 - dx;
00484             while (x0 != x1) {
00485                 if (err >= 0) {
00486                     err -= dx2;
00487                     y0  += stepy;
00488                 }
00489                 err += dy2;
00490                 x0  += stepx;
00491                 drawpixel(x0, y0, color);
00492             }
00493         } else {
00494             err = dx2 - dy;
00495             while (y0 != y1) {
00496                 if (err >= 0) {
00497                     err -= dy2;
00498                     x0  += stepx;
00499                 }
00500                 err += dx2;
00501                 y0  += stepy;
00502                 drawpixel(x0, y0, color);
00503             }
00504         }
00505     }
00506 
00507     return;
00508 }
00509 
00510 void LS020LCD::drawrectangle(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, unsigned int color) {
00511     fillrectangle(x0, y0, x0, y1, color);
00512     fillrectangle(x0, y1, x1, y1, color);
00513     fillrectangle(x1, y0, x1, y1, color);
00514     fillrectangle(x0, y0, x1, y0, color);
00515 
00516     return;
00517 }
00518 
00519 
00520 void LS020LCD::fillcircle(unsigned int x0, unsigned int y0, unsigned int radius, unsigned int color) {
00521     int err, x, y;
00522 
00523     err = -radius;
00524     x   = radius;
00525     y   = 0;
00526 
00527     set_window(0, 0, (_width-1), (_height-1));
00528 
00529     while (x >= y) {
00530         drawline(x0 - x, y0 + y, x0 + x, y0 + y, color);
00531         drawline(x0 - x, y0 - y, x0 + x, y0 - y, color);
00532         drawline(x0 - y, y0 + x, x0 + y, y0 + x, color);
00533         drawline(x0 - y, y0 - x, x0 + y, y0 - x, color);
00534 
00535         err += y;
00536         y++;
00537         err += y;
00538         if (err >= 0) {
00539             x--;
00540             err -= x;
00541             err -= x;
00542         }
00543     }
00544 
00545     return;
00546 }
00547 
00548 
00549 void  LS020LCD::drawcircle(unsigned int x0, unsigned int y0, unsigned int radius, unsigned int color) {
00550     int err, x, y;
00551 
00552     err = -radius;
00553     x   = radius;
00554     y   = 0;
00555 
00556     set_window(0, 0, (_width-1), (_height-1));
00557 
00558     while (x >= y) {
00559         drawpixel(x0 + x, y0 + y, color);
00560         drawpixel(x0 - x, y0 + y, color);
00561         drawpixel(x0 + x, y0 - y, color);
00562         drawpixel(x0 - x, y0 - y, color);
00563         drawpixel(x0 + y, y0 + x, color);
00564         drawpixel(x0 - y, y0 + x, color);
00565         drawpixel(x0 + y, y0 - x, color);
00566         drawpixel(x0 - y, y0 - x, color);
00567 
00568         err += y;
00569         y++;
00570         err += y;
00571         if (err >= 0) {
00572             x--;
00573             err -= x;
00574             err -= x;
00575         }
00576     }
00577 
00578     return;
00579 }
00580 
00581 void LS020LCD::rectangle8(char x1, char y1, char x2, char y2, char color) {
00582     set_window(x1,y1,x2,y2);
00583     for (char y=y1;y<=y2;y++) {
00584         for (char x=x1;x<=x2;x++) {
00585             write_data8(color);
00586         }
00587     }
00588 }
00589 
00590 
00591 void LS020LCD::putpixel(unsigned char r,unsigned char g,unsigned char b, unsigned char x, unsigned char y) {
00592     uint16_t data;
00593     write_cmd16(0xEF90);
00594     write_cmd16(0x0500);
00595     write_cmd16(0x0800+ x);
00596     write_cmd16(0x0A00+ y);
00597     write_cmd16(0x0900+ x+1);
00598     write_cmd16(0x0B00+ y+1);
00599     data=0xffff-(((uint16_t)(31*b/255))*0x800)+(((uint16_t)(63*g/255))*0x20)+(((uint16_t)(31*r/255)));
00600     write_data16(data);
00601 
00602 }
00603 void LS020LCD::put_char8(char x, char y, char symbol, char color, char bkcolor) {
00604     set_window(x,y,x+5,y+7);
00605     int offset=6*(symbol-0x20);
00606     for (char i=0;i<6;i++) {
00607         for (char j=0;j<8;j++) {
00608             if (((font0[offset+i]<<j)&0x80)==0x80) {
00609                 write_data8(color);
00610             } else {
00611                 write_data8(bkcolor);
00612             }
00613         }
00614     }
00615 }
00616 
00617 void  LS020LCD::put_string8(char x, char y, char* text, char color, char bkcolor) {
00618     char i=0;
00619     char x0=0;
00620     while (text[i]!=0) {
00621         put_char8(x+x0,y,text[i],color,bkcolor);
00622         i++;
00623         x0+=6;
00624     }
00625 }
00626 
00627 void  LS020LCD::draw_table(void) {
00628     for (char y=0; y<16; y++) {
00629         for (char x=0; x<16; x++) {
00630             rectangle8(x*10+9,y*7+5,x*10+8+9,y*7+5+5,y*16+x);
00631         }
00632     }
00633 }
00634 
00635 void LS020LCD::drawtext(unsigned int x, unsigned int y, char* text, unsigned int size,unsigned int font, unsigned int color, unsigned int bgcolor) {
00636     char i=0;
00637     char x0=0;
00638     
00639     while (text[i]!=0) {
00640         x=putc(x+x0,y,text[i],size,font,color,bgcolor);
00641         i++;
00642        
00643     }
00644 }
00645 
00646 void LS020LCD::cls() {
00647     fillrectangle(0, 0, _width, _height, _background);
00648 }
00649 
00650 void LS020LCD::scroll(char offset) {
00651     write_cmd16(0x1100+offset);
00652 }
00653 
00654 unsigned int checkbit(const unsigned long *data, unsigned int nr) {
00655     return (data[nr/32] & (0x80000000UL>>(nr&31))); // (data[nr/32] & (1<<(nr&31)))
00656 }