PCD8544 multiscreen
Embed:
(wiki syntax)
Show/hide line numbers
PCD8544MS.cpp
00001 /* mbed PCD8544 - Graphic Library for driving monochrome displays based on 00002 * the PCD8544 48 x 84 pixels matrix LCD controller/driver 00003 * used in Nokia 3310, 3315, 3330, 3350, 3410, 3210, 5110, 5120, 5130, 5160, 6110, 6150 00004 * 00005 * Copyright (c) 2011, Wim De Roeve 00006 * partial port of the code found on http://serdisplib.sourceforge.net/ser/pcd8544.html#links 00007 * and by Petras Saduikis <petras@petras.co.uk> 00008 * 00009 * Permission is hereby granted, free of charge, to any person obtaining a copy 00010 * of this software and associated documentation files (the "Software"), to deal 00011 * in the Software without restriction, including without limitation the rights 00012 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00013 * copies of the updaSoftware, and to permit persons to whom the Software is 00014 * furnished to do so, subject to the following conditions: 00015 * 00016 * The above copyright notice and this permission notice shall be included in 00017 * all copies or substantial portions of the Software. 00018 * 00019 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00020 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00021 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00022 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00023 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00024 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00025 * THE SOFTWARE. 00026 */ 00027 00028 #include "PCD8544MS.h" 00029 00030 #include "fonts/font_3x5.h" 00031 #include "fonts/font_5x7.h" 00032 #include "fonts/font_6x8.h" 00033 #include "fonts/font_8x8.h" 00034 #include "fonts/font_8x12.h" 00035 #include "fonts/font_16x20.h" 00036 #include "fonts/font_16x24.h" 00037 00038 #include "DebugTrace.h" 00039 #include "sstream" 00040 #include "stdio.h" 00041 #include "stringman.h" 00042 00043 #define GLCD_CS6_ON 0x01 //P0 00044 #define GLCD_RESET_ON 0x02 //P1 00045 #define GLCD_CS1_ON 0x04 //P2 00046 #define GLCD_CS5_ON 0x08 //P3 00047 #define GLCD_DC_ON 0x10 //P4 00048 #define GLCD_CS2_ON 0x20 //P5 00049 #define GLCD_CS3_ON 0x40 //P6 00050 #define GLCD_CS4_ON 0x80 //P7 00051 00052 #define TLCD_RS_ON 0x1000 //P12 00053 #define TLCD_E1_ON 0x2000 //P13 00054 #define TLCD_E2_ON 0x4000 //P14 00055 #define TLCD_BACKLIGHT_ON 0x8000 //P15 00056 00057 /* Display ON/OFF Control defines */ 00058 #define DON 0x0F //0b00001111 Display on 00059 #define DOFF 0x0B //0b00001011 Display off 00060 #define CURSOR_ON 0x0F //0b00001111 Cursor on 00061 #define CURSOR_OFF OxOD //0b00001101 Cursor off 00062 #define BLINK_ON 0x0F //0b00001111 Cursor Blink 00063 #define BLINK_OFF 0x0E //0b00001110 Cursor No Blink 00064 00065 /* Cursor or Display Shift defines */ 00066 #define SHIFT_CUR_LEFT Ox13 //0b00010011 Cursor shifts to the left 00067 #define SHIFT_CUR_RIGHT Ox17 //0b00010111 Cursor shifts to the right 00068 #define SHIFT_DISP_LEFT Ox1B //0b00011011 Display shifts to the left 00069 #define SHIFT_DISP_RIGHT 0x1F //0b00011111 Display shifts to the right 00070 00071 /* Function Set defines */ 00072 #define EIGHT_BITMODE 0x03 //0b00000011 8-bit Interface D4-D7 00073 #define FOUR_BITMODE 0x02 //0b00000010 4-bit Interface D4-D7 00074 #define LINE_5X7 0x30 //0b00110000 00075 #define LINE_5X10 0x34 //0b00110100 00076 #define LINES_5X7 0x38 //0b00111000 00077 00078 // Addtional define to support display mode 00079 00080 #define DISP_FLIP_NONE 0x00 //0b00111100 No flip 00081 #define CLEAR_LCD 0x01 //0b00000001 00082 00083 /* Number of pixels on the LCD */ 00084 00085 #define HIGH 1 00086 #define LOW 0 00087 #define TRUE 1 00088 #define FALSE 0 00089 00090 /* Display control command */ 00091 #define EXTENDEDSET 0x21 00092 #define STANDARDSET 0x20 00093 #define DISPLAYOFF 0x08 // switch off display 00094 #define ALL_SEG_ON 0x09 // switch on display and set to all pixels on 00095 #define NORMAL_MODE 0x0C // NOREVERSE 00096 #define INVERSE_MODE 0x0D // REVERSE 00097 00098 #define SET_ADDRES_X 0x80 00099 #define SET_ADDRES_Y 0x40 00100 00101 00102 DebugTrace pc_PCD8544(ON, TO_SERIAL); 00103 00104 /* 00105 PCD8544 from Philips Semiconductors is 00106 48 x 84 pixels monochrome matrix LCD controller/driver 00107 00108 generic for LPH7366, LPH7677, and LPH7779; no backlight 00109 00110 model name (of display) type used in cellphones 00111 LPH 7366 2 Nokia 5110, 5120, 5130, 5160, 6110, 6150 00112 LPH 7677 1 Nokia 3210 00113 LPH 7779 1 Nokia 3310, 3315, 3330, 3350, 3410 00114 00115 00116 +-------------------------+ 00117 | 1 2 3 4 5 6 7 8 | 00118 | # # # # # # # # | 00119 | ===#=#=#=#=#=#=#=#=== | Red 1 .. VDD - chip power supply +3.3V 00120 +--=====================--+ Green 2 .. SCLK - serial clock line of LCD 00121 | | Yellow 3 .. SI - serial data input of LCD 00122 | | Gray 4 .. D/C - command/data switch 00123 | rear view | Blue 5 .. /CS - active low chip select 00124 | connector is visible | Black 6 .. GND - for VDD 00125 | | 7 .. Vout - output of display-internal dc/dc converter 00126 | LPH7779 | White 8 .. /RES - active low reset 00127 | | 00128 +-------------------------+ 00129 00130 */ 00131 00132 00133 PCD8544MS::PCD8544MS(PinName mosi, PinName miso, PinName sclk, PinName sda, PinName scl,int i2cAddress, bool TextLCD, bool backlight): 00134 _spi(mosi, miso, sclk),_i2c(sda, scl) { 00135 00136 _i2cAddress = i2cAddress; 00137 // _type = type; 00138 00139 if (TextLCD) { 00140 TLCD_reset(); 00141 _columns = 16; 00142 _rows = 2; 00143 _backlight=backlight; 00144 } 00145 00146 GLCD_reset(); 00147 } 00148 00149 void PCD8544MS::writeI2CByte(int data) { 00150 char cmd[2]; 00151 cmd[0] = (data & 0xFF); 00152 cmd[1] = (data >> 8); 00153 _i2c.write(_i2cAddress, cmd, 2); 00154 // pc_PCD8544.traceOut("I2C=%i ",data); 00155 00156 } 00157 00158 // ############# TEXTLCD FUNCTIONS ################### 00159 00160 void PCD8544MS::TLCD_reset() { 00161 for (int i=0; i<3; i++) { 00162 TLCD_writeNibble(EIGHT_BITMODE,false); 00163 wait(0.00164); // this command takes 1.64ms, so wait for it 00164 } 00165 TLCD_writeNibble(FOUR_BITMODE,false); // 4-bit mode 00166 00167 TLCD_writeCommand(0x28); // Function set 001 BW N F - - 00168 TLCD_writeCommand(0x0C); 00169 TLCD_writeCommand(0x6); // Cursor Direction and Display Shift : 0000 01 CD S (CD 0-left, 1-right S(hift) 0-no, 1-yes 00170 } 00171 00172 void PCD8544MS::TLCD_writeNibble(int data, bool rs) { 00173 00174 data = ((data & 0xF) << 8) || GLCD_RESET_ON || GLCD_CS1_ON || GLCD_CS2_ON || GLCD_CS3_ON || GLCD_CS4_ON || GLCD_CS5_ON || GLCD_CS6_ON ; 00175 00176 if (_backlight) 00177 data= data | TLCD_BACKLIGHT_ON; 00178 00179 if (rs) { 00180 data = data | TLCD_RS_ON; // set rs bit 00181 } 00182 00183 writeI2CByte(data | TLCD_E1_ON); // E=1 00184 00185 wait(0.000040f); 00186 writeI2CByte(data); // E=0 00187 00188 wait(0.000040f); 00189 writeI2CByte(data | TLCD_E1_ON); // E=1 00190 } 00191 00192 00193 void PCD8544MS::TLCD_writeByte(int data, bool rs) { 00194 TLCD_writeNibble(data >> 4 , rs); 00195 TLCD_writeNibble(data >> 0 , rs); 00196 } 00197 00198 void PCD8544MS::TLCD_writeCommand(int command) { 00199 // RS = 0; 00200 TLCD_writeByte(command,false); 00201 } 00202 00203 void PCD8544MS::TLCD_writeData(int data) { 00204 //RS = 1 00205 TLCD_writeByte(data,true); 00206 00207 _column++; 00208 if (_column >= _columns) { 00209 TLCD_newline(); 00210 } 00211 } 00212 00213 int PCD8544MS::_putc(int value) { 00214 if (value == '\n') { 00215 TLCD_newline(); 00216 } else { 00217 TLCD_writeData(value); 00218 } 00219 return value; 00220 } 00221 00222 int PCD8544MS::_getc() { 00223 return 0; 00224 } 00225 00226 void PCD8544MS::TLCD_backlight(bool status) { 00227 _backlight=status; 00228 if (_backlight) 00229 writeI2CByte(TLCD_BACKLIGHT_ON | TLCD_E1_ON | TLCD_E2_ON | GLCD_CS1_ON); 00230 else 00231 writeI2CByte(TLCD_E1_ON | TLCD_E2_ON | GLCD_CS1_ON); 00232 } 00233 00234 00235 void PCD8544MS::TLCD_newline() { 00236 _column = 0; 00237 _row++; 00238 if (_row >= _rows) { 00239 _row = 0; 00240 } 00241 TLCD_locate(_column, _row); 00242 } 00243 00244 00245 void PCD8544MS::TLCD_locate(int column, int row) { 00246 if (column < 0 || column >= _columns || row < 0 || row >= _rows) { 00247 error("locate(%d,%d) out of range on %dx%d display", column, row, _columns, _rows); 00248 return; 00249 } 00250 00251 _row = row; 00252 _column = column; 00253 int address = 0x80 + (_row * 40) + _column; // memory starts at 0x80, and is 40 chars long per row 00254 // pc_LCD.traceOut("locate %dx%d\r\n", column, row); 00255 TLCD_writeCommand(address); 00256 } 00257 00258 00259 void PCD8544MS::TLCD_cls() { 00260 TLCD_writeCommand(0x01); // Clear Display 00261 wait(0.00164f); // This command takes 1.64 ms 00262 TLCD_locate(0, 0); 00263 } 00264 00265 00266 00267 // ############# GRAPHICLCD FUNCTIONS ################### 00268 00269 void PCD8544MS::GLCD_reset() { 00270 00271 /* reset lcd 00272 00273 After reset, the LCD driver has the following state: 00274 - Power-down mode (bit PD = 1) 00275 - Horizontal addressing (bit V = 0) 00276 - normal instruction set (bit H = 0) 00277 - Display blank (bit E = D = 0) 00278 - Address counter X6 to X0 = 0; Y2 to Y0 = 0 00279 - Temperature control mode (TC1 TC0 = 0) 00280 - Bias system (BS2 to BS0 = 0) 00281 - VLCD is equal to 0, the HV generator is switched off 00282 (VOP6 to VOP0 = 0) 00283 - After power-on, the RAM contents are undefined. 00284 */ 00285 00286 00287 GLCD_writeI2C(HIGH,LOW,HIGH,0); // all screens 00288 00289 _spi.format(8,0); 00290 _spi.frequency(1000000); 00291 00292 pc_PCD8544.traceOut("\r\nreset GLCD "); 00293 00294 //_cs=HIGH; 00295 //_reset=HIGH; 00296 00297 00298 // for (int i=1;i<=maxscreen;i++) { 00299 00300 wait_ms(1); 00301 //_reset=LOW; 00302 GLCD_writeI2C(LOW,LOW,HIGH,0); 00303 00304 wait_ms(1); 00305 //_reset = HIGH; 00306 GLCD_writeI2C(HIGH,LOW,HIGH,0); 00307 00308 GLCD_writeCmd(EXTENDEDSET,1,0); // folowing commands are extended ones 00309 GLCD_writeCmd(0xc8,0,0); // Set Voltage 0x80+value: set contrast 00310 GLCD_writeCmd(0x06,0,0); // set temp coefficient 00311 GLCD_writeCmd(0x13,0,0); // set BIAS mode 1:48 00312 GLCD_writeCmd(STANDARDSET,0,0); // STANDARDSET: following commands are standard ones 00313 00314 GLCD_writeCmd(NORMAL_MODE,2,0); 00315 _LoMark = 0; 00316 _HiMark = LCD_CACHE_SIZE - 1; 00317 00318 GLCD_cls(0,TRUE); 00319 } 00320 00321 void PCD8544MS::GLCD_writeCmd(BYTE data, BYTE CF, int screen) { 00322 //_cs = LOW; 00323 //_dc = LOW; 00324 // _spi.write(data); 00325 00326 // pc_PCD8544.traceOut("\r\n %i %i %i ",(CF & 1),data,(CF & 2)); 00327 00328 if ((CF & 1)==1) { 00329 GLCD_writeI2C(HIGH,LOW,LOW,screen); 00330 wait_ms(1); 00331 } 00332 00333 _spi.write(data); 00334 00335 if ((CF & 2)==2) { 00336 GLCD_writeI2C(HIGH,LOW,HIGH,screen); 00337 } 00338 00339 //_cs = HIGH; 00340 00341 } 00342 00343 void PCD8544MS::GLCD_writeData(BYTE data, BYTE CF, int screen) { 00344 // _cs = LOW; 00345 //_dc = HIGH; 00346 //_spi.write(data); 00347 00348 if ((CF & 1)==1) { 00349 GLCD_writeI2C(HIGH,HIGH,LOW,screen); 00350 wait_ms(1); 00351 } 00352 00353 _spi.write(data); 00354 00355 if ((CF & 2)==2) { 00356 GLCD_writeI2C(HIGH,HIGH,HIGH,screen); 00357 } 00358 00359 // _cs = HIGH; 00360 00361 } 00362 00363 void PCD8544MS::GLCD_writeI2C(bool reset, bool dc, bool cs,int screen) { 00364 00365 int cb=TLCD_E1_ON | TLCD_E2_ON; // prevent TextLCD for 00366 00367 if (reset==HIGH) cb = cb | GLCD_RESET_ON; 00368 if (dc==HIGH) cb = cb | GLCD_DC_ON; 00369 00370 if (cs==HIGH) { 00371 cb = cb | GLCD_CS1_ON | GLCD_CS2_ON | GLCD_CS3_ON | GLCD_CS4_ON | GLCD_CS5_ON | GLCD_CS6_ON ; 00372 } else { 00373 switch (screen) { 00374 case 1: { 00375 cb = cb | GLCD_CS2_ON | GLCD_CS3_ON | GLCD_CS4_ON | GLCD_CS5_ON | GLCD_CS6_ON; 00376 break; 00377 } 00378 case 2: { 00379 cb = cb | GLCD_CS1_ON | GLCD_CS3_ON | GLCD_CS4_ON | GLCD_CS5_ON | GLCD_CS6_ON; 00380 break; 00381 } 00382 case 3: { 00383 cb = cb | GLCD_CS1_ON | GLCD_CS2_ON | GLCD_CS4_ON | GLCD_CS5_ON | GLCD_CS6_ON; 00384 break; 00385 } 00386 case 4: { 00387 cb = cb | GLCD_CS1_ON | GLCD_CS2_ON | GLCD_CS3_ON | GLCD_CS5_ON | GLCD_CS6_ON; 00388 break; 00389 } 00390 case 5: { 00391 cb = cb | GLCD_CS1_ON | GLCD_CS2_ON | GLCD_CS3_ON | GLCD_CS4_ON | GLCD_CS6_ON; 00392 break; 00393 } 00394 case 6: { 00395 cb = cb | GLCD_CS1_ON | GLCD_CS2_ON | GLCD_CS3_ON | GLCD_CS4_ON | GLCD_CS5_ON; 00396 break; 00397 } 00398 default: { 00399 break; 00400 } 00401 } 00402 } 00403 00404 00405 writeI2CByte(cb); 00406 00407 } 00408 00409 void PCD8544MS::GLCD_close() { 00410 GLCD_writeCmd(DISPLAYOFF,3,0); 00411 GLCD_writeI2C(HIGH,HIGH,HIGH,0); 00412 // _cs = HIGH; 00413 // _reset = HIGH; 00414 00415 } 00416 00417 // GRAPHICAL functions 00418 00419 void PCD8544MS::GLCD_cls(int screen,bool fupdate) { 00420 // pc_PCD8544.traceOut("\r\ncls %i ",LCD_CACHE_SIZE); 00421 00422 for (int i = 0; i < LCD_CACHE_SIZE ; i++) { 00423 // pc_PCD8544.traceOut("%i",i); 00424 LcdCache[i]=0x00; 00425 } 00426 _LoMark = 0; 00427 _HiMark = LCD_CACHE_SIZE - 1; 00428 00429 // pc_PCD8544.traceOut("\r\nfupdate"); 00430 if (fupdate) 00431 GLCD_update(screen); 00432 } 00433 00434 void PCD8544MS::GLCD_update(int screen) { 00435 // pc_PCD8544.traceOut("\r\nupdate"); 00436 if ( _LoMark < 0 ) 00437 _LoMark = 0; 00438 else if ( _LoMark >= LCD_CACHE_SIZE ) 00439 _LoMark = LCD_CACHE_SIZE - 1; 00440 if ( _HiMark < 0 ) 00441 _HiMark = 0; 00442 else if ( _HiMark >= LCD_CACHE_SIZE ) 00443 _HiMark = LCD_CACHE_SIZE - 1; 00444 00445 GLCD_writeCmd(SET_ADDRES_X | (_LoMark % LCD_X_RES),1,screen); 00446 GLCD_writeCmd(SET_ADDRES_Y | (_LoMark / LCD_X_RES),2,screen); 00447 00448 GLCD_writeI2C(HIGH,HIGH,LOW,screen); 00449 wait_ms(1); 00450 00451 for (int i = _LoMark; i <= _HiMark; i++ ) { 00452 _spi.write(LcdCache[i]); 00453 //writeData( ); 00454 } 00455 GLCD_writeI2C(HIGH,HIGH,HIGH,screen); 00456 _LoMark = LCD_CACHE_SIZE - 1; 00457 _HiMark = 0; 00458 } 00459 00460 00461 00462 void PCD8544MS::GLCD_locate(BYTE x0, BYTE y0) { 00463 LcdCacheIdx = x0*LCD_BANKS + y0 * LCD_X_RES; 00464 } 00465 00466 // Bitmap 00467 00468 void PCD8544MS::GLCD_drawBitmap(BYTE x0, BYTE y0, const unsigned char* bitmap, BYTE bmpXSize, BYTE bmpYSize,BYTE fupdate,int screen) { 00469 BYTE row; 00470 // pc_PCD8544.traceOut("\r\ndrawbitmap"); 00471 00472 if (0 == bmpYSize % 8) 00473 row = bmpYSize/8; 00474 else 00475 row = bmpYSize/8 + 1; 00476 00477 _LoMark= 0; 00478 _HiMark= LCD_CACHE_SIZE - 1; 00479 00480 for (BYTE n = 0; n < row; n++) { 00481 GLCD_locate(x0, y0); 00482 00483 for (BYTE i = 0; i < bmpXSize; i++) { 00484 LcdCache[LcdCacheIdx+ i]=bitmap[i + (n * bmpXSize)]; 00485 } 00486 y0++; 00487 } 00488 if (fupdate==TRUE) 00489 GLCD_update(screen); 00490 } 00491 00492 void PCD8544MS::GLCD_writeString(BYTE x0, BYTE y0, char* string, eFonts font,ePixelMode pmode,eDisplayMode dmode,eSpaceMode smode, BYTE fupdate,int screen) { 00493 00494 // pc_PCD8544.traceOut("\r\nwriteString"); 00495 GLCD_locate(x0, y0); 00496 chooseFont(font); 00497 00498 while (*string) { 00499 GLCD_writeChar(x0,y0,*string++,font,pmode, dmode, FALSE,screen); 00500 x0+=_font_width; // width +1; 00501 if (smode==SPACE_NORMAL) 00502 x0++; 00503 } 00504 if (fupdate==TRUE) 00505 GLCD_update(screen); 00506 } 00507 00508 void PCD8544MS::chooseFont(eFonts font) { 00509 00510 switch (font) { 00511 00512 case VERYSMALLFONT: { 00513 _font_width = FONT3x5_WIDTH; 00514 _font_height = FONT3x5_HEIGHT; 00515 _font_start = FONT3x5_START; 00516 _font_end = FONT3x5_END; 00517 _font_bytes = FONT3x5_BYTES; 00518 00519 _pFont = (unsigned char*) font_3x5; 00520 00521 break; 00522 } 00523 case TINYFONT: { 00524 _font_width = FONT5x7_WIDTH; 00525 _font_height = FONT5x7_HEIGHT; 00526 _font_start = FONT5x7_START; 00527 _font_end = FONT5x7_END; 00528 _font_bytes = FONT5x7_BYTES; 00529 00530 _pFont = (unsigned char*) font_5x7; 00531 00532 break; 00533 } 00534 00535 case SMALLFONT: { 00536 _font_width = FONT6x8_WIDTH; 00537 _font_height = FONT6x8_HEIGHT; 00538 _font_start = FONT6x8_START; 00539 _font_end = FONT6x8_END; 00540 _font_bytes = FONT6x8_BYTES; 00541 00542 _pFont = (unsigned char*) font_6x8; 00543 00544 break; 00545 } 00546 case NORMALFONT: { 00547 _font_width = FONT8x8_WIDTH; 00548 _font_height = FONT8x8_HEIGHT; 00549 _font_start = FONT8x8_START; 00550 _font_end = FONT8x8_END; 00551 _font_bytes = FONT8x8_BYTES; 00552 00553 _pFont = (unsigned char*) font_8x8; 00554 00555 break; 00556 } 00557 case BIGFONT: { 00558 _font_width = FONT8x12_WIDTH; 00559 _font_height = FONT8x12_HEIGHT; 00560 _font_start = FONT8x12_START; 00561 _font_end = FONT8x12_END; 00562 _font_bytes = FONT8x12_BYTES; 00563 00564 _pFont = (unsigned char*) font_8x12; 00565 00566 break; 00567 } 00568 00569 case TIMENUMBERFONT: { 00570 _font_width = FONT16x20_WIDTH; 00571 _font_height = FONT16x20_HEIGHT; 00572 _font_start = FONT16x20_START; 00573 _font_end = FONT16x20_END; 00574 _font_bytes = FONT16x20_BYTES; 00575 00576 _pFont = (unsigned char*) font_16x20; 00577 00578 break; 00579 } 00580 00581 case BIGNUMBERFONT: { 00582 _font_width = FONT16x24_WIDTH; 00583 _font_height = FONT16x24_HEIGHT; 00584 _font_start = FONT16x24_START; 00585 _font_end = FONT16x24_END; 00586 _font_bytes = FONT16x24_BYTES; 00587 00588 _pFont = (unsigned char*) font_16x24; 00589 00590 break; 00591 } 00592 } 00593 } 00594 00595 void PCD8544MS::GLCD_writeChar(BYTE x0, BYTE y0, BYTE ch, eFonts font, ePixelMode pmode,eDisplayMode mode,BYTE fupdate,int screen) { 00596 BYTE sendByte; 00597 00598 chooseFont(font); 00599 00600 if ((ch <= _font_start) || (ch > _font_end)) 00601 ch=_font_start; 00602 00603 ch -= _font_start; 00604 00605 00606 /* for (BYTE i = 0; i < 3; i++) { 00607 locate(x, y + i); 00608 00609 for (BYTE j = 0; j < 16; j++) { 00610 sendByte = *(pFont + ch*48 + i*16 + j); 00611 writeData((mode == NORMAL)? sendByte : (sendByte^0xff)); 00612 } 00613 }*/ 00614 00615 00616 for (int i = 0; i < _font_width; i++ ) { 00617 for (int f=0; f<_font_bytes; f++) { 00618 sendByte = *(_pFont + ch*_font_width*_font_bytes +f*_font_width+i); 00619 sendByte = ((mode == DISPLAY_NORMAL)? sendByte:(sendByte ^ 0xff)); 00620 00621 for (int j=0 ; j<_font_height; j++) { 00622 if ((sendByte & 0x01) == 0x01) { 00623 GLCD_drawpixel(x0,y0+j+f*8,PIXEL_ON,FALSE,screen); 00624 } else { 00625 GLCD_drawpixel(x0,y0+j+f*8,PIXEL_OFF,FALSE,screen); 00626 } 00627 sendByte=sendByte>>1; 00628 } 00629 } 00630 x0++; 00631 } 00632 00633 00634 if (fupdate==TRUE) 00635 GLCD_update(screen); 00636 } 00637 00638 00639 void PCD8544MS::GLCD_drawpixel(BYTE x0, BYTE y0, ePixelMode mode,BYTE fupdate,int screen) { 00640 uint16_t index; 00641 BYTE offset; 00642 BYTE data; 00643 00644 if ( x0 > LCD_X_RES-1 ) return; 00645 if ( y0 > LCD_Y_RES-1 ) return; 00646 00647 index = ((y0 / 8) * LCD_X_RES) + x0; 00648 offset = y0 - ((y0 / 8) * 8); 00649 00650 data = LcdCache[index]; 00651 00652 if ( mode == PIXEL_OFF ) { 00653 data &= (~(0x01 << offset)); 00654 } else if ( mode == PIXEL_ON ) { 00655 data |= (0x01 << offset); 00656 } else if ( mode == PIXEL_XOR ) { 00657 data ^= (0x01 << offset); 00658 } 00659 LcdCache[index] = data; 00660 00661 if ( index < _LoMark ) { 00662 _LoMark = index; 00663 } 00664 if ( index > _HiMark ) { 00665 _HiMark = index; 00666 } 00667 if (fupdate==TRUE) 00668 GLCD_update(screen); 00669 } 00670 00671 void PCD8544MS::GLCD_drawline(BYTE x0, BYTE y0, BYTE x1, BYTE y1, ePixelMode mode,BYTE fupdate,int screen) { 00672 int dx, dy, stepx, stepy, fraction; 00673 00674 dy = y1 - y0; 00675 dx = x1 - x0; 00676 if ( dy < 0 ) { 00677 dy = -dy; 00678 stepy = -1; 00679 } else { 00680 stepy = 1; 00681 } 00682 if ( dx < 0 ) { 00683 dx = -dx; 00684 stepx = -1; 00685 } else { 00686 stepx = 1; 00687 } 00688 dx <<= 1; 00689 dy <<= 1; 00690 00691 GLCD_drawpixel( x0, y0, mode , FALSE,screen); 00692 if ( dx > dy ) { 00693 fraction = dy - (dx >> 1); 00694 while ( x0 != x1 ) { 00695 if ( fraction >= 0 ) { 00696 y0 += stepy; 00697 fraction -= dx; 00698 } 00699 x0 += stepx; 00700 fraction += dy; 00701 GLCD_drawpixel( x0, y0, mode , FALSE,screen); 00702 } 00703 } else { 00704 fraction = dx - (dy >> 1); 00705 while ( y0 != y1 ) { 00706 if ( fraction >= 0 ) { 00707 x0 += stepx; 00708 fraction -= dy; 00709 } 00710 y0 += stepy; 00711 fraction += dx; 00712 GLCD_drawpixel( x0, y0, mode , FALSE,screen); 00713 } 00714 } 00715 if (fupdate==TRUE) 00716 GLCD_update(screen); 00717 } 00718 00719 void PCD8544MS::GLCD_drawrectangle(BYTE x0, BYTE y0, BYTE x1, BYTE y1, eFillMode fill, ePixelMode mode,BYTE fupdate,int screen) { 00720 if (fill==1) { 00721 BYTE i, xmin, xmax, ymin, ymax; 00722 if (x0 < x1) { // Find x min and max 00723 xmin = x0; 00724 xmax = x1; 00725 } else { 00726 xmin = x1; 00727 xmax = x0; 00728 } 00729 if (y0 < y1) { // Find the y min and max 00730 ymin = y0; 00731 ymax = y1; 00732 } else { 00733 ymin = y1; 00734 ymax = y0; 00735 } 00736 for (; xmin <= xmax; ++xmin) { 00737 for (i=ymin; i<=ymax; ++i) { 00738 GLCD_drawpixel(xmin, i, mode, FALSE,screen); 00739 } 00740 } 00741 } else { 00742 GLCD_drawline(x0, y0, x1, y0, mode, FALSE,screen); // Draw the 4 sides 00743 GLCD_drawline(x0, y1, x1, y1, mode, FALSE,screen); 00744 GLCD_drawline(x0, y0, x0, y1, mode, FALSE,screen); 00745 GLCD_drawline(x1, y0, x1, y1, mode, FALSE,screen); 00746 } 00747 if (fupdate==TRUE) 00748 GLCD_update(screen); 00749 } 00750 00751 00752 void PCD8544MS::GLCD_drawcircle(BYTE x0, BYTE y0, BYTE radius, eFillMode fill, ePixelMode mode, BYTE fupdate,int screen) { 00753 int err, x, y; 00754 00755 err = -radius; 00756 x = radius; 00757 y = 0; 00758 00759 while (x >= y) { 00760 if (fill==1) { 00761 GLCD_drawline(x0 - x, y0 + y, x0 + x, y0 + y, mode,FALSE,screen); 00762 GLCD_drawline(x0 - x, y0 - y, x0 + x, y0 - y, mode,FALSE,screen); 00763 GLCD_drawline(x0 - y, y0 + x, x0 + y, y0 + x, mode,FALSE,screen); 00764 GLCD_drawline(x0 - y, y0 - x, x0 + y, y0 - x, mode,FALSE,screen); 00765 } else { 00766 GLCD_drawpixel(x0 + x, y0 + y, mode,FALSE,screen); 00767 GLCD_drawpixel(x0 - x, y0 + y, mode,FALSE,screen); 00768 GLCD_drawpixel(x0 + x, y0 - y, mode,FALSE,screen); 00769 GLCD_drawpixel(x0 - x, y0 - y, mode,FALSE,screen); 00770 GLCD_drawpixel(x0 + y, y0 + x, mode,FALSE,screen); 00771 GLCD_drawpixel(x0 - y, y0 + x, mode,FALSE,screen); 00772 GLCD_drawpixel(x0 + y, y0 - x, mode,FALSE,screen); 00773 GLCD_drawpixel(x0 - y, y0 - x, mode,FALSE,screen); 00774 } 00775 err += y; 00776 y++; 00777 err += y; 00778 if (err >= 0) { 00779 x--; 00780 err -= x; 00781 err -= x; 00782 } 00783 } 00784 00785 if (fupdate==TRUE) 00786 GLCD_update(screen); 00787 00788 } 00789 00790 void PCD8544MS::GLCD_drawprogressbar(BYTE x0, BYTE y0, BYTE w, BYTE h, BYTE percentage,BYTE fupdate,int screen) { 00791 GLCD_drawrectangle(x0,y0,x0+w,y0+h,FILL_OFF,PIXEL_ON, FALSE,screen); 00792 GLCD_drawrectangle(x0+2,y0+2,x0+w-2,y0+h-2,FILL_ON,PIXEL_OFF, FALSE,screen); 00793 GLCD_drawrectangle(x0+2,y0+2,x0+2+(percentage*(w-4)/100),y0+h-2,FILL_ON,PIXEL_ON, FALSE,screen); 00794 if (fupdate==TRUE) 00795 GLCD_update(screen); 00796 } 00797 00798 void PCD8544MS::GLCD_drawchart(BYTE x0, BYTE y0, BYTE w, BYTE h, BYTE unitx, BYTE unity, 00799 eRasterMode rMode, eChartMode cMode,eDrawMode dMode, int16_t * val, int size, int t,int screen) { 00800 int maxy; 00801 int _scale=1; 00802 int prescale=1; 00803 00804 signed char v1,v2; 00805 char buffer[4]; 00806 00807 if (size>w) 00808 size=w; 00809 00810 // search maximum value to calculate scale 00811 if (dMode==DRAW_OVERWRITE) { 00812 maxy=0; 00813 for (int i=0; i<size; i++) { 00814 if (val[i]>maxy) 00815 maxy=val[i]; 00816 00817 } 00818 00819 if (maxy>h) { //scale can be 1,2,5 *10i 00820 prescale= ((maxy-1)/((h/unity)*unity)); 00821 _scale=1; 00822 while (prescale>10) { 00823 _scale=_scale*10; 00824 prescale=prescale/10; 00825 } 00826 if (prescale>1) 00827 _scale=_scale*5; 00828 else if (prescale==1) 00829 _scale =_scale*2; 00830 00831 00832 } 00833 Scale=_scale; 00834 } 00835 00836 if (dMode==DRAW_OVERWRITE) { 00837 GLCD_drawrectangle(x0-11,y0-h,x0+w,y0+4+7,FILL_ON,PIXEL_OFF,FALSE,screen); 00838 GLCD_drawline(x0,y0,x0,y0-h,PIXEL_ON,FALSE,screen); 00839 GLCD_drawline(x0,y0,x0+w,y0,PIXEL_ON,FALSE,screen); 00840 00841 //drawrectangle(x0,y0-h,x0+w,y0,FILL_OFF,PIXEL_ON,FALSE); 00842 00843 for (int i=0; i<=h; i++) { 00844 if ((i % unity) == 0) { 00845 GLCD_drawpixel(x0-2,y0-i,PIXEL_ON,FALSE,screen); 00846 // drawpixel(x0+w+2,y0-i,PIXEL_ON,FALSE); 00847 00848 if (rMode==RASTER_ON) { 00849 for (int r=0; r<=w; r++) { 00850 if ((r % 2) ==0) 00851 GLCD_drawpixel(x0+r,y0-i,PIXEL_ON,FALSE,screen); 00852 } 00853 } 00854 // draw vertical axis labels 00855 00856 itostr(buffer,i*Scale); 00857 00858 // pc_PCD8544.traceOut(" %i %s |",i*Scale,buffer); 00859 GLCD_writeString(x0-11,y0-i+1,buffer,VERYSMALLFONT,PIXEL_OFF,DISPLAY_NORMAL,SPACE_NONE,FALSE,screen); 00860 00861 } 00862 if ((i % 2) == 0) { 00863 GLCD_drawpixel(x0-1,y0-i,PIXEL_ON,FALSE,screen); 00864 // drawpixel(x0+w+1,y0-i,PIXEL_ON,FALSE); 00865 } 00866 } 00867 00868 for (int i=0; i<=w; i++) { 00869 if (((i+(t % unitx)) % unitx) == 0) { 00870 GLCD_drawpixel(x0+i,y0+2,PIXEL_ON,FALSE,screen); 00871 00872 if (rMode==RASTER_ON) { 00873 for (int r=0; r<=h; r++) { 00874 if ((r % 2) ==0) 00875 GLCD_drawpixel(x0+i,y0-r,PIXEL_ON,FALSE,screen); 00876 } 00877 } 00878 if (((t-w+i)/unitx)>=0) 00879 snprintf(buffer,3,"%i",((t-w+i)/unitx)); 00880 else 00881 snprintf(buffer,3,"%i",24+((t-w+i)/unitx)); 00882 00883 // pc_PCD8544.traceOut(" %i %s ",(t-w+i)/unitx,buffer); 00884 GLCD_writeString(x0+i-3,y0+4,buffer,VERYSMALLFONT,PIXEL_OFF,DISPLAY_NORMAL,SPACE_NORMAL,FALSE,screen); 00885 } 00886 if ((i % 2) == 0) { 00887 GLCD_drawpixel(x0+i,y0+1,PIXEL_ON,FALSE,screen); 00888 } 00889 } 00890 // update(); 00891 } 00892 00893 for (int i=0; i<size; i++) { 00894 // pc_PCD8544.traceOut(" %i ",val[i]); 00895 v1 = val[i] / Scale; 00896 if (v1>h) 00897 v1=h; 00898 00899 if (i!=(size-1)) { 00900 v2 = val[i+1] / Scale; 00901 if (v2>h) 00902 v2=h; 00903 } else 00904 v2=v1; 00905 00906 00907 switch (cMode) { 00908 case C_POINT: { 00909 GLCD_drawpixel(x0+i,y0-v1,PIXEL_ON,FALSE,screen); 00910 break; 00911 } 00912 case C_LINE: { 00913 GLCD_drawline(x0+i,y0-v1,x0+i+1,y0-v2,PIXEL_ON,FALSE,screen); 00914 break; 00915 } 00916 case C_VLINE: { 00917 GLCD_drawline(x0+i,y0-v1,x0+i,y0,PIXEL_ON,FALSE,screen); 00918 break; 00919 } 00920 } 00921 } 00922 00923 GLCD_update(screen); 00924 } 00925
Generated on Thu Jul 14 2022 04:23:19 by 1.7.2