Addition Support for Arduino I2C based on PCF8574A

Fork of TextLCD by Wim Huiskamp

Files at this revision

API Documentation at this revision

Comitter:
wim
Date:
Tue Jun 17 17:41:47 2014 +0000
Parent:
28:30fa94f7341c
Child:
30:033048611c01
Commit message:
Tested with PCF2116

Changed in this revision

TextLCD.cpp Show annotated file Show diff for this revision Revisions of this file
TextLCD.h Show annotated file Show diff for this revision Revisions of this file
--- a/TextLCD.cpp	Sat Jun 14 17:04:25 2014 +0000
+++ b/TextLCD.cpp	Tue Jun 17 17:41:47 2014 +0000
@@ -10,6 +10,7 @@
  *               2014, v08: WH, Refactored in Base and Derived Classes to deal with mbed lib change regarding 'NC' defined pins 
  *               2014, v09: WH/EO, Added Class for Native SPI controllers such as ST7032 
  *               2014, v10: WH, Added Class for Native I2C controllers such as ST7032i, Added support for MCP23008 I2C portexpander, Added support for Adafruit module  
+ *               2014, v11: WH, Added support for native I2C controllers such as PCF21XX, improved the _initCtrl() method to deal with differences between all supported controllers  
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -33,6 +34,11 @@
 #include "TextLCD.h"
 #include "mbed.h"
 
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+
+
 /** Create a TextLCD_Base interface
   *
   * @param type  Sets the panel size/addressing mode (default = LCD16x2)
@@ -86,76 +92,281 @@
     // Display is now in 4-bit mode
     // Note: 4 bit mode is ignored for native SPI and I2C devices
    
-    // Device specific initialisations for DC/DC converter to generate VLCD or VLED
+    // Device specific initialisations: DC/DC converter to generate VLCD or VLED, number of lines etc
     switch (_ctrl) {
-      case ST7036:
-          // ST7036 controller: Initialise Voltage booster for VLCD. VDD=5V
-          // Note: supports 1,2 or 3 lines
-          _writeCommand(0x29);    // 4-bit Databus, 2 Lines, Select Instruction Set = 1
-          wait_ms(30);            // > 26,3ms 
-          _writeCommand(0x14);    // Bias: 1/5, 2-Lines LCD 
-//          _writeCommand(0x15);    // Bias: 1/5, 3-Lines LCD           
-          wait_ms(30);            // > 26,3ms
-          _writeCommand(0x55);    // Icon off, Booster on, Set Contrast C5, C4
-          wait_ms(30);            // > 26,3ms
-          _writeCommand(0x6D);    // Voltagefollower On, Ampl ratio Rab2, Rab1, Rab0
-          wait_ms(200);           // > 200ms!
-          _writeCommand(0x78);    // Set Contrast C3, C2, C1, C0
-          wait_ms(30);            // > 26,3ms
-          _writeCommand(0x28);    // Return to Instruction Set = 0
-          wait_ms(50);      
-          break;
-          
+      case KS0078:
+
+          // Initialise Display configuration
+          switch (_type) {
+            case LCD8x1:         //8x1 is a regular 1 line display
+            case LCD8x2B:        //8x2B is a special case of 16x1
+//            case LCD12x1:                                
+            case LCD16x1:                                            
+            case LCD24x1:
+//@TODO check config
+              _writeCommand(0x20); // Function set 001 DL N F - -
+                                   //  DL=0 (4 bits bus)             
+                                   //   N=0 (1 line)
+                                   //   F=0 (5x7 dots font)
+              break;                                
+
+            case LCD24x4B:
+              // Special mode for KS0078
+              _writeCommand(0x2A); // Function set 001 DL N RE DH REV
+                                   //   DL=0  (4 bits bus)             
+                                   //    N=1  (Dont care for KS0078)
+                                   //   RE=0  (Dis. Extended Regs, special mode for KS0078)
+                                   //   DH=1  (Disp shift, special mode for KS0078)                                
+                                   //   REV=0 (Reverse, special mode for KS0078)
+
+              _writeCommand(0x2E); // Function set 001 DL N RE DH REV
+                                   //   DL=0  (4 bits bus)             
+                                   //    N=1  (Dont care for KS0078)
+                                   //   RE=1  (Ena Extended Regs, special mode for KS0078)
+                                   //   DH=1  (Disp shift, special mode for KS0078)                                
+                                   //   REV=0 (Reverse, special mode for KS0078)
+
+              _writeCommand(0x09); // Ext Function set 0000 1 FW BW NW
+                                   //   FW=0  (5-dot font, special mode for KS0078)
+                                   //   BW=0  (Cur BW invert disable, special mode for KS0078)
+                                   //   NW=1  (4 Line, special mode for KS0078)                                
+
+              _writeCommand(0x2A); // Function set 001 DL N RE DH REV
+                                   //   DL=0  (4 bits bus)             
+                                   //    N=1  (Dont care for KS0078)
+                                   //   RE=0  (Dis. Extended Regs, special mode for KS0078)
+                                   //   DH=1  (Disp shift, special mode for KS0078)                                
+                                   //   REV=0 (Reverse, special mode for KS0078)
+                                                  
+            // All other LCD types are initialised as 2 Line displays (including LCD40x4)
+            default:
+//@TODO check config            
+              _writeCommand(0x28); // Function set 001 DL N F - -
+                                   //  DL=0 (4 bits bus)
+                                   //  Note: 4 bit mode is ignored for native SPI and I2C devices                                 
+                                   //   N=1 (2 lines)
+                                   //   F=0 (5x7 dots font, only option for 2 line display)
+                                   //    -  (Don't care)                                
+            
+              break;
+          } // switch type
+
+          break; // case KS0078 Controller
+              
       case ST7032_3V3:
           // ST7032 controller: Initialise Voltage booster for VLCD. VDD=3V3
 
-//          _writeCommand(0x39);    //FUNCTION SET 8 bit,N=1 2-line display mode,5*7dot, Select Instruction Set = 1
-          _writeCommand(0x29);    //FUNCTION SET 4 bit, N=1 2-line display mode, 5*7dot, Select Instruction Set = 1
-                                  //Note: 4 bit mode is ignored for native SPI and I2C devices
+          // Initialise Display configuration
+          switch (_type) {
+            case LCD8x1:         //8x1 is a regular 1 line display
+            case LCD8x2B:        //8x2B is a special case of 16x1
+//            case LCD12x1:                                
+            case LCD16x1:                                            
+            case LCD24x1:                    
 
-          _writeCommand(0x1C);    //Internal OSC frequency adjustment Framefreq=183HZ, bias will be 1/4 
+//              _writeCommand(0x31);    //FUNCTION SET 8 bit,N=0 1-line display mode,5*7dot, Select Instruction Set = 1
+              _writeCommand(0x21);    //FUNCTION SET 4 bit, N=0 1-line display mode, 5*7dot, Select Instruction Set = 1
+                                      //Note: 4 bit mode is ignored for native SPI and I2C devices
+
+              _writeCommand(0x1C);    //Internal OSC frequency adjustment Framefreq=183HZ, bias will be 1/4 
 
-          _writeCommand(0x73);    //Contrast control low byte
+              _writeCommand(0x73);    //Contrast control low byte
 
-          _writeCommand(0x57);    //booster circuit is turned on. /ICON display off. /Contrast control high byte
-          wait_ms(10);            // Wait 10ms to ensure powered up
+              _writeCommand(0x57);    //booster circuit is turned on. /ICON display off. /Contrast control high byte
+              wait_ms(10);            // Wait 10ms to ensure powered up
+          
+              _writeCommand(0x6C);    //Follower control
+              wait_ms(10);            // Wait 10ms to ensure powered up
           
-          _writeCommand(0x6C);    //Follower control
-          wait_ms(10);            // Wait 10ms to ensure powered up
+//              _writeCommand(0x30);    //FUNCTION SET 8 bit,N=0 1-line display mode,5*7dot, Return to Instruction Set = 0        
+              _writeCommand(0x20);    //FUNCTION SET 4 bit, N=0 1-line display mode, 5*7dot, Return to Instruction Set = 0                  
+                                      //Note: 4 bit mode is ignored for native SPI and I2C devices                                                                          
+
+              break;  
+
+            default:
+              // All other LCD types are initialised as 2 Line displays        
+                                    
+//              _writeCommand(0x39);    //FUNCTION SET 8 bit,N=1 2-line display mode,5*7dot, Select Instruction Set = 1
+              _writeCommand(0x29);    //FUNCTION SET 4 bit, N=1 2-line display mode, 5*7dot, Select Instruction Set = 1
+                                      //Note: 4 bit mode is ignored for native SPI and I2C devices
+
+              _writeCommand(0x1C);    //Internal OSC frequency adjustment Framefreq=183HZ, bias will be 1/4 
+
+              _writeCommand(0x73);    //Contrast control low byte
+
+              _writeCommand(0x57);    //booster circuit is turned on. /ICON display off. /Contrast control high byte
+              wait_ms(10);            // Wait 10ms to ensure powered up
           
-//          _writeCommand(0x38);    //FUNCTION SET 8 bit,N=1 2-line display mode,5*7dot, Return to Instruction Set = 0        
-          _writeCommand(0x28);    //FUNCTION SET 4 bit, N=1 2-line display mode, 5*7dot, Return to Instruction Set = 0                  
-                                  //Note: 4 bit mode is ignored for native SPI and I2C devices    
-                                  
-          _writeCommand(0x14);    // Cursor or Display shift 0001 S/C R/L x x 
-                                  //   S/C=0 Cursor moves
-                                  //   R/L=1 Right
-                                  //    
-          break;
+              _writeCommand(0x6C);    //Follower control
+              wait_ms(10);            // Wait 10ms to ensure powered up
+          
+//              _writeCommand(0x38);    //FUNCTION SET 8 bit,N=1 2-line display mode,5*7dot, Return to Instruction Set = 0        
+              _writeCommand(0x28);    //FUNCTION SET 4 bit, N=1 2-line display mode, 5*7dot, Return to Instruction Set = 0                  
+                                      //Note: 4 bit mode is ignored for native SPI and I2C devices                                                                          
+          } // switch type    
+                                     
+          break; // case ST7032_3V3 Controller
 
 
       case ST7032_5V:
           // ST7032 controller: Disable Voltage booster for VLCD. VDD=5V      
-//          _writeCommand(0x39);    //FUNCTION SET 8 bit,N=1 2-line display mode,5*7dot, Instruction Set = 1
-          _writeCommand(0x29);    //FUNCTION SET 4 bit, N=1 2-line display mode, 5*7dot, Select Instruction Set = 1
-                                  //Note: 4 bit mode is ignored for native SPI and I2C devices         
+
+          // Initialise Display configuration
+          switch (_type) {
+            case LCD8x1:         //8x1 is a regular 1 line display
+            case LCD8x2B:        //8x2B is a special case of 16x1
+//            case LCD12x1:                                
+            case LCD16x1:                                            
+            case LCD24x1:                    
+
+//              _writeCommand(0x31);    //FUNCTION SET 8 bit,N=0 1-line display mode,5*7dot, Select Instruction Set = 1
+              _writeCommand(0x21);    //FUNCTION SET 4 bit, N=0 1-line display mode, 5*7dot, Select Instruction Set = 1
+                                      //Note: 4 bit mode is ignored for native SPI and I2C devices
+
+              _writeCommand(0x1C);    //Internal OSC frequency adjustment Framefreq=183HZ, bias will be 1/4 
+
+              _writeCommand(0x73);    //Contrast control low byte
 
-          _writeCommand(0x1C);    //Internal OSC frequency adjustment 183HZ, bias will be 1/4 
+              _writeCommand(0x53);    //booster circuit is turned off. /ICON display off. /Contrast control high byte
+              wait_ms(10);            // Wait 10ms to ensure powered up
+          
+              _writeCommand(0x6C);    //Follower control
+              wait_ms(10);            // Wait 10ms to ensure powered up
+          
+//              _writeCommand(0x30);    //FUNCTION SET 8 bit,N=0 1-line display mode,5*7dot, Return to Instruction Set = 0        
+              _writeCommand(0x20);    //FUNCTION SET 4 bit, N=0 1-line display mode, 5*7dot, Return to Instruction Set = 0                  
+                                      //Note: 4 bit mode is ignored for native SPI and I2C devices                                                                          
+
+              break;  
 
-          _writeCommand(0x73);    //Contrast control low byte
+            default:
+              // All other LCD types are initialised as 2 Line displays        
+                                    
+//              _writeCommand(0x39);    //FUNCTION SET 8 bit,N=1 2-line display mode,5*7dot, Select Instruction Set = 1
+              _writeCommand(0x29);    //FUNCTION SET 4 bit, N=1 2-line display mode, 5*7dot, Select Instruction Set = 1
+                                      //Note: 4 bit mode is ignored for native SPI and I2C devices
+
+              _writeCommand(0x1C);    //Internal OSC frequency adjustment Framefreq=183HZ, bias will be 1/4 
+
+              _writeCommand(0x73);    //Contrast control low byte
+
+              _writeCommand(0x53);    //booster circuit is turned off. /ICON display off. /Contrast control high byte
+              wait_ms(10);            // Wait 10ms to ensure powered up
+          
+              _writeCommand(0x6C);    //Follower control
+              wait_ms(10);            // Wait 10ms to ensure powered up
+          
+//              _writeCommand(0x38);    //FUNCTION SET 8 bit,N=1 2-line display mode,5*7dot, Return to Instruction Set = 0        
+              _writeCommand(0x28);    //FUNCTION SET 4 bit, N=1 2-line display mode, 5*7dot, Return to Instruction Set = 0                  
+                                      //Note: 4 bit mode is ignored for native SPI and I2C devices                                                                          
+          } // switch type    
+                                    
+          break; // case ST7032_5V Controller
 
-          _writeCommand(0x53);    //booster circuit is turned off. /ICON display off. /Contrast control high byte
-          wait_ms(10);            // Wait 10ms to ensure powered up
-          
-          _writeCommand(0x6C);    //Follower control
-          wait_ms(10);            // Wait 10ms to ensure powered up
+      case ST7036:
+          // ST7036 controller: Initialise Voltage booster for VLCD. VDD=5V
+          // Note: supports 1,2 or 3 lines
           
-//          _writeCommand(0x38);    //FUNCTION SET 8 bit,N=1 2-line display mode,5*7dot, Instruction Set = 0                  
-          _writeCommand(0x28);    //FUNCTION SET 4 bit, N=1 2-line display mode, 5*7dot, Return to Instruction Set = 0                            
-                                  //Note: 4 bit mode is ignored for native SPI and I2C devices                   
+          // Initialise Display configuration
+          switch (_type) {
+            case LCD8x1:         //8x1 is a regular 1 line display
+            case LCD8x2B:        //8x2B is a special case of 16x1
+//            case LCD12x1:                                
+            case LCD16x1:   
+            case LCD24x1:                                                                         
+              _writeCommand(0x21);    // 4-bit Databus, N=0 1 Line, DH=0 5x7font, IS2,IS1 = 01 Select Instruction Set = 1
+              wait_ms(30);            // > 26,3ms 
+              _writeCommand(0x14);    // Bias: 1/5, 1 or 2-Lines LCD 
+//              _writeCommand(0x15);    // Bias: 1/5, 3-Lines LCD           
+              wait_ms(30);            // > 26,3ms
+              _writeCommand(0x55);    // Icon off, Booster on, Set Contrast C5, C4
+              wait_ms(30);            // > 26,3ms
+              _writeCommand(0x6D);    // Voltagefollower On, Ampl ratio Rab2, Rab1, Rab0
+              wait_ms(200);           // > 200ms!
+              _writeCommand(0x78);    // Set Contrast C3, C2, C1, C0
+              wait_ms(30);            // > 26,3ms
+              _writeCommand(0x20);    // Return to Instruction Set = 0
+              wait_ms(50);      
+              break;  
+#if(0)
+//            case LCD12x3:                                            
+            case LCD16x3:                                            
+              _writeCommand(0x29);    // 4-bit Databus, N=1 2 Line, DH=0 5x7font, IS2,IS1 = 01 Select Instruction Set = 1
+              wait_ms(30);            // > 26,3ms 
+//              _writeCommand(0x14);    // Bias: 1/5, 1 or 2-Lines LCD 
+              _writeCommand(0x15);    // Bias: 1/5, 3-Lines LCD           
+              wait_ms(30);            // > 26,3ms
+              _writeCommand(0x55);    // Icon off, Booster on, Set Contrast C5, C4
+              wait_ms(30);            // > 26,3ms
+              _writeCommand(0x6D);    // Voltagefollower On, Ampl ratio Rab2, Rab1, Rab0
+              wait_ms(200);           // > 200ms!
+              _writeCommand(0x78);    // Set Contrast C3, C2, C1, C0
+              wait_ms(30);            // > 26,3ms
+              _writeCommand(0x28);    // Return to Instruction Set = 0
+              wait_ms(50);      
+              break;  
+#endif
+            default:
+              // All other LCD types are initialised as 2 Line displays        
+              _writeCommand(0x29);    // 4-bit Databus, N=1 2 Line, DH=0 5x7font, IS2,IS1 = 01 Select Instruction Set = 1              
+              wait_ms(30);            // > 26,3ms 
+              _writeCommand(0x14);    // Bias: 1/5, 2-Lines LCD 
+//             _writeCommand(0x15);    // Bias: 1/5, 3-Lines LCD           
+              wait_ms(30);            // > 26,3ms
+              _writeCommand(0x55);    // Icon off, Booster on, Set Contrast C5, C4
+              wait_ms(30);            // > 26,3ms
+              _writeCommand(0x6D);    // Voltagefollower On, Ampl ratio Rab2, Rab1, Rab0
+              wait_ms(200);           // > 200ms!
+              _writeCommand(0x78);    // Set Contrast C3, C2, C1, C0
+              wait_ms(30);            // > 26,3ms
+              _writeCommand(0x28);    // Return to Instruction Set = 0
+              wait_ms(50);      
+          } // switch type
+          
+          break; // case ST7036 Controller
+          
+      case PCF21XX_3V3:
+          // PCF21XX controller: Initialise Voltage booster for VLCD. VDD=3V3
 
-          break;
-          
+          // Initialise Display configuration
+          switch (_type) {
+            case LCD8x1:         //8x1 is a regular 1 line display
+            case LCD8x2B:        //8x2B is a special case of 16x1
+//            case LCD12x1:                                
+            case LCD16x1:                                            
+            case LCD24x1:                    
+              _writeCommand(0x22);    //FUNCTION SET 4 bit, N=0/M=0 1-line/24 chars display mode, G=1 Booster on                               
+                                      //Note: 4 bit mode is ignored for I2C mode
+              wait_ms(10);            // Wait 10ms to ensure powered up                                                    
+              break;  
+
+            case LCD12x3B:                    
+            case LCD12x4B:                                
+              _writeCommand(0x2E);    //FUNCTION SET 4 bit, N=1/M=1 4-line/12 chars display mode, G=1 Booster on                               
+                                      //Note: 4 bit mode is ignored for I2C mode              
+              wait_ms(10);            // Wait 10ms to ensure powered up                                                    
+              break;  
+              
+            default:
+              // All other LCD types are initialised as 2 Line displays        
+              _writeCommand(0x2A);    //FUNCTION SET 4 bit, N=1/M=0 2-line/24 chars display mode, G=1 Booster on
+                                      //Note: 4 bit mode is ignored for I2C mode
+
+              wait_ms(10);            // Wait 10ms to ensure powered up   
+              
+              
+              led1=!led1;
+          } // switch type    
+
+
+          break; // case PCF21XX_3V3 Controller
+
+
+//      case PCF21XX_5V:
+          // PCF21XX controller: No Voltage booster for VLCD. VDD=5V
+                              
+
       case WS0010:         
           // WS0010 OLED controller: Initialise DC/DC Voltage converter for LEDs
           // Note: supports 1 or 2 lines (and 16x100 graphics)
@@ -170,66 +381,68 @@
           _writeCommand(0x17);   // DC/DC on        
           wait_ms(10);           // Wait 10ms to ensure powered up
           
-          break;
-        
+
+          // Initialise Display configuration
+          switch (_type) {                    
+            case LCD8x1:         //8x1 is a regular 1 line display
+            case LCD8x2B:        //8x2B is a special case of 16x1
+//            case LCD12x1:                                
+            case LCD16x1:                                            
+//            case LCD24x1:
+              _writeCommand(0x20); // Function set 001 DL N F - -
+                                   //  DL=0 (4 bits bus)             
+                                   //   N=0 (1 line)
+                                   //   F=0 (5x7 dots font)
+              break;  
+
+            default:
+              // All other LCD types are initialised as 2 Line displays (including LCD40x4)       
+              _writeCommand(0x28); // Function set 001 DL N F - -
+                                   //  DL=0 (4 bits bus)
+                                   //   N=1 (2 lines)
+                                   //   F=0 (5x7 dots font, only option for 2 line display)
+                                   //    -  (Don't care)                                
+          
+              break;
+           } // switch type
+           
+           break; // case WS0100 Controller
+           
         default:
-          // Devices that do not use DC/DC Voltage converters but external VLCD
-          break;                  
-    }
-    
-    // Initialise Display configuration
-    switch (_type) {
-        case LCD8x1:
-        case LCD8x2B:        
-            //8x1 is a regular 1 line display
-            //8x2B is a special case of 16x1
-            _writeCommand(0x20); // Function set 001 DL N F - -
-                                 //  DL=0 (4 bits bus)             
-                                 //   N=0 (1 line)
-                                 //   F=0 (5x7 dots font)
-            break;                                
-            
-        case LCD24x4:
-            // Special mode for KS0078
-            _writeCommand(0x2A); // Function set 001 DL N RE DH REV
-                                 //   DL=0  (4 bits bus)             
-                                 //    N=1  (Dont care for KS0078)
-                                 //   RE=0  (Extended Regs, special mode for KS0078)
-                                 //   DH=1  (Disp shift, special mode for KS0078)                                
-                                 //   REV=0 (Reverse, special mode for KS0078)
+          // Devices fully compatible to HD44780 that do not use any DC/DC Voltage converters but external VLCD
 
-            _writeCommand(0x2E); // Function set 001 DL N RE DH REV
-                                 //   DL=0  (4 bits bus)             
-                                 //    N=1  (Dont care for KS0078)
-                                 //   RE=1  (Ena Extended Regs, special mode for KS0078)
-                                 //   DH=1  (Disp shift, special mode for KS0078)                                
-                                 //   REV=0 (Reverse, special mode for KS0078)
-
-            _writeCommand(0x09); // Ext Function set 0000 1 FW BW NW
-                                 //   FW=0  (5-dot font, special mode for KS0078)
-                                 //   BW=0  (Cur BW invert disable, special mode for KS0078)
-                                 //   NW=1  (4 Line, special mode for KS0078)                                
+          // Initialise Display configuration
+          switch (_type) {
+            case LCD8x1:         //8x1 is a regular 1 line display
+            case LCD8x2B:        //8x2B is a special case of 16x1
+//            case LCD12x1:                                
+            case LCD16x1:                                            
+            case LCD24x1:
+              _writeCommand(0x20); // Function set 001 DL N F - -
+                                   //  DL=0 (4 bits bus)             
+                                   //   N=0 (1 line)
+                                   //   F=0 (5x7 dots font)
+              break;                                
+                                                  
+            // All other LCD types are initialised as 2 Line displays (including LCD40x4)
+            default:
+              _writeCommand(0x28); // Function set 001 DL N F - -
+                                   //  DL=0 (4 bits bus)
+                                   //  Note: 4 bit mode is ignored for native SPI and I2C devices                                 
+                                   //   N=1 (2 lines)
+                                   //   F=0 (5x7 dots font, only option for 2 line display)
+                                   //    -  (Don't care)                                
+            
+              break;
+          } // switch type
 
-            _writeCommand(0x2A); // Function set 001 DL N RE DH REV
-                                 //   DL=0  (4 bits bus)             
-                                 //    N=1  (Dont care for KS0078)
-                                 //   RE=0  (Dis. Extended Regs, special mode for KS0078)
-                                 //   DH=1  (Disp shift, special mode for KS0078)                                
-                                 //   REV=0 (Reverse, special mode for KS0078)
-            break;
-                                            
-// All other LCD types are initialised as 2 Line displays (including LCD40x4)
-        default:
-            _writeCommand(0x28); // Function set 001 DL N F - -
-                                 //  DL=0 (4 bits bus)
-                                 //  Note: 4 bit mode is ignored for native SPI and I2C devices                                 
-                                 //   N=1 (2 lines)
-                                 //   F=0 (5x7 dots font, only option for 2 line display)
-                                 //    -  (Don't care)                                
-            
-            break;
-    }
+          break; // case default Controller
+          
+    } // switch Controller specific initialisations 
+    
 
+    // Controller general initialisations
+                                           
     _writeCommand(0x01); // cls, and set cursor to 0
     wait_ms(10);         // The CLS command takes 1.64 ms.
                          // Since we are not using the Busy flag, Lets be safe and take 10 ms  
@@ -242,10 +455,17 @@
                          //   I/D=1 (Cur incr)
                          //     S=0 (No display shift)                        
 
+    _writeCommand(0x14); // Cursor or Display shift 0001 S/C R/L x x 
+                         //   S/C=0 Cursor moves
+                         //   R/L=1 Right
+                         // 
+
+
 //    _writeCommand(0x0C); // Display Ctrl 0000 1 D C B
 //                         //   Display On, Cursor Off, Blink Off   
     setCursor(CurOff_BlkOff);     
     setMode(DispOn);     
+    led2=!led2;    
 }
 
 
@@ -262,28 +482,31 @@
 
     // Second LCD controller Clearscreen
     _writeCommand(0x01);  // cls, and set cursor to 0    
-    wait_ms(10);     // The CLS command takes 1.64 ms.
-                     // Since we are not using the Busy flag, Lets be safe and take 10 ms
+    wait_ms(10);          // The CLS command takes 1.64 ms.
+                          // Since we are not using the Busy flag, Lets be safe and take 10 ms
   
     _ctrl_idx=_LCDCtrl_0; // Select primary controller
   }
   
   // Primary LCD controller Clearscreen
   _writeCommand(0x01);    // cls, and set cursor to 0
-  wait_ms(10);     // The CLS command takes 1.64 ms.
-                   // Since we are not using the Busy flag, Lets be safe and take 10 ms
+  wait_ms(10);            // The CLS command takes 1.64 ms.
+                          // Since we are not using the Busy flag, Lets be safe and take 10 ms
 
   // Restore cursormode on primary LCD controller when needed
   if(_type==LCD40x4) {
     _setCursorAndDisplayMode(_currentMode,_currentCursor);     
   }
                    
-  _row=0;          // Reset Cursor location
-  _column=0;
+  setAddress(0, 0);  // Reset Cursor location
+                     // Note: this is needed because some rare displays (eg PCF21XX) don't use line 0 in the '3 Line' mode.   
 }
 
-/** Move cursor to selected row and column
-  */
+/** Locate cursor to a screen column and row
+  *
+  * @param column  The horizontal position from the left, indexed from 0
+  * @param row     The vertical position from the top, indexed from 0
+  */ 
 void TextLCD_Base::locate(int column, int row) {
     
    // setAddress() does all the heavy lifting:
@@ -433,12 +656,26 @@
 
 // This is new method to return the memory address based on row, column and displaytype.
 //
+/** Return the memoryaddress of screen column and row location
+   *
+   * @param column  The horizontal position from the left, indexed from 0
+   * @param row     The vertical position from the top, indexed from 0
+   * @param return  The memoryaddress of screen column and row location
+   */
 int TextLCD_Base::getAddress(int column, int row) {
 
     switch (_type) {
         case LCD8x1:
+        case LCD24x1:        
             return 0x00 + column;                        
 
+        case LCD16x1:
+            // LCD16x1 is a special layout of LCD8x2
+            if (column<8) 
+              return 0x00 + column;                        
+            else   
+              return 0x40 + (column - 8);                        
+
         case LCD8x2B:
             // LCD8x2B is a special layout of LCD16x1
             if (row==0) 
@@ -446,26 +683,44 @@
             else   
               return 0x08 + column;                        
 
-        case LCD16x1:
-            // LCD16x1 is a special layout of LCD8x2
-            if (column<8) 
-              return 0x00 + column;                        
-            else   
-              return 0x40 + (column - 8);                        
+        case LCD8x2:               
+        case LCD12x2:                
+        case LCD16x2:
+        case LCD20x2:
+        case LCD24x2:        
+        case LCD40x2:                
+            return 0x00 + (row * 0x40) + column;
 
-#if(0)
+// Not sure about this one, seems wrong.
+// Left in for compatibility with original library
+        case LCD16x2B:      
+            return 0x00 + (row * 40) + column;
+    
+
 // Special mode for ST7036 
 //        case LCD16x3:
 
-// Special mode for PCF2116 (and KS0078) 
-        case LCD12x3:
+// Special mode for PCF2116 
+        case LCD12x3B:
+            switch (row) {
+                case 0:
+                    return 0x20 + column;
+                case 1:
+                    return 0x40 + column;
+                case 2:
+                    return 0x60 + column;
+            }
+
+        case LCD12x4:
             switch (row) {
                 case 0:
                     return 0x00 + column;
                 case 1:
-                    return 0x20 + column;
+                    return 0x40 + column;
                 case 2:
-                    return 0x40 + column;
+                    return 0x0C + column;
+                case 3:
+                    return 0x4C + column;
             }
 
 // Special mode for PCF2116 (and KS0078) 
@@ -481,20 +736,6 @@
                     return 0x60 + column;                   
             }
 
-#endif
-
-        case LCD12x4:
-            switch (row) {
-                case 0:
-                    return 0x00 + column;
-                case 1:
-                    return 0x40 + column;
-                case 2:
-                    return 0x0C + column;
-                case 3:
-                    return 0x4C + column;
-            }
-
         case LCD16x4:
             switch (row) {
                 case 0:
@@ -520,7 +761,7 @@
             }
 
 // Special mode for KS0078
-        case LCD24x4:
+        case LCD24x4B:
             switch (row) {
                 case 0:
                     return 0x00 + column;
@@ -532,19 +773,6 @@
                     return 0x60 + column;
             }
 
-// Not sure about this one, seems wrong.
-// Left in for compatibility with original library
-        case LCD16x2B:      
-            return 0x00 + (row * 40) + column;
-      
-        case LCD8x2:               
-        case LCD12x2:                
-        case LCD16x2:
-        case LCD20x2:
-        case LCD24x2:        
-        case LCD40x2:                
-            return 0x00 + (row * 0x40) + column;
-
         case LCD40x4:                
           // LCD40x4 is a special case since it has 2 controllers
           // Each controller is configured as 40x2
@@ -588,8 +816,11 @@
 }
 
 
-// Set row, column and update memoryaddress.
-//
+/** Set the memoryaddress of screen column and row location
+  *
+  * @param column  The horizontal position from the left, indexed from 0
+  * @param row     The vertical position from the top, indexed from 0
+  */
 void TextLCD_Base::setAddress(int column, int row) {
    
 // Sanity Check column
@@ -617,6 +848,11 @@
     _writeCommand(0x80 | addr);
 }
 
+
+/** Return the number of columns
+  *
+  * @param return  The number of columns
+  */   
 int TextLCD_Base::columns() {
     switch (_type) {
         case LCD8x1:
@@ -625,9 +861,9 @@
             return 8;
         
         case LCD12x2:        
-//        case LCD12x3:                
+        case LCD12x3B:                
         case LCD12x4:        
-//        case LCD12x4B:                
+        case LCD12x4B:                
             return 12;        
 
         case LCD16x1:        
@@ -641,8 +877,9 @@
         case LCD20x4:
             return 20;
 
+        case LCD24x1:
         case LCD24x2:
-        case LCD24x4:        
+        case LCD24x4B:        
             return 24;        
 
         case LCD40x2:
@@ -655,10 +892,15 @@
     }
 }
 
+/** Return the number of rows
+  *
+  * @param return  The number of rows
+  */
 int TextLCD_Base::rows() {
     switch (_type) {
         case LCD8x1: 
         case LCD16x1:         
+        case LCD24x1:                 
             return 1;           
 
         case LCD8x2:  
@@ -671,15 +913,15 @@
         case LCD40x2:                
             return 2;
 
-//        case LCD12x3:                
+        case LCD12x3B:                
 //        case LCD16x3:                
-//            return 3;
+            return 3;
                     
         case LCD12x4:        
-//        case LCD12x4B:                
+        case LCD12x4B:                
         case LCD16x4:
         case LCD20x4:
-        case LCD24x4:        
+        case LCD24x4B:        
         case LCD40x4:
             return 4;
 
@@ -689,8 +931,10 @@
     }
 }
 
-
-// Set the Cursor Mode (Cursor Off & Blink Off, Cursor On & Blink Off, Cursor Off & Blink On, Cursor On & Blink On
+/** Set the Cursormode
+  *
+  * @param cursorMode  The Cursor mode (CurOff_BlkOff, CurOn_BlkOff, CurOff_BlkOn, CurOn_BlkOn)
+  */
 void TextLCD_Base::setCursor(LCDCursor cursorMode) { 
 
   // Save new cursor mode, needed when 2 controllers are in use or when display is switched off/on
@@ -701,7 +945,10 @@
     
 }
 
-// Set the Displaymode (On/Off)
+/** Set the Displaymode
+  *
+  * @param displayMode The Display mode (DispOff, DispOn)
+  */
 void TextLCD_Base::setMode(LCDMode displayMode) { 
 
   // Save new displayMode, needed when 2 controllers are in use or when cursor is changed
@@ -745,14 +992,19 @@
 }
 
 
-// Set the Displaymode (On/Off) and Cursortype for current controller
+/** Low level method to restore the cursortype and display mode for current controller
+  */     
 void TextLCD_Base::_setCursorAndDisplayMode(LCDMode displayMode, LCDCursor cursorType) { 
     
     // Configure current LCD controller       
     _writeCommand(0x08 | displayMode | cursorType);
 }
 
-// Set the Backlight mode (Off/On)
+
+/** Set the Backlight mode
+  *
+  *  @param backlightMode The Backlight mode (LightOff, LightOn)
+  */
 void TextLCD_Base::setBacklight(LCDBacklight backlightMode) {
 
     if (backlightMode == LightOn) {
@@ -763,7 +1015,11 @@
     }
 } 
 
-
+/** Set User Defined Characters
+  *
+  * @param unsigned char c   The Index of the UDC (0..7)
+  * @param char *udc_data    The bitpatterns for the UDC (8 bytes of 5 significant bits)     
+  */
 void TextLCD_Base::setUDC(unsigned char c, char *udc_data) {
   
   // Select and configure second LCD controller when needed
@@ -792,6 +1048,8 @@
     
 }
 
+/** Low level method to store user defined characters for current controller
+  */     
 void TextLCD_Base::_setUDC(unsigned char c, char *udc_data) {
   
   // Select CG RAM for current LCD controller
@@ -854,6 +1112,18 @@
 
 }
 
+
+/** Destruct a TextLCD interface for using regular mbed pins
+  *
+  * @param  none
+  * @return none
+  */ 
+TextLCD::~TextLCD() {
+   if (_bl != NULL) {delete _bl;}  // BL pin
+   if (_e2 != NULL) {delete _e2;}  // E2 pin
+}
+
+
 /** Set E pin (or E2 pin)
   * Used for mbed pins, I2C bus expander or SPI shiftregister
   * Default PinName value for E2 is NC, must be used as pointer to avoid issues with mbed lib and DigitalOut pins
@@ -917,16 +1187,6 @@
   _d = value & 0x0F;   // Write Databits 
 }    
 
-/** Destruct a TextLCD interface for using regular mbed pins
-  *
-  * @param  none
-  * @return none
-  */ 
-TextLCD::~TextLCD() {
-   if (_bl != NULL) {delete _bl;}  // BL pin
-   if (_e2 != NULL) {delete _e2;}  // E2 pin
-}
-
     
 //----------- End TextLCD ---------------
 
@@ -1150,10 +1410,10 @@
                               
   _slaveAddress = deviceAddress & 0xFE;
   
-
   // Setup the I2C bus
-  // The max bitrate for ST7032 is 400kbit, 
-//  _i2c->frequency(100000);
+  // The max bitrate for ST7032i is 400kbit, lets stick to default here
+  _i2c->frequency(100000);
+//  _i2c->frequency(50000);
 
         
   // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
@@ -1196,6 +1456,12 @@
     }    
 }    
 
+    
+// Not used in this mode
+void TextLCD_I2C_N::_setData(int value) {
+}    
+
+
 // Write a byte using I2C
 void TextLCD_I2C_N::_writeByte(int value) {
 
@@ -1204,10 +1470,6 @@
   _i2c->write(_slaveAddress, data, 2);
  
 }
-    
-// Not used in this mode
-void TextLCD_I2C_N::_setData(int value) {
-}    
 
 
 //-------- End TextLCD_I2C_N ------------
@@ -1313,7 +1575,6 @@
 }    
 
 
-
 // Place the 4bit data on the databus
 // Used for mbed pins, I2C bus expander or SPI shiftregister
 void TextLCD_SPI::_setData(int value) {
@@ -1429,6 +1690,11 @@
     }    
 }    
 
+// Not used in this mode
+void TextLCD_SPI_N::_setData(int value) {
+}    
+
+
 // Write a byte using SPI
 void TextLCD_SPI_N::_writeByte(int value) {
     _cs = 0;
@@ -1438,9 +1704,6 @@
     _cs = 1;
 }
     
-// Not used in this mode
-void TextLCD_SPI_N::_setData(int value) {
-}    
 
 
 //-------- End TextLCD_SPI_N ------------
--- a/TextLCD.h	Sat Jun 14 17:04:25 2014 +0000
+++ b/TextLCD.h	Tue Jun 17 17:41:47 2014 +0000
@@ -10,6 +10,7 @@
  *               2014, v08: WH, Refactored in Base and Derived Classes to deal with mbed lib change regarding 'NC' defined DigitalOut pins
  *               2014, v09: WH/EO, Added Class for Native SPI controllers such as ST7032 
  *               2014, v10: WH, Added Class for Native I2C controllers such as ST7032i, Added support for MCP23008 I2C portexpander, Added support for Adafruit module  
+ *               2014, v11: WH, Added support for native I2C controllers such as PCF21XX, improved the _initCtrl() method to deal with differences between all supported controllers  
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -69,14 +70,15 @@
 //LCD and serial portexpanders should be wired accordingly 
 //
 //Select Hardware module (one option only)
-#define DEFAULT        1
-#define ADAFRUIT       0
+#define DEFAULT        0
+#define ADAFRUIT       1
 #define DFROBOT        0
 
 
 #if (DEFAULT==1)
-//Definitions for hardware used by WH 
+//Definitions for default (WH) mapping between serial port expander pins and LCD controller
 //This hardware supports the I2C bus expander (PCF8574/PCF8574A or MCP23008) and SPI bus expander (74595) interfaces
+//See https://mbed.org/cookbook/Text-LCD-Enhanced
 //
 //Note: LCD RW pin must be connected to GND
 //      E2 is used for LCD40x4 (second controller)
@@ -98,8 +100,9 @@
 #endif
 
 #if (ADAFRUIT==1)
-//Definitions for i2cspilcdbackpack from Adafruit, See http://www.ladyada.net/products/i2cspilcdbackpack
+//Definitions for Adafruit i2cspilcdbackpack mapping between serial port expander pins and LCD controller
 //This hardware supports both an I2C expander (MCP23008) and an SPI expander (74595) selectable by a jumper.
+//See http://www.ladyada.net/products/i2cspilcdbackpack
 //
 //Note: LCD RW pin must be kept LOW
 //      E2 is not available on this hardware and so it does not support LCD40x4 (second controller)
@@ -121,8 +124,9 @@
 #endif
 
 #if (DFROBOT==1)
-//Definitions for LCD2004 Module from DFROBOT, See http://arduino-info.wikispaces.com/LCD-Blue-I2C
+//Definitions for DFROBOT LCD2004 Module mapping between serial port expander pins and LCD controller
 //This hardware uses PCF8574 and is different from earlier/different Arduino I2C LCD displays
+//See http://arduino-info.wikispaces.com/LCD-Blue-I2C
 //
 //Note: LCD RW pin must be kept LOW
 //      E2 is not available on default Arduino hardware and so it does not support LCD40x4 (second controller)
@@ -205,6 +209,9 @@
 /* ST7032I I2C slave address */
 #define ST7032_SA     0x7C
 
+/* PCF21XX I2C slave address */
+#define PCF21XX_SA0   0x74
+#define PCF21XX_SA1   0x76
 
 /** Some sample User Defined Chars 5x7 dots */
 const char udc_ae[] = {0x00, 0x00, 0x1B, 0x05, 0x1F, 0x14, 0x1F, 0x00};  //æ
@@ -252,10 +259,10 @@
 //const char udc_ch_2[]  =  {0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1f};  // Hor bars 4 (inverted)
 //const char udc_ch_3[]  =  {0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15};  // Ver bars 3
 //const char udc_ch_4[]  =  {0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a};  // Ver bars 3 (inverted)
-//const char udc_ch_yr[] =  {0x08, 0x0f, 0x12, 0x0f, 0x0a, 0x1f, 0x02, 0x02};  // Year   (kanji)
-//const char udc_ch_mo[] =  {0x0f, 0x09, 0x0f, 0x09, 0x0f, 0x09, 0x09, 0x13};  // Month  (kanji)
-//const char udc_ch_dy[] =  {0x1f, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x1F};  // Day    (kanji)
-//const char udc_ch_mi[] =  {0x0C, 0x0a, 0x11, 0x1f, 0x09, 0x09, 0x09, 0x13};  // minute (kanji)
+//const char udc_ch_yr[] =  {0x08, 0x0f, 0x12, 0x0f, 0x0a, 0x1f, 0x02, 0x02};  // Year   (kana)
+//const char udc_ch_mo[] =  {0x0f, 0x09, 0x0f, 0x09, 0x0f, 0x09, 0x09, 0x13};  // Month  (kana)
+//const char udc_ch_dy[] =  {0x1f, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x1F};  // Day    (kana)
+//const char udc_ch_mi[] =  {0x0C, 0x0a, 0x11, 0x1f, 0x09, 0x09, 0x09, 0x13};  // minute (kana)
 
 
 /** A TextLCD interface for driving 4-bit HD44780-based LCDs
@@ -272,32 +279,37 @@
         LCD8x1,     /**<  8x1 LCD panel */    
         LCD8x2,     /**<  8x2 LCD panel */          
         LCD8x2B,    /**<  8x2 LCD panel (actually 16x1) */                  
+//        LCD12x1,    /**< 12x1 LCD panel */                          
+//        LCD12x1B,   /**< 12x1 LCD panel, special mode PCF21XX */                                  
         LCD12x2,    /**< 12x2 LCD panel */                          
-//        LCD12x3,    /**< 12x3 LCD panel, special mode PCF21XX */                                  
+        LCD12x3B,   /**< 12x3 LCD panel, special mode PCF21XX */                                  
         LCD12x4,    /**< 12x4 LCD panel */                  
-//        LCD12x4B,   /**< 12x4 LCD panel, special mode PCF21XX */                                          
+        LCD12x4B,   /**< 12x4 LCD panel, special mode PCF21XX */                                          
         LCD16x1,    /**< 16x1 LCD panel (actually 8x2) */          
         LCD16x2,    /**< 16x2 LCD panel (default) */
         LCD16x2B,   /**< 16x2 LCD panel alternate addressing */
-//        LCD16x3,    /**< 16x3 LCD panel, special mode ST7036 */                
+//        LCD16x3B,   /**< 16x3 LCD panel, special mode ST7036 */                
         LCD16x4,    /**< 16x4 LCD panel */        
+//        LCD20x1,    /**< 20x1 LCD panel */
         LCD20x2,    /**< 20x2 LCD panel */
         LCD20x4,    /**< 20x4 LCD panel */
+        LCD24x4B,   /**< 24x4 LCD panel, special mode KS0078 */                                                  
+        LCD24x1,    /**< 24x1 LCD panel */        
         LCD24x2,    /**< 24x2 LCD panel */        
-        LCD24x4,    /**< 24x4 LCD panel, special mode KS0078 */                
         LCD40x2,    /**< 40x2 LCD panel */                
         LCD40x4     /**< 40x4 LCD panel, Two controller version */                        
     };
 
     /** LCD Controller Device */
     enum LCDCtrl {
-        HD44780,    /**<  HD44780 (default)        */    
-        WS0010,     /**<  WS0010  OLED Controller  */    
-        ST7036,     /**<  ST7036  3V3 with Booster */   
-        ST7032_3V3, /**<  ST7032  3V3 with Booster */   
-        ST7032_5V   /**<  ST7032  5V no Booster    */           
-//        PCF210X,    /**<  PCF210X 5V no Booster    */                   
-//        PCF211X     /**<  PCF211X 3V3 with Booster */                           
+        HD44780,     /**<  HD44780 (default)                           */    
+        WS0010,      /**<  WS0010  OLED Controller, 4/8 bit            */    
+        ST7036,      /**<  ST7036  3V3 with Booster, 4/8 bit, SPI      */   
+        ST7032_3V3,  /**<  ST7032  3V3 with Booster, 4/8 bit, SPI, I2C */   
+        ST7032_5V,   /**<  ST7032  5V no Booster, 4/8 bit, SPI, I2C    */           
+        KS0078,      /**<  KS0078  24x3 support                        */                   
+        PCF21XX_3V3, /**<  PCF21XX 3V3 with Booster, 4/8 bit, I2C      */                           
+//        PCF21XX_5V   /**<  PCF21XX 5V no Booster, 4/8 bit, I2C         */        
     };
 
 
@@ -338,7 +350,7 @@
     int printf(const char* format, ...);
 #endif
 
-    /** Locate to a screen column and row
+    /** Locate cursor to a screen column and row
      *
      * @param column  The horizontal position from the left, indexed from 0
      * @param row     The vertical position from the top, indexed from 0
@@ -406,7 +418,9 @@
      */
     void setUDC(unsigned char c, char *udc_data);
 
-
+//test
+    void _initCtrl();    
+    
 protected:
 
    /** LCD controller select, mainly used for LCD40x4
@@ -429,29 +443,70 @@
     virtual int _putc(int value);
     virtual int _getc();
 
-/** Low level methods for LCD controller
+/** Low level method for LCD controller
   */
     void _init();    
-    void _initCtrl();    
+
+/** Low level initialisation method for LCD controller
+  */
+//    void _initCtrl();    
+
+/** Low level character address set method
+  */  
     int  _address(int column, int row);
+    
+/** Low level cursor enable or disable method
+  */  
     void _setCursor(LCDCursor show);
+
+/** Low level method to store user defined characters for current controller
+  */     
     void _setUDC(unsigned char c, char *udc_data);   
+
+/** Low level method to restore the cursortype and display mode for current controller
+  */     
     void _setCursorAndDisplayMode(LCDMode displayMode, LCDCursor cursorType);       
     
-/** Low level write operations to LCD controller
+
+/** Low level nibble write operation to LCD controller (serial or parallel)
   */
     void _writeNibble(int value);
-    virtual void _writeByte(int value);
+   
+/** Low level command byte write operation to LCD controller.
+  * Methods resets the RS bit and provides the required timing for the command.
+  */
     void _writeCommand(int command);
+
+/** Low level data byte write operation to LCD controller (serial or parallel).
+  * Methods sets the RS bit and provides the required timing for the data.
+  */   
     void _writeData(int data);
 
+
+/** Pure Virtual Low level writes to LCD Bus (serial or parallel)
+  * Set the Enable pin.
+  */
+    virtual void _setEnable(bool value) = 0;
+
 /** Pure Virtual Low level writes to LCD Bus (serial or parallel)
-  */
-    virtual void _setEnable(bool value) = 0;
+  * Set the RS pin ( 0 = Command, 1 = Data).
+  */   
     virtual void _setRS(bool value) = 0;  
+
+/** Pure Virtual Low level writes to LCD Bus (serial or parallel)
+  * Set the BL pin (0 = Backlight Off, 1 = Backlight On).
+  */   
     virtual void _setBL(bool value) = 0;
+    
+/** Pure Virtual Low level writes to LCD Bus (serial or parallel)
+  * Set the databus value (4 bit).
+  */   
     virtual void _setData(int value) = 0;
 
+/** Low level byte write operation to LCD controller (serial or parallel)
+  * Depending on the RS pin this byte will be interpreted as data or command
+  */
+    virtual void _writeByte(int value);
     
 //Display type
     LCDType _type;
@@ -503,12 +558,28 @@
     virtual ~TextLCD();
 
 private:    
-//Low level writes to LCD Bus (serial or parallel)
+
+/** Implementation of pure Virtual Low level writes to LCD Bus (parallel)
+  * Set the Enable pin.
+  */
     virtual void _setEnable(bool value);
+
+/** Implementation of pure Virtual Low level writes to LCD Bus (parallel)
+  * Set the RS pin ( 0 = Command, 1 = Data).
+  */   
     virtual void _setRS(bool value);  
+
+/** Implementation of pure Virtual Low level writes to LCD Bus (parallel)
+  * Set the BL pin (0 = Backlight Off, 1 = Backlight On).
+  */   
     virtual void _setBL(bool value);
+    
+/** Implementation of pure Virtual Low level writes to LCD Bus (parallel)
+  * Set the databus value (4 bit).
+  */   
     virtual void _setData(int value);
 
+
 /** Regular mbed pins bus
   */
     DigitalOut _rs, _e;
@@ -542,13 +613,34 @@
     TextLCD_I2C(I2C *i2c, char deviceAddress = PCF8574_SA0, LCDType type = LCD16x2, LCDCtrl ctrl = HD44780);
 
 private:
-//Low level writes to LCD Bus (serial or parallel)
+    
+/** Implementation of pure Virtual Low level writes to LCD Bus (serial expander)
+  * Set the Enable pin.
+  */
     virtual void _setEnable(bool value);
+
+/** Implementation of pure Virtual Low level writes to LCD Bus (serial expander)
+  * Set the RS pin ( 0 = Command, 1 = Data).
+  */   
     virtual void _setRS(bool value);  
+
+/** Implementation of pure Virtual Low level writes to LCD Bus (serial expander)
+  * Set the BL pin (0 = Backlight Off, 1 = Backlight On).
+  */   
     virtual void _setBL(bool value);
-    virtual void _setData(int value); 
-
-// Write data to MCP23008 I2C portexpander
+    
+/** Implementation of pure Virtual Low level writes to LCD Bus (serial expander)
+  * Set the databus value (4 bit).
+  */   
+    virtual void _setData(int value);
+    
+    
+/** Write data to MCP23008 I2C portexpander
+  *  @param reg register to write
+  *  @param value data to write
+  *  @return none     
+  *
+  */
     void _write_register (int reg, int value);     
   
 //I2C bus
@@ -584,15 +676,35 @@
 
 
 private:
-//Low level writes to LCD Bus (serial or parallel)
+
+/** Implementation of pure Virtual Low level writes to LCD Bus (serial expander)
+  * Set the Enable pin.
+  */
     virtual void _setEnable(bool value);
+
+/** Implementation of pure Virtual Low level writes to LCD Bus (serial expander)
+  * Set the RS pin ( 0 = Command, 1 = Data).
+  */   
     virtual void _setRS(bool value);  
+
+/** Implementation of pure Virtual Low level writes to LCD Bus (serial expander)
+  * Set the BL pin (0 = Backlight Off, 1 = Backlight On).
+  */   
     virtual void _setBL(bool value);
+    
+/** Implementation of pure Virtual Low level writes to LCD Bus (serial expander)
+  * Set the databus value (4 bit).
+  */   
     virtual void _setData(int value);
+    
+/** Implementation of Low level writes to LCD Bus (serial expander)
+  * Set the CS pin (0 = select, 1 = deselect).
+  */   
     virtual void _setCS(bool value);
     
-//Low level writes to LCD serial bus only
-    void _writeBus();      
+///** Low level writes to LCD serial bus only (serial expander)
+//  */
+//    void _writeBus();      
    
 // SPI bus        
     SPI *_spi;
@@ -627,11 +739,31 @@
     virtual ~TextLCD_SPI_N(void);
 
 private:
+
+/** Implementation of pure Virtual Low level writes to LCD Bus (serial native)
+  * Set the Enable pin.
+  */
     virtual void _setEnable(bool value);
+
+/** Implementation of pure Virtual Low level writes to LCD Bus (serial native)
+  * Set the RS pin ( 0 = Command, 1 = Data).
+  */   
     virtual void _setRS(bool value);  
+
+/** Implementation of pure Virtual Low level writes to LCD Bus (serial native)
+  * Set the BL pin (0 = Backlight Off, 1 = Backlight On).
+  */   
     virtual void _setBL(bool value);
+    
+/** Implementation of pure Virtual Low level writes to LCD Bus (serial native)
+  * Set the databus value (4 bit).
+  */   
     virtual void _setData(int value);
+
+/** Low level writes to LCD serial bus only (serial native)
+  */
     virtual void _writeByte(int value);
+
    
 // SPI bus        
     SPI *_spi;
@@ -663,12 +795,32 @@
     virtual ~TextLCD_I2C_N(void);
 
 private:
+
+/** Implementation of pure Virtual Low level writes to LCD Bus (serial native)
+  * Set the Enable pin.
+  */
     virtual void _setEnable(bool value);
+
+/** Implementation of pure Virtual Low level writes to LCD Bus (serial native)
+  * Set the RS pin ( 0 = Command, 1 = Data).
+  */   
     virtual void _setRS(bool value);  
+
+/** Implementation of pure Virtual Low level writes to LCD Bus (serial native)
+  * Set the BL pin (0 = Backlight Off, 1 = Backlight On).
+  */   
     virtual void _setBL(bool value);
+    
+/** Implementation of pure Virtual Low level writes to LCD Bus (serial native)
+  * Set the databus value (4 bit).
+  */   
     virtual void _setData(int value);
+
+/** Low level writes to LCD serial bus only (serial native)
+  */
     virtual void _writeByte(int value);
 
+
 //I2C bus
     I2C *_i2c;
     char _slaveAddress;