Aitendo OLED device driver library.

Dependents:   AitendoOLED_TestProgram

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers AitendoOLED.cpp Source File

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 }