From aac814f9304541e3e310217d1f050f07e58a3b70 Mon Sep 17 00:00:00 2001 From: marschap Date: Sat, 5 May 2007 18:05:50 +0000 Subject: [PATCH] overhauled picolcd driver (Nicu Pavel) --- ChangeLog | 1 + acinclude.m4 | 21 +- docs/lcdproc-user/drivers/picolcd.docbook | 71 ++-- server/drivers/Makefile.am | 3 +- server/drivers/picolcd.c | 385 +++++++++++++++++----- server/drivers/picolcd.h | 32 +- 6 files changed, 375 insertions(+), 138 deletions(-) diff --git a/ChangeLog b/ChangeLog index 970edfe..36025df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,7 @@ v.0.5dev (ongoing development) * server core: refactor renderin code + LCDd: config options TitleSpeed= and Heartbeat= * overhauled CwLnx driver (Dave Platt) + * overhauled picolcd driver (Nicu Pavel) v.0.5.2 * fix switching on/off the Load screen in lcdproc client using the menu diff --git a/acinclude.m4 b/acinclude.m4 index 3ff5aa3..eb65824 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -277,21 +277,12 @@ dnl else actdrivers=["$actdrivers NoritakeVFD"] ;; picolcd) - AC_CHECK_HEADERS([usblcd.h],[ - AC_CHECK_LIB(usblcd, main,[ - LIBUSBLCD="-lusblcd" - DRIVERS="$DRIVERS picolcd${SO}" - actdrivers=["$actdrivers picolcd"] - ],[ -dnl else - AC_MSG_WARN([The picolcd driver needs the usblcd library]) - ], - [-lusblcd] - ) - ],[ -dnl else - AC_MSG_WARN([The picolcd driver needs widgets.h, usblcd.h and usblcd_util.h from the usblcd package]) - ]) + if test "$enable_libusb" = yes ; then + DRIVERS="$DRIVERS picolcd${SO}" + actdrivers=["$actdrivers picolcd"] + else + AC_MSG_WARN([The picolcd driver needs the libusb library.]) + fi ;; pyramid) DRIVERS="$DRIVERS pyramid${SO}" diff --git a/docs/lcdproc-user/drivers/picolcd.docbook b/docs/lcdproc-user/drivers/picolcd.docbook index f3d4cd9..db4022a 100644 --- a/docs/lcdproc-user/drivers/picolcd.docbook +++ b/docs/lcdproc-user/drivers/picolcd.docbook @@ -11,42 +11,43 @@ - Setting up the picoLCD +Setting up the picoLCD - - The picoLCD device as used by this driver is USB connected and may be purchased - with an internal USB header connector (5-pin to 5-pin) or an external cable - (Type-A to 5-pin). See: . - It may also come pre-installed on systems like the Mini-Box M300: - . - - - Using the USB LCD with this driver requires the usblcd library from Mini-box.com - (available at ).i - The usblcd library - requires libusb and libhcd. Your distribution may or may not already provide - these libraries. The only kernel driver required is the USB host controller - driver (uhci_hcd on the M300) required to fire up the usb bus to which the LCD is - attached. - - - Lastly, the usbfs file system must be mounted on /proc/bus/usb. - mount -t usbfs usbfs /proc/bus/usb - - - Once connected and with libusblcd, libusb and libhid installed, testing the USB LCD - can be done with the usblcd program that comes with the usblcd - library. - You can also change the USB LCD's initial display (what it shows when you - initialize the device) by using the usblcd binary's - splash command. - - - To use the picolcd with LCDproc, add picolcd to the LCDproc configure drivers option - (or use all) and then start LCDd with the "-d picolcd" option. The driver has - sane default options and the options that are user configurable are limited to mostly - simple items, like contrast and which keys to lights up. - + + The picoLCD device as used by this driver is USB connected and may be purchased + with an internal USB header connector (5-pin to 5-pin) or an external cable + (Type-A to 5-pin). See: . + It may also come pre-installed on systems like the Mini-Box M300: + . + + + Building and using the USB LCD with this driver requires the + libusb library. + Most distributions do provide this library. + The only kernel module required is the USB host controller driver + (uhci_hcd on the M300) to fire up the USB bus + to which the LCD is attached. + + + Lastly, the usbfs file system must be mounted on + /proc/bus/usb, e.g. using the command + mount -t usbfs usbfs /proc/bus/usb or by your disptributions + default configuration. + + + You can also change the USB LCD's initial display (what it shows when you + initialize the device) by using the usblcd binary's + splash command. + + + To use the picoLCD with LCDproc, add picolcd + to the LCDproc ./configure --drivers option + (or use all), set the Driver= to + picolcd in the LCDd.conf config + file, and then start LCDd either directly or using startup scripts. + The driver has sane default options and the options that are user configurable + are limited to mostly simple items, like contrast and which keys to light up. + diff --git a/server/drivers/Makefile.am b/server/drivers/Makefile.am index c6f08f2..e31eacb 100644 --- a/server/drivers/Makefile.am +++ b/server/drivers/Makefile.am @@ -25,6 +25,7 @@ noinst_LIBRARIES = libLCD.a libbignum.a IOWarrior_CFLAGS = @libusb_cflags@ $(AM_CFLAGS) hd44780_CFLAGS = @libusb_cflags@ $(AM_CFLAGS) g15_CFLAGS = @libusb_cflags@ $(AM_CFLAGS) +picolcd_CFLAGS = @libusb_cflags@ $(AM_CFLAGS) CFontz_LDADD = libLCD.a libbignum.a CFontz633_LDADD = libLCD.a libbignum.a @@ -45,7 +46,7 @@ MD8800_LDADD = libLCD.a mtc_s16209x_LDADD = libLCD.a MtxOrb_LDADD = libLCD.a libbignum.a NoritakeVFD_LDADD = libLCD.a -picolcd_LDADD = libLCD.a @LIBUSBLCD@ +picolcd_LDADD = @libusb_libs@ libLCD.a libbignum.a pyramid_LDADD = libLCD.a serialPOS_LDADD = libLCD.a libbignum.a serialVFD_LDADD = libLCD.a libbignum.a diff --git a/server/drivers/picolcd.c b/server/drivers/picolcd.c index 0a80484..7a44158 100644 --- a/server/drivers/picolcd.c +++ b/server/drivers/picolcd.c @@ -4,6 +4,9 @@ * (c) 2007 NitroSecurity, Inc. * Written by Gatewood Green or * (c) 2007 Peter Marschall - adapted coding style and reporting to LCDproc + * (c) 2007 Mini-Box.com, Nicu Pavel + * - removed libusblcd and hid dependency + * - added vbar, hbar, custom char, bignum support * * License: GPL (same as usblcd and lcdPROC) * @@ -15,38 +18,16 @@ * of the picoLCD * * The picoLCD is usb connected and is driven (currently) via userspace - * libraries using the Mini-box.com usblcd library (not to be confused with the - * Linux usblcd module which does NOT support this device). The usblcd library - * rides atop libusb and libhid (both of which are required for this driver to - * operate). + * using libusb library. * * libusb: http://libusb.sf.net - * libhid: http://libhid.alioth.debian.org - * usblcd: http://www.mini-box.com/picoLCD-20x2-OEM - * - * The usblcd library is very haphazardly written and directly writes to - * stdout and stderr instead of returning the result for most functions - * (including read_events). Eventually it would be a good idea to eliminate - * the need for usblcd and drive the hardware via libusb and libhid directly. - * Such a conversion has the opportunity to provide meaningful return values - * for all fucntions (instead of stab and hope) and allow for use of multiple - * picoLCD devices. - * - * Due to the way libusblcd's read_events prints keys to stderr instead of - * returning a struct or some such, you will find my own get_key_events below. - * - * ### WARNING ###: libusblcd.so sets a handler for SIGTERM. Because most - * applications would set up their signal handling early on (before calling - * new_usblcd_operations()), this can result in a condition that will prevent - * a handler your application installed from executing. If your handler was - * responsible for cleaning up logs, syncing, etc, it can result in lost data. * */ /* lcdPROC includes */ #include "lcd.h" #include "picolcd.h" - +#include /* Debug mode: un-comment to turn on debugging messages in the server */ /* #define DEBUG 1 */ @@ -56,11 +37,6 @@ # include "config.h" #endif -/* These three includes are the Mini-box.com libusblcd (usblcd) and company. */ -#include -#include -#include - /* Various odds and ends */ #include #include @@ -77,17 +53,32 @@ #define DEFAULT_KEYLIGHTS 1 /* On */ #define DEFAULT_TIMEOUT 500 /* Half second */ +#define NUM_CCs 8 /* max. number of custom characters */ + +typedef enum { + standard, /* only char 0 is used for heartbeat */ + vbar, /* vertical bars */ + hbar, /* horizontal bars */ + custom, /* custom settings */ + bignum, /* big numbers */ + bigchar /* big characters */ +} CGmode; + /* PrivateData struct */ typedef struct pd { - usblcd_operations *lcd; // Reference to the LCD instance + usb_dev_handle *lcd; int width; int height; + int cellwidth; + int cellheight; int key_timeout; int contrast; int backlight; int keylights; int key_light[KEYPAD_LIGHTS]; + /* defineable characters */ + CGmode ccmode; char *key_matrix[KEYPAD_MAX]; char *info; unsigned char *framebuf; @@ -111,8 +102,11 @@ static char * keymap[KEYPAD_MAX] = { }; /* Private function definitions */ -void get_key_event (usblcd_operations *self, lcd_packet *packet, int timeout); -void set_key_lights (usblcd_operations *self, int keys[], int state); +static usb_dev_handle *picolcd_open(void); +static void picolcd_send(usb_dev_handle *lcd, unsigned char *data, int size); +static void picolcd_write(usb_dev_handle *lcd, const int row, const int col, const unsigned char *data); +static void get_key_event (usb_dev_handle *lcd, lcd_packet *packet, int timeout); +static void set_key_lights (usb_dev_handle *lcd, int keys[], int state); /* lcd_logical_driver Variables */ MODULE_EXPORT char *api_version = API_VERSION; @@ -120,7 +114,7 @@ MODULE_EXPORT int stay_in_foreground = 0; MODULE_EXPORT int supports_multiple = 1; MODULE_EXPORT char *symbol_prefix = "picoLCD_"; -/* lcd_logical_driver Manditory functions */ +/* lcd_logical_driver mandatory functions */ MODULE_EXPORT int picoLCD_init(Driver *drvthis) { PrivateData *pd; int x; @@ -133,11 +127,13 @@ MODULE_EXPORT int picoLCD_init(Driver *drvthis) { if (drvthis->store_private_ptr(drvthis, pd)) return -1; - pd->lcd = new_usblcd_operations(); - pd->lcd->init(pd->lcd); + pd->lcd = picolcd_open(); pd->width = 20; /* hard coded (mfg spec) */ pd->height = 2; /* hard coded (mfg spec) */ pd->info = "picoLCD: Supports the LCD as installed on the M300 (http://www.mini-box.com/Mini-Box-M300-LCD) "; + pd->cellwidth = LCD_DEFAULT_CELLWIDTH; + pd->cellheight = LCD_DEFAULT_CELLHEIGHT; + pd->ccmode = standard; for (x = 0; x < KEYPAD_LIGHTS; x++) pd->key_light[x] = 1; /* individual lights on */ @@ -191,7 +187,8 @@ MODULE_EXPORT int picoLCD_init(Driver *drvthis) { MODULE_EXPORT void picoLCD_close(Driver *drvthis) { PrivateData *pd = drvthis->private_data; - pd->lcd->close(pd->lcd); /* This actually does not do anything in usblcd (yet?) */ + usb_release_interface(pd->lcd, 0); + usb_close(pd->lcd); debug(RPT_DEBUG, "picolcd: close complete\n"); } @@ -213,6 +210,7 @@ MODULE_EXPORT void picoLCD_clear(Driver *drvthis) { PrivateData *pd = drvthis->private_data; memset(pd->framebuf, ' ', pd->width * pd->height); + pd->ccmode = standard; debug(RPT_DEBUG, "picolcd: clear complete\n"); } @@ -221,7 +219,7 @@ MODULE_EXPORT void picoLCD_flush(Driver *drvthis) { PrivateData *pd = drvthis->private_data; unsigned char *fb = pd->framebuf; unsigned char *lf = pd->lstframe; - static char text[48]; + static unsigned char text[48]; int i, line, offset; debug(RPT_DEBUG, "picolcd: flush started\n"); @@ -234,8 +232,8 @@ MODULE_EXPORT void picoLCD_flush(Driver *drvthis) { for (i = 0; i < pd->width; i++) { if (*fb++ != *lf++) { - strncpy(text, pd->framebuf + offset, pd->width); - pd->lcd->settext(pd->lcd, line, 0, text); + strncpy((char *)text, (char *)pd->framebuf + offset, pd->width); + picolcd_write(pd->lcd, line, 0, text); memcpy(pd->lstframe + offset, pd->framebuf + offset, pd->width); debug(RPT_DEBUG, "picolcd: flush wrote line %d (%s)\n", line + 1, text); @@ -248,9 +246,9 @@ MODULE_EXPORT void picoLCD_flush(Driver *drvthis) { debug(RPT_DEBUG, "picolcd: flush complete\n\t(%s)\n\t(%s)\n", pd->framebuf, pd->lstframe); } -MODULE_EXPORT void picoLCD_string(Driver *drvthis, int x, int y, char *str) { +MODULE_EXPORT void picoLCD_string(Driver *drvthis, int x, int y, unsigned char *str) { PrivateData *pd = drvthis->private_data; - char *dest; + unsigned char *dest; int len; debug(RPT_DEBUG, "picolcd: string start (%s)\n", str); @@ -260,7 +258,7 @@ MODULE_EXPORT void picoLCD_string(Driver *drvthis, int x, int y, char *str) { if (x < 1 || x > pd->width) return; - len = strlen(str); + len = strlen((char *)str); if (len + x > pd->width) { debug(RPT_DEBUG, "picolcd: string overlength (>%d). Start: %d Length: %d (%s)\n", pd->width, x, len ,str); @@ -274,10 +272,9 @@ MODULE_EXPORT void picoLCD_string(Driver *drvthis, int x, int y, char *str) { debug(RPT_DEBUG, "picolcd: string complete (%s)\n", str); } -MODULE_EXPORT void picoLCD_chr(Driver *drvthis, int x, int y, char chr) { +MODULE_EXPORT void picoLCD_chr(Driver *drvthis, int x, int y, unsigned char chr) { PrivateData *pd = drvthis->private_data; - char *dest; - + unsigned char *dest; debug(RPT_DEBUG, "picolcd: chr start (%c)\n", chr); if (y < 1 || y > pd->height) @@ -288,16 +285,168 @@ MODULE_EXPORT void picoLCD_chr(Driver *drvthis, int x, int y, char chr) { x--; y--; /* Convert 1-based to 0-based */ dest = pd->framebuf + (y * pd->width + x); memcpy(dest, &chr, sizeof(char)); - debug(RPT_DEBUG, "picolcd: chr complete (%c)\n", chr); } + +MODULE_EXPORT void picoLCD_set_char (Driver *drvthis, int n, unsigned char *dat) +{ + PrivateData *pd = drvthis->private_data; + unsigned char packet[10] = { 0x9c }; /* define character */ + unsigned char mask = (1 << pd->cellwidth) - 1; + int row; + + if ((n < 0) || (n >= NUM_CCs)) + return; + if (!dat) + return; + + packet[1] = n; /* Custom char to define. */ + + for (row = 0; row < pd->cellheight; row++) { + packet[row + 2] = dat[row] & mask; + } + + picolcd_send(pd->lcd, packet, 10); +} + +MODULE_EXPORT int picoLCD_get_free_chars (Driver *drvthis) +{ + return NUM_CCs; +} + + +MODULE_EXPORT void picoLCD_vbar (Driver *drvthis, int x, int y, int len, int promille, int options) +{ + PrivateData *pd = drvthis->private_data; + + if (pd->ccmode != vbar) { + unsigned char vBar[pd->cellheight]; + int i; + + if (pd->ccmode != standard) { + /* Not supported(yet) */ + report(RPT_WARNING, "%s: vbar: cannot combine two modes using user-defined characters", + drvthis->name); + return; + } + pd->ccmode = vbar; + + memset(vBar, 0x00, sizeof(vBar)); + + for (i = 1; i < pd->cellheight; i++) { + // add pixel line per pixel line ... + vBar[pd->cellheight - i] = 0xFF; + picoLCD_set_char(drvthis, i, vBar); + } + } + + lib_vbar_static(drvthis, x, y, len, promille, options, pd->cellheight, 0); +} + + + +MODULE_EXPORT void picoLCD_hbar (Driver *drvthis, int x, int y, int len, int promille, int options) +{ + PrivateData *pd = drvthis->private_data; + + if (pd->ccmode != hbar) { + unsigned char hBar[pd->cellheight]; + int i; + + if (pd->ccmode != standard) { + /* Not supported(yet) */ + report(RPT_WARNING, "%s: hbar: cannot combine two modes using user-defined characters", + drvthis->name); + return; + } + + pd->ccmode = hbar; + + memset(hBar, 0x00, sizeof(hBar)); + + for (i = 1; i <= pd->cellwidth; i++) { + // fill pixel columns from left to right. + memset(hBar, 0xFF & ~((1 << (pd->cellwidth - i)) - 1), sizeof(hBar)-1); + picoLCD_set_char(drvthis, i, hBar); + } + } + + lib_hbar_static(drvthis, x, y, len, promille, options, pd->cellwidth, 0); +} + +MODULE_EXPORT void picoLCD_num (Driver *drvthis, int x, int num) +{ + PrivateData *pd = drvthis->private_data; + int do_init = 0; + + if ((num < 0) || (num > 10)) + return; + + if (pd->ccmode != bignum) { + if (pd->ccmode != standard) { + /* Not supported (yet) */ + report(RPT_WARNING, "%s: num: cannot combine two modes using user-defined characters", + drvthis->name); + return; + } + + pd->ccmode = bignum; + + do_init = 1; + } + + // Lib_adv_bignum does everything needed to show the bignumbers. + lib_adv_bignum(drvthis, x, num, 0, do_init); +} + + +MODULE_EXPORT int picoLCD_icon (Driver *drvthis, int x, int y, int icon) +{ + PrivateData *pd = drvthis->private_data; + + /* 8x5 icons each number represents one row in binary */ + + static unsigned char heart_open[] = + { 0x0, 0xa, 0x15, 0x11, 0x1b, 0xa, 0x4, 0x0 }; + + + static unsigned char heart_filled[] = + { 0x0, 0xa, 0x1f, 0x1f, 0x1f, 0xe, 0x4, 0x0 }; + + switch (icon) { + case ICON_BLOCK_FILLED: + picoLCD_chr(drvthis, x, y, 255); + break; + case ICON_HEART_FILLED: + pd->ccmode = custom; + picoLCD_set_char(drvthis, 7, heart_filled); + picoLCD_chr(drvthis, x, y, 7); + break; + case ICON_HEART_OPEN: + pd->ccmode = custom; + picoLCD_set_char(drvthis, 7, heart_open); + picoLCD_chr(drvthis, x, y, 7); + break; + case ICON_ARROW_LEFT: + picoLCD_chr(drvthis, x, y, 127); + break; + case ICON_ARROW_RIGHT: + picoLCD_chr(drvthis, x, y, 126); + break; + + default: + return -1; /* Let the core do other icons */ + } + return 0; +} + /* lcd_logical_driver Essential input functions */ MODULE_EXPORT char *picoLCD_get_key(Driver *drvthis) { PrivateData *pd = drvthis->private_data; lcd_packet *keydata; - char *keystr; + char *keystr = NULL; int keys_read = 0; int key_pass = 0; int two_keys = 0; @@ -398,20 +547,23 @@ MODULE_EXPORT char *picoLCD_get_key(Driver *drvthis) { MODULE_EXPORT int picoLCD_set_contrast(Driver *drvthis, int promille) { PrivateData *pd = drvthis->private_data; int inv; /* The hardware seems to go dark on higher values, so we turn it around */ - + unsigned char packet[2] = { 0x92 }; /* set contrast id */ + if (promille <= 1000 && promille > 0) { inv = 1000 - promille; - pd->lcd->contrast(pd->lcd, (int) (inv / 1000 * 40)); - return 0; + packet[1] = inv / 1000 * 40; } else if (promille > 1000) { - pd->lcd->contrast(pd->lcd, 0); - return 0; + packet[1] = 0; } else if (promille <= 0) { - pd->lcd->contrast(pd->lcd, 40); - return 0; + packet[1] = 40; } else { return -1; } + + picolcd_send(pd->lcd, packet, 2); + return 0; + + } /*MODULE_EXPORT int picoLCD_get_brightness(Driver *drvthis, int state) { @@ -426,15 +578,18 @@ MODULE_EXPORT int picoLCD_set_contrast(Driver *drvthis, int promille) { MODULE_EXPORT void picoLCD_backlight(Driver *drvthis, int state) { PrivateData *pd = drvthis->private_data; - + unsigned char packet[2] = { 0x91 }; /* set backlight id */ + if (state == 0) { - pd->lcd->backlight(pd->lcd, state); + packet[1] = state; + picolcd_send(pd->lcd, packet, 2); set_key_lights(pd->lcd, pd->key_light, state); return; } if (state == 1) { - pd->lcd->backlight(pd->lcd, state); + packet[1] = state; + picolcd_send(pd->lcd, packet, 2); if (pd->keylights) set_key_lights(pd->lcd, pd->key_light, state); return; @@ -456,12 +611,90 @@ MODULE_EXPORT char *picoLCD_get_info(Driver *drvthis) { } /* Private functions */ -void get_key_event (usblcd_operations *self, lcd_packet *packet, int timeout) { + +static usb_dev_handle *picolcd_open(void) +{ + + usb_dev_handle *lcd; + struct usb_bus *busses, *bus; + struct usb_device *dev; + char driver[1024]; + int ret; + + lcd = NULL; + + debug(RPT_DEBUG, "picolcd: scanning for devices...\n"); + + usb_init(); + usb_find_busses(); + usb_find_devices(); + busses = usb_get_busses(); + + for (bus = busses; bus; bus = bus->next) { + for (dev = bus->devices; dev; dev = dev->next) { + if ((dev->descriptor.idVendor == picoLCD_VENDOR) && (dev->descriptor.idProduct == picoLCD_DEVICE)) { + debug(RPT_DEBUG, "Found picoLCD on bus %s device %s \n", bus->dirname, dev->filename); + lcd = usb_open(dev); + ret = usb_get_driver_np(lcd, 0, driver, sizeof(driver)); + if (ret == 0) { + debug(RPT_DEBUG, "Interface 0 already claimed by '%s' attempting to detach driver...\n", driver); + if (usb_detach_kernel_driver_np(lcd, 0) < 0) { + debug(RPT_DEBUG, "Failed to detach '%s' driver !\n", driver); + return NULL; + } + } + + usb_set_configuration(lcd, 1); + usleep(100); + + if (usb_claim_interface(lcd, 0) < 0) { + debug(RPT_DEBUG, "Failed to claim interface !\n"); + return NULL; + } + + usb_set_altinterface(lcd, 0); + return lcd; + } + } + } + + debug(RPT_DEBUG, "Could not find a picoLCD !\n"); + return NULL; +} + +static void picolcd_send(usb_dev_handle *lcd, unsigned char *data, int size) +{ + usb_interrupt_write(lcd, USB_ENDPOINT_OUT + 1, (char *) data, size, 1000); +} + +static void picolcd_write(usb_dev_handle *lcd, const int row, const int col, const unsigned char *data) +{ + unsigned char packet[64]; + int len, i; + + len = strlen((char *)data); + if (len > 20) len = 20; + + packet[0] = 0x98; + packet[1] = row; + packet[2] = col; + packet[3] = len; + + i = 4; + while (len--) { + packet[i++] = *data++; + } + + picolcd_send(lcd, packet, i); +} + + +void get_key_event (usb_dev_handle *lcd, lcd_packet *packet, int timeout) { int ret; memset(packet->data, 0, 255); packet->type = 0; - ret = usb_interrupt_read(self->hid->hiddev->handle, USB_ENDPOINT_IN + 1, packet->data, _USBLCD_MAX_DATA_LEN, timeout); + ret = usb_interrupt_read(lcd, USB_ENDPOINT_IN + 1, (char *)packet->data, PICOLCD_MAX_DATA_LEN, timeout); if (ret > 0) { switch (packet->data[0]) { case IN_REPORT_KEY_STATE: { @@ -477,28 +710,24 @@ void get_key_event (usblcd_operations *self, lcd_packet *packet, int timeout) { } } -void set_key_lights (usblcd_operations *self, int keys[], int state) { +void set_key_lights (usb_dev_handle *lcd, int keys[], int state) { + + unsigned char packet[2] = { 0x81 }; /* set led */ + unsigned int leds = 0; + int i; + if (state) { /* Only LEDs we want on */ - if (keys[0]) - self->setled(self, 0, 1); - if (keys[1]) - self->setled(self, 1, 1); - if (keys[2]) - self->setled(self, 2, 1); - if (keys[3]) - self->setled(self, 3, 1); - if (keys[4]) - self->setled(self, 4, 1); - if (keys[5]) - self->setled(self, 5, 1); + for (i = 0; i < picoLCD_MAX_LEDS; i++) + if(keys[i]) + leds |= 1 << i; + else + leds &= ~ (1 << i); } else { /* All LEDs off */ - self->setled(self, 0, 0); - self->setled(self, 1, 0); - self->setled(self, 2, 0); - self->setled(self, 3, 0); - self->setled(self, 4, 0); - self->setled(self, 5, 0); + leds = 0; } + + packet[1] = leds; + picolcd_send(lcd, packet, 2); } diff --git a/server/drivers/picolcd.h b/server/drivers/picolcd.h index d39beaa..059f054 100644 --- a/server/drivers/picolcd.h +++ b/server/drivers/picolcd.h @@ -4,6 +4,8 @@ * * (c) 2007 NitroSecurity, Inc. * Written by Gatewood Green or + * (c) 2007 Mini-Box.com. + * removed libusblcd dependency * * License: GPL (same as usblcd and lcdPROC) * @@ -19,6 +21,19 @@ #define PCIOLCD_H #include "lcd.h" +#include "lcd_lib.h" +#include "adv_bignum.h" + +#define picoLCD_VENDOR 0x04d8 +#define picoLCD_DEVICE 0x0002 + +#define picoLCD_MAX_LEDS 6 + +#define IN_REPORT_KEY_STATE 0x11 +#define IN_REPORT_IR_DATA 0x21 + +#define PICOLCD_MAX_DATA_LEN 24 + typedef struct _lcd_packet lcd_packet; struct _lcd_packet { @@ -32,17 +47,16 @@ MODULE_EXPORT int picoLCD_width(Driver *drvthis); MODULE_EXPORT int picoLCD_height(Driver *drvthis); MODULE_EXPORT void picoLCD_clear(Driver *drvthis); MODULE_EXPORT void picoLCD_flush(Driver *drvthis); -MODULE_EXPORT void picoLCD_string(Driver *drvthis, int x, int y, char *str); -MODULE_EXPORT void picoLCD_chr(Driver *drvthis, int x, int y, char c); - +MODULE_EXPORT void picoLCD_string(Driver *drvthis, int x, int y, unsigned char *str); +MODULE_EXPORT void picoLCD_chr(Driver *drvthis, int x, int y, unsigned char c); +MODULE_EXPORT void picoLCD_set_char (Driver *drvthis, int n, unsigned char *dat); MODULE_EXPORT char *picoLCD_get_key(Driver *drvthis); -//MODULE_EXPORT void picoLCD_vbar(Driver *drvthis, int x, int y, int len, int promille, int options); -//MODULE_EXPORT void picoLCD_hbar(Driver *drvthis, int x, int y, int len, int promille, int options); -//MODULE_EXPORT void picoLCD_num(Driver *drvthis, int x, int y, int num); -//MODULE_EXPORT void picoLCD_heartbeat(Driver *drvthis, int state); -//MODULE_EXPORT void picoLCD_icon(Driver *drvthis, int x, int y, int icon); -//MODULE_EXPORT void picoLCD_cursor(Driver *drvthis, int x, int y, int type); +MODULE_EXPORT void picoLCD_vbar(Driver *drvthis, int x, int y, int len, int promille, int options); +MODULE_EXPORT void picoLCD_hbar(Driver *drvthis, int x, int y, int len, int promille, int options); +MODULE_EXPORT void picoLCD_num(Driver *drvthis, int x, int num); +MODULE_EXPORT int picoLCD_icon(Driver *drvthis, int x, int y, int icon); +MODULE_EXPORT void picoLCD_cursor(Driver *drvthis, int x, int y, int type); //MODULE_EXPORT int picoLCD_get_contrast(Driver *drvthis); MODULE_EXPORT int picoLCD_set_contrast(Driver *drvthis, int promille);