diff --git a/ChangeLog b/ChangeLog
index c3d9b33..03c427b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -13,6 +13,7 @@ v0.5dev (ongoing development)
+ hd44780: Added 'raspberrypi' connection type (P. Corner)
* Build system: Rename configure.in to configure.ac
+ hd44780: Add support for FreeBSD's iic I2C framework
+ + hd44780: New connection type 'piplate' (J. Brogdon)
v0.5.6
- Remove deprecated CFontz633 driver. Use CFontzPacket with Model=633 instead!
diff --git a/acinclude.m4 b/acinclude.m4
index 3cc9b6c..3fe1325 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -227,6 +227,7 @@ dnl else
fi
if test "$x_ac_have_i2c" = yes; then
HD44780_DRIVERS="$HD44780_DRIVERS hd44780-hd44780-i2c.o"
+ HD44780_DRIVERS="$HD44780_DRIVERS hd44780-hd44780-piplate.o"
fi
dnl The hd4470-rpi driver only works on a Raspberry Pi,
dnl which is an ARM platform. Require people to compile on
diff --git a/docs/lcdproc-user/drivers/hd44780.docbook b/docs/lcdproc-user/drivers/hd44780.docbook
index 7d07ab5..881cf6a 100644
--- a/docs/lcdproc-user/drivers/hd44780.docbook
+++ b/docs/lcdproc-user/drivers/hd44780.docbook
@@ -24,165 +24,163 @@ Each of these different ways is called a connection type
of the driver.
-
-On a parallel port, probably the first interface type HD44780 devices were
-historically connected to, the driver supports the connection types:
-
-
-
-
- 4bit:
- 4bit Wiring
-
-
-
- 8bit:
- 8bit Wiring ("lcdtime")
-
-
-
- winamp:
- 8bit Wiring "winamp" Style
-
-
-
- serialLpt:
- Serial LPT Wiring
-
-
-
-
-For serial RS-232 ports you can choose among these connection types:
-
-
-
-
- picanlcd:
- PIC-an-LCD serial device
-
-
-
- lcdserializer:
- LCD serializer
-
-
-
- los-panel:
- LCD on Serial panel device ()
-
-
-
- vdr-lcd:
- VDR LCD serial device
-
-
-
- vdr-wakeup:
- VDR-Wakeup module
-
-
-
-
-In recent years, with with parallel ports and serial ports being declared legacy
-and on the demise on modern computers, the USB connection types get
-more important. Here are the USB connection types the HD44780 driver supports:
-
-
-
-
- pertelian:
- Pertelian X2040 LCD display ()
-
-
-
- bwctusb:
- BWCT USB LCD module ()
-
-
-
- lcd2usb:
- Till Harbaum's LCD2USB ()
-
-
-
- usbtiny:
- Dick Streefland's USBtiny ()
-
-
-
- uss720:
- Display connected to USS-720 USB-to-IEEE 1284 Bridge (Belkin F5U002)
-
-
-
- lis2:
- LIS2 from VLSystem ()
-
-
-
- mplay:
- MPlay Blast from VLSystem ()
-
-
-
- ftdi:
- Display connected to a dual channel FTDI 2232D USB chip
-
-
-
- usblcd:
- USBLCD from Adams IT Services ()
-
-
-
- USB-4-all:
- Display connected to USB-4-all controller ()
-
-
-
-
-
-Last but not least, for special purposes, there are even more connection types:
-
-
-
-
- i2c:
- LCD driven by PCF8574(A)/PCA9554(A) connected via I2C
-
-
-
- ethlcd:
- Display connected via TCP to PoE powered ethlcd device ()
-
-
-
- raspberrypi:
- LCD connected to the GPIO header of a Raspberry Pi
-
-
-
-
-
Depending on the connection type and the display connected, the driver supports
various special features.
Input keys
- software controllable brightness / backlight
- software controllable contrast
+ Software controllable brightness / backlight
+ Software controllable contrast
multiple displays / multi-controller displays
-
+
+ Parallel port connection types:
+
+
+ 4bit
+ 4-bit wiring. This is the default.
+
+
+ 8bit
+ 8-bit wiring ("lcdtime" style)
+
+
+ winamp
+ 8-bit wiring ("winamp" style)
+
+
+ serialLpt
+ Serial LPT wiring
+
+
+
+ Serial (RS-232) connection types:
+
+
+ picanlcd
+ PIC-an-LCD serial device "picanlcd"
+
+
+ lcdserializer
+ LCD serializer "lcdserializer"
+
+
+ los-panel
+ LCD on Serial panel device "los-panel" ()
+
+
+ vdr-lcd
+ VDR LCD serial device "vdr-lcd"
+
+
+ vdr-wakeup
+ VDR-Wakeup module "vdr-wakeup"
+
+
+
+ USB connection types:
+
+
+ pertelian
+ Pertelian X2040 LCD display ()
+
+
+ lis2
+ LIS2 from VLSystem ()
+
+
+ mplay
+ MPlay Blast from VLSystem ()
+
+
+ usblcd
+ USBLCD adapter from Adams IT Services ()
+
+
+ bwctusb
+ BWCT USB device "bwctusb" ()
+
+
+ lcd2usb
+ Till Harbaum's LCD2USB ()
+
+
+ usbtiny
+ Dick Streefland's USBtiny ()
+
+
+ uss720
+ Belkin USS-720 USB-to-IEEE 1284 Bridge (Belkin F5U002)
+
+
+ USB-4-all
+ The USB-4-all controller board from Sprut ()
+
+
+ ftdi
+ Display connected to a FTDI RS2232 (dual channel) or
+ FTDI RS232 (single channel) USB chip
+
+
+
+ I2C connection types:
+
+
+ i2c
+ LCD driven by PCF8574(A)/PCA9554(A) connected via I2C
+
+
+ piplate
+ Adafruit RGB Positive 16x2 LCD+Keypad for Raspberry Pi
+
+
+
+ Other connection types:
+
+
+ ethlcd
+ Display connected via TCP to PoE powered ethlcd device
+ ()
+
+
+ raspberrypi
+ LCD connected to the GPIO header of a Raspberry Pi
+
+
+
+
+
+
+
+
+ If you suspect the table above to be outdated, you might want to have a look at
+ server/drivers/hd44780-drivers.h in LCDproc's
+ source directory which contains the actual translation code.
+
+
--->
@@ -2229,105 +2227,6 @@ Device=/dev/ttyS0
Finally, start the daemon and relax watching lcdproc running.
-
-
-Customizing startup message
-
-
-If want to change the default startup message (OK.), you can edit the asm source
-and write anything you want.
-Open the asm source with your preferred editor and look for this:
-
-
-
-
-
-
-
-
-
-This piece of code sends three characters to the LCD.
-The first line sets the value of w register (working register, aka accumulator) to 0x4F ('O' in ascii). The second line copies this
-value to ARG1, then the value is sent to the LCD. The fourth line delays the execution.
-
-
-
-You don't have to write the ASCII values in your modification, gpasm does the translation for you, so
-if you want to see Booting... at startup, change the code above to look like this:
-
-
-
-
-
-
-
-
-
-Refer to burning section in order to compile and reflash the new firmware.
-
-
@@ -3121,9 +3020,46 @@ pin_BL=17
-
+
+Adafruit Pi Plate
+
+
+The Adafruit RGB Positive 16x2 LCD+Keypad for Raspberry Pi (aka Pi Plate,
+see ()) combines
+a 16x2 Character LCD, up to 3 backlight pins AND 5 keypad pins using only
+the two I2C pins on the Rasperry Pi.
+
+
+
+Note that this connection type drives all RGB pins of the backlight at the
+same time, resulting in a white backlight. You will need to modify the
+source code if you want to have some other color.
+
+
+
+HD44780: Configuration example for Pi Plate connection type
+
+
+
+
+
+
@@ -3159,6 +3095,9 @@ This can be done by specifying or by inclu
Common values for PORT are 0x278,
0x378 and 0x3BC.
If not given, the default is 0x378.
+
+ For I2C connection types this sets the slave
+ address.
@@ -3201,130 +3140,16 @@ This can be done by specifying or by inclu
usb4all |
ftdi |
i2c |
+ piplate |
ethlcd |
raspberrypi
}
- Select the type of the wiring / display connection.
+ Select the type of the wiring / display connection. See also
+ ().
-
-
-
-
- ConnectionType
- Wiring / Display Type
-
-
-
-
-
- 4bit
- 4bit Wiring to parallel port(default)
-
-
- 8bit
- 8bit Wiring to parallel port ("lcdtime")
-
-
- winamp
- 8bit Wiring "winamp" Style to parallel port
-
-
- serialLpt
- Serial LPT Wiring
-
-
-
- picanlcd
- PIC-an-LCD serial device "picanlcd"
-
-
- lcdserializer
- LCD serializer "lcdserializer"
-
-
- los-panel
- LCD on Serial panel device "los-panel" ()
-
-
- vdr-lcd
- VDR LCD serial device "vdr-lcd"
-
-
- vdr-wakeup
- VDR-Wakeup module "vdr-wakeup"
-
-
- pertelian
- Pertelian X2040 LCD display ()
-
-
-
- lis2
- LIS2 from VLSystem ()
-
-
- mplay
- MPlay Blast from VLSystem ()
-
-
- usblcd
- USBLCD adapter from Adams IT Services ()
-
-
- bwctusb
- BWCT USB device "bwctusb" ()
-
-
- lcd2usb
- Till Harbaum's LCD2USB ()
-
-
- usbtiny
- Dick Streefland's USBtiny ()
-
-
- uss720
- Belkin USS-720 USB-to-IEEE 1284 Bridge
-
-
- USB-4-all
- The USB-4-all controller board from Sprut ()
-
-
- ftdi
- Display connected to a dual channel FTDI 2232D USB chip
-
-
-
- i2c
- LCD driven by PCF8574(A)/PCA9554(A) connected via I2C
-
-
-
- ethlcd
- ethlcd device ()
-
-
-
- raspberrypi
- LCD connected to the GPIO header of a Raspberry Pi
-
-
-
-
-
-
-
-
- If you suspect the table above to be outdated, you might want to have a look at
- server/drivers/hd44780-drivers.h in LCDproc's
- source directory which contains the actual translation code.
-
-
-
diff --git a/server/drivers/Makefile.am b/server/drivers/Makefile.am
index 6a982cf..20c9db7 100644
--- a/server/drivers/Makefile.am
+++ b/server/drivers/Makefile.am
@@ -95,7 +95,7 @@ EXTRA_glcd_SOURCES = glcd-t6963.c t6963_low.c t6963_low.h glcd-png.c glcd-serdis
glcdlib_SOURCES = lcd.h lcd_lib.h glcdlib.h glcdlib.c report.h
glk_SOURCES = lcd.h glk.c glk.h glkproto.c glkproto.h report.h
hd44780_SOURCES = lcd.h lcd_lib.h hd44780.h hd44780.c hd44780-drivers.h hd44780-low.h hd44780-charmap.h report.h adv_bignum.h
-EXTRA_hd44780_SOURCES = hd44780-4bit.c hd44780-4bit.h hd44780-ext8bit.c hd44780-ext8bit.h lcd_sem.c lcd_sem.h hd44780-serialLpt.c hd44780-serialLpt.h hd44780-serial.c hd44780-serial.h hd44780-winamp.c hd44780-winamp.h hd44780-bwct-usb.c hd44780-bwct-usb.h hd44780-lcd2usb.c hd44780-lcd2usb.h hd44780-usbtiny.c hd44780-usbtiny.h hd44780-lis2.c hd44780-lis2.h hd44780-i2c.c hd44780-i2c.h hd44780-ftdi.c hd44780-ftdi.h hd44780-ethlcd.c hd44780-ethlcd.h hd44780-uss720.c hd44780-uss720.h hd44780-usblcd.c hd44780-usblcd.h hd44780-usb4all.c hd44780-usb4all.h port.h hd44780-rpi.c hd44780-rpi.h lpt-port.h timing.h
+EXTRA_hd44780_SOURCES = port.h lpt-port.h timing.h lcd_sem.c lcd_sem.h hd44780-4bit.c hd44780-4bit.h hd44780-ext8bit.c hd44780-ext8bit.h hd44780-serialLpt.c hd44780-serialLpt.h hd44780-serial.c hd44780-serial.h hd44780-winamp.c hd44780-winamp.h hd44780-bwct-usb.c hd44780-bwct-usb.h hd44780-lcd2usb.c hd44780-lcd2usb.h hd44780-usbtiny.c hd44780-usbtiny.h hd44780-lis2.c hd44780-lis2.h hd44780-i2c.c hd44780-i2c.h hd44780-ftdi.c hd44780-ftdi.h hd44780-ethlcd.c hd44780-ethlcd.h hd44780-uss720.c hd44780-uss720.h hd44780-usblcd.c hd44780-usblcd.h hd44780-usb4all.c hd44780-usb4all.h hd44780-rpi.c hd44780-rpi.h hd44780-piplate.c hd44780-piplate.h
i2500vfd_SOURCES = lcd.h i2500vfd.c i2500vfd.h glcd_font5x8.h report.h
icp_a106_SOURCES = lcd.h lcd_lib.h icp_a106.c icp_a106.h report.h
imon_SOURCES = lcd.h lcd_lib.h hd44780-charmap.h imon.h imon.c report.h adv_bignum.h
diff --git a/server/drivers/hd44780-drivers.h b/server/drivers/hd44780-drivers.h
index 9471dac..b155451 100644
--- a/server/drivers/hd44780-drivers.h
+++ b/server/drivers/hd44780-drivers.h
@@ -31,6 +31,7 @@
#endif
#ifdef HAVE_I2C
# include "hd44780-i2c.h"
+# include "hd44780-piplate.h"
#endif
#ifdef WITH_ETHLCD
# include "hd44780-ethlcd.h"
@@ -80,6 +81,7 @@ static const ConnectionMapping connectionMapping[] = {
/* I2C connection types */
#ifdef HAVE_I2C
{ "i2c", HD44780_CT_I2C, IF_TYPE_I2C, hd_init_i2c },
+ { "piplate", HD44780_CT_PIPLATE, IF_TYPE_I2C, hd_init_i2c_piplate },
#endif
/* TCP socket connection types */
#ifdef WITH_ETHLCD
diff --git a/server/drivers/hd44780-low.h b/server/drivers/hd44780-low.h
index 7c6bb22..4914dca 100644
--- a/server/drivers/hd44780-low.h
+++ b/server/drivers/hd44780-low.h
@@ -54,6 +54,7 @@
#define HD44780_CT_USBTINY 20
#define HD44780_CT_USB4ALL 21
#define HD44780_CT_RASPBERRYPI 22
+#define HD44780_CT_PIPLATE 23
/**@}*/
/** \name Symbolic names for interface types
diff --git a/server/drivers/hd44780-piplate.c b/server/drivers/hd44780-piplate.c
new file mode 100644
index 0000000..ab4f373
--- /dev/null
+++ b/server/drivers/hd44780-piplate.c
@@ -0,0 +1,373 @@
+/** \file server/drivers/hd44780-piplate.c
+ *
+ * \c I2C (via MCP23017) connection type of \c hd44780 driver for Hitachi
+ * HD44780 based LCD displays connected to the MCP23017 I2C I/O expander
+ * (Adafruit Pi Plate, see http://www.adafruit.com/products/1109).
+ *
+ * The LCD is operated in its 4 bit-mode to be connected to the 8 bit-port
+ * of a single MCP23017 that is accessed by the server via the I2C bus.
+ */
+
+/*-
+ * Copyright (c) 2013 Jonathan Brogdon
+ *
+ * This file is released under the GNU General Public License. Refer to the
+ * COPYING file distributed with this package.
+ *
+ * Based mostly on the hd44780-i2c module, see there for a complete history.
+ */
+
+/*-
+ * The connections are:
+ * MCP23017 LCD
+ * GPA7 Green LCD backlight
+ * GPA6 Red LCD backlight
+ * GPA4 Left key
+ * GPA3 Up key
+ * GPA2 Down key
+ * GPA1 Right key
+ * GPA0 Select key
+ * GPB7 RS (4)
+ * GPB6 RW (5)
+ * GPB5 EN (6)
+ * GPB4 D7 (14)
+ * GPB3 D6 (13)
+ * GPB2 D5 (12)
+ * GPB1 D4 (11)
+ * GPB0 Blue LCD backlight
+ *
+ * Configuration:
+ * device=/dev/i2c-1 # the device file of the i2c bus
+ * port=0x20 # the i2c address of the i2c port expander
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "hd44780-piplate.h"
+#include "hd44780-low.h"
+#include "report.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef HAVE_DEV_IICBUS_IIC_H
+# include
+# include
+#else /* HAVE_LINUX_I2C_DEV_H */
+# include
+#endif
+
+#define DEFAULT_DEVICE "/dev/i2c-1"
+
+void i2c_piplate_HD44780_senddata(PrivateData *p,
+ unsigned char displayID, unsigned char flags, unsigned char ch);
+void i2c_piplate_HD44780_backlight(PrivateData *p, unsigned char state);
+unsigned char i2c_piplate_HD44780_scankeypad(PrivateData *p);
+void i2c_piplate_HD44780_close(PrivateData *p);
+
+/* MCP23017 registers */
+#define MCP23017_IODIRA 0x00
+#define MCP23017_IODIRB 0x01
+#define MCP23017_GPPUA 0x0C
+#define MCP23017_GPPUB 0x0D
+#define MCP23017_GPIOA 0x12
+#define MCP23017_GPIOB 0x13
+
+/* GPIOA BITS */
+#define G_BIT (1 << 7)
+#define R_BIT (1 << 6)
+#define L_KEY_BIT (1 << 4)
+#define U_KEY_BIT (1 << 3)
+#define D_KEY_BIT (1 << 2)
+#define R_KEY_BIT (1 << 1)
+#define S_KEY_BIT (1 << 0)
+
+/* GPIOB BITS */
+#define RS_BIT (1 << 7)
+#define RW_BIT (1 << 6)
+#define EN_BIT (1 << 5)
+#define D0_BIT (1 << 4)
+#define D1_BIT (1 << 3)
+#define D2_BIT (1 << 2)
+#define D3_BIT (1 << 1)
+#define B_BIT (1 << 0)
+
+/* Reverses the bits in a 4 bit word */
+#define SWIZZLE_4BITS(x) ((((x) & 0x01) << 3) | (((x) & 0x02) << 1) | (((x) & 0x04) >> 1) | (((x) & 0x08) >> 3))
+
+/* Swizzle and offset bits correctly for the PiPlate wiring */
+#define DATA_BIT_START_OFFSET 1
+#define MAP_TO_DATA_PINS(x) (SWIZZLE_4BITS(x) << DATA_BIT_START_OFFSET)
+
+#define I2C_ADDR_MASK 0x7f
+
+/**
+ * Read one of the MCP23017 registers
+ * \param p Pointer to driver private data.
+ * \param reg Address of the register to read.
+ * \param val Pointer to the read buffer.
+ * \retval 0 Success.
+ * \retval -1 Error.
+ */
+static int
+i2c_read_reg(PrivateData *p, unsigned char reg, unsigned char *val)
+{
+ /* Set the address to be read */
+ if (write(p->fd, ®, 1) != 1) {
+ return -1;
+ }
+
+ /* Read the value */
+ if (read(p->fd, val, 1) != 1) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * Write one of the MCP23017 registers
+ * \param p Pointer to driver private data.
+ * \param reg Address of the register to write.
+ * \param val Value to be written.
+ * \retval 0 Success.
+ * \retval -1 Error.
+ */
+static int
+i2c_write_reg(PrivateData *p, unsigned char reg, unsigned char val)
+{
+ unsigned char buf[2];
+
+ buf[0] = reg;
+ buf[1] = val;
+ if (write(p->fd, buf, sizeof(buf)) != sizeof(buf)) {
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * Initialize the driver.
+ * \param drvthis Pointer to driver structure.
+ * \retval 0 Success.
+ * \retval -1 Error.
+ */
+int
+hd_init_i2c_piplate(Driver *drvthis)
+{
+ PrivateData *p = (PrivateData *) drvthis->private_data;
+ HD44780_functions *hd44780_functions = p->hd44780_functions;
+ char device[256] = DEFAULT_DEVICE;
+#ifdef HAVE_DEV_IICBUS_IIC_H
+ struct iiccmd cmd;
+ bzero(&cmd, sizeof(cmd));
+#endif
+
+ /* Get serial device to use */
+ strncpy(device, drvthis->config_get_string(drvthis->name, "Device", 0, DEFAULT_DEVICE), sizeof(device));
+ device[sizeof(device) - 1] = '\0';
+ report(RPT_INFO, "HD44780: piplate: Using device '%s' and address 0x%02X for a MCP23017",
+ device, p->port & I2C_ADDR_MASK);
+
+ /* Open the I2C device */
+ p->fd = open(device, O_RDWR);
+ if (p->fd < 0) {
+ report(RPT_ERR, "HD44780: piplate: open i2c device '%s' failed: %s",
+ device, strerror(errno));
+ return -1;
+ }
+
+ /* Set I2C address */
+#ifdef HAVE_DEV_IICBUS_IIC_H
+ cmd.slave = (p->port & I2C_ADDR_MASK) << 1;
+ cmd.last = 0;
+ cmd.count = 0;
+ if (ioctl(p->fd, I2CRSTCARD, &cmd) < 0) {
+ report(RPT_ERR, "HD44780: piplate: reset bus failed: %s", strerror(errno));
+ return -1;
+ }
+ if (ioctl(p->fd, I2CSTART, &cmd) < 0) {
+ report(RPT_ERR, "HD44780: piplate: set address to 0x%02X: %s",
+ p->port & I2C_ADDR_MASK, strerror(errno));
+ return -1;
+ }
+#else /* HAVE_LINUX_I2C_DEV_H */
+ if (ioctl(p->fd, I2C_SLAVE, p->port & I2C_ADDR_MASK) < 0) {
+ report(RPT_ERR, "HD44780: piplate: set address to 0x%02X: %s",
+ p->port & I2C_ADDR_MASK, strerror(errno));
+ return -1;
+ }
+#endif
+
+ /* IODIRA - keys as input, all other as output */
+ i2c_write_reg(p, MCP23017_IODIRA,
+ (unsigned char) (L_KEY_BIT | U_KEY_BIT | D_KEY_BIT | R_KEY_BIT | S_KEY_BIT) & ~(G_BIT | R_BIT));
+
+ /* IODIRB - LCD control/data bus signals as outputs */
+ i2c_write_reg(p, MCP23017_IODIRB,
+ (unsigned char) ~(RS_BIT | RW_BIT | EN_BIT | D0_BIT | D1_BIT | D2_BIT | D3_BIT | B_BIT));
+
+ /* GPPUA - Pullups for key switch inputs */
+ i2c_write_reg(p, MCP23017_GPPUA,
+ (unsigned char) (L_KEY_BIT | U_KEY_BIT | D_KEY_BIT | R_KEY_BIT | S_KEY_BIT) & ~(G_BIT | R_BIT));
+
+ /* GPPUB - Pullups disabled */
+ i2c_write_reg(p, MCP23017_GPPUB, (unsigned char) 0x00);
+
+ /* Set driver functions */
+ hd44780_functions->senddata = i2c_piplate_HD44780_senddata;
+ hd44780_functions->backlight = i2c_piplate_HD44780_backlight;
+ hd44780_functions->scankeypad = i2c_piplate_HD44780_scankeypad;
+ hd44780_functions->close = i2c_piplate_HD44780_close;
+
+ /* Initialize the LCD */
+ hd44780_functions->senddata(p, 0, RS_INSTR, 0x33);
+ hd44780_functions->uPause(p, 1);
+ hd44780_functions->senddata(p, 0, RS_INSTR, 0x32);
+ hd44780_functions->uPause(p, 1);
+ common_init(p, IF_4BIT);
+
+ report(RPT_INFO, "HD44780: piplate: initialized!");
+
+ return 0;
+}
+
+/**
+ * Close the device.
+ * \param p Pointer to driver's private data structure.
+ */
+void
+i2c_piplate_HD44780_close(PrivateData *p)
+{
+ if (p->fd >= 0) {
+ close(p->fd);
+ }
+}
+
+/**
+ * Send data or commands to the display.
+ * \param p Pointer to driver's private data structure.
+ * \param displayID ID of the display (or 0 for all) to send data to.
+ * \param flags Defines whether to end a command or data.
+ * \param ch The value to send.
+ */
+void
+i2c_piplate_HD44780_senddata(PrivateData *p,
+ unsigned char displayID, unsigned char flags, unsigned char ch)
+{
+ unsigned char nibble[2];
+ unsigned char write_val = 0;
+ int nibble_idx = 0;
+
+ /* Split the val byte into nibbles */
+ nibble[0] = (ch >> 4);
+ nibble[1] = (ch & 0x0f);
+
+ for (nibble_idx = 0; nibble_idx < 2; nibble_idx++) {
+ /* Adjust for 4-bit data pins */
+ write_val = MAP_TO_DATA_PINS(nibble[nibble_idx]);
+
+ /* Set the RS bit */
+ if (flags == RS_INSTR)
+ write_val &= ~RS_BIT;
+ else
+ write_val |= RS_BIT;
+
+ /* Set the blue backlight bit if backlight is on */
+ if (p->backlightstate == BACKLIGHT_OFF)
+ write_val |= B_BIT;
+
+ /* Set enable bit */
+ i2c_write_reg(p, MCP23017_GPIOB, write_val | EN_BIT);
+
+ p->hd44780_functions->uPause(p, 1);
+
+ /* Clear enable bit */
+ i2c_write_reg(p, MCP23017_GPIOB, write_val & ~EN_BIT);
+
+ } /* for each nibble */
+
+ p->hd44780_functions->uPause(p, 1);
+}
+
+/**
+ * Turn display backlight on or off. For the Pi Plate this means a read /
+ * modify / write cycle is required, as the bits are shared with other signals
+ * on the same byte.
+ *
+ * \param p Pointer to driver's private data structure.
+ * \param state New backlight status.
+ */
+void
+i2c_piplate_HD44780_backlight(PrivateData *p, unsigned char state)
+{
+ unsigned char gpioa = 0;
+ unsigned char gpiob = 0;
+
+ /* Read the RG bits */
+ if (i2c_read_reg(p, MCP23017_GPIOA, &gpioa) != 0) {
+ return;
+ }
+
+ /* Read the B bit */
+ if (i2c_read_reg(p, MCP23017_GPIOB, &gpiob) != 0) {
+ return;
+ }
+
+ /* Set or clear the RGB bits. Backlight is ON if the bits are CLEAR */
+ if (state == BACKLIGHT_ON) {
+ gpioa &= ~(R_BIT | G_BIT);
+ gpiob &= ~(B_BIT);
+ }
+ else {
+ gpioa |= (R_BIT | G_BIT);
+ gpiob |= (B_BIT);
+ }
+
+ /* Write the RGB bits */
+ i2c_write_reg(p, MCP23017_GPIOA, gpioa);
+ i2c_write_reg(p, MCP23017_GPIOB, gpiob);
+}
+
+/**
+ * Scan the LCD keys
+ * \param p Pointer to driver's private data structure.
+ * \retval key Key number
+ */
+unsigned char
+i2c_piplate_HD44780_scankeypad(PrivateData *p)
+{
+ unsigned char gpioa = 0;
+
+ /* Read the key bits */
+ if (i2c_read_reg(p, MCP23017_GPIOA, &gpioa) != 0)
+ return 0;
+
+ /* Select key */
+ if ((gpioa & S_KEY_BIT) == 0)
+ return 1;
+
+ /* Up key */
+ if ((gpioa & U_KEY_BIT) == 0)
+ return 2;
+
+ /* Down key */
+ if ((gpioa & D_KEY_BIT) == 0)
+ return 3;
+
+ /* Left key */
+ if ((gpioa & L_KEY_BIT) == 0)
+ return 4;
+
+ /* Right key */
+ if ((gpioa & R_KEY_BIT) == 0)
+ return 5;
+
+ return 0;
+}
diff --git a/server/drivers/hd44780-piplate.h b/server/drivers/hd44780-piplate.h
new file mode 100644
index 0000000..3d41c33
--- /dev/null
+++ b/server/drivers/hd44780-piplate.h
@@ -0,0 +1,9 @@
+#ifndef HD_PIPLATE_H
+#define HD_PIPLATE_H
+
+#include "lcd.h" /* for Driver */
+
+/* initialise this particular driver */
+int hd_init_i2c_piplate(Driver *drvthis);
+
+#endif