Skip to content

Instantly share code, notes, and snippets.

@deadbok
Last active March 3, 2018 21:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save deadbok/fcb8c0b96920caaca4ad63b46d383037 to your computer and use it in GitHub Desktop.
Save deadbok/fcb8c0b96920caaca4ad63b46d383037 to your computer and use it in GitHub Desktop.
Debian lcdproc patch to make pin mapping customisable in the HD44780 I2C driver.
Description: Patch to make the HD44870 pin mapping configurable in the I2C driver.
This patch makes it possible to customise the pin mapping for the HD44780
driver when using and I2C interface. The original sources are from https://github.com/wilberforce/lcdproc.
.
--- lcdproc-0.5.7.orig/clients/lcdproc/main.c
+++ lcdproc-0.5.7/clients/lcdproc/main.c
@@ -58,7 +58,7 @@ int Quit = 0;
int sock = -1;
char *version = VERSION;
-char *build_date = __DATE__;
+char *build_date = "Tue, 22 Mar 2016 19:45:10 +0100";
int lcd_wid = 0;
int lcd_hgt = 0;
--- lcdproc-0.5.7.orig/docs/lcdproc-user/drivers/hd44780.docbook
+++ lcdproc-0.5.7/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
+]]>
+</screen>
+</example>
+
+<para>
+If your port expander has different wiring you can re-assign the pins in the config file
+</para>
+
+<example id="hd44780-i2c-config.example alternative wiring">
+<title>HD44780: Configuration for I<superscript>2</superscript>C with port expander
+Alternative Wiring</title>
+<screen>
+<![CDATA[
+- PCF8574AP: P0 P1 P2 P3 P4 P5 P6 P7
+- | | | | | | | |
+- HD44780: RS RW EN BL D4 D5 D6 D7
+]]>
+</screen>
+</example>
+
+<example id="hd44780-i2c-config.example alternative config">
+<title>HD44780: Configuration for I<superscript>2</superscript>C with port expander
+alternative config</title>
+<screen>
+<![CDATA[
+[HD44780]
+ConnectionType=i2c
+Device=/dev/i2c-0
+Port=0x20
+Size=40x2
+DelayBus=false
+DelayMult=1
+Keypad=no
+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
]]>
</screen>
</example>
--- lcdproc-0.5.7.orig/server/drivers/hd44780-i2c.c
+++ lcdproc-0.5.7/server/drivers/hd44780-i2c.c
@@ -13,17 +13,38 @@
* 1997 Matthias Prinke <m.prinke@trashcan.mcnet.de>
*
* 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, uns
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, uns
*/
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);
}
--- lcdproc-0.5.7.orig/server/drivers/hd44780-low.h
+++ lcdproc-0.5.7/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
--- lcdproc-0.5.7.orig/server/main.c
+++ lcdproc-0.5.7/server/main.c
@@ -103,7 +103,7 @@
char *version = VERSION;
char *protocol_version = PROTOCOL_VERSION;
char *api_version = API_VERSION;
-char *build_date = __DATE__;
+char *build_date = "Tue, 22 Mar 2016 19:45:10 +0100";
/**** Configuration variables ****/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment