A simple yet powerful library for controlling graphical displays. Multiple display controllers are supported using inheritance.

Dependents:   mbed_rifletool Hexi_Bubble_Game Hexi_Catch-the-dot_Game Hexi_Acceleromagnetic_Synth

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SSD1306_I2C.cpp Source File

SSD1306_I2C.cpp

00001 /* NeatGUI Library
00002  * Copyright (c) 2013 Neil Thiessen
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "SSD1306_I2C.h"
00018 
00019 SSD1306_I2C::SSD1306_I2C(PinName sda, PinName scl, Address addr) : Display(128, 64), m_I2C(sda, scl), m_ADDR((int)addr)
00020 {
00021     //Set the I2C frequency to 400kHz
00022     m_I2C.frequency(400000);
00023 }
00024 
00025 bool SSD1306_I2C::open()
00026 {
00027     //Probe for the SSD1306 using a Zero Length Transfer
00028     if (!m_I2C.write(m_ADDR, NULL, 0)) {
00029         //Init sequence for 128x64 OLED module
00030         writeCommand(CMD_DISPLAYOFF);
00031         writeCommand(CMD_SETDISPLAYCLOCKDIV);
00032         writeCommand(0x80);
00033         writeCommand(CMD_SETMULTIPLEX);
00034         writeCommand(0x3F);
00035         writeCommand(CMD_SETDISPLAYOFFSET);
00036         writeCommand(0x0);
00037         writeCommand(CMD_SETSTARTLINE | 0x0);
00038         writeCommand(CMD_CHARGEPUMP);
00039         writeCommand(CMD_CHARGEPUMPON);
00040         writeCommand(CMD_MEMORYMODE);
00041         writeCommand(0x00);
00042         writeCommand(CMD_SEGREMAP | 0x1);
00043         writeCommand(CMD_COMSCANDEC);
00044         writeCommand(CMD_SETCOMPINS);
00045         writeCommand(0x12);
00046         writeCommand(CMD_SETCONTRAST);
00047         writeCommand(0xCF);
00048         writeCommand(CMD_SETPRECHARGE);
00049         writeCommand(0xF1);
00050         writeCommand(CMD_SETVCOMDETECT);
00051         writeCommand(0x40);
00052         writeCommand(CMD_DISPLAYALLON_RESUME);
00053         writeCommand(CMD_NORMALDISPLAY);
00054 
00055         //Return success
00056         return true;
00057     } else {
00058         //Return failure
00059         return false;
00060     }
00061 }
00062 
00063 void SSD1306_I2C::flush()
00064 {
00065     //Select low col 0, hi col 0, line 0
00066     writeCommand(CMD_SETLOWCOLUMN | 0x0);
00067     writeCommand(CMD_SETHIGHCOLUMN | 0x0);
00068     writeCommand(CMD_SETSTARTLINE | 0x0);
00069 
00070     //Make sure the first byte in the buffer is the control byte
00071     m_Buffer[0] = CONTROL_DATA;
00072 
00073     //Write the buffer
00074     m_I2C.write(m_ADDR, m_Buffer, 1025);
00075 }
00076 
00077 Display::State SSD1306_I2C::state()
00078 {
00079     //Return the base class's state
00080     return Display::state();
00081 }
00082 
00083 void SSD1306_I2C::state(State s)
00084 {
00085     //Check what the requested state is
00086     if (s == Display::DISPLAY_ON) {
00087         //Turn the display on
00088         writeCommand(CMD_DISPLAYON);
00089     } else if (s == Display::DISPLAY_OFF) {
00090         //Turn the display off
00091         writeCommand(CMD_DISPLAYOFF);
00092     }
00093 
00094     //Update the base class
00095     Display::state(s);
00096 }
00097 
00098 void SSD1306_I2C::drawPixel(int x, int y, unsigned int c)
00099 {
00100     //Range check the pixel
00101     if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
00102         return;
00103 
00104     //Make sure the color is fully opaque
00105     if ((c >> 24) != 255)
00106         return;
00107 
00108     //Determine the pixel byte index
00109     unsigned short byteIndex = x + (y / 8) * width();
00110 
00111     //HACK: Fix the whole 1025 byte i2c buffer thing
00112     byteIndex++;
00113 
00114     //Set or clear the pixel
00115     if ((c & 0x00FFFFFF) > 0)
00116         m_Buffer[byteIndex] |= (1 << (y % 8));
00117     else
00118         m_Buffer[byteIndex] &= ~(1 << (y % 8));
00119 }
00120 
00121 void SSD1306_I2C::writeCommand(char command)
00122 {
00123     //Create a temporary buffer
00124     char buff[2];
00125 
00126     //Load the control byte and 8-bit command
00127     buff[0] = CONTROL_COMMAND;
00128     buff[1] = command;
00129 
00130     //Write the command
00131     m_I2C.write(m_ADDR, buff, 2);
00132 }
00133 
00134 void SSD1306_I2C::writeData(char data)
00135 {
00136     //Create a temporary buffer
00137     char buff[2];
00138 
00139     //Load the control byte and 8-bit data
00140     buff[0] = CONTROL_DATA;
00141     buff[1] = data;
00142 
00143     //Write the data
00144     m_I2C.write(m_ADDR, buff, 2);
00145 }