Aitendo OLED device driver library.
Dependents: AitendoOLED_TestProgram
Diff: AitendoOLED.cpp
- Revision:
- 0:5062b7730235
- Child:
- 1:4b819d5ea905
--- /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; +}