Demonstration of SSD1308 OLED driver library

Dependencies:   mbed SSD1308_128x64_I2C

Revision:
1:00053cb70ac5
Parent:
0:2ded56b8407d
Child:
2:d86478c0f5da
--- a/SSD1308.cpp	Tue Jun 19 20:00:10 2012 +0000
+++ b/SSD1308.cpp	Sat Jun 30 14:44:39 2012 +0000
@@ -1,16 +1,15 @@
-// I2Cdev library collection - SSD1308 I2C device class header file
-// Based on Solomon Systech SSD1308 datasheet, rev. 1, 10/2008
-//  8/25/2011 by Andrew Schamp <schamp@gmail.com>
-// 19/06/2012 Ported to mbed (WH)
+// SSD1308 I2C device class file
+//   Based on Solomon Systech SSD1308 datasheet, rev. 1, 10/2008
+//   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
 //
-// This I2C device library is using (and submitted as a part of) Jeff Rowberg's I2Cdevlib library,
+// The original code is using (and submitted as a part of) Jeff Rowberg's I2Cdevlib library,
 // which should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
-// Note WH: I2Cdevlib not used for mbed port
 //
 // Changelog:
-//     2011-08-25 - initial release
-//     2012-06-19 - Ported to mbed (WH)
-        
+//   2011-08-25 - initial release by Andrew Schamp <schamp@gmail.com>
+//   2012-06-19 - Ported to mbed and optimised (WH)
+//       
 /* ============================================
 I2Cdev device library code is placed under the MIT license
 Copyright (c) 2011 Andrew Schamp
@@ -38,59 +37,138 @@
 #include "mbed.h"
 #include "SSD1308.h"
 
-#define SSD1308_USE_FONT
+//#define SSD1308_USE_FONT
 //#ifdef SSD1308_USE_FONT
 #include "FixedWidthFont.h"
 //#endif
 
+//Constructor
+//
 SSD1308::SSD1308(I2C &i2c, uint8_t deviceAddress) : _i2c(i2c) {
 //  m_devAddr = deviceAddress; 
   
   _writeOpcode = deviceAddress & 0xFE; // low order bit = 0 for write
   _readOpcode  = deviceAddress | 0x01; // low order bit = 1 for read  
+  
+  initialize(); 
 }
 
+// High level Init, most settings remain at Power-On reset value
+//
 void SSD1308::initialize() {
   setHorizontalAddressingMode();
   clearDisplay();
 }
 
+
+#if(0)
+// Standard version
 void SSD1308::clearDisplay() {
-  setDisplayOff();
+  //setDisplayOff();
   setPageAddress(0, MAX_PAGE);  // all pages
   setColumnAddress(0, MAX_COL); // all columns
-  for (uint8_t page = 0; page < PAGES; page++)
-  {
-    for (uint8_t col = 0; col < COLUMNS; col++)
-    {
-      sendData(0x0);
+
+  for (uint8_t page = 0; page < PAGES; page++) {
+    for (uint8_t col = 0; col < COLUMNS; col++) {
+      sendData(0x00);
     }
   }
-  setDisplayOn();
+
+//  setDisplayOn();
 }
+#else
+//Optimised version
+// Save lots of I2C S,P, address and datacommands:
+// Send S, address, DATA_MODE, data, data, data,...., P
+//
+void SSD1308::clearDisplay() {
 
-void SSD1308::fillDisplay() {
+  //setDisplayOff();
+  
   setPageAddress(0, MAX_PAGE);  // all pages
   setColumnAddress(0, MAX_COL); // all columns
 
-  uint8_t b = 0;
-  for (uint8_t page = 0; page < PAGES; page++)
-  {
-    for (uint8_t col = 0; col < COLUMNS; col++)
-    {
-      sendData(b++);
+  _i2c.start();
+  _i2c.write(_writeOpcode);
+  _i2c.write(DATA_MODE);  
+  for (int i=0; i<(PAGES * COLUMNS); i++) {
+    _i2c.write(0x00);  // Write Data   
+  }
+  _i2c.stop();
+
+//  setDisplayOn();
+}
+#endif
+
+
+#if(0)
+//Standard version
+void SSD1308::fillDisplay(uint8_t pattern) {
+  
+  //setDisplayOff();  
+  
+  setPageAddress(0, MAX_PAGE);  // all pages
+  setColumnAddress(0, MAX_COL); // all columns
+
+  for (uint8_t page = 0; page < PAGES; page++) {
+    for (uint8_t col = 0; col < COLUMNS; col++) {
+      sendData(pattern); 
     }
   }
+ 
+  //  setDisplayOn();  
+}
+#else
+//Optimised version
+// Save lots of I2C S,P, address and datacommands:
+// Send S, address, DATA_MODE, data, data, data,...., P
+//
+void SSD1308::fillDisplay(uint8_t pattern) {
+
+  //setDisplayOff();
+  setPageAddress(0, MAX_PAGE);  // all pages
+  setColumnAddress(0, MAX_COL); // all columns
+
+  _i2c.start();
+  _i2c.write(_writeOpcode);
+  _i2c.write(DATA_MODE);  
+  for (int i=0; i<(PAGES * COLUMNS); i++) {
+    _i2c.write(pattern);  // Write Data   
+  }
+  _i2c.stop();
+
+//  setDisplayOn();
+}
+#endif
+
+
+void SSD1308::writeBitmap(int len, uint8_t* data) {
+  //setDisplayOff();
+  setPageAddress(0, MAX_PAGE);  // all pages
+  setColumnAddress(0, MAX_COL); // all columns
+
+  _i2c.start();
+  _i2c.write(_writeOpcode);
+  _i2c.write(DATA_MODE);  
+  for (int i=0; i<len; i++) {
+    _i2c.write(data[i]);  // Write Data   
+  }
+  _i2c.stop();
+
+//  setDisplayOn();
 }
 
 void SSD1308::writeChar(char chr) {
 //#ifdef SSD1308_USE_FONT
+
   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 ); 
+//     const uint8_t b = fontData[char_index][i];     
+//     sendData( b ); 
+     sendData( fontData[char_index][i] );      
   }
+
 //#endif
 }
 
@@ -137,14 +215,15 @@
 }
 
 void SSD1308::sendCommands(uint8_t len, uint8_t* commands) {
-//  I2Cdev::writeBytes(m_devAddr, COMMAND_MODE, len, commands);
 
-  int i;
- 
+//  I2Cdev::writeBytes(m_devAddr, COMMAND_MODE, len, commands);
+//  Note this original code is not correct, continuationbit is set!
+
   _i2c.start();
   _i2c.write(_writeOpcode);
-  _i2c.write(COMMAND_MODE);  
-  for (i=0; i<len ; i++) {
+  
+  for (int i=0; i<len ; i++) {
+    _i2c.write(COMMAND_MODE);      
     _i2c.write(commands[i]);  // Write Commands   
   }
   _i2c.stop();
@@ -165,18 +244,18 @@
 void SSD1308::sendData(uint8_t len, uint8_t* data) {
 //  I2Cdev::writeBytes(m_devAddr, DATA_MODE, len, data);
   
-  int i;
- 
   _i2c.start();
   _i2c.write(_writeOpcode);
   _i2c.write(DATA_MODE);  
-  for (i=0; i<len ; i++) {
+  for (int i=0; i<len ; i++) {
     _i2c.write(data[i]);  // Write Data   
   }
   _i2c.stop();
     
 }
 
+
+
 void SSD1308::setHorizontalAddressingMode(){
   setMemoryAddressingMode(HORIZONTAL_ADDRESSING_MODE); 
 }
@@ -194,6 +273,17 @@
   sendCommands(2, cmds); 
 }
 
+void SSD1308::setPageAddress(uint8_t start, uint8_t end) {
+  uint8_t data[3] = { SET_PAGE_ADDRESS, start, end };
+  sendCommands(3, data);  
+}
+
+void SSD1308::setColumnAddress(uint8_t start, uint8_t end) {
+  uint8_t data[3] = { SET_COLUMN_ADDRESS, start, end };
+  sendCommands(3, data);  
+}
+
+
 void SSD1308::setDisplayOn() {
   sendCommand(SET_DISPLAY_POWER_ON);
 }
@@ -210,12 +300,27 @@
   }
 }
 
-void SSD1308::setPageAddress(uint8_t start, uint8_t end) {
-  uint8_t data[3] = { SET_PAGE_ADDRESS, start, end };
-  sendCommands(3, data);  
+void SSD1308::setDisplayNormal() {
+  sendCommand(SET_NORMAL_DISPLAY);
+}
+
+
+void SSD1308::setDisplayInverse() {
+  sendCommand(SET_INVERSE_DISPLAY);
 }
 
-void SSD1308::setColumnAddress(uint8_t start, uint8_t end) {
-  uint8_t data[3] = { SET_COLUMN_ADDRESS, start, end };
-  sendCommands(3, data);  
+
+// Low level Init
+// Init the configuration registers in accordance with the datasheet
+//
+void SSD1308::_init() {
+  setHorizontalAddressingMode();
+  clearDisplay();
+  
+  sendCommand(SET_DISPLAY_POWER_OFF);
+    
+  sendCommand(SET_NORMAL_DISPLAY);  
+  
+  sendCommand(SET_DISPLAY_POWER_ON);  
 }
+