- code cleaned up in many points for a better readability - removed SPIPreinit and I2CPreinit classes - moved various method implementations from .h files to the corresponding .cpp ones - the splash() and clearDisplay() methods now directly update the display; no more need to call the display() method after them
Dependencies: Adafruit_GFX mbed
Fork of Adafruit_GFX by
Diff: Adafruit_SSD1306.cpp
- Revision:
- 17:396d9b7eb7d5
- Parent:
- 16:7fb1d4d3525d
--- a/Adafruit_SSD1306.cpp Tue Nov 11 22:08:20 2014 +0000 +++ b/Adafruit_SSD1306.cpp Thu Sep 03 20:27:40 2015 +0000 @@ -18,84 +18,56 @@ /* * Modified by Neal Horman 7/14/2012 for use in mbed + * Edited by Francesco Adamo 2015/09/03: + * - code cleaned up in many points for a better readability + * - removed SPIPreinit and I2CPreinit classes + * - moved various method implementations from .h files to the corresponding .cpp ones + * - the splash() and clearDisplay() methods now directly update the display; no more need to call the display() method after them + * */ #include "mbed.h" #include "Adafruit_SSD1306.h" -#define SSD1306_SETCONTRAST 0x81 -#define SSD1306_DISPLAYALLON_RESUME 0xA4 -#define SSD1306_DISPLAYALLON 0xA5 -#define SSD1306_NORMALDISPLAY 0xA6 -#define SSD1306_INVERTDISPLAY 0xA7 -#define SSD1306_DISPLAYOFF 0xAE -#define SSD1306_DISPLAYON 0xAF -#define SSD1306_SETDISPLAYOFFSET 0xD3 -#define SSD1306_SETCOMPINS 0xDA -#define SSD1306_SETVCOMDETECT 0xDB -#define SSD1306_SETDISPLAYCLOCKDIV 0xD5 -#define SSD1306_SETPRECHARGE 0xD9 -#define SSD1306_SETMULTIPLEX 0xA8 -#define SSD1306_SETLOWCOLUMN 0x00 -#define SSD1306_SETHIGHCOLUMN 0x10 -#define SSD1306_SETSTARTLINE 0x40 -#define SSD1306_MEMORYMODE 0x20 -#define SSD1306_COMSCANINC 0xC0 -#define SSD1306_COMSCANDEC 0xC8 -#define SSD1306_SEGREMAP 0xA0 -#define SSD1306_CHARGEPUMP 0x8D +Adafruit_SSD1306::Adafruit_SSD1306(PinName RST, uint8_t rawHeight, uint8_t rawWidth) : Adafruit_GFX(rawWidth, rawHeight), rst(RST,false) +{ + buffer.resize(rawHeight * rawWidth / 8); +}; 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?) - + wait_ms(10); + command(SSD1306_DISPLAYOFF); command(SSD1306_SETDISPLAYCLOCKDIV); - command(0x80); // the suggested ratio 0x80 - + command(0x80); // the suggested ratio 0x8 command(SSD1306_SETMULTIPLEX); - command(_rawHeight-1); - + command(_rawHeight - 1); command(SSD1306_SETDISPLAYOFFSET); - command(0x0); // no offset - - command(SSD1306_SETSTARTLINE | 0x0); // line #0 - + command(0x00); // no offset + command(SSD1306_SETSTARTLINE); // line #0 command(SSD1306_CHARGEPUMP); command((vccstate == SSD1306_EXTERNALVCC) ? 0x10 : 0x14); - command(SSD1306_MEMORYMODE); command(0x00); // 0x0 act like ks0108 - command(SSD1306_SEGREMAP | 0x1); - command(SSD1306_COMSCANDEC); - command(SSD1306_SETCOMPINS); - command(_rawHeight == 32 ? 0x02 : 0x12); // TODO - calculate based on _rawHieght ? - + command(_rawHeight == 32 ? 0x02 : 0x12); // TODO - calculate based on _rawHeight ? command(SSD1306_SETCONTRAST); command(_rawHeight == 32 ? 0x8F : ((vccstate == SSD1306_EXTERNALVCC) ? 0x9F : 0xCF) ); - command(SSD1306_SETPRECHARGE); command((vccstate == SSD1306_EXTERNALVCC) ? 0x22 : 0xF1); - command(SSD1306_SETVCOMDETECT); command(0x40); - command(SSD1306_DISPLAYALLON_RESUME); - command(SSD1306_NORMALDISPLAY); - command(SSD1306_DISPLAYON); } @@ -146,7 +118,8 @@ // Clear the display buffer. Requires a display() call at some point afterwards void Adafruit_SSD1306::clearDisplay(void) { - std::fill(buffer.begin(),buffer.end(),0); + std::fill(buffer.begin(), buffer.end(), 0); + display(); } void Adafruit_SSD1306::splash(void) @@ -226,5 +199,129 @@ , &adaFruitLogo[0] + (_rawHeight == 32 ? sizeof(adaFruitLogo)/2 : sizeof(adaFruitLogo)) , buffer.begin() ); + display(); #endif } + + + /** Create a SSD1306 SPI transport display driver instance with the specified DC, RST, and CS pins, as well as the display dimensions + * + * Required parameters + * @param spi - a reference to an initialized SPI object + * @param DC (Data/Command) pin name + * @param RST (Reset) pin name + * @param CS (Chip Select) pin name + * + * Optional parameters + * @param rawHeight - the vertical number of pixels for the display, defaults to 32 + * @param rawWidth - the horizontal number of pixels for the display, defaults to 128 + */ +Adafruit_SSD1306_SPI::Adafruit_SSD1306_SPI(PinName MOSI, PinName CLK, PinName CS, PinName DC, PinName RST, uint8_t rawHeight, uint8_t rawWidth) + : Adafruit_SSD1306(RST, rawHeight, rawWidth) + , cs(CS, true) + , dc(DC, false) + , mspi(MOSI, NC, CLK) +{ + mspi.frequency(1000000); + mspi.format(8, 3); + begin(); + splash(); +}; + +uint8_t Adafruit_SSD1306_SPI::command(uint8_t c) +{ + cs = 1; + dc = 0; + cs = 0; + mspi.write(c); + cs = 1; + + return c; +}; + +void Adafruit_SSD1306_SPI::data(uint8_t c) +{ + cs = 1; + dc = 1; + cs = 0; + mspi.write(c); + cs = 1; +}; + + +void Adafruit_SSD1306_SPI::sendDisplayBuffer() +{ + cs = 1; + dc = 1; + cs = 0; + + for(uint16_t i=0, q = buffer.size(); i < q; i++) + mspi.write(buffer[i]); + + if(height() == 32) + { + for(uint16_t i=0, q = buffer.size(); i<q; i++) + mspi.write(0); + } + + cs = 1; +}; + + + /** Create a SSD1306 I2C transport display driver instance with the specified RST pin name, the I2C address, as well as the display dimensions + * + * Required parameters + * @param i2c - A reference to an initialized I2C object + * @param RST - The Reset pin name + * + * Optional parameters + * @param i2cAddress - The i2c address of the display + * @param rawHeight - The vertical number of pixels for the display, defaults to 32 + * @param rawWidth - The horizonal number of pixels for the display, defaults to 128 + */ + Adafruit_SSD1306_I2C::Adafruit_SSD1306_I2C(PinName SDA, PinName SCL, PinName RST, uint8_t i2cAddress, uint8_t rawHeight, uint8_t rawWidth) + : Adafruit_SSD1306(RST, rawHeight, rawWidth) + , mi2c(SDA, SCL) + , mi2cAddress(i2cAddress) + { + mi2c.frequency(400000); + mi2c.start(); + begin(); + splash(); + }; + +uint8_t Adafruit_SSD1306_I2C::command(uint8_t c) + { + char buff[2]; + buff[0] = 0; // Command Mode + buff[1] = c; + mi2c.write(mi2cAddress, buff, sizeof(buff)); + + return c; + } + +void Adafruit_SSD1306_I2C::data(uint8_t c) + { + char buff[2]; + buff[0] = 0x40; // Data Mode + buff[1] = c; + mi2c.write(mi2cAddress, buff, sizeof(buff)); + }; + + +void Adafruit_SSD1306_I2C::sendDisplayBuffer() + { + char buff[17]; + buff[0] = 0x40; // Data Mode + + // send display buffer in 16 byte chunks + for(uint16_t i=0, q=buffer.size(); i<q; i+=16 ) + { uint8_t x ; + + // TODO - this will segfault if buffer.size() % 16 != 0 + for(x=1; x<sizeof(buff); x++) + buff[x] = buffer[i+x-1]; + + mi2c.write(mi2cAddress, buff, sizeof(buff)); + } + };