Discussion:
[Lcdproc] serialVFD driver update
Stefan Herdler
2006-05-17 21:11:02 UTC
Permalink
This is a multi-part message in MIME format.
--------------090006010607090701090706
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

Hi,

I've updated the serialVFD driver. Many changes and improvements have
been made since the last version.
This are the important ones:
- Support for parallel connection added.
- Improved user-character handling to reduce data send to the display
(fixes flicker and reduces cpuload slightly).
- Backlight and brightness functions revised. The client can switch
between 2 brightnesslevels like in the CFontzPacket-driver.
- Driver has been successfully tested on a FUTABA M402SD06GL VFD.
Thanks to Robert Buchholz.
- Documentation updated.

Stefan

--------------090006010607090701090706
Content-Type: text/plain;
name="serialVFD_0.3.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="serialVFD_0.3.diff"

--- ../lcdproc-CVS-current-test/server/drivers/serialVFD.c 2006-04-28 09:00:36.000000000 +0200
+++ ./server/drivers/serialVFD.c 2006-05-17 16:16:45.000000000 +0200
@@ -6,7 +6,7 @@
driver.
It may contain parts of other drivers of this package too.

- 2006-02-13 Version 0.2: everything should work (not all hardware tested!)
+ 2006-05-16 Version 0.3: 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
@@ -24,120 +24,9 @@



- 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 of 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 "/clients/lcdproc/chrono.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.
-
-
-
+ The driver should operate most of NEC, Futaba and Noritake 7x5 dot VFDs with
+ serial(rs232) and/or parallel interface. See /docs/lcdproc-user/serialvfd-howto.html
+ for further information


List of driver entry point:
@@ -147,7 +36,7 @@ close Implemented.
width Implemented.
height Implemented.
clear Implemented by space filling no custom char info.
-flush Calling draw_frame only.
+flush Implemented.
string Implemented.
chr Implemented.
vbar Implemented.
@@ -164,7 +53,7 @@ get_contrast Not implemented, no softwar
set_contrast Not implemented, no software control.
get_brightness Implemented.
set_brightness Implemented.
-backlight Not implemented, no software control.
+backlight Implemented.
output Not implemented.
get_key Not implemented, no keys.
get_info Implemented.
@@ -185,6 +74,7 @@ get_info Implemented.
# include "config.h"
#endif

+
#include "lcd.h"
#include "serialVFD.h"

@@ -192,41 +82,16 @@ get_info Implemented.
#include "lcd_lib.h"
#include "adv_bignum.h"

+#define DEFAULT_OFF_BRIGHTNESS 300
+#define DEFAULT_ON_BRIGHTNESS 1000
+
#define pos1_cursor 4 //moves cursor to top left character.
#define mv_cursor 5 //moves cursor to position specified by the next byte.
#define reset 6 //reset
#define init_cmds 7 //commands needed to initialize the display.
#define set_user_char 8 //set user character.
#define hor_tab 9 //moves cursor 1 chr right
-
-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 int refresh_timer;
- 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;
+#define LPTPORT 0x378

/* Vars for the server core */
MODULE_EXPORT char *api_version = API_VERSION;
@@ -237,8 +102,6 @@ MODULE_EXPORT char *symbol_prefix = "ser
/* Internal functions */
static void serialVFD_init_vbar (Driver *drvthis);
static void serialVFD_init_hbar (Driver *drvthis);
-static void serialVFD_draw_frame (Driver *drvthis, unsigned char *dat);
-static void serialVFD_put_brightness (Driver *drvthis);
static void serialVFD_put_char (Driver *drvthis, int n);

// Opens com port and sets baud correctly...
@@ -246,8 +109,7 @@ static void serialVFD_put_char (Driver *
MODULE_EXPORT int
serialVFD_init (Driver *drvthis)
{
- struct termios portset;
- int tmp, w, h, brightness;
+ int tmp, w, h;
char size[200] = DEFAULT_SIZE;

PrivateData *p;
@@ -265,22 +127,44 @@ serialVFD_init (Driver *drvthis)
p->ccmode = CCMODE_STANDARD;
p->ISO_8859_1 = 1;
p->refresh_timer = 0;
+ p->hw_brightness = 0;

debug(RPT_INFO, "%s(%p)", __FUNCTION__, drvthis );
+
+/* Read config file */

- /* Read config file */
+ p->use_parallel = drvthis->config_get_bool( drvthis->name, "use_parallel", 0, 0 );
+ if (p->use_parallel){
+ p->port = drvthis->config_get_int( drvthis->name, "port", 0, LPTPORT );
+ }
+ else {
/* Which device should be used */
- strncpy(p->device, drvthis->config_get_string(drvthis->name, "Device", 0, DEFAULT_DEVICE), sizeof(p->device));
+ strncpy(p->device, drvthis->config_get_string (drvthis->name, "Device", 0, DEFAULT_DEVICE), sizeof(p->device));
p->device[sizeof(p->device)-1] = '\0';
report(RPT_INFO, "%s: using Device %s", drvthis->name, p->device);

+ /* 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",
+ drvthis->name, 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;
+ }
+// report(RPT_ERR, "%s: Port: %X\n", __FUNCTION__, p->port, strerror (errno));
+
/* 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",
+ report(RPT_WARNING, "%s: cannot parse size: %s; using default %s.",
drvthis->name, size, DEFAULT_SIZE);
sscanf(DEFAULT_SIZE, "%dx%d", &w, &h);
}
@@ -288,14 +172,24 @@ serialVFD_init (Driver *drvthis)
p->height = h;

/* Which backlight brightness */
- tmp = drvthis->config_get_int(drvthis->name, "Brightness", 0, DEFAULT_BRIGHTNESS);
+ tmp = drvthis->config_get_int(drvthis->name, "Brightness", 0, DEFAULT_ON_BRIGHTNESS);
+ debug(RPT_INFO, "%s: Brightness (in config) is '%d'", __FUNCTION__, tmp);
if ((tmp < 0) || (tmp > 1000)) {
report(RPT_WARNING, "%s: Brightness must be between 0 and 1000; using default %d",
- drvthis->name, DEFAULT_BRIGHTNESS);
- tmp = DEFAULT_BRIGHTNESS;
+ drvthis->name, DEFAULT_ON_BRIGHTNESS);
+ tmp = DEFAULT_ON_BRIGHTNESS;
}
- brightness = tmp;
+ p->on_brightness = tmp;

+ /* Which backlight-off "brightness" */
+ tmp = drvthis->config_get_int(drvthis->name, "OffBrightness", 0, DEFAULT_OFF_BRIGHTNESS);
+ debug(RPT_INFO, "%s: OffBrightness (in config) is '%d'", __FUNCTION__, tmp);
+ if ((tmp < 0) || (tmp > 1000)) {
+ report(RPT_WARNING, "%s: OffBrightness must be between 0 and 1000; using default %d",
+ drvthis->name, DEFAULT_OFF_BRIGHTNESS);
+ tmp = DEFAULT_OFF_BRIGHTNESS;
+ }
+ p->off_brightness = tmp;

/* ISO 8859 1 */
p->ISO_8859_1 = drvthis->config_get_bool(drvthis->name, "ISO_8859_1", 0, 1);
@@ -309,57 +203,29 @@ serialVFD_init (Driver *drvthis)
}
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",
- drvthis->name, DEFAULT_SPEED);
- tmp = DEFAULT_SPEED;
+ /* Number of custom characters */
+ tmp = drvthis->config_get_int (drvthis->name, "Custom-Characters", 0, -83);
+ if ((tmp < 0) || (tmp > 99)) {
+ report(RPT_WARNING, "%s: The number of Custom-Characters must be between 0 and 99. Using default.",
+ drvthis->name, 0);
+ tmp = -83;
}
- 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;
+ p->customchars = tmp;


+// report (RPT_ERR, "%s: Port: %X\n", __FUNCTION__, p->port, strerror (errno));

- /* 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(%s) failed (%s)", drvthis->name, p->device, strerror(errno));
+// Do connection type specific io-port init
+ if (Port_Function[p->use_parallel].init_fkt (drvthis)==-1) {
+ report(RPT_ERR, "%s: unable to initialize io-port.", drvthis->name);
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);
-
+// setup frame buffer and backing store
/* 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", drvthis->name);
+ report(RPT_ERR, "%s: unable to create framebuffer.", drvthis->name);
return -1;
}
memset(p->framebuf, ' ', p->width * p->height);
@@ -367,318 +233,85 @@ serialVFD_init (Driver *drvthis)
/* 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", drvthis->name);
+ report(RPT_ERR, "%s: unable to create framebuffer backing store.", drvthis->name);
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;
+ serialVFD_load_display_data(drvthis);

-//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;
+// report (RPT_ERR, "%s: Port: %X\n", drvthis->name, p->port, strerror (errno));

-//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
+ Port_Function[p->use_parallel].write_fkt (drvthis, &p->hw_cmd[reset][1],p->hw_cmd[reset][0]);
+ Port_Function[p->use_parallel].write_fkt (drvthis, &p->hw_cmd[init_cmds][1],p->hw_cmd[init_cmds][0]);
+ serialVFD_backlight(drvthis, 1);
+ report(RPT_DEBUG, "%s: init() done", drvthis->name);
+ return 0;

- //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: init() done", drvthis->name);
+/*
+ * Retrieves brightness (in promille)
+ */

- return 0;
+MODULE_EXPORT int
+serialVFD_get_brightness(Driver *drvthis, int state)
+{
+ PrivateData *p = drvthis->private_data;

+ return (state == BACKLIGHT_ON) ? p->on_brightness : p->off_brightness;
}


-/////////////////////////////////////////////////////////////////
-// Changes screen brightness (0 min ... 255 max ... 1000 also max)
-//
+/*
+ * Sets on/off brightness (in promille)
+ */
MODULE_EXPORT void
-serialVFD_set_brightness (Driver *drvthis, int state, int brightness)
-{ // set p->brightness
+serialVFD_set_brightness(Driver *drvthis, int state, int promille)
+{
PrivateData *p = drvthis->private_data;

- if (brightness > 0) {
- if (brightness > 255)
- brightness = 255;
- if (p->brightness != brightness) {
- p->brightness = brightness;
- serialVFD_put_brightness(drvthis);
- }
+ /* Check it */
+ if (promille < 0 || promille > 1000)
+ return;
+
+ /* store the software value since there is not get */
+ if (state == BACKLIGHT_ON) {
+ p->on_brightness = promille;
+ }
+ else {
+ p->off_brightness = promille;
}
}

-static void
-serialVFD_put_brightness (Driver *drvthis)
-{ // set hardware brightness
+
+/*
+ * Sets the backlight on or off.
+ * The hardware support any value between 0 and 100.
+ */
+MODULE_EXPORT void
+serialVFD_backlight (Driver *drvthis, int on)
+{
PrivateData *p = drvthis->private_data;
- int realbrightness = (int) (p->brightness / 64);
+ int hardware_value = (on == BACKLIGHT_ON)
+ ? p->on_brightness
+ : p->off_brightness;
+
+ // map range [0, 1000] -> [0, 4] that the hardware understands
+ //(4 steps 0-250, 251-500, 501-750, 751-1000)
+ hardware_value /= 251;
+ if(hardware_value != p->hw_brightness){
+ p->hw_brightness=hardware_value;
+ Port_Function[p->use_parallel].write_fkt (drvthis, &p->hw_cmd[p->hw_brightness][1],\
+ p->hw_cmd[p->hw_brightness][0]);
+ }

- //(4 steps 0-64, 65-128, 129-192, 193-1000)
- write(p->fd, &p->hw_cmd[realbrightness][1],\
- p->hw_cmd[realbrightness][0]);
}


+
/////////////////////////////////////////////////////////////////
// Draws a vertical bar...
//
@@ -719,7 +352,7 @@ serialVFD_set_char (Driver *drvthis, int
PrivateData *p = drvthis->private_data;
unsigned int byte, bit;

- if ((n < 0) || (n > p->customchars-1))
+ if (n < 0 || n > p->customchars-1)
return;
if (!dat)
return;
@@ -735,16 +368,11 @@ serialVFD_set_char (Driver *drvthis, int
int posbit = 4 - ((pos-1) % 5);

letter |= ((dat[posbyte] >> posbit) & 1) << bit;;
- }
+ }
}
p->custom_char[n][byte] = letter;
}

- if (p->display_type != 1) //not KD Rev 2.1
- serialVFD_put_char(drvthis, n);
-
- if (p->need_refresh == 1)
- p->custom_char_changed[n] = 1;
}

static void
@@ -752,10 +380,10 @@ serialVFD_put_char (Driver *drvthis, int
{ // put char in display
PrivateData *p = drvthis->private_data;

- write(p->fd, &p->hw_cmd[set_user_char][1],
+ Port_Function[p->use_parallel].write_fkt (drvthis, &p->hw_cmd[set_user_char][1],\
p->hw_cmd[set_user_char][0]);// substitute and select Character to overwrite
- write(p->fd, &p->usr_chr_mapping[n], 1);
- write(p->fd, &p->custom_char[n][0], p->usr_chr_dot_assignment[0]);// overwrite selected Character
+ Port_Function[p->use_parallel].write_fkt (drvthis, (char*)&p->usr_chr_mapping[n], 1);
+ Port_Function[p->use_parallel].write_fkt (drvthis, &p->custom_char[n][0], p->usr_chr_dot_assignment[0]);// overwrite selected Character
}


@@ -765,85 +393,95 @@ serialVFD_put_char (Driver *drvthis, int
//
// Input is a character array, sized serialVFD->width*serialVFD->height
//
-static void
-serialVFD_draw_frame (Driver *drvthis, unsigned char *dat)
+MODULE_EXPORT void
+serialVFD_flush (Driver *drvthis)
{
PrivateData *p = drvthis->private_data;
int i, j, last_chr = -10;
+ char custom_char_changed[32]={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};
+
+
+ for (i = 0; i < p->customchars; i++) {
+ for (j = 0; j < p->usr_chr_dot_assignment[0]; j++) {
+ if (p->custom_char[i][j] != p->custom_char_store[i][j]) {
+ custom_char_changed[i]=1;
+// report (RPT_ERR, "%s: Char: %X %i\n", __FUNCTION__, i, j, strerror (errno));
+ }
+ p->custom_char_store[i][j]=p->custom_char[i][j];
+ }
+ }

- if (!dat)
- return;
if (p->refresh_timer > 500) { // Do a full refresh every 500 refreshs.
// With this it is possible to switch display on and off while lcdproc is running
- write(p->fd, &p->hw_cmd[init_cmds][1],p->hw_cmd[init_cmds][0]);
- serialVFD_put_brightness(drvthis); // restore brightness
+ Port_Function[p->use_parallel].write_fkt (drvthis, &p->hw_cmd[init_cmds][1],p->hw_cmd[init_cmds][0]);
+
+ Port_Function[p->use_parallel].write_fkt (drvthis, &p->hw_cmd[p->hw_brightness][1],\
+ p->hw_cmd[p->hw_brightness][0]); // restore brightness

for (i = 0; i < (p->height * p->width); i++)
- p->backingstore[i] = '\0'; // clear Backing-store
+ p->backingstore[i]=0; // clear Backing-store

- if (p->display_type != 1) {//not KD Rev 2.1
- for (i = 0; i < p->customchars; i++) // refresh all customcharacters
- serialVFD_put_char(drvthis, i);
-/* {
- write(p->fd, &p->hw_cmd[set_user_char][1],\
- p->hw_cmd[set_user_char][0]);// substitute and select character to overwrite
- write(p->fd, &p->usr_chr_mapping[i], 1);
- write(p->fd, &p->custom_char[(int)dat[i]][0], p->usr_chr_dot_assignment[0]);// overwrite selected Character
- }*/
- }
+ for(i=0;i<p->customchars;i++) // refresh all customcharacters
+ custom_char_changed[i]=1;
p->refresh_timer = 0;
}
+
p->refresh_timer++;

+ if (p->display_type != 1) { //not KD Rev 2.1
+ for(i=0;i<p->customchars;i++) // set customcharacters
+ if(custom_char_changed[i])
+ serialVFD_put_char (drvthis, i);
+ }
+
+ if(custom_char_changed[p->last_custom])
+ p->last_custom=-10;
+
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],
+ if(p->framebuf[i] != p->backingstore[i] || (p->framebuf[i] <=30 && custom_char_changed[(int)p->framebuf[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]) {
+ Port_Function[p->use_parallel].write_fkt (drvthis, &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]);
+ Port_Function[p->use_parallel].write_fkt (drvthis, (char*)&i, 1);
}
+ else {
+ for (j = last_chr; j < (i-1); j++)
+ Port_Function[p->use_parallel].write_fkt (drvthis, &p->hw_cmd[hor_tab][1], p->hw_cmd[hor_tab][0]);
}
}

- if (dat[i] <= 30) {// custom character
- 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
+ if(p->framebuf[i] <= 30) { // custom character
+ if (p->display_type == 1) { // KD Rev 2.1 only
+ if (p->last_custom != p->framebuf[i]){
+ Port_Function[p->use_parallel].write_fkt (drvthis, "\x1A\xDB", 2); // substitute and select character to overwrite (237)
+ Port_Function[p->use_parallel].write_fkt (drvthis, &p->custom_char[(int)p->framebuf[i]][0], 7);// overwrite selected character
+ }
+ Port_Function[p->use_parallel].write_fkt (drvthis, "\xDB", 1); // write character
+ p->last_custom = p->framebuf[i];
}
else { // all other displays
- write(p->fd, &p->usr_chr_mapping[(int)dat[i]], 1);
+ Port_Function[p->use_parallel].write_fkt (drvthis, (char*)&p->usr_chr_mapping[(int)p->framebuf[i]], 1);
}
}
- else if (dat[i] > 127 && (p->ISO_8859_1 != 0)) { // ISO_8859_1 translation for 129 ... 255
- write(p->fd, &p->charmap[dat[i] + 128], 1);
+ else if(p->framebuf[i] > 127 && (p->ISO_8859_1 != 0)) { // ISO_8859_1 translation for 129 ... 255
+ Port_Function[p->use_parallel].write_fkt (drvthis, &p->charmap[p->framebuf[i] - 128], 1);
}
else {
- write(p->fd, &dat[i], 1);
+ Port_Function[p->use_parallel].write_fkt (drvthis, &p->framebuf[i], 1);
}

last_chr = i;
}
}

- if (last_chr != -10) { // update backingstore if something changed
- int i;
-
- memcpy(p->backingstore, dat, p->height * p->width);
-
- for (i = 0; i < p->customchars; i++)
- p->custom_char_changed[i] = '\0';
- }
+ if (last_chr != -10) // update backingstore if something changed
+ memcpy(p->backingstore, p->framebuf, p->height * p->width);
}


@@ -863,6 +501,7 @@ serialVFD_num( Driver * drvthis, int x,



+
/*
* Places an icon on screen
*/
@@ -870,7 +509,7 @@ MODULE_EXPORT int
serialVFD_icon (Driver *drvthis, int x, int y, int icon)
{
PrivateData *p = drvthis->private_data;
- static unsigned char heart_open[] =
+ static unsigned char heart_open[] =
{ b__XXXXX,
b__X_X_X,
b_______,
@@ -879,7 +518,7 @@ serialVFD_icon (Driver *drvthis, int x,
b__X___X,
b__XX_XX,
b__XXXXX };
- static unsigned char heart_filled[] =
+ static unsigned char heart_filled[] =
{ b__XXXXX,
b__X_X_X,
b___X_X_,
@@ -969,6 +608,7 @@ MODULE_EXPORT void
serialVFD_clear (Driver *drvthis)
{
PrivateData *p = drvthis->private_data;
+
memset(p->framebuf, ' ', p->width * p->height);

}
@@ -1001,17 +641,16 @@ MODULE_EXPORT void
serialVFD_close (Driver *drvthis)
{
PrivateData *p = drvthis->private_data;
-
if (p != NULL) {
- close(p->fd);
-
+ if (p->fd >= 0)
+ close(p->fd);
if (p->framebuf)
free(p->framebuf);
-
if (p->backingstore)
free(p->backingstore);
free(p);
}
+
drvthis->store_private_ptr(drvthis, NULL);
}

@@ -1073,16 +712,6 @@ serialVFD_cellheight (Driver *drvthis)
}


-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).
@@ -1091,23 +720,14 @@ MODULE_EXPORT void
serialVFD_chr (Driver *drvthis, int x, int y, char c)
{
PrivateData *p = drvthis->private_data;
-
+ if ((x > p->width) || (y > p->height))
+ return;
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
@@ -1116,7 +736,6 @@ MODULE_EXPORT const 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;
}
--- ../lcdproc-CVS-current-test/server/drivers/serialVFD.h 2006-04-26 09:00:40.000000000 +0200
+++ ./server/drivers/serialVFD.h 2006-05-16 14:47:20.000000000 +0200
@@ -6,7 +6,7 @@
driver.
It may contain parts of other drivers of this package too.

- 2006-02-13 Version 0.2: everything should work (not all hardware tested!)
+ 2006-05-16 Version 0.3: 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
@@ -26,6 +26,8 @@
#define SERIALVFD_H
#include "lcd.h"
#include "adv_bignum.h"
+#include "serialVFD_displays.h"
+#include "serialVFD_io.h"

#define CCMODE_STANDARD 0 /* only char 0 is used for heartbeat */
#define CCMODE_VBAR 1
@@ -63,8 +65,43 @@ MODULE_EXPORT void serialVFD_set_char (D

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_backlight (Driver *drvthis, int on);
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 const char * serialVFD_get_info( Driver *drvthis );
+
+typedef struct driver_private_data {
+ int use_parallel; // use parallel?
+ unsigned int port; // Port in parallel mode
+ char device[200]; // Device in serial mode
+ int fd;
+ int speed; // Speed in serial mode
+ /* 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 on_brightness;
+ int off_brightness;
+ int hw_brightness;
+ int customchars;
+ int ISO_8859_1;
+ unsigned int refresh_timer;
+ unsigned char charmap[128];
+ int display_type; // display type
+ int last_custom; // last custom character written
+ char custom_char[31][7]; // stored custom characters
+ char custom_char_store[31][7]; // custom characters backingstore
+ 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;
+
#endif
--- ../lcdproc-CVS-current-test/server/drivers/serialVFD_io.c 1970-01-01 01:00:00.000000000 +0100
+++ ./server/drivers/serialVFD_io.c 2006-05-17 01:03:56.000000000 +0200
@@ -0,0 +1,127 @@
+/* This file is part the LCDproc driver for various serial VFD Devices.
+
+ It contains the hardwaredependent commands ach characterset.
+
+ If you want to add a new device to the driver add a new section
+ to the displaytype-switch-case in the init-function, add a new load_...
+ function below 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.)
+
+ Copyright (C) 2006 Stefan Herdler
+
+ 2006-05-15 Version 0.3: 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
+
+*/
+
+
+#include "port.h"
+#include "serialVFD_io.h"
+#include "serialVFD.h"
+#include "lcd.h"
+#define WR_on 0x10
+#define WR_off 0x11
+#define Busy 0x80
+#define LPTPORT 0x378
+
+#define MAXBUSY 300
+
+void
+serialVFD_write_serial (Driver *drvthis, char *dat, size_t length)
+{
+ PrivateData *p = drvthis->private_data;
+ write (p->fd,dat,length);
+}
+
+void
+serialVFD_write_parallel (Driver *drvthis, char *dat, size_t length)
+{
+ PrivateData *p = drvthis->private_data;
+ int i_para, j_para;
+
+ for(i_para = 0; i_para < length; i_para++) {
+ port_out(p->port, dat[i_para]);
+ port_in(p->port+1);
+ port_out(p->port+2, WR_on);
+ port_in(p->port+1);
+ port_out(p->port+2, WR_off);
+
+ for(j_para=0; j_para < MAXBUSY; j_para++) {
+ if((port_in(p->port+1)) & Busy)
+ break;
+ }
+ }
+}
+
+int
+serialVFD_init_serial (Driver *drvthis)
+{
+ PrivateData *p = drvthis->private_data;
+ struct termios portset;
+
+ /* 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);
+ return 0;
+}
+
+int
+serialVFD_init_parallel (Driver *drvthis)
+{
+ int ret=0;
+ PrivateData *p = drvthis->private_data;
+ debug( RPT_DEBUG, "%s: Opening parallelport at: 0x%X", __FUNCTION__, p->port);
+// if(port_access_multiple(p->port,3)) return -1;
+ if(port_access(p->port) != 0) ret=-1;
+ if(port_access(p->port+1) != 0) ret=-1;
+ if(port_access(p->port+2) != 0) ret=-1;
+ if(ret == -1) {
+ report (RPT_ERR, "%s: port_access() of 0x%X failed (%s)\n", __FUNCTION__, p->port, strerror (errno));
+ return -1;
+ }
+ return 0;
+}
+
+
--- ../lcdproc-CVS-current-test/server/drivers/serialVFD_io.h 1970-01-01 01:00:00.000000000 +0100
+++ ./server/drivers/serialVFD_io.h 2006-05-16 14:46:09.000000000 +0200
@@ -0,0 +1,65 @@
+/* This is the LCDproc driver for various serial VFD Devices
+
+ Copyright (C) 2006 Stefan Herdler
+
+ 2006-05-16 Version 0.3: 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_IO_H
+#define SERIALVFD_IO_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <syslog.h>
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "serialVFD_displays.h"
+#include "port.h"
+#include "lpt-port.h"
+#include "lcd.h"
+#include "serialVFD.h"
+#include "report.h"
+
+
+int serialVFD_init_serial (Driver *drvthis);
+int serialVFD_init_parallel (Driver *drvthis);
+void serialVFD_write_serial (Driver *drvthis, char *dat, size_t length);
+void serialVFD_write_parallel (Driver *drvthis, char *dat, size_t length);
+
+typedef struct Port_fkt {
+ void (*write_fkt) (Driver *drvthis, char *dat, size_t length);
+ int (*init_fkt) (Driver *drvthis);
+} Port_fkt;
+
+
+static const Port_fkt Port_Function[] = {
+ // initialisation function
+ // write function
+
+ {serialVFD_write_serial, serialVFD_init_serial},
+ {serialVFD_write_parallel, serialVFD_init_parallel}
+};
+
+
+#endif
--- ../lcdproc-CVS-current-test/server/drivers/serialVFD_displays.c 1970-01-01 01:00:00.000000000 +0100
+++ ./server/drivers/serialVFD_displays.c 2006-05-17 01:07:26.000000000 +0200
@@ -0,0 +1,336 @@
+/* This file is part the LCDproc driver for various serial VFD Devices.
+
+ It contains the hardwaredependent commands ach characterset.
+
+ If you want to add a new device to the driver add a new section
+ to the displaytype-switch-case in the init-function, add a new load_...
+ function below 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.)
+
+ Copyright (C) 2006 Stefan Herdler
+
+ 2006-05-16 Version 0.3: 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
+
+*/
+
+#include "serialVFD_displays.h"
+#include "serialVFD.h"
+#include "lcd.h"
+
+void serialVFD_load_NEC_FIPC (Driver *drvthis);
+void serialVFD_load_KD (Driver *drvthis);
+void serialVFD_load_Noritake (Driver *drvthis);
+void serialVFD_load_Futaba (Driver *drvthis);
+
+
+void serialVFD_load_display_data(Driver *drvthis)
+{
+ PrivateData *p = (PrivateData*) drvthis->private_data;
+ switch (p->display_type)
+ {
+ case 0:
+ serialVFD_load_NEC_FIPC (drvthis);
+ break;
+ case 1:
+ serialVFD_load_KD (drvthis);
+ break;
+ case 2:
+ serialVFD_load_Noritake (drvthis);
+ break;
+ case 3:
+ serialVFD_load_Futaba (drvthis);
+ break;
+ }
+}
+
+
+
+void
+serialVFD_load_NEC_FIPC (Driver *drvthis)
+{ //nec_fipc
+ PrivateData *p = (PrivateData*) drvthis->private_data;
+ int tmp, w;
+
+ if (p->customchars == -83)
+ 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[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[tmp][w];
+
+ // Translates ISO 8859-1 to display charset.
+ const unsigned char charmap[] = {
+ /* #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[tmp];
+
+ //{bytes to send, icon bit mapped to bit 0, icon bit mapped to bit 1, ...}
+ const int usr_chr_dot_assignment[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[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[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[tmp];
+}
+
+void
+serialVFD_load_KD (Driver *drvthis)
+{ //KD Rev2.1
+ PrivateData *p = (PrivateData*) drvthis->private_data;
+ int tmp, w;
+
+ if (p->customchars == -83)
+ 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[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[tmp][w];
+
+ const unsigned char charmap[] = {
+ /* #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[tmp];
+
+
+ //{bytes to send, icon bit mapped to bit 0, icon bit mapped to bit 1, ...}
+ const int usr_chr_dot_assignment[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[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[31]=
+ {0xAF};
+ for (tmp=0;tmp < 31 ;tmp++)
+ p->usr_chr_mapping[tmp]=usr_chr_mapping[tmp];
+}
+
+void
+serialVFD_load_Noritake (Driver *drvthis)
+{ //Noritake
+ PrivateData *p = (PrivateData*) drvthis->private_data;
+ int tmp, w;
+
+ if (p->customchars == -83)
+ 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[10][4]={{3 ,0x1B, 0x4C, 0x00}, // dark
+ {3 ,0x1B, 0x4C, 0x50},
+ {3 ,0x1B, 0x4C, 0x90},
+ {3 ,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[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[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[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[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[tmp];
+}
+void
+serialVFD_load_Futaba (Driver *drvthis)
+{ //Futaba
+ PrivateData *p = (PrivateData*) drvthis->private_data;
+ int tmp, w;
+
+ if (p->customchars == -83)
+ 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[10][4]={{2 ,0x04, 0x20}, // dark
+ {2 ,0x04, 0x40},
+ {2 ,0x04, 0x60},
+ {2 ,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[tmp][w];
+
+ // Translates ISO 8859-1 to display charset.
+ const unsigned char charmap[] = {
+ /* #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[tmp];
+
+
+ //{bytes to send, icon bit mapped to bit 0, icon bit mapped to bit 1, ...}
+ const int usr_chr_dot_assignment[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[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[31]=
+ {0xCD, 0xCE, 0xCF};
+ for (tmp=0;tmp < 31 ;tmp++)
+ p->usr_chr_mapping[tmp]=usr_chr_mapping[tmp];
+ }
--- ../lcdproc-CVS-current-test/server/drivers/serialVFD_displays.h 1970-01-01 01:00:00.000000000 +0100
+++ ./server/drivers/serialVFD_displays.h 2006-05-16 14:46:31.000000000 +0200
@@ -0,0 +1,28 @@
+/* This is the LCDproc driver for various serial VFD Devices
+
+ Copyright (C) 2006 Stefan Herdler
+
+ 2006-05-16 Version 0.3: 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_DISPLAYS_H
+#define SERIALVFD_DISPLAYS_H
+
+#include "lcd.h"
+#include "serialVFD.h"
+
+void serialVFD_load_display_data(Driver *drvthis);
+#endif
--- ../lcdproc-CVS-current-test/server/drivers/Makefile.am 2006-05-08 23:56:19.000000000 +0200
+++ ./server/drivers/Makefile.am 2006-05-17 01:08:44.000000000 +0200
@@ -82,7 +82,7 @@ NoritakeVFD_SOURCES = lcd.h lcd_lib.h No
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
-serialVFD_SOURCES = lcd.h lcd_lib.h serialVFD.c serialVFD.h report.h adv_bignum.h
+serialVFD_SOURCES = lcd.h lcd_lib.h serialVFD.c serialVFD.h report.h adv_bignum.h serialVFD_displays.c serialVFD_displays.h serialVFD_io.c serialVFD_io.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 lcd_lib.h t6963.c t6963.h t6963_font.h report.h
--- ../lcdproc-CVS-current-test/docs/lcdproc-user/drivers/serialVFD.docbook 2006-04-05 12:36:59.000000000 +0200
+++ ./docs/lcdproc-user/drivers/serialVFD.docbook 2006-05-16 22:58:44.000000000 +0200
@@ -2,69 +2,116 @@
<title>The serialVFD Driver</title>

<para>
-This section talks about using LCDproc with LCD displays that use the
-serialVFD chipset.
+This section talks about using LCDproc with VFD character-displays build by NEC, FUTABA and NORITAKE.
</para>

-<sect2 id="serialVFD-connections">
-<title>Connections</title>

+<para>
+The serialVFD-driver is working with NEC FIPC8367 based VFDs
+and the "KD Rev 2.1" (an ATMEL AT90S.... based FM20X2KB-AB replacement).
+ It is also known to work on FUTABA VFDs.</para>

-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.
+<para>
+The driver should operate most of NEC, Futaba and Noritake 7x5 dot VFDs with
+ serial(rs232) and/or parallel interface. See the following table for testing-status.
+ Feedback is welcome.

-The driver may work or will be easy to get working on the following
-Displays / Controllers (not tested!).

-<table>
-<tgroup cols="2">
+<table><title>serialVFD: Display Status</title>
+<tgroup cols="5">
<thead>
<row>
<entry>Display</entry>
<entry>Controller</entry>
+ <entry>Serial</entry>
+ <entry>Parallel</entry>
+ <entry>Display tested</entry>
+ <entry>Remark</entry>
</row>
</thead>
<tbody>
<row>
+ <entry>NEC FM20X2KB-AB</entry>
+ <entry>NEC FIPC8367</entry>
+ <entry>Ok</entry>
+ <entry>Ok</entry>
+ <entry>Yes</entry>
+ <entry> </entry>
+ </row>
+ <row>
+ <entry>NEC FC20X2JA</entry>
+ <entry>NEC FIPC8367</entry>
+ <entry>(Ok)</entry>
+ <entry>(Ok)</entry>
+ <entry>No</entry>
+ <entry>Same Controller as on FM20X2KB-AB</entry>
+ </row>
+ <row>
+ <entry>NEC FC20X1SA-AB/AA</entry>
+ <entry>NEC FIPC8367</entry>
+ <entry>(Ok)</entry>
+ <entry>(Ok)</entry>
+ <entry>No</entry>
+ <entry>Same Controller as on FM20X2KB-AB</entry>
+ </row>
+ <row>
+ <entry>KD Rev 2.1</entry>
+ <entry>AT90S....
+ microcontroller</entry>
+ <entry>Ok</entry>
+ <entry>Ok</entry>
+ <entry>Yes</entry>
+ <entry> </entry>
+ </row>
+
+ <row>
+ <entry>FUTABA M402SD06GJ</entry>
+ <entry>?</entry>
+ <entry>(?)*</entry>
+ <entry>Ok</entry>
+ <entry>Yes</entry>
+ <entry>(* perhaps no compatible baudrate, not tested)
+ The display has no user-characters set <command>Custom-Characters=0</command>
+ in <filename>LCDd.conf.</filename></entry>
+ </row>
+ <row>
<entry>FUTABA M204SD01AA</entry>
<entry>FUTABA 5P00A016</entry>
+ <entry>(Ok)</entry>
+ <entry>(Ok)</entry>
+ <entry>No</entry>
+ <entry> </entry>
</row>
+
+
<row>
<entry>Noritake CU20026SCPB-T</entry>
- <entry>(microcontroller)</entry>
+ <entry>microcontroller</entry>
+ <entry>(Ok)</entry>
+ <entry>(Ok)</entry>
+ <entry>No</entry>
+ <entry> </entry>
+
</row>
<row>
<entry>Noritake CU20045SCPB-T28A</entry>
<entry>?</entry>
+ <entry>(Ok)</entry>
+ <entry>(Ok)</entry>
+ <entry>No</entry>
+ <entry> </entry>
</row>
</tbody>
</tgroup>
</table>
-
-... or compatible.
-(most Futaba/Noritake 7x5 dot VFDs with serial(rs232) interface
-(including serial(rs232)/parallel types))
-
-<para>
-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.
+() feature not tested.
</para>
-
<para>
-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 correct commands for the display.
-(Try which displaytype works best with your display, copy and modify
-it's section that is the easiest way I guess.)
+If your display isn't working 100% satisfactorily you can add a new device with modified hardware
+commands to the driver if you want. To do that you have to add a new section to the display-
+<command>Type=</command>-switch-case in <filename>./server/drivers/serialVFD-displays.c</filename>
+and to write a new "load"function with the correct commands for the display.(Try which display-<command>Type=</command>
+works best with your display, copy, rename and modify this function that is the easiest way I guess.)
</para>

<para>
@@ -78,24 +125,25 @@ running. It may take a few minutes until
the display show everything correctly.
</para>

-<para>
-To enable the bignumbers on 2-line displays (only this driver supports
-this yet) you have to edit <filename>clients/lcdproc/chrono.c</filename>
-before compiling.
-In function <function>big_clock_screen</function> you have to replace the
-<literal>4</literal> by a <literal>2</literal> in this line:
-<code>if (lcd_hgt &lt; 4)</code>
-</para>

+<sect2 id="serialVFD-connections">
+<title>Connecting The Display</title>
+<para>The Connections shown have been tested successfully.</para>
+<warning><para>Always cross-check with your datasheet, before connecting your display!
+ Displays of same manufacturer may have different pin assignments!</para></warning>
+<para>With this example connections it will be easy to connect displays with different connector
+ pin-layouts, the pins are commonly named equal in the datasheet.<para>
+
+<sect3 id="serialVFD-serial-connections">
+<title>Serial Connections</title>
<para>
-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.
</para>

<figure>
-<title>serialVFD: Connecting the display</title>
+<title>serialVFD: Serial Inverter</title>
<screen>
<![CDATA[
Computer Display
@@ -121,9 +169,9 @@ pin(signal)
| --->- A*
| E| |
| | |
-5(GND) --------o----------o----o----------------- GND
-
-Shield ------------------------------------------
+5(GND) --------o----------o----o--------------o-- GND
+ |*
+Shield ---------------------------------------o
optional

*connect near display
@@ -131,25 +179,27 @@ optional
</screen>
</figure>

-The pins on the different displays vary.
+<para>The pins on the different displays vary.</para>

+<para><title>NEC Displays (FM20X2KB-AB):</title></para>

-FM20X2KB-AB:
-
-CN1:
+<para>CN1:</para>
+<screen><![CDATA[
Pin 33 &lt;--- RxD
(Testmode: connect pins 25 and 26, then power up)
+]]></screen>

-CN2:
+<para>CN2:</para>
+<screen><![CDATA[
Pin 1 &lt;--- +5V
Pin 2 &lt;--- GND
+]]></screen>


-
-KD Rev 2.1:
-
-blue connector (6pin in a row) (the important one!):
-
+<para><title>KD Rev 2.1:</title></para>
+<para>
+The blue connector (6pin in a row) (the important one!):
+</para>
<screen>
<![CDATA[
--------------------------------
@@ -163,33 +213,147 @@ blue connector (6pin in a row) (the impo
Hold the display in that position where you can read
the "KD Rev 2.1" marking normally!
</para>
-</tip>
+</tip>

-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.
+<para>The gray connector (10pin 2 rows):</para>
+<screen>
+<![CDATA[Do not use. (the ATMEL ISP connector I guess)
+]]>
+</screen>
+<para>The two jumpers next to the gray connector:</para>
+<screen>
+<![CDATA[Normally not used.
You can activate two different testmodes with them.
+]]>
+</screen>

-</sect2>
+</sect3>
+
+<sect3 id="serialVFD-parallel-connections">
+<title>Parallel Connections</title>
+
+
+<para><title>NEC Displays (FM20X2KB-AB):</title></para>
+
+<para>CN1:</para>
+<screen><![CDATA[
+parallel Port: Display (NEC):
+Pin: Name: Name: Pin:
+
+1 /STROBE -------------- /WR 1
+2 D0 -------------- D0 15
+3 D1 -------------- D1 13
+4 D2 -------------- D2 11
+5 D3 -------------- D3 9
+6 D4 -------------- D4 7
+7 D5 -------------- D5 5
+8 D6 -------------- D6 3
+9 D7 -------------- D7 1
+10 /ACK --o
+ |
+11 BUSY --o----------- BUSY 27
+
+ o-- /CS 23
+ |
+18 - 25 GND ------------o-- GND 2,4,6,8,10,12,14,16,18,20,22,24,26,28,20,32,34
+ |*
+Shield -------------------o
+optional

+*connect near display
+]]></screen>
+<para>CN2:</para>
+<screen><![CDATA[
+Pin 1 &lt;--- +5V
+Pin 2 &lt;--- GND
+]]></screen>
+
+<para><title>FUTABA Displays (M402SD06GJ):</title></para>
+<screen><![CDATA[
+parallel Port: Display (FUTABA):
+Pin: Name: Name: Pin:
+
+1 /STROBE -------------- /WR 1
+2 D0 -------------- D0 15
+3 D1 -------------- D1 13
+4 D2 -------------- D2 11
+5 D3 -------------- D3 9
+6 D4 -------------- D4 7
+7 D5 -------------- D5 5
+8 D6 -------------- D6 3
+9 D7 -------------- D7 1
+10 /ACK --o
+ |
+11 BUSY --o----------- BUSY 20
+
+ o-- /SEL 23
+ |
+18 - 25 GND ------------o-- GND 10,12,14
+ |*
+Shield -------------------o
+optional
+ 0-- TEST 16
+ |
+ +5V -------o-- +5V 2,4,6
+
+*connect near display
+]]></screen>
+
+</sect3>
+</sect2>
<!-- ## Serial VFD driver ## -->
<sect2 id="serialVFD-config">
<title>Configuration in LCDd.conf</title>

+
<sect3>
<title>[serialVFD]</title>

<variablelist>
+
+<varlistentry>
+ <term>
+ <command>use_parallel=</command>
+ <arg choice="plain">
+ <group choice="req">
+ <arg choice="plain"><literal><emphasis>yes</emphasis></literal></arg>
+ <arg choice="plain"><literal>no</literal></arg>
+ </group>
+ </arg>
+ </term>
+ <listitem><para>
+ "<literal>no</literal>" if display connected serial, "<literal>yes</literal>" if connected parallel [default: <literal>no</literal>(serial)].
+ </para></listitem>
+</varlistentry>
+
+<varlistentry>
+ <term>
+ <command>Port=</command>
+ <arg choice="plain"><replaceable>PORT</replaceable></arg>
+ </term>
+ <listitem><para>
+ Portaddress where the LPT is. Used in parallelmode only. Usual values are 0x278, 0x378 and 0x3BC [default: <literal>0x278</literal>].
+ </para></listitem>
+</varlistentry>
+
<varlistentry>
<term>
<command>Device=</command>
<arg choice="plain"><replaceable>DEVICE</replaceable></arg>
</term>
<listitem><para>
- Device where the VFD is. Usual values are <filename>/dev/ttyS0</filename> and <filename>/dev/ttyS1</filename>
- Default: <filename>/dev/lcd</filename>
+ Device to use in serial mode. Usual values are <filename>/dev/ttyS0</filename> and <filename>/dev/ttyS1</filename>
+ [default: <filename>/dev/lcd</filename>].
+ </para></listitem>
+</varlistentry>
+
+<varlistentry>
+ <term>
+ <command>Custom-Characters=</command>
+ <arg choice="plain"><replaceable>CUSTOM-CHARACTERS</replaceable></arg>
+ </term>
+ <listitem><para>
+Number of Custom-Characters [default: Display-<command>Type</command> dependent].
</para></listitem>
</varlistentry>

@@ -204,7 +368,7 @@ You can activate two different testmodes
</term>
<listitem><para>
Specifies the size of the VFD.
- default: <literal>20x2</literal>
+ [default: <literal>20x2</literal>]
</para></listitem>
</varlistentry>

@@ -247,7 +411,7 @@ You can activate two different testmodes
</tgroup>
</informaltable>
<note><para>
- Options 3 and 4 should work, but have not been tested yet. Feedback is welcome.
+ Noritake VFDs have not been tested yet. Feedback is welcome.
</para></note>
</listitem>
</varlistentry>
@@ -258,9 +422,21 @@ You can activate two different testmodes
<arg choice="plain"><replaceable>BRIGHTNESS</replaceable></arg>
</term>
<listitem><para>
- Display brightness [default: 255].
- 0 min ... 255 max ... 1000 also max
- (4 steps 0-64, 65-128, 129-192, 193-1000)
+Set the initial brightness [default: 1000; legal: 0 - 1000]
+ (4 steps 0-250, 251-500, 501-750, 751-1000)
+ </para></listitem>
+</varlistentry>
+
+<varlistentry>
+ <term>
+ <command>OffBrightness=</command>
+ <arg choice="plain"><replaceable>OFFBRIGHTNESS</replaceable></arg>
+ </term>
+ <listitem><para>
+Set the initial off-brightness [default: 0; legal: 0 - 1000].
+ This value is used when the display is normally
+ switched off in case LCDd is inactive.
+ (4 steps 0-250, 251-500, 501-750, 751-1000)
</para></listitem>
</varlistentry>

@@ -279,7 +455,7 @@ You can activate two different testmodes
</term>
<listitem><para>
Set the the baud rate communication with the VFD.
- If not given, it defaults to <literal>9600</literal>.
+ If not given [default <literal>9600</literal>].
</para></listitem>
</varlistentry>

@@ -294,7 +470,7 @@ You can activate two different testmodes
</arg>
</term>
<listitem><para>
- Enable ISO-8859-1 compatibility. Ddefault is <literal>yes</literal>.
+ Enable ISO-8859-1 compatibility [default is <literal>yes</literal>].
</para></listitem>
</varlistentry>
</variablelist>
--- ../lcdproc-CVS-current-test/docs/LCDd.8 2006-04-14 15:05:00.000000000 +0200
+++ ./docs/LCDd.8 2006-05-16 23:04:52.000000000 +0200
@@ -169,7 +169,7 @@ SED1330/SED1335 (aka S1D13300/S1D13305)
122x32 pixel graphic displays based on SED1520 controllers
.TP
.B serialVFD
-NEC FIPC8367 based serial VFDs
+NEC (FIPC8367 based) and FUTABA VFDs
.TP
.B sli
Wirz SLI driver (unknown)
--- ../lcdproc-CVS-current-test/LCDd.conf 2006-05-08 23:56:19.000000000 +0200
+++ ./LCDd.conf 2006-05-17 16:27:06.000000000 +0200
@@ -662,30 +662,44 @@ Port=0x378
## Serial VFD driver ##
## Drives various (see below) serial 5x7dot VFD's. ##
[serialVFD]
-# device where the VFD is. Usual values are /dev/ttyS0 and /dev/ttyS1
+
+# 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.)
+Type=0
+
+# "no" if display connected serial, "yes" if connected parallel. [default: no(serial)]
+use_parallel=no
+
+# Number of Custom-Characters [default: displaytype dependent]
+#Custom-Characters=0
+
+# Portaddress where the LPT is. Used in parallelmode only. Usual values are 0x278, 0x378 and 0x3BC
+Port=0x378
+
+# Device to use in serial mode. Usual values are /dev/ttyS0 and /dev/ttyS1
Device=/dev/ttyS1

# Specifies the size of the VFD.
Size=20x2

-# Specifies the display type [default: 0]
-# 0 NEC (FIPC8367 based) VFDs.
-# 1 KD Rev 2.1.
-# 2 Noritake VFDs (*).
-# 3 Futaba VFDs (*).
-# (* most should work, not tested yet.)
-Type=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 initial brightness [default: 1000; legal: 0 - 1000]
+# (4 steps 0-250, 251-500, 501-750, 751-1000)
+Brightness=1000
+# Set the initial off-brightness [default: 0; legal: 0 - 1000]
+# This value is used when the display is normally
+# switched off in case LCDd is inactive
+# (4 steps 0-250, 251-500, 501-750, 751-1000)
+OffBrightness=0

-# set the serial port speed [default: 9600; legal: 1200, 2400, 9600, 19200, 115200]
+# set the serial port speed [default: 9600]
Speed=9600

-# enable ISO 8859 1 compatibility [default: yes; legal: yes, no]
-ISO_8859_1=yes
+# enable ISO 8859 1 compatibility [default: 1]
+# ISO_8859_1=1




--------------090006010607090701090706--
Peter Marschall
2006-05-20 19:43:02 UTC
Permalink
Hi,
Post by Stefan Herdler
I've updated the serialVFD driver. Many changes and improvements have
been made since the last version.
- Support for parallel connection added.
- Improved user-character handling to reduce data send to the display
(fixes flicker and reduces cpuload slightly).
- Backlight and brightness functions revised. The client can switch
between 2 brightnesslevels like in the CFontzPacket-driver.
- Driver has been successfully tested on a FUTABA M402SD06GL VFD.
Thanks to Robert Buchholz.
- Documentation updated.
Committed to CVS (with a few comment updates in LCDd.conf)

Thanks !
Peter
--
Peter Marschall
***@adpm.de
Loading...