From 08bb4b24b859f5bb31b1ea3877e1d167bd30e0d0 Mon Sep 17 00:00:00 2001 From: marschap Date: Wed, 8 Oct 2008 21:07:45 +0000 Subject: [PATCH] add files forgotten in previous commit --- server/drivers/hd44780-uss720.c | 348 ++++++++++++++++++++++++++++++++ server/drivers/hd44780-uss720.h | 10 + 2 files changed, 358 insertions(+) create mode 100644 server/drivers/hd44780-uss720.c create mode 100644 server/drivers/hd44780-uss720.h diff --git a/server/drivers/hd44780-uss720.c b/server/drivers/hd44780-uss720.c new file mode 100644 index 0000000..01510d7 --- /dev/null +++ b/server/drivers/hd44780-uss720.c @@ -0,0 +1,348 @@ +/** \file hd44780-uss720.c + * \c uss720 connection type of \c hd44780 driver for Hitachi HD44780 based LCD displays. + * + * The LCD is operated in its 8 bit-mode to be connected to a uss720 based Belkin F5U002. + */ + +/* + * Copyright (c) 2008 Eric Pooch + * + * This file is released under the GNU General Public License. Refer to the + * COPYING file distributed with this package. + * + * This is a uss720 driver module for Hitachi HD44780 based LCD displays + * connected to a uss720 USB-to-IEEE 1284 Bridge chip in 8 bit mode. + * The uss720 chip is found in many (but not all) + * Belkin F5U002 USB->parallel printer adapters. + * + * Applicable Data Sheets: + * - http://digilander.libero.it/demarchidaniele/qcamvc/uss-720.pdf + * - http://www.beyondlogic.org/parlcd/parlcd.htm + * + * Wiring is same as winamp connection. + * Uncomment //#define USS720_MAC_USB_LCD_KIT_WIRING 1 below to use a + * Mac USB LCD Kit instead. + * + */ + +#include "hd44780-uss720.h" +#include "hd44780-low.h" +#include "lpt-port.h" + +#include "report.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +enum { + SSPMode = 0, + PS2Mode, + HHCMode, + ECPMode, + EPPMode, +} /*ECRMode*/; + + +enum { + StatusIndex = 0, + ControlIndex, + ExtControlIndex, + USSSTZControlIndex, + DataIndex, + EPPIndex, + USSSTZSetupIndex, +} /*RegisterDataByteIndex*/; + +enum { + DataRegAdr = 0, + StatusRegAdr, + ControlRegAdr, + EPPAddressRegAdr, + EPPDataRegAdr, + ECPCommandRegAdr, + ExtControlRegAdr, + USSSTZControlRegAdr, + USSSTZSetupRegAdr, +} /*RegisterAddress*/; + + +/* connection type specific functions to be exposed using pointers in init() */ +void uss720_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch); +void uss720_HD44780_backlight(PrivateData *p, unsigned char state); +void uss720_HD44780_close(PrivateData *p); +static void uss720_HD44780_uPause(PrivateData *p, int usecs); + +//#define USS720_MAC_USB_LCD_KIT_WIRING 1 +#ifdef USS720_MAC_USB_LCD_KIT_WIRING +/* Mac OS X USB LCD Kit wiring */ +#define EN1 STRB +#define EN2 INIT +#define EN3 0 +#define RS SEL +#define BL INIT +#define VCC LF +#else +/* winamp wiring */ +#define EN1 STRB +#define EN2 SEL +#define EN3 LF +#define RW LF +#define RS INIT +#define BL SEL +#define LE LF +#define VCC 0 +#endif + +static const unsigned char EnMask[] = { EN1, EN2, EN3 }; + +/* local helper functions not exposed */ +int uss720_get_1284_register(usb_dev_handle *usbHandle, unsigned int regIndex, unsigned char *value); +int uss720_set_1284_register(usb_dev_handle *usbHandle, unsigned int regAddress, unsigned char value); +int uss720_set_1284_mode(usb_dev_handle *usbHandle, unsigned int mode); + +/** + * Initialize the driver. + * \param drvthis Pointer to driver structure. + * \retval 0 Success. + * \retval -1 Error. + */ + +int +hd_init_uss720(Driver *drvthis) +{ + unsigned int vendor_id, product_id; + struct usb_bus *bus; + + PrivateData *p = (PrivateData*) drvthis->private_data; + + p->hd44780_functions->senddata = uss720_HD44780_senddata; + p->hd44780_functions->backlight = uss720_HD44780_backlight; + p->hd44780_functions->close = uss720_HD44780_close; + p->hd44780_functions->uPause = uss720_HD44780_uPause; + + /* load config */ + vendor_id = drvthis->config_get_int(drvthis->name, "VendorID", 0, 0x1293); + product_id = drvthis->config_get_int(drvthis->name, "ProductID", 0, 0x0002); + + /* Hardware Init */ + + /* try to find USB device */ + usb_init(); + usb_find_busses(); + usb_find_devices(); + + p->usbHandle = NULL; + p->usbIndex = 0; + 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 uss720 device */ + if (dev->descriptor.idVendor != vendor_id || dev->descriptor.idProduct != product_id) { + continue; + } + + /* uss720 device found; try to open it */ + p->usbHandle = usb_open(dev); + if (p->usbHandle == NULL) { + report(RPT_WARNING, "hd_init_uss720: unable to open device"); + continue; + } + + debug(RPT_DEBUG, "hd_init_uss720: opening device succeeded"); + + errno = 0; + if (usb_claim_interface(p->usbHandle, p->usbIndex) < 0) { +#if defined(LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP) + report(RPT_WARNING, "hd_init_uss720: interface may be claimed by " + "kernel driver, attempting to detach it"); + + errno = 0; + if ((usb_detach_kernel_driver_np(p->usbHandle, p->usbIndex) < 0) || + (usb_claim_interface(p->usbHandle, p->usbIndex) < 0)) { + report(RPT_ERR, "hd_init_uss720: unable to re-claim interface: %s", + strerror(errno)); + usb_close(p->usbHandle); + continue; + } +#else + report(RPT_ERR, "hd_init_uss720: unable to claim interface: %s", + strerror(errno)); + usb_close(p->usbHandle); + continue; +#endif + } + /* Use the alternate, vendor-specific, interface so we have access to the registers */ + + errno = usb_set_altinterface(p->usbHandle, 2); + if (errno) { + report(RPT_WARNING, "hd_init_uss720: unable to set alt interface: %s", strerror(errno)); + usb_close(p->usbHandle); + continue; + } + /* Make sure the port is in SSP (Standard) mode for full software control. */ + errno = uss720_set_1284_mode(p->usbHandle, SSPMode); + if (errno) { + report(RPT_WARNING, "hd_init_uss720: unable to set SSP mode: %d", errno);//strerror(errno)); + /* probably not fatal, so try to keep going with this device */ + } + + /* init the HD44780 LCD */ + common_init(p, IF_8BIT); + + return 0; + } + } + report(RPT_ERR, "hd_init_uss720: no (matching) USS720 device found"); + return -1; +} + + +/** + * Send data or commands to the display. + * \param p Pointer to driver's 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 +uss720_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch) +{ + unsigned char enableLines = 0, portControl; + + if (flags == RS_DATA) + portControl = RS; /* enable RS for data */ + else + portControl = 0; /* disable RS for instruction */ + + portControl |= VCC; /* keep the power on */ + portControl |= p->backlight_bit; + + if (displayID == 0) + enableLines = EnMask[0] + | ((p->have_backlight) ? 0 : EnMask[1]) + | ((p->numDisplays == 3) ? EnMask[2] : 0); + else + enableLines = EnMask[displayID - 1]; + + uss720_set_1284_register(p->usbHandle, ControlRegAdr, portControl ^ OUTMASK); + + uss720_set_1284_register(p->usbHandle, DataRegAdr, ch); + p->hd44780_functions->uPause(p, 1); + + uss720_set_1284_register(p->usbHandle, ControlRegAdr, (portControl | enableLines ) ^ OUTMASK); + p->hd44780_functions->uPause(p, 1); + + uss720_set_1284_register(p->usbHandle, ControlRegAdr, portControl ^ OUTMASK); +} + +void +uss720_HD44780_backlight(PrivateData *p, unsigned char state) +{ + p->backlight_bit = (state?0:BL); +} + + +void +uss720_HD44780_close(PrivateData *p) +{ + if (p->usbHandle != NULL) { + usb_close(p->usbHandle); + p->usbHandle = NULL; + } +} + + +/** + * Pause as needed (= a long time). + * \param drvthis Pointer to driver structure. + * \param value pause duration value (integer). + */ +static void +uss720_HD44780_uPause(PrivateData *p, int usecs) +{ + usleep(10*usecs); +} + + +#pragma mark - +#pragma mark -Basic Register Methods + +int +uss720_get_1284_register(usb_dev_handle *usbHandle, unsigned int regIndex, unsigned char *value) +{ + int res = 0; + unsigned char regData[128]; + + res = usb_control_msg(usbHandle, + /* bmRequestType */ 0xc0,/*USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,*/ + /* bRequest */ 3, + /* wValue */ (unsigned int)regIndex<<8, + /* wIndex */ 0, + /* Data */ (char *)regData, + /* wLength */ 7, + 10000 ); + + if (res) { + + } else if (value && (regIndex < 8)) { + *value = regData[(int)regIndex]; + } + + return res; +} + + +int +uss720_set_1284_register(usb_dev_handle *usbHandle, unsigned int regAddress, unsigned char value) +{ + return usb_control_msg(usbHandle, + /* bmRequestType */ 0x40,/*USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,*/ + /* bRequest */ 4, + /* wValue */ ((unsigned int)regAddress<<8 | (unsigned int) value), + /* wIndex */ 0, + /* Data */ NULL, + /* wLength */ 0, + 10000 ); +} + + +#pragma mark - +#pragma mark -Extended Methods + +int +uss720_set_1284_mode(usb_dev_handle *usbHandle, unsigned int mode) +{ + unsigned char regByte = 0x00; + int res = 0; + + res = uss720_get_1284_register(usbHandle, 3, ®Byte); + if (res) return res; + + regByte &= ~0x01; + + res = uss720_set_1284_register(usbHandle, 7, regByte); + if (res) return res; + + res = uss720_get_1284_register(usbHandle, 2, ®Byte); + if (res) return res; + + regByte &= ~(mode<<5); // Mask off the mode bits 7-5. + regByte |= (mode<<5); // Set the mode bits 7-5. + + return uss720_set_1284_register(usbHandle, 6, regByte); +} + diff --git a/server/drivers/hd44780-uss720.h b/server/drivers/hd44780-uss720.h new file mode 100644 index 0000000..dad85f1 --- /dev/null +++ b/server/drivers/hd44780-uss720.h @@ -0,0 +1,10 @@ +#ifndef HD_USS720_H +#define HD_USS720_H + +#include "lcd.h" /* for Driver */ +#include "hd44780-low.h" + + +// initialise this particular driver +int hd_init_uss720(Driver *drvthis); +#endif