Dupuy Bruno / GLCD

Dependents:   LCD_Test

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers glcd.cpp Source File

glcd.cpp

00001 /***********************************************************
00002 Author: Dupuy Bruno
00003 Date: 5 mars 2001
00004 Version: beta
00005 ************************************************************/
00006 #include "glcd.h"
00007 
00008 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) {
00009     LCD_PORT = BUSLCD;
00010     ready = false;
00011 }
00012 
00013 void GLCD::reset_pins(int val) {
00014     GLCD_DI = val;
00015     GLCD_RW = val;
00016     GLCD_E = val;
00017     GLCD_CS2 = val;
00018     GLCD_CS1 = val;
00019     LCD_PORT->output();
00020     LCD_PORT->write((val==0)?(0):(0xFF));
00021 }
00022 
00023 void GLCD::setTest(int step) {
00024     char* strpin[] = {"DI", "RW", "E" ,"CS2", "CS1"};
00025     DigitalOut* ctrl[] = {&GLCD_DI, &GLCD_RW , &GLCD_E, &GLCD_CS2, &GLCD_CS1};
00026     printf("\n\rScanning all lcd pins mode:%d\n\r",step);
00027     if (step== 0) {
00028         reset_pins(0);;
00029         printf("All pins are set to 0\n\r");
00030     }
00031     if (step > 0 && step < 6) {
00032         ctrl[step-1]->write(1);
00033         printf("Pins (%s) is set to 1\n\r", strpin[step-1]);
00034     }
00035     if (step > 5 & step < 14) {
00036         LCD_PORT->write((1<<(step-6)));
00037         printf("Pins LCD_PORT are set to value 0x%X\n\r", (1<<(step-6)));
00038     }
00039     if (step == 255) {
00040         reset_pins(1);;
00041         printf("All pins are set to 1\n\r");
00042     }
00043 }
00044 
00045 bool GLCD::isUsed() {
00046     return isused;
00047 }
00048 
00049 bool GLCD::getXor() {
00050     return _xor;
00051 }
00052 void GLCD::setXor(bool s) {
00053     _xor = s;
00054 }
00055 
00056 // Purpose:    Write a byte of data to the specified chip
00057 // Inputs:     1) chipSelect - which chip to write the data to
00058 //             2) data - the byte of data to write
00059 void GLCD::writeByte(unsigned char side, unsigned char data) {
00060     // Choose which side to write to
00061     if (side == LEFT) GLCD_CS2 = 1;
00062     else              GLCD_CS1 = 1;
00063     GLCD_RW = 0; // Set for writing
00064     LCD_PORT->write(data); // Put the data on the port
00065     GLCD_E = 1;  // Pulse the enable pin
00066     wait_us(1);
00067     GLCD_E = 0;
00068     GLCD_CS1 = 0; // Reset the chip select lines
00069     GLCD_CS2 = 0;
00070 }
00071 
00072 // Purpose:       Reads a byte of data from the specified chip
00073 // Ouputs:        A byte of data read from the chip
00074 unsigned char GLCD::readByte(unsigned char side) {
00075     unsigned char data; // Stores the data reading in LCD
00076     // Choose which side to write to
00077     if (side == LEFT)  GLCD_CS2 = 1;
00078     else               GLCD_CS1 = 1;
00079     LCD_PORT->input(); // Set port b to input
00080     GLCD_RW = 1; // Set for reading
00081     GLCD_E = 1;
00082     wait_us(1);
00083     GLCD_E = 0; // Pulse the enable pin
00084     // wait_us(1);
00085     GLCD_E = 1;
00086     wait_us(1);
00087     data =  LCD_PORT->read(); // Get the data from the display's output register
00088     GLCD_E = 0;
00089     GLCD_CS1 = 0; // Reset the chip select lines
00090     GLCD_CS2 = 0;
00091     return data; // Return the read data
00092 }
00093 
00094 void GLCD::init(bool mode) {
00095     ready = true;
00096     // Initialize some pins.
00097     // Don't reset because GLCD_RST is connected to VDD
00098     // GLCD_RST = 1;
00099     isused = true;
00100     _xor = false;
00101     GLCD_E = 0;
00102     GLCD_CS1 = 0;
00103     GLCD_CS2 = 0;
00104     GLCD_DI = 0; // Set for instruction
00105     LCD_PORT->output();
00106     LCD_PORT->mode(PullDown);
00107     writeByte(LEFT, 0xC0); // Specify first RAM line at the top
00108     writeByte(RIGHT, 0xC0); // of the screen
00109     writeByte(LEFT, 0x40); // Set the column address to 0
00110     writeByte(RIGHT, 0x40);
00111     writeByte(LEFT, 0xB8); // Set the page address to 0
00112     writeByte(RIGHT, 0xB8);
00113     if (mode) {
00114         writeByte(LEFT, 0x3F); // Turn the display on
00115         writeByte(RIGHT, 0x3F);
00116     } else {
00117         writeByte(LEFT, 0x3E); // Turn the display off
00118         writeByte(RIGHT, 0x3E);
00119     }
00120     fillScreen(WHITE); // Clear the display
00121     repaint();
00122     isused = false;
00123 }
00124 
00125 // Purpose:       Fill the LCD screen with the passed in color.
00126 //                Works much faster than drawing a rectangle to fill the screen.
00127 // Inputs:        ON - turn all the pixels on
00128 //                OFF - turn all the pixels off
00129 void GLCD::fillScreen(bool color) {
00130     unsigned char data;
00131     char *p1, *p2;
00132     unsigned short i;
00133     p1 = left;
00134     p2 = right;
00135     data = 0xFF * color;
00136     for (i = 0; i < 512; ++i) {
00137         *p1++ = data;
00138         *p2++ = data;
00139     }
00140 }
00141 
00142 // Exec time 5.221ms
00143 void GLCD::repaint() {
00144     int j, i;
00145     isused = true;
00146     char* p1 = left;
00147     char* p2 = right;
00148     int page = 0xB8;
00149     GLCD_DI = 0;                // Set for instruction
00150     writeByte(LEFT, 0x40);     // Set the column address to 0
00151     writeByte(RIGHT, 0x40);
00152     writeByte(LEFT, page);     // Set the page address to 0
00153     writeByte(RIGHT, page);
00154     for (j = 0; j < 8; j++, page+=1) {
00155         GLCD_DI = 0;
00156         writeByte(LEFT, page);
00157         writeByte(RIGHT, page);
00158         for (i = 0; i < 64; i++) {
00159             GLCD_DI = 1;
00160             writeByte(LEFT, *p1++);
00161             writeByte(RIGHT, *p2++);
00162         }
00163     }
00164     isused = false;
00165 }
00166 
00167 void GLCD::setPixel( unsigned short x,  unsigned short y, bool color) {
00168     char* p;
00169     unsigned short temp;
00170     bool nec;
00171     if (x > 127 || y > 63) return;
00172     temp = y / 8;
00173     temp *= 64;
00174     temp += x;
00175     if (x > 63)
00176         p = right + temp - 64;
00177     else
00178         p = left + temp;
00179     if (_xor)
00180         nec = BIT_TEST(*p, y % 8) ^ color;
00181     else
00182         nec = color;
00183     if (nec == BLACK)
00184         BIT_SET(*p, y % 8);
00185     else
00186         BIT_CLEAR(*p, y % 8);
00187 }
00188 
00189 bool GLCD::getPixel( unsigned short x, unsigned short y) {
00190     char* p;
00191     unsigned short temp;
00192     if (x > 127 || y > 63) return false;
00193     temp = y / 8;
00194     temp *= 64;
00195     temp += x;
00196     if (x > 63)
00197         p = right + temp - 64;
00198     else
00199         p = left + temp;
00200     return  BIT_TEST(*p, y % 8);
00201 }
00202 
00203 void GLCD::lineh( unsigned short x0,  unsigned short y0,  unsigned short x1, bool color) {
00204     unsigned short x;
00205     for (x = x0; x < x1; x++) {
00206         setPixel(x, y0, color);
00207     }
00208 }
00209 
00210 void GLCD::linev( unsigned short x0,  unsigned short y0,  unsigned short y1, bool color) {
00211     unsigned short y;
00212     for (y = y0; y < y1; y++) {
00213         setPixel(x0, y, color);
00214     }
00215 }
00216 
00217 // Purpose:       Draw a line on a graphic LCD using Bresenham's
00218 //                line drawing algorithm
00219 // Inputs:        (x1, y1) - the start coordinate
00220 //                (x2, y2) - the end coordinate
00221 //                color - ON or OFF
00222 // Dependencies:  pixel()
00223 void GLCD::line( unsigned short x1,  unsigned short y1,  unsigned short x2,  unsigned short y2, char dash, bool color) {
00224     short x, y, addx, addy, dx, dy;
00225     signed long P;
00226     short i;
00227     int pat = 0;
00228     dx = abs((short)(x2 - x1));
00229     dy = abs((short)(y2 - y1));
00230     x = x1;
00231     y = y1;
00232     if (x1 > x2)
00233         addx = -1;
00234     else
00235         addx = 1;
00236     if (y1 > y2)
00237         addy = -1;
00238     else
00239         addy = 1;
00240     if (dx >= dy) {
00241         P = 2 * dy - dx;
00242         for (i = 0; i <= dx; ++i) {
00243             if ( (dash & (char)(1 << pat)) != 0)
00244                 setPixel(x, y, color);
00245             pat = ( (pat<7)? (pat+1): ( 0 ) );
00246             if (P < 0) {
00247                 P += 2 * dy;
00248                 x += addx;
00249             } else {
00250                 P += 2 * dy - 2 * dx;
00251                 x += addx;
00252                 y += addy;
00253             }
00254         }
00255     } else {
00256         P = 2 * dx - dy;
00257         for (i = 0; i <= dy; ++i) {
00258             if ( (dash & (char)(1 << pat)) != 0)
00259                 setPixel(x, y, color);
00260             pat = ( (pat<7)? (pat+1): ( 0 ) );
00261             if (P < 0) {
00262                 P += 2 * dx;
00263                 y += addy;
00264             } else {
00265                 P += 2 * dx - 2 * dy;
00266                 x += addx;
00267                 y += addy;
00268             }
00269         }
00270     }
00271 }
00272 
00273 // Purpose:       Draw a rectangle on a graphic LCD
00274 // Inputs:        (x1, y1) - the start coordinate
00275 //                (x2, y2) - the end coordinate
00276 //                fill  - YES or NO
00277 //                color - ON or OFF
00278 // Dependencies:  pixel(), line()
00279 void GLCD::rectangle( unsigned short x1,  unsigned short y1,  unsigned short x2,  unsigned short y2, char dash, bool fill, bool color) {
00280     if (fill) {
00281         unsigned short y, ymax; // Find the y min and max
00282         if (y1 < y2) {
00283             y = y1;
00284             ymax = y2;
00285         } else {
00286             y = y2;
00287             ymax = y1;
00288         }
00289         for (; y <= ymax; ++y)
00290             // Draw lines to fill the rectangle
00291             line(x1, y, x2, y, dash, color);
00292     } else {
00293         line(x1, y1, x2, y1, dash, color); // Draw the 4 sides
00294         line(x1, y2, x2, y2, dash, color);
00295         line(x1, y1, x1, y2, dash, color);
00296         line(x2, y1, x2, y2, dash, color);
00297     }
00298 }
00299 
00300 // Purpose:       Draw a bar (wide line) on a graphic LCD
00301 // Inputs:        (x1, y1) - the start coordinate
00302 //                (x2, y2) - the end coordinate
00303 //                width  - The number of pixels wide
00304 //                color - ON or OFF
00305 void GLCD::bar( unsigned short x1,  unsigned short y1,  unsigned short x2,  unsigned short y2, int width, bool color) {
00306     short x, y, addx, addy, j;
00307     int P, dx, dy, c1, c2;
00308     unsigned short i;
00309     dx = abs((short)(x2 - x1));
00310     dy = abs((short)(y2 - y1));
00311     x = x1;
00312     y = y1;
00313     c1 = -dx * x1 - dy * y1;
00314     c2 = -dx * x2 - dy * y2;
00315     if (x1 > x2) {
00316         addx = -1;
00317         c1 = -dx * x2 - dy * y2;
00318         c2 = -dx * x1 - dy * y1;
00319     } else
00320         addx = 1;
00321     if (y1 > y2) {
00322         addy = -1;
00323         c1 = -dx * x2 - dy * y2;
00324         c2 = -dx * x1 - dy * y1;
00325     } else
00326         addy = 1;
00327     if (dx >= dy) {
00328         P = 2 * dy - dx;
00329         for (i = 0; i <= dx; ++i) {
00330             for (j = -(width / 2); j < width
00331                     / 2 + width % 2; ++j) {
00332                 if (dx * x + dy * (y + j) + c1   >= 0 && dx * x + dy   * (y + j) + c2 <= 0)
00333                     setPixel(x, y + j,   color);
00334             }
00335             if (P < 0) {
00336                 P += 2 * dy;
00337                 x += addx;
00338             } else {
00339                 P += 2 * dy - 2 * dx;
00340                 x += addx;
00341                 y += addy;
00342             }
00343         }
00344     } else {
00345         P = 2 * dx - dy;
00346         for (i = 0; i <= dy; ++i) {
00347             if (P < 0) {
00348                 P += 2 * dx;
00349                 y += addy;
00350             } else {
00351                 P += 2 * dx - 2 * dy;
00352                 x += addx;
00353                 y += addy;
00354             }
00355             for (j = -(width / 2); j < width/ 2 + width % 2; ++j) {
00356                 if (dx * x + dy * (y + j) + c1   >= 0 && dx * x + dy   * (y + j) + c2 <= 0)
00357                     setPixel(x + j, y,   color);
00358             }
00359         }
00360     }
00361 }
00362 
00363 // Purpose:       Draw a circle on a graphic LCD
00364 // Inputs:        (x,y) - the center of the circle
00365 //                radius - the radius of the circle
00366 //                fill - YES or NO
00367 //                color - ON or OFF
00368 void GLCD::circle( unsigned short x,  unsigned short y, unsigned short radius, bool fill, bool color) {
00369     short a, b, P;
00370     a = 0;
00371     b = radius;
00372     P = 1 - radius;
00373     do {
00374         if (fill) {
00375             line(x - a, y + b, x + a, y + b, (char)0xff, color);
00376             line(x - a, y - b, x + a, y - b, (char)0xff, color);
00377             line(x - b, y + a, x + b, y + a, (char)0xff, color);
00378             line(x - b, y - a, x + b, y - a, (char)0xff, color);
00379         } else {
00380             setPixel(a + x, b + y, color);
00381             setPixel(b + x, a + y, color);
00382             setPixel(x - a, b + y, color);
00383             setPixel(x - b, a + y, color);
00384             setPixel(b + x, y - a, color);
00385             setPixel(a + x, y - b, color);
00386             setPixel(x - a, y - b, color);
00387             setPixel(x - b, y - a, color);
00388         }
00389         if (P < 0)
00390             P += 3 + 2 * a++;
00391         else
00392             P += 5 + 2 * (a++ - b--);
00393     } while (a <= b);
00394 }
00395 
00396 /**
00397 * This functions draw an
00398 * ellipse.
00399 *
00400 * @param x {double} X coordinate
00401 * @param y {double} Y coordinate
00402 * @param a {double} Semimajor axis
00403 * @param b {double} Semiminor axis
00404 * @param angle {double} Angle of the ellipse
00405 */
00406 unsigned short GLCD::ellipse(unsigned short x, unsigned short y,unsigned short  a, unsigned short b, float angle, unsigned short steps, bool color) {
00407     if (steps == 0)
00408         steps = 36;
00409 
00410     // Angle is given by Degree Value
00411     float beta = -angle * (PI / 180); //(Math.PI/180) converts Degree Value into Radians
00412     float sinbeta = sin(beta);
00413     float cosbeta = cos(beta);
00414 
00415     for (int i = 0; i < 360; i += 360 / steps) {
00416         float alpha = i * (PI / 180) ;
00417         float sinalpha = sin(alpha);
00418         float cosalpha = cos(alpha);
00419 
00420         float X = x + (a * cosalpha * cosbeta - b * sinalpha * sinbeta);
00421         float Y = y + (a * cosalpha * sinbeta + b * sinalpha * cosbeta);
00422         setPixel((int)X, (int)Y, color);
00423 
00424     }
00425    return x+a;
00426 }
00427 
00428 unsigned short GLCD::icon(unsigned short  xo, unsigned short  yo, const char* iconptr, bool color, bool transparency) {
00429     unsigned short  x, y, h, w, i=0;
00430     short b;
00431     char c;
00432     c = iconptr[i++]; // Codage 'H' or 'V'
00433     w = iconptr[i++]; // width in pixel
00434     h = iconptr[i++]; // height in pixel
00435     if (c=='V') {
00436         for (y=yo; y< yo + h;  y+=8) {
00437             for (x = xo;   x< xo + w;  x++) {
00438                 c = iconptr[i++];
00439                 for (b = 0; b < 8; b++) {
00440                     if ( (y+b)-yo < h) {
00441                         if (BIT_TEST(c, b))
00442                             setPixel(x, y+b, color);
00443                         else if (!transparency)
00444                             setPixel(x, y+b, !color);
00445                     }
00446                 }
00447             }
00448         }
00449         return xo + w; // last x position
00450     }
00451     if (c=='H') {
00452         for (y=yo; y< yo + h;  y++) {
00453             for (x = xo;   x< xo + w;  x+=8) {
00454                 c = iconptr[i++];
00455                 for (b = 0; b < 8; b++) {
00456                     if ( (x+b)-xo < w) {
00457                         if (BIT_TEST(c, b))
00458                             setPixel(x+b, y, color);
00459                         else if (!transparency)
00460                             setPixel(x+b, y, !color);
00461                     }
00462                 }
00463             }
00464         }
00465         return xo + w; // last x position
00466     }
00467     return xo + w; // last x position
00468 }
00469 
00470 // Purpose:       Write text on a graphic LCD
00471 // Inputs:        (x,y) - The upper left coordinate of the first letter
00472 //                textptr - A pointer to an array of text to display
00473 //                fontptr - A pointer to font
00474 //                size - The size of the text: 1 = 5x7, 2 = 10x14, ...
00475 //                color - ON or OFF
00476 //                transparency - ON or OFF
00477 unsigned short GLCD::text( unsigned short x, unsigned short y, const char* textptr, const char* fontptr, unsigned char size, bool color, bool transparency) {
00478     unsigned short i, j, k, l, m = 0; // Loop counters
00479     int w = fontptr[0]; // width
00480     int h = fontptr[1]; // height
00481     char fc = fontptr[2]; // First char
00482     char lc = fontptr[3]; // Last char
00483     char pixData;
00484     // Loop through the passed string
00485     for (i = 0; textptr[i] != '\0'; ++i, ++x) {
00486         // Loop through character byte data
00487         for (j = 0; j < w; ++j, x += size) {
00488             if ( textptr[i] >= fc && textptr[i] <= lc)
00489                 pixData = fontptr[((textptr[i] - fc) * w + j) + 4];
00490             else
00491                 pixData = 0xAA; // Bad char
00492             // Loop through the vertical pixels
00493             for (k = 0; k < h; k++) {
00494                 // Check if the pixel should be set
00495                 if (BIT_TEST(pixData, k)) {
00496                     // The next two loops change the character's size
00497                     for (l = 0; l < size; ++l) {
00498                         for (m = 0; m < size; ++m) {
00499                             // Draws the pixel at color
00500                             setPixel(x + m, y + k * size + l, color);
00501                         }
00502                     }
00503                 } else {
00504                     if (!transparency) {
00505                         for (l = 0; l < size; ++l) {
00506                             for (m = 0; m < size; ++m) {
00507                                 // Draws the pixel at ~color
00508                                 setPixel(x + m, y + k * size + l, !color);
00509                             }
00510                         }
00511                     }
00512                 }
00513             }
00514         }
00515         // Clean gap between two caracters
00516         if (!transparency) {
00517             for (k = 0; k < h * size; ++k) {
00518                 // Draws the pixel at ~color
00519                 setPixel(x, y + k, !color);
00520             }
00521         }
00522     }
00523     return x + m; // last x position
00524 }