Demonstration of SSD1308 OLED driver library
Dependencies: mbed SSD1308_128x64_I2C
Revision 2:d86478c0f5da, committed 2012-07-09
- Comitter:
- wim
- Date:
- Mon Jul 09 20:46:27 2012 +0000
- Parent:
- 1:00053cb70ac5
- Child:
- 3:1337e3d65ed0
- Commit message:
- Temp version
Changed in this revision
--- 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); }
--- a/SSD1308.h Sat Jun 30 14:44:39 2012 +0000 +++ b/SSD1308.h 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) // /* ============================================ @@ -65,7 +65,7 @@ #define SET_CONTRAST 0x81 // takes one byte, 0x00 - 0xFF -#define SET_SEGMENT_REMAP_0 0xA0 // column address 0 is mapped to SEG0 +#define SET_SEGMENT_REMAP_0 0xA0 // column address 0 is mapped to SEG0 (Reset) #define SET_SEGMENT_REMAP_127 0xA1 // column address 127 is mapped to SEG0 #define SET_ENTIRE_DISPLAY_ON 0xA5 // turns all pixels on, does not affect RAM @@ -96,10 +96,21 @@ #define PAGE7 0x07 #define SET_PAGE_START_ADDRESS 0xB0 // | with a page number to get start address +#define SET_COMMON_REMAP_0 0xC0 // row address 0 is mapped to COM0 (Reset) +#define SET_COMMON_REMAP_63 0xC8 // row address 63 is mapped to COM0 + + #define SET_DISPLAY_OFFSET 0xD3 #define SET_DISPLAY_CLOCK 0xD5 +#define COMMON_BASE 0x02 // +#define COMMON_SEQUENTIAL 0x00 // Sequential common pins config +#define COMMON_ALTERNATIVE 0x10 // Odd/Even common pins config (Reset) +#define COMMON_LEFTRIGHT_NORMAL 0x00 // LeftRight Normal (Reset) +#define COMMON_LEFTRIGHT_FLIP 0x20 // LeftRight Flip +#define SET_COMMON_CONF 0xDA + #define VCOMH_DESELECT_0_65_CODE 0x00 #define VCOMH_DESELECT_0_77_CODE 0x20 #define VCOMH_DESELECT_0_83_CODE 0x30 @@ -132,7 +143,7 @@ // x, y is position (x is row (i.e., page), y is character (0-15), starting at top-left) // text will wrap around until it is done. - void writeString(uint8_t row, uint8_t col, uint16_t len, const char* txt); + void writeString(uint8_t row, uint8_t col, uint16_t len, const char* txt, bool inverted = false); //void setXY(uint8_t, uint8_t y); @@ -179,6 +190,12 @@ void setDisplayNormal(); void setDisplayInverse(); + + // Display Flip (Up/Down, Left/Right) + // + void setDisplayFlip(bool left, bool down); + + // Set vertical shift by COM from 0 - 63 (0x00 - 0x3F) // set to 0x00 after RESET void setDisplayOffset(uint8_t offset); @@ -224,10 +241,13 @@ private: - // sends a single-byte command (given) to device - void sendCommand(uint8_t command); + // sends a command and optional params to device + void sendCommand(uint8_t command); + void sendCommand(uint8_t command, uint8_t param1); + void sendCommand(uint8_t command, uint8_t param1, uint8_t param2); + void sendCommands(uint8_t len, uint8_t* buf); - void writeChar(char chr); + void writeChar(char chr, bool inverted); // Init the configuration registers in accordance with the datasheet void _init();
--- a/main.cpp Sat Jun 30 14:44:39 2012 +0000 +++ b/main.cpp Mon Jul 09 20:46:27 2012 +0000 @@ -46,9 +46,10 @@ pc.printf("7: Display Invert\n\r"); pc.printf("8: Display Normal\n\r"); pc.printf("9: Display Bitmap\n\r"); -// pc.printf("A: \n\r"); -// pc.printf("B: \n\r"); -// pc.printf("C: \n\r"); + pc.printf("A: Brightness Ramp\n\r"); + pc.printf("B: Send Inverted Message\n\r"); + pc.printf("C: Flip and Mirror\n\r"); + // pc.printf("D: \n\r"); // pc.printf("E: \n\r"); // pc.printf("F: \n\r"); @@ -133,6 +134,9 @@ int main() { bool running=true; + bool left = true; + bool down = true; + char command; init_interfaces(); @@ -181,7 +185,7 @@ break; case '3' : - pc.printf("Fill Display 0xA5\n\r"); + pc.printf("Fill Display 0xAA\n\r"); oled.fillDisplay(0xA5); break; @@ -216,12 +220,33 @@ break; case 'A' : - + pc.printf("Brightness Ramp Down\r\n"); + for (int contrast=0x7F; contrast >= 0x00; contrast--) { + oled.setContrastControl(contrast); + wait(0.05); + } + + wait(1); + + pc.printf("Brightness Ramp Up\r\n"); + for (int contrast=0x00; contrast <= 0x7F; contrast++) { + oled.setContrastControl(contrast); + wait(0.05); + } + break; case 'B' : - - break; + pc.printf("Send Inverted Message\n\r"); + oled.writeString(0, 0, 13, "Hello World !", true); + break; + + case 'C' : + pc.printf("Flip and Mirror (Rewrite display to show horizontal effect)\n\r"); + left = !left; + down = !down; + oled.setDisplayFlip(left, down); + break; } //switch }//if
--- a/mbed_logo.h Sat Jun 30 14:44:39 2012 +0000 +++ b/mbed_logo.h Mon Jul 09 20:46:27 2012 +0000 @@ -32,7 +32,7 @@ 0x3C, 0x3E, 0x3E, 0x3E, 0x3E, 0x7E, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xFC, 0x7C, 0x3C, 0x3E, 0x3E, 0x3E, 0x3E, 0x7E, 0xFC, 0xFC, 0xFC, 0xF8, 0xF0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7C, 0x3C, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x7E, 0x7C, 0xFC, 0xFC, 0xF8, -0xF0, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0x7C, +0xF0, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFC, 0x7C, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3C, 0x7C, 0xFC, 0xF8, 0xF8, 0xF0, 0xE0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFC, 0x7E, 0x7E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3C, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -40,16 +40,16 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0xF8, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x38, 0x38, -0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x39, 0x38, +0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x39, 0x3F, 0x3F, 0x3F, 0x3F, 0x3E, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF8, 0xFE, 0x7F, -0x3F, 0x1F, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x1F, 0x3F, 0x7F, 0xFE, 0xF8, 0xF0, -0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x70, 0x30, 0x00, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF8, 0xFE, 0x7F, +0x3F, 0x1F, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0xFC, 0xF0, +0xF0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xF0, 0xF0, 0xF8, 0xF8, 0x70, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0xFC, 0xF8, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, @@ -57,7 +57,7 @@ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,