Stefan Staub / EADOG

Dependencies:   Fonts

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers EADOG.cpp Source File

EADOG.cpp

00001 /* mbed library for the mbed Lab Board  128*32 pixel LCD
00002  * use ST7565R controller
00003  * Copyright (c) 2016 Stefan Staub
00004  * Released under the MIT License: http://mbed.org/license/mit
00005  *
00006  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00007  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00008  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00009  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00010  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00011  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00012  * THE SOFTWARE.
00013  */
00014 
00015 #include "EADOG.h"
00016 #include "mbed.h"
00017 #include "stdio.h"
00018 #include "Small_7.h"
00019 
00020 EADOG::EADOG(PinName mosi, PinName sck, PinName reset, PinName a0, PinName cs, uint8_t type) : _spi(mosi, NC, sck), _reset(reset), _a0(a0), _cs(cs), _type(type), graphic_buffer() {
00021   if (_type == DOGM132) {
00022     width = 132;
00023     height = 32;
00024     graphic_buffer_size = 528;
00025     graphic_buffer = new uint8_t [graphic_buffer_size];
00026     }
00027 
00028   if (_type == DOGM128 || _type == DOGL128) {
00029     width = 128;
00030     height = 64;
00031     graphic_buffer_size = 1024;
00032     graphic_buffer = new uint8_t [graphic_buffer_size];
00033     }
00034     init();
00035   }
00036 
00037 static void inline swap(int &a, int &b) {
00038   int c = a;
00039   a = b;
00040   b = c;
00041   }
00042 
00043 void EADOG::display(uint8_t display) {
00044   if (display == ON) { // display on
00045     write_command(0xA4);
00046     write_command(0xAF);
00047     }
00048   if (display == OFF) { // display off
00049     write_command(0xAE);
00050     }
00051 
00052   if (display == SLEEP) {// display sleep
00053     write_command(0xA5);
00054     write_command(0xAE);
00055     }
00056   if(display == INVERT) { // invert display
00057     write_command(0xA7);
00058     }
00059   if(display == DEFAULT) { // set to normal display
00060     write_command(0xA6);
00061     }
00062   if (display == TOPVIEW) { // reverse orientation
00063     write_command(0xA0); // ADC normal
00064     write_command(0xC8); // reversed com31-com0
00065     update(); // update necessary
00066       }
00067   if (display == BOTTOM) { // normal orientation
00068     write_command(0xA1); // ADC reverse
00069     write_command(0xC0); // normal com0-com31
00070     update(); // update necessary
00071     }
00072   if (display == CONTRAST) {
00073     if (_type == DOGM132) {
00074       write_command(0x81); //  set contrast to default for dogm 128
00075       write_command(0x1F);
00076       }
00077     if (_type == DOGM128) {
00078       write_command(0x81); //  set contrast to default for dogm132
00079       write_command(0x16);
00080       }
00081     if (_type == DOGL128) {
00082       write_command(0x81); //  set contrast to default for dogl132
00083       write_command(0x10);
00084       }
00085     }
00086   }
00087 
00088 void EADOG::display(uint8_t display, uint8_t value) {
00089   if (display == CONTRAST) {
00090     if (value < 64) {
00091       write_command(0x81); //  set contrast
00092       write_command(value & 0x3F);
00093       }
00094     }
00095   }
00096 
00097 // write command to lcd controller
00098 void EADOG::write_command(uint8_t command) {
00099   _a0 = 0;
00100   _cs = 0;
00101   _spi.write(command);
00102   _cs = 1;
00103   }
00104 
00105 // write data to lcd controller
00106 void EADOG::write_data(uint8_t data) {
00107   _a0 = 1;
00108   _cs = 0;
00109   _spi.write(data);
00110   _cs = 1;
00111   }
00112 
00113 // reset and init the lcd controller
00114 void EADOG::init() {
00115   _spi.format(8, 3);                 // 8 bit spi mode 3
00116   _spi.frequency(20000000);          // 19,2 Mhz SPI clock
00117 
00118   //DigitalOut _reset(A1);
00119   _a0 = 0;
00120   _cs = 1;
00121   _reset = 0;                        // display reset
00122   wait_us(50);
00123   _reset = 1;                       // end reset
00124   wait_ms(5);
00125 
00126   // Start Initial Sequence
00127   write_command(0x40); // display start line 0
00128   write_command(0xA1); // ADC reverse
00129   write_command(0xC0); // normal com0-com31
00130   write_command(0xA6); // display normal
00131   write_command(0xA2); // set bias 1/9 (duty 1/33)
00132   write_command(0x2F); // booster, regulator and follower on
00133   write_command(0xF8); // set internal booster to 3x/4x
00134   write_command(0x00);
00135   if (_type == DOGM132) {
00136     write_command(0x23); //  set contrast
00137     write_command(0x81);
00138     write_command(0x1F);
00139     }
00140   if (_type == DOGM128) {
00141     write_command(0x27); //  set contrast
00142     write_command(0x81);
00143     write_command(0x16);
00144     }
00145   if (_type == DOGL128) {
00146     write_command(0x27); //  set contrast
00147     write_command(0x81);
00148     write_command(0x10);
00149     }
00150   write_command(0xAC); // no indicator
00151   write_command(0x00);
00152   write_command(0xAF); // display on
00153 
00154   // clear and update LCD
00155   cls();
00156   auto_update = 1;              // switch on auto update
00157   locate(0, 0);
00158   font((unsigned char*)Small_7);  // standard font
00159   }
00160 
00161 // update lcd
00162 void EADOG::update() {
00163   //page 0
00164   write_command(0x00);      // set column low nibble 0
00165   write_command(0x10);      // set column hi  nibble 0
00166   write_command(0xB0);      // set page address  0
00167   _a0 = 1;
00168 
00169   for (int i = 0; i < width; i++) {
00170     write_data(graphic_buffer[i]);
00171     }
00172 
00173   // page 1
00174   write_command(0x00);      // set column low nibble 0
00175   write_command(0x10);      // set column hi  nibble 0
00176   write_command(0xB1);      // set page address  1
00177   _a0 = 1;
00178 
00179   for (int i = width; i < width * 2; i++) {
00180     write_data(graphic_buffer[i]);
00181     }
00182 
00183   //page 2
00184   write_command(0x00);      // set column low nibble 0
00185   write_command(0x10);      // set column hi  nibble 0
00186   write_command(0xB2);      // set page address  2
00187   _a0 = 1;
00188 
00189   for (int i = width * 2; i < width * 3; i++) {
00190     write_data(graphic_buffer[i]);
00191     }
00192 
00193   //page 3
00194   write_command(0x00);      // set column low nibble 0
00195   write_command(0x10);      // set column hi  nibble 0
00196   write_command(0xB3);      // set page address  3
00197   _a0 = 1;
00198 
00199   for (int i = width * 3; i < width * 4; i++) {
00200     write_data(graphic_buffer[i]);
00201     }
00202 
00203   if (_type == DOGM128 || _type == DOGL128) {
00204     //page 4
00205     write_command(0x00);      // set column low nibble 0
00206     write_command(0x10);      // set column hi  nibble 0
00207     write_command(0xB4);      // set page address  3
00208     _a0 = 1;
00209 
00210     for (int i = width * 4; i < width * 5; i++) {
00211       write_data(graphic_buffer[i]);
00212       }
00213 
00214     //page 5
00215     write_command(0x00);      // set column low nibble 0
00216     write_command(0x10);      // set column hi  nibble 0
00217     write_command(0xB5);      // set page address  3
00218     _a0 = 1;
00219 
00220     for (int i = width * 5; i < width * 6; i++) {
00221       write_data(graphic_buffer[i]);
00222       }
00223 
00224     //page 6
00225     write_command(0x00);      // set column low nibble 0
00226     write_command(0x10);      // set column hi  nibble 0
00227     write_command(0xB6);      // set page address  3
00228     _a0 = 1;
00229 
00230     for (int i = width * 6; i < width *7; i++) {
00231       write_data(graphic_buffer[i]);
00232       }
00233 
00234     //page 7
00235     write_command(0x00);      // set column low nibble 0
00236     write_command(0x10);      // set column hi  nibble 0
00237     write_command(0xB7);      // set page address  3
00238     _a0 = 1;
00239 
00240     for (int i = width * 7; i < width *8; i++) {
00241       write_data(graphic_buffer[i]);
00242       }
00243     }
00244 
00245   _cs = 0;
00246 
00247   }
00248 void EADOG::update(uint8_t mode) {
00249   if (mode == MANUAL) auto_update = 0;
00250   if (mode == AUTO) auto_update = 1;
00251   }
00252 
00253 // clear screen
00254 void EADOG::cls() {
00255   memset(graphic_buffer, 0x00, graphic_buffer_size);  // clear display graphic_buffer
00256   update();
00257   }
00258 
00259 // set one pixel in graphic_buffer
00260 void EADOG::pixel(int x, int y, uint8_t color) {
00261   if (x > width - 1 || y > height - 1 || x < 0 || y < 0) return;
00262   if (color == 0) graphic_buffer[x + ((y / 8) * width)] &= ~(1 << (y % 8)); // erase pixel
00263   else graphic_buffer[x + ((y / 8) * width)] |= (1 << (y % 8));   // set pixel
00264   }
00265 
00266 void EADOG::point(int x, int y, uint8_t colour) {
00267   pixel(x, y, colour);
00268   if (auto_update) update();
00269   }
00270 
00271 // This function uses Bresenham's algorithm to draw a straight line.
00272 void EADOG::line(int x0, int y0, int x1, int y1, uint8_t colour) {
00273   int dx =  abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
00274   int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
00275   int err = dx + dy, e2; /* error value e_xy */
00276 
00277   while(1) {
00278     pixel(x0, y0, 1);
00279     if (x0 == x1 && y0 == y1) break;
00280     e2 = 2 * err;
00281     if (e2 > dy) { err += dy; x0 += sx; } /* e_xy+e_x > 0 */
00282     if (e2 < dx) { err += dx; y0 += sy; } /* e_xy+e_y < 0 */
00283     }
00284   if (auto_update) update();
00285   }
00286 
00287 void EADOG::rectangle(int x0, int y0, int x1, int y1, uint8_t colour) {
00288   uint8_t upd = auto_update;
00289   auto_update = 0;
00290   line(x0, y0, x1, y0, colour);
00291   line(x0, y1, x1, y1, colour);
00292   line(x0, y0, x0, y1, colour);
00293   line(x1, y0, x1, y1, colour);
00294   auto_update = upd;
00295   if (auto_update) update();
00296   }
00297 
00298 void EADOG::fillrect(int x0, int y0, int x1, int y1, uint8_t colour) {
00299   if (x0 > x1) swap(x0, x1);
00300   if (y0 > y1) swap(y0, y1);
00301   for (int i = x0; i <= x1; i++) {
00302     for (int j = y0; j <= y1; j++) {
00303       pixel(i, j, colour);
00304       }
00305     }
00306   if (auto_update) update();
00307   }
00308 
00309 void EADOG::roundrect(int x0, int y0, int x1, int y1, int rnd, uint8_t colour) {
00310   if (x0 > x1) swap(x0, x1);
00311   if (y0 > y1) swap(y0, y1);
00312   uint8_t upd = auto_update;
00313   auto_update = 0;
00314   int r = rnd;
00315   int x = -r, y = 0, err = 2 - 2 * r;
00316   line(x0 + rnd, y0, x1 - rnd, y0, colour);
00317   line(x0 + rnd, y1, x1 - rnd, y1, colour);
00318   line(x0, y0 + rnd, x0, y1 - rnd, colour);
00319   line(x1, y0 + rnd, x1, y1 - rnd, colour);
00320   do {
00321     pixel(x1 - rnd + y, y0 + x + rnd, 1); // 1 I. quadrant
00322     pixel(x1 - rnd - x, y1 + y - rnd, 1); // 2 IV. quadrant
00323     pixel(x0 + rnd - y, y1 - rnd - x, 1); // 3 III. quadrant
00324     pixel(x0 + rnd + x, y0 + rnd - y, 1); // 4 II. quadrant
00325     r = err;
00326     if (r <= y) err += ++y * 2 + 1;
00327     if (r > x || err > y) err += ++x * 2 + 1;
00328     } while (x < 0);
00329   auto_update = upd;
00330   if (auto_update) update();
00331   }
00332 
00333 void EADOG::fillrrect(int x0, int y0, int x1, int y1, int rnd, uint8_t colour) {
00334   if (x0 > x1) swap(x0, x1);
00335   if (y0 > y1) swap(y0, y1);
00336   uint8_t upd = auto_update;
00337   auto_update = 0;
00338   int r = rnd;
00339   int x = -r, y = 0, err = 2 - 2 * r;
00340   for (int i = x0; i <= x1; i++) {
00341     for (int j = y0+rnd; j <= y1-rnd; j++) {
00342       pixel(i, j, colour);
00343       }
00344     }
00345   do {
00346     line(x0 + rnd - y, y0 + rnd + x, x1 - rnd + y, y0 + rnd + x, 1);
00347     line(x0 + rnd + x, y1 - rnd + y, x1 - rnd - x, y1 - rnd + y, 1);
00348     r = err;
00349     if (r <= y) err += ++y * 2 + 1;
00350     if (r > x || err > y) err += ++x * 2 + 1;
00351     } while (x < 0);
00352   auto_update = upd;
00353   if (auto_update) update();
00354   }
00355 
00356 void EADOG::circle(int x0, int y0, int r, uint8_t colour) {
00357   int x = -r, y = 0, err = 2 - 2 * r;
00358   do {
00359     pixel(x0 + y, y0 + x, 1); // 1 I. quadrant
00360     pixel(x0 - x, y0 + y, 1); // 2 IV. quadrant
00361     pixel(x0 - y, y0 - x, 1); // 3 III. quadrant
00362     pixel(x0 + x, y0 - y, 1); // 4 II. quadrant
00363     r = err;
00364     if (r <= y) err += ++y * 2 + 1;
00365     if (r > x || err > y) err += ++x * 2 + 1;
00366     } while (x < 0);
00367   if (auto_update) update();
00368   }
00369 
00370 void EADOG::fillcircle(int x0, int y0, int r, uint8_t colour) {
00371   uint8_t upd;
00372   upd = auto_update;
00373   auto_update = 0;
00374   int x = -r, y = 0, err = 2 - 2 * r;
00375   do {
00376     line(x0 - y, y0 + x, x0 + y, y0 + x, 1);
00377     line(x0 + x, y0 + y, x0 - x, y0 + y, 1);
00378     r = err;
00379     if (r <= y) err += ++y * 2 + 1;
00380     if (r > x || err > y) err += ++x * 2 + 1;
00381     } while (x < 0);
00382   auto_update = upd;
00383   if (auto_update) update();
00384   }
00385 
00386 void EADOG::locate(uint8_t x, uint8_t y) {
00387   char_x = x;
00388   char_y = y;
00389   }
00390 
00391 int EADOG::_putc(int value) {
00392   if (value == '\n') {    // new line
00393     char_x = 0;
00394     char_y = char_y + font_buffer[2];
00395     if (char_y >= height - font_buffer[2]) {
00396       char_y = 0;
00397       }
00398     }
00399   else {
00400     character(char_x, char_y, value);
00401     if (auto_update) update();
00402     }
00403   return value;
00404   }
00405 
00406 int EADOG::_getc() {
00407       return -1;
00408   }
00409 
00410 void EADOG::character(uint8_t x, uint8_t y, uint8_t c) {
00411   unsigned int hor, vert, offset, bpl, b;
00412   uint8_t *sign;
00413   uint8_t z, w;
00414 
00415   if ((c < 31) || (c > 127)) return;   // test char range
00416 
00417   // read font parameter from start of array
00418   offset = font_buffer[0];                    // bytes / char
00419   hor = font_buffer[1];                       // get hor size of font
00420   vert = font_buffer[2];                      // get vert size of font
00421   bpl = font_buffer[3];                       // bytes per line
00422 
00423   if (char_x + hor > width) {
00424     char_x = 0;
00425     char_y = char_y + vert;
00426     if (char_y >= height - font_buffer[2]) {
00427       char_y = 0;
00428       }
00429     }
00430 
00431   sign = &font_buffer[((c - 32) * offset) + 4]; // start of char bitmap
00432   w = sign[0];                          // width of actual char
00433   // construct the char into the font_graphic_buffer
00434   for (unsigned int j = 0; j < vert; j++) {  //  vert line
00435     for (unsigned int i = 0; i < hor; i++) {   //  horz line
00436       z =  sign[bpl * i + ((j & 0xF8) >> 3) + 1];
00437       b = 1 << (j & 0x07);
00438       if (( z & b ) == 0x00) {
00439         pixel(x+i, y+j, 0);
00440         }
00441       else {
00442         pixel(x+i, y+j, 1);
00443         }
00444       }
00445     }
00446   char_x += w;
00447   }
00448 
00449 
00450 void EADOG::font(uint8_t *f) {
00451   font_buffer = f;
00452   }
00453 
00454 void EADOG::bitmap(Bitmap bm, int x, int y) {
00455   int b;
00456   char d;
00457 
00458   for (int v = 0; v < bm.ySize; v++) {   // lines
00459     for (int h = 0; h < bm.xSize; h++) { // pixel
00460       if (h + x >= width) break;
00461       if (v + y >= height) break;
00462       d = bm.data[bm.byte_in_Line * v + ((h & 0xF8) >> 3)];
00463       b = 0x80 >> (h & 0x07);
00464       if ((d & b) == 0) {
00465         pixel(x+h, y+v, 0);
00466         }
00467       else {
00468         pixel(x+h, y+v, 1);
00469         }
00470       }
00471     }
00472     if (auto_update) update();
00473   }