[Lcdproc] [patch] hd44780 FTDI USB support
Thomas Jarosch
thomas.jarosch@intra2net.com
Wed Oct 31 17:59:01 2007
--Boundary-00=_BJMKH3C72dBYa1f
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Hello together,
attached patch adds generic hd44780 FTDI USB support in 8 bit mode
using a dual channel FT2232C/D FTDI chip. Please have a look.
Documentation will be written once the code is ok. The patch needs
the configure-cleanup-v3 and report() patch I sent earlier.
Cheers,
Thomas
--Boundary-00=_BJMKH3C72dBYa1f
Content-Type: text/x-diff;
charset="us-ascii";
name="lcdproc-hd44780-ftdi.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="lcdproc-hd44780-ftdi.patch"
diff -u -r -p --new-file lcdproc-CVS-current-20071031/acinclude.m4 lcdproc.ftdi/acinclude.m4
--- lcdproc-CVS-current-20071031/acinclude.m4 2007-10-31 18:30:29.000000000 +0100
+++ lcdproc.ftdi/acinclude.m4 2007-10-31 18:17:23.000000000 +0100
@@ -192,6 +192,9 @@ dnl else
if test "$enable_libusb" = yes ; then
HD44780_DRIVERS="$HD44780_DRIVERS hd44780-hd44780-bwct-usb.o hd44780-hd44780-lcd2usb.o"
fi
+ if test "$enable_libftdi" = yes ; then
+ HD44780_DRIVERS="$HD44780_DRIVERS hd44780-ftdi.o"
+ fi
AC_CHECK_HEADER(linux/i2c-dev.h,
HD44780_DRIVERS="$HD44780_DRIVERS hd44780-i2c.o"
AC_DEFINE(HAVE_I2C,[1],[Define to 1 if you have the i2c headers])
diff -u -r -p --new-file lcdproc-CVS-current-20071031/server/drivers/hd44780-drivers.h lcdproc.ftdi/server/drivers/hd44780-drivers.h
--- lcdproc-CVS-current-20071031/server/drivers/hd44780-drivers.h 2007-10-14 14:02:53.000000000 +0200
+++ lcdproc.ftdi/server/drivers/hd44780-drivers.h 2007-10-31 18:12:00.000000000 +0100
@@ -23,6 +23,9 @@
# include "hd44780-bwct-usb.h"
# include "hd44780-lcd2usb.h"
#endif
+#ifdef HAVE_LIBFTDI
+# include "hd44780-ftdi.h"
+#endif
#ifdef HAVE_I2C
# include "hd44780-i2c.h"
#endif
@@ -55,6 +58,9 @@ static const ConnectionMapping connectio
{ "bwctusb", HD44780_CT_BWCTUSB, IF_TYPE_USB, hd_init_bwct_usb },
{ "lcd2usb", HD44780_CT_I2C, IF_TYPE_USB, hd_init_lcd2usb },
#endif
+#ifdef HAVE_LIBFTDI
+ { "ftdi", HD44780_CT_FTDI, IF_TYPE_USB, hd_init_ftdi },
+#endif
#ifdef HAVE_I2C
{ "i2c", HD44780_CT_I2C, IF_TYPE_I2C, hd_init_i2c },
#endif
diff -u -r -p --new-file lcdproc-CVS-current-20071031/server/drivers/hd44780-ftdi.c lcdproc.ftdi/server/drivers/hd44780-ftdi.c
--- lcdproc-CVS-current-20071031/server/drivers/hd44780-ftdi.c 1970-01-01 01:00:00.000000000 +0100
+++ lcdproc.ftdi/server/drivers/hd44780-ftdi.c 2007-10-31 17:35:55.000000000 +0100
@@ -0,0 +1,158 @@
+/*
+ * FTDI/USB driver module for Hitachi HD44780 based LCD displays
+ * connected to a FT2232C/D chip in 8 bit mode.
+ *
+ * Copyright (c) 2007, Intra2net AG <opensource@intra2net.com>
+ *
+ * This file is released under the GNU General Public License. Refer to the
+ * COPYING file distributed with this package.
+ *
+ */
+
+#include "hd44780-ftdi.h"
+
+#include "report.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <usb.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#include <errno.h>
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+// initialize the driver
+int
+hd_init_ftdi(Driver *drvthis)
+{
+ int vendor_id, product_id;
+ int f;
+
+ PrivateData *p = (PrivateData*) drvthis->private_data;
+
+ p->hd44780_functions->senddata = ftdi_HD44780_senddata;
+ p->hd44780_functions->backlight = ftdi_HD44780_backlight;
+ p->hd44780_functions->scankeypad = ftdi_HD44780_scankeypad;
+ p->hd44780_functions->close = ftdi_HD44780_close;
+
+ // Load config
+ vendor_id = drvthis->config_get_int(drvthis->name, "vendor_id", 0, 0x0403);
+ product_id = drvthis->config_get_int(drvthis->name, "product_id", 0, 0x6001);
+
+ p->ftdi_line_RS = drvthis->config_get_int(drvthis->name, "ftdi_line_RS", 0, 0x01);
+ p->ftdi_line_RW = drvthis->config_get_int(drvthis->name, "ftdi_line_RW", 0, 0x02);
+ p->ftdi_line_E = drvthis->config_get_int(drvthis->name, "ftdi_line_E", 0, 0x04);
+ p->ftdi_line_backlight = drvthis->config_get_int(drvthis->name, "ftdi_line_backlight", 0, 0x08);
+
+ // Init 1. channel: data
+ ftdi_init(&p->ftdic);
+ ftdi_set_interface(&p->ftdic, INTERFACE_A);
+ f = ftdi_usb_open(&p->ftdic, vendor_id, product_id);
+ if(f < 0 && f != -5) {
+ report(RPT_ERR, "unable to open ftdi device: %d (%s)", f, ftdi_get_error_string(&p->ftdic));
+ return -1;
+ }
+ debug(RPT_DEBUG, "ftdi open succeeded(channel 1): %d", f);
+
+ debug(RPT_DEBUG, "enabling bitbang mode(channel 1)\n");
+ ftdi_enable_bitbang(&p->ftdic, 0xFF);
+
+ // Init 2. channel: control
+ ftdi_init(&p->ftdic2);
+ ftdi_set_interface(&p->ftdic2, INTERFACE_B);
+ f = ftdi_usb_open(&p->ftdic2, vendor_id, product_id);
+ if(f < 0 && f != -5) {
+ report(RPT_ERR, "unable to open second ftdi device: %d (%s)", f, ftdi_get_error_string(&p->ftdic2));
+ return -2;
+ }
+ debug(RPT_DEBUG, "ftdi open succeeded(channel 2): %d", f);
+
+ debug(RPT_DEBUG, "enabling bitbang mode (channel 2)");
+ ftdi_enable_bitbang(&p->ftdic2, 0xFF);
+
+ // FTDI bug: Sometimes first write gets lost on kernel 2.6, needs investigation.
+ ftdi_HD44780_senddata (p, 0, RS_INSTR, FUNCSET | IF_8BIT);
+ usleep (4100);
+
+ common_init(p, IF_8BIT);
+
+ return 0;
+}
+
+// ftdi_HD44780_senddata
+void
+ftdi_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch)
+{
+ // Output data on first channel
+ int f = ftdi_write_data(&p->ftdic, &ch, 1);
+ if (f < 0) {
+ p->hd44780_functions->drv_report(RPT_ERR, "failed to write: %d (%s). Exiting", f, ftdi_get_error_string(&p->ftdic));
+ exit (-1);
+ }
+
+ // Setup RS and R/W and E
+ ch = p->ftdi_line_E | p->backlight_bit;
+ if (flags == RS_DATA) {
+ ch |= p->ftdi_line_RS;
+ }
+ f = ftdi_write_data(&p->ftdic2, &ch, 1);
+ if (f < 0) {
+ p->hd44780_functions->drv_report(RPT_ERR, "failed to write: %d (%s). Exiting", f, ftdi_get_error_string(&p->ftdic2));
+ exit(-1);
+ }
+
+ // Disable E
+ ch = 0x00 | p->backlight_bit;
+ if (flags == RS_DATA) {
+ ch |= p->ftdi_line_RS;
+ }
+ f = ftdi_write_data(&p->ftdic2, &ch, 1);
+ if (f < 0) {
+ p->hd44780_functions->drv_report(RPT_ERR, "failed to write: %d (%s). Exiting", f, ftdi_get_error_string(&p->ftdic2));
+ exit(-1);
+ }
+}
+
+
+void
+ftdi_HD44780_backlight(PrivateData *p, unsigned char state)
+{
+ int f;
+
+ p->backlight_bit = state ? p->ftdi_line_backlight : 0;
+
+ f = ftdi_write_data(&p->ftdic2, &state, 1);
+ if (f < 0) {
+ p->hd44780_functions->drv_report(RPT_ERR, "failed to write: %d (%s). Exiting", f, ftdi_get_error_string(&p->ftdic2));
+ exit(-1);
+ }
+}
+
+
+unsigned char
+ftdi_HD44780_scankeypad(PrivateData *p)
+{
+ return 0;
+}
+
+
+void
+ftdi_HD44780_close(PrivateData *p)
+{
+ ftdi_disable_bitbang(&p->ftdic);
+ ftdi_usb_close(&p->ftdic);
+ ftdi_deinit(&p->ftdic);
+
+ ftdi_disable_bitbang(&p->ftdic2);
+ ftdi_usb_close(&p->ftdic2);
+ ftdi_deinit(&p->ftdic2);
+}
+
+/* EOF */
diff -u -r -p --new-file lcdproc-CVS-current-20071031/server/drivers/hd44780-ftdi.h lcdproc.ftdi/server/drivers/hd44780-ftdi.h
--- lcdproc-CVS-current-20071031/server/drivers/hd44780-ftdi.h 1970-01-01 01:00:00.000000000 +0100
+++ lcdproc.ftdi/server/drivers/hd44780-ftdi.h 2007-10-30 11:45:53.000000000 +0100
@@ -0,0 +1,15 @@
+#ifndef HD_FTDI_H
+#define HD_FTDI_H
+
+#include "lcd.h" /* for Driver */
+#include "hd44780-low.h"
+
+// initialise this particular driver
+int hd_init_ftdi(Driver *drvthis);
+
+void ftdi_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch);
+void ftdi_HD44780_backlight(PrivateData *p, unsigned char state);
+unsigned char ftdi_HD44780_scankeypad(PrivateData *p);
+void ftdi_HD44780_close(PrivateData *p);
+
+#endif
diff -u -r -p --new-file lcdproc-CVS-current-20071031/server/drivers/hd44780-low.h lcdproc.ftdi/server/drivers/hd44780-low.h
--- lcdproc-CVS-current-20071031/server/drivers/hd44780-low.h 2007-10-31 18:30:33.000000000 +0100
+++ lcdproc.ftdi/server/drivers/hd44780-low.h 2007-10-31 18:27:47.000000000 +0100
@@ -21,6 +21,9 @@
# endif
# endif
+#ifdef HAVE_LIBFTDI
+# include <ftdi.h>
+#endif
// symbolic names for connection types
#define HD44780_CT_UNKNOWN 0
@@ -38,7 +41,8 @@
#define HD44780_CT_MPLAY 12
#define HD44780_CT_BWCTUSB 13
#define HD44780_CT_LCDUSB 14
-#define HD44780_CT_I2C 15
+#define HD44780_CT_FTDI 15
+#define HD44780_CT_I2C 16
// symbolic names for interface types
#define IF_TYPE_UNKNOWN 0
@@ -163,6 +167,15 @@ typedef struct driver_private_data {
int contrast; // Contrast setting (range 0 - 1000)
int brightness; // Brightness when backlight is "on" (range 0 - 1000)
int offbrightness; // Brightness when backlight is "off" (range 0 - 1000)
+
+#ifdef HAVE_LIBFTDI
+ struct ftdi_context ftdic, ftdic2;
+
+ int ftdi_line_RS;
+ int ftdi_line_RW;
+ int ftdi_line_E;
+ int ftdi_line_backlight;
+#endif
} PrivateData;
diff -u -r -p --new-file lcdproc-CVS-current-20071031/server/drivers/Makefile.am lcdproc.ftdi/server/drivers/Makefile.am
--- lcdproc-CVS-current-20071031/server/drivers/Makefile.am 2007-10-31 18:30:29.000000000 +0100
+++ lcdproc.ftdi/server/drivers/Makefile.am 2007-10-31 18:16:38.000000000 +0100
@@ -23,7 +23,7 @@ EXTRA_PROGRAMS = bayrad CFontz CFontz633
noinst_LIBRARIES = libLCD.a libbignum.a
IOWarrior_CFLAGS = @LIBUSB_CFLAGS@ $(AM_CFLAGS)
-hd44780_CFLAGS = @LIBUSB_CFLAGS@ $(AM_CFLAGS)
+hd44780_CFLAGS = @LIBUSB_CFLAGS@ @LIBFTDI_CFLAGS@ $(AM_CFLAGS)
g15_CFLAGS = @LIBUSB_CFLAGS@ $(AM_CFLAGS)
picolcd_CFLAGS = @LIBUSB_CFLAGS@ $(AM_CFLAGS)
shuttleVFD_CFLAGS = @LIBUSB_CFLAGS@ $(AM_CFLAGS)
@@ -35,7 +35,7 @@ curses_LDADD = @LIBCURSES@
CwLnx_LDADD = libLCD.a libbignum.a
g15_LDADD = libLCD.a @LIBG15@
glcdlib_LDADD = libLCD.a @LIBGLCD@
-hd44780_LDADD = libLCD.a @HD44780_DRIVERS@ @LIBUSB_LIBS@ libbignum.a
+hd44780_LDADD = libLCD.a @HD44780_DRIVERS@ @LIBUSB_LIBS@ @LIBFTDI_LIBS@ libbignum.a
hd44780_DEPENDENCIES = @HD44780_DRIVERS@
icp_a106_LDADD = libLCD.a
imon_LDADD = libLCD.a
@@ -75,7 +75,7 @@ g15_SOURCES = lcd.h lcd_lib.h g15.
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-lis2.c hd44780-lis2.h hd44780-i2c.c hd44780-i2c.h port.h lpt-port.h timing.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-lis2.c hd44780-lis2.h hd44780-i2c.c hd44780-i2c.h hd44780-ftdi.c hd44780-ftdi.h port.h lpt-port.h timing.h
icp_a106_SOURCES = lcd.h lcd_lib.h icp_a106.c icp_a106.h report.h
imon_SOURCES = lcd.h lcd_lib.h imon.h imon.c report.h
--Boundary-00=_BJMKH3C72dBYa1f--