LS020.h is a MobileLCD library for the LS020 display (used in GSM Siemens S65 family). Resolution 176x132
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 }
Generated on Thu Jul 14 2022 19:13:49 by 1.7.2