Fork of nkhorman's Adafruit mbed port with added I2C support
Fork of Adafruit_GFX by
Adafruit_SSD1306.cpp
- Committer:
- pommzorz
- Date:
- 2014-03-13
- Revision:
- 4:86b9481fa281
- Parent:
- 0:c3dcd4c4983a
- Child:
- 5:b8313591b561
File content as of revision 4:86b9481fa281:
/********************************************************************* This is a library for our Monochrome OLEDs based on SSD1306 drivers Pick one up today in the adafruit shop! ------> http://www.adafruit.com/category/63_98 These displays use SPI to communicate, 4 or 5 pins are required to interface Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Limor Fried/Ladyada for Adafruit Industries. BSD license, check license.txt for more information All text above, and the splash screen below must be included in any redistribution *********************************************************************/ /* * Modified by Neal Horman 7/14/2012 for use in LPC1768 */ #include "mbed.h" #include "Adafruit_SSD1306.h" #ifdef WITH_SPLASH uint8_t splashScreen[512] = { //SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH / 8 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x8C, 0x8E, 0x84, 0x00, 0x00, 0x80, 0xF8, 0xF8, 0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0x80, 0x00, 0xE0, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xC7, 0x01, 0x01, 0x01, 0x01, 0x83, 0xFF, 0xFF, 0x00, 0x00, 0x7C, 0xFE, 0xC7, 0x01, 0x01, 0x01, 0x01, 0x83, 0xFF, 0xFF, 0xFF, 0x00, 0x38, 0xFE, 0xC7, 0x83, 0x01, 0x01, 0x01, 0x83, 0xC7, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x07, 0x01, 0x01, 0x01, 0x00, 0x00, 0x7F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC7, 0xC7, 0x8F, 0x8F, 0x9F, 0xBF, 0xFF, 0xFF, 0xC3, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xF0, 0xE0, 0xC0, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 }; #endif #ifdef IS_SPI Adafruit_SSD1306::Adafruit_SSD1306(SPI &spi, PinName DC, PinName RST, PinName CS) : Adafruit_GFX(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT) , rst(RST,false), cs(CS,true), dc(DC,false), mspi(spi) { //memcpy(buffer,splashScreen,sizeof(buffer)); begin(); display(); }; #elif defined IS_I2C Adafruit_SSD1306::Adafruit_SSD1306(I2C &i2c, PinName RST) : Adafruit_GFX(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT) , rst(RST,false),mi2c(i2c),pc(USBTX, USBRX) { pc.baud(921600); mi2c.frequency(100000); pc.printf("\r\n\ninit."); mi2c.start(); //memcpy(buffer,splashScreen,sizeof(buffer)); pc.printf("cp."); begin(); pc.printf("bg."); display(); pc.printf("dp\r\n"); }; #endif void Adafruit_SSD1306::begin(uint8_t vccstate) { rst = 1; // VDD (3.3V) goes high at start, lets just chill for a ms wait_ms(1); // bring reset low rst = 0; // wait 10ms wait_ms(10); // bring out of reset rst = 1; // turn on VCC (9V?) #if defined SSD1306_128_32 // Init sequence for 128x32 OLED module ssd1306_command(SSD1306_DISPLAYOFF); // 0xAE ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5 ssd1306_command(0x80); // the suggested ratio 0x80 ssd1306_command(SSD1306_SETMULTIPLEX); // 0xA8 ssd1306_command(0x1F); ssd1306_command(SSD1306_SETDISPLAYOFFSET); // 0xD3 ssd1306_command(0x0); // no offset ssd1306_command(SSD1306_SETSTARTLINE | 0x0); // line #0 ssd1306_command(SSD1306_CHARGEPUMP); // 0x8D if (vccstate == SSD1306_EXTERNALVCC) { ssd1306_command(0x10); } else { ssd1306_command(0x14); } ssd1306_command(SSD1306_MEMORYMODE); // 0x20 ssd1306_command(0x00); // 0x0 act like ks0108 ssd1306_command(SSD1306_SEGREMAP | 0x1); ssd1306_command(SSD1306_COMSCANDEC); ssd1306_command(SSD1306_SETCOMPINS); // 0xDA ssd1306_command(0x02); ssd1306_command(SSD1306_SETCONTRAST); // 0x81 ssd1306_command(0x8F); ssd1306_command(SSD1306_SETPRECHARGE); // 0xd9 if (vccstate == SSD1306_EXTERNALVCC) { ssd1306_command(0x22); } else { ssd1306_command(0xF1); } ssd1306_command(SSD1306_SETVCOMDETECT); // 0xDB ssd1306_command(0x40); ssd1306_command(SSD1306_DISPLAYALLON_RESUME); // 0xA4 ssd1306_command(SSD1306_NORMALDISPLAY); // 0xA6 #endif #if defined SSD1306_128_64 // Init sequence for 128x64 OLED module ssd1306_command(SSD1306_DISPLAYOFF); // 0xAE ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5 ssd1306_command(0x80); // the suggested ratio 0x80 ssd1306_command(SSD1306_SETMULTIPLEX); // 0xA8 ssd1306_command(0x3F); ssd1306_command(SSD1306_SETDISPLAYOFFSET); // 0xD3 ssd1306_command(0x0); // no offset ssd1306_command(SSD1306_SETSTARTLINE | 0x0); // line #0 ssd1306_command(SSD1306_CHARGEPUMP); // 0x8D if (vccstate == SSD1306_EXTERNALVCC) { ssd1306_command(0x10); } else { ssd1306_command(0x14); } ssd1306_command(SSD1306_MEMORYMODE); // 0x20 ssd1306_command(0x00); // 0x0 act like ks0108 ssd1306_command(SSD1306_SEGREMAP | 0x1); ssd1306_command(SSD1306_COMSCANDEC); ssd1306_command(SSD1306_SETCOMPINS); // 0xDA ssd1306_command(0x12); ssd1306_command(SSD1306_SETCONTRAST); // 0x81 if (vccstate == SSD1306_EXTERNALVCC) { ssd1306_command(0x9F); } else { ssd1306_command(0xCF); } ssd1306_command(SSD1306_SETPRECHARGE); // 0xd9 if (vccstate == SSD1306_EXTERNALVCC) { ssd1306_command(0x22); } else { ssd1306_command(0xF1); } ssd1306_command(SSD1306_SETVCOMDETECT); // 0xDB ssd1306_command(0x40); ssd1306_command(SSD1306_DISPLAYALLON_RESUME); // 0xA4 ssd1306_command(SSD1306_NORMALDISPLAY); // 0xA6 #endif ssd1306_command(SSD1306_DISPLAYON);//--turn on oled panel } // the most basic function, set a single pixel void Adafruit_SSD1306::drawPixel(int16_t x, int16_t y, uint16_t color) { if ((x < 0) || (x >= width()) || (y < 0) || (y >= height())) return; // check rotation, move pixel around if necessary switch (getRotation()) { case 1: swap(x, y); x = _rawWidth - x - 1; break; case 2: x = _rawWidth - x - 1; y = _rawHeight - y - 1; break; case 3: swap(x, y); y = _rawHeight - y - 1; break; } // x is which column if (color == WHITE) buffer[x+ (y/8)*SSD1306_LCDWIDTH] |= _BV((y%8)); else buffer[x+ (y/8)*SSD1306_LCDWIDTH] &= ~_BV((y%8)); } void Adafruit_SSD1306::invertDisplay(bool i) { if (i) ssd1306_command(SSD1306_INVERTDISPLAY); else ssd1306_command(SSD1306_NORMALDISPLAY); } void Adafruit_SSD1306::ssd1306_command(uint8_t c) { #ifdef IS_SPI cs = 1; dc = 0; cs = 0; mspi.write(c); cs = 1; #elif defined IS_I2C char buff[2] ; buff[0] = SSD_Command_Mode ; buff[1] = c; if(mi2c.write(I2C_ADDRESS,buff,sizeof(buff)))pc.printf("!"); #endif } void Adafruit_SSD1306::ssd1306_data(uint8_t c) { #ifdef IS_SPI cs = 1; dc = 1; cs = 0; mspi.write(c); cs = 1; #elif defined IS_I2C char buff[2] ; // Setup D/C to switch to data mode buff[0] = SSD_Data_Mode; buff[1] = c; // Write on i2c if(mi2c.write(I2C_ADDRESS,buff,sizeof(buff)))pc.printf("?"); #endif } void Adafruit_SSD1306::display(void) { ssd1306_command(SSD1306_SETLOWCOLUMN | 0x0); // low col = 0 ssd1306_command(SSD1306_SETHIGHCOLUMN | 0x0); // hi col = 0 ssd1306_command(SSD1306_SETSTARTLINE | 0x0); // line #0 #ifdef IS_SPI cs = 1; dc = 1; cs = 0; for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) mspi.write(buffer[i]); // i wonder why we have to do this (check datasheet) if (SSD1306_LCDHEIGHT == 32) { for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) mspi.write(0); } cs = 1; #elif defined IS_I2C char buff[17] ; uint8_t x ; // Setup D/C to switch to data mode buff[0] = SSD_Data_Mode; // loop trough all OLED buffer and // send a bunch of 16 data byte in one xmission for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i+=16 ) { for (x=1; x<=16; x++) buff[x] = buffer[i+x]; if(mi2c.write(I2C_ADDRESS, buff, 17))pc.printf("?"); } #endif } // clear everything void Adafruit_SSD1306::clearDisplay(void) { memset(buffer,0,sizeof(buffer)); }