simple Graphics LCD library. This Lib is used with GDM12864B 128x64 display.
Diff: glcd.cpp
- Revision:
- 0:e3bff63312e5
diff -r 000000000000 -r e3bff63312e5 glcd.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/glcd.cpp Sun Sep 18 08:54:04 2011 +0000 @@ -0,0 +1,524 @@ +/*********************************************************** +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 +} \ No newline at end of file