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

Files at this revision

API Documentation at this revision

Comitter:
wim
Date:
Mon Jul 23 20:03:18 2012 +0000
Parent:
1:b7e8f5139026
Child:
3:fa18169dd7e6
Commit message:
Updated methods

Changed in this revision

SSD1308.cpp Show annotated file Show diff for this revision Revisions of this file
SSD1308.h Show annotated file Show diff for this revision Revisions of this file
--- a/SSD1308.cpp	Sat Jul 21 12:49:33 2012 +0000
+++ b/SSD1308.cpp	Mon Jul 23 20:03:18 2012 +0000
@@ -55,7 +55,6 @@
  *@param uint8_t deviceAddress slaveaddress
  */
 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  
@@ -223,7 +222,7 @@
 #endif
 
 
-/** @brief write a progressbar to the display, Max Width is 52 pixels
+/** @brief write a progressbar to the display, Width is (PRG_MAX_SCALE + 2) 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)
@@ -232,6 +231,7 @@
 #define PRG_LEFT_EDGE   0xFF
 #define PRG_RIGHT_EDGE  0xFF
 #define PRG_ACTIVE      0xFF
+//#define PRG_ACTIVE      0xBD
 #define PRG_NOT_ACTIVE  0x81
 
 #if(0)
@@ -239,10 +239,10 @@
 void SSD1308::writeProgressBar(uint8_t page, uint8_t col, int percentage) {
   uint8_t scale_value;
   
-  if (percentage < 0) {
+  if (percentage <= 0) {
     scale_value = 0;
-  } else if (percentage > 100) {
-      scale_value = PRG_MAX_SCALE;
+  } else if (percentage >= 100) {
+      scale_value = PRG_MAX_SCALE - 1;
   }
   else {
     scale_value = (percentage * PRG_MAX_SCALE) / 100; 
@@ -257,8 +257,10 @@
   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_ACTIVE);
+  
+  for (uint8_t col = (scale_value+1); col < PRG_MAX_SCALE; col++) {
       _sendData(PRG_NOT_ACTIVE);
   }
 
@@ -275,10 +277,10 @@
 void SSD1308::writeProgressBar(uint8_t page, uint8_t col, int percentage) {
   uint8_t scale_value;
   
-  if (percentage < 0) {
+  if (percentage <= 0) {
     scale_value = 0;
-  } else if (percentage > 100) {
-      scale_value = PRG_MAX_SCALE;
+  } else if (percentage >= 100) {
+      scale_value = PRG_MAX_SCALE - 1 ;
   }
   else {
     scale_value = (percentage * PRG_MAX_SCALE) / 100; 
@@ -298,7 +300,9 @@
      _i2c.write(PRG_ACTIVE);  // Write Data                       
   }
 
-  for (uint8_t col = scale_value; col < PRG_MAX_SCALE; col++) {
+  _i2c.write(PRG_ACTIVE);  // Write Data                       
+     
+  for (uint8_t col = (scale_value+1); col < PRG_MAX_SCALE; col++) {
      _i2c.write(PRG_NOT_ACTIVE);  // Write Data                 
   }
 
@@ -310,8 +314,53 @@
 }
 #endif
 
+/** @brief write a level meter to the display, Width is (PRG_MAX_SCALE + 2) 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)
+*/
+//Optimised version
+// Save lots of I2C S,P, address and datacommands:
+// Send S, address, DATA_MODE, data, data, data,...., P
+//
+void SSD1308::writeLevelBar(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 - 1;
+  }
+  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_NOT_ACTIVE);  // Write Data                       
+  }
+
+  _i2c.write(PRG_ACTIVE);  // Write Data at active meterlevel
+  
+  for (uint8_t col = scale_value+1; col < PRG_MAX_SCALE; col++) {
+     _i2c.write(PRG_NOT_ACTIVE);  // Write Data                 
+  }
+
+  _i2c.write(PRG_RIGHT_EDGE);  // Write Data           
+
+  _i2c.stop();
+    
+  //setDisplayOn();
+}
 
 /** @brief Write single character to the display using the 8x8 fontable
  *  @brief Start at current cursor location
@@ -334,14 +383,16 @@
 
 
 /** @brief Write a string to the display using the 8x8 font
- *  @brief Start at selected cursor location
+ *  @brief Start at selected cursor location, text will wrap around until it is done
  *  @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) {
+void SSD1308::writeString(uint8_t row, uint8_t col, const char * text) {
   uint16_t index = 0;
+  uint16_t len = strlen(text);
+  
   setPageAddress(row, MAX_PAGE);
   const uint8_t col_addr = FONT8x8_WIDTH*col;
   setColumnAddress(col_addr, MAX_COL);
@@ -449,6 +500,68 @@
   
 }
 
+/** @brief Write command that has five parameters
+*/ 
+void SSD1308::_sendCommand(uint8_t command, uint8_t param1, uint8_t param2,
+                                            uint8_t param3, uint8_t param4,
+                                            uint8_t param5) {
+
+//  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.write(COMMAND_MODE);      
+  _i2c.write(param3);        // Write Param3   
+  _i2c.write(COMMAND_MODE);      
+  _i2c.write(param4);        // Write Param4   
+  _i2c.write(COMMAND_MODE);      
+  _i2c.write(param5);        // Write Param5   
+
+  _i2c.stop();
+  
+}
+
+
+/** @brief Write command that has six parameters
+*/ 
+void SSD1308::_sendCommand(uint8_t command, uint8_t param1, uint8_t param2,
+                                            uint8_t param3, uint8_t param4,
+                                            uint8_t param5, uint8_t param6) {
+
+//  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.write(COMMAND_MODE);      
+  _i2c.write(param3);        // Write Param3   
+  _i2c.write(COMMAND_MODE);      
+  _i2c.write(param4);        // Write Param4   
+  _i2c.write(COMMAND_MODE);      
+  _i2c.write(param5);        // Write Param5   
+  _i2c.write(COMMAND_MODE);      
+  _i2c.write(param6);        // Write Param6   
+
+  _i2c.stop();
+  
+}
+
+
 #if(0)
 /** @brief Write command that has multiple parameters
 */ 
@@ -504,19 +617,30 @@
 }
 
 
-
+/** @brief Set Horizontal Addressing Mode (cursor incr left-to-right, top-to-bottom)
+ * 
+ */
 void SSD1308::setHorizontalAddressingMode(){
   setMemoryAddressingMode(HORIZONTAL_ADDRESSING_MODE); 
 }
 
+/** @brief Set Vertical Addressing Mode  (cursor incr top-to-bottom, left-to-right)
+ * 
+ */
 void SSD1308::setVerticalAddressingMode() {
   setMemoryAddressingMode(VERTICAL_ADDRESSING_MODE); 
 }
 
+/** @brief Set Page Addressing Mode  (cursor incr left-to-right)
+ * 
+ */
 void SSD1308::setPageAddressingMode(){
   setMemoryAddressingMode(PAGE_ADDRESSING_MODE); 
 }
     
+/** @brief Set Addressing Mode
+ *  @param uint8_t mode 
+ */
 void SSD1308::setMemoryAddressingMode(uint8_t mode){
 
   _sendCommand(SET_MEMORY_ADDRESSING_MODE, mode);   
@@ -540,6 +664,44 @@
   _sendCommand(SET_COLUMN_ADDRESS, start, end);     
 }
 
+/** 
+ *  @brief Set Display StartLine, takes one byte, 0x00-0x3F
+ *  @param uint8_t line startline (valid range 0..MAX_ROWS)
+ */  
+void SSD1308::setDisplayStartLine(uint8_t line) {
+
+  line = line & MAX_ROW;
+   
+  _sendCommand(SET_DISPLAY_START_LINE | line);     
+}
+
+
+/** 
+ *  @brief Set Column Start (for Page Addressing Mode only)
+ *  @param uint8_t column column start (valid range 0..MAX_COL)
+ */  
+void SSD1308::setColumnStartForPageAddressingMode(uint8_t column) {
+
+  column = column & MAX_COL;
+
+  _sendCommand(SET_LOWER_COLUMN  | ( column     & 0x0F));  // lower nibble   
+  _sendCommand(SET_HIGHER_COLUMN | ((column>>4) & 0x0F));  // higher nibble     
+}
+
+
+/** 
+ *  @brief Set Page Start (for Page Addressing Mode only)
+ *  @param uint8_t page page start (valid range PAGE0 - PAGE7)
+ */    
+void SSD1308::setPageStartForPageAddressingMode(uint8_t page) {
+
+  page = page & MAX_PAGE;
+
+  _sendCommand(SET_PAGE_START_ADDRESS | page);
+ 
+}
+
+
 /** @brief Set Contrast
  *  @param uint8_t contrast (valid range 0x00 (lowest) - 0xFF (highest))
 */
@@ -651,31 +813,135 @@
 }
 
 
+/** @brief Shows All Pixels On
+ */
+void SSD1308::setEntireDisplayOn(){
+  _sendCommand(SET_ENTIRE_DISPLAY_ON); 
+}
+
+/** @brief Shows Pixels as RAM content
+ */
+void SSD1308::setEntireDisplayRAM(){
+  _sendCommand(SET_DISPLAY_GDDRAM); 
+}
+
+/** @brief Shows Pixels On or as RAM content
+ *  @param bool on (true is All on, false is RAM content)
+ */
+void SSD1308::setEntireDisplay(bool on){
+  if (on) {
+    setEntireDisplayOn();  // All Pixels on
+  }
+  else {  
+    setEntireDisplayRAM(); // Pixels are RAM content
+  }
+}
+
+
+/** @brief Horizontal scroll by one column per interval
+ *  @param bool left select Left/Right scroll
+ *  @param uint8_t start_page begin page   (0..MAX_PAGE)
+ *  @param uint8_t end_page   end page     (start_page..MAX_PAGE)                     
+ *  @param uint8_t interval   scroll interval in frames (see codes above)                      
+ */  
+void SSD1308::setContinuousHorizontalScroll(bool left, uint8_t start_page, uint8_t end_page, uint8_t interval) {
+  if (left) {
+    _sendCommand(SET_LEFT_HOR_SCROLL, 0x00, start_page, interval, end_page, 0x00, 0xFF);  // Scroll Left
+  }
+  else {  
+    _sendCommand(SET_RIGHT_HOR_SCROLL, 0x00, start_page, interval, end_page, 0x00, 0xFF); // Scroll Right  
+  }
+
+}
+
+
+/** @brief Horizontal and Vertical scroll by one column per interval
+ *  @param bool left select Left/Right scroll
+ *  @param uint8_t start_page begin page   (0..MAX_PAGE)
+ *  @param uint8_t end_page   end page     (start_page..MAX_PAGE)                     
+ *  @param uint8_t offset     vert offset  (0x01..0x63)                       
+ *  @param uint8_t interval   scroll interval in frames (see codes above)                       
+ */  
+void SSD1308::setContinuousVerticalAndHorizontalScroll(bool left, uint8_t start_page, uint8_t end_page, 
+                                                       uint8_t offset, uint8_t interval) {
+  if (left) {
+    _sendCommand(SET_VERT_LEFT_HOR_SCROLL, 0x00, start_page, interval, end_page, offset);  // Scroll Left
+  }
+  else {  
+    _sendCommand(SET_VERT_RIGHT_HOR_SCROLL, 0x00, start_page, interval, end_page, offset); // Scroll Right  
+  }
+                                                       
+}    
+
+/** @brief Set Vertical scroll area
+ *  @param uint8_t topRowsFixed      fixed rows   (0..MAX_ROW)                     
+ *  @param uint8_t scrollRowsoffset  scroll rows  (topRowsFixed..ROWS)                       
+ */  
+void SSD1308::setVerticalScrollArea(uint8_t topRowsFixed, uint8_t scrollRows) { 
+   
+  if ((topRowsFixed + scrollRows) > ROWS) {
+     scrollRows = ROWS - topRowsFixed; 
+  };
+  
+  _sendCommand(SET_VERTICAL_SCROLL_AREA, topRowsFixed, scrollRows); 
+}
+
+/** @brief Activate or Deactivate Horizontal and Vertical scroll
+ *  @brief Note: after deactivating scrolling, the RAM data needs to be rewritten
+ *  @param bool on activate scroll 
+ */  
+void SSD1308::setDisplayScroll(bool on) {
+  if (on) {
+    _sendCommand(SET_ACTIVATE_SCROLL);   // Scroll on
+  }
+  else {  
+    _sendCommand(SET_DEACTIVATE_SCROLL); // Scroll off  
+  }
+}
+
+
+
 /** @brief Low level Init
  *  @brief Init the configuration registers in accordance with the datasheet
  */
 void SSD1308::_init() {
 
-//not complete yet  
-  _sendCommand(SET_DISPLAY_POWER_OFF);
+  _sendCommand(SET_DISPLAY_POWER_OFF);      // 0xAE
   
   // 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);    
+  // row address   0 is mapped to COM0 (Reset)      
+  _sendCommand(SET_SEGMENT_REMAP_0);        // 0xA0 (Reset)
+  _sendCommand(SET_COMMON_REMAP_0);         // 0xC0 (Reset) 
+
+  setDisplayStartLine(0);                   // 0x40 (Reset) 
   
-  _sendCommand(SET_COMMON_CONF, COMMON_BASE | COMMON_ALTERNATIVE | COMMON_LEFTRIGHT_NORMAL);   
+  _sendCommand(SET_COMMON_CONF, COMMON_BASE | COMMON_ALTERNATIVE | COMMON_LEFTRIGHT_NORMAL); // 0xDA, 0x12 (Reset)
 
-  setHorizontalAddressingMode(); // (Non-Reset)
-  
-  setExternalIref(); // (Reset)
+  // Pagemode or Horizontal mode
+//  setPageAddressingMode();                  // 0x20, 0x02 (Reset)  
+//  setColumnStartForPageAddressingMode(0);   // 0x00, 0x10 (Reset = Column 0)
+//  setPageStartForPageAddressingMode(PAGE_0);// 0xBO       (Reset = Page 0)
+  setHorizontalAddressingMode();            // 0x20, 0x00 (Non-Reset)
+  setColumnAddress(0, MAX_COL);             // 0x21, 0x00, 0x37 (Reset)
+  setPageAddress(0, MAX_PAGE);              // 0x22, 0x00, 0x07 (Reset)
 
-  _sendCommand(SET_CONTRAST, 0x7F);  // (Reset)
+  setExternalIref();                        // 0xAD, 0x10 (Reset)
+  
+  _sendCommand(SET_DISPLAY_CLOCK, 0x70);    // 0xD5, 0x70 (Reset = 0x80)
+  _sendCommand(SET_PRECHARGE_TIME, 0x21);   // 0xD9, 0x21 (Reset = 0x22)
+  _sendCommand(SET_VCOMH_DESELECT_LEVEL, 0x30); // 0xDB, 0x30 (Reset = 0x20)  
+  _sendCommand(SET_MULTIPLEX_RATIO, 0x3F);  // 0xA8, 0x3F (Reset)  
+  _sendCommand(SET_DISPLAY_OFFSET, 0x00);   // 0xD3, 0x00 (Reset)  
+  
+  _sendCommand(SET_CONTRAST, 0x7F);         // 0x81, 0x7F (Reset)
 
-  _sendCommand(SET_NORMAL_DISPLAY);  
+  _sendCommand(SET_NORMAL_DISPLAY);         // 0xA6 (Reset)
+  
+  setEntireDisplayRAM();                    // 0xA4 (Reset)
+  setDisplayScroll(false);
   
   clearDisplay();   
   
-  _sendCommand(SET_DISPLAY_POWER_ON);
+  _sendCommand(SET_DISPLAY_POWER_ON);       // 0xAF
 }
 
--- a/SSD1308.h	Sat Jul 21 12:49:33 2012 +0000
+++ b/SSD1308.h	Mon Jul 23 20:03:18 2012 +0000
@@ -53,6 +53,7 @@
 #define COLUMNS                    128
 #define PAGES                      (ROWS / 8)
 #define MAX_PAGE                   (PAGES - 1)
+#define MAX_ROW                    (ROWS - 1)
 #define MAX_COL                    (COLUMNS - 1)
 
 // Character dimensions 8x8 font
@@ -63,6 +64,9 @@
 #define DATA_MODE                  0x40
 
 // Commands and Parameter defines
+#define SET_LOWER_COLUMN           0x00 // | with lower nibble  (Page mode only)
+#define SET_HIGHER_COLUMN          0x10 // | with higher nibble (Page mode only)
+
 #define HORIZONTAL_ADDRESSING_MODE 0x00
 #define VERTICAL_ADDRESSING_MODE   0x01
 #define PAGE_ADDRESSING_MODE       0x02
@@ -85,7 +89,7 @@
                                         //  bit5-4 = 0, fade/blink mode
                                         //  bit3-0 = Time interval in frames 
 
-#define SET_DISPLAY_START_LINE     0x40 // | with a row number 0-63 to set start row. Reset = 0
+#define SET_DISPLAY_START_LINE     0x40 // | with a row number 0-63 to set start row. (Reset = 0)
 
 #define SET_CONTRAST               0x81 // takes one byte, 0x00 - 0xFF
 
@@ -115,7 +119,7 @@
 #define PAGE5                      0x05
 #define PAGE6                      0x06
 #define PAGE7                      0x07
-#define SET_PAGE_START_ADDRESS     0xB0 // | with a page number to get start address
+#define SET_PAGE_START_ADDRESS     0xB0 // | with a page number to get start address (Page mode only)
 
 #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
@@ -169,41 +173,86 @@
 class SSD1308 : public Stream {
   public:
     
-// Constructor
-    // takes 8bit I2C address to use for the controller (0x78 by default, assumes D/C# (pin 13) grounded)
+/**
+  *@brief Constructor
+  *@param I2C &i2c reference to i2c,
+  *@param uint8_t deviceAddress slaveaddress (8bit to use for the controller (0x78 by default, assumes D/C# (pin 13) grounded)
+ */    
     SSD1308(I2C &i2c, uint8_t address = SSD1308_DEF_SA);
 
 // High Level methods
+
+/** @brief High level Init, most settings remain at Power-On reset value
+ */
     void initialize();
 
+/** @brief clear the display
+*/
     void clearDisplay();
-//    void fillDisplay(uint8_t pattern); // pattern     
+
+
+/** @brief fill the display
+ *  @param uint8_t pattern fillpattern vertical patch or 8 bits 
+*/ 
     void fillDisplay(uint8_t pattern = 0x00,
                      uint8_t start_page=0, uint8_t end_page=MAX_PAGE,
                      uint8_t start_col=0, uint8_t end_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)
+*/  
     void writeBitmap(uint8_t* data,
                      uint8_t start_page=0, uint8_t end_page=MAX_PAGE,
                      uint8_t start_col=0, uint8_t end_col=MAX_COL);
     
+/** @brief write a level meter to the display, Width is (PRG_MAX_SCALE + 2) 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)
+*/
+    void writeProgressBar(uint8_t page, uint8_t col, int percentage);
 
-    void writeProgressBar(uint8_t page, uint8_t col, int percentage);
+
+/** @brief write a level meter to the display, Width is (PRG_MAX_SCALE + 2) 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)
+*/
+    void writeLevelBar(uint8_t page, uint8_t col, int percentage);
 
     //void setXY(uint8_t, uint8_t y);
     
     // Select inverted or normal text    
     void setInverted(bool inverted) { _inverted = inverted; };    
         
-    // write char at current cursor location
+/** @brief Write single character to the display using the 8x8 fontable
+ *  @brief Start at current cursor location
+ *  @param char chr character to write
+*/ 
     void writeChar(char chr);  
     
-    // write large char at cursor location    
+/** @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 writeBigChar(uint8_t row, uint8_t col, char chr);      
     
-    // 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);
-
+/** @brief Write a string to the display using the 8x8 font
+ *  @brief Start at selected cursor location, text will wrap around until it is done
+ *  @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 writeString(uint8_t row, uint8_t col, uint16_t len, const char* txt);
+    void writeString(uint8_t row, uint8_t col, const char* txt);
+    
     // Stream implementation - provides printf() interface
     // You would otherwise be forced to use writeChar() or writeString()
     virtual int _putc(int value) { writeChar(value); return 1; };
@@ -214,99 +263,226 @@
 //    virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0;
     
 // Medium Level methods
+
+/** @brief Set Horizontal Addressing Mode (cursor incr left-to-right, top-to-bottom)
+ * 
+ */
     void setHorizontalAddressingMode();
+    
+/** @brief Set Vertical Addressing Mode  (cursor incr top-to-bottom, left-to-right)
+ * 
+ */
     void setVerticalAddressingMode();
-    void setPageAddressingMode();
-    
-    void setMemoryAddressingMode(uint8_t mode);
     
-    // takes one byte, 0x00-0x0F
-    void setLowerColumnStartAddressForPageAddressingMode(uint8_t address);
+/** @brief Set Page Addressing Mode  (cursor incr left-to-right)
+ * 
+ */
+    void setPageAddressingMode();
+        
+/** @brief Set Addressing Mode
+ *  @param uint8_t mode 
+ */
+    void setMemoryAddressingMode(uint8_t mode);
+
+
+/** 
+ *  @brief Set Column Start (for Page Addressing Mode only)
+ *  @param uint8_t column column start (valid range 0..MAX_COLS)
+ */    
+    void setColumnStartForPageAddressingMode(uint8_t column);
     
-    // takes one byte, 0x10-0x1F
-    void setHigherColumnStartAddressForPageAddressingMode(uint8_t address);
-    
-    // takes two bytes, start address and end address of display data RAM
+/** 
+ *  @brief Set Page Start (for Page Addressing Mode only)
+ *  @param uint8_t page page start (valid range PAGE0 - PAGE7)
+ */    
+    void setPageStartForPageAddressingMode(uint8_t page);
+   
+
+
+/** @param uint8_t start startcolumn (valid range 0..MAX_COL)
+ *  @param uint8_t end   endcolumn   (valid range start..MAX_COL)
+ */   
     void setColumnAddress(uint8_t start, uint8_t end);
     
-    // takes two bytes, start address and end address of display data RAM
+/** @param uint8_t start startpage (valid range 0..MAX_PAGE)
+ *  @param uint8_t end   endpage   (valid range start..MAX_PAGE)
+ */  
     void setPageAddress(uint8_t start, uint8_t end);
     
-    // takes one byte, PAGE0 - PAGE7
-    void setPageStartForPageAddressingMode(uint8_t page);
-    
-    // takes one byte, 0x40-0x7F
+
+/** 
+ *  @brief Set Display StartLine, takes one byte, 0x00-0x3F
+ *  @param uint8_t line startline (valid range 0..MAX_ROWS)
+ */  
     void setDisplayStartLine(uint8_t line);
     
-    // takes one byte, 0x00 (lowest) - 0xFF (highest)
+/** @brief Set Contrast
+ *  @param uint8_t contrast (valid range 0x00 (lowest) - 0xFF (highest))
+*/    
     void setContrastControl(uint8_t contrast);
+
+
+/** @brief Shows All Pixels On
+ */
+    void setEntireDisplayOn();
     
-    void setEntireDisplayOn();
+/** @brief Shows Pixels as RAM content
+ */
     void setEntireDisplayRAM();
+    
+/** @brief Shows Pixels On or as RAM content
+ *  @param bool on (true is All on, false is RAM content)
+ */
     void setEntireDisplay(bool on);
     
-    // void setMultiplexRatio();
-    
+ 
+    // @brief Set Display line MPX Ratio, takes one byte, 0x00-0x3F
+    // @param uint8_t lines (valid range 0..MAX_ROWS)
+    void setMultiplexRatio(uint8_t lines);
+
+
+/** @brief Sets Internal Iref
+ */
     void setInternalIref();
+
+/** @brief Sets External Iref (default)
+ */   
     void setExternalIref();
-    
+
+
+/** @brief Enable Display
+*/    
     void setDisplayOn();
+
+/** @brief Disable Display
+*/     
     void setDisplayOff();
+
+/** @brief Enable or Disable Display
+ *  @param bool on
+ */    
     void setDisplayPower(bool on);
 
+/** @brief Show White pixels on Black background
+ */ 
     void setDisplayNormal();
+
+/** @brief Show Black pixels on White background
+ */   
     void setDisplayInverse();
+
+/** @brief Blink display by fading in and out over a set number of frames
+ *  @param bool on
+ */
+    void setDisplayBlink(bool on);  
     
-    void setDisplayBlink(bool on);       
+/** @brief Fade out display in set number of frames
+ *  @param bool on
+ */        
     void setDisplayFade(bool on);    
     
-    // Display Flip (Up/Down, Left/Right)
-    // 
+/** @brief Display Flip (Left/Right, Up/Down)
+ *  @param bool left flip Left/Right
+ *  @param bool down flip Up/Down
+ */  
     void setDisplayFlip(bool left, bool down);
 
-    // Set vertical shift by COM from 0 - 63 (0x00 - 0x3F)
-    // set to 0x00 after RESET
+    // Set vertical shift by COM from 0 - 63 (0x00 - 0x3F) (Reset = 0x00)
     void setDisplayOffset(uint8_t offset);
     
+    // Oscillator freq 0x00-0x0F (reset 0x08)
     // Divide ratio 0x00-0x0F, value +1 (reset 0x00)
-    // Oscillator freq 0x00-0x0F (reset 0x08)
     void setDisplayClock(uint8_t divideRatio, uint8_t oscFreq);
     
     // Phase1 0x01-0x0F period of up to 15 DCLK clocks (reset 0x02, 0 is invalid)
     // Phase2 0x01-0x0F period of up to 15 DCLK clocks (reset 0x02, 0 is invalid)
     void setPrechargePeriod(uint8_t phase1, uint8_t phase2);
     
+    // See defines above for levels
     void setVcomhDeselectLevel(uint8_t level);
-    
+
+
     // Command for no-operation
     void nop();
     
-    // End_page must not be less than start_page
-    void setContinuousHorizontalScroll(bool left, uint8_t start_page, uint8_t interval, uint8_t end_page);
-    // Horizontal scroll by one column per interval
-    // Offset = 1 (0x01) to 63 (0x3F)
-    void setContinuousVerticalAndHorizontalScroll(bool left, uint8_t start_page, uint8_t interval, uint8_t end_page, uint8_t offset);
+
+/** @brief Horizontal scroll by one column per interval
+ *  @param bool left select Left/Right scroll
+ *  @param uint8_t start_page begin page   (0..MAX_PAGE)
+ *  @param uint8_t end_page   end page     (start_page..MAX_PAGE)                     
+ *  @param uint8_t interval   scroll interval in frames (see codes above)                      
+ */  
+    void setContinuousHorizontalScroll(bool left, uint8_t start_page, uint8_t end_page, uint8_t interval);
+
+
+/** @brief Horizontal and Vertical scroll by one column per interval
+ *  @param bool left select Left/Right scroll
+ *  @param uint8_t start_page begin page   (0..MAX_PAGE)
+ *  @param uint8_t end_page   end page     (start_page..MAX_PAGE)                     
+ *  @param uint8_t offset     vert offset  (0x01..0x63)                       
+ *  @param uint8_t interval   scroll interval in frames (see codes above)                       
+ */  
+    void setContinuousVerticalAndHorizontalScroll(bool left, uint8_t start_page, uint8_t end_page, 
+                                                  uint8_t offset, uint8_t interval);
     
-    // Note, after deactivating scrolling, the RAM data needs to be rewritten
-    void deactivateScroll();
-    void activateScroll();
+/** @brief Activate or Deactivate Horizontal and Vertical scroll
+ *  @brief Note: after deactivating scrolling, the RAM data needs to be rewritten
+ *  @param bool on activate scroll 
+ */  
+    void setDisplayScroll(bool on);
     
+
+/** @brief Set Vertical scroll area
+ *  @param uint8_t topRowsFixed      fixed rows   (0..MAX_ROW)                     
+ *  @param uint8_t scrollRowsoffset  scroll rows  (topRowsFixed..MAX_ROW)                       
+ */  
     void setVerticalScrollArea(uint8_t topRowsFixed, uint8_t scrollRows); 
   
   private:
 
 // Low Level methods
-    // Sends a command and optional params to device
-    void _sendCommand(uint8_t command);  
+
+/** @brief Write command that has no parameters
+*/    
+    void _sendCommand(uint8_t command); 
+
+/** @brief Write command that has one parameter
+*/    
     void _sendCommand(uint8_t command, uint8_t param1);
+
+/** @brief Write command that has two parameters
+*/ 
     void _sendCommand(uint8_t command, uint8_t param1, uint8_t param2);              
 //    void sendCommands(uint8_t len, uint8_t* buf);
+
+/** @brief Write command that has five parameters
+*/ 
+    void _sendCommand(uint8_t command, uint8_t param1, uint8_t param2,
+                                       uint8_t param3, uint8_t param4,
+                                       uint8_t param5);
+
+/** @brief Write command that has six parameters
+*/ 
+    void _sendCommand(uint8_t command, uint8_t param1, uint8_t param2,
+                                       uint8_t param3, uint8_t param4,
+                                       uint8_t param5, uint8_t param6);
     
-    // Sends data to device
+/** @brief Write databyte to display
+ *  @brief Start at current cursor location
+ *  @param uint8_t data databyte to write
+*/  
     void _sendData(uint8_t 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 _sendData(uint8_t len, uint8_t* data);
 
-    // Init the configuration registers in accordance with the datasheet
+/** @brief Low level Init
+ *  @brief Init the configuration registers in accordance with the datasheet
+ */   
     void _init();
 
     I2C _i2c;              // I2C bus reference