simple Graphics LCD library. This Lib is used with GDM12864B 128x64 display.

Dependents:   LCD_Test

Revision:
0:e3bff63312e5
--- /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