picolcd - driver for Mini-box.com USB LCD picoLCD (Gatewood Green)
This commit is contained in:
@@ -220,6 +220,9 @@ Frank Jepsen
|
||||
Karsten Festag
|
||||
- ea65 driver
|
||||
|
||||
Gatewood Green
|
||||
- picolcd driver
|
||||
|
||||
|
||||
Further developers in the sourceforge lcdproc team:
|
||||
Mindaugas Idzelis aim4min
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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)
|
||||
])
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -33,6 +33,7 @@ well as the configuration of LCDd.
|
||||
&mtc_s16209x;
|
||||
&MtxOrb;
|
||||
&NoritakeVFD;
|
||||
&picolcd;
|
||||
&pylcd;
|
||||
&sed1330;
|
||||
&sed1520;
|
||||
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user