Demonstration of SSD1308 OLED driver library
Dependencies: mbed SSD1308_128x64_I2C
Diff: SSD1308.cpp
- Revision:
- 2:d86478c0f5da
- Parent:
- 1:00053cb70ac5
- Child:
- 3:1337e3d65ed0
--- a/SSD1308.cpp Sat Jun 30 14:44:39 2012 +0000 +++ b/SSD1308.cpp Mon Jul 09 20:46:27 2012 +0000 @@ -3,11 +3,11 @@ // The SSD1308 is used for example in the Seeed 128x64 OLED Display // http://www.seeedstudio.com/depot/grove-oled-display-12864-p-781.html?cPath=163_167 // -// The original code is using (and submitted as a part of) Jeff Rowberg's I2Cdevlib library, +// The original code is using (and has been submitted as a part of) Jeff Rowberg's I2Cdevlib library, // which should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib // // Changelog: -// 2011-08-25 - initial release by Andrew Schamp <schamp@gmail.com> +// 2011-08-25 - Initial release by Andrew Schamp <schamp@gmail.com> // 2012-06-19 - Ported to mbed and optimised (WH) // /* ============================================ @@ -64,6 +64,7 @@ #if(0) // Standard version void SSD1308::clearDisplay() { + //setDisplayOff(); setPageAddress(0, MAX_PAGE); // all pages setColumnAddress(0, MAX_COL); // all columns @@ -74,7 +75,7 @@ } } -// setDisplayOn(); + //setDisplayOn(); } #else //Optimised version @@ -96,7 +97,7 @@ } _i2c.stop(); -// setDisplayOn(); + //setDisplayOn(); } #endif @@ -116,7 +117,7 @@ } } - // setDisplayOn(); + //setDisplayOn(); } #else //Optimised version @@ -137,12 +138,13 @@ } _i2c.stop(); -// setDisplayOn(); + //setDisplayOn(); } #endif void SSD1308::writeBitmap(int len, uint8_t* data) { + //setDisplayOff(); setPageAddress(0, MAX_PAGE); // all pages setColumnAddress(0, MAX_COL); // all columns @@ -155,24 +157,35 @@ } _i2c.stop(); -// setDisplayOn(); + //setDisplayOn(); } -void SSD1308::writeChar(char chr) { -//#ifdef SSD1308_USE_FONT + +// Write single character to the display using the 8x8 fontable +// Start at current cursor location +// char chr character +// bool inverted invert pixels +void SSD1308::writeChar(char chr, bool inverted) { const uint8_t char_index = chr - 0x20; for (uint8_t i = 0; i < 8; i++) { // const uint8_t b = pgm_read_byte( &fontData[char_index][i] ); // const uint8_t b = fontData[char_index][i]; // sendData( b ); - sendData( fontData[char_index][i] ); + if (inverted) { + sendData( ~fontData[char_index][i] ); + } + else { + sendData( fontData[char_index][i] ); + } } -//#endif } -void SSD1308::writeString(uint8_t row, uint8_t col, uint16_t len, const char * text) { + +// Write a string to the display using the 8x8 fontable +// Start at current cursor location +void SSD1308::writeString(uint8_t row, uint8_t col, uint16_t len, const char * text, bool inverted) { uint16_t index = 0; setPageAddress(row, MAX_PAGE); const uint8_t col_addr = FONT_WIDTH*col; @@ -180,7 +193,7 @@ while ((col+index) < CHARS && (index < len)) { // write first line, starting at given position - writeChar(text[index++]); + writeChar(text[index++], inverted); } // write remaining lines @@ -191,7 +204,7 @@ setColumnAddress(0, MAX_COL); bool wrapEntireScreen = false; while (index + 1 < len) { - writeChar(text[index++]); + writeChar(text[index++], inverted); // if we've written the last character space on the screen, // reset the page and column address so that it wraps around from the top again if (!wrapEntireScreen && (row*CHARS + col + index) > 127) { @@ -203,6 +216,8 @@ } } +// Write command that has no parameters +// void SSD1308::sendCommand(uint8_t command) { // I2Cdev::writeByte(m_devAddr, COMMAND_MODE, command); @@ -214,10 +229,55 @@ } +// Write command that has one parameter +// +void SSD1308::sendCommand(uint8_t command, uint8_t param1) { + +// Note continuationbit is set, so COMMAND_MODE must be +// repeated before each databyte that serves as parameter! + + _i2c.start(); + _i2c.write(_writeOpcode); + + _i2c.write(COMMAND_MODE); + _i2c.write(command); // Write Command + _i2c.write(COMMAND_MODE); + _i2c.write(param1); // Write Param1 + + _i2c.stop(); + +} + +// Write command that has two parameters +// +void SSD1308::sendCommand(uint8_t command, uint8_t param1, uint8_t param2) { + +// Note continuationbit is set, so COMMAND_MODE must be +// repeated before each databyte that serves as parameter! + + _i2c.start(); + _i2c.write(_writeOpcode); + + _i2c.write(COMMAND_MODE); + _i2c.write(command); // Write Command + _i2c.write(COMMAND_MODE); + _i2c.write(param1); // Write Param1 + _i2c.write(COMMAND_MODE); + _i2c.write(param2); // Write Param2 + + _i2c.stop(); + +} + + + +// Write command that has multiple parameters +// void SSD1308::sendCommands(uint8_t len, uint8_t* commands) { // I2Cdev::writeBytes(m_devAddr, COMMAND_MODE, len, commands); -// Note this original code is not correct, continuationbit is set! +// Note this original code is not correct, continuationbit is set, +// so COMMAND_MODE must be repeated before each databyte that serves as parameter! _i2c.start(); _i2c.write(_writeOpcode); @@ -230,6 +290,8 @@ } +// Write databyte to display +// Start at current cursor location void SSD1308::sendData(uint8_t data){ // I2Cdev::writeByte(m_devAddr, DATA_MODE, data); @@ -241,6 +303,8 @@ } +// Write len bytes from buffer data to display +// Start at current cursor location void SSD1308::sendData(uint8_t len, uint8_t* data) { // I2Cdev::writeBytes(m_devAddr, DATA_MODE, len, data); @@ -284,10 +348,22 @@ } +// takes one byte, 0x00 (lowest) - 0xFF (highest) +void SSD1308::setContrastControl(uint8_t contrast) { +// uint8_t cmds[2] = { SET_CONTRAST, contrast }; +// sendCommands(2, cmds); + + sendCommand(SET_CONTRAST, contrast); +} + +// Enable Display +// void SSD1308::setDisplayOn() { sendCommand(SET_DISPLAY_POWER_ON); } +// Disable Display +// void SSD1308::setDisplayOff() { sendCommand(SET_DISPLAY_POWER_OFF); } @@ -300,27 +376,81 @@ } } +// White on Black background +// void SSD1308::setDisplayNormal() { sendCommand(SET_NORMAL_DISPLAY); } - +// Black on White background +// void SSD1308::setDisplayInverse() { sendCommand(SET_INVERSE_DISPLAY); } +// Display Flip (Left/Right, Up/Down) +// +void SSD1308::setDisplayFlip(bool left, bool down) { + if (left) { + // column address 0 is mapped to SEG0 (Reset) + sendCommand(SET_SEGMENT_REMAP_0); + } + else { + // column address 127 is mapped to SEG0 + sendCommand(SET_SEGMENT_REMAP_127); + } + + if (down) { + // Reset mode + sendCommand(SET_COMMON_REMAP_0); + } + else { + // Flip Up/Down (Need to rewrite display before H effect shows) + sendCommand(SET_COMMON_REMAP_63); + } + +} + +// Sets Internal Iref +// +void SSD1308::setInternalIref() { + uint8_t cmds[2] = {SET_IREF_SELECTION, INTERNAL_IREF}; + sendCommands(2, cmds); +} + +// Sets External Iref +// +void SSD1308::setExternalIref() { + uint8_t cmds[2] = {SET_IREF_SELECTION, EXTERNAL_IREF}; + sendCommands(2, cmds); +} + + // Low level Init // Init the configuration registers in accordance with the datasheet // void SSD1308::_init() { + +//not complete yet + sendCommand(SET_DISPLAY_POWER_OFF); + + // column address 0 is mapped to SEG0 (Reset) + // row address 0 is mapped to COMM0 (Reset) + sendCommand(SET_SEGMENT_REMAP_0); + sendCommand(SET_COMMON_REMAP_0); + + uint8_t cmds[2] = { SET_COMMON_CONF, COMMON_BASE | COMMON_ALTERNATIVE | COMMON_LEFTRIGHT_NORMAL}; + sendCommands(2, cmds); + setHorizontalAddressingMode(); - clearDisplay(); - sendCommand(SET_DISPLAY_POWER_OFF); + setExternalIref(); sendCommand(SET_NORMAL_DISPLAY); - sendCommand(SET_DISPLAY_POWER_ON); + clearDisplay(); + + sendCommand(SET_DISPLAY_POWER_ON); }