simple Graphics LCD library. This Lib is used with GDM12864B 128x64 display.
glcd.cpp
- Committer:
- dupuyb
- Date:
- 2011-09-18
- Revision:
- 0:e3bff63312e5
File content as of revision 0:e3bff63312e5:
/*********************************************************** Author: Dupuy Bruno Date: 5 mars 2001 Version: beta ************************************************************/ #include "glcd.h" GLCD::GLCD (PinName _DI, PinName _RW, PinName _E, PinName _CS2, PinName _CS1, BusInOut *BUSLCD):GLCD_DI(_DI),GLCD_RW(_RW),GLCD_E(_E),GLCD_CS2(_CS2),GLCD_CS1(_CS1) { LCD_PORT = BUSLCD; ready = false; } void GLCD::reset_pins(int val) { GLCD_DI = val; GLCD_RW = val; GLCD_E = val; GLCD_CS2 = val; GLCD_CS1 = val; LCD_PORT->output(); LCD_PORT->write((val==0)?(0):(0xFF)); } void GLCD::setTest(int step) { char* strpin[] = {"DI", "RW", "E" ,"CS2", "CS1"}; DigitalOut* ctrl[] = {&GLCD_DI, &GLCD_RW , &GLCD_E, &GLCD_CS2, &GLCD_CS1}; printf("\n\rScanning all lcd pins mode:%d\n\r",step); if (step== 0) { reset_pins(0);; printf("All pins are set to 0\n\r"); } if (step > 0 && step < 6) { ctrl[step-1]->write(1); printf("Pins (%s) is set to 1\n\r", strpin[step-1]); } if (step > 5 & step < 14) { LCD_PORT->write((1<<(step-6))); printf("Pins LCD_PORT are set to value 0x%X\n\r", (1<<(step-6))); } if (step == 255) { reset_pins(1);; printf("All pins are set to 1\n\r"); } } bool GLCD::isUsed() { return isused; } bool GLCD::getXor() { return _xor; } void GLCD::setXor(bool s) { _xor = s; } // Purpose: Write a byte of data to the specified chip // Inputs: 1) chipSelect - which chip to write the data to // 2) data - the byte of data to write void GLCD::writeByte(unsigned char side, unsigned char data) { // Choose which side to write to if (side == LEFT) GLCD_CS2 = 1; else GLCD_CS1 = 1; GLCD_RW = 0; // Set for writing LCD_PORT->write(data); // Put the data on the port GLCD_E = 1; // Pulse the enable pin wait_us(1); GLCD_E = 0; GLCD_CS1 = 0; // Reset the chip select lines GLCD_CS2 = 0; } // Purpose: Reads a byte of data from the specified chip // Ouputs: A byte of data read from the chip unsigned char GLCD::readByte(unsigned char side) { unsigned char data; // Stores the data reading in LCD // Choose which side to write to if (side == LEFT) GLCD_CS2 = 1; else GLCD_CS1 = 1; LCD_PORT->input(); // Set port b to input GLCD_RW = 1; // Set for reading GLCD_E = 1; wait_us(1); GLCD_E = 0; // Pulse the enable pin // wait_us(1); GLCD_E = 1; wait_us(1); data = LCD_PORT->read(); // Get the data from the display's output register GLCD_E = 0; GLCD_CS1 = 0; // Reset the chip select lines GLCD_CS2 = 0; return data; // Return the read data } void GLCD::init(bool mode) { ready = true; // Initialize some pins. // Don't reset because GLCD_RST is connected to VDD // GLCD_RST = 1; isused = true; _xor = false; GLCD_E = 0; GLCD_CS1 = 0; GLCD_CS2 = 0; GLCD_DI = 0; // Set for instruction LCD_PORT->output(); LCD_PORT->mode(PullDown); writeByte(LEFT, 0xC0); // Specify first RAM line at the top writeByte(RIGHT, 0xC0); // of the screen writeByte(LEFT, 0x40); // Set the column address to 0 writeByte(RIGHT, 0x40); writeByte(LEFT, 0xB8); // Set the page address to 0 writeByte(RIGHT, 0xB8); if (mode) { writeByte(LEFT, 0x3F); // Turn the display on writeByte(RIGHT, 0x3F); } else { writeByte(LEFT, 0x3E); // Turn the display off writeByte(RIGHT, 0x3E); } fillScreen(WHITE); // Clear the display repaint(); isused = false; } // Purpose: Fill the LCD screen with the passed in color. // Works much faster than drawing a rectangle to fill the screen. // Inputs: ON - turn all the pixels on // OFF - turn all the pixels off void GLCD::fillScreen(bool color) { unsigned char data; char *p1, *p2; unsigned short i; p1 = left; p2 = right; data = 0xFF * color; for (i = 0; i < 512; ++i) { *p1++ = data; *p2++ = data; } } // Exec time 5.221ms void GLCD::repaint() { int j, i; isused = true; char* p1 = left; char* p2 = right; int page = 0xB8; GLCD_DI = 0; // Set for instruction writeByte(LEFT, 0x40); // Set the column address to 0 writeByte(RIGHT, 0x40); writeByte(LEFT, page); // Set the page address to 0 writeByte(RIGHT, page); for (j = 0; j < 8; j++, page+=1) { GLCD_DI = 0; writeByte(LEFT, page); writeByte(RIGHT, page); for (i = 0; i < 64; i++) { GLCD_DI = 1; writeByte(LEFT, *p1++); writeByte(RIGHT, *p2++); } } isused = false; } void GLCD::setPixel( unsigned short x, unsigned short y, bool color) { char* p; unsigned short temp; bool nec; if (x > 127 || y > 63) return; temp = y / 8; temp *= 64; temp += x; if (x > 63) p = right + temp - 64; else p = left + temp; if (_xor) nec = BIT_TEST(*p, y % 8) ^ color; else nec = color; if (nec == BLACK) BIT_SET(*p, y % 8); else BIT_CLEAR(*p, y % 8); } bool GLCD::getPixel( unsigned short x, unsigned short y) { char* p; unsigned short temp; if (x > 127 || y > 63) return false; temp = y / 8; temp *= 64; temp += x; if (x > 63) p = right + temp - 64; else p = left + temp; return BIT_TEST(*p, y % 8); } void GLCD::lineh( unsigned short x0, unsigned short y0, unsigned short x1, bool color) { unsigned short x; for (x = x0; x < x1; x++) { setPixel(x, y0, color); } } void GLCD::linev( unsigned short x0, unsigned short y0, unsigned short y1, bool color) { unsigned short y; for (y = y0; y < y1; y++) { setPixel(x0, y, color); } } // Purpose: Draw a line on a graphic LCD using Bresenham's // line drawing algorithm // Inputs: (x1, y1) - the start coordinate // (x2, y2) - the end coordinate // color - ON or OFF // Dependencies: pixel() void GLCD::line( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, char dash, bool color) { short x, y, addx, addy, dx, dy; signed long P; short i; int pat = 0; dx = abs((short)(x2 - x1)); dy = abs((short)(y2 - y1)); x = x1; y = y1; if (x1 > x2) addx = -1; else addx = 1; if (y1 > y2) addy = -1; else addy = 1; if (dx >= dy) { P = 2 * dy - dx; for (i = 0; i <= dx; ++i) { if ( (dash & (char)(1 << pat)) != 0) setPixel(x, y, color); pat = ( (pat<7)? (pat+1): ( 0 ) ); if (P < 0) { P += 2 * dy; x += addx; } else { P += 2 * dy - 2 * dx; x += addx; y += addy; } } } else { P = 2 * dx - dy; for (i = 0; i <= dy; ++i) { if ( (dash & (char)(1 << pat)) != 0) setPixel(x, y, color); pat = ( (pat<7)? (pat+1): ( 0 ) ); if (P < 0) { P += 2 * dx; y += addy; } else { P += 2 * dx - 2 * dy; x += addx; y += addy; } } } } // Purpose: Draw a rectangle on a graphic LCD // Inputs: (x1, y1) - the start coordinate // (x2, y2) - the end coordinate // fill - YES or NO // color - ON or OFF // Dependencies: pixel(), line() void GLCD::rectangle( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, char dash, bool fill, bool color) { if (fill) { unsigned short y, ymax; // Find the y min and max if (y1 < y2) { y = y1; ymax = y2; } else { y = y2; ymax = y1; } for (; y <= ymax; ++y) // Draw lines to fill the rectangle line(x1, y, x2, y, dash, color); } else { line(x1, y1, x2, y1, dash, color); // Draw the 4 sides line(x1, y2, x2, y2, dash, color); line(x1, y1, x1, y2, dash, color); line(x2, y1, x2, y2, dash, color); } } // Purpose: Draw a bar (wide line) on a graphic LCD // Inputs: (x1, y1) - the start coordinate // (x2, y2) - the end coordinate // width - The number of pixels wide // color - ON or OFF void GLCD::bar( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int width, bool color) { short x, y, addx, addy, j; int P, dx, dy, c1, c2; unsigned short i; dx = abs((short)(x2 - x1)); dy = abs((short)(y2 - y1)); x = x1; y = y1; c1 = -dx * x1 - dy * y1; c2 = -dx * x2 - dy * y2; if (x1 > x2) { addx = -1; c1 = -dx * x2 - dy * y2; c2 = -dx * x1 - dy * y1; } else addx = 1; if (y1 > y2) { addy = -1; c1 = -dx * x2 - dy * y2; c2 = -dx * x1 - dy * y1; } else addy = 1; if (dx >= dy) { P = 2 * dy - dx; for (i = 0; i <= dx; ++i) { for (j = -(width / 2); j < width / 2 + width % 2; ++j) { if (dx * x + dy * (y + j) + c1 >= 0 && dx * x + dy * (y + j) + c2 <= 0) setPixel(x, y + j, color); } if (P < 0) { P += 2 * dy; x += addx; } else { P += 2 * dy - 2 * dx; x += addx; y += addy; } } } else { P = 2 * dx - dy; for (i = 0; i <= dy; ++i) { if (P < 0) { P += 2 * dx; y += addy; } else { P += 2 * dx - 2 * dy; x += addx; y += addy; } for (j = -(width / 2); j < width/ 2 + width % 2; ++j) { if (dx * x + dy * (y + j) + c1 >= 0 && dx * x + dy * (y + j) + c2 <= 0) setPixel(x + j, y, color); } } } } // Purpose: Draw a circle on a graphic LCD // Inputs: (x,y) - the center of the circle // radius - the radius of the circle // fill - YES or NO // color - ON or OFF void GLCD::circle( unsigned short x, unsigned short y, unsigned short radius, bool fill, bool color) { short a, b, P; a = 0; b = radius; P = 1 - radius; do { if (fill) { line(x - a, y + b, x + a, y + b, (char)0xff, color); line(x - a, y - b, x + a, y - b, (char)0xff, color); line(x - b, y + a, x + b, y + a, (char)0xff, color); line(x - b, y - a, x + b, y - a, (char)0xff, color); } else { setPixel(a + x, b + y, color); setPixel(b + x, a + y, color); setPixel(x - a, b + y, color); setPixel(x - b, a + y, color); setPixel(b + x, y - a, color); setPixel(a + x, y - b, color); setPixel(x - a, y - b, color); setPixel(x - b, y - a, color); } if (P < 0) P += 3 + 2 * a++; else P += 5 + 2 * (a++ - b--); } while (a <= b); } /** * This functions draw an * ellipse. * * @param x {double} X coordinate * @param y {double} Y coordinate * @param a {double} Semimajor axis * @param b {double} Semiminor axis * @param angle {double} Angle of the ellipse */ unsigned short GLCD::ellipse(unsigned short x, unsigned short y,unsigned short a, unsigned short b, float angle, unsigned short steps, bool color) { if (steps == 0) steps = 36; // Angle is given by Degree Value float beta = -angle * (PI / 180); //(Math.PI/180) converts Degree Value into Radians float sinbeta = sin(beta); float cosbeta = cos(beta); for (int i = 0; i < 360; i += 360 / steps) { float alpha = i * (PI / 180) ; float sinalpha = sin(alpha); float cosalpha = cos(alpha); float X = x + (a * cosalpha * cosbeta - b * sinalpha * sinbeta); float Y = y + (a * cosalpha * sinbeta + b * sinalpha * cosbeta); setPixel((int)X, (int)Y, color); } return x+a; } unsigned short GLCD::icon(unsigned short xo, unsigned short yo, const char* iconptr, bool color, bool transparency) { unsigned short x, y, h, w, i=0; short b; char c; c = iconptr[i++]; // Codage 'H' or 'V' w = iconptr[i++]; // width in pixel h = iconptr[i++]; // height in pixel if (c=='V') { for (y=yo; y< yo + h; y+=8) { for (x = xo; x< xo + w; x++) { c = iconptr[i++]; for (b = 0; b < 8; b++) { if ( (y+b)-yo < h) { if (BIT_TEST(c, b)) setPixel(x, y+b, color); else if (!transparency) setPixel(x, y+b, !color); } } } } return xo + w; // last x position } if (c=='H') { for (y=yo; y< yo + h; y++) { for (x = xo; x< xo + w; x+=8) { c = iconptr[i++]; for (b = 0; b < 8; b++) { if ( (x+b)-xo < w) { if (BIT_TEST(c, b)) setPixel(x+b, y, color); else if (!transparency) setPixel(x+b, y, !color); } } } } return xo + w; // last x position } return xo + w; // last x position } // Purpose: Write text on a graphic LCD // Inputs: (x,y) - The upper left coordinate of the first letter // textptr - A pointer to an array of text to display // fontptr - A pointer to font // size - The size of the text: 1 = 5x7, 2 = 10x14, ... // color - ON or OFF // transparency - ON or OFF unsigned short GLCD::text( unsigned short x, unsigned short y, const char* textptr, const char* fontptr, unsigned char size, bool color, bool transparency) { unsigned short i, j, k, l, m = 0; // Loop counters int w = fontptr[0]; // width int h = fontptr[1]; // height char fc = fontptr[2]; // First char char lc = fontptr[3]; // Last char char pixData; // Loop through the passed string for (i = 0; textptr[i] != '\0'; ++i, ++x) { // Loop through character byte data for (j = 0; j < w; ++j, x += size) { if ( textptr[i] >= fc && textptr[i] <= lc) pixData = fontptr[((textptr[i] - fc) * w + j) + 4]; else pixData = 0xAA; // Bad char // Loop through the vertical pixels for (k = 0; k < h; k++) { // Check if the pixel should be set if (BIT_TEST(pixData, k)) { // The next two loops change the character's size for (l = 0; l < size; ++l) { for (m = 0; m < size; ++m) { // Draws the pixel at color setPixel(x + m, y + k * size + l, color); } } } else { if (!transparency) { for (l = 0; l < size; ++l) { for (m = 0; m < size; ++m) { // Draws the pixel at ~color setPixel(x + m, y + k * size + l, !color); } } } } } } // Clean gap between two caracters if (!transparency) { for (k = 0; k < h * size; ++k) { // Draws the pixel at ~color setPixel(x, y + k, !color); } } } return x + m; // last x position }