picolcd - driver for Mini-box.com USB LCD picoLCD (Gatewood Green)

This commit is contained in:
marschap
2007-03-18 13:45:12 +00:00
parent 99daf2fa4b
commit 2d20fd83c6
10 changed files with 790 additions and 13 deletions
+3
View File
@@ -220,6 +220,9 @@ Frank Jepsen
Karsten Festag
- ea65 driver
Gatewood Green
- picolcd driver
Further developers in the sourceforge lcdproc team:
Mindaugas Idzelis aim4min
+1
View File
@@ -34,6 +34,7 @@ v.0.5dev (ongoing development)
+ new 2-line bignum mode using 6 user defined characters (Robin Gilks)
* fix custom characters [with NewFirmware=yes] & backlight in CFontz
+ ea65 - driver for VFD in AOpen XC Cube AV EA65 barebones (Karsten Festag)
+ picolcd - driver for Mini-box.com USB LCD picoLCD (Gatewood Green)
v.0.5.1
+ config file support in lcdproc client (Andrew Foss)
+39 -6
View File
@@ -36,10 +36,10 @@
# driver specific section.
#
# The following drivers are supported:
# bayrad, CFontz, CFontz633, CFontzPacket, curses, CwLnx, EyeboxOne,
# g15, glcdlib, glk, hd44780, icp_a106, imon, IOWarrior, irman,
# joy, lb216,lcdm001, lcterm, lirc,MD8800, ms6931, mtc_s16209x,
# MtxOrb, NoritakeVFD, pyramid, sed1330, sed1520, serialPOS,
# bayrad, CFontz, CFontz633, CFontzPacket, curses, CwLnx, ea65,
# EyeboxOne, g15, glcdlib, glk, hd44780, icp_a106, imon, IOWarrior,
# irman, joy, lb216,lcdm001, lcterm, lirc,MD8800, ms6931, mtc_s16209x,
# MtxOrb, NoritakeVFD, picolcd, pyramid, sed1330, sed1520, serialPOS,
# serialVFD, sli, stv5730, svga, t6963, text, tyan, ula200, xosd
Driver=curses
@@ -279,6 +279,7 @@ Keypad=yes
#keypad_test_mode=yes
## ea65 driver for the display in AOpen XC Cube AV EA65 media barebones ##
[ea65]
@@ -295,6 +296,7 @@ Brightness=500
OffBrightness=0
## EyeboxOne driver ##
[EyeboxOne]
@@ -329,6 +331,7 @@ EscapeKey=P
keypad_test_mode=no
## g15 driver for Logitech G15 Keyboard LCDs ##
[g15]
@@ -357,7 +360,6 @@ TextResolution=20x4
# path to font file to use
FontFile=/usr/share/fonts/corefonts/courbd.ttf
## these only apply if UseFT2=yes:
# character encoding to use
@@ -366,7 +368,6 @@ CharEncoding=iso8859-2
# minumum size in pixels in which fonts should be rendered
MinFontFaceSize=7x12
## optional:
Brightness=50 # Brightness (in %) if applicable
Contrast=50 # Contrast (in %) if applicable
@@ -709,6 +710,38 @@ Speed=9600
## Mini-box.com picoLCD (usblcd) driver ##
[picolcd]
# This is for the Mini-Box.com usblcd device that ships with the M300. It can
# also be purchased separately but this driver has only been tested on the M300
# setup.
# KeyTimeout is the time that LCDd spends waiting for a key press before cycling
# through other duties. Higher values make LCDd use less CPU time and make
# key presses more detectable. Lower values make LCDd more responsive but a
# little prone to missing key presses. 500 (.5 second) is the default and a
# balanced value.
KeyTimeout=500
# Contrast: [default: 1000; legal: 0 - 1000]
Contrast=1000
# Light the keys? i[default: on; legal: on, off]
Keylights=on
# If Keylights is on, the you can unlight specific keys below:
# Key0 is the directional pad. Key1 - Key5 correspond to the F1 - F5 keys.
# There is no LED for the +/- keys. This is a handy way to indicate to users
# which keys are disabled. [default: on; legal: on, off]
Key0Light=on
Key1Light=on
Key2Light=on
Key3Light=on
Key4Light=on
Key5Light=on
## Pyramid LCD driver ##
[pyramid]
+25 -6
View File
@@ -5,17 +5,18 @@ AC_ARG_ENABLE(drivers,
[ --enable-drivers=<list> compile drivers for LCDs in <list>,]
[ which is a comma-separated list of drivers.]
[ Possible drivers are:]
[ bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,ea65,EyeboxOne,]
[ g15,glcdlib,glk,hd44780,icp_a106,imon,IOWarrior,irman,]
[ joy,lb216,lcdm001,lcterm,lirc,MD8800,ms6931,mtc_s16209x,]
[ MtxOrb,NoritakeVFD,pyramid,sed1330,sed1520,serialPOS,]
[ serialVFD,sli,stv5730,svga,t6963,text,tyan,ula200,xosd]
[ bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,ea65,]
[ EyeboxOne,g15,glcdlib,glk,hd44780,icp_a106,imon,IOWarrior,]
[ irman,joy,lb216,lcdm001,lcterm,lirc,MD8800,ms6931,]
[ mtc_s16209x,MtxOrb,NoritakeVFD,picolcd,pyramid,sed1330]
[ sed1520,serialPOS,serialVFD,sli,stv5730,svga,t6963,text,]
[ tyan,ula200,xosd]
[ 'all' compiles all drivers;]
[ 'all,!xxx,!yyy' de-selects previously selected drivers],
drivers="$enableval",
drivers=[bayrad,CFontz,CFontz633,curses,CwLnx,glk,lb216,lcdm001,MtxOrb,pyramid,text])
allDrivers=[bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,ea65,EyeboxOne,g15,glcdlib,glk,hd44780,icp_a106,imon,IOWarrior,irman,joy,lb216,lcdm001,lcterm,lirc,MD8800,ms6931,mtc_s16209x,MtxOrb,NoritakeVFD,pyramid,sed1330,sed1520,serialPOS,serialVFD,sli,stv5730,svga,t6963,text,tyan,ula200,xosd]
allDrivers=[bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,ea65,EyeboxOne,g15,glcdlib,glk,hd44780,icp_a106,imon,IOWarrior,irman,joy,lb216,lcdm001,lcterm,lirc,MD8800,ms6931,mtc_s16209x,MtxOrb,NoritakeVFD,picolcd,pyramid,sed1330,sed1520,serialPOS,serialVFD,sli,stv5730,svga,t6963,text,tyan,ula200,xosd]
drivers=`echo $drivers | sed -e 's/,/ /g'`
@@ -275,6 +276,23 @@ dnl else
DRIVERS="$DRIVERS NoritakeVFD${SO}"
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])
])
;;
pyramid)
DRIVERS="$DRIVERS pyramid${SO}"
actdrivers=["$actdrivers pyramid"]
@@ -399,6 +417,7 @@ AC_SUBST(LIBG15)
AC_SUBST(LIBGLCD)
AC_SUBST(LIBFTDI)
AC_SUBST(LIBXOSD)
AC_SUBST(LIBUSBLCD)
])
+3
View File
@@ -195,6 +195,9 @@ Matrix Orbital displays (except Matrix Orbital GLK displays)
.B NoritakeVFD
Noritake VFD Device CU20045SCPB-T28A
.TP
.B picolcd
Mini-box.com USB LCD (picoLCD 20x2)
.TP
.B pyramid
LCD displays from Pyramid (http://www.pyramid.de)
.TP
+1
View File
@@ -33,6 +33,7 @@ well as the configuration of LCDd.
&mtc_s16209x;
&MtxOrb;
&NoritakeVFD;
&picolcd;
&pylcd;
&sed1330;
&sed1520;
+139
View File
@@ -0,0 +1,139 @@
<sect1 id="picolcd">
<title>The Mini-Box USB LCD (picoLCD 20x2) Driver (picolcd)</title>
<para>
This section covers the installation and use of the Mini-Box USB LCD (picoLCD
20x2) display.
</para>
<para>
The picoLCD page indicates that the device can be connected via I2C or USART.
This lcdproc driver, however, is limited to the USB connected model.
</para>
<sect2 id="picolcd-setup">
<title>Setting up the picoLCD</title>
<para>
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: http://www.mini-box.com/picoLCD-20x2-OEM. It may also
come pre-installed on systems like the Mini-Box M300:
http://www.mini-box.com/Mini-Box-M300-LCD.
</para>
<para>
Using the USB LCD with this driver requires the usblcd library from Mini-box.com
(avaiable at http://www.mini-box.com/picoLCD-20x2-OEM). 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.
</para>
<para>
Lastly, the usbfs file system must be mounted on /proc/bus/usb.
<code>mount -t usbfs usbfs /proc/bus/usb</code>
</para>
<para>
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.
</para>
<para>
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.
</para>
</sect2>
<sect2 id="picolcd-options">
<para>
Contrast: 0-1000. 0 is visible, and 1000 is not on my M300. Default is 0.
</para>
<para>
Keylights: 0/1. 0 turns off the key LEDs and 1 turns them on. Default is 1.
</para>
</sect2>
<sect2>
<para>
Key0Light: if Keylights is set to 1, you can disable the directional pad LED by
setting this value to 0. Default is 1.
</para>
</sect2>
<sect2>
<para>
Key1Light: if Keylights is set to 1, you can disable the F1 LED by setting this value
to 0. Default is 1.
</para>
</sect2>
<sect2>
<para>
Key2Light: if Keylights is set to 1, you can disable the F2 LED by setting this value
to 0. Default is 1.
</para>
</sect2>
<sect2>
<para>
Key3Light: if Keylights is set to 1, you can disable the F3 LED by setting this value
to 0. Default is 1.
</para>
</sect2>
<sect2>
<para>
Key4Light: if Keylights is set to 1, you can disable the F4 LED by setting this value
to 0. Default is 1.
</para>
</sect2>
<sect2>
<para>
Key5Light: if Keylights is set to 1, you can disable the F5 LED by setting this value
to 0. Default is 1.
</para>
</sect2>
<sect2>
<para>
KeyTimeout: (Advanced) This value controls how long LCDd waits for a key press when
get_key is called. The value represents microseconds and the default is 500 or .5
seconds. Lowering this value will make LCDd more responsive but also causes LCDd to use
more CPU time and, as the timeout grows shorter, key presses become harder to detect.
Larger values make key presses more reliable if somewhat slow to take effect.
</para>
</sect2>
<sect2 id="picolcd-status">
<title>picolcd driver status</title>
<para>
The lcdproc picolcd driver relies upon Mini-Box's usblcd library to setup the USB/HID
interface. Unfortunately the usblcd library is very thin and tends to put function
results on stdout/stderr instead of in return values. They (Mini-Box) really had
scripting interfaces in mind.
</para>
<para>
The primary example of this is that I had to write a replacement (get_key_events) for
usblcd's read_events so that I could get the key presses back to the calling function
instead of on stdout. usblcd also has a large number of function shells for which no
code exists yet. I am not an expert on HID and USB coding, but if and as time permits
and hardware is available I will try and improve this drivers access to the hardware in
order to get back data (get_contrast for example) and to potentially drive multiple
pcioLCDs at once (or pick the one we want out of many).
</para>
<para>
To sum up, this driver right now stabs and hopes since response data is lacking.
</para>
<para>
The hardware also reports key-up events. Normally this would be of no issue (they are
usually a 0 or 'no key') except that when keys are used in combonation, the key-up
event may actually come back as multiple events depending on how the user released the
keys. If the key-up event for a multiple key press comes back as two events, the first
up event will actually look like a new key press. The algorithm in get_key tries to
deal with this in a sane way and toss out all key-up events for now. The hardware is
touchy and both combo key-down and key-up actions may be reported as mutiple events if
the user is more than a tenth of a second (maybe less?) off in motions.
</para>
</sect2>
<sect2 id="picolcd-copy">
<title>Copyright</title>
<para>
The lcdproc picolcd driver was written by Gatewood Green (woody@nitrosecurity.com)
or (woody@linif.org) and paid for by NitroSecurity, Inc (nitrosecurity.com).
</para>
</sect2>
</sect1>
+3 -1
View File
@@ -19,7 +19,7 @@ AM_LDFLAGS = @LDSHARED@
#LIBS =
pkglib_PROGRAMS = @DRIVERS@
EXTRA_PROGRAMS = bayrad CFontz CFontz633 CFontzPacket curses CwLnx ea65 EyeboxOne g15 glcdlib glk hd44780 icp_a106 imon IOWarrior irman joy lb216 lcdm001 lcterm lirc MD8800 ms6931 mtc_s16209x MtxOrb NoritakeVFD pyramid sed1330 sed1520 serialPOS serialVFD stv5730 svga t6963 text tyan sli ula200 xosd
EXTRA_PROGRAMS = bayrad CFontz CFontz633 CFontzPacket curses CwLnx ea65 EyeboxOne g15 glcdlib glk hd44780 icp_a106 imon IOWarrior irman joy lb216 lcdm001 lcterm lirc MD8800 ms6931 mtc_s16209x MtxOrb NoritakeVFD picolcd pyramid sed1330 sed1520 serialPOS serialVFD stv5730 svga t6963 text tyan sli ula200 xosd
noinst_LIBRARIES = libLCD.a libbignum.a
IOWarrior_CFLAGS = @libusb_cflags@ $(AM_CFLAGS)
@@ -45,6 +45,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@
pyramid_LDADD = libLCD.a
serialPOS_LDADD = libLCD.a libbignum.a
serialVFD_LDADD = libLCD.a libbignum.a
@@ -86,6 +87,7 @@ ms6931_SOURCES = lcd.h lcd_lib.h ms6931.h ms6931.c report.h
mtc_s16209x_SOURCES = lcd.h lcd_lib.h mtc_s16209x.c mtc_s16209x.h report.h
MtxOrb_SOURCES = lcd.h lcd_lib.h MtxOrb.c MtxOrb.h report.h adv_bignum.h
NoritakeVFD_SOURCES = lcd.h lcd_lib.h NoritakeVFD.c NoritakeVFD.h report.h
picolcd_SOURCES = lcd.h picolcd.h picolcd.c report.h
pyramid_SOURCES = lcd.h pylcd.c pylcd.h
sed1330_SOURCES = lcd.h sed1330.h sed1330.c port.h lpt-port.h timing.h report.h
sed1520_SOURCES = lcd.h sed1520.c sed1520.h sed1520fm.c sed1520fm.h port.h report.h
+520
View File
@@ -0,0 +1,520 @@
/*
* picoLCD driver for lcdPROC
*
* (c) 2007 NitroSecurity, Inc.
* Written by Gatewood Green <woody@nitrosecurity.com> or <woody@linif.org>
*
* License: GPL (same as usblcd and lcdPROC)
*
* picoLCD: http://www.mini-box.com/picoLCD-20x2-OEM
* Can be purchased separately or preinstalled in units such as the
* M300 http://www.mini-box.com/Mini-Box-M300-LCD
*
* This driver (key lables and arrangement) is based on the M300 implementation
* 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).
*
* 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 "report.h"
/* These three includes are the Mini-box.com libusblcd (usblcd) and company. */
#include <usblcd.h>
#include <widgets.h>
#include <usblcd_util.h>
/* Various odds and ends */
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
/* This is a hack */
#define API_VERSION "0.5"
/* 12 keys plus a 0 placeholder */
#define KEYPAD_MAX 13
#define KEYPAD_LIGHTS 6
#define DEFAULT_CONTRAST 1000 /* Full */
#define DEFAULT_BACKLIGHT 1 /* On */
#define DEFAULT_KEYLIGHTS 1 /* On */
#define DEFAULT_TIMEOUT 500 /* Half second */
/* Set this to 1 and get lots of cruft on stderr when using "LCDd -f 1 -d picolcd" */
#define DEBUG_PICO 0
/* PrivateData struct */
typedef struct pd {
usblcd_operations *lcd; // Reference to the LCD instance
int width;
int height;
int key_timeout;
int contrast;
int backlight;
int keylights;
int key_light[KEYPAD_LIGHTS];
char *key_matrix[KEYPAD_MAX];
char *info;
unsigned char *framebuf;
unsigned char *lstframe;
} PrivateData;
static char * keymap[KEYPAD_MAX] = {
NULL,
"Plus",
"Minus",
"F1",
"F2",
"F3",
"F4",
"F5",
"Left",
"Right",
"Up",
"Down",
"Enter"
};
/* 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 );
/* lcd_logical_driver Variables */
MODULE_EXPORT char *api_version = API_VERSION;
MODULE_EXPORT int stay_in_foreground = 0;
MODULE_EXPORT int supports_multiple = 1;
MODULE_EXPORT char *symbol_prefix = "picoLCD_";
/* lcd_logical_driver Manditory functions */
MODULE_EXPORT int picoLCD_init( Driver *drvthis ) {
PrivateData *pd;
int x;
pd = ( PrivateData * ) malloc( sizeof( PrivateData ) );
if ( ! pd )
return -1;
if ( drvthis->store_private_ptr( drvthis, pd ) )
return -1;
pd->lcd = new_usblcd_operations();
pd->lcd->init( pd->lcd );
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) ";
for ( x = 0; x < KEYPAD_LIGHTS; x++ )
pd->key_light[x] = 1; /* individual lights on */
pd->contrast = drvthis->config_get_int( drvthis->name, "Contrast", 0, DEFAULT_CONTRAST );
pd->backlight = drvthis->config_get_bool( drvthis->name, "BackLight", 0, DEFAULT_BACKLIGHT );
pd->keylights = drvthis->config_get_bool( drvthis->name, "KeyLights", 0, DEFAULT_KEYLIGHTS ); /* key lights with LCD Backlight? */
pd->key_timeout = drvthis->config_get_int( drvthis->name, "KeyTimeout", 0, DEFAULT_TIMEOUT );
/* These allow individual lights to be disabled */
pd->key_light[0] = drvthis->config_get_bool( drvthis->name, "Key0Light", 0, 1 ); /* Directional PAD */
pd->key_light[1] = drvthis->config_get_bool( drvthis->name, "Key1Light", 0, 1 ); /* F1 */
pd->key_light[2] = drvthis->config_get_bool( drvthis->name, "Key2Light", 0, 1 ); /* F2 */
pd->key_light[3] = drvthis->config_get_bool( drvthis->name, "Key3Light", 0, 1 ); /* F3 */
pd->key_light[4] = drvthis->config_get_bool( drvthis->name, "Key4Light", 0, 1 ); /* F4 */
pd->key_light[5] = drvthis->config_get_bool( drvthis->name, "Key5Light", 0, 1 ); /* F5 */
for ( x = 0; x < KEYPAD_MAX; x++ )
pd->key_matrix[x] = keymap[x];
pd->framebuf = ( unsigned char * ) malloc( pd->width * pd->height + 1 );
if ( pd->framebuf == NULL ) {
report( RPT_ERR, "%s: unable to create framebuf.\n", __FUNCTION__ );
return -1;
}
memset( pd->framebuf, ' ', pd->width * pd->height );
pd->framebuf[pd->width * pd->height] = 0;
pd->lstframe = ( unsigned char * ) malloc( pd->width * pd->height + 1 );
if ( pd->lstframe == NULL ) {
report( RPT_ERR, "%s: unable to create lstframe.\n", __FUNCTION__ );
return -1;
}
memset( pd->lstframe, ' ', pd->width * pd->height );
pd->lstframe[pd->width * pd->height] = 0;
if ( pd->backlight )
picoLCD_backlight( drvthis, 1 );
if ( ! pd->keylights )
set_key_lights( pd->lcd, pd->key_light, 0 );
else
picoLCD_backlight( drvthis, 0 );
picoLCD_set_contrast( drvthis, pd->contrast );
report( RPT_INFO, "picolcd: init complete\n", __FUNCTION__ );
if ( DEBUG_PICO )
fprintf( stderr, "picolcd: init complete\n" );
return 0;
}
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?) */
if ( DEBUG_PICO )
fprintf( stderr, "picolcd: close complete\n" );
}
/* lcd_logical_driver Essential output functions */
MODULE_EXPORT int picoLCD_width( Driver *drvthis ) {
PrivateData *pd = drvthis->private_data;
return pd->width;
}
MODULE_EXPORT int picoLCD_height( Driver *drvthis ) {
PrivateData *pd = drvthis->private_data;
return pd->height;
}
MODULE_EXPORT void picoLCD_clear( Driver *drvthis ) {
PrivateData *pd = drvthis->private_data;
memset( pd->framebuf, ' ', pd->width * pd->height );
if ( DEBUG_PICO )
fprintf( stderr, "picolcd: clear complete\n" );
}
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];
int i, line, offset;
if ( DEBUG_PICO )
fprintf( stderr, "picolcd: flush started\n" );
for ( line = 0; line < pd->height; line++ ) {
memset( text, 0, 48 );
offset = line * pd->width;
fb = pd->framebuf + offset;
lf = pd->lstframe + offset;
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 );
memcpy( pd->lstframe + offset, pd->framebuf + offset, pd->width );
if ( DEBUG_PICO )
fprintf( stderr, "picolcd: flush wrote line %d (%s)\n", line + 1, text );
break;
}
}
}
if ( DEBUG_PICO )
fprintf( stderr, "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 ) {
PrivateData *pd = drvthis->private_data;
char *dest;
int len;
if ( DEBUG_PICO )
fprintf( stderr, "picolcd: string start (%s)\n", str );
if ( y < 1 || y > pd->height )
return;
if ( x < 1 || x > pd->width )
return;
len = strlen( str );
if ( len + x > pd->width ) {
if ( DEBUG_PICO )
fprintf( stderr, "picolcd: string overlength (>%d). Start: %d Length: %d (%s)\n", pd->width, x, len ,str );
len = pd->width - x; /* Copy what we can */
}
x--; y--; /* Convert 1-based to 0-based */
dest = pd->framebuf + ( y * pd->width + x );
memcpy( dest, str, len * sizeof(char) );
if ( DEBUG_PICO )
fprintf( stderr, "picolcd: string complete (%s)\n", str );
}
MODULE_EXPORT void picoLCD_chr( Driver *drvthis, int x, int y, char chr ) {
PrivateData *pd = drvthis->private_data;
char *dest;
if ( DEBUG_PICO )
fprintf( stderr, "picolcd: chr start (%c)\n", chr );
if ( y < 1 || y > pd->height )
return;
if ( x < 1 || x > pd->width )
return;
x--; y--; /* Convert 1-based to 0-based */
dest = pd->framebuf + ( y * pd->width + x );
memcpy( dest, &chr, sizeof(char) );
if ( DEBUG_PICO )
fprintf( stderr, "picolcd: chr complete (%c)\n", chr );
}
/* lcd_logical_driver Essential input functions */
MODULE_EXPORT char *picoLCD_get_key( Driver *drvthis ) {
PrivateData *pd = drvthis->private_data;
lcd_packet *keydata;
char *keystr;
int keys_read = 0;
int key_pass = 0;
int two_keys = 0;
if ( DEBUG_PICO )
fprintf( stderr, "picolcd: get_key start (timeout %d)\n", pd->key_timeout );
keydata = malloc( sizeof( lcd_packet ) );
while ( ! keys_read ) {
get_key_event( pd->lcd, keydata, pd->key_timeout );
if ( DEBUG_PICO )
fprintf( stderr, "picolcd: get_key got an event\n" );
if ( keydata->type == IN_REPORT_KEY_STATE ) {
if ( ! keydata->data[1] && key_pass ) {
if ( DEBUG_PICO )
fprintf( stderr, "picolcd: get_key got all clear\n" );
/* Got a <0, 0> key-up event after reading a valid key press event */
keys_read++; /* All clear */
} else if ( ! keydata->data[2] && ! two_keys ) {
if ( DEBUG_PICO )
fprintf( stderr, "picolcd: get_key got one key\n" );
/* We got one key (but not after a two key event and before and all clear) */
keystr = pd->key_matrix[keydata->data[1]];
} else {
/* We got two keys */
if ( DEBUG_PICO )
fprintf( stderr, "picolcd: get_key got two keys\n" );
two_keys++;
sprintf( keystr, "%s+%s", pd->key_matrix[keydata->data[1]], pd->key_matrix[keydata->data[2]] );
}
key_pass++; /* This hack allows us to deal with receiving left over <0,0> first */
} else {
if ( DEBUG_PICO )
fprintf( stderr, "picolcd: get_key got non-key data or timeout\n" );
/* We got IR or otherwise bad data */
return NULL;
}
}
free( keydata );
if ( DEBUG_PICO )
fprintf( stderr, "picolcd: get_key complete (%s)\n", keystr );
if ( ! strlen( keystr ) )
return NULL;
return keystr;
/*
* Due to how key events are reported, we need to keep reading key presses
* until we get the all clear (all keys up) event.
*
* Key events come back in such a way to report up to two simultanious keys
* pressed. The highest numbered key always comes back as the first key and
* the lower numbered key follows. If only one key was pressed, the second
* key is 0. I will refer to a key event as: <high key, low key>.
*
* Key ID numbers:
* 0 = (no key)
* 1 = + (plus)
* 2 = - (minus)
* 3 = F1
* 4 = F2
* 5 = F3
* 6 = F4
* 7 = F5
* 8 = Left
* 9 = Right
* 10 = Up
* 11 = Down
* 12 = Enter
*
* The picoLCD also sends key-up events.
*
* On a single key press, the return is <keynum, 0>. The key-up event is a
* read that returns <0, 0> (all clear). On a dual key press, if one key is
* released later than the other key, the first key-up event is
* <remainingkey, 0>. This will be followed by a final "all clear" key-up
* <0, 0>. If both keys are release simultaniously, then after <hk, lk>,
* you will receive <0, 0>. If the keys are pressed down in a staggard
* fashion, you will receive <first key, 0> followed by <hk, lk> followed by
* key-up events as already detailed.
*
* What this means is that we need to keep reading key presses until we get
* the <0, 0> all clear.
*/
}
/* lcd_logical_driver Extended output functions */
/* lcd_logical_driver User-defined character functions */
/* lcd_logical_driver Hardware functions */
/*MODULE_EXPORT int picoLCD_get_contrast( Driver *drvthis ) {
PrivateData *pd = drvthis->private_data;
}*/
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 */
if ( promille <= 1000 && promille > 0 ) {
inv = 1000 - promille;
pd->lcd->contrast( pd->lcd, ( int ) ( inv / 1000 * 40 ) );
return 0;
} else if ( promille > 1000 ) {
pd->lcd->contrast( pd->lcd, 0 );
return 0;
} else if ( promille <= 0 ) {
pd->lcd->contrast( pd->lcd, 40 );
return 0;
} else {
return -1;
}
}
/*MODULE_EXPORT int picoLCD_get_brightness( Driver *drvthis, int state ) {
PrivateData *pd = drvthis->private_data;
}*/
/*MODULE_EXPORT int picoLCD_set_brightness( Driver *drvthis, int state, int promille ) {
PrivateData *pd = drvthis->private_data;
}*/
MODULE_EXPORT void picoLCD_backlight( Driver *drvthis, int state ) {
PrivateData *pd = drvthis->private_data;
if ( state == 0 ) {
pd->lcd->backlight( pd->lcd, state );
set_key_lights( pd->lcd, pd->key_light, state );
return;
}
if ( state == 1 ) {
pd->lcd->backlight( pd->lcd, state );
if ( pd->keylights )
set_key_lights( pd->lcd, pd->key_light, state );
return;
}
return;
}
/*MODULE_EXPORT int picoLCD_output( Driver *drvthis, int state ) {
PrivateData *pd = drvthis->private_data;
}*/
/* lcd_logical_driver Informational functions */
MODULE_EXPORT char *picoLCD_get_info( Driver *drvthis ) {
PrivateData *pd = drvthis->private_data;
return pd->info;
}
/* Private functions */
void get_key_event ( usblcd_operations *self, 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 );
if ( ret > 0 ) {
switch ( packet->data[0] ) {
case IN_REPORT_KEY_STATE: {
packet->type = IN_REPORT_KEY_STATE;
} break;
case IN_REPORT_IR_DATA: {
packet->type = IN_REPORT_IR_DATA;
} break;
default: {
packet->type = 0;
}
}
}
}
void set_key_lights ( usblcd_operations *self, int keys[], int state ) {
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 );
} 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 );
}
}
+56
View File
@@ -0,0 +1,56 @@
/*
* Driver for picoLCD graphical displays
* Header file
*
* (c) 2007 NitroSecurity, Inc.
* Written by Gatewood Green <woody@nitrosecurity.com> or <woody@linif.org>
*
* License: GPL (same as usblcd and lcdPROC)
*
* picoLCD: http://www.mini-box.com/picoLCD-20x2-OEM
* Can be purchased separately or preinstalled in units such as the
* M300 http://www.mini-box.com/Mini-Box-M300-LCD
*
* See picolcd.c for full details
*
*/
#ifndef PICOLCD_H
#define PCIOLCD_H
#include "lcd.h"
typedef struct _lcd_packet lcd_packet;
struct _lcd_packet {
unsigned char data[255];
unsigned int type;
};
MODULE_EXPORT int picoLCD_init ( Driver *drvthis );
MODULE_EXPORT void picoLCD_close ( Driver *drvthis );
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 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 int picoLCD_get_contrast ( Driver *drvthis );
MODULE_EXPORT int picoLCD_set_contrast ( Driver *drvthis, int promille );
//MODULE_EXPORT int picoLCD_get_brightness ( Driver *drvthis, int state );
//MODULE_EXPORT int picoLCD_set_brightness ( Driver *drvthis, int state, int promille );
MODULE_EXPORT void picoLCD_backlight ( Driver *drvthis, int promille );
//MODULE_EXPORT void picoLCD_output ( Driver *drvthis, int state );
MODULE_EXPORT char *picoLCD_get_info ( Driver *drvthis );
#endif