A fork of dreschpe library with pin names added to the constructor
Fork of C12832_lcd by
C12832_lcd.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_lcd.h" 00024 #include "mbed.h" 00025 #include "stdio.h" 00026 #include "Small_7.h" 00027 00028 #define BPP 1 // Bits per pixel 00029 00030 00031 C12832_LCD::C12832_LCD(PinName mosi, PinName sck, PinName reset, PinName a0, PinName ncs, const char* name) 00032 : _spi(mosi,NC,sck),_reset(reset),_A0(a0),_CS(ncs),GraphicsDisplay(name) 00033 { 00034 orientation = 1; 00035 draw_mode = NORMAL; 00036 char_x = 0; 00037 lcd_reset(); 00038 } 00039 00040 00041 int C12832_LCD::width() 00042 { 00043 if (orientation == 0 || orientation == 2) return 32; 00044 else return 128; 00045 } 00046 00047 int C12832_LCD::height() 00048 { 00049 if (orientation == 0 || orientation == 2) return 128; 00050 else return 32; 00051 } 00052 00053 00054 /*void C12832_LCD::set_orientation(unsigned int o) 00055 { 00056 orientation = o; 00057 switch (o) { 00058 case (0): 00059 wr_cmd(0xA0); 00060 wr_cmd(0xC0); 00061 break; 00062 case (1): 00063 wr_cmd(0xA0); 00064 wr_cmd(0xC8); 00065 break; 00066 case (2): 00067 wr_cmd(0xA1); 00068 wr_cmd(0xC8); 00069 break; 00070 case (3): 00071 wr_cmd(0xA1); 00072 wr_cmd(0xC0); 00073 break; 00074 } 00075 } 00076 00077 */ 00078 00079 void C12832_LCD::invert(unsigned int o) 00080 { 00081 if(o == 0) wr_cmd(0xA6); 00082 else wr_cmd(0xA7); 00083 } 00084 00085 00086 void C12832_LCD::set_contrast(unsigned int o) 00087 { 00088 contrast = o; 00089 wr_cmd(0x81); // set volume 00090 wr_cmd(o & 0x3F); 00091 } 00092 00093 unsigned int C12832_LCD::get_contrast(void) 00094 { 00095 return(contrast); 00096 } 00097 00098 00099 // write command to lcd controller 00100 00101 void C12832_LCD::wr_cmd(unsigned char cmd) 00102 { 00103 _A0 = 0; 00104 _CS = 0; 00105 #if defined TARGET_LPC1768 // fast without mbed lib 00106 LPC_SSP1->DR = cmd; 00107 do { 00108 } while ((LPC_SSP1->SR & 0x10) == 0x10); // wait for SPI1 idle 00109 #else 00110 _spi.write(cmd); 00111 #endif 00112 _CS = 1; 00113 } 00114 00115 // write data to lcd controller 00116 00117 void C12832_LCD::wr_dat(unsigned char dat) 00118 { 00119 _A0 = 1; 00120 _CS = 0; 00121 #if defined TARGET_LPC1768 // fast without mbed lib 00122 LPC_SSP1->DR = dat; 00123 do { 00124 } while ((LPC_SSP1->SR & 0x10) == 0x10); // wait for SPI1 idle 00125 #else 00126 _spi.write(dat); 00127 #endif 00128 _CS = 1; 00129 } 00130 00131 // reset and init the lcd controller 00132 00133 void C12832_LCD::lcd_reset() 00134 { 00135 00136 _spi.format(8,3); // 8 bit spi mode 3 00137 _spi.frequency(20000000); // 19,2 Mhz SPI clock 00138 // DigitalOut _reset(p6); 00139 _A0 = 0; 00140 _CS = 1; 00141 _reset = 0; // display reset 00142 wait_us(50); 00143 _reset = 1; // end reset 00144 wait_ms(5); 00145 00146 /* Start Initial Sequence ----------------------------------------------------*/ 00147 00148 wr_cmd(0xAE); // display off 00149 wr_cmd(0xA2); // bias voltage 00150 00151 wr_cmd(0xA0); 00152 wr_cmd(0xC8); // colum normal 00153 00154 wr_cmd(0x22); // voltage resistor ratio 00155 wr_cmd(0x2F); // power on 00156 //wr_cmd(0xA4); // LCD display ram 00157 wr_cmd(0x40); // start line = 0 00158 wr_cmd(0xAF); // display ON 00159 00160 wr_cmd(0x81); // set contrast 00161 wr_cmd(0x17); // set contrast 00162 00163 wr_cmd(0xA6); // display normal 00164 00165 00166 #if defined TARGET_LPC1768 //setup DMA channel 0 00167 LPC_SC->PCONP |= (1UL << 29); // Power up the GPDMA 00168 LPC_GPDMA->DMACConfig = 1; // enable DMA controller 00169 LPC_GPDMA->DMACIntTCClear = 0x1; 00170 LPC_GPDMA->DMACIntErrClr = 0x1; 00171 LPC_GPDMACH0->DMACCLLI = 0; 00172 #endif 00173 // clear and update LCD 00174 memset(buffer,0x00,512); // clear display buffer 00175 copy_to_lcd(); 00176 auto_up = 1; // switch on auto update 00177 // dont do this by default. Make the user call 00178 //claim(stdout); // redirekt printf to lcd 00179 locate(0,0); 00180 set_font((unsigned char*)Small_7); // standart font 00181 } 00182 00183 // set one pixel in buffer 00184 00185 void C12832_LCD::pixel(int x, int y, int color) 00186 { 00187 // first check parameter 00188 if(x > 128 || y > 32 || x < 0 || y < 0) return; 00189 00190 if(draw_mode == NORMAL) { 00191 if(color == 0) 00192 buffer[x + ((y/8) * 128)] &= ~(1 << (y%8)); // erase pixel 00193 else 00194 buffer[x + ((y/8) * 128)] |= (1 << (y%8)); // set pixel 00195 } else { // XOR mode 00196 if(color == 1) 00197 buffer[x + ((y/8) * 128)] ^= (1 << (y%8)); // xor pixel 00198 } 00199 } 00200 00201 // update lcd 00202 00203 void C12832_LCD::copy_to_lcd(void) 00204 { 00205 #ifndef TARGET_LPC1768 00206 int i; 00207 #endif 00208 //page 0 00209 wr_cmd(0x00); // set column low nibble 0 00210 wr_cmd(0x10); // set column hi nibble 0 00211 wr_cmd(0xB0); // set page address 0 00212 _A0 = 1; 00213 #if defined TARGET_LPC1768 00214 _CS = 0; 00215 // start 128 byte DMA transfer to SPI1 00216 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1 00217 LPC_SSP1->DMACR = 0x2; // Enable SSP1 for DMA. 00218 LPC_GPDMA->DMACIntTCClear = 0x1; 00219 LPC_GPDMA->DMACIntErrClr = 0x1; 00220 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t) (buffer); 00221 LPC_GPDMACH0->DMACCControl = 128 | (1UL << 31) | DMA_CHANNEL_SRC_INC ; // 8 bit transfer , address increment, interrupt 00222 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | DMA_DEST_SSP1_TX; 00223 LPC_GPDMA->DMACSoftSReq = 0x1; 00224 do { 00225 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running 00226 do { 00227 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle 00228 _CS = 1; 00229 #else // no DMA 00230 for(i=0; i<128; i++) { 00231 wr_dat(buffer[i]); 00232 } 00233 #endif 00234 00235 // page 1 00236 wr_cmd(0x00); // set column low nibble 0 00237 wr_cmd(0x10); // set column hi nibble 0 00238 wr_cmd(0xB1); // set page address 1 00239 _A0 = 1; 00240 #if defined TARGET_LPC1768 00241 _CS = 0; 00242 // start 128 byte DMA transfer to SPI1 00243 LPC_GPDMA->DMACIntTCClear = 0x1; 00244 LPC_GPDMA->DMACIntErrClr = 0x1; 00245 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t) (buffer + 128); 00246 LPC_GPDMACH0->DMACCControl = 128 | (1UL << 31) | DMA_CHANNEL_SRC_INC ; // 8 bit transfer , address increment, interrupt 00247 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | DMA_DEST_SSP1_TX; 00248 LPC_GPDMA->DMACSoftSReq = 0x1; 00249 do { 00250 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running 00251 do { 00252 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle 00253 _CS = 1; 00254 #else // no DMA 00255 for(i=128; i<256; i++) { 00256 wr_dat(buffer[i]); 00257 } 00258 #endif 00259 00260 //page 2 00261 wr_cmd(0x00); // set column low nibble 0 00262 wr_cmd(0x10); // set column hi nibble 0 00263 wr_cmd(0xB2); // set page address 2 00264 _A0 = 1; 00265 #if defined TARGET_LPC1768 00266 _CS = 0; 00267 // start 128 byte DMA transfer to SPI1 00268 LPC_GPDMA->DMACIntTCClear = 0x1; 00269 LPC_GPDMA->DMACIntErrClr = 0x1; 00270 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t) (buffer + 256); 00271 LPC_GPDMACH0->DMACCControl = 128 | (1UL << 31) | DMA_CHANNEL_SRC_INC ; // 8 bit transfer , address increment, interrupt 00272 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | DMA_DEST_SSP1_TX ; 00273 LPC_GPDMA->DMACSoftSReq = 0x1; 00274 do { 00275 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running 00276 do { 00277 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle 00278 _CS = 1; 00279 #else // no DMA 00280 for(i=256; i<384; i++) { 00281 wr_dat(buffer[i]); 00282 } 00283 #endif 00284 00285 //page 3 00286 wr_cmd(0x00); // set column low nibble 0 00287 wr_cmd(0x10); // set column hi nibble 0 00288 wr_cmd(0xB3); // set page address 3 00289 _A0 = 1; 00290 00291 _CS = 0; 00292 #if defined TARGET_LPC1768 00293 // start 128 byte DMA transfer to SPI1 00294 LPC_GPDMA->DMACIntTCClear = 0x1; 00295 LPC_GPDMA->DMACIntErrClr = 0x1; 00296 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t) (buffer + 384); 00297 LPC_GPDMACH0->DMACCControl = 128 | (1UL << 31) | DMA_CHANNEL_SRC_INC ; // 8 bit transfer , address increment, interrupt 00298 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | DMA_DEST_SSP1_TX; 00299 LPC_GPDMA->DMACSoftSReq = 0x1; 00300 do { 00301 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running 00302 do { 00303 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle 00304 _CS = 1; 00305 #else // no DMA 00306 for(i=384; i<512; i++) { 00307 wr_dat(buffer[i]); 00308 } 00309 #endif 00310 } 00311 00312 void C12832_LCD::cls(void) 00313 { 00314 memset(buffer,0x00,512); // clear display buffer 00315 copy_to_lcd(); 00316 } 00317 00318 00319 void C12832_LCD::line(int x0, int y0, int x1, int y1, int color) 00320 { 00321 int dx = 0, dy = 0; 00322 int dx_sym = 0, dy_sym = 0; 00323 int dx_x2 = 0, dy_x2 = 0; 00324 int di = 0; 00325 00326 dx = x1-x0; 00327 dy = y1-y0; 00328 00329 // if (dx == 0) { /* vertical line */ 00330 // if (y1 > y0) vline(x0,y0,y1,color); 00331 // else vline(x0,y1,y0,color); 00332 // return; 00333 // } 00334 00335 if (dx > 0) { 00336 dx_sym = 1; 00337 } else { 00338 dx_sym = -1; 00339 } 00340 // if (dy == 0) { /* horizontal line */ 00341 // if (x1 > x0) hline(x0,x1,y0,color); 00342 // else hline(x1,x0,y0,color); 00343 // return; 00344 // } 00345 00346 if (dy > 0) { 00347 dy_sym = 1; 00348 } else { 00349 dy_sym = -1; 00350 } 00351 00352 dx = dx_sym*dx; 00353 dy = dy_sym*dy; 00354 00355 dx_x2 = dx*2; 00356 dy_x2 = dy*2; 00357 00358 if (dx >= dy) { 00359 di = dy_x2 - dx; 00360 while (x0 != x1) { 00361 00362 pixel(x0, y0, color); 00363 x0 += dx_sym; 00364 if (di<0) { 00365 di += dy_x2; 00366 } else { 00367 di += dy_x2 - dx_x2; 00368 y0 += dy_sym; 00369 } 00370 } 00371 pixel(x0, y0, color); 00372 } else { 00373 di = dx_x2 - dy; 00374 while (y0 != y1) { 00375 pixel(x0, y0, color); 00376 y0 += dy_sym; 00377 if (di < 0) { 00378 di += dx_x2; 00379 } else { 00380 di += dx_x2 - dy_x2; 00381 x0 += dx_sym; 00382 } 00383 } 00384 pixel(x0, y0, color); 00385 } 00386 if(auto_up) copy_to_lcd(); 00387 } 00388 00389 void C12832_LCD::rect(int x0, int y0, int x1, int y1, int color) 00390 { 00391 00392 if (x1 > x0) line(x0,y0,x1,y0,color); 00393 else line(x1,y0,x0,y0,color); 00394 00395 if (y1 > y0) line(x0,y0,x0,y1,color); 00396 else line(x0,y1,x0,y0,color); 00397 00398 if (x1 > x0) line(x0,y1,x1,y1,color); 00399 else line(x1,y1,x0,y1,color); 00400 00401 if (y1 > y0) line(x1,y0,x1,y1,color); 00402 else line(x1,y1,x1,y0,color); 00403 00404 if(auto_up) copy_to_lcd(); 00405 } 00406 00407 void C12832_LCD::fillrect(int x0, int y0, int x1, int y1, int color) 00408 { 00409 int l,c,i; 00410 if(x0 > x1) { 00411 i = x0; 00412 x0 = x1; 00413 x1 = i; 00414 } 00415 00416 if(y0 > y1) { 00417 i = y0; 00418 y0 = y1; 00419 y1 = i; 00420 } 00421 00422 for(l = x0; l<= x1; l ++) { 00423 for(c = y0; c<= y1; c++) { 00424 pixel(l,c,color); 00425 } 00426 } 00427 if(auto_up) copy_to_lcd(); 00428 } 00429 00430 00431 00432 void C12832_LCD::circle(int x0, int y0, int r, int color) 00433 { 00434 00435 int draw_x0, draw_y0; 00436 int draw_x1, draw_y1; 00437 int draw_x2, draw_y2; 00438 int draw_x3, draw_y3; 00439 int draw_x4, draw_y4; 00440 int draw_x5, draw_y5; 00441 int draw_x6, draw_y6; 00442 int draw_x7, draw_y7; 00443 int xx, yy; 00444 int di; 00445 //WindowMax(); 00446 if (r == 0) { /* no radius */ 00447 return; 00448 } 00449 00450 draw_x0 = draw_x1 = x0; 00451 draw_y0 = draw_y1 = y0 + r; 00452 if (draw_y0 < height()) { 00453 pixel(draw_x0, draw_y0, color); /* 90 degree */ 00454 } 00455 00456 draw_x2 = draw_x3 = x0; 00457 draw_y2 = draw_y3 = y0 - r; 00458 if (draw_y2 >= 0) { 00459 pixel(draw_x2, draw_y2, color); /* 270 degree */ 00460 } 00461 00462 draw_x4 = draw_x6 = x0 + r; 00463 draw_y4 = draw_y6 = y0; 00464 if (draw_x4 < width()) { 00465 pixel(draw_x4, draw_y4, color); /* 0 degree */ 00466 } 00467 00468 draw_x5 = draw_x7 = x0 - r; 00469 draw_y5 = draw_y7 = y0; 00470 if (draw_x5>=0) { 00471 pixel(draw_x5, draw_y5, color); /* 180 degree */ 00472 } 00473 00474 if (r == 1) { 00475 return; 00476 } 00477 00478 di = 3 - 2*r; 00479 xx = 0; 00480 yy = r; 00481 while (xx < yy) { 00482 00483 if (di < 0) { 00484 di += 4*xx + 6; 00485 } else { 00486 di += 4*(xx - yy) + 10; 00487 yy--; 00488 draw_y0--; 00489 draw_y1--; 00490 draw_y2++; 00491 draw_y3++; 00492 draw_x4--; 00493 draw_x5++; 00494 draw_x6--; 00495 draw_x7++; 00496 } 00497 xx++; 00498 draw_x0++; 00499 draw_x1--; 00500 draw_x2++; 00501 draw_x3--; 00502 draw_y4++; 00503 draw_y5++; 00504 draw_y6--; 00505 draw_y7--; 00506 00507 if ( (draw_x0 <= width()) && (draw_y0>=0) ) { 00508 pixel(draw_x0, draw_y0, color); 00509 } 00510 00511 if ( (draw_x1 >= 0) && (draw_y1 >= 0) ) { 00512 pixel(draw_x1, draw_y1, color); 00513 } 00514 00515 if ( (draw_x2 <= width()) && (draw_y2 <= height()) ) { 00516 pixel(draw_x2, draw_y2, color); 00517 } 00518 00519 if ( (draw_x3 >=0 ) && (draw_y3 <= height()) ) { 00520 pixel(draw_x3, draw_y3, color); 00521 } 00522 00523 if ( (draw_x4 <= width()) && (draw_y4 >= 0) ) { 00524 pixel(draw_x4, draw_y4, color); 00525 } 00526 00527 if ( (draw_x5 >= 0) && (draw_y5 >= 0) ) { 00528 pixel(draw_x5, draw_y5, color); 00529 } 00530 if ( (draw_x6 <=width()) && (draw_y6 <= height()) ) { 00531 pixel(draw_x6, draw_y6, color); 00532 } 00533 if ( (draw_x7 >= 0) && (draw_y7 <= height()) ) { 00534 pixel(draw_x7, draw_y7, color); 00535 } 00536 } 00537 if(auto_up) copy_to_lcd(); 00538 } 00539 00540 void C12832_LCD::fillcircle(int x, int y, int r, int color) 00541 { 00542 int i,up; 00543 up = auto_up; 00544 auto_up = 0; // off 00545 for (i = 0; i <= r; i++) 00546 circle(x,y,i,color); 00547 auto_up = up; 00548 if(auto_up) copy_to_lcd(); 00549 } 00550 00551 void C12832_LCD::setmode(int mode) 00552 { 00553 draw_mode = mode; 00554 } 00555 00556 void C12832_LCD::locate(int x, int y) 00557 { 00558 char_x = x; 00559 char_y = y; 00560 } 00561 00562 00563 00564 int C12832_LCD::columns() 00565 { 00566 return width() / font[1]; 00567 } 00568 00569 00570 00571 int C12832_LCD::rows() 00572 { 00573 return height() / font[2]; 00574 } 00575 00576 00577 00578 int C12832_LCD::_putc(int value) 00579 { 00580 if (value == '\n') { // new line 00581 char_x = 0; 00582 char_y = char_y + font[2]; 00583 if (char_y >= height() - font[2]) { 00584 char_y = 0; 00585 } 00586 } else { 00587 character(char_x, char_y, value); 00588 if(auto_up) copy_to_lcd(); 00589 } 00590 return value; 00591 } 00592 00593 void C12832_LCD::character(int x, int y, int c) 00594 { 00595 unsigned int hor,vert,offset,bpl,j,i,b; 00596 unsigned char* zeichen; 00597 unsigned char z,w; 00598 00599 if ((c < 31) || (c > 127)) return; // test char range 00600 00601 // read font parameter from start of array 00602 offset = font[0]; // bytes / char 00603 hor = font[1]; // get hor size of font 00604 vert = font[2]; // get vert size of font 00605 bpl = font[3]; // bytes per line 00606 00607 if (char_x + hor > width()) { 00608 char_x = 0; 00609 char_y = char_y + vert; 00610 if (char_y >= height() - font[2]) { 00611 char_y = 0; 00612 } 00613 } 00614 00615 zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap 00616 w = zeichen[0]; // width of actual char 00617 // construct the char into the buffer 00618 for (j=0; j<vert; j++) { // vert line 00619 for (i=0; i<hor; i++) { // horz line 00620 z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1]; 00621 b = 1 << (j & 0x07); 00622 if (( z & b ) == 0x00) { 00623 pixel(x+i,y+j,0); 00624 } else { 00625 pixel(x+i,y+j,1); 00626 } 00627 00628 } 00629 } 00630 00631 char_x += w; 00632 } 00633 00634 00635 void C12832_LCD::set_font(unsigned char* f) 00636 { 00637 font = f; 00638 } 00639 00640 void C12832_LCD::set_auto_up(unsigned int up) 00641 { 00642 if(up ) auto_up = 1; 00643 else auto_up = 0; 00644 } 00645 00646 unsigned int C12832_LCD::get_auto_up(void) 00647 { 00648 return (auto_up); 00649 } 00650 00651 void C12832_LCD::print_bm(Bitmap bm, int x, int y) 00652 { 00653 int h,v,b; 00654 char d; 00655 00656 for(v=0; v < bm.ySize; v++) { // lines 00657 for(h=0; h < bm.xSize; h++) { // pixel 00658 if(h + x > 127) break; 00659 if(v + y > 31) break; 00660 d = bm.data[bm.Byte_in_Line * v + ((h & 0xF8) >> 3)]; 00661 b = 0x80 >> (h & 0x07); 00662 if((d & b) == 0) { 00663 pixel(x+h,y+v,0); 00664 } else { 00665 pixel(x+h,y+v,1); 00666 } 00667 } 00668 } 00669 00670 } 00671 00672
Generated on Wed Jul 13 2022 04:23:46 by 1.7.2