PCD8544 multiscreen
Diff: PCD8544MS.cpp
- Revision:
- 0:61dcd2c0299a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCD8544MS.cpp Fri Jun 15 18:37:00 2012 +0000 @@ -0,0 +1,925 @@ +/* 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); +} +