From 4ea3f1cf984f048d1ad9f2156d63aa2ac14b1868 Mon Sep 17 00:00:00 2001 From: mmdolze Date: Sat, 18 Feb 2012 15:24:43 +0000 Subject: [PATCH] hd44780: Added 'usb4all' connection type for USB-4-all devices (T. Mohaupt) --- ChangeLog | 1 + LCDd.conf | 12 +- acinclude.m4 | 2 +- docs/LCDd.8.in | 3 + docs/lcdproc-user/drivers/hd44780.docbook | 253 +++++++++++- server/drivers/Makefile.am | 2 +- server/drivers/hd44780-drivers.h | 2 + server/drivers/hd44780-low.h | 5 + server/drivers/hd44780-usb4all.c | 474 ++++++++++++++++++++++ server/drivers/hd44780-usb4all.h | 46 +++ 10 files changed, 790 insertions(+), 10 deletions(-) create mode 100644 server/drivers/hd44780-usb4all.c create mode 100644 server/drivers/hd44780-usb4all.h 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 or by inclu pertelian | bwctusb | lcd2usb | + usb4all | lis2 | mplay | i2c | @@ -2853,9 +3092,13 @@ This can be done by specifying 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