Aitendo OLED device driver library.
Dependents: AitendoOLED_TestProgram
AitendoOLED.cpp
00001 /** 00002 * ============================================================================= 00003 * Aitendo OLED device driver library. (Version 0.0.2) 00004 * 00005 * [The product] 00006 * OLED-2P-095BWNN-SPI : http://www.aitendo.co.jp/product/2099 00007 * ALO-095BWNN-J9 : http://www.aitendo.co.jp/product/1449 00008 * 00009 * [References] 00010 * http://serdisplib.sourceforge.net/ser/doc/Treiber_IC-SSD1332_OLED_96x64_COLOR.pdf 00011 * ============================================================================= 00012 * Copyright (c) 2010 Shinichiro Nakamura (CuBeatSystems) 00013 * 00014 * Permission is hereby granted, free of charge, to any person obtaining a copy 00015 * of this software and associated documentation files (the "Software"), to deal 00016 * in the Software without restriction, including without limitation the rights 00017 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00018 * copies of the Software, and to permit persons to whom the Software is 00019 * furnished to do so, subject to the following conditions: 00020 * 00021 * The above copyright notice and this permission notice shall be included in 00022 * all copies or substantial portions of the Software. 00023 * 00024 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00025 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00026 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00027 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00028 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00029 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00030 * THE SOFTWARE. 00031 * ============================================================================= 00032 */ 00033 #include "AitendoOLED.h" 00034 00035 #define RES_ENA() io_res = 0 00036 #define RES_DIS() io_res = 1 00037 #define CS_ENA() io_cs = 0 00038 #define CS_DIS() io_cs = 1 00039 #define DC_CMD() io_dc = 0 00040 #define DC_DAT() io_dc = 1 00041 #define SPI_WRITE(a) io_spi.write((a)) 00042 #define SPI_READ() io_spi.write(0x00) 00043 #define WAIT_US(a) wait_us((a)) 00044 #define swap(a,b) {int c=a;a=b;b=c;} 00045 00046 /** 00047 * Create. 00048 * 00049 * @param pin_mosi MOSI. 00050 * @param pin miso MISO. 00051 * @param pin_sclk SCLK. 00052 * @param pin_res RES. 00053 * @param pin_cs CS. 00054 * @param pin_dc DC. 00055 */ 00056 AitendoOLED::AitendoOLED( 00057 PinName pin_mosi, 00058 PinName pin_miso, 00059 PinName pin_sclk, 00060 PinName pin_res, 00061 PinName pin_cs, 00062 PinName pin_dc) 00063 : 00064 io_spi(pin_mosi, pin_miso, pin_sclk), 00065 io_res(pin_res), 00066 io_cs(pin_cs), 00067 io_dc(pin_dc) { 00068 io_spi.format(8, 0); 00069 #if 0 00070 io_spi.frequency(4000000); 00071 #else 00072 io_spi.frequency(40000000); 00073 #endif 00074 reset(); 00075 } 00076 00077 /** 00078 * Dispose. 00079 */ 00080 AitendoOLED::~AitendoOLED() { 00081 } 00082 00083 /** 00084 * Draw pixel. 00085 * 00086 * @param x X. 00087 * @param y Y. 00088 * @param c Color. 00089 */ 00090 void AitendoOLED::drawPixel(int x, int y, Color c) { 00091 setColumnAddress(x, x); 00092 setRowAddress(y, y); 00093 c.b = c.b >> 3; 00094 c.g = c.g >> 2; 00095 c.r = c.r >> 3; 00096 writeData((((c.b << 3) & 0xF8) | ((c.g >> 3) & 0x07))); 00097 writeData((((c.g << 5) & 0xE0) | ((c.r >> 0) & 0x1F))); 00098 } 00099 00100 /** 00101 * Draw line. 00102 * 00103 * @param x1 X1. 00104 * @param y1 Y1. 00105 * @param x2 X2. 00106 * @param y2 Y2. 00107 * @param c Color. 00108 */ 00109 void AitendoOLED::drawLine(int x1, int y1, int x2, int y2, Color c) { 00110 #if 0 00111 DC_CMD(); 00112 CS_ENA(); 00113 SPI_WRITE(0x21); 00114 SPI_WRITE(x1); 00115 SPI_WRITE(y1); 00116 SPI_WRITE(x2); 00117 SPI_WRITE(y2); 00118 SPI_WRITE(c.b >> 3); 00119 SPI_WRITE(c.g >> 2); 00120 SPI_WRITE(c.r >> 3); 00121 CS_DIS(); 00122 WAIT_US(100); 00123 #else 00124 /* 00125 * Bresenham's line algorithm 00126 */ 00127 bool steep = abs(y2 - y1) > abs(x2 - x1); 00128 if (steep) { 00129 swap(x1, y1); 00130 swap(x2, y2); 00131 } 00132 if (x1 > x2) { 00133 swap(x1, x2); 00134 swap(y1, y2); 00135 } 00136 int deltax = x2 - x1; 00137 int deltay = abs(y2 - y1); 00138 int error = deltax / 2; 00139 int ystep; 00140 int y = y1; 00141 if (y1 < y2) { 00142 ystep = 1; 00143 } else { 00144 ystep = -1; 00145 } 00146 for (int x = x1; x <= x2; x++) { 00147 if (steep) { 00148 drawPixel(y, x, c); 00149 } else { 00150 drawPixel(x, y, c); 00151 } 00152 error = error - deltay; 00153 if (error < 0) { 00154 y = y + ystep; 00155 error = error + deltax; 00156 } 00157 } 00158 #endif 00159 } 00160 00161 /** 00162 * Fill box. 00163 * 00164 * @param x1 X1. 00165 * @param y1 Y1. 00166 * @param x2 X2. 00167 * @param y2 Y2. 00168 * @param c1 Color1. 00169 * @param c2 Color2. 00170 */ 00171 void AitendoOLED::fillBox(int x1, int y1, int x2, int y2, Color c1, Color c2) { 00172 DC_CMD(); 00173 CS_ENA(); 00174 SPI_WRITE(0x22); 00175 SPI_WRITE(x1); 00176 SPI_WRITE(y1); 00177 SPI_WRITE(x2); 00178 SPI_WRITE(y2); 00179 SPI_WRITE(c1.b >> 3); 00180 SPI_WRITE(c1.g >> 2); 00181 SPI_WRITE(c1.r >> 3); 00182 SPI_WRITE(c2.b >> 3); 00183 SPI_WRITE(c2.g >> 2); 00184 SPI_WRITE(c2.r >> 3); 00185 CS_DIS(); 00186 WAIT_US(400); 00187 } 00188 00189 /** 00190 * Copy. 00191 * 00192 * @param x1 X1. 00193 * @param y1 Y1. 00194 * @param x2 X2. 00195 * @param y2 Y2. 00196 * @param nx X of the destination. 00197 * @param ny Y of the destination. 00198 */ 00199 void AitendoOLED::copy(int x1, int y1, int x2, int y2, int nx, int ny) { 00200 DC_CMD(); 00201 CS_ENA(); 00202 SPI_WRITE(0x23); 00203 SPI_WRITE(x1); 00204 SPI_WRITE(y1); 00205 SPI_WRITE(x2); 00206 SPI_WRITE(y2); 00207 SPI_WRITE(nx); 00208 SPI_WRITE(ny); 00209 CS_DIS(); 00210 WAIT_US(400); 00211 } 00212 00213 /** 00214 * Darker. 00215 * 00216 * @param x1 X1. 00217 * @param y1 Y1. 00218 * @param x2 X2. 00219 * @param y2 Y2. 00220 */ 00221 void AitendoOLED::darker(int x1, int y1, int x2, int y2) { 00222 DC_CMD(); 00223 CS_ENA(); 00224 SPI_WRITE(0x24); 00225 SPI_WRITE(x1); 00226 SPI_WRITE(y1); 00227 SPI_WRITE(x2); 00228 SPI_WRITE(y2); 00229 CS_DIS(); 00230 WAIT_US(400); 00231 } 00232 00233 /** 00234 * Clear. 00235 * 00236 * @param x1 X1. 00237 * @param y1 Y1. 00238 * @param x2 X2. 00239 * @param y2 Y2. 00240 */ 00241 void AitendoOLED::clear(int x1, int y1, int x2, int y2) { 00242 #if 1 00243 DC_CMD(); 00244 CS_ENA(); 00245 SPI_WRITE(0x25); 00246 SPI_WRITE(x1); 00247 SPI_WRITE(y1); 00248 SPI_WRITE(x2); 00249 SPI_WRITE(y2); 00250 CS_DIS(); 00251 WAIT_US(400); 00252 #else 00253 AitendoOLED::Color c; 00254 c.r = 0x00; 00255 c.g = 0x00; 00256 c.b = 0x00; 00257 for (int x = x1; x <= x2; x++) { 00258 for (int y = y1; y <= y2; y++) { 00259 drawPixel(x, y, c); 00260 } 00261 } 00262 #endif 00263 } 00264 00265 /** 00266 * Reset. 00267 */ 00268 void AitendoOLED::reset() { 00269 00270 RES_ENA(); 00271 WAIT_US(200 * 1000); 00272 RES_DIS(); 00273 WAIT_US(200 * 1000); 00274 00275 setDisplayOnOff(false); 00276 setRowAddress(0, 63); 00277 setColumnAddress(0, 95); 00278 setRemapAndDataFormat(0x70); 00279 setDisplayStartLine(0); 00280 setDisplayOffset(0); 00281 setDisplayMode(AitendoOLED::NormalDisplay); 00282 setMultiplexRatio(0x3f); 00283 setMasterCurrentControl(0x8f); 00284 setPowerSavingMode(0x00); 00285 setPhasePeriod(0x74); 00286 setDisplayClockDivideRatio(0xD0); 00287 setSecondPreChargeSpeedForColorA(0x80); 00288 setSecondPreChargeSpeedForColorB(0x80); 00289 setSecondPreChargeSpeedForColorC(0x80); 00290 setPreChargeLevelForColorA(0x3F); 00291 setPreChargeLevelForColorB(0x3F); 00292 setPreChargeLevelForColorC(0x3F); 00293 setVCOMH(0x3E); 00294 setMasterCurrentControl(0x0F); 00295 // A:Blue, B:Green, C:Red 00296 setContrastForColorA(0x80); 00297 setContrastForColorB(0x80); 00298 setContrastForColorC(0x80); 00299 setMode(true, false); 00300 setDisplayOnOff(true); 00301 } 00302 00303 /** 00304 * Write data. 00305 * 00306 * @param data Data. 00307 */ 00308 void AitendoOLED::writeData(uint8_t data) { 00309 DC_DAT(); 00310 CS_ENA(); 00311 SPI_WRITE(data); 00312 CS_DIS(); 00313 } 00314 00315 /** 00316 * Set mode. 00317 * 00318 * @param fillrect Fill the rectangle. 00319 * @param revcopy Reverse copy. 00320 */ 00321 void AitendoOLED::setMode(bool fillrect, bool revcopy) { 00322 uint8_t val = 0x00; 00323 if (fillrect) { 00324 val |= 1 << 0; 00325 } 00326 if (revcopy) { 00327 val |= 1 << 4; 00328 } 00329 DC_CMD(); 00330 CS_ENA(); 00331 SPI_WRITE(0x26); 00332 SPI_WRITE(val); 00333 CS_DIS(); 00334 } 00335 00336 /** 00337 * Set column address. 00338 * 00339 * @param start Start address. (0-95) 00340 * @param end End address. (0-95) 00341 */ 00342 void AitendoOLED::setColumnAddress(int start, int end) { 00343 DC_CMD(); 00344 CS_ENA(); 00345 SPI_WRITE(0x15); 00346 SPI_WRITE(start); 00347 SPI_WRITE(end); 00348 CS_DIS(); 00349 } 00350 00351 /** 00352 * Set row address. 00353 * 00354 * @param start Start address. (0-63) 00355 * @param end End address. (0-63) 00356 */ 00357 void AitendoOLED::setRowAddress(int start, int end) { 00358 DC_CMD(); 00359 CS_ENA(); 00360 SPI_WRITE(0x75); 00361 SPI_WRITE(start); 00362 SPI_WRITE(end); 00363 CS_DIS(); 00364 } 00365 00366 /** 00367 * Set contrast for Color A. 00368 * 00369 * @param contrast Contrast. (Default:0x80) 00370 */ 00371 void AitendoOLED::setContrastForColorA(int contrast) { 00372 DC_CMD(); 00373 CS_ENA(); 00374 SPI_WRITE(0x81); 00375 SPI_WRITE(contrast); 00376 CS_DIS(); 00377 } 00378 00379 /** 00380 * Set contrast for Color B. 00381 * 00382 * @param contrast Contrast. (Default:0x80) 00383 */ 00384 void AitendoOLED::setContrastForColorB(int contrast) { 00385 DC_CMD(); 00386 CS_ENA(); 00387 SPI_WRITE(0x82); 00388 SPI_WRITE(contrast); 00389 CS_DIS(); 00390 } 00391 00392 /** 00393 * Set contrast for Color C. 00394 * 00395 * @param contrast Contrast. (Default:0x80) 00396 */ 00397 void AitendoOLED::setContrastForColorC(int contrast) { 00398 DC_CMD(); 00399 CS_ENA(); 00400 SPI_WRITE(0x83); 00401 SPI_WRITE(contrast); 00402 CS_DIS(); 00403 } 00404 00405 /** 00406 * Set master current control value. 00407 * 00408 * @param current Current value. (0x00-0x0F) 00409 */ 00410 void AitendoOLED::setMasterCurrentControl(int current) { 00411 DC_CMD(); 00412 CS_ENA(); 00413 SPI_WRITE(0x87); 00414 SPI_WRITE(current); 00415 CS_DIS(); 00416 } 00417 00418 /** 00419 * Set remapping mode and the data format. 00420 * 00421 * @param mode See the document. 00422 */ 00423 void AitendoOLED::setRemapAndDataFormat(int mode) { 00424 DC_CMD(); 00425 CS_ENA(); 00426 SPI_WRITE(0xA0); 00427 SPI_WRITE(mode); 00428 CS_DIS(); 00429 } 00430 00431 /** 00432 * Set display start line. 00433 * 00434 * @param line Start line number. (0-63) 00435 */ 00436 void AitendoOLED::setDisplayStartLine(int line) { 00437 DC_CMD(); 00438 CS_ENA(); 00439 SPI_WRITE(0xA1); 00440 SPI_WRITE(line); 00441 CS_DIS(); 00442 } 00443 00444 /** 00445 * Set display offset line. 00446 * 00447 * @param offset Offset line number. (0-63) 00448 */ 00449 void AitendoOLED::setDisplayOffset(int offset) { 00450 DC_CMD(); 00451 CS_ENA(); 00452 SPI_WRITE(0xA2); 00453 SPI_WRITE(offset); 00454 CS_DIS(); 00455 } 00456 00457 /** 00458 * Set display mode. 00459 * 00460 * @param mode Display mode. 00461 */ 00462 void AitendoOLED::setDisplayMode(DisplayMode mode) { 00463 int val = 0; 00464 switch (mode) { 00465 case NormalDisplay: 00466 val = 0xA4; 00467 break; 00468 case EntireDisplayOn: 00469 val = 0xA5; 00470 break; 00471 case EntireDisplayOff: 00472 val = 0xA6; 00473 break; 00474 case InverseDisplay: 00475 val = 0xA7; 00476 break; 00477 default: 00478 break; 00479 } 00480 if (val != 0) { 00481 DC_CMD(); 00482 CS_ENA(); 00483 SPI_WRITE(val); 00484 CS_DIS(); 00485 } 00486 } 00487 00488 /** 00489 * Set multiplex ratio. 00490 * 00491 * @param ratio Ratio. 00492 */ 00493 void AitendoOLED::setMultiplexRatio(int ratio) { 00494 DC_CMD(); 00495 CS_ENA(); 00496 SPI_WRITE(0xA8); 00497 SPI_WRITE(ratio); 00498 CS_DIS(); 00499 } 00500 00501 /** 00502 * Set display on/off. 00503 * 00504 * @param on On. 00505 */ 00506 void AitendoOLED::setDisplayOnOff(bool on) { 00507 if (on) { 00508 DC_CMD(); 00509 CS_ENA(); 00510 SPI_WRITE(0xAF); 00511 CS_DIS(); 00512 } else { 00513 DC_CMD(); 00514 CS_ENA(); 00515 SPI_WRITE(0xAE); 00516 CS_DIS(); 00517 } 00518 } 00519 00520 /** 00521 * Set gray scale table. 00522 * 00523 * @param p A pointer to the look up table. 00524 */ 00525 void AitendoOLED::setGrayScaleTable(gray_scale_table_t *p) { 00526 DC_CMD(); 00527 CS_ENA(); 00528 SPI_WRITE(0xB8); 00529 for (int i = 0; i < 32; i++) { 00530 SPI_WRITE(p->data[i]); 00531 } 00532 CS_DIS(); 00533 } 00534 00535 /** 00536 * NOP. 00537 */ 00538 void AitendoOLED::nop() { 00539 DC_CMD(); 00540 CS_ENA(); 00541 SPI_WRITE(0xE3); 00542 CS_DIS(); 00543 } 00544 00545 /** 00546 * Set power saving mode. 00547 * 00548 * @param value Value. (0x00:None, 0x12:power saving) 00549 */ 00550 void AitendoOLED::setPowerSavingMode(int value) { 00551 DC_CMD(); 00552 CS_ENA(); 00553 SPI_WRITE(0xB0); 00554 SPI_WRITE(value); 00555 CS_DIS(); 00556 } 00557 00558 /** 00559 * Set phase period. 00560 * 00561 * @param value Value. (Default:0x74) 00562 */ 00563 void AitendoOLED::setPhasePeriod(int value) { 00564 DC_CMD(); 00565 CS_ENA(); 00566 SPI_WRITE(0xB1); 00567 SPI_WRITE(value); 00568 CS_DIS(); 00569 } 00570 00571 /** 00572 * Set display clock divide ratio. 00573 * 00574 * @param value Value. (Default:0x00) 00575 */ 00576 void AitendoOLED::setDisplayClockDivideRatio(int value) { 00577 DC_CMD(); 00578 CS_ENA(); 00579 SPI_WRITE(0xB3); 00580 SPI_WRITE(value); 00581 CS_DIS(); 00582 } 00583 00584 /** 00585 * Set second pre-charge speed for color A. 00586 * 00587 * @param value Value. 00588 */ 00589 void AitendoOLED::setSecondPreChargeSpeedForColorA(int value) { 00590 DC_CMD(); 00591 CS_ENA(); 00592 SPI_WRITE(0x8A); 00593 SPI_WRITE(value); 00594 CS_DIS(); 00595 } 00596 00597 /** 00598 * Set second pre-charge speed for color B. 00599 * 00600 * @param value Value. 00601 */ 00602 void AitendoOLED::setSecondPreChargeSpeedForColorB(int value) { 00603 DC_CMD(); 00604 CS_ENA(); 00605 SPI_WRITE(0x8B); 00606 SPI_WRITE(value); 00607 CS_DIS(); 00608 } 00609 00610 /** 00611 * Set second pre-charge speed for color C. 00612 * 00613 * @param value Value. 00614 */ 00615 void AitendoOLED::setSecondPreChargeSpeedForColorC(int value) { 00616 DC_CMD(); 00617 CS_ENA(); 00618 SPI_WRITE(0x8C); 00619 SPI_WRITE(value); 00620 CS_DIS(); 00621 } 00622 00623 /** 00624 * Set pre charge level for color A. 00625 * 00626 * @param value The value. 00627 */ 00628 void AitendoOLED::setPreChargeLevelForColorA(int value) { 00629 DC_CMD(); 00630 CS_ENA(); 00631 SPI_WRITE(0xBB); 00632 SPI_WRITE(value); 00633 CS_DIS(); 00634 } 00635 00636 /** 00637 * Set pre charge level for color B. 00638 * 00639 * @param value The value. 00640 */ 00641 void AitendoOLED::setPreChargeLevelForColorB(int value) { 00642 DC_CMD(); 00643 CS_ENA(); 00644 SPI_WRITE(0xBC); 00645 SPI_WRITE(value); 00646 CS_DIS(); 00647 } 00648 00649 /** 00650 * Set pre charge level for color C. 00651 * 00652 * @param value The value. 00653 */ 00654 void AitendoOLED::setPreChargeLevelForColorC(int value) { 00655 DC_CMD(); 00656 CS_ENA(); 00657 SPI_WRITE(0xBD); 00658 SPI_WRITE(value); 00659 CS_DIS(); 00660 } 00661 00662 /** 00663 * Set VCOMH. 00664 * 00665 * @param value VCOMH value. (0x00:0.43 * Vref, 0x3F:0x83 * Vref) 00666 */ 00667 void AitendoOLED::setVCOMH(int value) { 00668 DC_CMD(); 00669 CS_ENA(); 00670 SPI_WRITE(0xBE); 00671 SPI_WRITE(value); 00672 CS_DIS(); 00673 } 00674 00675 /** 00676 * Read the status register. 00677 * 00678 * @return the value. (0x80:CommandLock) 00679 */ 00680 uint8_t AitendoOLED::readStatusRegister() { 00681 uint8_t s; 00682 DC_CMD(); 00683 CS_ENA(); 00684 s = SPI_READ(); 00685 CS_DIS(); 00686 return s; 00687 }
Generated on Mon Jul 18 2022 10:37:03 by 1.7.2