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);