Add module fc113 (PCF8574t)

Dependents:   Cassaforte Cassaforte2 Cassaforte5dic18 Cassaforte5_copy ... more

Fork of TextLCD by Wim Huiskamp

Files at this revision

API Documentation at this revision

Comitter:
wim
Date:
Sat Apr 18 11:33:02 2015 +0000
Parent:
37:ce348c002929
Child:
39:e9c2319de9c5
Commit message:
Fixed Adafruit I2C/SPI portexpander pinmappings, fixed SYDZ Backlight control

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
TextLCD_Config.h Show annotated file Show diff for this revision Revisions of this file
TextLCD_UDC.h Show annotated file Show diff for this revision Revisions of this file
TextLCD_UDC.inc Show annotated file Show diff for this revision Revisions of this file
--- a/TextLCD.cpp	Sun Mar 29 13:08:03 2015 +0000
+++ b/TextLCD.cpp	Sat Apr 18 11:33:02 2015 +0000
@@ -18,6 +18,8 @@
  *               2014, v15: WH, Added AC780 support, added I2C expander modules, fixed setBacklight() for inverted logic modules. Fixed bug in LCD_SPI_N define 
  *               2014, v16: WH, Added ST7070 and KS0073 support, added setIcon(), clrIcon() and setInvert() method for supported devices 
  *               2015, v17: WH, Clean up low-level _writeCommand() and _writeData(), Added support for alternative fonttables (eg PCF21XX), Added ST7066_ACM controller for ACM1602 module 
+ *               2015, v18: WH, Performance improvement I2C portexpander
+ *               2015, v19: WH, Fixed Adafruit I2C/SPI portexpander pinmappings, fixed SYDZ Backlight 
  *
  * 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,6 +71,8 @@
   *  @return none 
   */
 void TextLCD_Base::_init(_LCDDatalength dl) {
+
+  wait_ms(100);                  // Wait 100ms to ensure powered up
   
   // Select and configure second LCD controller when needed
   if(_type==LCD40x4) {
@@ -101,8 +105,6 @@
   int _lines=0;      // Set lines (Ext Instr Set), temporary variable.
 
     this->_setRS(false); // command mode
-    
-    wait_ms(20);         // Wait 20ms to ensure powered up
 
     if (dl == _LCD_DL_4) {
       // The Controller could be in 8 bit mode (power-on reset) or in 4 bit mode (warm reboot) at this point.
@@ -110,18 +112,18 @@
       // between the uP and the LCD can only write the 4 most significant bits (Most Significant Nibble, MSN).
       // In 4 bit mode the LCD expects the MSN first, followed by the LSN.
       //
-      //    Current state:               8 bit mode                |  4 bit mode, MSN is next      | 4 bit mode, LSN is next          
+      //    Current state:               8 bit mode                |      4 bit mode, MSN is next        | 4 bit mode, LSN is next          
                            //-------------------------------------------------------------------------------------------------                          
-      _writeNibble(0x3);   //  set 8 bit mode (MSN) and dummy LSN, |   set 8 bit mode (MSN),       |    set dummy LSN, 
-                           //  remains in 8 bit mode               |    change to 8 bit mode       |  remains in 4 bit mode
+      _writeNibble(0x3);   //  set 8 bit mode (MSN) and dummy LSN, |   set 8 bit mode (MSN),             |    set dummy LSN, 
+                           //  remains in 8 bit mode               |    remains in 4 bit mode            |  remains in 4 bit mode
       wait_ms(15);         //                           
      
-      _writeNibble(0x3);   //  set 8 bit mode and dummy LSN,       | set 8 bit mode and dummy LSN, |    set 8bit mode (MSN), 
-                           //  remains in 8 bit mode               |   remains in 8 bit mode       |  remains in 4 bit mode
+      _writeNibble(0x3);   //  set 8 bit mode (MSN) and dummy LSN, |      set dummy LSN,                 |    set 8bit mode (MSN), 
+                           //  remains in 8 bit mode               |   change to 8 bit mode              |  remains in 4 bit mode
       wait_ms(15);         // 
     
-      _writeNibble(0x3);   //  set 8 bit mode and dummy LSN,       | set 8 bit mode and dummy LSN, |    set dummy LSN, 
-                           //  remains in 8 bit mode               |   remains in 8 bit mode       |  change to 8 bit mode
+      _writeNibble(0x3);   //  set 8 bit mode (MSN) and dummy LSN, | set 8 bit mode (MSN) and dummy LSN, |    set dummy LSN, 
+                           //  remains in 8 bit mode               |   remains in 8 bit mode             |  change to 8 bit mode
       wait_ms(15);         // 
 
       // Controller is now in 8 bit mode
@@ -132,6 +134,10 @@
       // Controller is now in 4-bit mode
       // Note: 4/8 bit mode is ignored for most native SPI and I2C devices. They dont use the parallel bus.
       //       However, _writeNibble() method is void anyway for native SPI and I2C devices.
+    }
+    else {
+      // Reset in 8 bit mode, final Function set will follow 
+      _writeCommand(0x30); // Function set 0 0 1 DL=1 N F x x       
     }      
    
     // Device specific initialisations: DC/DC converter to generate VLCD or VLED, number of lines etc
@@ -1422,7 +1428,7 @@
 
 // Enable is Low
     this->_setEnable(true);        
-    this->_setData(value);        // Low nibble
+    this->_setData(value);        // Low nibble of value on D4..D7
     wait_us(1); // Data setup time        
     this->_setEnable(false);    
     wait_us(1); // Datahold time
@@ -2676,8 +2682,8 @@
     // No Hardware Enable pin       
     _e2 = NULL;                 //Construct dummy pin     
   }  
-
-  _init(_LCD_DL_4);   // Set Datalength to 4 bit for mbed bus interfaces
+  
+   _init(_LCD_DL_4);   // Set Datalength to 4 bit for mbed bus interfaces
 }
 
 /** Destruct a TextLCD interface for using regular mbed pins
@@ -2791,7 +2797,7 @@
 //  _writeRegister(OLAT,    0x00);  // Output Latch  
     
   // Init the portexpander bus
-  _lcd_bus = D_LCD_BUS_DEF;
+  _lcd_bus = LCD_BUS_I2C_DEF;
   
   // write the new data to the portexpander
   _writeRegister(GPIO, _lcd_bus);      
@@ -2799,7 +2805,7 @@
   // PCF8574 of PCF8574A portexpander
 
   // Init the portexpander bus
-  _lcd_bus = D_LCD_BUS_DEF;
+  _lcd_bus = LCD_BUS_I2C_DEF;
 
   // write the new data to the portexpander
   _i2c->write(_slaveAddress, &_lcd_bus, 1);    
@@ -2814,18 +2820,18 @@
 
   if(_ctrl_idx==_LCDCtrl_0) {
     if (value) {
-      _lcd_bus |= D_LCD_E;     // Set E bit 
+      _lcd_bus |= LCD_BUS_I2C_E;     // Set E bit 
     }  
     else {                    
-      _lcd_bus &= ~D_LCD_E;    // Reset E bit                     
+      _lcd_bus &= ~LCD_BUS_I2C_E;    // Reset E bit                     
     }  
   }
   else {
     if (value) {
-      _lcd_bus |= D_LCD_E2;    // Set E2 bit 
+      _lcd_bus |= LCD_BUS_I2C_E2;    // Set E2 bit 
     }  
     else {
-      _lcd_bus &= ~D_LCD_E2;   // Reset E2bit                     
+      _lcd_bus &= ~LCD_BUS_I2C_E2;   // Reset E2bit                     
     }  
   }    
 }    
@@ -2856,10 +2862,10 @@
 void TextLCD_I2C::_setRS(bool value) {
 
   if (value) {
-    _lcd_bus |= D_LCD_RS;    // Set RS bit 
+    _lcd_bus |= LCD_BUS_I2C_RS;    // Set RS bit 
   }  
   else {                    
-    _lcd_bus &= ~D_LCD_RS;   // Reset RS bit                     
+    _lcd_bus &= ~LCD_BUS_I2C_RS;   // Reset RS bit                     
   }
 
 #if (MCP23008==1)
@@ -2880,10 +2886,10 @@
 void TextLCD_I2C::_setBL(bool value) {
 
   if (value) {
-    _lcd_bus |= D_LCD_BL;    // Set BL bit 
+    _lcd_bus |= LCD_BUS_I2C_BL;    // Set BL bit 
   }  
   else {                    
-    _lcd_bus &= ~D_LCD_BL;   // Reset BL bit                     
+    _lcd_bus &= ~LCD_BUS_I2C_BL;   // Reset BL bit                     
   }
   
 #if (MCP23008==1)
@@ -2899,40 +2905,76 @@
 #endif                 
 }    
 
-
+#if(0)
+// New optimized v018
+// Test faster _writeByte 0.11s vs 0.27s for a 20x4 fillscreen (PCF8574), same as v018
+// Place the 4bit data in the databus shadowvalue
+// Used for mbed I2C bus expander
+const char _LCD_DATA_BITS[16] = {
+      0x00,
+      (                                                   LCD_BUS_I2C_D4),
+      (                                  LCD_BUS_I2C_D5                 ),
+      (                                  LCD_BUS_I2C_D5 | LCD_BUS_I2C_D4),
+      (                 LCD_BUS_I2C_D6                                  ),                  
+      (                 LCD_BUS_I2C_D6                  | LCD_BUS_I2C_D4),
+      (                 LCD_BUS_I2C_D6 | LCD_BUS_I2C_D5                 ),
+      (                 LCD_BUS_I2C_D6 | LCD_BUS_I2C_D5 | LCD_BUS_I2C_D4),
+      (LCD_BUS_I2C_D7                                                   ),
+      (LCD_BUS_I2C_D7                                   | LCD_BUS_I2C_D4),
+      (LCD_BUS_I2C_D7                  | LCD_BUS_I2C_D5                 ),
+      (LCD_BUS_I2C_D7                  | LCD_BUS_I2C_D5 | LCD_BUS_I2C_D4),                  
+      (LCD_BUS_I2C_D7 | LCD_BUS_I2C_D6                                  ),
+      (LCD_BUS_I2C_D7 | LCD_BUS_I2C_D6                  | LCD_BUS_I2C_D4),
+      (LCD_BUS_I2C_D7 | LCD_BUS_I2C_D6 | LCD_BUS_I2C_D5                 ),
+      (LCD_BUS_I2C_D7 | LCD_BUS_I2C_D6 | LCD_BUS_I2C_D5 | LCD_BUS_I2C_D4)
+    };
+void TextLCD_I2C::_setDataBits(int value) {
+
+  //Clear all databits
+  _lcd_bus &= ~LCD_BUS_I2C_MSK;
+
+  // Set bit by bit to support any mapping of expander portpins to LCD pins 
+  _lcd_bus |= _LCD_DATA_BITS[value & 0x0F];
+}    
+
+#else
+//orig v017
+// Test faster _writeByte 0.11s vs 0.27s for a 20x4 fillscreen (PCF8574)
 // Place the 4bit data in the databus shadowvalue
 // Used for mbed I2C bus expander
 void TextLCD_I2C::_setDataBits(int value) {
 
   // Set bit by bit to support any mapping of expander portpins to LCD pins 
   if (value & 0x01){
-    _lcd_bus |= D_LCD_D4;   // Set Databit 
+    _lcd_bus |= LCD_BUS_I2C_D4;   // Set Databit 
   }  
   else { 
-    _lcd_bus &= ~D_LCD_D4;  // Reset Databit
+    _lcd_bus &= ~LCD_BUS_I2C_D4;  // Reset Databit
   }  
 
   if (value & 0x02){
-    _lcd_bus |= D_LCD_D5;   // Set Databit 
+    _lcd_bus |= LCD_BUS_I2C_D5;   // Set Databit 
   }  
   else {
-    _lcd_bus &= ~D_LCD_D5;  // Reset Databit
+    _lcd_bus &= ~LCD_BUS_I2C_D5;  // Reset Databit
   }  
 
   if (value & 0x04) {
-    _lcd_bus |= D_LCD_D6;   // Set Databit 
+    _lcd_bus |= LCD_BUS_I2C_D6;   // Set Databit 
   }  
   else {                    
-    _lcd_bus &= ~D_LCD_D6;  // Reset Databit
+    _lcd_bus &= ~LCD_BUS_I2C_D6;  // Reset Databit
   }  
 
   if (value & 0x08) {
-    _lcd_bus |= D_LCD_D7;   // Set Databit 
+    _lcd_bus |= LCD_BUS_I2C_D7;   // Set Databit 
   }  
   else {
-    _lcd_bus &= ~D_LCD_D7;  // Reset Databit
+    _lcd_bus &= ~LCD_BUS_I2C_D7;  // Reset Databit
   }                                      
 }    
+#endif
+
 
 // Place the 4bit data on the databus
 // Used for mbed pins, I2C bus expander or SPI shifregister
@@ -3032,8 +3074,7 @@
 TextLCD_SPI::TextLCD_SPI(SPI *spi, PinName cs, LCDType type, LCDCtrl ctrl) :
                          TextLCD_Base(type, ctrl), 
                          _spi(spi),        
-                         _cs(cs) {      
-        
+                         _cs(cs) {              
   // Init cs
   _cs = 1;  
 
@@ -3043,8 +3084,10 @@
   _spi->frequency(500000);    
   //_spi.frequency(1000000);    
 
+  wait_ms(100);                   // Wait 100ms to ensure LCD powered up
+  
   // Init the portexpander bus
-  _lcd_bus = D_LCD_BUS_DEF;
+  _lcd_bus = LCD_BUS_SPI_DEF;
   
   // write the new data to the portexpander
   _cs = 0;  
@@ -3060,18 +3103,18 @@
 
   if(_ctrl_idx==_LCDCtrl_0) {
     if (value) {
-      _lcd_bus |= D_LCD_E;     // Set E bit 
+      _lcd_bus |= LCD_BUS_SPI_E;     // Set E bit 
     }  
     else {                    
-      _lcd_bus &= ~D_LCD_E;    // Reset E bit                     
+      _lcd_bus &= ~LCD_BUS_SPI_E;    // Reset E bit                     
     }  
   }
   else {
     if (value) {
-      _lcd_bus |= D_LCD_E2;    // Set E2 bit 
+      _lcd_bus |= LCD_BUS_SPI_E2;    // Set E2 bit 
     }  
     else {
-      _lcd_bus &= ~D_LCD_E2;   // Reset E2 bit                     
+      _lcd_bus &= ~LCD_BUS_SPI_E2;   // Reset E2 bit                     
     }  
   }
                   
@@ -3086,10 +3129,10 @@
 void TextLCD_SPI::_setRS(bool value) {
 
   if (value) {
-    _lcd_bus |= D_LCD_RS;    // Set RS bit 
+    _lcd_bus |= LCD_BUS_SPI_RS;    // Set RS bit 
   }  
   else {                    
-    _lcd_bus &= ~D_LCD_RS;   // Reset RS bit                     
+    _lcd_bus &= ~LCD_BUS_SPI_RS;   // Reset RS bit                     
   }
      
   // write the new data to the SPI portexpander
@@ -3103,10 +3146,10 @@
 void TextLCD_SPI::_setBL(bool value) {
 
   if (value) {
-    _lcd_bus |= D_LCD_BL;    // Set BL bit 
+    _lcd_bus |= LCD_BUS_SPI_BL;    // Set BL bit 
   }  
   else {
-    _lcd_bus &= ~D_LCD_BL;   // Reset BL bit                     
+    _lcd_bus &= ~LCD_BUS_SPI_BL;   // Reset BL bit                     
   }
       
   // write the new data to the SPI portexpander
@@ -3121,31 +3164,31 @@
 
   // Set bit by bit to support any mapping of expander portpins to LCD pins
   if (value & 0x01) {
-    _lcd_bus |= D_LCD_D4;   // Set Databit 
+    _lcd_bus |= LCD_BUS_SPI_D4;   // Set Databit 
   }  
   else {                    
-    _lcd_bus &= ~D_LCD_D4;  // Reset Databit                     
+    _lcd_bus &= ~LCD_BUS_SPI_D4;  // Reset Databit                     
   }
   
   if (value & 0x02) {
-    _lcd_bus |= D_LCD_D5;   // Set Databit 
+    _lcd_bus |= LCD_BUS_SPI_D5;   // Set Databit 
   }  
   else {
-    _lcd_bus &= ~D_LCD_D5;  // Reset Databit                     
+    _lcd_bus &= ~LCD_BUS_SPI_D5;  // Reset Databit                     
   }
   
   if (value & 0x04) {
-    _lcd_bus |= D_LCD_D6;   // Set Databit 
+    _lcd_bus |= LCD_BUS_SPI_D6;   // Set Databit 
   }  
   else {
-    _lcd_bus &= ~D_LCD_D6;  // Reset Databit                     
+    _lcd_bus &= ~LCD_BUS_SPI_D6;  // Reset Databit                     
   }
   
   if (value & 0x08) {
-    _lcd_bus |= D_LCD_D7;   // Set Databit 
+    _lcd_bus |= LCD_BUS_SPI_D7;   // Set Databit 
   }  
   else {
-    _lcd_bus &= ~D_LCD_D7;  // Reset Databit
+    _lcd_bus &= ~LCD_BUS_SPI_D7;  // Reset Databit
   }  
                     
   // write the new data to the SPI portexpander
--- a/TextLCD.h	Sun Mar 29 13:08:03 2015 +0000
+++ b/TextLCD.h	Sat Apr 18 11:33:02 2015 +0000
@@ -18,6 +18,7 @@
  *               2014, v15: WH, Added AC780 support, added I2C expander modules, fixed setBacklight() for inverted logic modules. Fixed bug in LCD_SPI_N define 
  *               2014, v16: WH, Added ST7070 and KS0073 support, added setIcon(), clrIcon() and setInvert() method for supported devices  
  *               2015, v17: WH, Clean up low-level _writeCommand() and _writeData(), Added support for alternative fonttables (eg PCF21XX), Added ST7066_ACM controller for ACM1602 module
+ *               2015, v18: WH, Performance improvement I2C portexpander
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -1215,4 +1216,5 @@
 #endif /* Native SPI bus     */
 //-------- End TextLCD_SPI_N_3_24 ----------
 
+
 #endif
--- a/TextLCD_Config.h	Sun Mar 29 13:08:03 2015 +0000
+++ b/TextLCD_Config.h	Sat Apr 18 11:33:02 2015 +0000
@@ -5,6 +5,8 @@
  *               2014, v03: WH, Added LCD_SPI_N_3_8 define for ST7070
  *               2015, v04: WH, Added support for alternative fonttables (eg PCF21XX)
  *               2015, v05: WH, Clean up low-level _writeCommand() and _writeData(), Added support for alt fonttables (eg PCF21XX), Added ST7066_ACM for ACM1602 module, fixed contrast for ST7032 
+ *               2015, v06: WH, Performance improvement I2C portexpander
+ *               2015, v07: WH, Fixed Adafruit I2C/SPI portexpander pinmappings, fixed SYDZ Backlight
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -65,16 +67,30 @@
 //Note: LCD RW pin must be connected to GND
 //      E2 is used for LCD40x4 (second controller)
 //      BL may be used to control backlight
-#define D_LCD_PIN_D4   0
-#define D_LCD_PIN_D5   1
-#define D_LCD_PIN_D6   2
-#define D_LCD_PIN_D7   3
-#define D_LCD_PIN_RS   4
-#define D_LCD_PIN_E    5
-#define D_LCD_PIN_E2   6
-#define D_LCD_PIN_BL   7
+
+//I2C bus expander (PCF8574/PCF8574A or MCP23008) interface
+#define LCD_BUS_I2C_D4 (1 << 0)
+#define LCD_BUS_I2C_D5 (1 << 1)
+#define LCD_BUS_I2C_D6 (1 << 2)
+#define LCD_BUS_I2C_D7 (1 << 3)
+#define LCD_BUS_I2C_RS (1 << 4)
+#define LCD_BUS_I2C_E  (1 << 5)
+#define LCD_BUS_I2C_E2 (1 << 6)
+#define LCD_BUS_I2C_BL (1 << 7)
 
-#define D_LCD_PIN_RW   D_LCD_PIN_E2
+#define LCD_BUS_I2C_RW (1 << 6)
+
+//SPI bus expander (74595) interface, same as I2C 
+#define LCD_BUS_SPI_D4 LCD_BUS_I2C_D4
+#define LCD_BUS_SPI_D5 LCD_BUS_I2C_D5
+#define LCD_BUS_SPI_D6 LCD_BUS_I2C_D6
+#define LCD_BUS_SPI_D7 LCD_BUS_I2C_D7
+#define LCD_BUS_SPI_RS LCD_BUS_I2C_RS
+#define LCD_BUS_SPI_E  LCD_BUS_I2C_E
+#define LCD_BUS_SPI_E2 LCD_BUS_I2C_E2
+#define LCD_BUS_SPI_BL LCD_BUS_I2C_BL
+
+#define LCD_BUS_SPI_RW LCD_BUS_I2C_RW
 
 //Select I2C Portexpander type (one option only)
 #define PCF8574        1
@@ -93,16 +109,33 @@
 //Note: LCD RW pin must be kept LOW
 //      E2 is not available on this hardware and so it does not support LCD40x4 (second controller)
 //      BL is used to control backlight
-#define D_LCD_PIN_0    0
-#define D_LCD_PIN_RS   1
-#define D_LCD_PIN_E    2
-#define D_LCD_PIN_D4   3
-#define D_LCD_PIN_D5   4
-#define D_LCD_PIN_D6   5
-#define D_LCD_PIN_D7   6
-#define D_LCD_PIN_BL   7
+//Note: The pinmappings are different for the MCP23008 and the 74595!
+
+//I2C bus expander (MCP23008) interface
+#define LCD_BUS_I2C_0  (1 << 0)
+#define LCD_BUS_I2C_RS (1 << 1)
+#define LCD_BUS_I2C_E  (1 << 2)
+#define LCD_BUS_I2C_D4 (1 << 3)
+#define LCD_BUS_I2C_D5 (1 << 4)
+#define LCD_BUS_I2C_D6 (1 << 5)
+#define LCD_BUS_I2C_D7 (1 << 6)
+#define LCD_BUS_I2C_BL (1 << 7)
 
-#define D_LCD_PIN_E2   D_LCD_PIN_0
+#define LCD_BUS_I2C_E2 (1 << 0)
+#define LCD_BUS_I2C_RW (1 << 0)
+
+//SPI bus expander (74595) interface
+#define LCD_BUS_SPI_0  (1 << 0)
+#define LCD_BUS_SPI_RS (1 << 1)
+#define LCD_BUS_SPI_E  (1 << 2)
+#define LCD_BUS_SPI_D7 (1 << 3)
+#define LCD_BUS_SPI_D6 (1 << 4)
+#define LCD_BUS_SPI_D5 (1 << 5)
+#define LCD_BUS_SPI_D4 (1 << 6)
+#define LCD_BUS_SPI_BL (1 << 7)
+
+#define LCD_BUS_SPI_E2 (1 << 0)
+#define LCD_BUS_SPI_RW (1 << 0)
 
 //Force I2C portexpander type
 #define PCF8574        0
@@ -127,16 +160,31 @@
 //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)
 //      BL is used to control backlight
-#define D_LCD_PIN_RS   0
-#define D_LCD_PIN_RW   1
-#define D_LCD_PIN_E    2
-#define D_LCD_PIN_BL   3
-#define D_LCD_PIN_D4   4
-#define D_LCD_PIN_D5   5
-#define D_LCD_PIN_D6   6
-#define D_LCD_PIN_D7   7
+
+//I2C bus expander PCF8574 interface
+#define LCD_BUS_I2C_RS (1 << 0)
+#define LCD_BUS_I2C_RW (1 << 1)
+#define LCD_BUS_I2C_E  (1 << 2)
+#define LCD_BUS_I2C_BL (1 << 3)
+#define LCD_BUS_I2C_D4 (1 << 4)
+#define LCD_BUS_I2C_D5 (1 << 5)
+#define LCD_BUS_I2C_D6 (1 << 6)
+#define LCD_BUS_I2C_D7 (1 << 7)
+
+#define LCD_BUS_I2C_E2 (1 << 1)
 
-#define D_LCD_PIN_E2   D_LCD_PIN_RW
+//SPI bus expander (74595) interface, same as I2C
+#define LCD_BUS_SPI_RS LCD_BUS_I2C_RS
+#define LCD_BUS_SPI_RW LCD_BUS_I2C_RW
+#define LCD_BUS_SPI_E  LCD_BUS_I2C_E
+#define LCD_BUS_SPI_BL LCD_BUS_I2C_BL
+#define LCD_BUS_SPI_D4 LCD_BUS_I2C_D4
+#define LCD_BUS_SPI_D5 LCD_BUS_I2C_D5
+#define LCD_BUS_SPI_D6 LCD_BUS_I2C_D6
+#define LCD_BUS_SPI_D7 LCD_BUS_I2C_D7
+
+#define LCD_BUS_SPI_E2 LCD_BUS_I2C_E2
+
 
 //Force I2C portexpander type
 #define PCF8574        1
@@ -155,16 +203,30 @@
 //Note: LCD RW pin must be kept LOW
 //      E2 is not available on default hardware and so it does not support LCD40x4 (second controller)
 //      BL is used to control backlight, reverse logic: Low turns on Backlight. This is handled in setBacklight()
-#define D_LCD_PIN_RS   0
-#define D_LCD_PIN_RW   1
-#define D_LCD_PIN_E    2
-#define D_LCD_PIN_BL   3
-#define D_LCD_PIN_D4   4
-#define D_LCD_PIN_D5   5
-#define D_LCD_PIN_D6   6
-#define D_LCD_PIN_D7   7
+
+//I2C bus expander PCF8574 interface
+#define LCD_BUS_I2C_RS (1 << 0)
+#define LCD_BUS_I2C_RW (1 << 1)
+#define LCD_BUS_I2C_E  (1 << 2)
+#define LCD_BUS_I2C_BL (1 << 3)
+#define LCD_BUS_I2C_D4 (1 << 4)
+#define LCD_BUS_I2C_D5 (1 << 5)
+#define LCD_BUS_I2C_D6 (1 << 6)
+#define LCD_BUS_I2C_D7 (1 << 7)
 
-#define D_LCD_PIN_E2   D_LCD_PIN_RW
+#define LCD_BUS_I2C_E2 (1 << 1)
+
+//SPI bus expander (74595) interface, same as I2C
+#define LCD_BUS_SPI_RS LCD_BUS_I2C_RS
+#define LCD_BUS_SPI_RW LCD_BUS_I2C_RW
+#define LCD_BUS_SPI_E  LCD_BUS_I2C_E
+#define LCD_BUS_SPI_BL LCD_BUS_I2C_BL
+#define LCD_BUS_SPI_D4 LCD_BUS_I2C_D4
+#define LCD_BUS_SPI_D5 LCD_BUS_I2C_D5
+#define LCD_BUS_SPI_D6 LCD_BUS_I2C_D6
+#define LCD_BUS_SPI_D7 LCD_BUS_I2C_D7
+
+#define LCD_BUS_SPI_E2 LCD_BUS_I2C_E2
 
 //Force I2C portexpander type
 #define PCF8574        1
@@ -183,16 +245,30 @@
 //Note: LCD RW pin must be kept LOW
 //      E2 is not available on default hardware and so it does not support LCD40x4 (second controller)
 //      BL is used to control backlight, reverse logic: Low turns on Backlight. This is handled in setBacklight()
-#define D_LCD_PIN_D4   0
-#define D_LCD_PIN_D5   1
-#define D_LCD_PIN_D6   2
-#define D_LCD_PIN_D7   3
-#define D_LCD_PIN_EN   4
-#define D_LCD_PIN_RW   5
-#define D_LCD_PIN_RS   6
-#define D_LCD_PIN_BL   7
+
+//I2C bus expander PCF8574 interface
+#define LCD_BUS_I2C_D4 (1 << 0)
+#define LCD_BUS_I2C_D5 (1 << 1)
+#define LCD_BUS_I2C_D6 (1 << 2)
+#define LCD_BUS_I2C_D7 (1 << 3)
+#define LCD_BUS_I2C_E  (1 << 4)
+#define LCD_BUS_I2C_RW (1 << 5)
+#define LCD_BUS_I2C_RS (1 << 6)
+#define LCD_BUS_I2C_BL (1 << 7)
 
-#define D_LCD_PIN_E2   D_LCD_PIN_RW
+#define LCD_BUS_I2C_E2 (1 << 5)
+
+//SPI bus expander (74595) interface
+#define LCD_BUS_SPI_D4 LCD_BUS_I2C_D4
+#define LCD_BUS_SPI_D5 LCD_BUS_I2C_D5
+#define LCD_BUS_SPI_D6 LCD_BUS_I2C_D6
+#define LCD_BUS_SPI_D7 LCD_BUS_I2C_D7
+#define LCD_BUS_SPI_E  LCD_BUS_I2C_E
+#define LCD_BUS_SPI_RW LCD_BUS_I2C_RW
+#define LCD_BUS_SPI_RS LCD_BUS_I2C_RS
+#define LCD_BUS_SPI_BL LCD_BUS_I2C_BL
+
+#define LCD_BUS_SPI_E2 LCD_BUS_I2C_E2
 
 //Force I2C portexpander type
 #define PCF8574        1
@@ -204,47 +280,62 @@
 
 #if (SYDZ==1)
 //Definitions for SYDZ Module mapping between serial port expander pins and LCD controller. 
-//Very similar to DFROBOT. This hardware uses PCF8574A and uses inverted Backlight control
-//Slaveaddress may be set by switches (default 0x40). SDA/SCL has pullup Resistors onboard.
+//Very similar to DFROBOT. This hardware uses PCF8574A.
+//Slaveaddress may be set by switches (default 0x70). SDA/SCL has pullup Resistors onboard.
 //See ebay
 //
 //Note: LCD RW pin must be kept LOW
 //      E2 is not available on default hardware and so it does not support LCD40x4 (second controller)
-//      BL is used to control backlight, reverse logic: Low turns on Backlight. This is handled in setBacklight()
-#define D_LCD_PIN_RS   0
-#define D_LCD_PIN_RW   1
-#define D_LCD_PIN_E    2
-#define D_LCD_PIN_BL   3
-#define D_LCD_PIN_D4   4
-#define D_LCD_PIN_D5   5
-#define D_LCD_PIN_D6   6
-#define D_LCD_PIN_D7   7
+//      BL is used to control backlight
+
+//I2C bus expander PCF8574A interface
+#define LCD_BUS_I2C_RS (1 << 0)
+#define LCD_BUS_I2C_RW (1 << 1)
+#define LCD_BUS_I2C_E  (1 << 2)
+#define LCD_BUS_I2C_BL (1 << 3)
+#define LCD_BUS_I2C_D4 (1 << 4)
+#define LCD_BUS_I2C_D5 (1 << 5)
+#define LCD_BUS_I2C_D6 (1 << 6)
+#define LCD_BUS_I2C_D7 (1 << 7)
 
-#define D_LCD_PIN_E2   D_LCD_PIN_RW
+#define LCD_BUS_I2C_E2 (1 << 1)
+
+//SPI bus expander (74595) interface, same as I2C
+#define LCD_BUS_SPI_RS LCD_BUS_I2C_RS
+#define LCD_BUS_SPI_RW LCD_BUS_I2C_RW
+#define LCD_BUS_SPI_E  LCD_BUS_I2C_E
+#define LCD_BUS_SPI_BL LCD_BUS_I2C_BL
+#define LCD_BUS_SPI_D4 LCD_BUS_I2C_D4
+#define LCD_BUS_SPI_D5 LCD_BUS_I2C_D5
+#define LCD_BUS_SPI_D6 LCD_BUS_I2C_D6
+#define LCD_BUS_SPI_D7 LCD_BUS_I2C_D7
+
+#define LCD_BUS_SPI_E2 LCD_BUS_I2C_E2
 
 //Force I2C portexpander type
 #define PCF8574        1
 #define MCP23008       0
 
 //Force Inverted Backlight control
-#define BACKLIGHT_INV  1
+#define BACKLIGHT_INV  0
 #endif
 
 //Bitpattern Defines for I2C PCF8574/PCF8574A, MCP23008 and SPI 74595 Bus expanders
 //Don't change!
-//
-#define D_LCD_D4       (1<<D_LCD_PIN_D4)
-#define D_LCD_D5       (1<<D_LCD_PIN_D5)
-#define D_LCD_D6       (1<<D_LCD_PIN_D6)
-#define D_LCD_D7       (1<<D_LCD_PIN_D7)
-#define D_LCD_RS       (1<<D_LCD_PIN_RS)
-#define D_LCD_E        (1<<D_LCD_PIN_E)
-#define D_LCD_E2       (1<<D_LCD_PIN_E2)
-#define D_LCD_BL       (1<<D_LCD_PIN_BL)
-//#define D_LCD_RW       (1<<D_LCD_PIN_RW)
+#define LCD_BUS_I2C_MSK (LCD_BUS_I2C_D4 | LCD_BUS_I2C_D5 | LCD_BUS_I2C_D6 | LCD_BUS_I2C_D7)
+#if (BACKLIGHT_INV == 1)
+#define LCD_BUS_I2C_DEF (0x00 | LCD_BUS_I2C_BL)
+#else
+#define LCD_BUS_I2C_DEF  0x00
+#endif
 
-#define D_LCD_BUS_MSK  (D_LCD_D4 | D_LCD_D5 | D_LCD_D6 | D_LCD_D7)
-#define D_LCD_BUS_DEF  0x00
+#define LCD_BUS_SPI_MSK (LCD_BUS_SPI_D4 | LCD_BUS_SPI_D5 | LCD_BUS_SPI_D6 | LCD_BUS_SPI_D7)
+#if (BACKLIGHT_INV == 1)
+#define LCD_BUS_SPI_DEF (0x00 | LCD_BUS_SPI_BL)
+#else
+#define LCD_BUS_SPI_DEF  0x00
+#endif
+
 
 /* PCF8574/PCF8574A I2C portexpander slave address */
 #define PCF8574_SA0    0x40
--- a/TextLCD_UDC.h	Sun Mar 29 13:08:03 2015 +0000
+++ b/TextLCD_UDC.h	Sat Apr 18 11:33:02 2015 +0000
@@ -1,6 +1,7 @@
 /* mbed TextLCD Library, for LCDs based on HD44780 controllers
  * Copyright (c) 2014, WH
  *               2014, v01: WH, Extracted from TextLCD.h as of v14
+ *               2015, v02: WH, Added some UDC definitions and commented out several UDCs
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -51,10 +52,10 @@
 extern const char udc_6[];       // checkerboard
 extern const char udc_7[];       // \
 
-extern const char udc_degr[];    // Degree symbol
+//extern const char udc_degr[];    // Degree symbol
 
-extern const char udc_TM_T[];    // Trademark T
-extern const char udc_TM_M[];    // Trademark M
+//extern const char udc_TM_T[];    // Trademark T
+//extern const char udc_TM_M[];    // Trademark M
 
 //extern const char udc_Bat_Hi[];  // Battery Full
 //extern const char udc_Bat_Ha[];  // Battery Half
@@ -82,8 +83,20 @@
 //extern const char udc_ch_mo[];   // Month  (kana)
 //extern const char udc_ch_dy[];   // Day    (kana)
 //extern const char udc_ch_mi[];   // minute (kana)
-extern const char udc_None[]; 
-extern const char udc_All[];
+
+//extern const char udc_bell[];
+//extern const char udc_note[];
+//extern const char udc_clock[];
+//extern const char udc_heart[];
+//extern const char udc_duck[];
+//extern const char udc_check[];
+//extern const char udc_cross[];
+//extern const char udc_retarrow[];
+//extern const char udc_OK[];
+//extern const char udc_1_2[];
+
+//extern const char udc_None[]; 
+//extern const char udc_All[];
 #endif /* LCD_UDC Examples */
 
 #endif // MBED_TEXTLCDUDC_H
\ No newline at end of file
--- a/TextLCD_UDC.inc	Sun Mar 29 13:08:03 2015 +0000
+++ b/TextLCD_UDC.inc	Sat Apr 18 11:33:02 2015 +0000
@@ -1,6 +1,7 @@
 /* mbed TextLCD Library, for LCDs based on HD44780 controllers
  * Copyright (c) 2014, WH
  *               2014, v01: WH, Extracted from TextLCD.cpp as of v14
+ *               2015, v02: WH, Added some UDC definitions and commented out several UDCs
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -63,10 +64,10 @@
 const char udc_6[]  = {0x15, 0x0a, 0x15, 0x0a, 0x15, 0x0a, 0x15, 0x00};  // checkerboard
 const char udc_7[]  = {0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x10, 0x00};  // \
 
-const char udc_degr[]   = {0x06, 0x09, 0x09, 0x06, 0x00, 0x00, 0x00, 0x00};  // Degree symbol
+//const char udc_degr[]   = {0x06, 0x09, 0x09, 0x06, 0x00, 0x00, 0x00, 0x00};  // Degree symbol
 
-const char udc_TM_T[]   = {0x1F, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00};  // Trademark T
-const char udc_TM_M[]   = {0x11, 0x1B, 0x15, 0x11, 0x00, 0x00, 0x00, 0x00};  // Trademark M
+//const char udc_TM_T[]   = {0x1F, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00};  // Trademark T
+//const char udc_TM_M[]   = {0x11, 0x1B, 0x15, 0x11, 0x00, 0x00, 0x00, 0x00};  // Trademark M
 
 //const char udc_Bat_Hi[] = {0x0E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00};  // Battery Full
 //const char udc_Bat_Ha[] = {0x0E, 0x11, 0x13, 0x17, 0x1F, 0x1F, 0x1F, 0x00};  // Battery Half
@@ -79,7 +80,7 @@
 const char udc_Bat_Lo[] = {0x8E, 0x91, 0x91, 0x91, 0x91, 0x9F, 0x9F, 0x00};  // Battery Low, Blink
 const char udc_AC[]     = {0x0A, 0x0A, 0x1F, 0x11, 0x0E, 0x04, 0x04, 0x00};  // AC Power
 
-const char udc_smiley[] = {0x00, 0x0A, 0x00, 0x04, 0x11, 0x0E, 0x00, 0x00};  // Smiley
+//const char udc_smiley[] = {0x00, 0x0A, 0x00, 0x04, 0x11, 0x0E, 0x00, 0x00};  // Smiley
 //const char udc_droopy[] = {0x00, 0x0A, 0x00, 0x04, 0x00, 0x0E, 0x11, 0x00};  // Droopey
 //const char udc_note[]   = {0x01, 0x03, 0x05, 0x09, 0x0B, 0x1B, 0x18, 0x00};  // Note
 
@@ -98,15 +99,17 @@
 //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)
 
-//const char udc_bell[]     = {0x04,0x0E,0x0E,0x0E,0x1F,0x00,0x04};
-//const char udc_note[]     = {0x02,0x03,0x02,0x0E,0x1E,0x0C,0x00};
-//const char udc_clock[]    = {0x00,0x0E,0x15,0x17,0x11,0x0E,0x00};
-//const char udc_heart[]    = {0x00,0x0a,0x1F,0x1F,0x0E,0x04,0x00};
-//const char udc_duck[]     = {0x00,0x0c,0x1D,0x0F,0x0F,0x06,0x00};
-//const char udc_check[]    = {0x00,0x01,0x03,0x16,0x1C,0x08,0x00};
-//const char udc_cross[]    = {0x00,0x1B,0x0E,0x04,0x0E,0x1B,0x00};
-//const char udc_retarrow[] = {0x01,0x01,0x05,0x09,0x1f,0x08,0x04};
+//const char udc_bell[]     = {0x04, 0x0E, 0x0E, 0x0E, 0x1F, 0x00, 0x04, 0x00};
+//const char udc_note[]     = {0x02, 0x03, 0x02, 0x0E, 0x1E, 0x0C, 0x00, 0x00};
+//const char udc_clock[]    = {0x00, 0x0E, 0x15, 0x17, 0x11, 0x0E, 0x00, 0x00};
+//const char udc_heart[]    = {0x00, 0x0a, 0x1F, 0x1F, 0x0E, 0x04, 0x00, 0x00};
+//const char udc_duck[]     = {0x00, 0x0c, 0x1D, 0x0F, 0x0F, 0x06, 0x00, 0x00};
+//const char udc_check[]    = {0x00, 0x01, 0x03, 0x16, 0x1C, 0x08, 0x00, 0x00};
+//const char udc_cross[]    = {0x00, 0x1B, 0x0E, 0x04, 0x0E, 0x1B, 0x00, 0x00};
+//const char udc_retarrow[] = {0x01, 0x01, 0x05, 0x09, 0x1f, 0x08, 0x04, 0x00};
+//const char udc_OK[]       = {0x08, 0x14, 0x14, 0x08, 0x05, 0x06, 0x05, 0x05};  // OK
+//const char udc_1_2[]      = {0x11, 0x12, 0x17, 0x09, 0x13, 0x04, 0x07, 0x00};  // 1/2
 
-const char udc_None[]    =  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 
-const char udc_All[]     =  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 
+//const char udc_None[]       = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 
+//const char udc_All[]        = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 
 #endif /* UDC_EXAMPLES */