PCD8544 multiscreen
PCD8544MS.cpp
- Committer:
- Wimpie
- Date:
- 2012-06-15
- Revision:
- 0:61dcd2c0299a
File content as of revision 0:61dcd2c0299a:
/* mbed PCD8544 - Graphic Library for driving monochrome displays based on * the PCD8544 48 x 84 pixels matrix LCD controller/driver * used in Nokia 3310, 3315, 3330, 3350, 3410, 3210, 5110, 5120, 5130, 5160, 6110, 6150 * * Copyright (c) 2011, Wim De Roeve * partial port of the code found on http://serdisplib.sourceforge.net/ser/pcd8544.html#links * and by Petras Saduikis <petras@petras.co.uk> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the updaSoftware, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include "PCD8544MS.h" #include "fonts/font_3x5.h" #include "fonts/font_5x7.h" #include "fonts/font_6x8.h" #include "fonts/font_8x8.h" #include "fonts/font_8x12.h" #include "fonts/font_16x20.h" #include "fonts/font_16x24.h" #include "DebugTrace.h" #include "sstream" #include "stdio.h" #include "stringman.h" #define GLCD_CS6_ON 0x01 //P0 #define GLCD_RESET_ON 0x02 //P1 #define GLCD_CS1_ON 0x04 //P2 #define GLCD_CS5_ON 0x08 //P3 #define GLCD_DC_ON 0x10 //P4 #define GLCD_CS2_ON 0x20 //P5 #define GLCD_CS3_ON 0x40 //P6 #define GLCD_CS4_ON 0x80 //P7 #define TLCD_RS_ON 0x1000 //P12 #define TLCD_E1_ON 0x2000 //P13 #define TLCD_E2_ON 0x4000 //P14 #define TLCD_BACKLIGHT_ON 0x8000 //P15 /* Display ON/OFF Control defines */ #define DON 0x0F //0b00001111 Display on #define DOFF 0x0B //0b00001011 Display off #define CURSOR_ON 0x0F //0b00001111 Cursor on #define CURSOR_OFF OxOD //0b00001101 Cursor off #define BLINK_ON 0x0F //0b00001111 Cursor Blink #define BLINK_OFF 0x0E //0b00001110 Cursor No Blink /* Cursor or Display Shift defines */ #define SHIFT_CUR_LEFT Ox13 //0b00010011 Cursor shifts to the left #define SHIFT_CUR_RIGHT Ox17 //0b00010111 Cursor shifts to the right #define SHIFT_DISP_LEFT Ox1B //0b00011011 Display shifts to the left #define SHIFT_DISP_RIGHT 0x1F //0b00011111 Display shifts to the right /* Function Set defines */ #define EIGHT_BITMODE 0x03 //0b00000011 8-bit Interface D4-D7 #define FOUR_BITMODE 0x02 //0b00000010 4-bit Interface D4-D7 #define LINE_5X7 0x30 //0b00110000 #define LINE_5X10 0x34 //0b00110100 #define LINES_5X7 0x38 //0b00111000 // Addtional define to support display mode #define DISP_FLIP_NONE 0x00 //0b00111100 No flip #define CLEAR_LCD 0x01 //0b00000001 /* Number of pixels on the LCD */ #define HIGH 1 #define LOW 0 #define TRUE 1 #define FALSE 0 /* Display control command */ #define EXTENDEDSET 0x21 #define STANDARDSET 0x20 #define DISPLAYOFF 0x08 // switch off display #define ALL_SEG_ON 0x09 // switch on display and set to all pixels on #define NORMAL_MODE 0x0C // NOREVERSE #define INVERSE_MODE 0x0D // REVERSE #define SET_ADDRES_X 0x80 #define SET_ADDRES_Y 0x40 DebugTrace pc_PCD8544(ON, TO_SERIAL); /* PCD8544 from Philips Semiconductors is 48 x 84 pixels monochrome matrix LCD controller/driver generic for LPH7366, LPH7677, and LPH7779; no backlight model name (of display) type used in cellphones LPH 7366 2 Nokia 5110, 5120, 5130, 5160, 6110, 6150 LPH 7677 1 Nokia 3210 LPH 7779 1 Nokia 3310, 3315, 3330, 3350, 3410 +-------------------------+ | 1 2 3 4 5 6 7 8 | | # # # # # # # # | | ===#=#=#=#=#=#=#=#=== | Red 1 .. VDD - chip power supply +3.3V +--=====================--+ Green 2 .. SCLK - serial clock line of LCD | | Yellow 3 .. SI - serial data input of LCD | | Gray 4 .. D/C - command/data switch | rear view | Blue 5 .. /CS - active low chip select | connector is visible | Black 6 .. GND - for VDD | | 7 .. Vout - output of display-internal dc/dc converter | LPH7779 | White 8 .. /RES - active low reset | | +-------------------------+ */ PCD8544MS::PCD8544MS(PinName mosi, PinName miso, PinName sclk, PinName sda, PinName scl,int i2cAddress, bool TextLCD, bool backlight): _spi(mosi, miso, sclk),_i2c(sda, scl) { _i2cAddress = i2cAddress; // _type = type; if (TextLCD) { TLCD_reset(); _columns = 16; _rows = 2; _backlight=backlight; } GLCD_reset(); } void PCD8544MS::writeI2CByte(int data) { char cmd[2]; cmd[0] = (data & 0xFF); cmd[1] = (data >> 8); _i2c.write(_i2cAddress, cmd, 2); // pc_PCD8544.traceOut("I2C=%i ",data); } // ############# TEXTLCD FUNCTIONS ################### void PCD8544MS::TLCD_reset() { for (int i=0; i<3; i++) { TLCD_writeNibble(EIGHT_BITMODE,false); wait(0.00164); // this command takes 1.64ms, so wait for it } TLCD_writeNibble(FOUR_BITMODE,false); // 4-bit mode TLCD_writeCommand(0x28); // Function set 001 BW N F - - TLCD_writeCommand(0x0C); TLCD_writeCommand(0x6); // Cursor Direction and Display Shift : 0000 01 CD S (CD 0-left, 1-right S(hift) 0-no, 1-yes } void PCD8544MS::TLCD_writeNibble(int data, bool rs) { 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 ; if (_backlight) data= data | TLCD_BACKLIGHT_ON; if (rs) { data = data | TLCD_RS_ON; // set rs bit } writeI2CByte(data | TLCD_E1_ON); // E=1 wait(0.000040f); writeI2CByte(data); // E=0 wait(0.000040f); writeI2CByte(data | TLCD_E1_ON); // E=1 } void PCD8544MS::TLCD_writeByte(int data, bool rs) { TLCD_writeNibble(data >> 4 , rs); TLCD_writeNibble(data >> 0 , rs); } void PCD8544MS::TLCD_writeCommand(int command) { // RS = 0; TLCD_writeByte(command,false); } void PCD8544MS::TLCD_writeData(int data) { //RS = 1 TLCD_writeByte(data,true); _column++; if (_column >= _columns) { TLCD_newline(); } } int PCD8544MS::_putc(int value) { if (value == '\n') { TLCD_newline(); } else { TLCD_writeData(value); } return value; } int PCD8544MS::_getc() { return 0; } void PCD8544MS::TLCD_backlight(bool status) { _backlight=status; if (_backlight) writeI2CByte(TLCD_BACKLIGHT_ON | TLCD_E1_ON | TLCD_E2_ON | GLCD_CS1_ON); else writeI2CByte(TLCD_E1_ON | TLCD_E2_ON | GLCD_CS1_ON); } void PCD8544MS::TLCD_newline() { _column = 0; _row++; if (_row >= _rows) { _row = 0; } TLCD_locate(_column, _row); } void PCD8544MS::TLCD_locate(int column, int row) { if (column < 0 || column >= _columns || row < 0 || row >= _rows) { error("locate(%d,%d) out of range on %dx%d display", column, row, _columns, _rows); return; } _row = row; _column = column; int address = 0x80 + (_row * 40) + _column; // memory starts at 0x80, and is 40 chars long per row // pc_LCD.traceOut("locate %dx%d\r\n", column, row); TLCD_writeCommand(address); } void PCD8544MS::TLCD_cls() { TLCD_writeCommand(0x01); // Clear Display wait(0.00164f); // This command takes 1.64 ms TLCD_locate(0, 0); } // ############# GRAPHICLCD FUNCTIONS ################### void PCD8544MS::GLCD_reset() { /* reset lcd After reset, the LCD driver has the following state: - Power-down mode (bit PD = 1) - Horizontal addressing (bit V = 0) - normal instruction set (bit H = 0) - Display blank (bit E = D = 0) - Address counter X6 to X0 = 0; Y2 to Y0 = 0 - Temperature control mode (TC1 TC0 = 0) - Bias system (BS2 to BS0 = 0) - VLCD is equal to 0, the HV generator is switched off (VOP6 to VOP0 = 0) - After power-on, the RAM contents are undefined. */ GLCD_writeI2C(HIGH,LOW,HIGH,0); // all screens _spi.format(8,0); _spi.frequency(1000000); pc_PCD8544.traceOut("\r\nreset GLCD "); //_cs=HIGH; //_reset=HIGH; // for (int i=1;i<=maxscreen;i++) { wait_ms(1); //_reset=LOW; GLCD_writeI2C(LOW,LOW,HIGH,0); wait_ms(1); //_reset = HIGH; GLCD_writeI2C(HIGH,LOW,HIGH,0); GLCD_writeCmd(EXTENDEDSET,1,0); // folowing commands are extended ones GLCD_writeCmd(0xc8,0,0); // Set Voltage 0x80+value: set contrast GLCD_writeCmd(0x06,0,0); // set temp coefficient GLCD_writeCmd(0x13,0,0); // set BIAS mode 1:48 GLCD_writeCmd(STANDARDSET,0,0); // STANDARDSET: following commands are standard ones GLCD_writeCmd(NORMAL_MODE,2,0); _LoMark = 0; _HiMark = LCD_CACHE_SIZE - 1; GLCD_cls(0,TRUE); } void PCD8544MS::GLCD_writeCmd(BYTE data, BYTE CF, int screen) { //_cs = LOW; //_dc = LOW; // _spi.write(data); // pc_PCD8544.traceOut("\r\n %i %i %i ",(CF & 1),data,(CF & 2)); if ((CF & 1)==1) { GLCD_writeI2C(HIGH,LOW,LOW,screen); wait_ms(1); } _spi.write(data); if ((CF & 2)==2) { GLCD_writeI2C(HIGH,LOW,HIGH,screen); } //_cs = HIGH; } void PCD8544MS::GLCD_writeData(BYTE data, BYTE CF, int screen) { // _cs = LOW; //_dc = HIGH; //_spi.write(data); if ((CF & 1)==1) { GLCD_writeI2C(HIGH,HIGH,LOW,screen); wait_ms(1); } _spi.write(data); if ((CF & 2)==2) { GLCD_writeI2C(HIGH,HIGH,HIGH,screen); } // _cs = HIGH; } void PCD8544MS::GLCD_writeI2C(bool reset, bool dc, bool cs,int screen) { int cb=TLCD_E1_ON | TLCD_E2_ON; // prevent TextLCD for if (reset==HIGH) cb = cb | GLCD_RESET_ON; if (dc==HIGH) cb = cb | GLCD_DC_ON; if (cs==HIGH) { cb = cb | GLCD_CS1_ON | GLCD_CS2_ON | GLCD_CS3_ON | GLCD_CS4_ON | GLCD_CS5_ON | GLCD_CS6_ON ; } else { switch (screen) { case 1: { cb = cb | GLCD_CS2_ON | GLCD_CS3_ON | GLCD_CS4_ON | GLCD_CS5_ON | GLCD_CS6_ON; break; } case 2: { cb = cb | GLCD_CS1_ON | GLCD_CS3_ON | GLCD_CS4_ON | GLCD_CS5_ON | GLCD_CS6_ON; break; } case 3: { cb = cb | GLCD_CS1_ON | GLCD_CS2_ON | GLCD_CS4_ON | GLCD_CS5_ON | GLCD_CS6_ON; break; } case 4: { cb = cb | GLCD_CS1_ON | GLCD_CS2_ON | GLCD_CS3_ON | GLCD_CS5_ON | GLCD_CS6_ON; break; } case 5: { cb = cb | GLCD_CS1_ON | GLCD_CS2_ON | GLCD_CS3_ON | GLCD_CS4_ON | GLCD_CS6_ON; break; } case 6: { cb = cb | GLCD_CS1_ON | GLCD_CS2_ON | GLCD_CS3_ON | GLCD_CS4_ON | GLCD_CS5_ON; break; } default: { break; } } } writeI2CByte(cb); } void PCD8544MS::GLCD_close() { GLCD_writeCmd(DISPLAYOFF,3,0); GLCD_writeI2C(HIGH,HIGH,HIGH,0); // _cs = HIGH; // _reset = HIGH; } // GRAPHICAL functions void PCD8544MS::GLCD_cls(int screen,bool fupdate) { // pc_PCD8544.traceOut("\r\ncls %i ",LCD_CACHE_SIZE); for (int i = 0; i < LCD_CACHE_SIZE ; i++) { // pc_PCD8544.traceOut("%i",i); LcdCache[i]=0x00; } _LoMark = 0; _HiMark = LCD_CACHE_SIZE - 1; // pc_PCD8544.traceOut("\r\nfupdate"); if (fupdate) GLCD_update(screen); } void PCD8544MS::GLCD_update(int screen) { // pc_PCD8544.traceOut("\r\nupdate"); if ( _LoMark < 0 ) _LoMark = 0; else if ( _LoMark >= LCD_CACHE_SIZE ) _LoMark = LCD_CACHE_SIZE - 1; if ( _HiMark < 0 ) _HiMark = 0; else if ( _HiMark >= LCD_CACHE_SIZE ) _HiMark = LCD_CACHE_SIZE - 1; GLCD_writeCmd(SET_ADDRES_X | (_LoMark % LCD_X_RES),1,screen); GLCD_writeCmd(SET_ADDRES_Y | (_LoMark / LCD_X_RES),2,screen); GLCD_writeI2C(HIGH,HIGH,LOW,screen); wait_ms(1); for (int i = _LoMark; i <= _HiMark; i++ ) { _spi.write(LcdCache[i]); //writeData( ); } GLCD_writeI2C(HIGH,HIGH,HIGH,screen); _LoMark = LCD_CACHE_SIZE - 1; _HiMark = 0; } void PCD8544MS::GLCD_locate(BYTE x0, BYTE y0) { LcdCacheIdx = x0*LCD_BANKS + y0 * LCD_X_RES; } // Bitmap void PCD8544MS::GLCD_drawBitmap(BYTE x0, BYTE y0, const unsigned char* bitmap, BYTE bmpXSize, BYTE bmpYSize,BYTE fupdate,int screen) { BYTE row; // pc_PCD8544.traceOut("\r\ndrawbitmap"); if (0 == bmpYSize % 8) row = bmpYSize/8; else row = bmpYSize/8 + 1; _LoMark= 0; _HiMark= LCD_CACHE_SIZE - 1; for (BYTE n = 0; n < row; n++) { GLCD_locate(x0, y0); for (BYTE i = 0; i < bmpXSize; i++) { LcdCache[LcdCacheIdx+ i]=bitmap[i + (n * bmpXSize)]; } y0++; } if (fupdate==TRUE) GLCD_update(screen); } void PCD8544MS::GLCD_writeString(BYTE x0, BYTE y0, char* string, eFonts font,ePixelMode pmode,eDisplayMode dmode,eSpaceMode smode, BYTE fupdate,int screen) { // pc_PCD8544.traceOut("\r\nwriteString"); GLCD_locate(x0, y0); chooseFont(font); while (*string) { GLCD_writeChar(x0,y0,*string++,font,pmode, dmode, FALSE,screen); x0+=_font_width; // width +1; if (smode==SPACE_NORMAL) x0++; } if (fupdate==TRUE) GLCD_update(screen); } void PCD8544MS::chooseFont(eFonts font) { switch (font) { case VERYSMALLFONT: { _font_width = FONT3x5_WIDTH; _font_height = FONT3x5_HEIGHT; _font_start = FONT3x5_START; _font_end = FONT3x5_END; _font_bytes = FONT3x5_BYTES; _pFont = (unsigned char*) font_3x5; break; } case TINYFONT: { _font_width = FONT5x7_WIDTH; _font_height = FONT5x7_HEIGHT; _font_start = FONT5x7_START; _font_end = FONT5x7_END; _font_bytes = FONT5x7_BYTES; _pFont = (unsigned char*) font_5x7; break; } case SMALLFONT: { _font_width = FONT6x8_WIDTH; _font_height = FONT6x8_HEIGHT; _font_start = FONT6x8_START; _font_end = FONT6x8_END; _font_bytes = FONT6x8_BYTES; _pFont = (unsigned char*) font_6x8; break; } case NORMALFONT: { _font_width = FONT8x8_WIDTH; _font_height = FONT8x8_HEIGHT; _font_start = FONT8x8_START; _font_end = FONT8x8_END; _font_bytes = FONT8x8_BYTES; _pFont = (unsigned char*) font_8x8; break; } case BIGFONT: { _font_width = FONT8x12_WIDTH; _font_height = FONT8x12_HEIGHT; _font_start = FONT8x12_START; _font_end = FONT8x12_END; _font_bytes = FONT8x12_BYTES; _pFont = (unsigned char*) font_8x12; break; } case TIMENUMBERFONT: { _font_width = FONT16x20_WIDTH; _font_height = FONT16x20_HEIGHT; _font_start = FONT16x20_START; _font_end = FONT16x20_END; _font_bytes = FONT16x20_BYTES; _pFont = (unsigned char*) font_16x20; break; } case BIGNUMBERFONT: { _font_width = FONT16x24_WIDTH; _font_height = FONT16x24_HEIGHT; _font_start = FONT16x24_START; _font_end = FONT16x24_END; _font_bytes = FONT16x24_BYTES; _pFont = (unsigned char*) font_16x24; break; } } } void PCD8544MS::GLCD_writeChar(BYTE x0, BYTE y0, BYTE ch, eFonts font, ePixelMode pmode,eDisplayMode mode,BYTE fupdate,int screen) { BYTE sendByte; chooseFont(font); if ((ch <= _font_start) || (ch > _font_end)) ch=_font_start; ch -= _font_start; /* for (BYTE i = 0; i < 3; i++) { locate(x, y + i); for (BYTE j = 0; j < 16; j++) { sendByte = *(pFont + ch*48 + i*16 + j); writeData((mode == NORMAL)? sendByte : (sendByte^0xff)); } }*/ for (int i = 0; i < _font_width; i++ ) { for (int f=0; f<_font_bytes; f++) { sendByte = *(_pFont + ch*_font_width*_font_bytes +f*_font_width+i); sendByte = ((mode == DISPLAY_NORMAL)? sendByte:(sendByte ^ 0xff)); for (int j=0 ; j<_font_height; j++) { if ((sendByte & 0x01) == 0x01) { GLCD_drawpixel(x0,y0+j+f*8,PIXEL_ON,FALSE,screen); } else { GLCD_drawpixel(x0,y0+j+f*8,PIXEL_OFF,FALSE,screen); } sendByte=sendByte>>1; } } x0++; } if (fupdate==TRUE) GLCD_update(screen); } void PCD8544MS::GLCD_drawpixel(BYTE x0, BYTE y0, ePixelMode mode,BYTE fupdate,int screen) { uint16_t index; BYTE offset; BYTE data; if ( x0 > LCD_X_RES-1 ) return; if ( y0 > LCD_Y_RES-1 ) return; index = ((y0 / 8) * LCD_X_RES) + x0; offset = y0 - ((y0 / 8) * 8); data = LcdCache[index]; if ( mode == PIXEL_OFF ) { data &= (~(0x01 << offset)); } else if ( mode == PIXEL_ON ) { data |= (0x01 << offset); } else if ( mode == PIXEL_XOR ) { data ^= (0x01 << offset); } LcdCache[index] = data; if ( index < _LoMark ) { _LoMark = index; } if ( index > _HiMark ) { _HiMark = index; } if (fupdate==TRUE) GLCD_update(screen); } void PCD8544MS::GLCD_drawline(BYTE x0, BYTE y0, BYTE x1, BYTE y1, ePixelMode mode,BYTE fupdate,int screen) { int dx, dy, stepx, stepy, fraction; dy = y1 - y0; dx = x1 - x0; if ( dy < 0 ) { dy = -dy; stepy = -1; } else { stepy = 1; } if ( dx < 0 ) { dx = -dx; stepx = -1; } else { stepx = 1; } dx <<= 1; dy <<= 1; GLCD_drawpixel( x0, y0, mode , FALSE,screen); if ( dx > dy ) { fraction = dy - (dx >> 1); while ( x0 != x1 ) { if ( fraction >= 0 ) { y0 += stepy; fraction -= dx; } x0 += stepx; fraction += dy; GLCD_drawpixel( x0, y0, mode , FALSE,screen); } } else { fraction = dx - (dy >> 1); while ( y0 != y1 ) { if ( fraction >= 0 ) { x0 += stepx; fraction -= dy; } y0 += stepy; fraction += dx; GLCD_drawpixel( x0, y0, mode , FALSE,screen); } } if (fupdate==TRUE) GLCD_update(screen); } void PCD8544MS::GLCD_drawrectangle(BYTE x0, BYTE y0, BYTE x1, BYTE y1, eFillMode fill, ePixelMode mode,BYTE fupdate,int screen) { if (fill==1) { BYTE i, xmin, xmax, ymin, ymax; if (x0 < x1) { // Find x min and max xmin = x0; xmax = x1; } else { xmin = x1; xmax = x0; } if (y0 < y1) { // Find the y min and max ymin = y0; ymax = y1; } else { ymin = y1; ymax = y0; } for (; xmin <= xmax; ++xmin) { for (i=ymin; i<=ymax; ++i) { GLCD_drawpixel(xmin, i, mode, FALSE,screen); } } } else { GLCD_drawline(x0, y0, x1, y0, mode, FALSE,screen); // Draw the 4 sides GLCD_drawline(x0, y1, x1, y1, mode, FALSE,screen); GLCD_drawline(x0, y0, x0, y1, mode, FALSE,screen); GLCD_drawline(x1, y0, x1, y1, mode, FALSE,screen); } if (fupdate==TRUE) GLCD_update(screen); } void PCD8544MS::GLCD_drawcircle(BYTE x0, BYTE y0, BYTE radius, eFillMode fill, ePixelMode mode, BYTE fupdate,int screen) { int err, x, y; err = -radius; x = radius; y = 0; while (x >= y) { if (fill==1) { GLCD_drawline(x0 - x, y0 + y, x0 + x, y0 + y, mode,FALSE,screen); GLCD_drawline(x0 - x, y0 - y, x0 + x, y0 - y, mode,FALSE,screen); GLCD_drawline(x0 - y, y0 + x, x0 + y, y0 + x, mode,FALSE,screen); GLCD_drawline(x0 - y, y0 - x, x0 + y, y0 - x, mode,FALSE,screen); } else { GLCD_drawpixel(x0 + x, y0 + y, mode,FALSE,screen); GLCD_drawpixel(x0 - x, y0 + y, mode,FALSE,screen); GLCD_drawpixel(x0 + x, y0 - y, mode,FALSE,screen); GLCD_drawpixel(x0 - x, y0 - y, mode,FALSE,screen); GLCD_drawpixel(x0 + y, y0 + x, mode,FALSE,screen); GLCD_drawpixel(x0 - y, y0 + x, mode,FALSE,screen); GLCD_drawpixel(x0 + y, y0 - x, mode,FALSE,screen); GLCD_drawpixel(x0 - y, y0 - x, mode,FALSE,screen); } err += y; y++; err += y; if (err >= 0) { x--; err -= x; err -= x; } } if (fupdate==TRUE) GLCD_update(screen); } void PCD8544MS::GLCD_drawprogressbar(BYTE x0, BYTE y0, BYTE w, BYTE h, BYTE percentage,BYTE fupdate,int screen) { GLCD_drawrectangle(x0,y0,x0+w,y0+h,FILL_OFF,PIXEL_ON, FALSE,screen); GLCD_drawrectangle(x0+2,y0+2,x0+w-2,y0+h-2,FILL_ON,PIXEL_OFF, FALSE,screen); GLCD_drawrectangle(x0+2,y0+2,x0+2+(percentage*(w-4)/100),y0+h-2,FILL_ON,PIXEL_ON, FALSE,screen); if (fupdate==TRUE) GLCD_update(screen); } void PCD8544MS::GLCD_drawchart(BYTE x0, BYTE y0, BYTE w, BYTE h, BYTE unitx, BYTE unity, eRasterMode rMode, eChartMode cMode,eDrawMode dMode, int16_t * val, int size, int t,int screen) { int maxy; int _scale=1; int prescale=1; signed char v1,v2; char buffer[4]; if (size>w) size=w; // search maximum value to calculate scale if (dMode==DRAW_OVERWRITE) { maxy=0; for (int i=0; i<size; i++) { if (val[i]>maxy) maxy=val[i]; } if (maxy>h) { //scale can be 1,2,5 *10i prescale= ((maxy-1)/((h/unity)*unity)); _scale=1; while (prescale>10) { _scale=_scale*10; prescale=prescale/10; } if (prescale>1) _scale=_scale*5; else if (prescale==1) _scale =_scale*2; } Scale=_scale; } if (dMode==DRAW_OVERWRITE) { GLCD_drawrectangle(x0-11,y0-h,x0+w,y0+4+7,FILL_ON,PIXEL_OFF,FALSE,screen); GLCD_drawline(x0,y0,x0,y0-h,PIXEL_ON,FALSE,screen); GLCD_drawline(x0,y0,x0+w,y0,PIXEL_ON,FALSE,screen); //drawrectangle(x0,y0-h,x0+w,y0,FILL_OFF,PIXEL_ON,FALSE); for (int i=0; i<=h; i++) { if ((i % unity) == 0) { GLCD_drawpixel(x0-2,y0-i,PIXEL_ON,FALSE,screen); // drawpixel(x0+w+2,y0-i,PIXEL_ON,FALSE); if (rMode==RASTER_ON) { for (int r=0; r<=w; r++) { if ((r % 2) ==0) GLCD_drawpixel(x0+r,y0-i,PIXEL_ON,FALSE,screen); } } // draw vertical axis labels itostr(buffer,i*Scale); // pc_PCD8544.traceOut(" %i %s |",i*Scale,buffer); GLCD_writeString(x0-11,y0-i+1,buffer,VERYSMALLFONT,PIXEL_OFF,DISPLAY_NORMAL,SPACE_NONE,FALSE,screen); } if ((i % 2) == 0) { GLCD_drawpixel(x0-1,y0-i,PIXEL_ON,FALSE,screen); // drawpixel(x0+w+1,y0-i,PIXEL_ON,FALSE); } } for (int i=0; i<=w; i++) { if (((i+(t % unitx)) % unitx) == 0) { GLCD_drawpixel(x0+i,y0+2,PIXEL_ON,FALSE,screen); if (rMode==RASTER_ON) { for (int r=0; r<=h; r++) { if ((r % 2) ==0) GLCD_drawpixel(x0+i,y0-r,PIXEL_ON,FALSE,screen); } } if (((t-w+i)/unitx)>=0) snprintf(buffer,3,"%i",((t-w+i)/unitx)); else snprintf(buffer,3,"%i",24+((t-w+i)/unitx)); // pc_PCD8544.traceOut(" %i %s ",(t-w+i)/unitx,buffer); GLCD_writeString(x0+i-3,y0+4,buffer,VERYSMALLFONT,PIXEL_OFF,DISPLAY_NORMAL,SPACE_NORMAL,FALSE,screen); } if ((i % 2) == 0) { GLCD_drawpixel(x0+i,y0+1,PIXEL_ON,FALSE,screen); } } // update(); } for (int i=0; i<size; i++) { // pc_PCD8544.traceOut(" %i ",val[i]); v1 = val[i] / Scale; if (v1>h) v1=h; if (i!=(size-1)) { v2 = val[i+1] / Scale; if (v2>h) v2=h; } else v2=v1; switch (cMode) { case C_POINT: { GLCD_drawpixel(x0+i,y0-v1,PIXEL_ON,FALSE,screen); break; } case C_LINE: { GLCD_drawline(x0+i,y0-v1,x0+i+1,y0-v2,PIXEL_ON,FALSE,screen); break; } case C_VLINE: { GLCD_drawline(x0+i,y0-v1,x0+i,y0,PIXEL_ON,FALSE,screen); break; } } } GLCD_update(screen); }