From 4d60c5b73c1b02493a1b4dddcc8b19323bd8f8e7 Mon Sep 17 00:00:00 2001 From: marschap Date: Fri, 3 Feb 2006 19:17:01 +0000 Subject: [PATCH] add serialVFD driver provided by Stefan Herdler --- LCDd.conf | 57 +- acinclude.m4 | 10 +- docs/README.serialVFD | 113 ++++ server/drivers/Makefile.am | 7 +- server/drivers/adv_bignum.c | 986 ++++++++++++++++++++++++++++ server/drivers/adv_bignum.h | 34 + server/drivers/serialVFD.c | 1201 +++++++++++++++++++++++++++++++++++ server/drivers/serialVFD.h | 70 ++ 8 files changed, 2461 insertions(+), 17 deletions(-) create mode 100644 docs/README.serialVFD create mode 100644 server/drivers/adv_bignum.c create mode 100644 server/drivers/adv_bignum.h create mode 100644 server/drivers/serialVFD.c create mode 100644 server/drivers/serialVFD.h diff --git a/LCDd.conf b/LCDd.conf index b239c05..d8b102e 100644 --- a/LCDd.conf +++ b/LCDd.conf @@ -41,6 +41,7 @@ Driver=CFontzPacket #Driver=glcdlib #Driver=imon #Driver=NoritakeVFD +#Driver=serialVFD # Tells the driver to bind to the given interface Bind=127.0.0.1 @@ -350,18 +351,6 @@ KeyMatrix_4_3=Down KeyMatrix_4_4=Escape -## Noritake VFD driver ## -[NoritakeVFD] -# Port where the VFD is. Usual values are /dev/ttyS0 and /dev/ttyS1 -Device=/dev/ttyS0 - -# Specifies the size of the LCD. -Size=20x4 - -Contrast=255 -# set the serial port speed [default: 9600] -Speed=9600 - ## ICP A106 driver ## [icp_a106] @@ -539,6 +528,20 @@ keypad_test_mode=no +## Noritake VFD driver ## +[NoritakeVFD] +# Port where the VFD is. Usual values are /dev/ttyS0 and /dev/ttyS1 +Device=/dev/ttyS0 + +# Specifies the size of the LCD. +Size=20x4 + +Contrast=255 +# set the serial port speed [default: 9600] +Speed=9600 + + + ## Pyramid pylcd driver ## [pylcd] @@ -566,6 +569,36 @@ Port=0x378 +## Serial VFD driver ## +## Drives various (see below) serial 5x7dot VFD's. ## +[serialVFD] +# Port where the VFD is. Usual values are /dev/ttyS0 and /dev/ttyS1 +Device=/dev/ttyS1 + +# Specifies the size of the VFD. +Size=20x2 + +# Specifies the displaytype.[default: 0] +# 0 NEC (FIPC8367 based) VFDs. +# 1 KD Rev 2.1. +# 2 Noritake VFDs (*). +# 3 Futaba VFDs (*). +# (* most should work, not testet yet.) +Displaytype=1 + +# Display brightness [default: 255]. +# 0 min ... 255 max ... 1000 also max +# (4 steps 0-64, 65-128, 129-192, 193-1000) +Brightness=255 + +# set the serial port speed [default: 9600] +Speed=9600 + +# enable ISO 8859 1 compatibility [default: 1] +#ISO_8859_1=1 + + + ## stv5730 driver ## [stv5730] diff --git a/acinclude.m4 b/acinclude.m4 index 912030b..c5c5ec0 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -8,14 +8,14 @@ AC_ARG_ENABLE(drivers, [ bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,] [ glcdlib,glk,hd44780,icp_a106,imon,IOWarrior,irman,] [ joy,lb216,lcdm001,lcterm,lirc,ms6931,mtc_s16209x,] - [ MtxOrb,NoritakeVFD,pylcd,sed1330,sed1520,sli,stv5730,] - [ svga,t6963,text,tyan,xosd] + [ MtxOrb,NoritakeVFD,pylcd,sed1330,sed1520,serialVFD,] + [ sli,stv5730,svga,t6963,text,tyan,xosd] [ \"all\" compiles all drivers], drivers="$enableval", drivers=[bayrad,CFontz,CFontz633,curses,CwLnx,glk,lb216,lcdm001,MtxOrb,pylcd,text]) if test "$drivers" = "all"; then - drivers=[bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,glcdlib,glk,hd44780,icp_a106,imon,IOWarrior,irman,joy,lb216,lcdm001,lcterm,lirc,ms6931,mtc_s16209x,MtxOrb,NoritakeVFD,pylcd,sed1330,sed1520,sli,stv5730,svga,t6963,text,tyan,xosd] + drivers=[bayrad,CFontz,CFontz633,CFontzPacket,curses,CwLnx,glcdlib,glk,hd44780,icp_a106,imon,IOWarrior,irman,joy,lb216,lcdm001,lcterm,lirc,ms6931,mtc_s16209x,MtxOrb,NoritakeVFD,pylcd,sed1330,sed1520,serialVFD,sli,stv5730,svga,t6963,text,tyan,xosd] fi drivers=`echo $drivers | sed 's/,/ /g'` @@ -236,6 +236,10 @@ dnl else AC_MSG_WARN([The sed1520 driver needs a parallel port.]) fi ;; + serialVFD) + DRIVERS="$DRIVERS serialVFD${SO}" + actdrivers=["$actdrivers serialVFD"] + ;; sli) DRIVERS="$DRIVERS wirz_sli${SO}" actdrivers=["$actdrivers sli"] diff --git a/docs/README.serialVFD b/docs/README.serialVFD new file mode 100644 index 0000000..c81b731 --- /dev/null +++ b/docs/README.serialVFD @@ -0,0 +1,113 @@ + The serialVFD-driver should work with all NEC FIPC8367 based VFDs: + NEC FC20X2JA + NEC FM20X2KB-AB + NEC FC20X1SA-AB/AA + ... + Tested only on: NEC FM20X2KB-AB + The driver also works (tested) on "KD Rev 2.1" (an ATMEL AT90S.... + based FM20X2KB-AB replacement). + Note: Above char. 128 the FIPC-displays and KD's charactersets + are different. + + The driver may work or will be easy to get working on the following + Displays / Controllers (not tested!). + Display: Controller: + FUTABA M204SD01AA FUTABA 5P00A016 + Noritake CU20026SCPB-T (microcontroller) + Noritake CU20045SCPB-T28A ? + ... or compatible. + (most Futaba/Noritake 7x5 dot VFDs with serial(rs232) interface + (including serial(rs232)/parallel types)) + Maybe there are little changes in the commands to do to get all + functions to work correctly. But because of the similarity of the + protocols, it wont be much work. + + If you want to add a new device to the driver add a new section + to the displaytype-switch-case in the init-function and fill it + with the corrrect commands for the display. + (Try wich displaytype works best with your display, copy and modify + it's section that is the easiest way I guess.) + + + On this page I found pictures and datasheets from the VFD's: + http://www.maltepoeggel.de/html/vfd/index.html + + + + + To enable the bignumbers on 2-line displays (only this driver supports + this yet) you have to edit "/clientchrono.c" before compiling. + In function "big_clock_screen" you have to replace the "4" by a "2" in + this line: "if (lcd_hgt < 4)" + + + + This driver uses the serial mode of the displays. + It is NOT possible to connect most of the displays directly to the + serialport. The signal has to be inverted. I use the following + circuit to do that job. + + Computer Display + (signal) + HDD Powerconnector + color(Voltage) + + red(+5V) --------------------------------o----- +5V + | + black(GND) --------------------o | + | R + | R 10k + Serial(SUB-D 9Pin female) V* R + pin(signal) | + | + 3(TxD) --RRRR--o--o o-----------------o----- RxD + 10k | | | + | | C| + | | ----- BC547c (or similar NPN) + R | B| / | + 10k R o--|-| | + R | \ | + | --->- A* + | E| | + | | | + 5(GND) --------o----------o----o----------------- GND + + Shield ------------------------------------------ + optional + + *connect near display + + + The pins on the different displays vary. + + + + FM20X2KB-AB: + + CN1: + Pin 33 <--- RxD + (Testmode: connect pins 25 & 26 then power up) + + CN2: + Pin 1 <--- +5V + Pin 2 ---- GND + + + + KD Rev 2.1: + + blue connector (6pin in a row) (the important one!): + -------------------------------- + | +5V +5V RxD GND GND GND | + -------------------------------- + NOTE: hold the display in that position where you can read + the "KD Rev 2.1" marking normally! + + gray connector (10pin 2 rows): + Do not use. (the ATMEL ISP connector I guess) + + The two jumpers next to the gray connector: + Normally not used. + You can activate two different testmodes with them. + + diff --git a/server/drivers/Makefile.am b/server/drivers/Makefile.am index 39b3c30..b048a26 100644 --- a/server/drivers/Makefile.am +++ b/server/drivers/Makefile.am @@ -19,8 +19,8 @@ AM_LDFLAGS = @LDSHARED@ LIBS = pkglib_PROGRAMS = @DRIVERS@ -EXTRA_PROGRAMS = bayrad CFontz CFontz633 CFontzPacket curses CwLnx glcdlib glk hd44780 icp_a106 imon IOWarrior irman joy lb216 lcdm001 lcterm lirc ms6931 mtc_s16209x MtxOrb NoritakeVFD pylcd sed1330 sed1520 stv5730 svga t6963 text tyan wirz_sli xosd -noinst_LIBRARIES = libLCD.a +EXTRA_PROGRAMS = bayrad CFontz CFontz633 CFontzPacket curses CwLnx glcdlib glk hd44780 icp_a106 imon IOWarrior irman joy lb216 lcdm001 lcterm lirc ms6931 mtc_s16209x MtxOrb NoritakeVFD pylcd sed1330 sed1520 serialVFD stv5730 svga t6963 text tyan wirz_sli xosd +noinst_LIBRARIES = libLCD.a libbignum.a IOWarrior_CFLAGS = @libusb_cflags@ $(AM_CFLAGS) hd44780_CFLAGS = @libusb_cflags@ $(AM_CFLAGS) @@ -41,12 +41,14 @@ irman_LDADD = @LIBIRMAN@ lirc_LDADD = @LIBLIRC_CLIENT@ lcterm_LDADD = libLCD.a NoritakeVFD_LDADD = libLCD.a +serialVFD_LDADD = libLCD.a libbignum.a svga_LDADD = @LIBSVGA@ t6963_LDADD = libLCD.a tyan_LDADD = libLCD.a xosd_LDADD = @LIBXOSD@ libLCD_a_SOURCES = lcd_lib.h lcd_lib.c +libbignum_a_SOURCES = adv_bignum.h adv_bignum.c bayrad_SOURCES = lcd.h bayrad.h bayrad.c report.h CFontz_SOURCES = lcd.h CFontz.c CFontz.h CFontz-charmap.h report.h @@ -74,6 +76,7 @@ NoritakeVFD_SOURCES = lcd.h NoritakeVFD.c NoritakeVFD.h report.h pylcd_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 +serialVFD_SOURCES = lcd.h serialVFD.c serialVFD.h report.h adv_bignum.h stv5730_SOURCES = lcd.h stv5730.c stv5730.h report.h svga_SOURCES = lcd.h svgalib_drv.c svgalib_drv.h report.h t6963_SOURCES = lcd.h t6963.c t6963.h t6963_font.h report.h diff --git a/server/drivers/adv_bignum.c b/server/drivers/adv_bignum.c new file mode 100644 index 0000000..1218a32 --- /dev/null +++ b/server/drivers/adv_bignum.c @@ -0,0 +1,986 @@ +/* This is the bignumber-library used by the serialVFD driver. + + Copyright (C) 2006 Stefan Herdler + + Based on drivers.c and lcd-lib.c. + It may contain parts of other drivers of this package too. + + 2006-01-26 Version 0.1: everything should work (not all hardware tested!) + + 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 + + + + Demands on the calling driver / display: + cellwidth == 5 + cellheight == 7 or 8 (testet only on 7) + needed functions: + drvthis->set_char (only if the display has usercharacters) + drvthis->chr + usercharacters (if available) at 0, 1, 2, ..... ,n + + USAGE: + + Just call lib_adv_bignum(drvthis, x, num, height, do_init, customchars) + from drvthis->num. + The library does everything needed to show bignumbers EXPECT checking or + setting the CCMODE variable. The driver has to do this (see serialVFD.c + for details). +*/ + +#include +//#include +#include +//#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "lcd.h" +#include "adv_bignum.h" + +#include "report.h" +#include "lcd_lib.h" + + + + + +static void adv_bignum_num_2_0 (Driver *drvthis, int x, int num, int height, int do_init); +static void adv_bignum_num_2_1 (Driver *drvthis, int x, int num, int height, int do_init); +static void adv_bignum_num_2_2 (Driver *drvthis, int x, int num, int height, int do_init); +static void adv_bignum_num_2_5 (Driver *drvthis, int x, int num, int height, int do_init); +static void adv_bignum_num_2_28 (Driver *drvthis, int x, int num, int height, int do_init); + +static void adv_bignum_num_4_0 (Driver *drvthis, int x, int num, int height, int do_init); +static void adv_bignum_num_4_3 (Driver *drvthis, int x, int num, int height, int do_init); + +static void adv_bignum_write_num (Driver *drvthis, char write_num_map[][4][4], int x, int num, int height); + + + + +void +lib_adv_bignum(Driver *drvthis, int x, int num, int height, int do_init, int customchars) +{ + + switch (height) { + case 2: + case 3: + if(customchars == 0){ + adv_bignum_num_2_0 (drvthis, x, num, height, do_init); + } + else if(customchars ==1 ){ + adv_bignum_num_2_1 (drvthis, x, num, height, do_init); + } + else if(customchars < 3){ + adv_bignum_num_2_2 (drvthis, x, num, height, do_init); + } + else if(customchars < 28){ + adv_bignum_num_2_5 (drvthis, x, num, height, do_init); + } + else { //p->customchars <= 28 + adv_bignum_num_2_28 (drvthis, x, num, height, do_init); + } + break; + case 4: + if(customchars < 3){ + adv_bignum_num_4_0 (drvthis, x, num, height, do_init); + } + else { //p->customchars <= 4 + adv_bignum_num_4_3 (drvthis, x, num, height, do_init); + } + break; + default: + return; + + } +} +static void adv_bignum_write_num (Driver *drvthis, char write_num_map[][4][4], int x, int num, int height) +{ + int y, dx; + for (y = 0; y < height; y++) + { + if(num == 10) + drvthis->chr (drvthis, x, y+1, write_num_map[num][y][0]); + else + for (dx = 0; dx <3; dx++) + drvthis->chr (drvthis, x + dx, y+1, write_num_map[num][y][dx]); + } + + +} + +// +// +// +// stored usercharacters +// +// +// + + + +static void adv_bignum_num_2_0 (Driver *drvthis, int x, int num, int height, int do_init) +{ +static char num_map[][4][4] = { + { /* 0 */ + " ||", + " ||", + " ", + " " }, + { /* 1 */ + " |", + " |", + " ", + " " }, + { /* 2 */ + " ]", + " [ ", + " ", + " " }, + { /* 3 */ + " ]", + " ]", + " ", + " " }, + { /* 4 */ + " L|", + " |", + " ", + " " }, + { /* 5 */ + " [ ", + " ]", + " ", + " " }, + { /* 6 */ + " [ ", + " []", + " ", + " " }, + { /* 7 */ + " 7", + " |", + " ", + " " }, + { /* 8 */ + " []", + " []", + " ", + " " }, + { /* 9 */ + " []", + " ]", + " ", + " " }, + { /* colon */ + ".", + ".", + " ", + " " } + }; + + adv_bignum_write_num (drvthis, num_map, x, num, height); + +} + + + +static void adv_bignum_num_2_1 (Driver *drvthis, int x, int num, int height, int do_init) +{ +static char num_map[][4][4] = { + { /* 0 */ + {'|' , 0 , '|',0}, + {"|_|"}, + {" "}, + {" "} }, + { /* 1 */ + {" |"}, + {" |"}, + {" "}, + {" "} }, + { /* 2 */ + {' ',0,']',0}, + {" [_"}, + {" "}, + {" "} }, + { /* 3 */ + {' ',0,']',0}, + {" _]"}, + {" "}, + {" "} }, + { /* 4 */ + {" L|"}, + {" |"}, + {" "}, + {" "} }, + { /* 5 */ + {' ','[',0,0}, + {" _]"}, + {" "}, + {" " }}, + { /* 6 */ + {' ','[',0,0}, + {" []"}, + {" "}, + {" "} }, + { /* 7 */ + {' ',0,'|',0}, + {" |"}, + {" "}, + {" "} }, + { /* 8 */ + {" []"}, + {" []"}, + {" "}, + {" "} }, + { /* 9 */ + {" []"}, + {" _]"}, + {" "}, + {" "} }, + { /* colon */ + {"."}, + {"."}, + {" "}, + {" "} } + }; +if (do_init) + { + static char bignum[1][5 * 8] = { + { + 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + }}; + drvthis->set_char (drvthis, 0, &bignum[0][0]); + } + adv_bignum_write_num (drvthis, num_map, x, num, height); + +} + + + +static void adv_bignum_num_2_2 (Driver *drvthis, int x, int num, int height, int do_init) +{ +static char num_map[][4][4] ={ + { /* 0 */ + {'|',0,'|'}, + "|_|", + " ", + " " }, + { /* 1 */ + " |", + " |", + " ", + " " }, + { /* 2 */ + {' ',1,'|'}, + "|_ ", + " ", + " " }, + { /* 3 */ + {' ',1,'|'}, + " _|", + " ", + " " }, + { /* 4 */ + "|_|", + " |", + " ", + " " }, + { /* 5 */ + {'|',1,' '}, + " _|", + " ", + " " }, + { /* 6 */ + {'|',0,' '}, + {'|',1,'|'}, + " ", + " " }, + { /* 7 */ + {' ',0,'|'}, + " |", + " ", + " " }, + { /* 8 */ + {'|',1,'|'}, + "|_|", + " ", + " " }, + { /* 9 */ + {'|',1,'|'}, + " _|", + " ", + " " }, + { /* colon */ + ".", + ".", + " ", + " " } + }; +if (do_init) + { + static char bignum[2][5 * 8] = { + { + 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + }, + { + 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + }}; + int i; + for (i = 0; i <= 2 ; i++) { + drvthis->set_char (drvthis, i, &bignum[i][0]); + } +} + adv_bignum_write_num (drvthis, num_map, x, num, height); +} + + + +static void adv_bignum_num_2_5 (Driver *drvthis, int x, int num, int height, int do_init) +{ +static char num_map[][4][4] = + {{{3 ,0 ,2}, /*0*/ + {3 ,1 ,2}, + {" "}, + {" "}}, + {{' ' ,' ', 2},/*1*/ + {' ' ,' ', 2}, + {" "}, + {" "}}, + {{' ' ,4 ,2},/*2*/ + {3 ,1 ,' '}, + {" "}, + {" "}}, + {{' ' ,4 ,2},/*3*/ + {' ' ,1 ,2}, + {" "}, + {" "}}, + {{3 ,1 ,2},/*4*/ + {' ' ,' ' ,2}, + {" "}, + {" "}}, + {{3 ,4 ,' '},/*5*/ + {' ' ,1 ,2}, + {" "}, + {" "}}, + {{3 ,0 ,' '},/*6*/ + {3 ,4 ,2}, + {" "}, + {" "}}, + {{' ' ,0 ,2},/*7*/ + {' ' ,' ' ,2}, + {" "}, + {" "}}, + {{3 ,4 ,2},/*8*/ + {3 ,1 ,2}, + {" "}, + {" "}}, + {{3 ,4 ,2},/*9*/ + {' ' ,1 ,2}, + {" "}, + {" "}}, + {{'.'},/*:*/ + {'.'}, + {" "}, + {" "}}}; +if (do_init) + { + static char bignum[5][5 * 8] = { + { + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + }, + { + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + }, + { + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + }, + { + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + }, + { + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + }}; + int i; + for (i = 0; i <= 5 ; i++) { + drvthis->set_char (drvthis, i, &bignum[i][0]); + } +} + adv_bignum_write_num (drvthis, num_map, x, num, height); +} + + + +static void adv_bignum_num_2_28 (Driver *drvthis, int x, int num, int height, int do_init) +{ +static char num_map[][4][4] = + {{{15 ,6 ,2}, /*0*/ + {14 ,4 ,5}, + {" "}, + {" "}}, + {{' ' ,26 ,' '},/*1*/ + {' ' ,10 ,' '}, + {" "}, + {" "}}, + {{1 ,6 ,2},/*2*/ + {7 ,8 ,9}, + {" "}, + {" "}}, + {{0 ,11 ,2},/*3*/ + {3 ,13 ,5}, + {" "}, + {" "}}, + {{25 ,21 ,23},/*4*/ + {17 ,22 ,24}, + {" "}, + {" "}}, + {{10 ,11 ,12},/*5*/ + {3 ,13 ,5}, + {" "}, + {" "}}, + {{15 ,11 ,16},/*6*/ + {14 ,13 ,5}, + {" "}, + {" "}}, + {{17 ,18 ,19},/*7*/ + {' ' ,20 ,' '}, + {" "}, + {" "}}, + {{15 ,11 ,2},/*8*/ + {14 ,13 ,5}, + {" "}, + {" "}}, + {{15 ,11 ,2},/*9*/ + {3 ,13 ,5}, + {" "}, + {" "}}, + {{27},/*:*/ + {27}, + {" "}, + {" "}}}; + + if (do_init) + { + +static char bignum[28][5 * 8] = { + { //0 + 0, 0, 0, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + }, + { //1 + 0, 0, 0, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + }, + { //2 + 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0 + }, + { //3 + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, + 0, 0, 0, 1, 1, + }, + { //4 + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + }, + { //5 + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, + 1, 0, 0, 0, 0, + }, + { //6 + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + }, + { //7 + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + }, + { //8 + 0, 0, 1, 1, 1, + 0, 1, 1, 1, 1, + 1, 1, 1, 1, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + }, + { //9 + 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + }, + { //10 + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + }, + { //11 + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + }, + { //12 + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + }, + { //13 + 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + }, + { //14 + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, + 0, 0, 0, 1, 1, + }, + { //15 + 0, 0, 0, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + }, + { //16 + 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + }, + { //17 + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + }, + { //18 + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, + 0, 0, 0, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + }, + { //19 + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, + 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + }, + { //20 + 0, 1, 1, 1, 0, + 0, 1, 1, 1, 0, + 1, 1, 1, 1, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + }, + { //21 + 0, 0, 0, 0, 1, + 0, 0, 0, 1, 1, + 0, 0, 1, 1, 1, + 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 0, 1, + 1, 1, 0, 0, 1, + 1, 1, 0, 0, 1, + }, + { //22 + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 0, 0, 0, 0, 1, + 0, 0, 0, 0, 1, + 0, 0, 0, 0, 1, + 0, 0, 0, 0, 1, + 0, 0, 0, 0, 1, + }, + { //23 + 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, + }, + { //24 + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, + }, + { //25 + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, + 0, 0, 0, 0, 1, + }, + { //26 + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + }, + { //27 + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 1, 1, 0, + 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + } + }; + int i; + for (i = 0; i <= 28 ; i++) { + drvthis->set_char (drvthis, i, &bignum[i][0]); + } +} + adv_bignum_write_num (drvthis, num_map, x, num, height); +} + + + +static void adv_bignum_num_4_0 (Driver *drvthis, int x, int num, int height, int do_init) +{ +static char num_map[][4][4] = { + { /* 0 */ + " _ ", + "| |", + "|_|", + " " }, + { /* 1 */ + " ", + " |", + " |", + " " }, + { /* 2 */ + " _ ", + " _|", + "|_ ", + " " }, + { /* 3 */ + " _ ", + " _|", + " _|", + " " }, + { /* 4 */ + " ", + "|_|", + " |", + " " }, + { /* 5 */ + " _ ", + "|_ ", + " _|", + " " }, + { /* 6 */ + " _ ", + "|_ ", + "|_|", + " " }, + { /* 7 */ + " _ ", + " |", + " |", + " " }, + { /* 8 */ + " _ ", + "|_|", + "|_|", + " " }, + { /* 9 */ + " _ ", + "|_|", + " _|", + " " }, + { /* colon */ + " ", + ".", + ".", + " " } + }; + + adv_bignum_write_num (drvthis, num_map, x, num, height); +} + + + +static void adv_bignum_num_4_3 (Driver *drvthis, int x, int num, int height, int do_init) +{ +static char num_map[][4][4] = + {{{3 ,1 ,3}, /*0*/ + {3 ,' ' ,3}, + {3 ,' ' ,3}, + {3 ,2 ,3}}, + {{' ' ,' ' ,3},/*1*/ + {' ' ,' ' ,3}, + {' ' ,' ' ,3}, + {' ' ,' ' ,3}}, + {{' ' ,1 ,3},/*2*/ + {' ' ,2 ,3}, + {3 ,' ' ,3}, + {3 ,2 ,3}}, + {{' ' ,1 ,3},/*3*/ + {' ' ,' ' ,3}, + {' ' ,2 ,3}, + {' ' ,' ' ,3}}, + {{3 ,2 ,3},/*4*/ + {3 ,2 ,3}, + {' ' ,' ' ,3}, + {' ' ,' ' ,3}}, + {{3 ,1 ,3},/*5*/ + {3 ,2 ,3}, + {' ' ,' ' ,3}, + {' ' ,2 ,3}}, + {{3 ,1 ,3},/*6*/ + {3 ,' ' ,3}, + {3 ,1 ,3}, + {3 ,2 ,3}}, + {{' ' ,1 ,3},/*7*/ + {' ' ,' ' ,3}, + {' ' ,' ' ,3}, + {' ' ,' ' ,3}}, + {{3 ,1 ,3},/*8*/ + {3 ,2 ,3}, + {3 ,' ' ,3}, + {3 ,2 ,3}}, + {{3 ,1 ,3},/*9*/ + {3 ,2 ,3}, + {' ' ,' ' ,3}, + {' ' ,2 ,3}}, + {{" "},/*:*/ + {'.'}, + {'.'}, + {" "}}}; +if (do_init) + { + static char bignum[5][5 * 8] = { + { + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + }, + { + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + }, + { + 0, 1, 1, 1, 0, + 0, 1, 1, 1, 0, + 0, 1, 1, 1, 0, + 0, 1, 1, 1, 0, + 0, 1, 1, 1, 0, + 0, 1, 1, 1, 0, + 0, 1, 1, 1, 0, + 0, 1, 1, 1, 0, + } + }; + int i; + for (i = 0; i <= 3 ; i++) { + drvthis->set_char (drvthis, i, &bignum[i][0]); + } +} + adv_bignum_write_num (drvthis, num_map, x, num, height); + + +} diff --git a/server/drivers/adv_bignum.h b/server/drivers/adv_bignum.h new file mode 100644 index 0000000..107a8be --- /dev/null +++ b/server/drivers/adv_bignum.h @@ -0,0 +1,34 @@ +/* This is the bignumber-library used by the serialVFD driver. + + Copyright (C) 2006 Stefan Herdler + + Based on drivers.c and lcd-lib.c. + It may contain parts of other drivers of this package too. + + 2006-01-26 Version 0.1: everything should work (not all hardware tested!) + + 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 + */ + +#ifndef ADV_BIGNUM_H +#define ADV_BIGNUM_H + +#include "lcd.h" + +void lib_adv_bignum (Driver *drvthis, int x, int num, int height , int do_init, int customchars); + + + +#endif diff --git a/server/drivers/serialVFD.c b/server/drivers/serialVFD.c new file mode 100644 index 0000000..15cad1b --- /dev/null +++ b/server/drivers/serialVFD.c @@ -0,0 +1,1201 @@ +/* This is the LCDproc driver for various serial VFD Devices + + Copyright (C) 2006 Stefan Herdler + + This driver is based on drv_base.c, wirz-sli.c and hd44780 from LCDproc + and the NoritakeVFD driver from this package. + It may contain parts of other drivers of this package too. + + 2006-01-26 Version 0.1: everything should work (not all hardware tested!) + + 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 + + + + The serialVFD-driver should work with all NEC FIPC8367 based VFDs: + NEC FC20X2JA + NEC FM20X2KB-AB + NEC FC20X1SA-AB/AA + ... + Tested only on: NEC FM20X2KB-AB + The driver also works (tested) on "KD Rev 2.1" (an ATMEL AT90S.... + based FM20X2KB-AB replacement). + Note: Above char. 128 the FIPC-displays and KD's charactersets + are different. + + The driver may work or will be easy to get working on the following + Displays / Controllers (not tested!). + Display: Controller: + FUTABA M204SD01AA FUTABA 5P00A016 + Noritake CU20026SCPB-T (microcontroller) + Noritake CU20045SCPB-T28A ? + ... or compatible. + (most Futaba/Noritake 7x5 dot VFDs with serial(rs232) interface + (including serial(rs232)/parallel types)) + Maybe there are little changes in the commands to do to get all + functions to work correctly. But because of the similarity of the + protocols, it wont be much work. + + If you want to add a new device to the driver add a new section + to the displaytype-switch-case in the init-function and fill it + with the corrrect commands for the display. + (Try wich displaytype works best with your display, copy and modify + it's section that is the easiest way I guess.) + + + On this page I found pictures and datasheets from the VFD's: + http://www.maltepoeggel.de/html/vfd/index.html + + + + + To enable the bignumbers on 2-line displays (only this driver supports + this yet) you have to edit "/clientchrono.c" before compiling. + In function "big_clock_screen" you have to replace the "4" by a "2" in + this line: "if (lcd_hgt < 4)" + + + + This driver uses the serial mode of the displays. + It is NOT possible to connect most of the displays directly to the + serialport. The signal has to be inverted. I use the following + circuit to do that job. + + Computer Display + (signal) + HDD Powerconnector + color(Voltage) + + red(+5V) --------------------------------o----- +5V + | + black(GND) --------------------o | + | R + | R 10k + Serial(SUB-D 9Pin female) V* R + pin(signal) | + | + 3(TxD) --RRRR--o--o o-----------------o----- RxD + 10k | | | + | | C| + | | ----- BC547c (or similar NPN) + R | B| / | + 10k R o--|-| | + R | \ | + | --->- A* + | E| | + | | | + 5(GND) --------o----------o----o----------------- GND + + Shield ------------------------------------------ + optional + + *connect near display + + + The pins on the different displays vary. + + + + FM20X2KB-AB: + + CN1: + Pin 33 <--- RxD + (Testmode: connect pins 25 & 26 then power up) + + CN2: + Pin 1 <--- +5V + Pin 2 ---- GND + + + + KD Rev 2.1: + + blue connector (6pin in a row) (the important one!): + -------------------------------- + | +5V +5V RxD GND GND GND | + -------------------------------- + NOTE: hold the display in that position where you can read + the "KD Rev 2.1" marking normally! + + gray connector (10pin 2 rows): + Do not use. (the ATMEL ISP connector I guess) + + The two jumpers next to the gray connector: + Normally not used. + You can activate two different testmodes with them. + + + + + +List of driver entry point: + +init Implemented. +close Implemented. +width Implemented. +height Implemented. +clear Implemented by space filling no custom char info. +flush Calling draw_frame only. +string Implemented. +chr Implemented. +vbar Implemented. +hbar Implemented. +num Implemented. +heartbeat Implemented. +icon Implemented. +cursor NOT IMPLEMENTED: Is it really used? +set_char Implemented. +get_free_chars Implemented. +cellwidth Implemented. +cellheight Implemented. +get_contrast Not implemented, no software control. +set_contrast Not implemented, no software control. +get_brightness Implemented. +set_brightness Implemented. +backlight Not implemented, no software control. +output Not implemented. +get_key Not implemented, no keys. +get_info Implemented. + +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "lcd.h" +#include "serialVFD.h" + +#include "report.h" +#include "lcd_lib.h" +#include "adv_bignum.h" + +#define pos1_cursor 4 +#define mv_cursor 5 //moves cursor to position (next byte). +#define reset 6 +#define init_cmds 7 +#define set_user_char 8 +#define hor_tab 9 //moves cursor 1 chr right + +/* Constants for userdefchar_mode */ +//#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, +// } CGmode; + +typedef struct driver_private_data { + char device[200]; + int fd; + int speed; + /* dimensions */ + int width, height; + int cellwidth, cellheight; + /* framebuffer and buffer for old LCD contents */ + unsigned char *framebuf; + unsigned char *backingstore; + /* defineable characters */ + int ccmode; + int brightness; + int customchars; + int ISO_8859_1; + unsigned char charmap[128]; + int display_type; + char custom_char[31][7]; // used for "KD Rev 2.1" only + char custom_char_changed[32]; // used only if need_refresh==1 + int need_refresh; // 1 if displays need refresh after changing custonchars + char hw_cmd[10][4]; // hardwarespecific commands + int usr_chr_dot_assignment[57]; // how to setup usercharacters + unsigned int usr_chr_mapping[31];// where to place the usercharacters (0..30) in the asciicode + int hbar_cc_offset; // character offset of the bars + int vbar_cc_offset; // character offset of the bars + char info[255]; +} PrivateData; + +/* Vars for the server core */ +MODULE_EXPORT char *api_version = API_VERSION; +MODULE_EXPORT int stay_in_foreground = 0; +MODULE_EXPORT int supports_multiple = 0; +MODULE_EXPORT char *symbol_prefix = "serialVFD_"; + +/* Internal functions */ +static void serialVFD_init_vbar (Driver *drvthis); +static void serialVFD_init_hbar (Driver *drvthis); +static void serialVFD_draw_frame (Driver *drvthis, char *dat); + + +// Opens com port and sets baud correctly... +// +MODULE_EXPORT int +serialVFD_init (Driver *drvthis) +{ + struct termios portset; + int tmp, w, h, brightness; +// int reboot = 0; + char size[200] = DEFAULT_SIZE; + + PrivateData *p; + + /* Allocate and store private data */ + p = (PrivateData *) calloc(1, sizeof(PrivateData)); + if (p == NULL) + return -1; + if (drvthis->store_private_ptr(drvthis, p)) + return -1; + + /* Initialize the PrivateData structure */ + p->cellwidth = DEFAULT_CELL_WIDTH; + p->cellheight = DEFAULT_CELL_HEIGHT; + p->ccmode = CCMODE_STANDARD; + p->ISO_8859_1 = 1; + + debug(RPT_INFO, "%s(%p)", __FUNCTION__, drvthis ); + + /* Read config file */ + /* Which device should be used */ + strncpy(p->device, drvthis->config_get_string (drvthis->name, "Device", 0, DEFAULT_DEVICE), sizeof(p->device)); + p->device[sizeof(p->device)-1] = '\0'; + debug (RPT_INFO,"%s: Device (in config) is: '%s'", __FUNCTION__, p->device); + + /* Which size */ + strncpy(size, drvthis->config_get_string (drvthis->name, "Size", 0, DEFAULT_SIZE), sizeof(size)); + size[sizeof(size)-1] = '\0'; + if ((sscanf(size, "%dx%d", &w, &h) != 2) + || (w <= 0) || (w > LCD_MAX_WIDTH) + || (h <= 0) || (h > LCD_MAX_HEIGHT)) { + report (RPT_WARNING, "%s: Cannot parse size: %s. Using default %s.\n", + __FUNCTION__, size, DEFAULT_SIZE); + sscanf(DEFAULT_SIZE, "%dx%d", &w, &h); + } + p->width = w; + p->height = h; + + /* Which backlight brightness */ + tmp = drvthis->config_get_int (drvthis->name, "Brightness", 0, DEFAULT_BRIGHTNESS); + if ((tmp < 0) || (tmp > 1000)) { + report (RPT_WARNING, "%s: Brightness must be between 0 and 1000. Using default %d.\n", + __FUNCTION__, DEFAULT_BRIGHTNESS); + tmp = DEFAULT_BRIGHTNESS; + } + brightness = tmp; + + + /* ISO 8859 1 */ + tmp = drvthis->config_get_int (drvthis->name, "ISO_8859_1", 0, 1); + if ((tmp < 0) || (tmp > 1)) { + report (RPT_WARNING, "%s: ISO_8859_1 must be 0 or 1000. Using default %d.\n", + __FUNCTION__, 1); + tmp = 1; + } + p->ISO_8859_1 = tmp; + + /* Which displaytype */ + tmp = drvthis->config_get_int (drvthis->name, "Displaytype", 0, DEFAULT_DISPLAYTYPE); + if ((tmp < 0) || (tmp > 3)) { + report (RPT_WARNING, "%s: Displaytype must be between 0 and 3. Using default %d.\n", + __FUNCTION__, DEFAULT_DISPLAYTYPE); + tmp = DEFAULT_DISPLAYTYPE; + } + p->display_type = tmp; + + + /* Which speed */ + tmp = drvthis->config_get_int (drvthis->name, "Speed", 0, DEFAULT_SPEED); + if ((tmp != 1200) && (tmp != 2400) && (tmp != 9600) && (tmp != 19200) && (tmp != 115200)) { + report (RPT_WARNING, "%s: Speed must be 1200, 2400, 9600, 19200 or 115200. Using default %d.\n", + __FUNCTION__, DEFAULT_SPEED); + tmp = DEFAULT_SPEED; + } + if (tmp == 1200) p->speed = B1200; + else if (tmp == 2400) p->speed = B2400; + else if (tmp == 9600) p->speed = B9600; + else if (tmp == 19200) p->speed = B19200; + else if (tmp == 115200) p->speed = B115200; + + + + /* Set up io port correctly, and open it...*/ + debug( RPT_DEBUG, "%s: Opening device: %s", __FUNCTION__, p->device); + p->fd = open (p->device, O_RDWR | O_NOCTTY | O_NDELAY); + + if (p->fd == -1) { + report (RPT_ERR, "%s: open() of %s failed (%s)\n", __FUNCTION__, p->device, strerror (errno)); + return -1; + } + + tcgetattr (p->fd, &portset); + + // We use RAW mode +#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, p->speed); + cfsetispeed (&portset, B0); + + // Do it... + tcsetattr (p->fd, TCSANOW, &portset); + + /* make sure the frame buffer is there... */ + p->framebuf = (unsigned char *) malloc(p->width * p->height); + if (p->framebuf == NULL) { + report(RPT_ERR, "%s: unable to create framebuffer.\n", __FUNCTION__); + return -1; + } + memset(p->framebuf, ' ', p->width * p->height); + + /* make sure the framebuffer backing store is there... */ + p->backingstore = (unsigned char *) malloc(p->width * p->height); + if (p->backingstore == NULL) { + report(RPT_ERR, "%s: unable to create framebuffer backing store.\n", __FUNCTION__); + return -1; + } + memset(p->backingstore, ' ', p->width * p->height); + +//setup displayspecific data + switch (p->display_type) + { +//nec_fipc + case 0: //nec_fipc + p->need_refresh=0; // 1 if displays need refresh after changing custonchars + p->customchars=1; // number of customchaaracters the display provides + p->vbar_cc_offset=5; // character offset of the bars + p->hbar_cc_offset=12; // character offset of the bars + + // hardwarespecific commands: + // hw_cmd[Command][data] = {{commandlength , command 1}, + // ..... + // {commandlength , command N}} + const char hw_cmd_0[10][4]= {{1 ,0x04}, // dark + {1 ,0x03}, + {1 ,0x02}, + {1 ,0x01}, // bright + {1 ,0x0D}, // pos1 + {1 ,0x1B}, // move cursor + {1 ,0x0C}, // reset + {2 ,0x14, 0x11}, // init + {1 ,0x1A}, // set user char + {1 ,0x09}}; // tab + for (tmp=0;tmp < (10) ;tmp++) + for (w=0;w < (4) ;w++) + p->hw_cmd[tmp][w]=hw_cmd_0[tmp][w]; + + // Translates ISO 8859-1 to display charset. + const unsigned char charmap_0[] = { + /* #128 = 0x80 */ + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + /* #160 = 0xA0 */ + 160, '!', 0xF7, 0xF8, '?', '?', 0x7C, 0xF9, + '"', '?', '?', '?', '?', '-', '?', '?', + 0x8B, 0xF3, 0x89, 0x8A, 0x27, 0x98, '?', '.', + ',', '?', '?', '?', '?', 0x8C, '?', 0xAA, + /* #192 = 0xC0 */ + 'A', 'A', 'A', 'A', 0xA2, 0xA8, 'A', 'C', + 'E', 'E', 'E', 0xB6, 'I', 'I', 'I', 'I', + 'D', 0xA9, 'O', 'O', 'O', 'O', 0xA3, 0x8D, + '0', 'U', 'U', 'U', 0xA4, 'Y', 'p', 0x91, + /* #224 = 0xE0 */ + 'a', 'a', 'a', 'a', 0xA5, 'a', 'a', 'c', + 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', + 'o', 'n', 'o', 'o', 'o', 'o', 0xA6, 0x8E, + '0', 'u', 'u', 'u', 0xA7, 'y', 'p', 'y' + }; + for (tmp=0;tmp < 128 ;tmp++) + p->charmap[tmp]=charmap_0[tmp]; + + //{bytes to send, icon bit mapped to bit 0, icon bit mapped to bit 1, ...} + const int usr_chr_dot_assignment_0[57]={7, 1, 2, 3, 4, 5, 0, 0, 0, + 6, 7, 8, 9,10, 0, 0, 0, + 11,12,13,14,15, 0, 0, 0, + 16,17,18,19,20, 0, 0, 0, + 21,22,23,24,25, 0, 0, 0, + 26,27,28,29,30, 0, 0, 0, + 31,32,33,34,35, 0, 0, 0}; + for (tmp=0;tmp < 57 ;tmp++) + p->usr_chr_dot_assignment[tmp]=usr_chr_dot_assignment_0[tmp]; + + //Where to place the usercharacters (0..30) in the asciicode. + //Also used to map standardcharacters in the usercharacterspace(0..30) + //(useful for displays with less then 30 usercharacters and predefined bars) + const unsigned int usr_chr_mapping_0[31]= + {0xAF,0,0,0,0,0, 0x5F, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0, 0x5F, 0xE1, 0xE3, 0xE4}; + for (tmp=0;tmp < 31 ;tmp++) + p->usr_chr_mapping[tmp]=usr_chr_mapping_0[tmp]; + break; + +//KD Rev2.1 + case 1: //KD Rev2.1 + p->need_refresh=1; // 1 if displays need refresh after changing custonchars + p->customchars=31; // number of customchaaracters the display provides + p->vbar_cc_offset=0; // character offset of the bars + p->hbar_cc_offset=0; // character offset of the bars + + // hardwarespecific commands: + // hw_cmd[Command][data] = {{commandlength , command 1}, + // ..... + // {commandlength , command N}} + const char hw_cmd_1[10][4]= {{1 ,0x04}, // dark + {1 ,0x03}, + {1 ,0x02}, + {1 ,0x01}, // bright + {1 ,0x0D}, // pos1 + {1 ,0x1B}, // move cursor + {1 ,0x0C}, // reset + {2 ,0x14, 0x11}, // init + {1 ,0x1A}, // set user char + {1 ,0x09}}; // tab + for (tmp=0;tmp < (10) ;tmp++) + for (w=0;w < (4) ;w++) + p->hw_cmd[tmp][w]=hw_cmd_1[tmp][w]; + + const unsigned char charmap_1[] = { + /* #128 = 0x80 */ + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + /* #160 = 0xA0 */ + 160, '!', 0xF7, 0xF8, '?', '?', 0x7C, 0xF9, + '"', '?', '?', '?', '?', '-', '?', '?', + 0xA9, 0xBA, '?', '?', 0x27, '?', '?', '.', + ',', '?', '?', '?', '?', '?', '?', '?', + /* #192 = 0xC0 */ + 0xB2, 'A', 'A', 'A', 0xA2, 0xA1, 'A', 'C', + 'E', 'E', 0xA8, 0xB6, 0xAB, 0xAA, 0xAC, 0xA9, + 'D', 0xAE, 0xB1, 0xB0, 0xBF, 'O', 0xA3, 'x', + 0xAF, 0xB7, 0xB6, 0xB8, 0xA4, 'Y', 'p', 0x91, + /* #224 = 0xE0 */ + 0xD2, 0xC2, 0xC4, 'a', 0xA5, 0xC1, 0xC5, 0xC3, + 0xC7, 0xC6, 0xC8, 0xD4, 0xCC, 0xCB, 0xCD, 0xCA, + 'o', 0xCF, 0xD1, 0xD0, 0xCE, 'o', 0xA6, 0xBB, + 0xD0, 0xD7, 0xD6, 0xD8, 0xA7, 'y', 'p', 'y' + }; + for (tmp=0;tmp < 128 ;tmp++) + p->charmap[tmp]=charmap_1[tmp]; + + + //{bytes to send, icon bit mapped to bit 0, icon bit mapped to bit 1, ...} + const int usr_chr_dot_assignment_1[57]={7, 1, 2, 3, 4, 5, 0, 0, 0, + 6, 7, 8, 9,10, 0, 0, 0, + 11,12,13,14,15, 0, 0, 0, + 16,17,18,19,20, 0, 0, 0, + 21,22,23,24,25, 0, 0, 0, + 26,27,28,29,30, 0, 0, 0, + 31,32,33,34,35, 0, 0, 0}; + for (tmp=0;tmp < 57 ;tmp++) + p->usr_chr_dot_assignment[tmp]=usr_chr_dot_assignment_1[tmp]; + + //Where to place the usercharacters (0..30) in the asciicode. + //Also used to map standardcharacters in the usercharacterspace(0..30) + //(useful for displays with less then 30 usercharacters and predefined bars) + const unsigned int usr_chr_mapping_1[31]= + {0xAF}; + for (tmp=0;tmp < 31 ;tmp++) + p->usr_chr_mapping[tmp]=usr_chr_mapping_1[tmp]; + break; + +//Noritake + case 2: //Noritake + p->need_refresh=0; // 1 if displays need refresh after changing custonchars + p->customchars=16; // number of customchaaracters the display provides + p->vbar_cc_offset=0; // character offset of the bars + p->hbar_cc_offset=0; // character offset of the bars + + // hardwarespecific commands: + // hw_cmd[Command][data] = {{commandlength , command 1}, + // ..... + // {commandlength , command N}} + const char hw_cmd_2[10][4]= {{1 ,0x1B, 0x4C, 0x00}, // dark + {1 ,0x1B, 0x4C, 0x50}, + {2 ,0x1B, 0x4C, 0x90}, + {1 ,0x1B, 0x4C, 0xFF}, // bright + {1 ,0x0C}, // pos1 + {2 ,0x1B, 0x48}, // move cursor + {2 ,0x1B, 0x49}, // reset + {2 ,0x14, 0x11}, // init + {2 ,0x1B, 0x43}, // set user char + {1 ,0x09}}; // tab + for (tmp=0;tmp < (10) ;tmp++) + for (w=0;w < (4) ;w++) + p->hw_cmd[tmp][w]=hw_cmd_2[tmp][w]; + + // no charmap needed + for (tmp=128;tmp <= 255 ;tmp++) + p->charmap[tmp]=tmp; + + //{bytes to send, icon bit mapped to bit 0, icon bit mapped to bit 1, ...} + const int usr_chr_dot_assignment_2[57]={5, 1, 2, 3, 4, 5, 6, 7, 8, + 9,10,11,12,13,14,15,16, + 17,18,19,20,21,22,23,24, + 25,26,27,28,29,30,31,32, + 33,34,35, 0, 0, 0, 0, 0}; + for (tmp=0;tmp < 57 ;tmp++) + p->usr_chr_dot_assignment[tmp]=usr_chr_dot_assignment_2[tmp]; + + //Where to place the usercharacters (0..30) in the asciicode. + //Also used to map standardcharacters in the usercharacterspace(0..30) + //(useful for displays with less then 30 usercharacters and predefined bars) + const unsigned int usr_chr_mapping_2[31]= + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\ + 0x0F, 0x10, 0x13 , 0x14, 0x1C, 0x1D, 0x1E, 0x1F}; + for (tmp=0;tmp < 31 ;tmp++) + p->usr_chr_mapping[tmp]=usr_chr_mapping_2[tmp]; + break; +//Futaba + case 3: //Futaba + p->need_refresh=0; // 1 if displays need refresh after changing custonchars + p->customchars=3; // number of customchaaracters the display provides + p->vbar_cc_offset=0x30; // character offset of the bars + p->hbar_cc_offset=0x30; // character offset of the bars + + // hardwarespecific commands: + // hw_cmd[Command][data] = {{commandlength , command 1}, + // ..... + // {commandlength , command N}} + const char hw_cmd_3[10][4]= {{1 ,0x04, 0x20}, // dark + {1 ,0x04, 0x40}, + {2 ,0x04, 0x60}, + {1 ,0x04, 0xFF}, // bright + {2 ,0x10, 0x00}, // pos1 + {1 ,0x10,}, // move cursor + {1 ,0x1F}, // reset + {1 ,0x11}, // init + {1 ,0x03}, // set user char + {1 ,0x09}}; // tab + for (tmp=0;tmp < (10) ;tmp++) + for (w=0;w < (4) ;w++) + p->hw_cmd[tmp][w]=hw_cmd_3[tmp][w]; + + // Translates ISO 8859-1 to display charset. + const unsigned char charmap_3[] = { + /* #128 = 0x80 */ + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + /* #160 = 0xA0 */ + 160, 0xAD, 0x9B, 0x9C, 0xC8, 0x9D, 0x7C, 0xC0, + '"', '?', 0xA6, 0xAE, 0xAA, '-', '?', '?', + 0xEF, 0xCA, 0xC6, 0xC7, 0x27, 0xB8, '?', '.', + ',', '?', 0xA7, 0xAF, 0xAC, 0xAB, '?', 0xA8, + /* #192 = 0xC0 */ + 0xD0, 'A', 0xD5, 'A', 0x8E, 0x8F, 0x92, 0x80, + 0xD1, 0x90, 0xD6, 0xD3, 'I', 'I', 0xD7, 0xD4, + 'D', 0xA5, 'O', 'O', 0xD8, 'O', 0x99, 'x', + '0', 0xD2, 'U', 0xD9, 0x9A, 'Y', 'p', 0xB1, + /* #224 = 0xE0 */ + 0x85, 0xA0, 0x83, 'a', 0x84, 0x86, 0x91, 0x87, + 0x8A, 0x82, 0x88, 0x89, 0x8D, 0xA1, 0x8C, 0x8B, + 'o', 0xA4, 0x95, 0xA9, 0x93, 'o', 0x94, '/', + '0', 0x97, 0xA3, 0x96, 0x81, 'y', 'p', 0x89 + }; + for (tmp=0;tmp < 128 ;tmp++) + p->charmap[tmp]=charmap_3[tmp]; + + + //{bytes to send, icon bit mapped to bit 0, icon bit mapped to bit 1, ...} + const int usr_chr_dot_assignment_3[57]={5, 8, 7, 6, 5, 4, 3, 2, 1, + 16,15,14,13,12,11,10, 9, + 24,23,22,21,20,19,18,17, + 32,31,30,29,28,27,26,25, + 0, 0, 0, 0, 0,35,34,33}; + for (tmp=0;tmp < 57 ;tmp++) + p->usr_chr_dot_assignment[tmp]=usr_chr_dot_assignment_3[tmp]; + + //Where to place the usercharacters (0..30) in the asciicode. + //Also used to map standardcharacters in the usercharacterspace(0..30) + //(useful for displays with less then 30 usercharacters and predefined bars) + const unsigned int usr_chr_mapping_3[31]= + {0xCD, 0xCE, 0xCF}; + for (tmp=0;tmp < 31 ;tmp++) + p->usr_chr_mapping[tmp]=usr_chr_mapping_3[tmp]; + break; + } + + //initialise display + write (p->fd, &p->hw_cmd[reset][1],p->hw_cmd[reset][0]); + write (p->fd, &p->hw_cmd[init_cmds][1],p->hw_cmd[init_cmds][0]); + serialVFD_set_brightness (drvthis, 1, brightness); + + + report (RPT_DEBUG, "%s: done\n", __FUNCTION__); + return 0; + +} + + +///////////////////////////////////////////////////////////////// +// Changes screen brightness (0-255; 140 seems good) +// +MODULE_EXPORT void +serialVFD_set_brightness (Driver *drvthis, int state, int brightness) +{ + PrivateData *p = drvthis->private_data; + int realbrightness = -1; + + if (brightness > 0) { + if (brightness > 255) + brightness = 255; + if (p->brightness != brightness) + { + realbrightness = (int) (brightness / 64); + write (p->fd, &p->hw_cmd[realbrightness][1],\ + p->hw_cmd[realbrightness][0]); + } + p->brightness=brightness; + } +} + + + +///////////////////////////////////////////////////////////////// +// Draws a vertical bar... +// +MODULE_EXPORT void +serialVFD_vbar (Driver *drvthis, int x, int y, int len, int promille, int options) +{ + PrivateData *p = drvthis->private_data; + + serialVFD_init_vbar(drvthis); + lib_vbar_static(drvthis, x, y, len, promille, options, p->cellheight, p->vbar_cc_offset); +} + +///////////////////////////////////////////////////////////////// +// Draws a horizontal bar to the right. +// + +MODULE_EXPORT void +serialVFD_hbar (Driver *drvthis, int x, int y, int len, int promille, int options) +{ + PrivateData *p = drvthis->private_data; + + serialVFD_init_hbar(drvthis); + lib_hbar_static(drvthis, x, y, len, promille, options, p->cellwidth, p->hbar_cc_offset); + +} + + +///////////////////////////////////////////////////////////////// +// Sets a custom character from 0-7... +// +// For input, value 1 mean "on" and 0 is "off". +// +// The input is just an array of characters... +// +MODULE_EXPORT void +serialVFD_set_char (Driver *drvthis, int n, char *dat) +{ + PrivateData *p = drvthis->private_data; + int letter=0; + unsigned int byte, bit; + + if (n < 0 || n > p->customchars-1) + return; + if (!dat) + return; + + + if(p->display_type==1) + { + for (byte = 0;byte < p->usr_chr_dot_assignment[0]; byte++) + { + for (bit = 0;bit < 8; bit++) + { + if((int)p->usr_chr_dot_assignment[bit+8*byte+1] != 0) + letter |= (dat[(int)p->usr_chr_dot_assignment[bit+8*byte+1]-1] << bit); + } + p->custom_char[n][byte] = letter; + letter = 0; + } + } + else + { + write (p->fd, &p->hw_cmd[set_user_char][1],\ + p->hw_cmd[set_user_char][0]); + + write (p->fd, &p->usr_chr_mapping[n], 1); + + for (byte = 0;byte < p->usr_chr_dot_assignment[0]; byte++) + { + for (bit = 0;bit < 8; bit++) + { + if((int)p->usr_chr_dot_assignment[bit+8*byte+1] != 0) + letter |= (dat[(int)p->usr_chr_dot_assignment[bit+8*byte+1]-1] << bit); + } + write (p->fd, &letter, 1); + letter = 0; + } + } + if (p->need_refresh == 1) + p->custom_char_changed[n]=1; +} + +///////////////////////////////////////////////////////////// +// Blasts a single frame onscreen, to the lcd... +// +// Input is a character array, sized serialVFD->width*serialVFD->height +// +void +serialVFD_draw_frame (Driver *drvthis, char *dat) +{ + PrivateData *p = drvthis->private_data; + int i,j, last_chr=-10; + + if (!dat) + return; + + for (i = 0; i < (p->height * p->width); i++) + { + + /* Backing-store implementation. If it's already + * on the screen, don't put it there again + */ + + if(dat[i] != p->backingstore[i] || (dat[i] <=30 && p->custom_char_changed[(int)dat[i]])) + { + if (last_chr < i-1) // if not last char written cursor has to be moved. + { + if(last_chr < i-2-p->hw_cmd[mv_cursor][0]) + { + write (p->fd, &p->hw_cmd[mv_cursor][1],\ + p->hw_cmd[mv_cursor][0]); + write (p->fd, &i, 1); + } + else + { + for (j = last_chr; j < (i-1); j++) + { + write (p->fd, &p->hw_cmd[hor_tab][1], p->hw_cmd[hor_tab][0]); + } + } + } + + if(dat[i] >= 0 && dat[i] <= 30) + { + if (p->display_type == 1) // KD Rev 2.1 only + { + write (p->fd, "\x1A\xDB", 2); // substitute and select Character to overwrite (237) + write (p->fd, &p->custom_char[(int)dat[i]][0], 7);// overwrite selected Character + write (p->fd, "\xDB", 1); // Write Character + } + else // all other displays + { + write (p->fd, &p->usr_chr_mapping[(int)dat[i]], 1); + } + } + else if(dat[i] < 0 && (p->ISO_8859_1 != 0)) + { + write (p->fd, &p->charmap[dat[i] + 128], 1); + } + else + { + write (p->fd, &dat[i], 1); + } + + last_chr=i; + } + } + + if (last_chr != -10) + { + memcpy(p->backingstore, dat, p->height * p->width); + int i; + for(i=0;i<32;i++) + p->custom_char_changed[i]=0; + } + + +} + + +MODULE_EXPORT void +serialVFD_num( Driver * drvthis, int x, int num ) +{ + int do_init=0; + PrivateData *p = drvthis->private_data; + + + if (p->ccmode != CCMODE_BIGNUM) + { + do_init=1; + p->ccmode = CCMODE_BIGNUM; + } + lib_adv_bignum(drvthis, x, num, p->height, do_init, p->customchars); +} + + + +/* + * Places an icon on screen + */ +MODULE_EXPORT int +serialVFD_icon (Driver *drvthis, int x, int y, int icon) +{ + PrivateData *p = drvthis->private_data; + char icons[2][5 * 7] = { + { + 1, 1, 1, 1, 1, // Empty Heart + 1, 0, 1, 0, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, + 1, 1, 0, 1, 1, + }, + + { + 1, 1, 1, 1, 1, // Filled Heart + 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, + 0, 1, 1, 1, 0, + 0, 1, 1, 1, 0, + 1, 0, 1, 0, 1, + 1, 1, 0, 1, 1, + }, + }; + // Yes we know, this is a VERY BAD implementation :-) + switch (icon) { + case ICON_BLOCK_FILLED: + serialVFD_chr(drvthis, x, y, 127 ); + break; + case ICON_HEART_FILLED: + p->ccmode = CCMODE_STANDARD; + serialVFD_set_char(drvthis, 0, icons[1]); + serialVFD_chr(drvthis, x, y, 0); + break; + case ICON_HEART_OPEN: + p->ccmode = CCMODE_STANDARD; + serialVFD_set_char(drvthis, 0, icons[0]); + serialVFD_chr(drvthis, x, y, 0); +// serialVFD_chr(drvthis, x, y, 127 ); + break; + default: + return -1; // Let the core do other icons + } + return 0; +} + + + +///////////////////////////////////////////////////////////////// +// Sets up for vertical bars. Call before serialVFD->vbar() +// +void +serialVFD_init_vbar (Driver *drvthis) +{ + PrivateData *p = drvthis->private_data; + char a[] = { + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, + }; + char b[] = { + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + }; + char c[] = { + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + }; + char d[] = { + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + }; + char e[] = { + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + }; + char f[] = { + 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + }; + + if (p->ccmode != CCMODE_VBAR) { + p->ccmode = CCMODE_VBAR; + serialVFD_set_char (drvthis, 1, a); + serialVFD_set_char (drvthis, 2, b); + serialVFD_set_char (drvthis, 3, c); + serialVFD_set_char (drvthis, 4, d); + serialVFD_set_char (drvthis, 5, e); + serialVFD_set_char (drvthis, 6, f); + } +} + +///////////////////////////////////////////////////////////////// +// Inits horizontal bars... +// +void +serialVFD_init_hbar (Driver *drvthis) +{ + PrivateData *p = drvthis->private_data; + char a[] = { + 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, + }; + char b[] = { + 1, 1, 0, 0, 0, + 1, 1, 0, 0, 0, + 1, 1, 0, 0, 0, + 1, 1, 0, 0, 0, + 1, 1, 0, 0, 0, + 1, 1, 0, 0, 0, + 1, 1, 0, 0, 0, + }; + char c[] = { + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, + }; + char d[] = { + 1, 1, 1, 1, 0, + 1, 1, 1, 1, 0, + 1, 1, 1, 1, 0, + 1, 1, 1, 1, 0, + 1, 1, 1, 1, 0, + 1, 1, 1, 1, 0, + 1, 1, 1, 1, 0, + }; + + if (p->ccmode != CCMODE_HBAR) { + p->ccmode = CCMODE_HBAR; + serialVFD_set_char (drvthis, 1, a); + serialVFD_set_char (drvthis, 2, b); + serialVFD_set_char (drvthis, 3, c); + serialVFD_set_char (drvthis, 4, d); + } +} + + + + + +///////////////////////////////////////////////////////////////// +// Clears the LCD screen +// +MODULE_EXPORT void +serialVFD_clear (Driver *drvthis) +{ + PrivateData *p = 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 (20,4). +// +MODULE_EXPORT void +serialVFD_string (Driver *drvthis, int x, int y, char string[]) +{ + PrivateData *p = drvthis->private_data; + x--; + y--; + int i; + 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]; + } +} + +///////////////////////////////////////////////////////////////// +// Clean-up +// +MODULE_EXPORT void +serialVFD_close (Driver *drvthis) +{ + PrivateData *p = drvthis->private_data; + if (p != NULL) { + close (p->fd); + + if (p->framebuf) + free (p->framebuf); + + if (p->backingstore) + free (p->backingstore); + free(p); + } + drvthis->store_private_ptr(drvthis, NULL); +} + +/* + * Returns the display width in characters + */ +MODULE_EXPORT int +serialVFD_width (Driver *drvthis) +{ + PrivateData *p = drvthis->private_data; + + return p->width; +} + + +/* + * Returns the display height in characters + */ +MODULE_EXPORT int +serialVFD_height (Driver *drvthis) +{ + PrivateData *p = drvthis->private_data; + + return p->height; +} + +///////////////////////////////////////////////////////////////// +// Returns the maximum number of custom char slots (not how many +// are free at a moment, maybe this isn't even needed... +// +MODULE_EXPORT int +serialVFD_get_free_chars (Driver *drvthis) +{ + PrivateData *p = drvthis->private_data; + return p->customchars; +} +/* + * Returns the width of a character in pixels + */ +MODULE_EXPORT int +serialVFD_cellwidth (Driver *drvthis) +{ + PrivateData *p = drvthis->private_data; + + return p->cellwidth; +} + + +/* + * Returns the height of a character in pixels + */ +MODULE_EXPORT int +serialVFD_cellheight (Driver *drvthis) +{ + PrivateData *p = drvthis->private_data; + + return p->cellheight; +} + + +MODULE_EXPORT void +serialVFD_flush (Driver *drvthis) +{ + PrivateData *p = drvthis->private_data; + serialVFD_draw_frame (drvthis, p->framebuf); +} + + + +///////////////////////////////////////////////////////////////// +// Prints a character on the lcd display, at position (x,y). The +// upper-left is (1,1), and the lower right should be (20,4). +// +MODULE_EXPORT void +serialVFD_chr (Driver *drvthis, int x, int y, char c) +{ + PrivateData *p = drvthis->private_data; + y--; + x--; + + p->framebuf[(y * p->width) + x ] = c; +} + +///////////////////////////////////////////////////////////////// +// +// Retrieves brightness +// +MODULE_EXPORT int +serialVFD_get_brightness(Driver *drvthis, int state) +{ + PrivateData *p = drvthis->private_data; + + return p->brightness; +} + +///////////////////////////////////////////////////////////////// +// provides some info about this driver +// +MODULE_EXPORT char * +serialVFD_get_info (Driver *drvthis) +{ + PrivateData *p = drvthis->private_data; + strcpy(p->info, "Driver for many serialVFDs from NEC(all FIPC based), Noritake, Futaba and the \"KD Rev2.1\"VFD"); + return p->info; +} diff --git a/server/drivers/serialVFD.h b/server/drivers/serialVFD.h new file mode 100644 index 0000000..28891eb --- /dev/null +++ b/server/drivers/serialVFD.h @@ -0,0 +1,70 @@ +/* This is the LCDproc driver for various serial VFD Devices + + Copyright (C) 2006 Stefan Herdler + + This driver is based on drv_base.c, wirz-sli.c and hd44780 from LCDproc + 0.4.5 and the NoritakeVFD driver from this package. + It may contain parts of other drivers of this package too. + + 2006-01-26 Version 0.1: everything should work (not all hardware tested!) + + 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 */ + +#ifndef SERIALVFD_H +#define SERIALVFD_H +#include "lcd.h" +#include "adv_bignum.h" + +#define CCMODE_STANDARD 0 /* only char 0 is used for heartbeat */ +#define CCMODE_VBAR 1 +#define CCMODE_HBAR 2 +#define CCMODE_BIGNUM 3 +#define CCMODE_BIGCHAR 4 +#define CCMODE_CUSTOM 5 + + +#define DEFAULT_CELL_WIDTH 5 +#define DEFAULT_CELL_HEIGHT 7 +#define DEFAULT_DEVICE "/dev/lcd" +#define DEFAULT_SPEED 9600 +#define DEFAULT_BRIGHTNESS 140 +#define DEFAULT_SIZE "20x2" +#define DEFAULT_DISPLAYTYPE 0 + + +MODULE_EXPORT int serialVFD_init (Driver *drvthis); +MODULE_EXPORT void serialVFD_close (Driver *drvthis); +MODULE_EXPORT int serialVFD_width (Driver *drvthis); +MODULE_EXPORT int serialVFD_height (Driver *drvthis); +MODULE_EXPORT int serialVFD_cellwidth (Driver *drvthis); +MODULE_EXPORT int serialVFD_cellheight (Driver *drvthis); +MODULE_EXPORT void serialVFD_clear (Driver *drvthis); +MODULE_EXPORT void serialVFD_flush (Driver *drvthis); +MODULE_EXPORT void serialVFD_string (Driver *drvthis, int x, int y, char string[]); +MODULE_EXPORT void serialVFD_chr (Driver *drvthis, int x, int y, char c); + +MODULE_EXPORT void serialVFD_vbar (Driver *drvthis, int x, int y, int len, int promille, int options); +MODULE_EXPORT void serialVFD_hbar (Driver *drvthis, int x, int y, int len, int promille, int options); +MODULE_EXPORT int serialVFD_icon(Driver *drvthis, int x, int y, int icon); + +MODULE_EXPORT void serialVFD_set_char (Driver *drvthis, int n, char *dat); + +MODULE_EXPORT int serialVFD_get_brightness (Driver *drvthis, int state); +MODULE_EXPORT void serialVFD_set_brightness (Driver *drvthis, int state, int promille); +MODULE_EXPORT void serialVFD_output (Driver *drvthis, int state); +MODULE_EXPORT void serialVFD_num (Driver * drvthis, int x, int num); +MODULE_EXPORT int serialVFD_get_free_chars (Driver *drvthis); +MODULE_EXPORT char * serialVFD_get_info( Driver *drvthis ); +#endif