From e340911d0c60de427c9b29f0286da4bc07089faf Mon Sep 17 00:00:00 2001 From: marschap Date: Sun, 18 Mar 2007 12:37:41 +0000 Subject: [PATCH] ea65 - driver for VFD in AOpen XC Cube AV EA65 barebones (Karsten ) --- CREDITS | 3 + ChangeLog | 1 + LCDd.conf | 37 ++- acinclude.m4 | 8 +- docs/LCDd.8.in | 3 + docs/lcdproc-user/drivers.docbook | 1 + docs/lcdproc-user/lcdproc-user.docbook | 1 + server/drivers/Makefile.am | 3 +- server/drivers/ea65.c | 318 +++++++++++++++++++++++++ server/drivers/ea65.h | 21 ++ 10 files changed, 382 insertions(+), 14 deletions(-) create mode 100644 server/drivers/ea65.c create mode 100644 server/drivers/ea65.h diff --git a/CREDITS b/CREDITS index 930a006..bc2765f 100644 --- a/CREDITS +++ b/CREDITS @@ -217,6 +217,9 @@ Frank Jepsen - vdr-wakeup support in hd44780 driver (originally for v0.4.5) - new options for the hd44780 driver +Karsten + - ea65 driver + Further developers in the sourceforge lcdproc team: Mindaugas Idzelis aim4min diff --git a/ChangeLog b/ChangeLog index f312300..ff13b3b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -33,6 +33,7 @@ v.0.5dev (ongoing development) + new driver for text based serial Point of Sale displays (Eric Pooch) + 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 ) v.0.5.1 + config file support in lcdproc client (Andrew Foss) diff --git a/LCDd.conf b/LCDd.conf index 04506ad..5eeec9e 100644 --- a/LCDd.conf +++ b/LCDd.conf @@ -279,6 +279,21 @@ Keypad=yes #keypad_test_mode=yes +## ea65 driver for the display in AOpen XC Cube AV EA65 media barebones ## +[ea65] + +# Device is fixed /dev/ttyS1 +# Width and Height are fixed 9x1 + +# As the VFD is self luminescent we don't have a backlight +# But we can use the backlight functions to control the front LEDs +# Brightness 0 to 299 -> LEDs off +# Brightness 300 to 699 -> LEDs half bright +# Brightness 700 to 1000 -> LEDs full bright +Brightness=500 +# OffBrightness is the the value used for the 'backlight off' state +OffBrightness=0 + ## EyeboxOne driver ## [EyeboxOne] @@ -353,17 +368,17 @@ MinFontFaceSize=7x12 ## optional: -Brightness=50 # Brightness (in %) if applicable -Contrast=50 # Contrast (in %) if applicable -Backlight=no # Backlight if applicable -UpsideDown=no # flip image upside down -Invert=no # invert light/dark pixels -ShowDebugFrame=no # turns on/off 1 pixel thick debugging - # border whithin the usable text area, - # for setting up TextResolution and - # MinFontFaceSize (if using FT2); -ShowBigBorder=no # border around the unused area -ShowThinBorder=yes # border around the unused area +Brightness=50 # Brightness (in %) if applicable +Contrast=50 # Contrast (in %) if applicable +Backlight=no # Backlight if applicable +UpsideDown=no # flip image upside down +Invert=no # invert light/dark pixels +ShowDebugFrame=no # turns on/off 1 pixel thick debugging + # border whithin the usable text area, + # for setting up TextResolution and + # MinFontFaceSize (if using FT2); +ShowBigBorder=no # border around the unused area +ShowThinBorder=yes # border around the unused area PixelShiftX=0 PixelShiftY=2 diff --git a/acinclude.m4 b/acinclude.m4 index a468c08..88b71a9 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -5,7 +5,7 @@ AC_ARG_ENABLE(drivers, [ --enable-drivers= compile drivers for LCDs in ,] [ which is a comma-separated list of drivers.] [ Possible drivers are:] - [ bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,EyeboxOne,] + [ 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,] @@ -15,7 +15,7 @@ AC_ARG_ENABLE(drivers, drivers="$enableval", drivers=[bayrad,CFontz,CFontz633,curses,CwLnx,glk,lb216,lcdm001,MtxOrb,pyramid,text]) -allDrivers=[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,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,pyramid,sed1330,sed1520,serialPOS,serialVFD,sli,stv5730,svga,t6963,text,tyan,ula200,xosd] drivers=`echo $drivers | sed -e 's/,/ /g'` @@ -124,6 +124,10 @@ dnl else DRIVERS="$DRIVERS CwLnx${SO}" actdrivers=["$actdrivers CwLnx"] ;; + ea65) + DRIVERS="$DRIVERS ea65${SO}" + actdrivers=["$actdrivers ea65"] + ;; EyeboxOne) DRIVERS="$DRIVERS EyeboxOne${SO}" actdrivers=["$actdrivers EyeboxOne"] diff --git a/docs/LCDd.8.in b/docs/LCDd.8.in index 8fed163..5a4a5f8 100644 --- a/docs/LCDd.8.in +++ b/docs/LCDd.8.in @@ -99,6 +99,9 @@ Standard video display using the (n)curses library .B CwLnx serial/USB displays by Cwlinux (http://www.cwlinux.com) .TP +.B ea65 +VFD front panel display on Aopen XC Cube EA65 media barebone +.TP .B EyeboxOne LCD display on the EyeboxOne (http://www.rightvision.com) .TP diff --git a/docs/lcdproc-user/drivers.docbook b/docs/lcdproc-user/drivers.docbook index 3c428ed..7a6cdb4 100644 --- a/docs/lcdproc-user/drivers.docbook +++ b/docs/lcdproc-user/drivers.docbook @@ -13,6 +13,7 @@ well as the configuration of LCDd. &CFontzPacket; &curses; &CwLnx; +&ea65; &EyeboxOne; &g15; &glcdlib; diff --git a/docs/lcdproc-user/lcdproc-user.docbook b/docs/lcdproc-user/lcdproc-user.docbook index 518a18e..70cf007 100644 --- a/docs/lcdproc-user/lcdproc-user.docbook +++ b/docs/lcdproc-user/lcdproc-user.docbook @@ -19,6 +19,7 @@ + diff --git a/server/drivers/Makefile.am b/server/drivers/Makefile.am index c0c67d8..41eb3a2 100644 --- a/server/drivers/Makefile.am +++ b/server/drivers/Makefile.am @@ -19,7 +19,7 @@ AM_LDFLAGS = @LDSHARED@ #LIBS = pkglib_PROGRAMS = @DRIVERS@ -EXTRA_PROGRAMS = 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 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 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) @@ -64,6 +64,7 @@ CFontz633_SOURCES = lcd.h lcd_lib.h CFontz633.c CFontz633.h CFontz-charmap.h CF CFontzPacket_SOURCES = lcd.h lcd_lib.h CFontzPacket.c CFontzPacket.h CFontz-charmap.h CFontz633io.c CFontz633io.h report.h adv_bignum.h curses_SOURCES = lcd.h curses_drv.h curses_drv.c report.h CwLnx_SOURCES = lcd.h lcd_lib.h CwLnx.c CwLnx.h report.h +ea65_SOURCES = lcd.h ea65.h ea65.c report.h EyeboxOne_SOURCES = lcd.h lcd_lib.h EyeboxOne.c EyeboxOne.h report.h g15_SOURCES = lcd.h lcd_lib.h g15.h g15-num.c g15.c report.h glcdlib_SOURCES = lcd.h lcd_lib.h glcdlib.h glcdlib.c report.h diff --git a/server/drivers/ea65.c b/server/drivers/ea65.c new file mode 100644 index 0000000..c69cfc9 --- /dev/null +++ b/server/drivers/ea65.c @@ -0,0 +1,318 @@ +/* This is the LCDproc driver for the vfd on the Aopen EA65, based on + the Crystal Fontz driver. + + Copyright (C) 2004 ???? + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 */ + +/*Initial modification of CFontz driver by Kent Williams (c) 2005*/ +/*some additions and updates by Karsten Festag (c) 2007*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "lcd.h" +#include "ea65.h" +#include "report.h" +#include "lcd_lib.h" + +typedef struct driver_private_data { + int fd; + int brightness; + int offbrightness; + int width; + int height; + unsigned char *framebuf; +} PrivateData; + +// Vars for the server core +MODULE_EXPORT char *api_version = API_VERSION; +MODULE_EXPORT int stay_in_foreground = 1; +MODULE_EXPORT int supports_multiple = 0; +MODULE_EXPORT int does_input = 0; +MODULE_EXPORT int does_output = 1; +MODULE_EXPORT char *symbol_prefix = "EA65_"; + +///////////////////////////////////////////////////////////////// +// Opens com port and sets baud correctly... +// +MODULE_EXPORT int +EA65_init (Driver * drvthis) +{ + debug(RPT_INFO, "EA65: init(%p)", drvthis); + + /* device is fixed */ + char device[] = "/dev/ttyS1"; + /*speed is fixed at 9600*/ + int speed = B9600; + + /* Allocate and store private data */ + PrivateData *p; + p = (PrivateData *) malloc(sizeof(PrivateData)); + if (p == NULL) + return -1; + if (drvthis->store_private_ptr(drvthis, p)) + return -1; + + //// initialize private data + // Width and Height are fixed + p->width = 9; + p->height = 1; + // Make sure the frame buffer is there... + p->framebuf = (unsigned char *) malloc (p->width * p->height); + memset (p->framebuf, ' ', p->width * p->height); + + //// Read config file + // Which backlight brightness + p->brightness = drvthis->config_get_int ( drvthis->name , "Brightness" , 0 , DEFAULT_BRIGHTNESS); + if (0 <= p->brightness && p->brightness <= 1000) { + if (p->brightness < 300) { + p->brightness = 0x00; // command char that turns button LEDs off + } else if (p->brightness >= 700 ) { + p->brightness = 0x01; // command char that turns button LEDs on full + } else { + p->brightness = 0x02; // command char that turns button LEDs on half + } + } else { + report (RPT_WARNING, "EA65_init: Brightness must be between 0 and 1000. Using default value.\n"); + p->brightness = DEFAULT_BRIGHTNESS; + } + + // Which backlight-off "brightness" + p->offbrightness = drvthis->config_get_int ( drvthis->name , "OffBrightness" , 0 , DEFAULT_OFFBRIGHTNESS); + if (0 <= p->offbrightness && p->offbrightness <= 1000) { + if (p->offbrightness < 300) { + p->offbrightness = 0x00; // command char that turns button LEDs off + } else if (p->offbrightness >= 700) { + p->offbrightness = 0x01; // command char that turns button LEDs on full + } else { + p->offbrightness = 0x02; // command char that turns button LEDs on half + } + } else { + report (RPT_WARNING, "EA65_init: OffBrightness must be between 0 and 1000. Using default value.\n"); + p->offbrightness = DEFAULT_OFFBRIGHTNESS; + } + + // Set up io port correctly, and open it... + debug( RPT_DEBUG, "EA65: Opening serial device: %s", device); + struct termios portset; + p->fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY); + if (p->fd == -1) { + report (RPT_ERR, "EA65_init: failed (%s)\n", strerror (errno)); + return -1; + } + tcgetattr (p->fd, &portset); + +#ifdef HAVE_CFMAKERAW + // The easy way + cfmakeraw( &portset ); +#else + // The hard way + portset.c_iflag &= ~( IGNBRK | BRKINT | PARMRK | ISTRIP + | INLCR | IGNCR | ICRNL | IXON ); + portset.c_oflag &= ~OPOST; + portset.c_lflag &= ~( ECHO | ECHONL | ICANON | ISIG | IEXTEN ); + portset.c_cflag &= ~( CSIZE | PARENB | CRTSCTS ); + portset.c_cflag |= CS8 | CREAD | CLOCAL ; +#endif + + // Set port speed + cfsetospeed (&portset, speed); + cfsetispeed (&portset, B0); + + // Do it... + tcsetattr (p->fd, TCSANOW, &portset); + + report (RPT_DEBUG, "EA65_init: done\n"); + + return 0; +} + +///////////////////////////////////////////////////////////////// +// Clean-up +// +MODULE_EXPORT void +EA65_close (Driver *drvthis) +{ + PrivateData *p = (PrivateData *) drvthis->private_data; + + close (p->fd); + + if(p->framebuf) free (p->framebuf); + p->framebuf = NULL; +} + +///////////////////////////////////////////////////////////////// +// Returns the display width +// +MODULE_EXPORT int +EA65_width (Driver *drvthis) +{ + PrivateData *p = (PrivateData *) drvthis->private_data; + + return p->width; +} + +///////////////////////////////////////////////////////////////// +// Returns the display height +// +MODULE_EXPORT int +EA65_height (Driver *drvthis) +{ + PrivateData *p = (PrivateData *) drvthis->private_data; + + return p->height; +} + +////////////////////////////////////////////////////////////////// +// Flushes all output to the lcd... +// +MODULE_EXPORT void +EA65_flush (Driver *drvthis) +{ + char out[6]; + int i; + PrivateData *p = (PrivateData *) drvthis->private_data; + + // Need to check for and deal with unsupported chars or the display gets a little upset + for (i=0; i < p->width * p->height; i++) { + if ( (p->framebuf[i] >= 224 && p->framebuf[i] <= 253) || // is a lowercase accented letter + (p->framebuf[i] >= 97 && p->framebuf[i] <= 122) ) { // is a lowercase letter + p->framebuf[i] -= 32; // -> convert to upper case + } + if (p->framebuf[i] >= 48 && p->framebuf[i] <= 57) { } // is a number -> do nothing + else if (p->framebuf[i] >= 65 && p->framebuf[i] <= 90) { } // is a uppercase letter -> do nothing + else if (p->framebuf[i] == 42 || p->framebuf[i] == 43 || + p->framebuf[i] == 45 || p->framebuf[i] == 47 ) { } // is +,-,/,* -> do nothing + // Now lets replace some accented characters with remotely similar looking ones + else if (p->framebuf[i] == 223) p->framebuf[i] = 83; // use an "S" instead of "ß" + else if (p->framebuf[i] >= 192 && p->framebuf[i] <= 197) // use an "A" + p->framebuf[i] = 65; + else if (p->framebuf[i] >= 200 && p->framebuf[i] <= 203) // use an "E" + p->framebuf[i] = 69; + else if (p->framebuf[i] >= 204 && p->framebuf[i] <= 207) // use an "I" + p->framebuf[i] = 73; + else if (p->framebuf[i] >= 210 && p->framebuf[i] <= 214) // use an "O" + p->framebuf[i] = 79; + else if (p->framebuf[i] >= 217 && p->framebuf[i] <= 220) // use an "U" + p->framebuf[i] = 85; + else p->framebuf[i] = 32; // other characters replaced by a space + } + snprintf(out, sizeof(out), "%c%c%c%c%c", 0xa0, 0x00, 0x80, 0x8a, 0x8a); + write(p->fd, out, 5); + write(p->fd, p->framebuf, p->width * p->height); +} + +///////////////////////////////////////////////////////////////// +// Prints a character on the lcd display, at position (x,y). The +// upper-left is (1,1), and the lower right should be (9,1). +// +MODULE_EXPORT void +EA65_chr (Driver * drvthis, int x, int y, char c) +{ + PrivateData *p = (PrivateData *) drvthis->private_data; + + y--; + x--; + + //if (c < 32 && c >= 0) + // c += 128; + + // For V2 of the firmware to get the block to display right + //if (newfirmware && c==-1) { + // c=214; + //} + + p->framebuf[(y * p->width) + x] = c; +} + +///////////////////////////////////////////////////////////////// +// Sets the backlight on or off +// +MODULE_EXPORT void +EA65_backlight (Driver * drvthis, int on) +{ + PrivateData *p = (PrivateData *) drvthis->private_data; + + char out[6]; + if (on) { + snprintf (out, sizeof(out), "%c%c%c%c%c", 0xa0, 0x00, 0x50, 0x81, p->brightness); + } else { + snprintf (out, sizeof(out), "%c%c%c%c%c", 0xa0, 0x00, 0x50, 0x81, p->offbrightness); + } + write (p->fd, out, 5); +} + +///////////////////////////////////////////////////////////////// +// Clears the LCD screen +// +MODULE_EXPORT void +EA65_clear (Driver * drvthis) +{ + PrivateData *p = (PrivateData *) drvthis->private_data; + + memset (p->framebuf, ' ', p->width * p->height); + +} + +///////////////////////////////////////////////////////////////// +// Prints a string on the lcd display, at position (x,y). The +// upper-left is (1,1), and the lower right should be (9,1). +// +MODULE_EXPORT void +EA65_string (Driver * drvthis, int x, int y, char string[]) +{ + PrivateData *p = (PrivateData *) drvthis->private_data; + + int i; + + x -= 1; // Convert 1-based coords to 0-based... + y -= 1; + + for (i = 0; string[i]; i++) { + + // Check for buffer overflows... + if ((y * p->width) + x + i > (p->width * p->height)) + break; + p->framebuf[(y * p->width) + x + i] = string[i]; + } +} + +///////////////////////////////////////////////////////////////// +//// Turns the recording LED on or off as desired. +//// +MODULE_EXPORT void +EA65_output (Driver * drvthis, int on) +{ + PrivateData *p = (PrivateData *) drvthis->private_data; + + char out[6]; + if (on) { + snprintf (out, sizeof(out), "%c%c%c%c%c", 0xa0,0x00,0x32,0x81,0x01); + } else { + snprintf (out, sizeof(out), "%c%c%c%c%c", 0xa0,0x00,0x32,0x81,0x00); + } + write (p->fd, out, 5); +} diff --git a/server/drivers/ea65.h b/server/drivers/ea65.h new file mode 100644 index 0000000..8ae1594 --- /dev/null +++ b/server/drivers/ea65.h @@ -0,0 +1,21 @@ +#ifndef EA65_H +#define EA65_H + +#include "lcd.h" + +#define DEFAULT_BRIGHTNESS 500 +#define DEFAULT_OFFBRIGHTNESS 0 + +MODULE_EXPORT int EA65_init (Driver * drvthis); +MODULE_EXPORT void EA65_close (Driver * drvthis); +MODULE_EXPORT int EA65_width (Driver * drvthis); +MODULE_EXPORT int EA65_height (Driver * drvthis); +MODULE_EXPORT void EA65_clear (Driver * drvthis); +MODULE_EXPORT void EA65_flush (Driver * drvthis); +MODULE_EXPORT void EA65_string (Driver * drvthis, int x, int y, char string[]); +MODULE_EXPORT void EA65_chr (Driver * drvthis, int x, int y, char c); + +MODULE_EXPORT void EA65_brightness (Driver * drvthis, int promille); +MODULE_EXPORT void EA65_output (Driver * drvthis, int on); + +#endif