SSD1308 128x64 OLED Driver with I2C interface

Dependents:   sense xadow_m0_ada_gps xadow_m0_SD_Hello sense-DHT11 ... more

See http://mbed.org/users/wim/notebook/oled-display-with-ssd1308-driver/#c6729

Revision:
1:b7e8f5139026
Parent:
0:300d08d9b058
Child:
2:16c84a134393
--- a/SSD1308.cpp	Wed Jul 18 14:10:57 2012 +0000
+++ b/SSD1308.cpp	Sat Jul 21 12:49:33 2012 +0000
@@ -1,8 +1,8 @@
-// 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
-//
+/**  @file 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
+*/
 // The original code by Andrew Schamp 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
 // Some parts also mashed up from Graphic Library for driving monochrome displays based on the PCD8544,
@@ -13,7 +13,8 @@
 //   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
 Copyright (c) 2012 WH (mbed port)
@@ -35,14 +36,11 @@
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
-===============================================
+================================================================================
 */
 #include "mbed.h"
 #include "SSD1308.h"
 
-//#define SSD1308_USE_FONT
-//#ifdef SSD1308_USE_FONT
-
 //#include "font_3x5.h"
 //#include "font_5x7.h"
 //#include "font_6x8.h"
@@ -50,12 +48,12 @@
 //#include "font_8x12.h"
 //#include "font_16x20.h"
 #include "font_16x24.h"
-//#endif
 
-//@brief Constructor
-//@param I2C &i2c reference to i2c
-//@param uint8_t deviceAddress slaveaddress
-//
+/**
+ *@brief Constructor
+ *@param I2C &i2c reference to i2c
+ *@param uint8_t deviceAddress slaveaddress
+ */
 SSD1308::SSD1308(I2C &i2c, uint8_t deviceAddress) : _i2c(i2c) {
 //  m_devAddr = deviceAddress; 
   
@@ -65,8 +63,8 @@
   initialize(); 
 }
 
-// @brief High level Init, most settings remain at Power-On reset value
-//
+/** @brief High level Init, most settings remain at Power-On reset value
+ */
 void SSD1308::initialize() {
   setHorizontalAddressingMode();
 
@@ -78,8 +76,8 @@
 }
 
 
-// @brief clear the display
-//
+/** @brief clear the display
+*/
 #if(0)
 // Standard version
 void SSD1308::clearDisplay() {
@@ -121,9 +119,9 @@
 #endif
 
 
-// @brief fill the display
-// @param uint8_t pattern fillpattern vertical patch or 8 bits 
-//
+/** @brief fill the display
+ *  @param uint8_t pattern fillpattern vertical patch or 8 bits 
+*/
 #if(0)
 //Standard version
 void SSD1308::fillDisplay(uint8_t pattern) {
@@ -171,13 +169,13 @@
 #endif
 
 
-// @brief write a bitmap to the display
-// @param uint8_t* data pointer to bitmap
-// @param uint8_t start_page begin page   (0..MAX_PAGE)
-// @param uint8_t end_page   end page     (start_page..MAX_PAGE)                     
-// @param uint8_t start_col  begin column (0..MAX_COL)
-// @param uint8_t end_col    end column   (start_col..MAX_COL)
-//
+/** @brief write a bitmap to the display
+ *  @param uint8_t* data pointer to bitmap
+ *  @param uint8_t start_page begin page   (0..MAX_PAGE)
+ *  @param uint8_t end_page   end page     (start_page..MAX_PAGE)                     
+ *  @param uint8_t start_col  begin column (0..MAX_COL)
+ *  @param uint8_t end_col    end column   (start_col..MAX_COL)
+*/
 #if(0)
 //Standard version
 void SSD1308::writeBitmap(int len, uint8_t* data) {
@@ -225,10 +223,100 @@
 #endif
 
 
-// @brief Write single character to the display using the 8x8 fontable
-// @brief Start at current cursor location
-// @param char chr character to write
+/** @brief write a progressbar to the display, Max Width is 52 pixels
+ *  @param uint8_t page begin page   (0..MAX_PAGE)
+ *  @param uint8_t col  begin column (0..MAX_COL)
+ *  @param int percentage value      (0..100)
+*/
+#define PRG_MAX_SCALE     50
+#define PRG_LEFT_EDGE   0xFF
+#define PRG_RIGHT_EDGE  0xFF
+#define PRG_ACTIVE      0xFF
+#define PRG_NOT_ACTIVE  0x81
+
+#if(0)
+//Standard version
+void SSD1308::writeProgressBar(uint8_t page, uint8_t col, int percentage) {
+  uint8_t scale_value;
+  
+  if (percentage < 0) {
+    scale_value = 0;
+  } else if (percentage > 100) {
+      scale_value = PRG_MAX_SCALE;
+  }
+  else {
+    scale_value = (percentage * PRG_MAX_SCALE) / 100; 
+  }      
+      
+  //setDisplayOff();
+  setPageAddress(page, page);  
+  setColumnAddress(col, MAX_COL); 
+  
+  _sendData(PRG_LEFT_EDGE);
+
+  for (uint8_t col = 0; col < scale_value; col++) {
+      _sendData(PRG_ACTIVE);
+  }
+
+  for (uint8_t col = scale_value; col < PRG_MAX_SCALE; col++) {
+      _sendData(PRG_NOT_ACTIVE);
+  }
+
+  _sendData(PRG_RIGHT_EDGE);    
+  
+  //setDisplayOn();
+}
+#else
+
+//Optimised version
+// Save lots of I2C S,P, address and datacommands:
+// Send S, address, DATA_MODE, data, data, data,...., P
 //
+void SSD1308::writeProgressBar(uint8_t page, uint8_t col, int percentage) {
+  uint8_t scale_value;
+  
+  if (percentage < 0) {
+    scale_value = 0;
+  } else if (percentage > 100) {
+      scale_value = PRG_MAX_SCALE;
+  }
+  else {
+    scale_value = (percentage * PRG_MAX_SCALE) / 100; 
+  }      
+      
+  //setDisplayOff();
+  setPageAddress(page, page);  
+  setColumnAddress(col, MAX_COL); 
+
+  _i2c.start();
+  _i2c.write(_writeOpcode);
+  _i2c.write(DATA_MODE);  
+
+  _i2c.write(PRG_LEFT_EDGE);  // Write Data         
+
+  for (uint8_t col = 0; col < scale_value; col++) {
+     _i2c.write(PRG_ACTIVE);  // Write Data                       
+  }
+
+  for (uint8_t col = scale_value; col < PRG_MAX_SCALE; col++) {
+     _i2c.write(PRG_NOT_ACTIVE);  // Write Data                 
+  }
+
+  _i2c.write(PRG_RIGHT_EDGE);  // Write Data           
+
+  _i2c.stop();
+    
+  //setDisplayOn();
+}
+#endif
+
+
+
+
+/** @brief Write single character to the display using the 8x8 fontable
+ *  @brief Start at current cursor location
+ *  @param char chr character to write
+*/
 void SSD1308::writeChar(char chr) {
 
   const uint8_t char_index = chr - 0x20;
@@ -245,13 +333,13 @@
 }
 
 
-// @brief Write a string to the display using the 8x8 font
-// @brief Start at selected cursor location
-// @param uint8_t row  row number    (0...ROWS/FONT_HEIGHT)
-// @param uint8_t col  column number (0...COLUMNS/FONT_WIDTH)
-// @param uint16_t len number of chars in text
-// @param const char * text pointer to text
-//
+/** @brief Write a string to the display using the 8x8 font
+ *  @brief Start at selected cursor location
+ *  @param uint8_t row  row number    (0...ROWS/FONT_HEIGHT)
+ *  @param uint8_t col  column number (0...COLUMNS/FONT_WIDTH)
+ *  @param uint16_t len number of chars in text
+ *  @param const char * text pointer to text
+ */
 void SSD1308::writeString(uint8_t row, uint8_t col, uint16_t len, const char * text) {
   uint16_t index = 0;
   setPageAddress(row, MAX_PAGE);
@@ -285,11 +373,11 @@
 
 
 
-// @brief Write large character (16x24 font)
-// @param uint8_t row  row number    (0...MAX_ROW)
-// @param uint8_t col  column number (0...MAX_COL)
-// @param char chr     Used for displaying numbers 0 - 9 and '+', '-', '.'
-//
+/** @brief Write large character (16x24 font)
+ *  @param uint8_t row  row number    (0...MAX_ROW)
+ *  @param uint8_t col  column number (0...MAX_COL)
+ *  @param char chr     Used for displaying numbers 0 - 9 and '+', '-', '.'
+ */
 void SSD1308::writeBigChar(uint8_t row, uint8_t col, char chr) {
 
   writeBitmap((uint8_t*) font_16x24[int(chr) - FONT16x24_START],
@@ -298,8 +386,8 @@
 }
 
 
-// @brief Write command that has no parameters
-// 
+/** @brief Write command that has no parameters
+*/ 
 void SSD1308::_sendCommand(uint8_t command) {
 //  I2Cdev::writeByte(m_devAddr, COMMAND_MODE, command);
 
@@ -321,8 +409,8 @@
 
 }
 
-// @brief Write command that has one parameter
-// 
+/** @brief Write command that has one parameter
+*/ 
 void SSD1308::_sendCommand(uint8_t command, uint8_t param1) {
 
 //  Note continuationbit is set, so COMMAND_MODE must be
@@ -340,8 +428,8 @@
   
 }
 
-// @brief Write command that has two parameters
-// 
+/** @brief 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
@@ -362,8 +450,8 @@
 }
 
 #if(0)
-// @brief Write command that has multiple parameters
-// 
+/** @brief Write command that has multiple parameters
+*/ 
 void SSD1308::_sendCommands(uint8_t len, uint8_t* commands) {
 
 //  I2Cdev::writeBytes(m_devAddr, COMMAND_MODE, len, commands);
@@ -382,10 +470,10 @@
 }
 #endif
 
-// @brief Write databyte to display
-// @brief Start at current cursor location
-// @param uint8_t data databyte to write
-//
+/** @brief Write databyte to display
+ *  @brief Start at current cursor location
+ *  @param uint8_t data databyte to write
+*/
 void SSD1308::_sendData(uint8_t data){
 //  I2Cdev::writeByte(m_devAddr, DATA_MODE, data);
 
@@ -397,11 +485,11 @@
   
 }
 
-// @brief Write len bytes from buffer data to display, 
-// @brief Start at current cursor location
-// @param uint8_t len number of bytes to write 
-// @param uint8_t* data pointer to data
-//
+/** @brief Write len bytes from buffer data to display, 
+ *  @brief Start at current cursor location
+ *  @param uint8_t len number of bytes to write 
+ *  @param uint8_t* data pointer to data
+*/
 void SSD1308::_sendData(uint8_t len, uint8_t* data) {
 //  I2Cdev::writeBytes(m_devAddr, DATA_MODE, len, data);
   
@@ -435,44 +523,46 @@
 }
 
 
-// @param uint8_t start startpage (valid range 0..MAX_PAGE)
-// @param uint8_t end   endpage   (valid range start..MAX_PAGE)
-//
+/** @param uint8_t start startpage (valid range 0..MAX_PAGE)
+ *  @param uint8_t end   endpage   (valid range start..MAX_PAGE)
+ */
 void SSD1308::setPageAddress(uint8_t start, uint8_t end) {
 
   _sendCommand(SET_PAGE_ADDRESS, start, end);   
 }
 
 
-// @param uint8_t start startcolumn (valid range 0..MAX_COL)
-// @param uint8_t end   endcolumn   (valid range start..MAX_COL)
-//
+/** @param uint8_t start startcolumn (valid range 0..MAX_COL)
+ *  @param uint8_t end   endcolumn   (valid range start..MAX_COL)
+ */
 void SSD1308::setColumnAddress(uint8_t start, uint8_t end) {
 
   _sendCommand(SET_COLUMN_ADDRESS, start, end);     
 }
 
-// @brief Set Contrast
-// @param uint8_t contrast (valid range 0x00 (lowest) - 0xFF (highest))
+/** @brief Set Contrast
+ *  @param uint8_t contrast (valid range 0x00 (lowest) - 0xFF (highest))
+*/
 void SSD1308::setContrastControl(uint8_t contrast) {
   
     _sendCommand(SET_CONTRAST, contrast);  
 } 
 
-// @brief Enable Display
-// 
+/** @brief Enable Display
+*/ 
 void SSD1308::setDisplayOn() {
   _sendCommand(SET_DISPLAY_POWER_ON);
 }
 
-// @brief Disable Display
-// 
+/** @brief Disable Display
+*/ 
 void SSD1308::setDisplayOff() {
   _sendCommand(SET_DISPLAY_POWER_OFF);
 }
 
-// @brief Enable or Disable Display
-// @param bool on
+/** @brief Enable or Disable Display
+ *  @param bool on
+ */
 void SSD1308::setDisplayPower(bool on) {
   if (on) {
     setDisplayOn();
@@ -481,21 +571,21 @@
   }
 }
 
-// @brief White pixels on Black background
-// 
+/** @brief Show White pixels on Black background
+ */ 
 void SSD1308::setDisplayNormal() {
   _sendCommand(SET_NORMAL_DISPLAY);
 }
 
-// @brief Black pixels on White background
-// 
+/** @brief Show Black pixels on White background
+ */ 
 void SSD1308::setDisplayInverse() {
   _sendCommand(SET_INVERSE_DISPLAY);
 }
 
-// @brief Blink display by fading in and out over a set number of frames
-// @param bool on
-//
+/** @brief Blink display by fading in and out over a set number of frames
+ *  @param bool on
+ */
 void SSD1308::setDisplayBlink(bool on){
   if (on) {
     _sendCommand(SET_FADE_BLINK, (BLINK_ENABLE | FADE_INTERVAL_128_FRAMES));
@@ -506,9 +596,9 @@
 }       
 
 
-// @brief Fade out display in set number of frames
-// @param bool on
-//
+/** @brief Fade out display in set number of frames
+ *  @param bool on
+ */
 void SSD1308::setDisplayFade(bool on) {
   if (on) {
     _sendCommand(SET_FADE_BLINK, (FADE_OUT_ENABLE | FADE_INTERVAL_128_FRAMES));
@@ -518,10 +608,10 @@
   }
 }    
 
-// @brief Display Flip (Left/Right, Up/Down)
-// @param bool left flip Left/Right
-// @param bool down flip Up/Down
-//
+/** @brief Display Flip (Left/Right, Up/Down)
+ *  @param bool left flip Left/Right
+ *  @param bool down flip Up/Down
+ */
 void SSD1308::setDisplayFlip(bool left, bool down) {
   if (left) {
     // column address   0 is mapped to SEG0 (Reset)    
@@ -543,8 +633,8 @@
 
 }
 
-// @brief Sets Internal Iref
-//
+/** @brief Sets Internal Iref
+ */
 void SSD1308::setInternalIref() {
 //  uint8_t cmds[2] = {SET_IREF_SELECTION, INTERNAL_IREF};
 //  _sendCommands(2, cmds); 
@@ -552,8 +642,8 @@
   _sendCommand(SET_IREF_SELECTION, INTERNAL_IREF);   
 }
 
-// @brief Sets External Iref (default)
-//
+/** @brief Sets External Iref (default)
+ */
 void SSD1308::setExternalIref() {
 //  uint8_t cmds[2] = {SET_IREF_SELECTION, EXTERNAL_IREF};
 //  _sendCommands(2, cmds); 
@@ -561,9 +651,9 @@
 }
 
 
-// @brief Low level Init
-// @brief Init the configuration registers in accordance with the datasheet
-//
+/** @brief Low level Init
+ *  @brief Init the configuration registers in accordance with the datasheet
+ */
 void SSD1308::_init() {
 
 //not complete yet