SG12864A
Dependents: SG12864A_TestProgram
SG12864A.cpp
00001 /** 00002 * SG12864A Graphics LCD module driver class (Version 0.0.1) 00003 * 00004 * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems) 00005 * http://shinta.main.jp/ 00006 * 00007 * See also ... 00008 * http://mbed.org/users/shintamainjp/notebook/sg12864asunlike-display-graphics-lcd-driver/ 00009 */ 00010 00011 #include "SG12864A.h" 00012 00013 #define setPixel(x,y) buffer[((COLUMNS * 2)* ((y) / 8)) + (x)] |= (1 << ((y) % 8)) 00014 #define unsetPixel(x,y) buffer[((COLUMNS * 2)* ((y) / 8)) + (x)] &= ~(1 << ((y) % 8)) 00015 #define swap(a,b) {int c=a;a=b;b=c;} 00016 00017 const uint8_t SG12864A::font5x7_data[] = { 00018 0x00, 0x00, 0x00, 0x00, 0x00, // (white space) 00019 0x00, 0x00, 0x5F, 0x00, 0x00, // ! 00020 0x00, 0x07, 0x00, 0x07, 0x00, // " 00021 0x14, 0x7F, 0x14, 0x7F, 0x14, // # 00022 0x24, 0x2A, 0x7F, 0x2A, 0x12, // $ 00023 0x23, 0x13, 0x08, 0x64, 0x62, // % 00024 0x36, 0x49, 0x55, 0x22, 0x50, // & 00025 0x00, 0x05, 0x03, 0x00, 0x00, // ' 00026 0x00, 0x1C, 0x22, 0x41, 0x00, // ( 00027 0x00, 0x41, 0x22, 0x1C, 0x00, // ) 00028 0x08, 0x2A, 0x1C, 0x2A, 0x08, // * 00029 0x08, 0x08, 0x3E, 0x08, 0x08, // + 00030 0x00, 0x50, 0x30, 0x00, 0x00, // , 00031 0x08, 0x08, 0x08, 0x08, 0x08, // - 00032 0x00, 0x60, 0x60, 0x00, 0x00, // . 00033 0x20, 0x10, 0x08, 0x04, 0x02, // / 00034 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0 00035 0x00, 0x42, 0x7F, 0x40, 0x00, // 1 00036 0x42, 0x61, 0x51, 0x49, 0x46, // 2 00037 0x21, 0x41, 0x45, 0x4B, 0x31, // 3 00038 0x18, 0x14, 0x12, 0x7F, 0x10, // 4 00039 0x27, 0x45, 0x45, 0x45, 0x39, // 5 00040 0x3C, 0x4A, 0x49, 0x49, 0x30, // 6 00041 0x01, 0x71, 0x09, 0x05, 0x03, // 7 00042 0x36, 0x49, 0x49, 0x49, 0x36, // 8 00043 0x06, 0x49, 0x49, 0x29, 0x1E, // 9 00044 0x00, 0x36, 0x36, 0x00, 0x00, // : 00045 0x00, 0x56, 0x36, 0x00, 0x00, // ; 00046 0x00, 0x08, 0x14, 0x22, 0x41, // < 00047 0x14, 0x14, 0x14, 0x14, 0x14, // = 00048 0x41, 0x22, 0x14, 0x08, 0x00, // > 00049 0x02, 0x01, 0x51, 0x09, 0x06, // ? 00050 0x32, 0x49, 0x79, 0x41, 0x3E, // @ 00051 0x7E, 0x11, 0x11, 0x11, 0x7E, // A 00052 0x7F, 0x49, 0x49, 0x49, 0x36, // B 00053 0x3E, 0x41, 0x41, 0x41, 0x22, // C 00054 0x7F, 0x41, 0x41, 0x22, 0x1C, // D 00055 0x7F, 0x49, 0x49, 0x49, 0x41, // E 00056 0x7F, 0x09, 0x09, 0x01, 0x01, // F 00057 0x3E, 0x41, 0x41, 0x51, 0x32, // G 00058 0x7F, 0x08, 0x08, 0x08, 0x7F, // H 00059 0x00, 0x41, 0x7F, 0x41, 0x00, // I 00060 0x20, 0x40, 0x41, 0x3F, 0x01, // J 00061 0x7F, 0x08, 0x14, 0x22, 0x41, // K 00062 0x7F, 0x40, 0x40, 0x40, 0x40, // L 00063 0x7F, 0x02, 0x04, 0x02, 0x7F, // M 00064 0x7F, 0x04, 0x08, 0x10, 0x7F, // N 00065 0x3E, 0x41, 0x41, 0x41, 0x3E, // O 00066 0x7F, 0x09, 0x09, 0x09, 0x06, // P 00067 0x3E, 0x41, 0x51, 0x21, 0x5E, // Q 00068 0x7F, 0x09, 0x19, 0x29, 0x46, // R 00069 0x46, 0x49, 0x49, 0x49, 0x31, // S 00070 0x01, 0x01, 0x7F, 0x01, 0x01, // T 00071 0x3F, 0x40, 0x40, 0x40, 0x3F, // U 00072 0x1F, 0x20, 0x40, 0x20, 0x1F, // V 00073 0x7F, 0x20, 0x18, 0x20, 0x7F, // W 00074 0x63, 0x14, 0x08, 0x14, 0x63, // X 00075 0x03, 0x04, 0x78, 0x04, 0x03, // Y 00076 0x61, 0x51, 0x49, 0x45, 0x43, // Z 00077 0x00, 0x00, 0x7F, 0x41, 0x41, // [ 00078 0x02, 0x04, 0x08, 0x10, 0x20, // / 00079 0x41, 0x41, 0x7F, 0x00, 0x00, // ] 00080 0x04, 0x02, 0x01, 0x02, 0x04, // ^ 00081 0x40, 0x40, 0x40, 0x40, 0x40, // _ 00082 0x00, 0x01, 0x02, 0x04, 0x00, // ` 00083 0x20, 0x54, 0x54, 0x54, 0x78, // a 00084 0x7F, 0x48, 0x44, 0x44, 0x38, // b 00085 0x38, 0x44, 0x44, 0x44, 0x20, // c 00086 0x38, 0x44, 0x44, 0x48, 0x7F, // d 00087 0x38, 0x54, 0x54, 0x54, 0x18, // e 00088 0x08, 0x7E, 0x09, 0x01, 0x02, // f 00089 0x08, 0x14, 0x54, 0x54, 0x3C, // g 00090 0x7F, 0x08, 0x04, 0x04, 0x78, // h 00091 0x00, 0x44, 0x7D, 0x40, 0x00, // i 00092 0x20, 0x40, 0x44, 0x3D, 0x00, // j 00093 0x00, 0x7F, 0x10, 0x28, 0x44, // k 00094 0x00, 0x41, 0x7F, 0x40, 0x00, // l 00095 0x7C, 0x04, 0x18, 0x04, 0x78, // m 00096 0x7C, 0x08, 0x04, 0x04, 0x78, // n 00097 0x38, 0x44, 0x44, 0x44, 0x38, // o 00098 0x7C, 0x14, 0x14, 0x14, 0x08, // p 00099 0x08, 0x14, 0x14, 0x18, 0x7C, // q 00100 0x7C, 0x08, 0x04, 0x04, 0x08, // r 00101 0x48, 0x54, 0x54, 0x54, 0x20, // s 00102 0x04, 0x3F, 0x44, 0x40, 0x20, // t 00103 0x3C, 0x40, 0x40, 0x20, 0x7C, // u 00104 0x1C, 0x20, 0x40, 0x20, 0x1C, // v 00105 0x3C, 0x40, 0x30, 0x40, 0x3C, // w 00106 0x44, 0x28, 0x10, 0x28, 0x44, // x 00107 0x0C, 0x50, 0x50, 0x50, 0x3C, // y 00108 0x44, 0x64, 0x54, 0x4C, 0x44, // z 00109 0x00, 0x08, 0x36, 0x41, 0x00, // { 00110 0x00, 0x00, 0x7F, 0x00, 0x00, // | 00111 0x00, 0x41, 0x36, 0x08, 0x00, // } 00112 0x08, 0x08, 0x2A, 0x1C, 0x08, // -> 00113 0x08, 0x1C, 0x2A, 0x08, 0x08 // <- 00114 }; 00115 00116 SG12864A::SG12864A(PinName di, 00117 PinName rw, 00118 PinName en, 00119 PinName db0, 00120 PinName db1, 00121 PinName db2, 00122 PinName db3, 00123 PinName db4, 00124 PinName db5, 00125 PinName db6, 00126 PinName db7, 00127 PinName cs1, 00128 PinName cs2, 00129 PinName res) 00130 : 00131 ioDI(di), 00132 ioRW(rw), 00133 ioEN(en), 00134 ioDB(db0, db1, db2, db3, db4, db5, db6, db7), 00135 ioCS1(cs1), 00136 ioCS2(cs2), 00137 ioRES(res) { 00138 bufferClear(); 00139 setDirectionToWrite(); 00140 } 00141 00142 SG12864A::~SG12864A() { 00143 } 00144 00145 void SG12864A::bufferPush(void) { 00146 for (uint8_t i = 0; i < PAGES; i++) { 00147 // CS1 00148 setPageAddress(SG12864A::CS1, i); 00149 setColumnAddress(SG12864A::CS1, 0); 00150 for (uint8_t j = 0; j < COLUMNS; j++) { 00151 writeData(CS1, buffer[0 + ((COLUMNS * 2) * i) + j]); 00152 } 00153 // CS2 00154 setPageAddress(SG12864A::CS2, i); 00155 setColumnAddress(SG12864A::CS2, 0); 00156 for (uint8_t j = 0; j < COLUMNS; j++) { 00157 writeData(CS2, buffer[COLUMNS + ((COLUMNS * 2) * i) + j]); 00158 } 00159 } 00160 } 00161 00162 void SG12864A::bufferPull(void) { 00163 } 00164 00165 void SG12864A::bufferClear(bool reverse) { 00166 for (int i = 0; i < sizeof(buffer); i++) { 00167 if (reverse) { 00168 buffer[i] = 0xFF; 00169 } else { 00170 buffer[i] = 0x00; 00171 } 00172 } 00173 } 00174 00175 void SG12864A::bufferDrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool reverse) { 00176 /* 00177 * Bresenham's line algorithm 00178 */ 00179 bool steep = abs(y2 - y1) > abs(x2 - x1); 00180 if (steep) { 00181 swap(x1, y1); 00182 swap(x2, y2); 00183 } 00184 if (x1 > x2) { 00185 swap(x1, x2); 00186 swap(y1, y2); 00187 } 00188 int deltax = x2 - x1; 00189 int deltay = abs(y2 - y1); 00190 int error = deltax / 2; 00191 int ystep; 00192 int y = y1; 00193 if (y1 < y2) { 00194 ystep = 1; 00195 } else { 00196 ystep = -1; 00197 } 00198 for (int x = x1; x <= x2; x++) { 00199 if (steep) { 00200 if (reverse) { 00201 unsetPixel(y, x); 00202 } else { 00203 setPixel(y, x); 00204 } 00205 } else { 00206 if (reverse) { 00207 unsetPixel(x, y); 00208 } else { 00209 setPixel(x, y); 00210 } 00211 } 00212 error = error - deltay; 00213 if (error < 0) { 00214 y = y + ystep; 00215 error = error + deltax; 00216 } 00217 } 00218 } 00219 00220 void SG12864A::bufferDrawBox(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool reverse) { 00221 for (int x = x1; x <= x2; x++) { 00222 if (reverse) { 00223 unsetPixel(x, y1); 00224 unsetPixel(x, y2); 00225 } else { 00226 setPixel(x, y1); 00227 setPixel(x, y2); 00228 } 00229 } 00230 for (int y = y1; y <= y2; y++) { 00231 if (reverse) { 00232 unsetPixel(x1, y); 00233 unsetPixel(x2, y); 00234 } else { 00235 setPixel(x1, y); 00236 setPixel(x2, y); 00237 } 00238 } 00239 } 00240 00241 void SG12864A::bufferFillBox(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool reverse) { 00242 for (int x = x1; x <= x2; x++) { 00243 for (int y = y1; y <= y2; y++) { 00244 if (reverse) { 00245 unsetPixel(x, y); 00246 } else { 00247 setPixel(x, y); 00248 } 00249 } 00250 } 00251 } 00252 00253 void SG12864A::bufferDrawString(uint8_t x, uint8_t y, char * str, bool reverse) { 00254 char *p = str; 00255 int cnt = 0; 00256 while (*p) { 00257 bufferDrawChar(x + (FONT_X * cnt), y, *p, reverse); 00258 p++; 00259 cnt++; 00260 } 00261 } 00262 00263 void SG12864A::bufferDrawChar(uint8_t x, uint8_t y, char c, bool reverse) { 00264 if ((FONT_MIN_CODE <= c) &&(c <= FONT_MAX_CODE)) { 00265 int aofs = (c - FONT_MIN_CODE) * FONT_X; 00266 for (int i = 0; i < FONT_X; i++) { 00267 uint8_t pat = font5x7_data[aofs + i]; 00268 for (int j = 0; j < FONT_Y; j++) { 00269 if (pat & (1 << j)) { 00270 if (reverse) { 00271 unsetPixel(x + i, y + j); 00272 } else { 00273 setPixel(x + i, y + j); 00274 } 00275 } else { 00276 if (reverse) { 00277 setPixel(x + i, y + j); 00278 } else { 00279 unsetPixel(x + i, y + j); 00280 } 00281 } 00282 } 00283 } 00284 } else { 00285 for (int i = 0; i < FONT_X; i++) { 00286 uint8_t pat = (i % 2) ? 0x55 : 0xAA; 00287 for (int j = 0; j < FONT_Y; j++) { 00288 if (pat & (1 << j)) { 00289 if (reverse) { 00290 unsetPixel(x + i, y + j); 00291 } else { 00292 setPixel(x + i, y + j); 00293 } 00294 } else { 00295 if (reverse) { 00296 setPixel(x + i, y + j); 00297 } else { 00298 unsetPixel(x + i, y + j); 00299 } 00300 } 00301 } 00302 } 00303 } 00304 } 00305 00306 void SG12864A::bufferDrawCheckbox(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, bool state, bool reverse) { 00307 bufferDrawBox(x1, y1, x2, y2, reverse); 00308 if (state) { 00309 bufferDrawLine(x1, y1, x2, y2, reverse); 00310 bufferDrawLine(x1, y2, x2, y1, reverse); 00311 } 00312 } 00313 00314 void SG12864A::bufferDrawProgressbar(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, int min, int max, int value, bool reverse) { 00315 bufferDrawBox(x1, y1, x2, y2, reverse); 00316 if ((value < min) || (max < value)) { 00317 return; 00318 } 00319 int tmp_max = max - min; 00320 int tmp_val = value - min; 00321 int pix = ((x2 - x1) * tmp_val) / tmp_max; 00322 bufferFillBox(x1 + 1, y1 + 1, x1 + pix - 1, y2 - 1, reverse); 00323 } 00324 00325 /** 00326 * High Level Interface. 00327 * 00328 * Reset display module. 00329 */ 00330 void SG12864A::reset(void) { 00331 reset(true); 00332 wait_ms(200); 00333 reset(false); 00334 wait_ms(200); 00335 00336 setDisplayOnOff(SG12864A::CS1, true); 00337 setDisplayOnOff(SG12864A::CS2, true); 00338 setDisplayStartLine(SG12864A::CS1, 0); 00339 setDisplayStartLine(SG12864A::CS2, 0); 00340 setPageAddress(SG12864A::CS1, 0); 00341 setPageAddress(SG12864A::CS2, 0); 00342 setColumnAddress(SG12864A::CS1, 0); 00343 setColumnAddress(SG12864A::CS2, 0); 00344 } 00345 00346 /** 00347 * High Level Interface. 00348 * 00349 * Clear display module. 00350 */ 00351 void SG12864A::clear(void) { 00352 for (uint8_t page = 0; page < PAGES; page++) { 00353 for (uint8_t column = 0; column < COLUMNS; column++) { 00354 // CS1 00355 setPageAddress(SG12864A::CS1, page); 00356 setColumnAddress(SG12864A::CS1, column); 00357 writeData(CS1, 0x00); 00358 // CS2 00359 setPageAddress(SG12864A::CS2, page); 00360 setColumnAddress(SG12864A::CS2, column); 00361 writeData(CS2, 0x00); 00362 } 00363 } 00364 // CS1 00365 setPageAddress(SG12864A::CS1, 0); 00366 setColumnAddress(SG12864A::CS1, 0); 00367 writeData(CS1, 0x00); 00368 // CS2 00369 setPageAddress(SG12864A::CS2, 0); 00370 setColumnAddress(SG12864A::CS2, 0); 00371 writeData(CS2, 0x00); 00372 } 00373 00374 /** 00375 * Middle Level Interface. 00376 * 00377 * Set display on/off. 00378 * 00379 * @param t Target (CS1, CS2). 00380 * @param on ON/OFF (true, false). 00381 */ 00382 void SG12864A::setDisplayOnOff(Target t, bool on) { 00383 setDirectionToWrite(); 00384 uint8_t c = 0x3e | (on ? 0x01 : 0x00); 00385 write(t, SG12864A::Instruction, c); 00386 wait_us(1); 00387 } 00388 00389 /** 00390 * Middle Level Interface. 00391 * 00392 * Set display start line. 00393 * 00394 * @param t Target (CS1, CS2). 00395 * @param addr Display start line (0-63). 00396 */ 00397 void SG12864A::setDisplayStartLine(Target t, uint8_t addr) { 00398 setDirectionToWrite(); 00399 uint8_t c = 0xc0 | (addr & 0x3f); 00400 write(t, SG12864A::Instruction, c); 00401 wait_us(1); 00402 } 00403 00404 /** 00405 * Middle Level Interface. 00406 * 00407 * Set page address. 00408 * 00409 * @param t Target (CS1, CS2). 00410 * @param addr Page address(0-7). 00411 */ 00412 void SG12864A::setPageAddress(Target t, uint8_t addr) { 00413 setDirectionToWrite(); 00414 uint8_t c = 0xb8 | (addr & 0x07); 00415 write(t, SG12864A::Instruction, c); 00416 wait_us(1); 00417 } 00418 00419 /** 00420 * Middle Level Interface. 00421 * 00422 * Set column address. 00423 * 00424 * @param t Target. (CS1, CS2) 00425 * @param addr Column address (0-63). 00426 */ 00427 void SG12864A::setColumnAddress(Target t, uint8_t addr) { 00428 setDirectionToWrite(); 00429 uint8_t c = 0x40 | (addr & 0x3f); 00430 write(t, SG12864A::Instruction, c); 00431 wait_us(1); 00432 } 00433 00434 /** 00435 * Middle Level Interface. 00436 */ 00437 void SG12864A::readStatus(Target t, uint8_t *c) { 00438 setDirectionToRead(); 00439 read(t, SG12864A::Instruction, c); 00440 wait_us(1); 00441 } 00442 00443 /** 00444 * Middle Level Interface. 00445 */ 00446 void SG12864A::writeData(Target t, uint8_t c) { 00447 setDirectionToWrite(); 00448 write(t, SG12864A::Data, c); 00449 wait_us(1); 00450 } 00451 00452 /** 00453 * Middle Level Interface. 00454 */ 00455 void SG12864A::readData(Target t, uint8_t *c) { 00456 setDirectionToRead(); 00457 read(t, SG12864A::Data, c); 00458 wait_us(1); 00459 } 00460 00461 /** 00462 * Low Level Interface. 00463 */ 00464 void SG12864A::setDirectionToRead() { 00465 ioDB.input(); 00466 ioRW = 1; 00467 } 00468 00469 /** 00470 * Low Level Interface. 00471 */ 00472 void SG12864A::setDirectionToWrite() { 00473 ioDB.output(); 00474 ioRW = 0; 00475 } 00476 00477 /** 00478 * Low Level Interface. 00479 */ 00480 void SG12864A::write(Target t, Mode m, uint8_t c) { 00481 switch (t) { 00482 case CS1: 00483 ioCS1 = 1; 00484 ioCS2 = 0; 00485 break; 00486 case CS2: 00487 ioCS1 = 0; 00488 ioCS2 = 1; 00489 break; 00490 } 00491 switch (m) { 00492 case Data: 00493 ioDI = 1; 00494 break; 00495 case Instruction: 00496 ioDI = 0; 00497 break; 00498 } 00499 ioDB = c; 00500 wait_us(1); 00501 ioEN = 1; 00502 wait_us(1); 00503 ioEN = 0; 00504 wait_us(5); 00505 } 00506 00507 /** 00508 * Low Level Interface. 00509 */ 00510 void SG12864A::read(Target t, Mode m, uint8_t *c) { 00511 // TODO 00512 } 00513 00514 /** 00515 * Low Level Interface. 00516 */ 00517 void SG12864A::reset(bool b) { 00518 if (b) { 00519 ioRES = 0; 00520 } else { 00521 ioRES = 1; 00522 } 00523 }
Generated on Tue Jul 12 2022 11:03:55 by 1.7.2