added the WANT_ABSTRACTS define so the library works with text sizes greater than 1

Dependents:   car_stereo

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     // Init sequence for 128x32 OLED module
00119     ssd1306_command(SSD1306_DISPLAYOFF);                    // 0xAE
00120     ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV);            // 0xD5
00121     ssd1306_command(0x80);                                  // the suggested ratio 0x80
00122     ssd1306_command(SSD1306_SETMULTIPLEX);                  // 0xA8
00123     ssd1306_command(0x1F);
00124     ssd1306_command(SSD1306_SETDISPLAYOFFSET);              // 0xD3
00125     ssd1306_command(0x0);                                   // no offset
00126     ssd1306_command(SSD1306_SETSTARTLINE | 0x0);            // line #0
00127     ssd1306_command(SSD1306_CHARGEPUMP);                    // 0x8D
00128     if (vccstate == SSD1306_EXTERNALVCC) 
00129     { ssd1306_command(0x10); }
00130     else 
00131     { ssd1306_command(0x14); }
00132     ssd1306_command(SSD1306_MEMORYMODE);                    // 0x20
00133     ssd1306_command(0x00);                                  // 0x0 act like ks0108
00134     ssd1306_command(SSD1306_SEGREMAP | 0x1);
00135     ssd1306_command(SSD1306_COMSCANDEC);
00136     ssd1306_command(SSD1306_SETCOMPINS);                    // 0xDA
00137     ssd1306_command(0x02);
00138     ssd1306_command(SSD1306_SETCONTRAST);                   // 0x81
00139     ssd1306_command(0x8F);
00140     ssd1306_command(SSD1306_SETPRECHARGE);                  // 0xd9
00141     if (vccstate == SSD1306_EXTERNALVCC) 
00142     { ssd1306_command(0x22); }
00143     else 
00144     { ssd1306_command(0xF1); }
00145     ssd1306_command(SSD1306_SETVCOMDETECT);                 // 0xDB
00146     ssd1306_command(0x40);
00147     ssd1306_command(SSD1306_DISPLAYALLON_RESUME);           // 0xA4
00148     ssd1306_command(SSD1306_NORMALDISPLAY);                 // 0xA6
00149 #endif
00150     
00151 #if defined SSD1306_128_64
00152     // Init sequence for 128x64 OLED module
00153     ssd1306_command(SSD1306_DISPLAYOFF);                    // 0xAE
00154     ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV);            // 0xD5
00155     ssd1306_command(0x80);                                  // the suggested ratio 0x80
00156     ssd1306_command(SSD1306_SETMULTIPLEX);                  // 0xA8
00157     ssd1306_command(0x3F);
00158     ssd1306_command(SSD1306_SETDISPLAYOFFSET);              // 0xD3
00159     ssd1306_command(0x0);                                   // no offset
00160     ssd1306_command(SSD1306_SETSTARTLINE | 0x0);            // line #0
00161     ssd1306_command(SSD1306_CHARGEPUMP);                    // 0x8D
00162     if (vccstate == SSD1306_EXTERNALVCC) 
00163     { ssd1306_command(0x10); }
00164     else 
00165     { ssd1306_command(0x14); }
00166     ssd1306_command(SSD1306_MEMORYMODE);                    // 0x20
00167     ssd1306_command(0x00);                                  // 0x0 act like ks0108
00168     ssd1306_command(SSD1306_SEGREMAP | 0x1);
00169     ssd1306_command(SSD1306_COMSCANDEC);
00170     ssd1306_command(SSD1306_SETCOMPINS);                    // 0xDA
00171     ssd1306_command(0x12);
00172     ssd1306_command(SSD1306_SETCONTRAST);                   // 0x81
00173     if (vccstate == SSD1306_EXTERNALVCC) 
00174     { ssd1306_command(0x9F); }
00175     else 
00176     { ssd1306_command(0xCF); }
00177     ssd1306_command(SSD1306_SETPRECHARGE);                  // 0xd9
00178     if (vccstate == SSD1306_EXTERNALVCC) 
00179     { ssd1306_command(0x22); }
00180     else 
00181     { ssd1306_command(0xF1); }
00182     ssd1306_command(SSD1306_SETVCOMDETECT);                 // 0xDB
00183     ssd1306_command(0x40);
00184     ssd1306_command(SSD1306_DISPLAYALLON_RESUME);           // 0xA4
00185     ssd1306_command(SSD1306_NORMALDISPLAY);                 // 0xA6
00186 #endif
00187     
00188     ssd1306_command(SSD1306_DISPLAYON);//--turn on oled panel
00189 }
00190 
00191 // the most basic function, set a single pixel
00192 void Adafruit_SSD1306::drawPixel(int16_t x, int16_t y, uint16_t color)
00193 {
00194     if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
00195         return;
00196     
00197     // check rotation, move pixel around if necessary
00198     switch (getRotation())
00199     {
00200         case 1:
00201             swap(x, y);
00202             x = _rawWidth - x - 1;
00203             break;
00204         case 2:
00205             x = _rawWidth - x - 1;
00206             y = _rawHeight - y - 1;
00207             break;
00208         case 3:
00209             swap(x, y);
00210             y = _rawHeight - y - 1;
00211             break;
00212     }  
00213     
00214     // x is which column
00215     if (color == WHITE) 
00216         buffer[x+ (y/8)*SSD1306_LCDWIDTH] |= _BV((y%8));  
00217     else
00218         buffer[x+ (y/8)*SSD1306_LCDWIDTH] &= ~_BV((y%8)); 
00219 }
00220 
00221 void Adafruit_SSD1306::invertDisplay(bool i)
00222 {
00223     if (i)
00224         ssd1306_command(SSD1306_INVERTDISPLAY);
00225     else
00226         ssd1306_command(SSD1306_NORMALDISPLAY);
00227 }
00228 
00229 void Adafruit_SSD1306::ssd1306_command(uint8_t c)
00230 {
00231     cs = 1;
00232     dc = 0;
00233     cs = 0;
00234     mspi.write(c);
00235     cs = 1;
00236 }
00237 
00238 void Adafruit_SSD1306::ssd1306_data(uint8_t c)
00239 {
00240     cs = 1;
00241     dc = 1;
00242     cs = 0;
00243     mspi.write(c);
00244     cs = 1;
00245 }
00246 
00247 void Adafruit_SSD1306::display(void)
00248 {
00249     ssd1306_command(SSD1306_SETLOWCOLUMN | 0x0);  // low col = 0
00250     ssd1306_command(SSD1306_SETHIGHCOLUMN | 0x0);  // hi col = 0
00251     ssd1306_command(SSD1306_SETSTARTLINE | 0x0); // line #0
00252 
00253     cs = 1;
00254     dc = 1;
00255     cs = 0;
00256     
00257     for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++)
00258         mspi.write(buffer[i]);
00259 
00260     // i wonder why we have to do this (check datasheet)
00261     if (SSD1306_LCDHEIGHT == 32)
00262     {
00263         for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++)
00264             mspi.write(0);
00265     }
00266     
00267     cs = 1;
00268 }
00269 
00270 // clear everything
00271 void Adafruit_SSD1306::clearDisplay(void)
00272 {
00273     memset(buffer,0,sizeof(buffer));
00274 }