for alanteam

Dependents:   termometro

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers C12832.cpp Source File

C12832.cpp

00001 /* mbed library for the mbed Lab Board  128*32 pixel LCD
00002  * use C12832 controller
00003  * Copyright (c) 2012 Peter Drescher - DC2PD
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 // 13.10.12    initial design
00016 // 25.10.12    add autorefresh of screen
00017 // 25.10.12    add standart font
00018 // 20.12.12    add bitmap graphics
00019 
00020 // optional defines :
00021 // #define debug_lcd  1
00022 
00023 #include "C12832.h"
00024 #include "mbed.h"
00025 #include "stdio.h"
00026 #include "Small_7.h"
00027 
00028 #define BPP    1       // Bits per pixel
00029 
00030 //C12832 lcd(D11, D13, D12, D7, D10);
00031 
00032 C12832::C12832(PinName mosi, PinName sck, PinName reset, PinName a0, PinName ncs, const char* name)
00033     : _spi(mosi,NC,sck),_reset(reset),_A0(a0),_CS(ncs),GraphicsDisplay(name)
00034 {
00035     orientation = 1;
00036     draw_mode = NORMAL;
00037     char_x = 0;
00038     lcd_reset();
00039 }
00040 
00041 
00042 int C12832::width()
00043 {
00044     if (orientation == 0 || orientation == 2) return 32;
00045     else return 128;
00046 }
00047 
00048 int C12832::height()
00049 {
00050     if (orientation == 0 || orientation == 2) return 128;
00051     else return 32;
00052 }
00053 
00054 
00055 void C12832::invert(unsigned int o)
00056 {
00057     if(o == 0) wr_cmd(0xA6);
00058     else wr_cmd(0xA7);
00059 }
00060 
00061 
00062 void C12832::set_contrast(unsigned int o)
00063 {
00064     contrast = o;
00065     wr_cmd(0x81);      //  set volume
00066     wr_cmd(o & 0x3F);
00067 }
00068 
00069 unsigned int C12832::get_contrast(void)
00070 {
00071     return(contrast);
00072 }
00073 
00074 
00075 // write command to lcd controller
00076 
00077 void C12832::wr_cmd(unsigned char cmd)
00078 {
00079     _A0 = 0;
00080     _CS = 0;
00081     _spi.write(cmd);
00082     _CS = 1;
00083 }
00084 
00085 // write data to lcd controller
00086 
00087 void C12832::wr_dat(unsigned char dat)
00088 {
00089     _A0 = 1;
00090     _CS = 0;
00091     _spi.write(dat);
00092     _CS = 1;
00093 }
00094 
00095 // reset and init the lcd controller
00096 
00097 void C12832::lcd_reset()
00098 {
00099 
00100     _spi.format(8,3);                 // 8 bit spi mode 3
00101     _spi.frequency(20000000);          // 19,2 Mhz SPI clock
00102     _A0 = 0;
00103     _CS = 1;
00104     _reset = 0;                        // display reset
00105     wait_us(50);
00106     _reset = 1;                       // end reset
00107     wait_ms(5);
00108 
00109     /* Start Initial Sequence ----------------------------------------------------*/
00110 
00111     wr_cmd(0xAE);   //  display off
00112     wr_cmd(0xA2);   //  bias voltage
00113 
00114     wr_cmd(0xA0);
00115     wr_cmd(0xC8);   //  colum normal
00116 
00117     wr_cmd(0x22);   //  voltage resistor ratio
00118     wr_cmd(0x2F);   //  power on
00119     //wr_cmd(0xA4);   //  LCD display ram
00120     wr_cmd(0x40);   // start line = 0
00121     wr_cmd(0xAF);     // display ON
00122 
00123     wr_cmd(0x81);   //  set contrast
00124     wr_cmd(0x17);   //  set contrast
00125 
00126     wr_cmd(0xA6);     // display normal
00127 
00128 
00129     // clear and update LCD
00130     memset(buffer,0x00,512);  // clear display buffer
00131     copy_to_lcd();
00132     auto_up = 1;              // switch on auto update
00133     // dont do this by default. Make the user call
00134     //claim(stdout);           // redirekt printf to lcd
00135     locate(0,0);
00136     set_font((unsigned char*)Small_7);  // standart font
00137 }
00138 
00139 // set one pixel in buffer
00140 
00141 void C12832::pixel(int x, int y, int color)
00142 {
00143     // first check parameter
00144     if(x > 128 || y > 32 || x < 0 || y < 0) return;
00145 
00146     if(draw_mode == NORMAL) {
00147         if(color == 0)
00148             buffer[x + ((y/8) * 128)] &= ~(1 << (y%8));  // erase pixel
00149         else
00150             buffer[x + ((y/8) * 128)] |= (1 << (y%8));   // set pixel
00151     } else { // XOR mode
00152         if(color == 1)
00153             buffer[x + ((y/8) * 128)] ^= (1 << (y%8));   // xor pixel
00154     }
00155 }
00156 
00157 // update lcd
00158 
00159 void C12832::copy_to_lcd(void)
00160 {
00161     
00162     int i=0;
00163     
00164     //page 0
00165     wr_cmd(0x00);      // set column low nibble 0
00166     wr_cmd(0x10);      // set column hi  nibble 0
00167     wr_cmd(0xB0);      // set page address  0
00168     _A0 = 1;
00169     for(i=0; i<128; i++) {
00170         wr_dat(buffer[i]);
00171     }
00172 
00173     // page 1
00174     wr_cmd(0x00);      // set column low nibble 0
00175     wr_cmd(0x10);      // set column hi  nibble 0
00176     wr_cmd(0xB1);      // set page address  1
00177     _A0 = 1;
00178     for(i=128; i<256; i++) {
00179         wr_dat(buffer[i]);
00180     }
00181 
00182     //page 2
00183     wr_cmd(0x00);      // set column low nibble 0
00184     wr_cmd(0x10);      // set column hi  nibble 0
00185     wr_cmd(0xB2);      // set page address  2
00186     _A0 = 1;
00187     for(i=256; i<384; i++) {
00188         wr_dat(buffer[i]);
00189     }
00190 
00191     //page 3
00192     wr_cmd(0x00);      // set column low nibble 0
00193     wr_cmd(0x10);      // set column hi  nibble 0
00194     wr_cmd(0xB3);      // set page address  3
00195     _A0 = 1;
00196 
00197     _CS = 0;
00198     
00199     for(i=384; i<512; i++) {
00200         wr_dat(buffer[i]);
00201     }
00202 
00203 }
00204 
00205 void C12832::cls(void)
00206 {
00207     memset(buffer,0x00,512);  // clear display buffer
00208     copy_to_lcd();
00209 }
00210 
00211 
00212 void C12832::line(int x0, int y0, int x1, int y1, int color)
00213 {
00214     int   dx = 0, dy = 0;
00215     int   dx_sym = 0, dy_sym = 0;
00216     int   dx_x2 = 0, dy_x2 = 0;
00217     int   di = 0;
00218 
00219     dx = x1-x0;
00220     dy = y1-y0;
00221 
00222     //  if (dx == 0) {        /* vertical line */
00223     //      if (y1 > y0) vline(x0,y0,y1,color);
00224     //      else vline(x0,y1,y0,color);
00225     //      return;
00226     //  }
00227 
00228     if (dx > 0) {
00229         dx_sym = 1;
00230     } else {
00231         dx_sym = -1;
00232     }
00233     //  if (dy == 0) {        /* horizontal line */
00234     //      if (x1 > x0) hline(x0,x1,y0,color);
00235     //      else  hline(x1,x0,y0,color);
00236     //      return;
00237     //  }
00238 
00239     if (dy > 0) {
00240         dy_sym = 1;
00241     } else {
00242         dy_sym = -1;
00243     }
00244 
00245     dx = dx_sym*dx;
00246     dy = dy_sym*dy;
00247 
00248     dx_x2 = dx*2;
00249     dy_x2 = dy*2;
00250 
00251     if (dx >= dy) {
00252         di = dy_x2 - dx;
00253         while (x0 != x1) {
00254 
00255             pixel(x0, y0, color);
00256             x0 += dx_sym;
00257             if (di<0) {
00258                 di += dy_x2;
00259             } else {
00260                 di += dy_x2 - dx_x2;
00261                 y0 += dy_sym;
00262             }
00263         }
00264         pixel(x0, y0, color);
00265     } else {
00266         di = dx_x2 - dy;
00267         while (y0 != y1) {
00268             pixel(x0, y0, color);
00269             y0 += dy_sym;
00270             if (di < 0) {
00271                 di += dx_x2;
00272             } else {
00273                 di += dx_x2 - dy_x2;
00274                 x0 += dx_sym;
00275             }
00276         }
00277         pixel(x0, y0, color);
00278     }
00279     if(auto_up) copy_to_lcd();
00280 }
00281 
00282 void C12832::rect(int x0, int y0, int x1, int y1, int color)
00283 {
00284 
00285     if (x1 > x0) line(x0,y0,x1,y0,color);
00286     else  line(x1,y0,x0,y0,color);
00287 
00288     if (y1 > y0) line(x0,y0,x0,y1,color);
00289     else line(x0,y1,x0,y0,color);
00290 
00291     if (x1 > x0) line(x0,y1,x1,y1,color);
00292     else  line(x1,y1,x0,y1,color);
00293 
00294     if (y1 > y0) line(x1,y0,x1,y1,color);
00295     else line(x1,y1,x1,y0,color);
00296 
00297     if(auto_up) copy_to_lcd();
00298 }
00299 
00300 void C12832::fillrect(int x0, int y0, int x1, int y1, int color)
00301 {
00302     int l,c,i;
00303     if(x0 > x1) {
00304         i = x0;
00305         x0 = x1;
00306         x1 = i;
00307     }
00308 
00309     if(y0 > y1) {
00310         i = y0;
00311         y0 = y1;
00312         y1 = i;
00313     }
00314 
00315     for(l = x0; l<= x1; l ++) {
00316         for(c = y0; c<= y1; c++) {
00317             pixel(l,c,color);
00318         }
00319     }
00320     if(auto_up) copy_to_lcd();
00321 }
00322 
00323 
00324 
00325 void C12832::circle(int x0, int y0, int r, int color)
00326 {
00327 
00328     int draw_x0, draw_y0;
00329     int draw_x1, draw_y1;
00330     int draw_x2, draw_y2;
00331     int draw_x3, draw_y3;
00332     int draw_x4, draw_y4;
00333     int draw_x5, draw_y5;
00334     int draw_x6, draw_y6;
00335     int draw_x7, draw_y7;
00336     int xx, yy;
00337     int di;
00338     //WindowMax();
00339     if (r == 0) {       /* no radius */
00340         return;
00341     }
00342 
00343     draw_x0 = draw_x1 = x0;
00344     draw_y0 = draw_y1 = y0 + r;
00345     if (draw_y0 < height()) {
00346         pixel(draw_x0, draw_y0, color);     /* 90 degree */
00347     }
00348 
00349     draw_x2 = draw_x3 = x0;
00350     draw_y2 = draw_y3 = y0 - r;
00351     if (draw_y2 >= 0) {
00352         pixel(draw_x2, draw_y2, color);    /* 270 degree */
00353     }
00354 
00355     draw_x4 = draw_x6 = x0 + r;
00356     draw_y4 = draw_y6 = y0;
00357     if (draw_x4 < width()) {
00358         pixel(draw_x4, draw_y4, color);     /* 0 degree */
00359     }
00360 
00361     draw_x5 = draw_x7 = x0 - r;
00362     draw_y5 = draw_y7 = y0;
00363     if (draw_x5>=0) {
00364         pixel(draw_x5, draw_y5, color);     /* 180 degree */
00365     }
00366 
00367     if (r == 1) {
00368         return;
00369     }
00370 
00371     di = 3 - 2*r;
00372     xx = 0;
00373     yy = r;
00374     while (xx < yy) {
00375 
00376         if (di < 0) {
00377             di += 4*xx + 6;
00378         } else {
00379             di += 4*(xx - yy) + 10;
00380             yy--;
00381             draw_y0--;
00382             draw_y1--;
00383             draw_y2++;
00384             draw_y3++;
00385             draw_x4--;
00386             draw_x5++;
00387             draw_x6--;
00388             draw_x7++;
00389         }
00390         xx++;
00391         draw_x0++;
00392         draw_x1--;
00393         draw_x2++;
00394         draw_x3--;
00395         draw_y4++;
00396         draw_y5++;
00397         draw_y6--;
00398         draw_y7--;
00399 
00400         if ( (draw_x0 <= width()) && (draw_y0>=0) ) {
00401             pixel(draw_x0, draw_y0, color);
00402         }
00403 
00404         if ( (draw_x1 >= 0) && (draw_y1 >= 0) ) {
00405             pixel(draw_x1, draw_y1, color);
00406         }
00407 
00408         if ( (draw_x2 <= width()) && (draw_y2 <= height()) ) {
00409             pixel(draw_x2, draw_y2, color);
00410         }
00411 
00412         if ( (draw_x3 >=0 ) && (draw_y3 <= height()) ) {
00413             pixel(draw_x3, draw_y3, color);
00414         }
00415 
00416         if ( (draw_x4 <= width()) && (draw_y4 >= 0) ) {
00417             pixel(draw_x4, draw_y4, color);
00418         }
00419 
00420         if ( (draw_x5 >= 0) && (draw_y5 >= 0) ) {
00421             pixel(draw_x5, draw_y5, color);
00422         }
00423         if ( (draw_x6 <=width()) && (draw_y6 <= height()) ) {
00424             pixel(draw_x6, draw_y6, color);
00425         }
00426         if ( (draw_x7 >= 0) && (draw_y7 <= height()) ) {
00427             pixel(draw_x7, draw_y7, color);
00428         }
00429     }
00430     if(auto_up) copy_to_lcd();
00431 }
00432 
00433 void C12832::fillcircle(int x, int y, int r, int color)
00434 {
00435     int i,up;
00436     up = auto_up;
00437     auto_up = 0;   // off
00438     for (i = 0; i <= r; i++)
00439         circle(x,y,i,color);
00440     auto_up = up;
00441     if(auto_up) copy_to_lcd();
00442 }
00443 
00444 void C12832::setmode(int mode)
00445 {
00446     draw_mode = mode;
00447 }
00448 
00449 void C12832::locate(int x, int y)
00450 {
00451     char_x = x;
00452     char_y = y;
00453 }
00454 
00455 
00456 
00457 int C12832::columns()
00458 {
00459     return width() / font[1];
00460 }
00461 
00462 
00463 
00464 int C12832::rows()
00465 {
00466     return height() / font[2];
00467 }
00468 
00469 
00470 
00471 int C12832::_putc(int value)
00472 {
00473     if (value == '\n') {    // new line
00474         char_x = 0;
00475         char_y = char_y + font[2];
00476         if (char_y >= height() - font[2]) {
00477             char_y = 0;
00478         }
00479     } else {
00480         character(char_x, char_y, value);
00481         if(auto_up) copy_to_lcd();
00482     }
00483     return value;
00484 }
00485 
00486 void C12832::character(int x, int y, int c)
00487 {
00488     unsigned int hor,vert,offset,bpl,j,i,b;
00489     unsigned char* zeichen;
00490     unsigned char z,w;
00491 
00492     if ((c < 31) || (c > 127)) return;   // test char range
00493 
00494     // read font parameter from start of array
00495     offset = font[0];                    // bytes / char
00496     hor = font[1];                       // get hor size of font
00497     vert = font[2];                      // get vert size of font
00498     bpl = font[3];                       // bytes per line
00499 
00500     if (char_x + hor > width()) {
00501         char_x = 0;
00502         char_y = char_y + vert;
00503         if (char_y >= height() - font[2]) {
00504             char_y = 0;
00505         }
00506     }
00507 
00508     zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap
00509     w = zeichen[0];                          // width of actual char
00510     // construct the char into the buffer
00511     for (j=0; j<vert; j++) {  //  vert line
00512         for (i=0; i<hor; i++) {   //  horz line
00513             z =  zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
00514             b = 1 << (j & 0x07);
00515             if (( z & b ) == 0x00) {
00516                 pixel(x+i,y+j,0);
00517             } else {
00518                 pixel(x+i,y+j,1);
00519             }
00520 
00521         }
00522     }
00523 
00524     char_x += w;
00525 }
00526 
00527 
00528 void C12832::set_font(unsigned char* f)
00529 {
00530     font = f;
00531 }
00532 
00533 void C12832::set_auto_up(unsigned int up)
00534 {
00535     if(up ) auto_up = 1;
00536     else auto_up = 0;
00537 }
00538 
00539 unsigned int C12832::get_auto_up(void)
00540 {
00541     return (auto_up);
00542 }
00543 
00544 void C12832::print_bm(Bitmap bm, int x, int y)
00545 {
00546     int h,v,b;
00547     char d;
00548 
00549     for(v=0; v < bm.ySize; v++) {   // lines
00550         for(h=0; h < bm.xSize; h++) { // pixel
00551             if(h + x > 127) break;
00552             if(v + y > 31) break;
00553             d = bm.data[bm.Byte_in_Line * v + ((h & 0xF8) >> 3)];
00554             b = 0x80 >> (h & 0x07);
00555             if((d & b) == 0) {
00556                 pixel(x+h,y+v,0);
00557             } else {
00558                 pixel(x+h,y+v,1);
00559             }
00560         }
00561     }
00562 
00563 }
00564 
00565