Christian Taedcke / Adafruit_GFX

Dependents:   ObdDisplay

Fork of Adafruit_GFX by Neal Horman

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Adafruit_SSD1306.cpp Source File

Adafruit_SSD1306.cpp

00001 /*********************************************************************
00002 This is a library for our Monochrome OLEDs based on SSD1306 drivers
00003 
00004   Pick one up today in the adafruit shop!
00005   ------> http://www.adafruit.com/category/63_98
00006 
00007 These displays use SPI to communicate, 4 or 5 pins are required to  
00008 interface
00009 
00010 Adafruit invests time and resources providing this open source code, 
00011 please support Adafruit and open-source hardware by purchasing 
00012 products from Adafruit!
00013 
00014 Written by Limor Fried/Ladyada  for Adafruit Industries.  
00015 BSD license, check license.txt for more information
00016 All text above, and the splash screen below must be included in any redistribution
00017 *********************************************************************/
00018 
00019 /*
00020  *  Modified by Neal Horman 7/14/2012 for use in LPC1768
00021  */
00022 
00023 #include "mbed.h"
00024 #include "Adafruit_SSD1306.h"
00025 
00026 uint8_t splashScreen[SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH / 8] = { 
00027 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00028 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00029 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00030 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
00031 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00032 0x00, 0x80, 0x80, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00033 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00034 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00035 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00036 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0x00,
00037 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80,
00038 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xFF,
00039 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
00040 0x80, 0xFF, 0xFF, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80,
00041 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x8C, 0x8E, 0x84, 0x00, 0x00, 0x80, 0xF8,
00042 0xF8, 0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00043 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0x80,
00044 0x00, 0xE0, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
00045 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0x01, 0x01,
00046 0x01, 0x01, 0x83, 0xFF, 0xFF, 0x00, 0x00, 0x7C, 0xFE, 0xC7, 0x01, 0x01, 0x01, 0x01, 0x83, 0xFF,
00047 0xFF, 0xFF, 0x00, 0x38, 0xFE, 0xC7, 0x83, 0x01, 0x01, 0x01, 0x83, 0xC7, 0xFF, 0xFF, 0x00, 0x00,
00048 0x01, 0xFF, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x07, 0x01, 0x01, 0x01, 0x00, 0x00, 0x7F, 0xFF,
00049 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF,
00050 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00051 0x03, 0x0F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC7, 0xC7, 0x8F,
00052 0x8F, 0x9F, 0xBF, 0xFF, 0xFF, 0xC3, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC,
00053 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xF0, 0xE0, 0xC0, 0x00, 0x01, 0x03, 0x03, 0x03,
00054 0x03, 0x03, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01,
00055 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03, 0x00, 0x00,
00056 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
00057 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x03,
00058 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00059 #if (SSD1306_LCDHEIGHT == 64)
00060 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x0F,
00061 0x87, 0xC7, 0xF7, 0xFF, 0xFF, 0x1F, 0x1F, 0x3D, 0xFC, 0xF8, 0xF8, 0xF8, 0xF8, 0x7C, 0x7D, 0xFF,
00062 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x0F, 0x07, 0x00, 0x30, 0x30, 0x00, 0x00,
00063 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00064 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00065 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xC0, 0x00,
00066 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
00067 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00068 0x00, 0xC0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x3F, 0x1F,
00069 0x0F, 0x07, 0x1F, 0x7F, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xE0,
00070 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00,
00071 0x00, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x0E, 0xFC, 0xF8, 0x00, 0x00, 0xF0, 0xF8, 0x1C, 0x0E,
00072 0x06, 0x06, 0x06, 0x0C, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFC,
00073 0xFE, 0xFC, 0x00, 0x18, 0x3C, 0x7E, 0x66, 0xE6, 0xCE, 0x84, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0x06,
00074 0x06, 0xFC, 0xFE, 0xFC, 0x0C, 0x06, 0x06, 0x06, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0xC0, 0xF8,
00075 0xFC, 0x4E, 0x46, 0x46, 0x46, 0x4E, 0x7C, 0x78, 0x40, 0x18, 0x3C, 0x76, 0xE6, 0xCE, 0xCC, 0x80,
00076 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00077 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0F, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x1F, 0x0F, 0x03,
00078 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00,
00079 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x03, 0x07, 0x0E, 0x0C,
00080 0x18, 0x18, 0x0C, 0x06, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x0F, 0x0E, 0x0C, 0x18, 0x0C, 0x0F,
00081 0x07, 0x01, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00,
00082 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x07,
00083 0x07, 0x0C, 0x0C, 0x18, 0x1C, 0x0C, 0x06, 0x06, 0x00, 0x04, 0x0E, 0x0C, 0x18, 0x0C, 0x0F, 0x07,
00084 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00085 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00086 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00087 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00088 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00089 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00090 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00091 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00092 #endif
00093 };
00094 
00095 Adafruit_SSD1306::Adafruit_SSD1306(SPI &spi, PinName DC, PinName RST, PinName CS)
00096     : Adafruit_GFX(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT)
00097     , rst(RST,false), cs(CS,true), dc(DC,false), mspi(spi)
00098 {
00099     memcpy(buffer,splashScreen,sizeof(buffer));
00100     begin();
00101     display();
00102 };
00103 
00104 void Adafruit_SSD1306::begin(uint8_t vccstate)
00105 {
00106     rst = 1;
00107     // VDD (3.3V) goes high at start, lets just chill for a ms
00108     wait_ms(1);
00109     // bring reset low
00110     rst = 0;
00111     // wait 10ms
00112     wait_ms(10);
00113     // bring out of reset
00114     rst = 1;
00115     // turn on VCC (9V?)
00116     
00117 #if defined SSD1306_128_32
00118     uint8_t setmultiplex = 0x1F;
00119     uint8_t setcompins = 0x02;
00120     uint8_t setcontrast = 0x8F;
00121 #elif defined SSD1306_128_64
00122     uint8_t setmultiplex = 0x3F;
00123     uint8_t setcompins = 0x12;
00124     uint8_t setcontrast = (vccstate == SSD1306_EXTERNALVCC) ? 0x9F : 0xCF;
00125 #else
00126 #error "Display dimensions must be defined"
00127 #endif
00128 
00129     ssd1306_command(SSD1306_DISPLAYOFF);                    // 0xAE
00130     ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV);            // 0xD5
00131     ssd1306_command(0x80);                                  // the suggested ratio 0x80
00132     ssd1306_command(SSD1306_SETMULTIPLEX);                  // 0xA8
00133     ssd1306_command(setmultiplex);
00134     ssd1306_command(SSD1306_SETDISPLAYOFFSET);              // 0xD3
00135     ssd1306_command(0x0);                                   // no offset
00136     ssd1306_command(SSD1306_SETSTARTLINE | 0x0);            // line #0
00137     ssd1306_command(SSD1306_CHARGEPUMP);                    // 0x8D
00138     if (vccstate == SSD1306_EXTERNALVCC) 
00139     { ssd1306_command(0x10); }
00140     else 
00141     { ssd1306_command(0x14); }
00142     ssd1306_command(SSD1306_MEMORYMODE);                    // 0x20
00143     ssd1306_command(0x00);                                  // 0x0 act like ks0108
00144     ssd1306_command(SSD1306_SEGREMAP | 0x1);
00145     ssd1306_command(SSD1306_COMSCANDEC);
00146     ssd1306_command(SSD1306_SETCOMPINS);                    // 0xDA
00147     ssd1306_command(setcompins);
00148     ssd1306_command(SSD1306_SETCONTRAST);                   // 0x81
00149     ssd1306_command(setcontrast);
00150     ssd1306_command(SSD1306_SETPRECHARGE);                  // 0xd9
00151     if (vccstate == SSD1306_EXTERNALVCC) 
00152     { ssd1306_command(0x22); }
00153     else 
00154     { ssd1306_command(0xF1); }
00155     ssd1306_command(SSD1306_SETVCOMDETECT);                 // 0xDB
00156     ssd1306_command(0x40);
00157     ssd1306_command(SSD1306_DISPLAYALLON_RESUME);           // 0xA4
00158     ssd1306_command(SSD1306_NORMALDISPLAY);                 // 0xA6
00159     
00160     ssd1306_command(SSD1306_DISPLAYON);//--turn on oled panel
00161 }
00162 
00163 // the most basic function, set a single pixel
00164 void Adafruit_SSD1306::drawPixel(int16_t x, int16_t y, uint16_t color)
00165 {
00166     if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
00167         return;
00168     
00169     // check rotation, move pixel around if necessary
00170     switch (getRotation())
00171     {
00172         case 1:
00173             swap(x, y);
00174             x = _rawWidth - x - 1;
00175             break;
00176         case 2:
00177             x = _rawWidth - x - 1;
00178             y = _rawHeight - y - 1;
00179             break;
00180         case 3:
00181             swap(x, y);
00182             y = _rawHeight - y - 1;
00183             break;
00184     }  
00185     
00186     // x is which column
00187     if (color == WHITE) 
00188         buffer[x+ (y/8)*SSD1306_LCDWIDTH] |= _BV((y%8));  
00189     else
00190         buffer[x+ (y/8)*SSD1306_LCDWIDTH] &= ~_BV((y%8)); 
00191 }
00192 
00193 void Adafruit_SSD1306::invertDisplay(bool i)
00194 {
00195     if (i)
00196         ssd1306_command(SSD1306_INVERTDISPLAY);
00197     else
00198         ssd1306_command(SSD1306_NORMALDISPLAY);
00199 }
00200 
00201 void Adafruit_SSD1306::ssd1306_command(uint8_t c)
00202 {
00203     cs = 1;
00204     dc = 0;
00205     cs = 0;
00206     mspi.write(c);
00207     cs = 1;
00208 }
00209 
00210 void Adafruit_SSD1306::ssd1306_data(uint8_t c)
00211 {
00212     cs = 1;
00213     dc = 1;
00214     cs = 0;
00215     mspi.write(c);
00216     cs = 1;
00217 }
00218 
00219 void Adafruit_SSD1306::display(void)
00220 {
00221     ssd1306_command(SSD1306_SETLOWCOLUMN | 0x0);  // low col = 0
00222     ssd1306_command(SSD1306_SETHIGHCOLUMN | 0x0);  // hi col = 0
00223     ssd1306_command(SSD1306_SETSTARTLINE | 0x0); // line #0
00224 
00225     cs = 1;
00226     dc = 1;
00227     cs = 0;
00228     
00229     for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++)
00230         mspi.write(buffer[i]);
00231 
00232     // i wonder why we have to do this (check datasheet)
00233     if (SSD1306_LCDHEIGHT == 32)
00234     {
00235         for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++)
00236             mspi.write(0);
00237     }
00238     
00239     cs = 1;
00240 }
00241 
00242 // clear everything
00243 void Adafruit_SSD1306::clearDisplay(void)
00244 {
00245     memset(buffer,0,sizeof(buffer));
00246 }