diff --git a/docs/lcdproc-user/drivers/hd44780.docbook b/docs/lcdproc-user/drivers/hd44780.docbook
index 324a82a..721e5fa 100644
--- a/docs/lcdproc-user/drivers/hd44780.docbook
+++ b/docs/lcdproc-user/drivers/hd44780.docbook
@@ -2516,6 +2516,61 @@ Size=40x2
DelayBus=false
DelayMult=1
Keypad=no
+#i2c_line_RS=0x10
+#i2c_line_RW=0x20
+#i2c_line_EN=0x40
+#i2c_line_BL=0x80
+#i2c_line_D4=0x01
+#i2c_line_D5=0x02
+#i2c_line_D6=0x04
+#i2c_line_D7=0x08
+# BacklightInvert=yes
+# The Backlight Invert is used if a 0 turns the backlight on, and 1 turns it off, i.e. npn transistor
+]]>
+
+
+
+
+If your port expander has different wiring you can re-assign the pins in the config file
+
+
+
+HD44780: Configuration for I2C with port expander
+Alternative Wiring
+
+
+
+
+
+
+HD44780: Configuration for I2C with port expander
+alternative config
+
+
diff --git a/server/drivers/hd44780-i2c.c b/server/drivers/hd44780-i2c.c
index 0a5e45e..8f19694 100644
--- a/server/drivers/hd44780-i2c.c
+++ b/server/drivers/hd44780-i2c.c
@@ -13,17 +13,38 @@
* 1997 Matthias Prinke
*
* The connections are:
- * PCF8574AP LCD
- * P0 (4) D4 (11)
- * P1 (5) D5 (12)
- * P2 (6) D6 (13)
- * P3 (7) D7 (14)
- * P4 (9) RS (4)
- * P5 (10) RW (5)
- * P6 (11) EN (6)
+ * PCF8574AP Bit LCD
+ * P0 (4) 0x01 D4 (11)
+ * P1 (5) 0x02 D5 (12)
+ * P2 (6) 0x04 D6 (13)
+ * P3 (7) 0x08 D7 (14)
+ * P4 (9) 0x10 RS (4)
+ * P5 (10) 0x20 RW (5)
+ * P6 (11) 0x40 EN (6)
+ * P7 (12) 0x80 /backlight (optional, active-low)
*
- * Backlight
- * P7 (12) /backlight (optional, active-low)
+ * Configuration:
+ \verbatim
+ alternative wiring example:
+ PCF8574AP: P0 P1 P2 P3 P4 P5 P6 P7
+ | | | | | | | |
+ HD44780: RS RW EN BL D4 D5 D6 D7
+
+ in LCDd.conf we then need to define
+ i2c_line_RS=0x01
+ i2c_line_RW=0x02
+ i2c_line_EN=0x04
+ i2c_line_BL=0x80
+ i2c_line_D4=0x10
+ i2c_line_D5=0x20
+ i2c_line_D6=0x40
+ i2c_line_D7=0x80
+ Backlight=yes
+ BacklightInvert=yes
+
+ The Backlight Invert is used if a 0 turns the backlight on, and 1 turns it off, i.e. npn transistor
+\endverbatim
+
*
* Configuration:
* device=/dev/i2c-0 # the device file of the i2c bus
@@ -89,6 +110,11 @@ void i2c_HD44780_close(PrivateData *p);
#define RW 0x20
#define EN 0x40
#define BL 0x80
+#define D4 0x01
+#define D5 0x02
+#define D6 0x04
+#define D7 0x08
+#define BL_INVERT 0
// note that the above bits are all meant for the data port of PCF8574
#define I2C_ADDR_MASK 0x7f
@@ -145,14 +171,34 @@ hd_init_i2c(Driver *drvthis)
PrivateData *p = (PrivateData*) drvthis->private_data;
HD44780_functions *hd44780_functions = p->hd44780_functions;
- int enableLines = EN;
- char device[256] = DEFAULT_DEVICE;
+ p->i2c_backlight_invert = drvthis->config_get_bool(drvthis->name, "BacklightInvert", 0, BL_INVERT);
+ p->i2c_line_RS = drvthis->config_get_int(drvthis->name, "i2c_line_RS", 0, RS);
+ p->i2c_line_RW = drvthis->config_get_int(drvthis->name, "i2c_line_RW", 0, RW);
+ p->i2c_line_EN = drvthis->config_get_int(drvthis->name, "i2c_line_EN", 0, EN);
+ p->i2c_line_BL = drvthis->config_get_int(drvthis->name, "i2c_line_BL", 0, BL);
+ p->i2c_line_D4 = drvthis->config_get_int(drvthis->name, "i2c_line_D4", 0, D4);
+ p->i2c_line_D5 = drvthis->config_get_int(drvthis->name, "i2c_line_D5", 0, D5);
+ p->i2c_line_D6 = drvthis->config_get_int(drvthis->name, "i2c_line_D6", 0, D6);
+ p->i2c_line_D7 = drvthis->config_get_int(drvthis->name, "i2c_line_D7", 0, D7);
+
+ report(RPT_INFO, "HD44780: I2C: Init using D4 and D5, and or'd lines, invert", p->i2c_line_RS);
+ report(RPT_INFO, "HD44780: I2C: Pin RS mapped to 0x%02X", p->i2c_line_RS);
+ report(RPT_INFO, "HD44780: I2C: Pin RW mapped to 0x%02X", p->i2c_line_RW);
+ report(RPT_INFO, "HD44780: I2C: Pin EN mapped to 0x%02X", p->i2c_line_EN);
+ report(RPT_INFO, "HD44780: I2C: Pin BL mapped to 0x%02X", p->i2c_line_BL);
+ report(RPT_INFO, "HD44780: I2C: Pin D4 mapped to 0x%02X", p->i2c_line_D4);
+ report(RPT_INFO, "HD44780: I2C: Pin D5 mapped to 0x%02X", p->i2c_line_D5);
+ report(RPT_INFO, "HD44780: I2C: Pin D6 mapped to 0x%02X", p->i2c_line_D6);
+ report(RPT_INFO, "HD44780: I2C: Pin D7 mapped to 0x%02X", p->i2c_line_D7);
+ report(RPT_INFO, "HD44780: I2C: Invert Backlight %d", p->i2c_backlight_invert);
+
+ char device[256] = DEFAULT_DEVICE;
#ifdef HAVE_DEV_IICBUS_IIC_H
struct iiccmd cmd;
bzero(&cmd, sizeof(cmd));
#endif
- p->backlight_bit = BL;
+ p->backlight_bit = p->i2c_line_BL;
/* READ CONFIG FILE */
@@ -209,44 +255,49 @@ hd_init_i2c(Driver *drvthis)
// powerup the lcd now
/* We'll now send 0x03 a couple of times,
- * which is in fact (FUNCSET | IF_8BIT) >> 4 */
- i2c_out(p, 0x03);
+ * which is in fact (FUNCSET | IF_8BIT) >> 4
+ */
+ i2c_out(p, p->i2c_line_D4 | p->i2c_line_D5);
if (p->delayBus)
hd44780_functions->uPause(p, 1);
- i2c_out(p, enableLines | 0x03);
+ i2c_out(p, p->i2c_line_EN | p->i2c_line_D4 | p->i2c_line_D5);
if (p->delayBus)
hd44780_functions->uPause(p, 1);
- i2c_out(p, 0x03);
+ i2c_out(p, p->i2c_line_D4 | p->i2c_line_D5);
hd44780_functions->uPause(p, 15000);
- i2c_out(p, enableLines | 0x03);
+ i2c_out(p, p->i2c_line_EN | p->i2c_line_D4 | p->i2c_line_D5);
if (p->delayBus)
hd44780_functions->uPause(p, 1);
- i2c_out(p, 0x03);
+ i2c_out(p, p->i2c_line_D4 | p->i2c_line_D5);
hd44780_functions->uPause(p, 5000);
- i2c_out(p, enableLines | 0x03);
+ i2c_out(p, p->i2c_line_EN | p->i2c_line_D4 | p->i2c_line_D5);
if (p->delayBus)
hd44780_functions->uPause(p, 1);
- i2c_out(p, 0x03);
+ i2c_out(p, p->i2c_line_D4 | p->i2c_line_D5);
hd44780_functions->uPause(p, 100);
- i2c_out(p, enableLines | 0x03);
+ i2c_out(p, p->i2c_line_EN | p->i2c_line_D4 | p->i2c_line_D5);
if (p->delayBus)
hd44780_functions->uPause(p, 1);
- i2c_out(p, 0x03);
+ i2c_out(p, p->i2c_line_D4 | p->i2c_line_D5);
hd44780_functions->uPause(p, 100);
// now in 8-bit mode... set 4-bit mode
- i2c_out(p, 0x02);
+ /*
+ OLD (FUNCSET | IF_4BIT) >> 4 0x02
+ ALT (FUNCSET | IF_4BIT) 0x20
+ */
+ i2c_out(p, p->i2c_line_D5);
if (p->delayBus)
hd44780_functions->uPause(p, 1);
- i2c_out(p, enableLines | 0x02);
+ i2c_out(p, p->i2c_line_EN | p->i2c_line_D5);
if (p->delayBus)
hd44780_functions->uPause(p, 1);
- i2c_out(p, 0x02);
+ i2c_out(p, p->i2c_line_D5);
hd44780_functions->uPause(p, 100);
// Set up two-line, small character (5x8) mode
@@ -279,23 +330,28 @@ i2c_HD44780_close(PrivateData *p) {
void
i2c_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch)
{
- unsigned char enableLines = 0, portControl = 0;
- unsigned char h = (ch >> 4) & 0x0f; // high and low nibbles
- unsigned char l = ch & 0x0f;
-
+ unsigned char portControl = 0;
+ unsigned char h=0;
+ unsigned char l=0;
+ if( ch & 0x80 ) h |= p->i2c_line_D7;
+ if( ch & 0x40 ) h |= p->i2c_line_D6;
+ if( ch & 0x20 ) h |= p->i2c_line_D5;
+ if( ch & 0x10 ) h |= p->i2c_line_D4;
+ if( ch & 0x08 ) l |= p->i2c_line_D7;
+ if( ch & 0x04 ) l |= p->i2c_line_D6;
+ if( ch & 0x02 ) l |= p->i2c_line_D5;
+ if( ch & 0x01 ) l |= p->i2c_line_D4;
if (flags == RS_INSTR)
portControl = 0;
else //if (flags == RS_DATA)
- portControl = RS;
+ portControl = p->i2c_line_RS;
portControl |= p->backlight_bit;
- enableLines = EN;
-
i2c_out(p, portControl | h);
if (p->delayBus)
p->hd44780_functions->uPause(p, 1);
- i2c_out(p, enableLines | portControl | h);
+ i2c_out(p, p->i2c_line_EN | portControl | h);
if (p->delayBus)
p->hd44780_functions->uPause(p, 1);
i2c_out(p, portControl | h);
@@ -303,7 +359,7 @@ i2c_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flag
i2c_out(p, portControl | l);
if (p->delayBus)
p->hd44780_functions->uPause(p, 1);
- i2c_out(p, enableLines | portControl | l);
+ i2c_out(p, p->i2c_line_EN | portControl | l);
if (p->delayBus)
p->hd44780_functions->uPause(p, 1);
i2c_out(p, portControl | l);
@@ -317,7 +373,9 @@ i2c_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flag
*/
void i2c_HD44780_backlight(PrivateData *p, unsigned char state)
{
- p->backlight_bit = ((!p->have_backlight||state) ? 0 : BL);
-
+ if ( p->i2c_backlight_invert == 0 )
+ p->backlight_bit = ((!p->have_backlight||state) ? 0 : p->i2c_line_BL);
+ else // Inverted backlight - npn transistor
+ p->backlight_bit = ((p->have_backlight && state) ? p->i2c_line_BL : 0);
i2c_out(p, p->backlight_bit);
}
diff --git a/server/drivers/hd44780-low.h b/server/drivers/hd44780-low.h
index 47acf45..8b7bba6 100644
--- a/server/drivers/hd44780-low.h
+++ b/server/drivers/hd44780-low.h
@@ -155,6 +155,21 @@ typedef struct hd44780_private_data {
int ftdi_line_backlight;
#endif
+#ifdef HAVE_I2C
+ /* libi2c-based connection types */
+
+ int i2c_backlight_invert;
+ int i2c_line_RS;
+ int i2c_line_RW;
+ int i2c_line_EN;
+ int i2c_line_BL;
+ int i2c_line_D4;
+ int i2c_line_D5;
+ int i2c_line_D6;
+ int i2c_line_D7;
+
+#endif
+
#ifdef WITH_ETHLCD
int sock; /**< socket for TCP devices */
#endif