Aitendo OLED device driver library.

Dependents:   AitendoOLED_TestProgram

Revision:
0:5062b7730235
Child:
1:4b819d5ea905
diff -r 000000000000 -r 5062b7730235 AitendoOLED.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AitendoOLED.cpp	Sun Dec 19 06:20:01 2010 +0000
@@ -0,0 +1,675 @@
+/**
+ * =============================================================================
+ * Aitendo OLED device driver library. (Version 0.0.1)
+ *
+ * [The product]
+ * OLED-2P-095BWNN-SPI : http://www.aitendo.co.jp/product/2099
+ * ALO-095BWNN-J9      : http://www.aitendo.co.jp/product/1449
+ *
+ * [References]
+ * http://serdisplib.sourceforge.net/ser/doc/Treiber_IC-SSD1332_OLED_96x64_COLOR.pdf
+ * =============================================================================
+ * Copyright (c) 2010 Shinichiro Nakamura (CuBeatSystems)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ * =============================================================================
+ */
+#include "AitendoOLED.h"
+
+#define RES_ENA()       io_res = 0
+#define RES_DIS()       io_res = 1
+#define CS_ENA()        io_cs = 0
+#define CS_DIS()        io_cs = 1
+#define DC_CMD()        io_dc = 0
+#define DC_DAT()        io_dc = 1
+#define SPI_WRITE(a)    io_spi.write((a))
+#define SPI_READ()      io_spi.write(0x00)
+#define swap(a,b) {int c=a;a=b;b=c;}
+#define waitDone() while(1) {uint8_t s = readStatusRegister();if ((s & 0x80) != 0) {break;}}
+
+/**
+ * Create.
+ *
+ * @param pin_mosi MOSI.
+ * @param pin miso MISO.
+ * @param pin_sclk SCLK.
+ * @param pin_res RES.
+ * @param pin_cs CS.
+ * @param pin_dc DC.
+ */
+AitendoOLED::AitendoOLED(
+    PinName pin_mosi,
+    PinName pin_miso,
+    PinName pin_sclk,
+    PinName pin_res,
+    PinName pin_cs,
+    PinName pin_dc)
+        :
+        io_spi(pin_mosi, pin_miso, pin_sclk),
+        io_res(pin_res),
+        io_cs(pin_cs),
+        io_dc(pin_dc) {
+    io_spi.format(8, 0);
+#if 0
+    io_spi.frequency(4000000);
+#else
+    io_spi.frequency(40000000);
+#endif
+    reset();
+}
+
+/**
+ * Dispose.
+ */
+AitendoOLED::~AitendoOLED() {
+}
+
+/**
+ * Draw pixel.
+ *
+ * @param x X.
+ * @param y Y.
+ * @param c Color.
+ */
+void AitendoOLED::drawPixel(int x, int y, Color c) {
+    setColumnAddress(x, x);
+    setRowAddress(y, y);
+    c.b = c.b >> 3;
+    c.g = c.g >> 2;
+    c.r = c.r >> 3;
+    writeData((((c.b << 3) & 0xF8) | ((c.g >> 3) & 0x07)));
+    writeData((((c.g << 5) & 0xE0) | ((c.r >> 0) & 0x1F)));
+}
+
+/**
+ * Draw line.
+ *
+ * @param x1 X1.
+ * @param y1 Y1.
+ * @param x2 X2.
+ * @param y2 Y2.
+ * @param c Color.
+ */
+void AitendoOLED::drawLine(int x1, int y1, int x2, int y2, Color c) {
+#if 0
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0x21);
+    SPI_WRITE(x1);
+    SPI_WRITE(y1);
+    SPI_WRITE(x2);
+    SPI_WRITE(y2);
+    SPI_WRITE(c.b);
+    SPI_WRITE(c.g);
+    SPI_WRITE(c.r);
+    CS_DIS();
+    waitDone();
+#else
+    /*
+     * Bresenham's line algorithm
+     */
+    bool steep = abs(y2 - y1) > abs(x2 - x1);
+    if (steep) {
+        swap(x1, y1);
+        swap(x2, y2);
+    }
+    if (x1 > x2) {
+        swap(x1, x2);
+        swap(y1, y2);
+    }
+    int deltax = x2 - x1;
+    int deltay = abs(y2 - y1);
+    int error = deltax / 2;
+    int ystep;
+    int y = y1;
+    if (y1 < y2) {
+        ystep = 1;
+    } else {
+        ystep = -1;
+    }
+    for (int x = x1; x <= x2; x++) {
+        if (steep) {
+            drawPixel(y, x, c);
+        } else {
+            drawPixel(x, y, c);
+        }
+        error = error - deltay;
+        if (error < 0) {
+            y = y + ystep;
+            error = error + deltax;
+        }
+    }
+#endif
+}
+
+/**
+ * Fill box.
+ *
+ * @param x1 X1.
+ * @param y1 Y1.
+ * @param x2 X2.
+ * @param y2 Y2.
+ * @param c1 Color1.
+ * @param c2 Color2.
+ */
+void AitendoOLED::fillBox(int x1, int y1, int x2, int y2, Color c1, Color c2) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0x22);
+    SPI_WRITE(x1);
+    SPI_WRITE(y1);
+    SPI_WRITE(x2);
+    SPI_WRITE(y2);
+    SPI_WRITE(c1.b);
+    SPI_WRITE(c1.g);
+    SPI_WRITE(c1.r);
+    SPI_WRITE(c2.b);
+    SPI_WRITE(c2.g);
+    SPI_WRITE(c2.r);
+    CS_DIS();
+    waitDone();
+}
+
+/**
+ * Copy.
+ *
+ * @param x1 X1.
+ * @param y1 Y1.
+ * @param x2 X2.
+ * @param y2 Y2.
+ * @param nx X of the destination.
+ * @param ny Y of the destination.
+ */
+void AitendoOLED::copy(int x1, int y1, int x2, int y2, int nx, int ny) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0x23);
+    SPI_WRITE(x1);
+    SPI_WRITE(y1);
+    SPI_WRITE(x2);
+    SPI_WRITE(y2);
+    SPI_WRITE(nx);
+    SPI_WRITE(ny);
+    CS_DIS();
+    waitDone();
+}
+
+/**
+ * Darker.
+ *
+ * @param x1 X1.
+ * @param y1 Y1.
+ * @param x2 X2.
+ * @param y2 Y2.
+ */
+void AitendoOLED::darker(int x1, int y1, int x2, int y2) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0x24);
+    SPI_WRITE(x1);
+    SPI_WRITE(y1);
+    SPI_WRITE(x2);
+    SPI_WRITE(y2);
+    CS_DIS();
+    waitDone();
+}
+
+/**
+ * Clear.
+ *
+ * @param x1 X1.
+ * @param y1 Y1.
+ * @param x2 X2.
+ * @param y2 Y2.
+ */
+void AitendoOLED::clear(int x1, int y1, int x2, int y2) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0x25);
+    SPI_WRITE(x1);
+    SPI_WRITE(y1);
+    SPI_WRITE(x2);
+    SPI_WRITE(y2);
+    CS_DIS();
+    waitDone();
+}
+
+/**
+ * Reset.
+ */
+void AitendoOLED::reset() {
+
+    RES_ENA();
+    wait_ms(200);
+    RES_DIS();
+    wait_ms(200);
+
+    setDisplayOnOff(false);
+    setRowAddress(0, 63);
+    setColumnAddress(0, 95);
+    setRemapAndDataFormat(0x70);
+    setDisplayStartLine(0);
+    setDisplayOffset(0);
+    setDisplayMode(AitendoOLED::NormalDisplay);
+    setMultiplexRatio(0x3f);
+    setMasterCurrentControl(0x8f);
+    setPowerSavingMode(0x00);
+    setPhasePeriod(0x74);
+    setDisplayClockDivideRatio(0xD0);
+    setSecondPreChargeSpeedForColorA(0x80);
+    setSecondPreChargeSpeedForColorB(0x80);
+    setSecondPreChargeSpeedForColorC(0x80);
+    setPreChargeLevelForColorA(0x3F);
+    setPreChargeLevelForColorB(0x3F);
+    setPreChargeLevelForColorC(0x3F);
+    setVCOMH(0x3E);
+    setMasterCurrentControl(0x0F);
+    // A:Blue, B:Green, C:Red
+    setContrastForColorA(0x80);
+    setContrastForColorB(0x80);
+    setContrastForColorC(0x80);
+    setMode(true, false);
+    setDisplayOnOff(true);
+}
+
+/**
+ * Write data.
+ *
+ * @param data Data.
+ */
+void AitendoOLED::writeData(uint8_t data) {
+    DC_DAT();
+    CS_ENA();
+    SPI_WRITE(data);
+    CS_DIS();
+}
+
+/**
+ * Set mode.
+ *
+ * @param fillrect Fill the rectangle.
+ * @param revcopy Reverse copy.
+ */
+void AitendoOLED::setMode(bool fillrect, bool revcopy) {
+    uint8_t val = 0x00;
+    if (fillrect) {
+        val |= 1 << 0;
+    }
+    if (revcopy) {
+        val |= 1 << 4;
+    }
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0x26);
+    SPI_WRITE(val);
+    CS_DIS();
+}
+
+/**
+ * Set column address.
+ *
+ * @param start Start address. (0-95)
+ * @param end End address. (0-95)
+ */
+void AitendoOLED::setColumnAddress(int start, int end) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0x15);
+    SPI_WRITE(start);
+    SPI_WRITE(end);
+    CS_DIS();
+}
+
+/**
+ * Set row address.
+ *
+ * @param start Start address. (0-63)
+ * @param end End address. (0-63)
+ */
+void AitendoOLED::setRowAddress(int start, int end) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0x75);
+    SPI_WRITE(start);
+    SPI_WRITE(end);
+    CS_DIS();
+}
+
+/**
+ * Set contrast for Color A.
+ *
+ * @param contrast Contrast. (Default:0x80)
+ */
+void AitendoOLED::setContrastForColorA(int contrast) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0x81);
+    SPI_WRITE(contrast);
+    CS_DIS();
+}
+
+/**
+ * Set contrast for Color B.
+ *
+ * @param contrast Contrast. (Default:0x80)
+ */
+void AitendoOLED::setContrastForColorB(int contrast) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0x82);
+    SPI_WRITE(contrast);
+    CS_DIS();
+}
+
+/**
+ * Set contrast for Color C.
+ *
+ * @param contrast Contrast. (Default:0x80)
+ */
+void AitendoOLED::setContrastForColorC(int contrast) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0x83);
+    SPI_WRITE(contrast);
+    CS_DIS();
+}
+
+/**
+ * Set master current control value.
+ *
+ * @param current Current value. (0x00-0x0F)
+ */
+void AitendoOLED::setMasterCurrentControl(int current) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0x87);
+    SPI_WRITE(current);
+    CS_DIS();
+}
+
+/**
+ * Set remapping mode and the data format.
+ *
+ * @param mode See the document.
+ */
+void AitendoOLED::setRemapAndDataFormat(int mode) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0xA0);
+    SPI_WRITE(mode);
+    CS_DIS();
+}
+
+/**
+ * Set display start line.
+ *
+ * @param line Start line number. (0-63)
+ */
+void AitendoOLED::setDisplayStartLine(int line) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0xA1);
+    SPI_WRITE(line);
+    CS_DIS();
+}
+
+/**
+ * Set display offset line.
+ *
+ * @param offset Offset line number. (0-63)
+ */
+void AitendoOLED::setDisplayOffset(int offset) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0xA2);
+    SPI_WRITE(offset);
+    CS_DIS();
+}
+
+/**
+ * Set display mode.
+ *
+ * @param mode Display mode.
+ */
+void AitendoOLED::setDisplayMode(DisplayMode mode) {
+    int val = 0;
+    switch (mode) {
+        case NormalDisplay:
+            val = 0xA4;
+            break;
+        case EntireDisplayOn:
+            val = 0xA5;
+            break;
+        case EntireDisplayOff:
+            val = 0xA6;
+            break;
+        case InverseDisplay:
+            val = 0xA7;
+            break;
+        default:
+            break;
+    }
+    if (val != 0) {
+        DC_CMD();
+        CS_ENA();
+        SPI_WRITE(val);
+        CS_DIS();
+    }
+}
+
+/**
+ * Set multiplex ratio.
+ *
+ * @param ratio Ratio.
+ */
+void AitendoOLED::setMultiplexRatio(int ratio) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0xA8);
+    SPI_WRITE(ratio);
+    CS_DIS();
+}
+
+/**
+ * Set display on/off.
+ *
+ * @param on On.
+ */
+void AitendoOLED::setDisplayOnOff(bool on) {
+    if (on) {
+        DC_CMD();
+        CS_ENA();
+        SPI_WRITE(0xAF);
+        CS_DIS();
+    } else {
+        DC_CMD();
+        CS_ENA();
+        SPI_WRITE(0xAE);
+        CS_DIS();
+    }
+}
+
+/**
+ * Set gray scale table.
+ *
+ * @param p A pointer to the look up table.
+ */
+void AitendoOLED::setGrayScaleTable(gray_scale_table_t *p) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0xB8);
+    for (int i = 0; i < 32; i++) {
+        SPI_WRITE(p->data[i]);
+    }
+    CS_DIS();
+}
+
+/**
+ * NOP.
+ */
+void AitendoOLED::nop() {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0xE3);
+    CS_DIS();
+}
+
+/**
+ * Set power saving mode.
+ *
+ * @param value Value. (0x00:None, 0x12:power saving)
+ */
+void AitendoOLED::setPowerSavingMode(int value) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0xB0);
+    SPI_WRITE(value);
+    CS_DIS();
+}
+
+/**
+ * Set phase period.
+ *
+ * @param value Value. (Default:0x74)
+ */
+void AitendoOLED::setPhasePeriod(int value) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0xB1);
+    SPI_WRITE(value);
+    CS_DIS();
+}
+
+/**
+ * Set display clock divide ratio.
+ *
+ * @param value Value. (Default:0x00)
+ */
+void AitendoOLED::setDisplayClockDivideRatio(int value) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0xB3);
+    SPI_WRITE(value);
+    CS_DIS();
+}
+
+/**
+ * Set second pre-charge speed for color A.
+ *
+ * @param value Value.
+ */
+void AitendoOLED::setSecondPreChargeSpeedForColorA(int value) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0x8A);
+    SPI_WRITE(value);
+    CS_DIS();
+}
+
+/**
+ * Set second pre-charge speed for color B.
+ *
+ * @param value Value.
+ */
+void AitendoOLED::setSecondPreChargeSpeedForColorB(int value) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0x8B);
+    SPI_WRITE(value);
+    CS_DIS();
+}
+
+/**
+ * Set second pre-charge speed for color C.
+ *
+ * @param value Value.
+ */
+void AitendoOLED::setSecondPreChargeSpeedForColorC(int value) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0x8C);
+    SPI_WRITE(value);
+    CS_DIS();
+}
+
+/**
+ * Set pre charge level for color A.
+ *
+ * @param value The value.
+ */
+void AitendoOLED::setPreChargeLevelForColorA(int value) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0xBB);
+    SPI_WRITE(value);
+    CS_DIS();
+}
+
+/**
+ * Set pre charge level for color B.
+ *
+ * @param value The value.
+ */
+void AitendoOLED::setPreChargeLevelForColorB(int value) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0xBC);
+    SPI_WRITE(value);
+    CS_DIS();
+}
+
+/**
+ * Set pre charge level for color C.
+ *
+ * @param value The value.
+ */
+void AitendoOLED::setPreChargeLevelForColorC(int value) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0xBD);
+    SPI_WRITE(value);
+    CS_DIS();
+}
+
+/**
+ * Set VCOMH.
+ *
+ * @param value VCOMH value. (0x00:0.43 * Vref, 0x3F:0x83 * Vref)
+ */
+void AitendoOLED::setVCOMH(int value) {
+    DC_CMD();
+    CS_ENA();
+    SPI_WRITE(0xBE);
+    SPI_WRITE(value);
+    CS_DIS();
+}
+
+/**
+ * Read the status register.
+ *
+ * @return the value.
+ */
+uint8_t AitendoOLED::readStatusRegister() {
+    uint8_t s;
+    DC_CMD();
+    CS_ENA();
+    s = SPI_READ();
+    CS_DIS();
+    return s;
+}