yup

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 0x70, 0xFC, 0xFE, 0xFC, 0xF1, 0x07, 0xFF, 0xFF, 0xFE, 0xFC, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00,
00031 0x80, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0xF0,
00032 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 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, 0x80, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00037 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFE, 0xFF, 0xFE, 0xF8, 0xF0,
00038 0xF0, 0xE1, 0xE3, 0x47, 0x47, 0x00, 0x07, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x7C, 0xFE, 0xFF,
00039 0xFF, 0xFF, 0xE7, 0xC3, 0x83, 0x83, 0x83, 0x03, 0x03, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF,
00040 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xE0, 0xE0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xC0, 0x00, 0x00,
00041 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xE0, 0xE0, 0xE0, 0x70, 0x70, 0x70, 0xE0, 0xE0, 0xE0, 0xC0,
00042 0xC0, 0x80, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0,
00043 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00044 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
00045 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF, 0x7F, 0x7F, 0x3F, 0x1F, 0x1F, 0x0F, 0x87, 0x87, 0xC3,
00046 0xC1, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
00047 0x03, 0x07, 0x07, 0x0F, 0x0F, 0x0F, 0x1F, 0xFF, 0xFF, 0xFE, 0xFC, 0xF0, 0x00, 0x00, 0x00, 0xFF,
00048 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
00049 0x00, 0x00, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xFF, 0xFF,
00050 0xFF, 0xFF, 0x7C, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
00051 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00052 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0xE0, 0xF0, 0xF8, 0x78, 0x3C, 0x3E, 0x1F, 0x1F, 0x0F,
00053 0x8F, 0x87, 0x03, 0x03, 0x01, 0x00, 0x00, 0xF8, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
00054 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0F, 0x1F,
00055 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x0F, 0x0F, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x1F,
00056 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00,
00057 0x00, 0x00, 0x00, 0x01, 0x07, 0x07, 0x0F, 0x0F, 0x1F, 0x1E, 0x1E, 0x1E, 0x1F, 0x0F, 0x0F, 0x07,
00058 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x0F, 0x1F, 0x1F, 0x1E, 0x1E, 0x1E, 0x1E,
00059 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0xC0, 0x60, 0x70, 0x30, 0x38, 0x18, 0x1C,
00060 0x0E, 0x8E, 0x07, 0x07, 0x03, 0x03, 0x01, 0xF1, 0xF0, 0xF8, 0xF8, 0xFC, 0xFC, 0xFE, 0xFF, 0xFF,
00061 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00062 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0,
00063 0xE0, 0x60, 0x30, 0x30, 0x30, 0x30, 0x30, 0x70, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0,
00064 0xC0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00065 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xE0, 0x00, 0x00, 0x00,
00066 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00067 0x04, 0x04, 0x02, 0x02, 0x01, 0x01, 0x01, 0xF0, 0xF8, 0xF8, 0xF8, 0xFC, 0xFC, 0xFE, 0xFE, 0xFF,
00068 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00069 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00070 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x3F, 0x7F,
00071 0x78, 0xF0, 0xE0, 0xC0, 0xC0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0xFF,
00072 0xFF, 0xFF, 0x0C, 0x0C, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x28, 0x18, 0x18, 0x0C, 0x0C, 0x0C, 0x0C,
00073 0x18, 0x38, 0xF8, 0xF0, 0xC0, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0xFF, 0xFF, 0xFF, 0x0C, 0x0C, 0x0C,
00074 0x0C, 0x00, 0x00, 0x00, 0xE0, 0xF0, 0xF8, 0x1C, 0x0C, 0x0C, 0x0C, 0x1C, 0x18, 0x00, 0x00, 0x00,
00075 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x7F,
00076 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00077 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00078 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
00079 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x87, 0xFF, 0xFE, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
00080 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xF0, 0xF8, 0x1C, 0x0C, 0x06, 0x06, 0x06,
00081 0x06, 0x86, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
00082 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x07, 0x0F, 0x0E, 0x1C, 0xFC, 0xF8, 0xF0, 0x00, 0x00,
00083 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00084 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, 0x07, 0x07,
00085 0x07, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x7F, 0x7F, 0x7F,
00086 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x07,
00087 0x06, 0x06, 0x06, 0x06, 0x06, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
00088 0x03, 0x07, 0x07, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x03, 0x03, 0x07, 0x06, 0x06, 0x06, 0x03,
00089 0x03, 0x01, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x06, 0x06,
00090 0x06, 0x00, 0x00, 0x00, 0x03, 0x03, 0x06, 0x06, 0x06, 0x07, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00
00091 };
00092 
00093 Adafruit_SSD1306::Adafruit_SSD1306(SPI &spi, PinName DC, PinName RST, PinName CS)
00094     : Adafruit_GFX(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT)
00095     , rst(RST,false), cs(CS,true), dc(DC,false), mspi(spi)
00096 {
00097     memcpy(buffer,splashScreen,sizeof(buffer));
00098     begin();
00099 };
00100 
00101 void Adafruit_SSD1306::begin(uint8_t vccstate)
00102 {
00103     rst = 1;
00104     // VDD (3.3V) goes high at start, lets just chill for a ms
00105     wait_ms(1);
00106     // bring reset low
00107     rst = 0;
00108     // wait 10ms
00109     wait_ms(10);
00110     // bring out of reset
00111     rst = 1;
00112     // turn on VCC (9V?)
00113     
00114 #if defined SSD1306_128_32
00115     // Init sequence for 128x32 OLED module
00116     ssd1306_command(SSD1306_DISPLAYOFF);                    // 0xAE
00117     ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV);            // 0xD5
00118     ssd1306_command(0x80);                                  // the suggested ratio 0x80
00119     ssd1306_command(SSD1306_SETMULTIPLEX);                  // 0xA8
00120     ssd1306_command(0x1F);
00121     ssd1306_command(SSD1306_SETDISPLAYOFFSET);              // 0xD3
00122     ssd1306_command(0x0);                                   // no offset
00123     ssd1306_command(SSD1306_SETSTARTLINE | 0x0);            // line #0
00124     ssd1306_command(SSD1306_CHARGEPUMP);                    // 0x8D
00125     if (vccstate == SSD1306_EXTERNALVCC) 
00126     { ssd1306_command(0x10); }
00127     else 
00128     { ssd1306_command(0x14); }
00129     ssd1306_command(SSD1306_MEMORYMODE);                    // 0x20
00130     ssd1306_command(0x00);                                  // 0x0 act like ks0108
00131     ssd1306_command(SSD1306_SEGREMAP | 0x1);
00132     ssd1306_command(SSD1306_COMSCANDEC);
00133     ssd1306_command(SSD1306_SETCOMPINS);                    // 0xDA
00134     ssd1306_command(0x02);
00135     ssd1306_command(SSD1306_SETCONTRAST);                   // 0x81
00136     ssd1306_command(0x8F);
00137     ssd1306_command(SSD1306_SETPRECHARGE);                  // 0xd9
00138     if (vccstate == SSD1306_EXTERNALVCC) 
00139     { ssd1306_command(0x22); }
00140     else 
00141     { ssd1306_command(0xF1); }
00142     ssd1306_command(SSD1306_SETVCOMDETECT);                 // 0xDB
00143     ssd1306_command(0x40);
00144     ssd1306_command(SSD1306_DISPLAYALLON_RESUME);           // 0xA4
00145     ssd1306_command(SSD1306_NORMALDISPLAY);                 // 0xA6
00146 #endif
00147     
00148 #if defined SSD1306_128_64
00149     // Init sequence for 128x64 OLED module
00150     ssd1306_command(SSD1306_DISPLAYOFF);                    // 0xAE
00151     ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV);            // 0xD5
00152     ssd1306_command(0x80);                                  // the suggested ratio 0x80
00153     ssd1306_command(SSD1306_SETMULTIPLEX);                  // 0xA8
00154     ssd1306_command(0x3F);
00155     ssd1306_command(SSD1306_SETDISPLAYOFFSET);              // 0xD3
00156     ssd1306_command(0x0);                                   // no offset
00157     ssd1306_command(SSD1306_SETSTARTLINE | 0x0);            // line #0
00158     ssd1306_command(SSD1306_CHARGEPUMP);                    // 0x8D
00159     if (vccstate == SSD1306_EXTERNALVCC) 
00160     { ssd1306_command(0x10); }
00161     else 
00162     { ssd1306_command(0x14); }
00163     ssd1306_command(SSD1306_MEMORYMODE);                    // 0x20
00164     ssd1306_command(0x00);                                  // 0x0 act like ks0108
00165     ssd1306_command(SSD1306_SEGREMAP | 0x1);
00166     ssd1306_command(SSD1306_COMSCANDEC);
00167     ssd1306_command(SSD1306_SETCOMPINS);                    // 0xDA
00168     ssd1306_command(0x12);
00169     ssd1306_command(SSD1306_SETCONTRAST);                   // 0x81
00170     if (vccstate == SSD1306_EXTERNALVCC) 
00171     { ssd1306_command(0x9F); }                              // Originally 0x9F
00172     else 
00173     { ssd1306_command(0xCF); }                              // Originally 0xCF
00174     ssd1306_command(SSD1306_SETPRECHARGE);                  // 0xd9
00175     if (vccstate == SSD1306_EXTERNALVCC) 
00176     { ssd1306_command(0x22); }
00177     else 
00178     { ssd1306_command(0xF1); }
00179     ssd1306_command(SSD1306_SETVCOMDETECT);                 // 0xDB
00180     ssd1306_command(0x40);
00181     ssd1306_command(SSD1306_DISPLAYALLON_RESUME);           // 0xA4
00182     ssd1306_command(SSD1306_NORMALDISPLAY);                 // 0xA6
00183 #endif
00184     
00185     ssd1306_command(SSD1306_DISPLAYON);//--turn on oled panel
00186 }
00187 
00188 // the most basic function, set a single pixel
00189 void Adafruit_SSD1306::drawPixel(int16_t x, int16_t y, uint16_t color)
00190 {
00191     if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
00192         return;
00193     
00194     // check rotation, move pixel around if necessary
00195     switch (getRotation())
00196     {
00197         case 1:
00198             swap(x, y);
00199             x = _rawWidth - x - 1;
00200             break;
00201         case 2:
00202             x = _rawWidth - x - 1;
00203             y = _rawHeight - y - 1;
00204             break;
00205         case 3:
00206             swap(x, y);
00207             y = _rawHeight - y - 1;
00208             break;
00209     }  
00210     
00211     // x is which column
00212     if (color == WHITE) 
00213         buffer[x+ (y/8)*SSD1306_LCDWIDTH] |= _BV((y%8));  
00214     else
00215         buffer[x+ (y/8)*SSD1306_LCDWIDTH] &= ~_BV((y%8)); 
00216 }
00217 
00218 void Adafruit_SSD1306::invertDisplay(bool i)
00219 {
00220     if (i)
00221         ssd1306_command(SSD1306_INVERTDISPLAY);
00222     else
00223         ssd1306_command(SSD1306_NORMALDISPLAY);
00224 }
00225 
00226 void Adafruit_SSD1306::ssd1306_command(uint8_t c)
00227 {
00228     cs = 1;
00229     dc = 0;
00230     cs = 0;
00231     mspi.write(c);
00232     cs = 1;
00233 }
00234 
00235 void Adafruit_SSD1306::ssd1306_data(uint8_t c)
00236 {
00237     cs = 1;
00238     dc = 1;
00239     cs = 0;
00240     mspi.write(c);
00241     cs = 1;
00242 }
00243 
00244 void Adafruit_SSD1306::display(void)
00245 {
00246     ssd1306_command(SSD1306_SETLOWCOLUMN | 0x0);  // low col = 0
00247     ssd1306_command(SSD1306_SETHIGHCOLUMN | 0x0);  // hi col = 0
00248     ssd1306_command(SSD1306_SETSTARTLINE | 0x0); // line #0
00249 
00250     cs = 1;
00251     dc = 1;
00252     cs = 0;
00253     
00254     for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++)
00255         mspi.write(buffer[i]);
00256 
00257     // i wonder why we have to do this (check datasheet)
00258     if (SSD1306_LCDHEIGHT == 32)
00259     {
00260         for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++)
00261             mspi.write(0);
00262     }
00263     
00264     cs = 1;
00265 }
00266 
00267 // clear everything
00268 void Adafruit_SSD1306::clearDisplay(void)
00269 {
00270     memset(buffer,0,sizeof(buffer));
00271 }