From 48393215691157077cc985bbf76a04b62d949333 Mon Sep 17 00:00:00 2001 From: marschap Date: Sat, 31 Mar 2007 12:43:27 +0000 Subject: [PATCH] new ConnectionType lcd2usb in hd44780 driver --- CREDITS | 1 + ChangeLog | 1 + LCDd.conf | 2 +- acinclude.m4 | 2 +- docs/LCDd.8.in | 3 + docs/lcdproc-user/drivers/hd44780.docbook | 64 +++++++-- server/drivers/Makefile.am | 6 +- server/drivers/hd44780-bwct-usb.c | 34 +++-- server/drivers/hd44780-bwct-usb.h | 13 +- server/drivers/hd44780-drivers.h | 2 + server/drivers/hd44780-lcd2usb.c | 160 ++++++++++++++++++++++ server/drivers/hd44780-lcd2usb.h | 46 +++++++ 12 files changed, 301 insertions(+), 33 deletions(-) create mode 100644 server/drivers/hd44780-lcd2usb.c create mode 100644 server/drivers/hd44780-lcd2usb.h diff --git a/CREDITS b/CREDITS index 58b9c64..c7efa74 100644 --- a/CREDITS +++ b/CREDITS @@ -163,6 +163,7 @@ Peter Marschall: (current maintainer) - bwctusb connectiontype for the HD44780 driver - extensions to CFontz* drivers: support CF631 & CF635 - various fixes in preparation of 0.5 + - lcd2usb connectiontype for the HD44780 driver Markus Dolze: - various fixes (especially for *BSD) diff --git a/ChangeLog b/ChangeLog index b942dc5..d8dbe57 100644 --- a/ChangeLog +++ b/ChangeLog @@ -36,6 +36,7 @@ v.0.5dev (ongoing development) + ea65 - driver for VFD in AOpen XC Cube AV EA65 barebones (Karsten Festag) + picolcd - driver for Mini-box.com USB LCD picoLCD (Gatewood Green) + new ConnectionType pertelian in hd44780 driver (Matteo Pillon) + + new ConnectionType lcd2usb in hd44780 driver v.0.5.1 + config file support in lcdproc client (Andrew Foss) diff --git a/LCDd.conf b/LCDd.conf index 82b48db..13070c6 100644 --- a/LCDd.conf +++ b/LCDd.conf @@ -38,7 +38,7 @@ # The following drivers are supported: # bayrad, CFontz, CFontz633, CFontzPacket, curses, CwLnx, ea65, # EyeboxOne, g15, glcdlib, glk, hd44780, icp_a106, imon, IOWarrior, -# irman, joy, lb216,lcdm001, lcterm, lirc,MD8800, ms6931, mtc_s16209x, +# irman, joy, lb216, lcdm001, lcterm, lirc, MD8800, ms6931, mtc_s16209x, # MtxOrb, NoritakeVFD, picolcd, pyramid, sed1330, sed1520, serialPOS, # serialVFD, sli, stv5730, svga, t6963, text, tyan, ula200, xosd Driver=curses diff --git a/acinclude.m4 b/acinclude.m4 index ff62658..3ff5aa3 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -190,7 +190,7 @@ dnl else HD44780_DRIVERS="$HD44780_DRIVERS hd44780-hd44780-4bit.o hd44780-hd44780-ext8bit.o hd44780-lcd_sem.o hd44780-hd44780-winamp.o hd44780-hd44780-serialLpt.o" fi if test "$enable_libusb" = yes ; then - HD44780_DRIVERS="$HD44780_DRIVERS hd44780-hd44780-bwct-usb.o" + HD44780_DRIVERS="$HD44780_DRIVERS hd44780-hd44780-bwct-usb.o hd44780-hd44780-lcd2usb.o" fi AC_CHECK_HEADER(linux/i2c-dev.h, HD44780_DRIVERS="$HD44780_DRIVERS hd44780-i2c.o" diff --git a/docs/LCDd.8.in b/docs/LCDd.8.in index 89c53d9..470c5ce 100644 --- a/docs/LCDd.8.in +++ b/docs/LCDd.8.in @@ -155,6 +155,9 @@ LIS2 from VLSystem (http://www.vlsys.co.kr), connected to USB .B bwctusb USB-to-HD44780 converter by BWCT (http://www.bwct.de) .TP +.B lcd2usb +Till Harbaum's open source/open hardware LCD2USB (http://www.harbaum.org/till/lcd2usb/) +.TP .B i2c LCD in 4-bit mode driven by PCF8574(A) / PCA9554(A), connected via I2C bus .RE diff --git a/docs/lcdproc-user/drivers/hd44780.docbook b/docs/lcdproc-user/drivers/hd44780.docbook index 491e1de..f16264b 100644 --- a/docs/lcdproc-user/drivers/hd44780.docbook +++ b/docs/lcdproc-user/drivers/hd44780.docbook @@ -799,9 +799,9 @@ such as portato. Further details can be obtained from: -http://metalab.unc.edu/pub/linux/system/status/lcdtime-0.2.tar.gz -http://metalab.unc.edu/pub/linux/system/status/meter-0.2.tar.gz -http://metalab.unc.edu/pub/linux/system/status/portato-1.2.tar.gz + + + @@ -986,7 +986,7 @@ Andrew McMeikan andrewm@engineer.com. The original wiring and driver can be found at: -http://members.xoom.com/andrewmuck + @@ -1249,7 +1249,7 @@ help of the kernel modules ftdi_sio that map the USB port t LCD on Serial panel device "los-panel" -See http://www.xs4all.nl/~mlf/los/ +See for more information on this device. @@ -1277,7 +1277,7 @@ famous Linux-based VDR that allows to connect an LCD to it and supports LCDproc. -See http://www.jepsennet.de/vdr/ +See (German) for more information on VDR-Wakeup. @@ -1293,8 +1293,8 @@ ftdi_sio modules loaded. Display will be available on /dev/ttyUSB0. - See product + See the + product page for more information. @@ -1513,13 +1513,38 @@ specifying which one (of multiple BWCT LCD devices) is wanted using the + +Till Harbaum's "lcd2usb" + + +LCD2USB +is a cheap but powerful do-it-yourself interface to connect HD44780 based displays via USB, +consisting of easily available parts only. +The device supports software adjustable contrast and backlight as well as dual controller displays +(required for 4*27 and 4*40). + + + +It is based upon Atmel AVR Mega8 CPU with a pure software implementation of the USB protocol +for the Atmel AVR microcontroller series. + + + +The whole interface incl. the hardware layout is under a GPL like license. +This means that you can take these schematics and use it as a basis for your own interface +e.g. for a graphic LCD + + + + + I<superscript>2</superscript>C with Port-Expander If you have an I2C port available that is supported by your kernel -(through /dev/i2c*), you can add a I2C port expander there -(PCF8574P in this example). +(through /dev/i2c*), you can add a I2C +port expander there (PCF8574P in this example).
@@ -1676,8 +1701,13 @@ can be done by specifying "--enable-drivers=all" or by serialLpt winamp picanlcd - bwctusb lcdserializer + los-panel + vdr-lcd + vdr-wakeup + pertelian + bwctusb + lcd2usb lis2 i2c @@ -1733,13 +1763,21 @@ can be done by specifying "--enable-drivers=all" or by VDR-Wakeup module "vdr-wakeup" - lis2 - LIS2 from VLSystem () + pertelian + Pertelian X2040 LCD display () bwctusb BWCT USB device "bwctusb" () + + lcd2usb + Tim Harbaum's LCD2USB () + + + lis2 + LIS2 from VLSystem () + i2c LCD driven by PCF8574(A)/PCA9554(A) connected via I2C diff --git a/server/drivers/Makefile.am b/server/drivers/Makefile.am index b2541f0..c6f08f2 100644 --- a/server/drivers/Makefile.am +++ b/server/drivers/Makefile.am @@ -66,12 +66,12 @@ CFontzPacket_SOURCES = lcd.h lcd_lib.h CFontzPacket.c CFontzPacket.h CFontz-char curses_SOURCES = lcd.h curses_drv.h curses_drv.c report.h CwLnx_SOURCES = lcd.h lcd_lib.h CwLnx.c CwLnx.h report.h ea65_SOURCES = lcd.h ea65.h ea65.c report.h -EyeboxOne_SOURCES = lcd.h lcd_lib.h EyeboxOne.c EyeboxOne.h report.h -g15_SOURCES = lcd.h lcd_lib.h g15.h g15-num.c g15.c report.h +EyeboxOne_SOURCES = lcd.h lcd_lib.h EyeboxOne.c EyeboxOne.h report.h +g15_SOURCES = lcd.h lcd_lib.h g15.h g15-num.c g15.c report.h 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-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 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 diff --git a/server/drivers/hd44780-bwct-usb.c b/server/drivers/hd44780-bwct-usb.c index ea4e55e..5557a0e 100644 --- a/server/drivers/hd44780-bwct-usb.c +++ b/server/drivers/hd44780-bwct-usb.c @@ -41,7 +41,7 @@ int hd_init_bwct_usb (Driver *drvthis) { PrivateData *p = (PrivateData*) drvthis->private_data; - struct usb_bus *busses; + struct usb_bus *bus; //char device_manufacturer[LCD_MAX_WIDTH+1] = ""; char device_serial[LCD_MAX_WIDTH+1] = DEFAULT_SERIALNO; @@ -51,6 +51,7 @@ hd_init_bwct_usb (Driver *drvthis) p->hd44780_functions->senddata = bwct_usb_HD44780_senddata; p->hd44780_functions->backlight = bwct_usb_HD44780_backlight; p->hd44780_functions->scankeypad = bwct_usb_HD44780_scankeypad; + p->hd44780_functions->close = bwct_usb_HD44780_close; /* Read config file's contents: serial number and contrast */ @@ -71,17 +72,16 @@ hd_init_bwct_usb (Driver *drvthis) usb_init(); usb_find_busses(); usb_find_devices(); - busses = usb_get_busses(); bwct_usb = NULL; - for (bus = busses; bus; bus = bus->next) { + for (bus = usb_get_busses(); bus != NULL; bus = bus->next) { struct usb_device *dev; - for (dev = bus->devices; dev; dev = dev->next) { + for (dev = bus->devices; dev != NULL; dev = dev->next) { int c; /* Check if this device is a BWCT device */ - if (dev->descriptor.idVendor != 0x03DA) { + if (dev->descriptor.idVendor != BWCT_USB_VENDORID) { continue; } /* Loop through all of the configurations */ @@ -92,10 +92,10 @@ hd_init_bwct_usb (Driver *drvthis) /* Loop through all of the alternate settings */ for (a = 0; a < dev->config[c].interface[bwct_usb_i].num_altsetting; a++) { - /* Check if this interface is a BWCT ulcd */ - if (((dev->config[c].interface[bwct_usb_i].altsetting[a].bInterfaceClass == 0xFf) && + /* Check if this interface is a BWCT lcd */ + if (((dev->config[c].interface[bwct_usb_i].altsetting[a].bInterfaceClass == 0xFF) && (dev->config[c].interface[bwct_usb_i].altsetting[a].bInterfaceSubClass == 0x01)) || - (dev->descriptor.idProduct == 0x0002)) { + (dev->descriptor.idProduct == BWCT_USB_PRODUCTID)) { /* BWCT device found; try to find its description and serial number */ bwct_usb = usb_open(dev); @@ -167,7 +167,7 @@ hd_init_bwct_usb (Driver *drvthis) /* set contrast */ if ((0 <= contrast) && (contrast <= 1000)) { - int res = usb_control_msg(bwct_usb, USB_TYPE_VENDOR, VENDOR_LCD_CONTRAST, + int res = usb_control_msg(bwct_usb, USB_TYPE_VENDOR, BWCT_LCD_SET_CONTRAST, (contrast * 255) / 1000, bwct_usb_i, NULL, 0, 1000); if (res < 0) report(RPT_WARNING, "hd_init_bwct_usb: setting contrast failed"); @@ -183,9 +183,9 @@ hd_init_bwct_usb (Driver *drvthis) void bwct_usb_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch) { -int type = (flags == RS_DATA) ? VENDOR_LCD_DATA : VENDOR_LCD_CMD; +int type = (flags == RS_DATA) ? BWCT_LCD_DATA : BWCT_LCD_CMD; - usb_control_msg(bwct_usb, USB_TYPE_VENDOR, type, ch, bwct_usb_i, NULL, 0, 1000); + usb_control_msg(bwct_usb, USB_TYPE_VENDOR, type, ch, bwct_usb_i, NULL, 0, 1000); } @@ -200,3 +200,15 @@ bwct_usb_HD44780_scankeypad(PrivateData *p) { return 0; } + + +void +bwct_usb_HD44780_close(PrivateData *p) +{ + if (bwct_usb != NULL) { + usb_close(bwct_usb); + bwct_usb = NULL; + } +} + +/* EOF */ diff --git a/server/drivers/hd44780-bwct-usb.h b/server/drivers/hd44780-bwct-usb.h index 5ea4bbc..8ec4f2e 100644 --- a/server/drivers/hd44780-bwct-usb.h +++ b/server/drivers/hd44780-bwct-usb.h @@ -4,10 +4,14 @@ #include "lcd.h" /* for Driver */ #include "hd44780-low.h" -#define VENDOR_LCD_RESET 1 -#define VENDOR_LCD_CMD 2 -#define VENDOR_LCD_DATA 3 -#define VENDOR_LCD_CONTRAST 4 +/* vendor and product id */ +#define BWCT_USB_VENDORID 0x03DA +#define BWCT_USB_PRODUCTID 0x0002 + +#define BWCT_LCD_RESET 1 +#define BWCT_LCD_CMD 2 +#define BWCT_LCD_DATA 3 +#define BWCT_LCD_SET_CONTRAST 4 #define DEFAULT_SERIALNO "" #define DEFAULT_CONTRAST 300 @@ -18,5 +22,6 @@ int hd_init_bwct_usb(Driver *drvthis); void bwct_usb_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch); void bwct_usb_HD44780_backlight(PrivateData *p, unsigned char state); unsigned char bwct_usb_HD44780_scankeypad(PrivateData *p); +void bwct_usb_HD44780_close(PrivateData *p); #endif diff --git a/server/drivers/hd44780-drivers.h b/server/drivers/hd44780-drivers.h index 47044e0..01f9348 100644 --- a/server/drivers/hd44780-drivers.h +++ b/server/drivers/hd44780-drivers.h @@ -19,6 +19,7 @@ #endif #ifdef HAVE_LIBUSB # include "hd44780-bwct-usb.h" +# include "hd44780-lcd2usb.h" #endif #include "hd44780-serial.h" #include "hd44780-lis2.h" @@ -49,6 +50,7 @@ static const ConnectionMapping connectionMapping[] = { {"lis2", hd_init_lis2, "\tnone\n"}, #ifdef HAVE_LIBUSB {"bwctusb", hd_init_bwct_usb, "\tnone\n"}, + {"lcd2usb", hd_init_lcd2usb, "\tnone\n"}, #endif #ifdef HAVE_I2C {"i2c", hd_init_i2c, "\tnone\n"}, diff --git a/server/drivers/hd44780-lcd2usb.c b/server/drivers/hd44780-lcd2usb.c new file mode 100644 index 0000000..6fcfaba --- /dev/null +++ b/server/drivers/hd44780-lcd2usb.c @@ -0,0 +1,160 @@ +/* driver module for Hitachi HD44780 based LCD displays + * connected to using the lcd2usb interface + * (http://www.harbaum.org/till/lcd2usb) + * + * Copyright (C) 2007 Peter Marschall + * + * This file is released under the GNU General Public License. Refer to the + * COPYING file distributed with this package. + */ + +#include "hd44780-lcd2usb.h" + +#include "report.h" + +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + +/* USB device handle & interface index we write to */ +static usb_dev_handle *lcd2usb; + + +// initialize the driver +int +hd_init_lcd2usb (Driver *drvthis) +{ + PrivateData *p = (PrivateData*) drvthis->private_data; + + struct usb_bus *bus; + //char device_manufacturer[LCD_MAX_WIDTH+1] = ""; + int contrast = -1; /* illegal contrast value (to detect errors) */ + int brightness = -1; /* illegal brightness value (to detect errors) */ + + p->hd44780_functions->senddata = lcd2usb_HD44780_senddata; + p->hd44780_functions->backlight = lcd2usb_HD44780_backlight; + p->hd44780_functions->scankeypad = lcd2usb_HD44780_scankeypad; + p->hd44780_functions->close = lcd2usb_HD44780_close; + + /* Read config file's contents: contrast */ + + contrast = drvthis->config_get_int(drvthis->name, "Contrast", 0, DEFAULT_CONTRAST); + brightness = drvthis->config_get_int(drvthis->name, "Brightness", 0, DEFAULT_BRIGHTNESS); + + /* try to find USB device */ +#if 0 + usb_debug = 2; +#endif + + usb_init(); + usb_find_busses(); + usb_find_devices(); + + lcd2usb = NULL; + for (bus = usb_get_busses(); bus != NULL; bus = bus->next) { + struct usb_device *dev; + + for (dev = bus->devices; dev != NULL; dev = dev->next) { + + /* Check if this device is a LCD2USB device */ + if ((dev->descriptor.idVendor == LCD2USB_VENDORID) && + (dev->descriptor.idProduct == LCD2USB_PRODUCTID)) { + + /* LCD2USB device found; try to find its description */ + lcd2usb = usb_open(dev); + if (lcd2usb == NULL) { + report(RPT_WARNING, "hd_init_lcd2usb: unable to open device"); + // return -1; /* it's better to continue */ + } + else { + /* get device information & check for serial number */ + //if (usb_get_string_simple(lcd2usb, dev->descriptor.iManufacturer, + // manufacturer, LCD_MAX_WIDTH) <= 0) + // *manufacturer = '\0'; + //manufacturer[sizeof(manufacturer)-1] = '\0'; + + //if (usb_get_string_simple(lcd2usb, dev->descriptor.iProduct, + // product, LCD_MAX_WIDTH) <= 0) + // *product = '\0'; + //product[sizeof(product)-1] = '\0'; + + //usb_close(lcd2usb); + //lcd2usb = NULL; + } + } + } + } + + if (lcd2usb != NULL) { + debug(RPT_DEBUG, "hd_init_lcd2usb: opening device succeeded"); + + } + else { + report(RPT_ERR, "hd_init_lcd2usb: no (matching) LCD2USB device found"); + return -1; + } + + common_init(p, IF_4BIT); + + /* set contrast */ + if ((0 <= contrast) && (contrast <= 1000)) { + int res = usb_control_msg(lcd2usb, USB_TYPE_VENDOR, LCD2USB_SET_CONTRAST, + (contrast * 255) / 1000, 0, NULL, 0, 1000); + if (res < 0) + report(RPT_WARNING, "hd_init_lcd2usb: setting contrast failed"); + } else { + report(RPT_INFO, "hd_init_lcd2usb: Using default contrast value"); + } + + /* set brightness */ + if ((0 <= brightness) && (brightness <= 1000)) { + int res = usb_control_msg(lcd2usb, USB_TYPE_VENDOR, LCD2USB_SET_BRIGHTNESS, + (brightness * 255) / 1000, 0, NULL, 0, 1000); + if (res < 0) + report(RPT_WARNING, "hd_init_lcd2usb: setting brightness failed"); + } else { + report(RPT_INFO, "hd_init_lcd2usb: Using default brightness value"); + } + + return 0; +} + + +// lcd2usb_HD44780_senddata +void +lcd2usb_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch) +{ +int type = (flags == RS_DATA) ? (LCD2USB_DATA | LCD2USB_CTRL_0) : (LCD2USB_CMD | LCD2USB_CTRL_0); + + usb_control_msg(lcd2usb, USB_TYPE_VENDOR, type, ch, 0, NULL, 0, 1000); +} + + +void +lcd2usb_HD44780_backlight(PrivateData *p, unsigned char state) +{ +} + + +unsigned char +lcd2usb_HD44780_scankeypad(PrivateData *p) +{ + return 0; +} + +void +lcd2usb_HD44780_close(PrivateData *p) +{ + if (lcd2usb != NULL) { + usb_close(lcd2usb); + lcd2usb = NULL; + } +} + +/* EOF */ diff --git a/server/drivers/hd44780-lcd2usb.h b/server/drivers/hd44780-lcd2usb.h new file mode 100644 index 0000000..224a7ef --- /dev/null +++ b/server/drivers/hd44780-lcd2usb.h @@ -0,0 +1,46 @@ +#ifndef HD_LCD2USB_H +#define HD_LCD2USB_H + +#include "lcd.h" /* for Driver */ +#include "hd44780-low.h" + +/* vendor and product id */ +#define LCD2USB_VENDORID 0x0403 +#define LCD2USB_PRODUCTID 0xc630 + +/* target is a bit map for CMD/DATA */ +#define LCD2USB_CTRL_0 (1<<3) +#define LCD2USB_CTRL_1 (1<<4) +#define LCD2USB_CTRL_BOTH (LCD_CTRL_0 | LCD_CTRL_1) + +#define LCD2USB_ECHO (0<<5) +#define LCD2USB_CMD (1<<5) +#define LCD2USB_DATA (2<<5) +#define LCD2USB_SET (3<<5) +#define LCD2USB_GET (4<<5) + +/* target is value to set */ +#define LCD2USB_SET_CONTRAST (LCD2USB_SET | (0<<3)) +#define LCD2USB_SET_BRIGHTNESS (LCD2USB_SET | (1<<3)) +#define LCD2USB_SET_RESERVED0 (LCD2USB_SET | (2<<3)) +#define LCD2USB_SET_RESERVED1 (LCD2USB_SET | (3<<3)) + +/* target is value to get */ +#define LCD2USB_GET_FWVER (LCD2USB_GET | (0<<3)) +#define LCD2USB_GET_KEYS (LCD2USB_GET | (1<<3)) +#define LCD2USB_GET_CTRL (LCD2USB_GET | (2<<3)) +#define LCD2USB_GET_RESERVED1 (LCD2USB_GET | (3<<3)) + +#define DEFAULT_CONTRAST 300 +#define DEFAULT_BRIGHTNESS 600 +#define DEFAULT_OFFBRIGHTNESS 300 + +// initialise this particular driver +int hd_init_lcd2usb(Driver *drvthis); + +void lcd2usb_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch); +void lcd2usb_HD44780_backlight(PrivateData *p, unsigned char state); +unsigned char lcd2usb_HD44780_scankeypad(PrivateData *p); +void lcd2usb_HD44780_close(PrivateData *p); + +#endif