diff --git a/ChangeLog b/ChangeLog
index eff6c40..663159b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -25,6 +25,7 @@ v0.5dev (ongoing development)
* lis driver: Make the last pixel row work (add lastline option parsing)
* hd44780/ftdi: Fix error in setting backlight and add backlight for 4bit mode
+ new driver: sdeclcd for Watchguard FireBox appliances (F. Mertz)
+ + hd44780: Added 'usb4all' connection type (T. Mohaupt)
v0.5.5
+ sed1330 driver: Add support for HG25504 (L. Lagendijk)
diff --git a/LCDd.conf b/LCDd.conf
index e37ac42..fec7b98 100644
--- a/LCDd.conf
+++ b/LCDd.conf
@@ -514,11 +514,17 @@ Speed=0
# You may also need to configure the keypad layout further on in this file.
Keypad=no
-# Set the initial contrast (bwctusb and lcd2usb) [default: 500; legal: 0 - 1000]
-Contrast=0
+# Set the initial contrast (bwctusb, lcd2usb, and usb4all)
+# [default: 800; legal: 0 - 1000]
+#Contrast=0
-# Set brightness of the backlight (lcd2usb only) [default: 0; legal: 0 - 1000]
+# Set brightness of the backlight (lcd2usb and usb4all):
+# Brightness is the brightness while the backlight is set to 'on'.
+# [default: 800; legal: 0 - 1000]
#Brightness=1000
+
+# OffBrightness is the brightness while the backlight is set to 'off'.
+# [default: 300; legal: 0 - 1000]
#OffBrightness=0
# If you have a switchable backlight.
diff --git a/acinclude.m4 b/acinclude.m4
index 1586b9b..ae1b552 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -216,7 +216,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-hd44780-lcd2usb.o hd44780-hd44780-uss720.o hd44780-hd44780-usbtiny.o"
+ HD44780_DRIVERS="$HD44780_DRIVERS hd44780-hd44780-bwct-usb.o hd44780-hd44780-lcd2usb.o hd44780-hd44780-uss720.o hd44780-hd44780-usbtiny.o hd44780-hd44780-usb4all.o"
fi
if test "$enable_libftdi" = yes ; then
HD44780_DRIVERS="$HD44780_DRIVERS hd44780-hd44780-ftdi.o"
diff --git a/docs/LCDd.8.in b/docs/LCDd.8.in
index 4a8a86b..0420be7 100644
--- a/docs/LCDd.8.in
+++ b/docs/LCDd.8.in
@@ -193,6 +193,9 @@ LCD device from Adams IT Services (http://www.usblcd.de/)
.TP
.B usbtiny
Devices based on Dick Streefland's USBtiny firmware
+.TP
+.B usb4all
+Sprut's open source / open hardware USB-4-all (http://www.sprut.de/)
.RE
.TP
.B i2500vfd
diff --git a/docs/lcdproc-user/drivers/hd44780.docbook b/docs/lcdproc-user/drivers/hd44780.docbook
index b89e67f..ff3bf8a 100644
--- a/docs/lcdproc-user/drivers/hd44780.docbook
+++ b/docs/lcdproc-user/drivers/hd44780.docbook
@@ -133,6 +133,12 @@ more important. Here are the USB connection types the HD44780 driver supports:
usblcd:
USBLCD from Adams IT Services ( )
+
+
+ USB-4-all:
+ Display connected to USB-4-all controller ( )
+
+
@@ -2134,12 +2140,13 @@ The default is /dev/lcd .
It does not support a keypad nor backlight switching.
+
-For more information see the
-PIC-an-LCD User Manual
-by Dale Wheat.
+As of 2012 these devices are not sold anymore. Search the Internet Archive for
+a copy of if you need
+the manual.
-
+
@@ -2715,6 +2722,237 @@ lcdproc 0.4.5 to support existing users.
+
+USB-4-all controller
+
+
+The USB-4-all controller board from Sprut ( )
+is a small interface board which allows you to connect different hardware to the USB.
+The subdriver for LCDproc supports dual HD44780 displays and a 4x4 keypad as well as
+software adjustable contrast and brightness (backlight).
+
+
+
+HD44780: USB-4-all - Display connection
+
+
+
+
+
+
+
+ USB-4-all
+ LCD1
+ LCD2
+
+
+ name
+ pin
+ name
+ name
+
+
+
+
+ RB7
+ 28
+ D7
+ D7
+
+
+ RB6
+ 27
+ D6
+ D6
+
+
+ RB5
+ 26
+ D5
+ D5
+
+
+ RB4
+ 25
+ D4
+ D4
+
+
+ RB3
+ 24
+ R/W
+ R/W
+
+
+ RB2
+ 23
+ RS
+ RS
+
+
+ RB0
+ 21
+ EN
+
+
+
+ RC0
+ 11
+
+ EN
+
+
+
+
+
+
+HD44780: USB-4-all - Keypad connection
+
+
+
+
+
+
+ USB-4-all
+ keypad
+
+
+ name
+ pin
+ name
+
+
+
+
+ RA0
+ 2
+ X1
+
+
+ RA1
+ 3
+ X2
+
+
+ RA2
+ 4
+ X3
+
+
+ RA3
+ 5
+ X4
+
+
+ RA4
+ 6
+ Y1
+
+
+ RA5
+ 7
+ Y2
+
+
+ RC6
+ 17
+ Y3
+
+
+ RC7
+ 18
+ Y4
+
+
+
+
+
+
+HD44780: USB-4-all - Brightness and contrast connection
+
+
+
+
+
+
+ USB-4-all
+ Desc
+
+
+ name
+ pin
+
+
+
+
+
+ RC1
+ 12
+ brightness
+
+
+ RC2
+ 13
+ contrast
+
+
+
+
+
+
+
+HD44780: USB-4-all brightness control
+
+ LCD 15 (+ Backlight)
+
+ +---> LCD 16 (- Backlight)
+ |
+ === GND
+]]>
+
+
+
+
+HD44780: USB-4-all contrast control
+
+ LCD 3 (Contrast)
+ |c 680R |
+ ___ b |/ |+
+ RC2 o------|___|------| npn --- 10uF
+ 22k |\ ---
+ |e |
+ | |
+ | |
+ === === GND
+]]>
+
+
+
+
+
+
@@ -2782,6 +3020,7 @@ This can be done by specifying --enable-drivers=all or by inclu
pertelian |
bwctusb |
lcd2usb |
+ usb4all |
lis2 |
mplay |
i2c |
@@ -2853,9 +3092,13 @@ This can be done by specifying --enable-drivers=all or by inclu
lcd2usb
Till Harbaum's LCD2USB ( )
+
+ USB-4-all
+ The USB-4-all controller board from Sprut ( )
+
usbtiny
- Dick Streefland's USBtiny ( )
+ Dick Streefland's USBtiny ( )
lis2
diff --git a/server/drivers/Makefile.am b/server/drivers/Makefile.am
index b1eca3a..7711acc 100644
--- a/server/drivers/Makefile.am
+++ b/server/drivers/Makefile.am
@@ -94,7 +94,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 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-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 lpt-port.h timing.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 53ff3ef..4c58cac 100644
--- a/server/drivers/hd44780-drivers.h
+++ b/server/drivers/hd44780-drivers.h
@@ -24,6 +24,7 @@
# include "hd44780-lcd2usb.h"
# include "hd44780-usbtiny.h"
# include "hd44780-uss720.h"
+# include "hd44780-usb4all.h"
#endif
#ifdef HAVE_LIBFTDI
# include "hd44780-ftdi.h"
@@ -68,6 +69,7 @@ static const ConnectionMapping connectionMapping[] = {
{ "lcd2usb", HD44780_CT_LCD2USB, IF_TYPE_USB, hd_init_lcd2usb },
{ "usbtiny", HD44780_CT_USBTINY, IF_TYPE_USB, hd_init_usbtiny },
{ "uss720", HD44780_CT_USS720, IF_TYPE_USB, hd_init_uss720 },
+ { "usb4all", HD44780_CT_USB4ALL, IF_TYPE_USB, hd_init_usb4all },
#endif
#ifdef HAVE_LIBFTDI
{ "ftdi", HD44780_CT_FTDI, IF_TYPE_USB, hd_init_ftdi },
diff --git a/server/drivers/hd44780-low.h b/server/drivers/hd44780-low.h
index 81bad56..448a1a5 100644
--- a/server/drivers/hd44780-low.h
+++ b/server/drivers/hd44780-low.h
@@ -52,6 +52,7 @@
#define HD44780_CT_USS720 18
#define HD44780_CT_USBLCD 19
#define HD44780_CT_USBTINY 20
+#define HD44780_CT_USB4ALL 21
/**@}*/
/** \name Symbolic names for interface types
@@ -132,6 +133,10 @@ typedef struct hd44780_private_data {
/* libusb-based connection types */
usb_dev_handle *usbHandle; /**< USB device handle */
int usbIndex; /**< USB interface index */
+ int usbMode; /**< USB write mode (bulk or interrupt)*/
+ int usbEpOut; /**< USB Endpoint Out */
+ int usbEpIn; /**< USB Endpoint In */
+ tx_buffer rx_buf; /**< Input buffer */
#endif
#ifdef HAVE_LIBFTDI
diff --git a/server/drivers/hd44780-usb4all.c b/server/drivers/hd44780-usb4all.c
new file mode 100644
index 0000000..aeacedb
--- /dev/null
+++ b/server/drivers/hd44780-usb4all.c
@@ -0,0 +1,474 @@
+/** \file server/drivers/hd44780-usb4all.c
+ * USB-4-all connection type of hd44780 driver for Hitachi HD44780 based
+ * LCD displays connected to an USB-4-all controller.
+ *
+ * USB-4-all is PIC based USB controller, see
+ * http://www.sprut.de/electronic/pic/projekte/usb4all/usb4all.htm
+ *
+ * It supports
+ * - up to two displays with each up to 2x40 or 4x20 lines/characters.
+ * - contrast control (PWM1)
+ * - brightness control (PWM2)
+ * - 4x4 keypad (RA0 - RA3 - X lines, RA4, RA5, RC6, RC7 - Y lines)
+ *
+ * Only the MCD version is supported!
+ */
+
+/*-
+ * Copyright (C) 2012 Thomas Mohaupt
+ * 2010 Roland Wundrig
+ *
+ * Some code parts are adapted from Roland Wundrig linux demo code
+ * (part of usb4all package)
+ *
+ * This file is released under the GNU General Public License version 2.
+ * Refer to the COPYING file distributed with this package.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include
+#include
+#include
+
+#include "hd44780-usb4all.h"
+#include "hd44780-low.h"
+#include "report.h"
+
+/* connection type specific functions to be exposed using pointers in init() */
+void usb4all_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch);
+void usb4all_HD44780_close(PrivateData *p);
+void usb4all_HD44780_backlight(PrivateData *p, unsigned char state);
+void usb4all_HD44780_set_contrast(PrivateData *p, unsigned char value);
+unsigned char usb4all_HD44780_readkeypad(PrivateData *p, unsigned int Ydata);
+
+/**
+ * Send a command with data to usb4all controller and reads the answer.
+ * Even if some inputs should be read a command to do this has to send before.
+ * \param p pointer to private data structure
+ * \param data_out pointer to data send to controller
+ * \param data_in pointer to buffer where read in data is stored
+ * \return number of bytes read in
+ */
+int
+usb4all_data_io(PrivateData *p, tx_buffer * data_out, tx_buffer * data_in)
+{
+ int res;
+
+ if (p->usbMode == MODE_BULK) {
+ res = usb_bulk_write(p->usbHandle,
+ p->usbEpOut,
+ (char *)data_out->buffer,
+ data_out->use_count,
+ TIMEOUT_WRITE);
+ }
+ else {
+ res = usb_interrupt_write(p->usbHandle,
+ p->usbEpOut,
+ (char *)data_out->buffer,
+ data_out->use_count,
+ TIMEOUT_WRITE);
+ }
+
+ if (res < 0) {
+ p->hd44780_functions->drv_report(RPT_WARNING,
+ "usb4all_data_io: unable to send, result = %d ...", res);
+ return -1;
+ }
+
+ /* if a reset command is send the usb4all controller doesn't answer */
+ if (data_out->buffer[0] == USB4ALL_RESET) {
+ return 0;
+ }
+
+ if (res != data_out->use_count) {
+ p->hd44780_functions->drv_report(RPT_WARNING,
+ "usb4all_data_io: Want to send %d bytes but currently only %d bytes was send!?",
+ data_out->use_count, res);
+ return -1;
+ }
+
+ if (p->usbMode == MODE_BULK) {
+ res = usb_bulk_read(p->usbHandle,
+ p->usbEpIn,
+ (char *)data_in->buffer,
+ USB4ALL_RX_MAX,
+ TIMEOUT_READ);
+ }
+ else {
+ res = usb_interrupt_read(p->usbHandle,
+ p->usbEpIn,
+ (char *)data_in->buffer,
+ USB4ALL_RX_MAX,
+ TIMEOUT_READ);
+ }
+
+ return res;
+}
+
+/**
+ * Set the pwm value on the pwm channel
+ * \param p pointer to private date structure
+ * \param pwm_channel the pwm channel
+ * \param value the high-part of each pwm cylce
+ */
+void
+usb4all_set_pwm_value(PrivateData *p, unsigned char pwm_channel, unsigned char value)
+{
+ p->tx_buf.buffer[0] = 0x56 + pwm_channel;
+ p->tx_buf.buffer[1] = 0x02;
+ p->tx_buf.buffer[2] = value;
+ p->tx_buf.buffer[3] = 0x00;
+ p->tx_buf.use_count = 4;
+ usb4all_data_io(p, &p->tx_buf, &p->rx_buf);
+}
+
+/**
+ * Init the usb-4-all controller part for PWM
+ * The PWM outputs can be used to control bightness and contrast
+ * \param p pointer to private date structure
+ * \param pwm_channel channel to initialize (1 or 2)
+ */
+void
+usb4all_init_pwm(PrivateData *p, unsigned char pwm_channel)
+{
+ p->hd44780_functions->drv_report(RPT_INFO,
+ "init usb4all controller for PWM channel %d ", pwm_channel);
+
+ p->tx_buf.buffer[0] = 0x056 + pwm_channel;
+ p->tx_buf.buffer[1] = 0x01;
+ p->tx_buf.buffer[2] = 0x05;
+ p->tx_buf.use_count = 3;
+ usb4all_data_io(p, &p->tx_buf, &p->rx_buf);
+}
+
+/**
+ * Init the usb-4-all controller part for digital I/O (keypad)
+ * \param p pointer to private date structure
+ */
+void
+usb4all_init_keypad(PrivateData *p)
+{
+ p->hd44780_functions->drv_report(RPT_INFO, "init usb4all controller for keypad");
+
+ /* Input lines (X) RA0, RA1, RA2, RA3 */
+ p->tx_buf.buffer[0] = 0x50;
+ p->tx_buf.buffer[1] = 0x04;
+ p->tx_buf.buffer[2] = 0x0F;
+ p->tx_buf.buffer[3] = 0x00;
+ p->tx_buf.buffer[4] = 0x00;
+ p->tx_buf.use_count = 5;
+ usb4all_data_io(p, &p->tx_buf, &p->rx_buf);
+
+ /* Output lines (Y) RA4, RA5, RC6, RC7 */
+ p->tx_buf.buffer[0] = 0x50;
+ p->tx_buf.buffer[1] = 0x05;
+ p->tx_buf.buffer[2] = 0x30;
+ p->tx_buf.buffer[3] = 0x00;
+ p->tx_buf.buffer[4] = 0xC0;
+ p->tx_buf.use_count = 5;
+ usb4all_data_io(p, &p->tx_buf, &p->rx_buf);
+}
+
+/**
+ * Init the usb-4-all controller part for LCD displays
+ * \param p pointer to private date structure
+ * \param displayID display to init
+ * \param rows number of lines
+ * \param cols number of characters
+ */
+void
+usb4all_init_lcd(PrivateData *p, unsigned char displayID, unsigned char rows, unsigned char cols)
+{
+ p->hd44780_functions->drv_report(RPT_INFO,
+ "init usb4all controller for display %d ", displayID);
+
+ p->tx_buf.buffer[0] = 0x054 + displayID;
+ p->tx_buf.buffer[1] = 0x01;
+ p->tx_buf.buffer[2] = rows;
+ p->tx_buf.buffer[3] = cols;
+ p->tx_buf.use_count = 4;
+ usb4all_data_io(p, &p->tx_buf, &p->rx_buf);
+}
+
+/**
+ * Init the usb-4-all controller
+ * \param p pointer to private date structure
+ */
+void
+usb4all_init(PrivateData *p)
+{
+ usb4all_init_lcd(p, 1, p->dispVOffset[0], p->width);
+ if (p->numDisplays == 2) {
+ usb4all_init_lcd(p, 2, p->dispVOffset[1], p->width);
+ }
+
+ usb4all_init_pwm(p, USB4ALL_PWM_CONTRAST);
+ if (p->have_backlight) {
+ usb4all_init_pwm(p, USB4ALL_PWM_BRIGHTNESS);
+ }
+
+ if (p->have_keypad) {
+ usb4all_init_keypad(p);
+ }
+}
+
+/**
+ * Identifies the usb transfer mode and endpoint addresses.
+ * Values are stored in the corresponding private data
+ * fields (usbMode, usbEpIn and usbEpOut).
+ * \param p Pointer to PrivateData structure
+ * \param iface Pointer to USB interface descriptor
+ */
+void
+usb4all_determine_usb_params(PrivateData *p, struct usb_interface_descriptor *iface)
+{
+ p->usbMode = -1;
+
+ if ((iface->endpoint[0].bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_INTERRUPT &&
+ (iface->endpoint[1].bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_INTERRUPT) {
+ p->usbMode = MODE_INT;
+ }
+ if ((iface->endpoint[0].bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK &&
+ (iface->endpoint[1].bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK) {
+ p->usbMode = MODE_BULK;
+ }
+
+ if (p->usbMode == -1) {
+ p->hd44780_functions->drv_report(RPT_ERR,
+ "Unsupported USB_ENDPOINT_TYPE = %d / %d",
+ iface->endpoint[0].bmAttributes & USB_ENDPOINT_TYPE_MASK,
+ iface->endpoint[1].bmAttributes & USB_ENDPOINT_TYPE_MASK);
+ return;
+ }
+
+ if (iface->endpoint[0].bEndpointAddress & USB_ENDPOINT_DIR_MASK) {
+ p->usbEpIn = iface->endpoint[0].bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK;
+ p->usbEpOut = iface->endpoint[1].bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK;
+ }
+ else {
+ p->usbEpIn = iface->endpoint[1].bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK;
+ p->usbEpOut = iface->endpoint[0].bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK;
+ }
+}
+
+/**
+ * Pseudo (empty) uPause function.
+ * Override the uPause function as a usb4all device takes care of timing itself.
+ * \param p Pointer to PrivateData structure (unused)
+ * \param usecs Number of micro-seconds to sleep (ignored)
+ */
+void
+usb4all_HD44780_uPause(PrivateData *p, int usecs)
+{
+}
+
+
+/**
+ * Initialize the driver.
+ * \param drvthis Pointer to driver structure.
+ * \retval 0 Success.
+ * \retval -1 Error.
+ */
+int
+hd_init_usb4all(Driver *drvthis)
+{
+ PrivateData *p = (PrivateData *) drvthis->private_data;
+
+ struct usb_bus *bus;
+
+ p->hd44780_functions->senddata = usb4all_HD44780_senddata;
+ p->hd44780_functions->close = usb4all_HD44780_close;
+
+ p->hd44780_functions->set_contrast = usb4all_HD44780_set_contrast;
+ p->hd44780_functions->backlight = usb4all_HD44780_backlight;
+ p->hd44780_functions->readkeypad = usb4all_HD44780_readkeypad;
+
+ /* try to find USB device */
+ usb_init();
+ usb_find_busses();
+ usb_find_devices();
+
+ p->usbHandle = 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 usb4all device */
+ if ((dev->descriptor.idVendor == USB4ALL_VENDORID) &&
+ (dev->descriptor.idProduct == USB4ALL_PRODUCTID)) {
+
+ /* USB-4-all device found; try to open it */
+ p->usbHandle = usb_open(dev);
+ if (p->usbHandle == NULL) {
+ report(RPT_WARNING, "hd_init_usb4all: unable to open device");
+ /*
+ * Do not exit here because other
+ * (possibly working) devices may be
+ * connected.
+ */
+ }
+ else {
+ report(RPT_INFO, "hd_init_usb4all: USB-4-all device found");
+ usb4all_determine_usb_params(p, &dev->config[0].interface[0].altsetting[0]);
+ }
+ }
+ }
+ }
+
+ /* No device found at all */
+ if (p->usbHandle == NULL) {
+ report(RPT_ERR, "hd_init_usb4all: no (matching) USB-4-all device found");
+ return -1;
+ }
+
+ if (p->usbMode == -1) {
+ report(RPT_ERR, "hd_init_usb4all: unknown usb mode");
+ return -1;
+ }
+
+ /* allocate and initialize buffer */
+ if ((p->tx_buf.buffer = malloc(USB4ALL_TX_MAX)) == NULL) {
+ report(RPT_ERR, "hd_init_usb4all: could not allocate send buffer");
+ usb4all_HD44780_close(p);
+ return -1;
+ }
+
+ if ((p->rx_buf.buffer = malloc(USB4ALL_RX_MAX)) == NULL) {
+ report(RPT_ERR, "hd_init_usb4all: could not allocate receive buffer");
+ usb4all_HD44780_close(p);
+ return -1;
+ }
+
+ common_init(p, IF_4BIT);
+
+ /* replace uPause with empty one after initialization */
+ p->hd44780_functions->uPause = usb4all_HD44780_uPause;
+
+ /* initialize usb-4-all controller */
+ usb4all_init(p);
+
+ return 0;
+}
+
+/**
+ * Send a single byte of data to the LCD.
+ * \param p pointer to private date structure
+ * \param dispID display to send data to (0 = all displays)
+ * \param flags data or instruction command (RS_DATA | RS_INSTR)
+ * \param ch character to display or instruction value
+ */
+void
+usb4all_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch)
+{
+ if (displayID == 0) {
+ usb4all_HD44780_senddata(p, 1, flags, ch);
+ if (p->numDisplays == 2) {
+ usb4all_HD44780_senddata(p, 2, flags, ch);
+ }
+ return;
+ }
+
+ p->tx_buf.buffer[0] = 0x54 + displayID;
+ p->tx_buf.buffer[1] = (flags == RS_DATA) ? 0x02 : 0x03;
+ p->tx_buf.buffer[2] = ch;
+ p->tx_buf.use_count = 3;
+ usb4all_data_io(p, &p->tx_buf, &p->rx_buf);
+}
+
+/**
+ * Turn display backlight on or off.
+ * Backlight is turned on or off by toggeling between the brightness
+ * and offbrightness values.
+ * \param p Pointer to driver's private data structure.
+ * \param state New backlight status.
+ */
+void
+usb4all_HD44780_backlight(PrivateData *p, unsigned char state)
+{
+ /* get backlight brightness */
+ int promille = (state == BACKLIGHT_ON) ? p->brightness : p->offbrightness;
+
+ p->hd44780_functions->drv_debug(RPT_DEBUG,
+ "usb4all_HD44780_backlight: Setting backlight to %d", promille);
+
+ /* and set it (converted from [0,1000] -> [255,0]) */
+ usb4all_set_pwm_value(p, USB4ALL_PWM_BRIGHTNESS, ((1000 - promille) * 255) / 1000);
+}
+
+/**
+ * Change display contrast.
+ * \param p Pointer to driver's private data structure.
+ * \param value New contrast value (one byte).
+ */
+void
+usb4all_HD44780_set_contrast(PrivateData *p, unsigned char value)
+{
+ p->hd44780_functions->drv_debug(RPT_DEBUG,
+ "usb4all_HD44780_set_contrast: Setting contrast to %d", value);
+ usb4all_set_pwm_value(p, USB4ALL_PWM_CONTRAST, value);
+}
+
+/**
+ * Read the keypad
+ * \param Ydata the up to 4 bits that should be put on the Y side of the matrix
+ * \return the up to 4 bits that are read out on the X side of the matrix
+ */
+unsigned char
+usb4all_HD44780_readkeypad(PrivateData *p, unsigned int Ydata)
+{
+ /* adjust and invert bits */
+ Ydata = ((Ydata << 4) ^ 0xF0);
+
+ /* Output lines (Y) are RA4, RA5, RC6, RC7 */
+ p->tx_buf.buffer[0] = 0x50;
+ p->tx_buf.buffer[1] = 0x02;
+ p->tx_buf.buffer[2] = Ydata & 0x30;
+ p->tx_buf.buffer[3] = 0x00;
+ p->tx_buf.buffer[4] = Ydata & 0xC0;
+ p->tx_buf.use_count = 5;
+
+ usb4all_data_io(p, &p->tx_buf, &p->rx_buf);
+
+ /* Read RA3 RA2 RA1 RA0 */
+ p->tx_buf.buffer[0] = 0x50;
+ p->tx_buf.buffer[1] = 0x03;
+ p->tx_buf.use_count = 2;
+ usb4all_data_io(p, &p->tx_buf, &p->rx_buf);
+
+ /* filter and invert the result */
+ return ((p->rx_buf.buffer[2] & 0x0F) | 0xF0) ^ 0xFF;
+}
+
+/**
+ * Close the driver (do necessary clean-up).
+ * \param p Pointer to driver's private data structure.
+ */
+void
+usb4all_HD44780_close(PrivateData *p)
+{
+ if (p->usbHandle != NULL) {
+ if (p->have_backlight) {
+ usb4all_HD44780_backlight(p, BACKLIGHT_OFF);
+ }
+
+ usb_close(p->usbHandle);
+ p->usbHandle = NULL;
+ }
+
+ if (p->tx_buf.buffer != NULL) {
+ free(p->tx_buf.buffer);
+ p->tx_buf.buffer = NULL;
+ }
+
+ if (p->rx_buf.buffer != NULL) {
+ free(p->rx_buf.buffer);
+ p->rx_buf.buffer = NULL;
+ }
+
+}
+
+/* EOF */
diff --git a/server/drivers/hd44780-usb4all.h b/server/drivers/hd44780-usb4all.h
new file mode 100644
index 0000000..988704a
--- /dev/null
+++ b/server/drivers/hd44780-usb4all.h
@@ -0,0 +1,46 @@
+/** \file server/drivers/hd44780-usb4all.h
+ * USB-4-all connection type of hd44780 driver for Hitachi HD44780 based
+ * LCD displays connected to an USB-4-all controller.
+ */
+
+/*-
+ * Copyright (C) 2012 Thomas Mohaupt
+ * 2010 Roland Wundrig
+ *
+ * Some code parts are adapted from Roland Wundrig linux demo code
+ * (part of usb4all package)
+ *
+ * This file is released under the GNU General Public License version 2.
+ * Refer to the COPYING file distributed with this package.
+ */
+
+#ifndef HD_USB4ALL_H
+#define HD_USB4ALL_H
+
+#include "lcd.h" /* for Driver */
+
+/* vendor and product id */
+#define USB4ALL_VENDORID 0x004D8
+#define USB4ALL_PRODUCTID 0x0FF0B
+
+/* USB read/write timeouts */
+#define TIMEOUT_READ 1000
+#define TIMEOUT_WRITE 1000
+
+/* USB transfer modes */
+#define MODE_INT 0x04 /* usb interface : interrup mode */
+#define MODE_BULK 0x08 /* usb interface : bulk mode */
+
+#define USB4ALL_TX_MAX 64 /* usb4all tx buffer size */
+#define USB4ALL_RX_MAX 16 /* usb4all rx buffer size */
+
+/* assignment of PWM channels */
+#define USB4ALL_PWM_CONTRAST 0x01 /* PWM channel used for contrast */
+#define USB4ALL_PWM_BRIGHTNESS 0x02 /* PWM channel used for brightness */
+
+#define USB4ALL_RESET 0xFF
+
+/* initialise this particular driver */
+int hd_init_usb4all(Driver *drvthis);
+
+#endif