serialVFD driver:

* Add more documentation about the inner working of this driver.
* Consolidate constant definitions.
* Stop the 'include-mania': Only include necessary header files within the .c
  files.
* Use lpt-port.h to define LPT port register values.
* Modify some comments to conform the the style guide.
This commit is contained in:
mmdolze
2010-12-09 21:25:42 +00:00
parent 04039c5b97
commit 68d4903b4b
6 changed files with 576 additions and 448 deletions
+142 -147
View File
@@ -1,66 +1,46 @@
/** \file server/drivers/serialVFD.c /** \file server/drivers/serialVFD.c
* LCDd \c serialVFD driver for various serial (& parallel) VFD devices. * LCDd \c serialVFD driver for various serial (& parallel) VFD devices.
*
* 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.
*
* This driver consists of three parts:
* \li This file \c serialVFD.c implements most the driver API.
* \li \c serialVFD_io.c implements low-level I/O functions for serial and
* parallel ports.
* \li \c serialVFD_displays.c initializes display-specific character mappings
* and command sequences.
*/
/*-
* Copyright (C) 2006 Stefan Herdler
*
* This driver is based on wirz-sli.c, hd44780.c, drv_base.c and NoritakeVFD
* driver. It may contain parts of other drivers of this package too.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*/ */
/* /*
Copyright (C) 2006 Stefan Herdler * 2006-05-16 Version 0.3: everything should work (not all hardware tested!)
*/
This driver is based on wirz-sli.c, hd44780.c, drv_base.c and NoritakeVFD
driver.
It may contain parts of other drivers of this package too.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
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:
init Implemented.
close Implemented.
width Implemented.
height Implemented.
clear Implemented by space filling no custom char info.
flush Implemented.
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 Implemented.
output Not implemented.
get_key Not implemented, no keys.
get_info Implemented.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
@@ -69,22 +49,18 @@ get_info Implemented.
#include <fcntl.h> #include <fcntl.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <syslog.h>
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "lcd.h" #include "lcd.h"
#include "serialVFD.h"
#include "report.h" #include "report.h"
#include "lcd_lib.h" #include "lcd_lib.h"
#include "adv_bignum.h" #include "adv_bignum.h"
#include "serialVFD.h"
#include "serialVFD_displays.h"
#include "serialVFD_io.h"
#define DEFAULT_OFF_BRIGHTNESS 300 /*
#define DEFAULT_ON_BRIGHTNESS 1000 * This file uses __FUNCTION__ in debug() and drvthis->name in report() calls.
*/
#define pos1_cursor 4 //moves cursor to top left character. #define pos1_cursor 4 //moves cursor to top left character.
#define mv_cursor 5 //moves cursor to position specified by the next byte. #define mv_cursor 5 //moves cursor to position specified by the next byte.
@@ -93,7 +69,6 @@ get_info Implemented.
#define set_user_char 8 //set user character. #define set_user_char 8 //set user character.
#define hor_tab 9 //moves cursor 1 chr right #define hor_tab 9 //moves cursor 1 chr right
#define next_line 10 //moves cursor to the first character of the next line (= LF + CR) #define next_line 10 //moves cursor to the first character of the next line (= LF + CR)
#define LPTPORT 0x378
/* Vars for the server core */ /* Vars for the server core */
MODULE_EXPORT char *api_version = API_VERSION; MODULE_EXPORT char *api_version = API_VERSION;
@@ -123,6 +98,8 @@ serialVFD_init (Driver *drvthis)
PrivateData *p; PrivateData *p;
debug(RPT_INFO, "%s(%p)", __FUNCTION__, drvthis);
/* Allocate and store private data */ /* Allocate and store private data */
p = (PrivateData *) calloc(1, sizeof(PrivateData)); p = (PrivateData *) calloc(1, sizeof(PrivateData));
if (p == NULL) if (p == NULL)
@@ -138,25 +115,20 @@ serialVFD_init (Driver *drvthis)
p->refresh_timer = 480; p->refresh_timer = 480;
p->hw_brightness = 0; p->hw_brightness = 0;
p->para_wait = DEFAULT_PARA_WAIT; p->para_wait = DEFAULT_PARA_WAIT;
p->hw_cmd[next_line][0] = 0; p->hw_cmd[next_line][0] = 0; /* disable line / set normal mode */
debug(RPT_INFO, "%s(%p)", __FUNCTION__, drvthis);
/* Read config file */
/* Connection type: parallel or serial? */
p->use_parallel = drvthis->config_get_bool(drvthis->name, "use_parallel", 0, 0); p->use_parallel = drvthis->config_get_bool(drvthis->name, "use_parallel", 0, 0);
/* Which device should be used */ /* 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'; p->device[sizeof(p->device)-1] = '\0';
report(RPT_INFO, "%s: using Device %s", drvthis->name, p->device); report(RPT_INFO, "%s: using Device %s", drvthis->name, p->device);
if (p->use_parallel) { if (p->use_parallel) {
p->port = drvthis->config_get_int(drvthis->name, "port", 0, LPTPORT); p->port = drvthis->config_get_int(drvthis->name, "port", 0, DEFAULT_LPTPORT);
} }
else { else {
/* Which speed */ /* Which speed */
tmp = drvthis->config_get_int(drvthis->name, "Speed", 0, DEFAULT_SPEED); tmp = drvthis->config_get_int(drvthis->name, "Speed", 0, DEFAULT_SPEED);
if ((tmp != 1200) && (tmp != 2400) && (tmp != 9600) && (tmp != 19200) && (tmp != 115200)) { if ((tmp != 1200) && (tmp != 2400) && (tmp != 9600) && (tmp != 19200) && (tmp != 115200)) {
@@ -170,7 +142,6 @@ serialVFD_init (Driver *drvthis)
else if (tmp == 19200) p->speed = B19200; else if (tmp == 19200) p->speed = B19200;
else if (tmp == 115200) p->speed = B115200; else if (tmp == 115200) p->speed = B115200;
} }
// report(RPT_ERR, "%s: Port: %X", __FUNCTION__, p->port, strerror(errno));
/* Which size */ /* Which size */
strncpy(size, drvthis->config_get_string(drvthis->name, "Size", 0, DEFAULT_SIZE), sizeof(size)); strncpy(size, drvthis->config_get_string(drvthis->name, "Size", 0, DEFAULT_SIZE), sizeof(size));
@@ -212,24 +183,20 @@ serialVFD_init (Driver *drvthis)
p->display_type = drvthis->config_get_int(drvthis->name, "Type", 0, DEFAULT_DISPLAYTYPE); p->display_type = drvthis->config_get_int(drvthis->name, "Type", 0, DEFAULT_DISPLAYTYPE);
/* Number of custom characters */ /* Number of custom characters */
tmp = drvthis->config_get_int(drvthis->name, "Custom-Characters", 0, -83); tmp = drvthis->config_get_int(drvthis->name, "Custom-Characters", 0, CC_UNSET);
if ((tmp < 0) || (tmp > 99)) { if ((tmp < 0) || (tmp > 99)) {
report(RPT_WARNING, "%s: The number of Custom-Characters must be between 0 and 99. Using default", report(RPT_WARNING, "%s: The number of Custom-Characters must be between 0 and 99. Using default",
drvthis->name, 0); drvthis->name, 0);
tmp = -83; tmp = CC_UNSET;
} }
p->customchars = tmp; p->customchars = tmp;
/* Do connection type specific io-port init */
// report(RPT_ERR, "%s: Port: %X", __FUNCTION__, p->port, strerror(errno));
// Do connection type specific io-port init
if (Port_Function[p->use_parallel].init_fkt(drvthis) == -1) { if (Port_Function[p->use_parallel].init_fkt(drvthis) == -1) {
report(RPT_ERR, "%s: unable to initialize io-port", drvthis->name); report(RPT_ERR, "%s: unable to initialize io-port", drvthis->name);
return -1; return -1;
} }
// setup frame buffer and backing store
/* make sure the frame buffer is there... */ /* make sure the frame buffer is there... */
p->framebuf = (unsigned char *) malloc(p->width * p->height); p->framebuf = (unsigned char *) malloc(p->width * p->height);
if (p->framebuf == NULL) { if (p->framebuf == NULL) {
@@ -246,8 +213,8 @@ serialVFD_init (Driver *drvthis)
} }
memset(p->backingstore, 0, p->width * p->height); memset(p->backingstore, 0, p->width * p->height);
//setup displayspecific data /* setup displayspecific data */
memset(p->usr_chr_mapping, 0, 31); memset(p->usr_chr_mapping, 0, 31); /* no character mapping by default */
memset(p->usr_chr_load_mapping, 0, 31); memset(p->usr_chr_load_mapping, 0, 31);
if (serialVFD_load_display_data(drvthis) != 0) { if (serialVFD_load_display_data(drvthis) != 0) {
report(RPT_WARNING, "%s: Type %d not defined; using default %d", report(RPT_WARNING, "%s: Type %d not defined; using default %d",
@@ -259,24 +226,24 @@ serialVFD_init (Driver *drvthis)
} }
} }
/* parallel port wait */ /* Things to set up after loading display specific data */
/* parallel port wait, overwrites value set by display specific data */
tmp = p->para_wait; tmp = p->para_wait;
p->para_wait = drvthis->config_get_int(drvthis->name, "PortWait", 0, p->para_wait); p->para_wait = drvthis->config_get_int(drvthis->name, "PortWait", 0, p->para_wait);
/* load user defined character mapping table */
if ((p->usr_chr_load_mapping[0] == 0) && (p->usr_chr_load_mapping[1] == 0)){ //this should not happen if usr_chr_load_mapping had been set if ((p->usr_chr_load_mapping[0] == 0) && (p->usr_chr_load_mapping[1] == 0)){ //this should not happen if usr_chr_load_mapping had been set
memcpy(p->usr_chr_load_mapping, p->usr_chr_mapping, 31); memcpy(p->usr_chr_load_mapping, p->usr_chr_mapping, 31);
} }
/* initialise display */
// report(RPT_ERR, "%s: Port: %X", drvthis->name, p->port, strerror(errno));
//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[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]); Port_Function[p->use_parallel].write_fkt(drvthis, &p->hw_cmd[init_cmds][1],p->hw_cmd[init_cmds][0]);
serialVFD_backlight(drvthis, 1); serialVFD_backlight(drvthis, 1);
report(RPT_DEBUG, "%s: init() done", drvthis->name); report(RPT_DEBUG, "%s: init() done", drvthis->name);
return 0; return 0;
} }
@@ -387,64 +354,66 @@ serialVFD_flush (Driver *drvthis)
for (j = 0; j < p->usr_chr_dot_assignment[0]; j++) { for (j = 0; j < p->usr_chr_dot_assignment[0]; j++) {
if (p->custom_char[i][j] != p->custom_char_store[i][j]) { if (p->custom_char[i][j] != p->custom_char_store[i][j]) {
custom_char_changed[i] = 1; custom_char_changed[i] = 1;
// report(RPT_ERR, "%s: Char: %X %i", __FUNCTION__, i, j, strerror(errno)); }
}
p->custom_char_store[i][j] = p->custom_char[i][j]; p->custom_char_store[i][j] = p->custom_char[i][j];
} }
} }
if (p->refresh_timer > 500) { // Do a full refresh every 500 refreshs. /* Do a full refresh every 500 refreshs. */
// With this it is possible to switch the display on and off while LCDd is running if (p->refresh_timer > 500) {
/* With this it is possible to switch the display on and off
* while LCDd is running. */
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[init_cmds][1],p->hw_cmd[init_cmds][0]);
Port_Function[p->use_parallel].write_fkt(drvthis, &p->hw_cmd[p->hw_brightness][1],\ Port_Function[p->use_parallel].write_fkt(drvthis, &p->hw_cmd[p->hw_brightness][1],\
p->hw_cmd[p->hw_brightness][0]); // restore brightness p->hw_cmd[p->hw_brightness][0]); /* restore brightness */
memset(p->backingstore, 0, p->width * p->height); // clear Backing-store memset(p->backingstore, 0, p->width * p->height); /* clear Backing-store */
for (i = 0; i < p->customchars; i++) // refresh all customcharacters for (i = 0; i < p->customchars; i++) /* refresh all customcharacters */
custom_char_changed[i] = 1; custom_char_changed[i] = 1;
p->refresh_timer = 0; p->refresh_timer = 0;
} }
p->refresh_timer++; p->refresh_timer++;
if (p->display_type == 1) { // KD Rev 2.1 only if (p->display_type == 1) { /* KD Rev 2.1 only */
if (custom_char_changed[p->last_custom]) if (custom_char_changed[p->last_custom])
p->last_custom = -10; p->last_custom = -10;
} }
else { // other Displays else { /* other Displays */
for (i = 0; i < p->customchars; i++) // set customcharacters for (i = 0; i < p->customchars; i++) /* set customcharacters */
if (custom_char_changed[i]) if (custom_char_changed[i])
serialVFD_put_char(drvthis, i); serialVFD_put_char(drvthis, i);
} }
/* normal mode Display */
if (p->hw_cmd[next_line][0] == 0) { // normal mode Display if (p->hw_cmd[next_line][0] == 0) {
if (p->hw_cmd[mv_cursor][0] == 0) { // Workaround for Displays that doesn't support mv_cursor command /* Workaround for Displays that doesn't support mv_cursor
* command */
if (p->hw_cmd[mv_cursor][0] == 0) {
Port_Function[p->use_parallel].write_fkt(drvthis, &p->hw_cmd[pos1_cursor][1], p->hw_cmd[pos1_cursor][0]); Port_Function[p->use_parallel].write_fkt(drvthis, &p->hw_cmd[pos1_cursor][1], p->hw_cmd[pos1_cursor][0]);
last_chr = -1; last_chr = -1;
} }
for (i = 0; i < (p->height * p->width); i++) { for (i = 0; i < (p->height * p->width); i++) {
/*
/* Backing-store implementation. If it's already * Backing-store implementation. If it's already
* on the screen, don't put it there again * on the screen, don't put it there again.
*/ */
if ((p->framebuf[i] != p->backingstore[i]) || (p->hw_cmd[hor_tab][0] == 0) || if ((p->framebuf[i] != p->backingstore[i]) || (p->hw_cmd[hor_tab][0] == 0) ||
((p->framebuf[i] <= 30) && (custom_char_changed[(int)p->framebuf[i]] != 0))) { ((p->framebuf[i] <= 30) && (custom_char_changed[(int)p->framebuf[i]] != 0))) {
if (last_chr < i-1) { // if not last char written cursor has to be moved. if (last_chr < i-1) { /* if not last char written cursor has to be moved. */
if (((p->hw_cmd[hor_tab][0] * (i-1-last_chr)) > (p->hw_cmd[mv_cursor][0]+1)) && (p->hw_cmd[mv_cursor][0] != 0)) { if (((p->hw_cmd[hor_tab][0] * (i-1-last_chr)) > (p->hw_cmd[mv_cursor][0]+1)) && (p->hw_cmd[mv_cursor][0] != 0)) {
Port_Function[p->use_parallel].write_fkt(drvthis, &p->hw_cmd[mv_cursor][1], Port_Function[p->use_parallel].write_fkt(drvthis, &p->hw_cmd[mv_cursor][1],
p->hw_cmd[mv_cursor][0]); p->hw_cmd[mv_cursor][0]);
Port_Function[p->use_parallel].write_fkt(drvthis, (unsigned char *) &i, 1); Port_Function[p->use_parallel].write_fkt(drvthis, (unsigned char *) &i, 1);
//report(RPT_WARNING, "%s: move %d", drvthis->name, i); debug(RPT_DEBUG, "%s: move %d", __FUNCTION__, i);
} }
else { else {
for (j = last_chr; j < (i-1); j++) 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]); Port_Function[p->use_parallel].write_fkt(drvthis, &p->hw_cmd[hor_tab][1], p->hw_cmd[hor_tab][0]);
//report(RPT_WARNING, "%s: TAB %d", drvthis->name, j-last_chr); debug(RPT_DEBUG, "%s: TAB %d", __FUNCTION__, j-last_chr);
} }
} }
serialVFD_hw_write(drvthis, i); serialVFD_hw_write(drvthis, i);
@@ -452,23 +421,25 @@ serialVFD_flush (Driver *drvthis)
} }
} }
} }
/* line mode Display (partitially borrowed from serialPOS.c) */
else { // line mode Display (partitially borrowed from serialPOS.c) else {
for (j = 0; j < p->height; j++) { for (j = 0; j < p->height; j++) {
// set pointers to start of the line in frame buffer & backing store /* set pointers to start of the line in frame buffer
* & backing store */
unsigned char *sp = p->framebuf + (j * p->width); unsigned char *sp = p->framebuf + (j * p->width);
unsigned char *sq = p->backingstore + (j * p->width); unsigned char *sq = p->backingstore + (j * p->width);
/* Move to start of line */
if (j == 0) { if (j == 0) {
Port_Function[p->use_parallel].write_fkt(drvthis, &p->hw_cmd[pos1_cursor][1], p->hw_cmd[pos1_cursor][0]); Port_Function[p->use_parallel].write_fkt(drvthis, &p->hw_cmd[pos1_cursor][1], p->hw_cmd[pos1_cursor][0]);
} }
else { else {
Port_Function[p->use_parallel].write_fkt(drvthis, &p->hw_cmd[next_line][1], p->hw_cmd[next_line][0]); Port_Function[p->use_parallel].write_fkt(drvthis, &p->hw_cmd[next_line][1], p->hw_cmd[next_line][0]);
} }
// skip over identical lines /* skip over identical lines */
if ( memcmp(sp, sq, p->width) == 0) { if (memcmp(sp, sq, p->width) == 0) {
/* The lines are the same. */
continue; continue;
} }
/* write the data */
for (i = 0; i < p->width; i++) { for (i = 0; i < p->width; i++) {
serialVFD_hw_write(drvthis, (i + (j * p->width))); serialVFD_hw_write(drvthis, (i + (j * p->width)));
} }
@@ -476,9 +447,10 @@ serialVFD_flush (Driver *drvthis)
} }
} }
if (last_chr >= 0) { // update backingstore if something changed /* update backingstore if something changed */
if (last_chr >= 0) {
memcpy(p->backingstore, p->framebuf, p->height * p->width); memcpy(p->backingstore, p->framebuf, p->height * p->width);
//report(RPT_WARNING, "%s: memcpy", drvthis->name); debug(RPT_DEBUG, "%s: memcpy", __FUNCTION__);
} }
} }
@@ -500,7 +472,7 @@ serialVFD_string (Driver *drvthis, int x, int y, const char string[])
x--; x--;
y--; y--;
for (i = 0; string[i] != '\0'; i++) { for (i = 0; string[i] != '\0'; i++) {
// Check for buffer overflows... /* Check for buffer overflows... */
if ((y * p->width) + x + i > (p->width * p->height)) if ((y * p->width) + x + i > (p->width * p->height))
break; break;
p->framebuf[(y * p->width) + x + i] = string[i]; p->framebuf[(y * p->width) + x + i] = string[i];
@@ -590,11 +562,12 @@ serialVFD_num(Driver * drvthis, int x, int num)
PrivateData *p = drvthis->private_data; PrivateData *p = drvthis->private_data;
int do_init = 0; int do_init = 0;
if (p->ccmode != CCMODE_BIGNUM) { // Are the customcharacters set up correctly? If not: if (p->ccmode != CCMODE_BIGNUM) {
do_init = 1; // Lib_adv_bignum has to set the customcharacters. /* If custom characters are not yet set up Lib_adv_bignum has
p->ccmode = CCMODE_BIGNUM; // Switch customcharactermode to bignum. * to do it. */
do_init = 1;
p->ccmode = CCMODE_BIGNUM;
} }
// Lib_adv_bignum does everything needed to show the bignumbers.
lib_adv_bignum(drvthis, x, num, 0, do_init); lib_adv_bignum(drvthis, x, num, 0, do_init);
} }
@@ -631,7 +604,6 @@ serialVFD_icon (Driver *drvthis, int x, int y, int icon)
b__XX_XX, b__XX_XX,
b__XXXXX }; b__XXXXX };
// Yes we know, this is a VERY BAD implementation :-)
switch (icon) { switch (icon) {
case ICON_BLOCK_FILLED: case ICON_BLOCK_FILLED:
serialVFD_chr(drvthis, x, y, 127); serialVFD_chr(drvthis, x, y, 127);
@@ -655,7 +627,7 @@ serialVFD_icon (Driver *drvthis, int x, int y, int icon)
serialVFD_chr(drvthis, x, y, 0x23); serialVFD_chr(drvthis, x, y, 0x23);
break; break;
default: default:
return -1; // Let the core do other icons return -1; /* Let the core do other icons */
} }
return 0; return 0;
} }
@@ -677,6 +649,10 @@ serialVFD_get_free_chars (Driver *drvthis)
/** /**
* Define a custom character and write it to the VFD. * Define a custom character and write it to the VFD.
*
* Converts the 5x7 matrix of bits stored in 7 bytes into a VFD specific
* byte sequence.
*
* \param drvthis Pointer to driver structure. * \param drvthis Pointer to driver structure.
* \param n Custom character to define [0 - (p->customchars)]. * \param n Custom character to define [0 - (p->customchars)].
* \param dat Array of 7(=cellheight) bytes, each representing a pixel row * \param dat Array of 7(=cellheight) bytes, each representing a pixel row
@@ -686,7 +662,7 @@ serialVFD_get_free_chars (Driver *drvthis)
*/ */
MODULE_EXPORT void MODULE_EXPORT void
serialVFD_set_char (Driver *drvthis, int n, unsigned char *dat) serialVFD_set_char (Driver *drvthis, int n, unsigned char *dat)
{ //set char in p->custom_char {
PrivateData *p = drvthis->private_data; PrivateData *p = drvthis->private_data;
unsigned int byte, bit; unsigned int byte, bit;
@@ -699,6 +675,7 @@ serialVFD_set_char (Driver *drvthis, int n, unsigned char *dat)
int letter = 0; int letter = 0;
for (bit = 0; bit < 8; bit++) { for (bit = 0; bit < 8; bit++) {
/* map bit from 5x7 matrix into current byte/bit */
int pos = (int) p->usr_chr_dot_assignment[bit+8*byte+1]; int pos = (int) p->usr_chr_dot_assignment[bit+8*byte+1];
if (pos > 0) { if (pos > 0) {
@@ -769,8 +746,10 @@ serialVFD_backlight (Driver *drvthis, int on)
? p->on_brightness ? p->on_brightness
: p->off_brightness; : p->off_brightness;
// map range [0, 1000] -> [0, 4] that the hardware understands /*
//(4 steps 0-250, 251-500, 501-750, 751-1000) * map range [0, 1000] -> [0, 4] that the hardware understands
* (4 steps 0-250, 251-500, 501-750, 751-1000)
*/
hardware_value /= 251; hardware_value /= 251;
if (hardware_value != p->hw_brightness) { if (hardware_value != p->hw_brightness) {
p->hw_brightness = hardware_value; p->hw_brightness = hardware_value;
@@ -817,7 +796,7 @@ serialVFD_init_vbar (Driver *drvthis)
memset(vBar, 0x00, sizeof(vBar)); memset(vBar, 0x00, sizeof(vBar));
for (i = 1; i < p->cellheight; i++) { for (i = 1; i < p->cellheight; i++) {
// add pixel line per pixel line ... /* add pixel line per pixel line ... */
vBar[p->cellheight - i] = 0xFF; vBar[p->cellheight - i] = 0xFF;
serialVFD_set_char(drvthis, i, vBar); serialVFD_set_char(drvthis, i, vBar);
} }
@@ -845,7 +824,7 @@ serialVFD_init_hbar (Driver *drvthis)
p->ccmode = CCMODE_HBAR; p->ccmode = CCMODE_HBAR;
for (i = 1; i < p->cellwidth; i++) { for (i = 1; i < p->cellwidth; i++) {
// fill pixel columns from left to right. /* fill pixel columns from left to right. */
memset(hBar, 0xFF & ~((1 << (p->cellwidth - i)) - 1), sizeof(hBar)); memset(hBar, 0xFF & ~((1 << (p->cellwidth - i)) - 1), sizeof(hBar));
serialVFD_set_char(drvthis, i, hBar); serialVFD_set_char(drvthis, i, hBar);
} }
@@ -853,39 +832,55 @@ serialVFD_init_hbar (Driver *drvthis)
} }
/**
* Put a custom character in the display's RAM. The character definition is
* read from custom_char cache.
* \param drvthis Pointer to driver
* \param n Index of the custom character in cache
*/
static void static void
serialVFD_put_char (Driver *drvthis, int n) serialVFD_put_char (Driver *drvthis, int n)
{ // put userchar in display {
PrivateData *p = drvthis->private_data; PrivateData *p = drvthis->private_data;
Port_Function[p->use_parallel].write_fkt(drvthis, &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 p->hw_cmd[set_user_char][0]);
Port_Function[p->use_parallel].write_fkt(drvthis, (unsigned char *) &p->usr_chr_load_mapping[n], 1); Port_Function[p->use_parallel].write_fkt(drvthis, (unsigned char *) &p->usr_chr_load_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 Port_Function[p->use_parallel].write_fkt(drvthis, &p->custom_char[n][0], p->usr_chr_dot_assignment[0]);// overwrite selected Character
} }
/**
* Finally write character/usercharacter on the display.
* Written characters in area 128...255 are mapped according to charmap if
* ISO_8859_1 is enabled.
* \param drvthis Pointer to driver
* \param i Index of character in framebuffer to write
*
*/
static void static void
serialVFD_hw_write (Driver *drvthis, int i) serialVFD_hw_write (Driver *drvthis, int i)
{ // finally write character/usercharacter on the display {
PrivateData *p = drvthis->private_data; PrivateData *p = drvthis->private_data;
if (p->framebuf[i] <= 30) { // custom character if (p->framebuf[i] <= 30) { /* custom character */
if (p->display_type == 1) { // KD Rev 2.1 only if (p->display_type == 1) { /* KD Rev 2.1 only */
if (p->last_custom != p->framebuf[i]) { if (p->last_custom != p->framebuf[i]) {
// substitute and select character to overwrite (237) /* substitute and select character to overwrite (237) */
Port_Function[p->use_parallel].write_fkt(drvthis, (unsigned char *)"\x1A\xDB", 2); Port_Function[p->use_parallel].write_fkt(drvthis, (unsigned char *)"\x1A\xDB", 2);
// overwrite selected character /* overwrite selected character */
Port_Function[p->use_parallel].write_fkt(drvthis, &p->custom_char[(int)p->framebuf[i]][0], 7); Port_Function[p->use_parallel].write_fkt(drvthis, &p->custom_char[(int)p->framebuf[i]][0], 7);
} }
Port_Function[p->use_parallel].write_fkt(drvthis, (unsigned char *)"\xDB", 1); // write character /* write character */
Port_Function[p->use_parallel].write_fkt(drvthis, (unsigned char *)"\xDB", 1);
p->last_custom = p->framebuf[i]; p->last_custom = p->framebuf[i];
} }
else { // all other displays else { /* all other displays */
Port_Function[p->use_parallel].write_fkt(drvthis, (unsigned char *) &p->usr_chr_mapping[(int)p->framebuf[i]], 1); Port_Function[p->use_parallel].write_fkt(drvthis, (unsigned char *) &p->usr_chr_mapping[(int)p->framebuf[i]], 1);
} }
} }
else if ((p->framebuf[i] == 127) || ((p->framebuf[i] > 127) && (p->ISO_8859_1 != 0))) { // ISO_8859_1 translation for 129 ... 255 else if ((p->framebuf[i] == 127) || ((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] - 127], 1); Port_Function[p->use_parallel].write_fkt(drvthis, &p->charmap[p->framebuf[i] - 127], 1);
} }
else { else {
+44 -45
View File
@@ -1,35 +1,32 @@
/* This is the LCDproc driver for various serial VFD Devices /*-
* Copyright (C) 2006 Stefan Herdler
*
* This driver is based on wirz-sli.c, hd44780.c, drv_base.c and NoritakeVFD
* driver. It may contain parts of other drivers of this package too.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*/
Copyright (C) 2006 Stefan Herdler /*
* 2006-05-16 Version 0.3: everything should work (not all hardware tested!)
This driver is based on wirz-sli.c, hd44780.c, drv_base.c and NoritakeVFD */
driver.
It may contain parts of other drivers of this package too.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */
#ifndef SERIALVFD_H #ifndef SERIALVFD_H
#define SERIALVFD_H #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_STANDARD 0 /* only char 0 is used for heartbeat */
#define CCMODE_VBAR 1 #define CCMODE_VBAR 1
#define CCMODE_HBAR 2 #define CCMODE_HBAR 2
#define CCMODE_BIGNUM 3 #define CCMODE_BIGNUM 3
@@ -45,6 +42,9 @@
#define DEFAULT_SIZE "20x2" #define DEFAULT_SIZE "20x2"
#define DEFAULT_DISPLAYTYPE 0 #define DEFAULT_DISPLAYTYPE 0
#define DEFAULT_PARA_WAIT 2 #define DEFAULT_PARA_WAIT 2
#define DEFAULT_OFF_BRIGHTNESS 300
#define DEFAULT_ON_BRIGHTNESS 1000
#define DEFAULT_LPTPORT 0x378
MODULE_EXPORT int serialVFD_init (Driver *drvthis); MODULE_EXPORT int serialVFD_init (Driver *drvthis);
@@ -74,39 +74,38 @@ MODULE_EXPORT const char * serialVFD_get_info( Driver *drvthis );
/** private data for the \c serialVFD driver */ /** private data for the \c serialVFD driver */
typedef struct serialVFD_private_data { typedef struct serialVFD_private_data {
int use_parallel; // use parallel? int use_parallel; /**< use parallel port? */
unsigned short port; // Port in parallel mode unsigned short port; /**< port in parallel mode */
char device[200]; // Device in serial mode char device[200]; /**> device in serial mode */
int fd; int fd; /**< file descriptor in serial mode */
int speed; // Speed in serial mode int speed; /**< Speed in serial mode */
/* dimensions */ /* dimensions */
int width, height; int width, height;
int cellwidth, cellheight; int cellwidth, cellheight;
/* framebuffer and buffer for old LCD contents */ /* framebuffer and buffer for old LCD contents */
unsigned char *framebuf; unsigned char *framebuf;
unsigned char *backingstore; unsigned char *backingstore;
/* defineable characters */
int ccmode; int ccmode;
int on_brightness; int on_brightness;
int off_brightness; int off_brightness;
int hw_brightness; int hw_brightness;
int customchars; int customchars;
int predefined_hbar; int predefined_hbar; /**< display has predefined hbar-characters */
int predefined_vbar; int predefined_vbar; /**< display has predefined vbar-characters */
int ISO_8859_1; int ISO_8859_1;
unsigned int refresh_timer; unsigned int refresh_timer;
unsigned int para_wait; unsigned int para_wait;
unsigned char charmap[129]; unsigned char charmap[129];
int display_type; // display type int display_type; /**< display type */
int last_custom; // last custom character written int last_custom; /**< last custom character written */
unsigned char custom_char[31][7]; // stored custom characters unsigned char custom_char[31][7]; /**< stored custom characters */
unsigned char custom_char_store[31][7]; // custom characters backingstore unsigned char custom_char_store[31][7]; /**< custom characters backingstore */
unsigned char hw_cmd[11][10]; // hardwarespecific commands unsigned char hw_cmd[11][10]; /**< table of hardwarespecific commands */
int usr_chr_dot_assignment[57]; // how to setup usercharacters 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 unsigned int usr_chr_mapping[31]; /**< where to place the usercharacters (0..30) in the asciicode */
unsigned int usr_chr_load_mapping[31];// needed for displays with different read and write mapping unsigned int usr_chr_load_mapping[31]; /**< needed for displays with different read and write mapping */
int hbar_cc_offset; // character offset of the bars int hbar_cc_offset; /**< character offset of the bars */
int vbar_cc_offset; // character offset of the bars int vbar_cc_offset; /**< character offset of the bars */
char info[255]; char info[255];
} PrivateData; } PrivateData;
+237 -150
View File
@@ -1,42 +1,99 @@
/** \file server/drivers/serialVFD_displays.c /** \file server/drivers/serialVFD_displays.c
* Setup routines for the inidividual displays supported by the \c serialVFD driver. * Setup routines for the inidividual displays supported by the \c serialVFD driver.
*
* Here are the routines that set up the data as well as function pointers * Here are the routines that set up the data as well as function pointers
* for the individual displays supported by the \c serialVFD driver. * for the individual displays supported by the \c serialVFD driver.
*
* 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.)
*
* For each display the following setting have to be set in
* serialVFD_private_data:
*
* \li customchars Number of possible custom characters
* \li predefined_hbar The display has predefined hbar-characters
* \li hbar_cc_offset Offset of the predefined hbar-characters
* \li predefined_vbar The display has predefined vbar-characters
* \li vbar_cc_offset Offset of the predefined vbar-characters
* \li hw_cmd Table with hardware commands (see below)
* \li charmap Table mapping characters 127...255 to other chars
* \li usr_chr_dot_assignment Mapping of icon bits (see below)
* \li usr_chr_mapping Map indicating which chars may be overwritten in RAM
* \li usr_chr_load_mapping Location byte (see below)
*
* \b hw_cmd:
* The hw_cmd is a two-dimensional array used as a table to store hardware-
* dependant command. 10 commands are supported. For each command a byte
* array is set with the 1st byte defining the command length (which may be
* zero) and up to 9 bytes of command. The following commands exist:
*
* \li Set brightness level 0
* \li Set brightness level 1
* \li Set brightness level 2
* \li Set brightness level 3
* \li Move cursor to Pos1
* \li Move cursor to position X
* \li Reset
* \li Initialize
* \li Set user character
* \li Horizontal tab
* \li Move cursor to next line
*
*\verbatim
* hw_cmd[Command][data] = {{commandlength , command 1},
* .....
* {commandlength , command N}}
*\endverbatim
*
* \b usr_chr_dot_assignment:
* usr_chr_dot_assignment is an array specifying how our 5x7 matrix of custom
* character bits are mapped into user defined characters (UDC). The very
* first byte of usr_chr_dot_assignment gives the number of bytes this VFD
* uses for one UDC. The remaining numbers give which byte/bit if a UDC hold
* which bit of the 5x7 matrix.
*
* Note: LSB of an icon line is the leftmost entry in the array!
*
* \b usr_chr_load_mapping:
* Usually any character may be overwritten in RAM. Some VFD however use
* an index number for user defined characters. The usr_chr_load_mapping
* array specifies which byte of usr_chr_mapping is assigned which index.
*
* For displays not using index numbers usr_chr_load_mapping is a copy of
* usr_chr_mapping.
*/ */
/* This file is part the LCDproc driver for various serial VFD Devices. /*-
* Copyright (C) 2006 Stefan Herdler
*
* This driver is based on wirz-sli.c, hd44780.c, drv_base.c and NoritakeVFD
* driver. It may contain parts of other drivers of this package too.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*/
It contains the hardwaredependent commands ach characterset. /*
* 2006-05-16 Version 0.3: everything should work (not all hardware tested!)
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*/
#include "lcd.h"
#include "serialVFD_displays.h" #include "serialVFD_displays.h"
#include "serialVFD.h" #include "serialVFD.h"
#include "lcd.h"
void serialVFD_load_NEC_FIPC (Driver *drvthis); void serialVFD_load_NEC_FIPC (Driver *drvthis);
void serialVFD_load_KD (Driver *drvthis); void serialVFD_load_KD (Driver *drvthis);
@@ -48,6 +105,11 @@ void serialVFD_load_Futaba_NA202SD08FA(Driver *drvthis);
void serialVFD_load_Samsung (Driver *drvthis); void serialVFD_load_Samsung (Driver *drvthis);
void serialVFD_load_Nixdorf_BA6x (Driver *drvthis); void serialVFD_load_Nixdorf_BA6x (Driver *drvthis);
/**
* Load display specific settings.
* \param drvthis Pointer to driver
* \return 0 on success; -1 if unknown display type selected in config
*/
int serialVFD_load_display_data(Driver *drvthis) int serialVFD_load_display_data(Driver *drvthis)
{ {
PrivateData *p = (PrivateData*) drvthis->private_data; PrivateData *p = (PrivateData*) drvthis->private_data;
@@ -86,24 +148,26 @@ int serialVFD_load_display_data(Driver *drvthis)
return 0; return 0;
} }
/* Init data for NEC FIPS based VFD */
void void
serialVFD_load_NEC_FIPC (Driver *drvthis) serialVFD_load_NEC_FIPC (Driver *drvthis)
{ //nec_fipc {
PrivateData *p = (PrivateData*) drvthis->private_data; PrivateData *p = (PrivateData*) drvthis->private_data;
int tmp, w; int tmp, w;
if (p->customchars == -83) if (p->customchars == CC_UNSET)
p->customchars = 1; // number of custom characters the display provides p->customchars = 1;
p->vbar_cc_offset = 5; // character offset of the bars p->vbar_cc_offset = 5;
p->hbar_cc_offset = 12; // character offset of the bars p->hbar_cc_offset = 12;
p->predefined_hbar = 1; // the display has predefined hbar-characters p->predefined_hbar = 1;
p->predefined_vbar = 1; // the display has predefined vbar-characters p->predefined_vbar = 1;
// hardwarespecific commands: /*-
// hw_cmd[Command][data] = {{commandlength , command 1}, * hardwarespecific commands:
// ..... * hw_cmd[Command][data] = {{commandlength , command 1},
// {commandlength , command N}} * .....
* {commandlength , command N}};
*/
const char hw_cmd[11][4] = {{1 ,0x04}, // dark const char hw_cmd[11][4] = {{1 ,0x04}, // dark
{1 ,0x03}, {1 ,0x03},
{1 ,0x02}, {1 ,0x02},
@@ -123,9 +187,9 @@ serialVFD_load_NEC_FIPC (Driver *drvthis)
for (w = 0; w < 4; w++) for (w = 0; w < 4; w++)
p->hw_cmd[tmp][w] = hw_cmd[tmp][w]; p->hw_cmd[tmp][w] = hw_cmd[tmp][w];
// Translates ISO 8859-1 to display charset. /* Translates ISO 8859-1 to display charset. */
const unsigned char charmap[] = { const unsigned char charmap[] = {
127, // the "filled-block"-character usually 127 127, /* the "filled-block"-character usually 127 */
/* #128 = 0x80 */ /* #128 = 0x80 */
128, 129, 130, 131, 132, 133, 134, 135, 128, 129, 130, 131, 132, 133, 134, 135,
136, 137, 138, 139, 140, 141, 142, 143, 136, 137, 138, 139, 140, 141, 142, 143,
@@ -180,23 +244,26 @@ serialVFD_load_NEC_FIPC (Driver *drvthis)
} }
/* Init data for KD Rev2.1 */
void void
serialVFD_load_KD (Driver *drvthis) serialVFD_load_KD (Driver *drvthis)
{ //KD Rev2.1 {
PrivateData *p = (PrivateData*) drvthis->private_data; PrivateData *p = (PrivateData*) drvthis->private_data;
int tmp, w; int tmp, w;
if (p->customchars == -83) if (p->customchars == CC_UNSET)
p->customchars = 31; // number of custom characters the display provides p->customchars = 31;
p->vbar_cc_offset = 0; // character offset of the bars p->vbar_cc_offset = 0;
p->hbar_cc_offset = 0; // character offset of the bars p->hbar_cc_offset = 0;
p->predefined_hbar = 0; // the display has predefined hbar-characters p->predefined_hbar = 0;
p->predefined_vbar = 0; // the display has predefined vbar-characters p->predefined_vbar = 0;
// hardwarespecific commands: /*-
// hw_cmd[Command][data] = {{commandlength , command 1}, * hardwarespecific commands:
// ..... * hw_cmd[Command][data] = {{commandlength , command 1},
// {commandlength , command N}} * .....
* {commandlength , command N}};
*/
const char hw_cmd[10][4] = {{1 ,0x04}, // dark const char hw_cmd[10][4] = {{1 ,0x04}, // dark
{1 ,0x03}, {1 ,0x03},
{1 ,0x02}, {1 ,0x02},
@@ -211,8 +278,9 @@ serialVFD_load_KD (Driver *drvthis)
for (w = 0; w < 4; w++) for (w = 0; w < 4; w++)
p->hw_cmd[tmp][w] = hw_cmd[tmp][w]; p->hw_cmd[tmp][w] = hw_cmd[tmp][w];
/* Translates ISO 8859-1 to display charset. */
const unsigned char charmap[] = { const unsigned char charmap[] = {
127, // the "filled-block"-character usually 127 127, /* the "filled-block"-character usually 127 */
/* #128 = 0x80 */ /* #128 = 0x80 */
128, 129, 130, 131, 132, 133, 134, 135, 128, 129, 130, 131, 132, 133, 134, 135,
136, 137, 138, 139, 140, 141, 142, 143, 136, 137, 138, 139, 140, 141, 142, 143,
@@ -257,24 +325,26 @@ serialVFD_load_KD (Driver *drvthis)
p->usr_chr_mapping[tmp] = usr_chr_mapping[tmp]; p->usr_chr_mapping[tmp] = usr_chr_mapping[tmp];
} }
/* Init data for Noritake VFD */
void void
serialVFD_load_Noritake (Driver *drvthis) serialVFD_load_Noritake (Driver *drvthis)
{ //Noritake {
PrivateData *p = (PrivateData*) drvthis->private_data; PrivateData *p = (PrivateData*) drvthis->private_data;
int tmp, w; int tmp, w;
if (p->customchars == -83) if (p->customchars == CC_UNSET)
p->customchars = 16; // number of custom characters the display provides p->customchars = 16;
p->vbar_cc_offset = 0; // character offset of the bars p->vbar_cc_offset = 0;
p->hbar_cc_offset = 0; // character offset of the bars p->hbar_cc_offset = 0;
p->predefined_hbar = 0; // the display has predefined hbar-characters p->predefined_hbar = 0;
p->predefined_vbar = 0; // the display has predefined vbar-characters p->predefined_vbar = 0;
// hardwarespecific commands: /*-
// hw_cmd[Command][data] = {{commandlength , command 1}, * hardwarespecific commands:
// ..... * hw_cmd[Command][data] = {{commandlength , command 1},
// {commandlength , command N}} * .....
* {commandlength , command N}};
*/
const char hw_cmd[10][4] = {{3 ,0x1B, 0x4C, 0x00}, // dark const char hw_cmd[10][4] = {{3 ,0x1B, 0x4C, 0x00}, // dark
{3 ,0x1B, 0x4C, 0x50}, {3 ,0x1B, 0x4C, 0x50},
{3 ,0x1B, 0x4C, 0x90}, {3 ,0x1B, 0x4C, 0x90},
@@ -289,7 +359,7 @@ serialVFD_load_Noritake (Driver *drvthis)
for (w = 0; w < 4; w++) for (w = 0; w < 4; w++)
p->hw_cmd[tmp][w] = hw_cmd[tmp][w]; p->hw_cmd[tmp][w] = hw_cmd[tmp][w];
// no charmap needed /* no charmap needed */
for (tmp = 0; tmp < 129; tmp++) for (tmp = 0; tmp < 129; tmp++)
p->charmap[tmp] = tmp+127; p->charmap[tmp] = tmp+127;
@@ -314,23 +384,26 @@ serialVFD_load_Noritake (Driver *drvthis)
} }
/* Init data for Futaba VFD */
void void
serialVFD_load_Futaba (Driver *drvthis) serialVFD_load_Futaba (Driver *drvthis)
{ //Futaba {
PrivateData *p = (PrivateData*) drvthis->private_data; PrivateData *p = (PrivateData*) drvthis->private_data;
int tmp, w; int tmp, w;
if (p->customchars == -83) if (p->customchars == CC_UNSET)
p->customchars = 3; // number of custom characters the display provides p->customchars = 3;
p->vbar_cc_offset = 0; // character offset of the bars p->vbar_cc_offset = 0;
p->hbar_cc_offset = 0; // character offset of the bars p->hbar_cc_offset = 0;
p->predefined_hbar = 0; // the display has predefined hbar-characters p->predefined_hbar = 0;
p->predefined_vbar = 0; // the display has predefined vbar-characters p->predefined_vbar = 0;
// hardwarespecific commands: /*-
// hw_cmd[Command][data] = {{commandlength , command 1}, * hardwarespecific commands:
// ..... * hw_cmd[Command][data] = {{commandlength , command 1},
// {commandlength , command N}} * .....
* {commandlength , command N}};
*/
const char hw_cmd[10][4] = {{2 ,0x04, 0x20}, // dark const char hw_cmd[10][4] = {{2 ,0x04, 0x20}, // dark
{2 ,0x04, 0x40}, {2 ,0x04, 0x40},
{2 ,0x04, 0x60}, {2 ,0x04, 0x60},
@@ -345,9 +418,9 @@ serialVFD_load_Futaba (Driver *drvthis)
for (w = 0; w < 4; w++) for (w = 0; w < 4; w++)
p->hw_cmd[tmp][w] = hw_cmd[tmp][w]; p->hw_cmd[tmp][w] = hw_cmd[tmp][w];
// Translates ISO 8859-1 to display charset. /* Translates ISO 8859-1 to display charset. */
const unsigned char charmap[] = { const unsigned char charmap[] = {
127, // the "filled-block"-character usually 127 127, /* the "filled-block"-character usually 127 */
/* #128 = 0x80 */ /* #128 = 0x80 */
128, 129, 130, 131, 132, 133, 134, 135, 128, 129, 130, 131, 132, 133, 134, 135,
136, 137, 138, 139, 140, 141, 142, 143, 136, 137, 138, 139, 140, 141, 142, 143,
@@ -390,24 +463,27 @@ serialVFD_load_Futaba (Driver *drvthis)
} }
/* Init data for IEE_03601-95B_2x40_VFD */
void void
serialVFD_load_IEE_95B (Driver *drvthis) serialVFD_load_IEE_95B (Driver *drvthis)
{ //IEE_03601-95B_2x40_VFD {
PrivateData *p = (PrivateData*) drvthis->private_data; PrivateData *p = (PrivateData*) drvthis->private_data;
int tmp, w; int tmp, w;
if (p->customchars == -83) if (p->customchars == CC_UNSET)
p->customchars = 10; // number of custom characters the display provides p->customchars = 10;
p->vbar_cc_offset = 0; // character offset of the bars p->vbar_cc_offset = 0;
p->hbar_cc_offset = 0; // character offset of the bars p->hbar_cc_offset = 0;
p->predefined_hbar = 0; // the display has predefined hbar-characters p->predefined_hbar = 0;
p->predefined_vbar = 0; // the display has predefined vbar-characters p->predefined_vbar = 0;
p->para_wait = 60; // the display needs more delay in the parallelport mode p->para_wait = 60; // the display needs more delay in the parallelport mode
// hardwarespecific commands: /*-
// hw_cmd[Command][data] = {{commandlength , command 1}, * hardwarespecific commands:
// ..... * hw_cmd[Command][data] = {{commandlength , command 1},
// {commandlength , command N}} * .....
* {commandlength , command N}};
*/
const char hw_cmd[10][4] = {{1 ,0x1C}, // dark const char hw_cmd[10][4] = {{1 ,0x1C}, // dark
{1 ,0x1D}, {1 ,0x1D},
{1 ,0x1E}, {1 ,0x1E},
@@ -422,9 +498,9 @@ serialVFD_load_IEE_95B (Driver *drvthis)
for (w = 0; w < 4; w++) for (w = 0; w < 4; w++)
p->hw_cmd[tmp][w] = hw_cmd[tmp][w]; p->hw_cmd[tmp][w] = hw_cmd[tmp][w];
/* Translates ISO 8859-1 to display charset. */
const unsigned char charmap[] = { const unsigned char charmap[] = {
0xEF, // the "filled-block"-character usually 127 0xEF, /* the "filled-block"-character usually 127 */
/* #128 = 0x80 */ /* #128 = 0x80 */
0x7F, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0x7F, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
@@ -479,24 +555,28 @@ serialVFD_load_IEE_95B (Driver *drvthis)
} }
/* Init data for IEE_03601-96_2x40_VFD */
void void
serialVFD_load_IEE_96 (Driver *drvthis) serialVFD_load_IEE_96 (Driver *drvthis)
{ //IEE_03601-96_2x40_VFD {
PrivateData *p = (PrivateData*) drvthis->private_data; PrivateData *p = (PrivateData*) drvthis->private_data;
int tmp, w; int tmp, w;
if (p->customchars == -83) if (p->customchars == CC_UNSET)
p->customchars = 3; // number of custom characters the display provides p->customchars = 3;
p->vbar_cc_offset = 0; // character offset of the bars p->vbar_cc_offset = 0;
p->hbar_cc_offset = 0; // character offset of the bars p->hbar_cc_offset = 0;
p->predefined_hbar = 0; // the display has predefined hbar-characters p->predefined_hbar = 0;
p->predefined_vbar = 0; // the display has predefined vbar-characters p->predefined_vbar = 0;
p->para_wait = 60; // the display needs more delay in the parallelport mode p->para_wait = 60; // the display needs more delay in the parallelport mode
// hardwarespecific commands: /*-
// hw_cmd[Command][data] = {{commandlength , command 1}, * hardwarespecific commands:
// ..... * hw_cmd[Command][data] = {{commandlength , command 1},
// {commandlength , command N}} * .....
* {commandlength , command N}};
*/
const char hw_cmd[10][4] = {{1 ,0x1C}, // dark const char hw_cmd[10][4] = {{1 ,0x1C}, // dark
{1 ,0x1D}, {1 ,0x1D},
{1 ,0x1E}, {1 ,0x1E},
@@ -511,9 +591,9 @@ serialVFD_load_IEE_96 (Driver *drvthis)
for (w = 0; w < 4; w++) for (w = 0; w < 4; w++)
p->hw_cmd[tmp][w] = hw_cmd[tmp][w]; p->hw_cmd[tmp][w] = hw_cmd[tmp][w];
/* Translates ISO 8859-1 to display charset. */
const unsigned char charmap[] = { const unsigned char charmap[] = {
0xEF, // the "filled-block"-character usually 127 0xEF, /* the "filled-block"-character usually 127 */
/* #128 = 0x80 */ /* #128 = 0x80 */
0x7F, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0x7F, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
@@ -565,27 +645,29 @@ serialVFD_load_IEE_96 (Driver *drvthis)
{ 0x02, 0x01, 0x00}; { 0x02, 0x01, 0x00};
for (tmp = 0; tmp < 31; tmp++) for (tmp = 0; tmp < 31; tmp++)
p->usr_chr_load_mapping[tmp] = usr_chr_load_mapping[tmp]; p->usr_chr_load_mapping[tmp] = usr_chr_load_mapping[tmp];
} }
/* Init data for Futaba NA202SD08FA */
void void
serialVFD_load_Futaba_NA202SD08FA (Driver *drvthis) serialVFD_load_Futaba_NA202SD08FA (Driver *drvthis)
{ //IEE_03601-96_2x40_VFD {
PrivateData *p = (PrivateData*) drvthis->private_data; PrivateData *p = (PrivateData*) drvthis->private_data;
int tmp, w; int tmp, w;
//if (p->customchars == -83) // display doesn't support custom characters p->customchars = 0; /* display doesn't support custom characters */
p->customchars = 0; // number of custom characters the display provides p->vbar_cc_offset = 5;
p->vbar_cc_offset = 5; // character offset of the bars p->hbar_cc_offset = 12;
p->hbar_cc_offset = 12; // character offset of the bars p->predefined_hbar = 1;
p->predefined_hbar = 1; // the display has predefined hbar-characters p->predefined_vbar = 1;
p->predefined_vbar = 1; // the display has predefined vbar-characters
p->para_wait = 25; // the display needs more delay in the parallelport mode p->para_wait = 25; // the display needs more delay in the parallelport mode
// hardwarespecific commands: /*-
// hw_cmd[Command][data] = {{commandlength , command 1}, * hardwarespecific commands:
// ..... * hw_cmd[Command][data] = {{commandlength , command 1},
// {commandlength , command N}} * .....
* {commandlength , command N}};
*/
const char hw_cmd[10][4] ={{2 ,0x04, 0x20}, // dark const char hw_cmd[10][4] ={{2 ,0x04, 0x20}, // dark
{2 ,0x04, 0x40}, {2 ,0x04, 0x40},
{2 ,0x04, 0x60}, {2 ,0x04, 0x60},
@@ -600,9 +682,9 @@ serialVFD_load_Futaba_NA202SD08FA (Driver *drvthis)
for (w = 0; w < 4; w++) for (w = 0; w < 4; w++)
p->hw_cmd[tmp][w] = hw_cmd[tmp][w]; p->hw_cmd[tmp][w] = hw_cmd[tmp][w];
/* Translates ISO 8859-1 to display charset. */
const unsigned char charmap[] = { const unsigned char charmap[] = {
127, // the "filled-block"-character usually 127 127, /* the "filled-block"-character usually 127 */
/* #128 = 0x80 */ /* #128 = 0x80 */
128, 129, 130, 131, 132, 133, 134, 135, 128, 129, 130, 131, 132, 133, 134, 135,
136, 137, 138, 139, 140, 141, 142, 143, 136, 137, 138, 139, 140, 141, 142, 143,
@@ -628,7 +710,7 @@ serialVFD_load_Futaba_NA202SD08FA (Driver *drvthis)
// {bytes to send, icon bit mapped to bit 0, icon bit mapped to bit 1, ...} // {bytes to send, icon bit mapped to bit 0, icon bit mapped to bit 1, ...}
const int usr_chr_dot_assignment[57] = { 0, 0 }; // no usercharacters const int usr_chr_dot_assignment[57] = { 0, 0 }; // no usercharacters
for (tmp = 0; tmp < 57; tmp++) for (tmp = 0; tmp < 57; tmp++)
p->usr_chr_dot_assignment[tmp] = usr_chr_dot_assignment[tmp]; p->usr_chr_dot_assignment[tmp] = usr_chr_dot_assignment[tmp];
@@ -639,27 +721,29 @@ serialVFD_load_Futaba_NA202SD08FA (Driver *drvthis)
{0,0,0,0,0,0, 0xF4, 0xF4, 0xF5, 0xF6, 0xF6, 0xF7, 0, 0xF0, 0xF1, 0xF2, 0xF3}; {0,0,0,0,0,0, 0xF4, 0xF4, 0xF5, 0xF6, 0xF6, 0xF7, 0, 0xF0, 0xF1, 0xF2, 0xF3};
for (tmp = 0; tmp < 31; tmp++) for (tmp = 0; tmp < 31; tmp++)
p->usr_chr_mapping[tmp] = usr_chr_mapping[tmp]; p->usr_chr_mapping[tmp] = usr_chr_mapping[tmp];
} }
/* Init data for Samsung 20S207DA4 & 20S207DA6 */
void void
serialVFD_load_Samsung (Driver *drvthis) serialVFD_load_Samsung (Driver *drvthis)
{ //Samsung 20S207DA4 & 20S207DA6 {
PrivateData *p = (PrivateData*) drvthis->private_data; PrivateData *p = (PrivateData*) drvthis->private_data;
int tmp, w; int tmp, w;
if (p->customchars == -83) if (p->customchars == CC_UNSET)
p->customchars = 16; // number of custom characters the display provides p->customchars = 16;
p->vbar_cc_offset = 0; // character offset of the bars p->vbar_cc_offset = 0;
p->hbar_cc_offset = 0; // character offset of the bars p->hbar_cc_offset = 0;
p->predefined_hbar = 0; // the display has predefined hbar-characters p->predefined_hbar = 0;
p->predefined_vbar = 0; // the display has predefined vbar-characters p->predefined_vbar = 0;
// hardwarespecific commands: /*-
// hw_cmd[Command][data] = {{commandlength , command 1}, * hardwarespecific commands:
// ..... * hw_cmd[Command][data] = {{commandlength , command 1},
// {commandlength , command N}} * .....
* {commandlength , command N}};
*/
const char hw_cmd[10][4] = {{2 ,0x04, 0x20}, // dark const char hw_cmd[10][4] = {{2 ,0x04, 0x20}, // dark
{2 ,0x04, 0x40}, {2 ,0x04, 0x40},
{2 ,0x04, 0x60}, {2 ,0x04, 0x60},
@@ -674,9 +758,9 @@ serialVFD_load_Samsung (Driver *drvthis)
for (w = 0; w < 4; w++) for (w = 0; w < 4; w++)
p->hw_cmd[tmp][w] = hw_cmd[tmp][w]; p->hw_cmd[tmp][w] = hw_cmd[tmp][w];
// Translates ISO 8859-1 to display charset. /* Translates ISO 8859-1 to display charset. */
const unsigned char charmap[] = { const unsigned char charmap[] = {
127, // the "filled-block"-character usually 127 127, /* the "filled-block"-character usually 127 */
/* #128 = 0x80 */ /* #128 = 0x80 */
128, 129, 130, 131, 132, 133, 134, 135, 128, 129, 130, 131, 132, 133, 134, 135,
136, 137, 138, 139, 140, 141, 142, 143, 136, 137, 138, 139, 140, 141, 142, 143,
@@ -721,23 +805,26 @@ serialVFD_load_Samsung (Driver *drvthis)
p->usr_chr_mapping[tmp] = usr_chr_mapping[tmp]; p->usr_chr_mapping[tmp] = usr_chr_mapping[tmp];
} }
/* Init data for Nixdorf BA63 & BA66 */
void void
serialVFD_load_Nixdorf_BA6x (Driver *drvthis) serialVFD_load_Nixdorf_BA6x (Driver *drvthis)
{ // Nixdorf BA63 & BA66 {
PrivateData *p = (PrivateData*) drvthis->private_data; PrivateData *p = (PrivateData*) drvthis->private_data;
int tmp, w; int tmp, w;
//if (p->customchars == -83) // display doesn't support custom characters p->customchars = 0; /* display doesn't support custom characters */
p->customchars = 0; // number of custom characters the display provides p->vbar_cc_offset = 5;
p->vbar_cc_offset = 5; // character offset of the bars p->hbar_cc_offset = 12;
p->hbar_cc_offset = 12; // character offset of the bars p->predefined_hbar = 1;
p->predefined_hbar = 1; // the display has predefined hbar-characters p->predefined_vbar = 1;
p->predefined_vbar = 1; // the display has predefined vbar-characters
// hardwarespecific commands: /*-
// hw_cmd[Command][data] = {{commandlength , command 1}, * hardwarespecific commands:
// ..... * hw_cmd[Command][data] = {{commandlength , command 1},
// {commandlength , command N}} * .....
* {commandlength , command N}};
*/
const char hw_cmd[11][10] = {{0 }, // dark const char hw_cmd[11][10] = {{0 }, // dark
{0 }, {0 },
{0 }, {0 },
@@ -758,9 +845,9 @@ serialVFD_load_Nixdorf_BA6x (Driver *drvthis)
for (w = 0; w < 10; w++) for (w = 0; w < 10; w++)
p->hw_cmd[tmp][w] = hw_cmd[tmp][w]; p->hw_cmd[tmp][w] = hw_cmd[tmp][w];
// Translates ISO 8859-1 to display charset. /* Translates ISO 8859-1 to display charset. */
const unsigned char charmap[] = { const unsigned char charmap[] = {
0xDB, // the "filled-block"-character usually 127 0xDB, /* the "filled-block"-character usually 127 */
/* #128 = 0x80 */ /* #128 = 0x80 */
128, 129, 130, 131, 132, 133, 134, 135, 128, 129, 130, 131, 132, 133, 134, 135,
136, 137, 138, 139, 140, 141, 142, 143, 136, 137, 138, 139, 140, 141, 142, 143,
+24 -20
View File
@@ -1,28 +1,32 @@
/* This is the LCDproc driver for various serial VFD Devices /*-
* Copyright (C) 2006 Stefan Herdler
*
* This driver is based on wirz-sli.c, hd44780.c, drv_base.c and NoritakeVFD
* driver. It may contain parts of other drivers of this package too.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*/
Copyright (C) 2006 Stefan Herdler /*
* 2006-05-16 Version 0.3: 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
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */
#ifndef SERIALVFD_DISPLAYS_H #ifndef SERIALVFD_DISPLAYS_H
#define SERIALVFD_DISPLAYS_H #define SERIALVFD_DISPLAYS_H
#include "lcd.h" #define CC_UNSET -83 /**< number of custom characters not set */
#include "serialVFD.h"
int serialVFD_load_display_data(Driver *drvthis); int serialVFD_load_display_data(Driver *drvthis);
#endif #endif
+100 -42
View File
@@ -4,49 +4,65 @@
* serial resp. parallel port for the \c serialVFD driver. * serial resp. parallel port for the \c serialVFD driver.
*/ */
/* This file is part the LCDproc driver for various serial VFD Devices. /*-
* Copyright (C) 2006 Stefan Herdler
*
* This driver is based on wirz-sli.c, hd44780.c, drv_base.c and NoritakeVFD
* driver. It may contain parts of other drivers of this package too.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*/
It contains the hardwaredependent commands ach characterset. /*
* 2006-05-16 Version 0.3: everything should work (not all hardware tested!)
*/
If you want to add a new device to the driver add a new section #ifdef HAVE_CONFIG_H
to the displaytype-switch-case in the init-function, add a new load_... # include "config.h"
function below and fill it with the corrrect commands for the display. #endif
(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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include "lcd.h"
#include "report.h"
#include "lpt-port.h"
#include "port.h" #include "port.h"
#include "serialVFD_io.h" #include "serialVFD_io.h"
#include "serialVFD.h" #include "serialVFD.h"
#include "lcd.h"
#define WR_on 0x10 /*
#define WR_off 0x11 * XXX: ENIRQ used to be set, although no IRQ handler is defined. As the
#define Busy 0x80 * schematic in the user guide shows BUSY connected to ACK, leave it as is.
#define LPTPORT 0x378 */
#define WR_on ((ENIRQ | STRB) ^ OUTMASK) /* STRB (1) is active low */
#define WR_off (ENIRQ ^ OUTMASK)
#define MAXBUSY 300 #define MAXBUSY 300
/**
* Write bytes to the serial port.
* \param drvthis Pointer to driver
* \param dat Pointer to array storing the data
* \param length Number of bytes to write
*/
void void
serialVFD_write_serial (Driver *drvthis, unsigned char *dat, size_t length) serialVFD_write_serial (Driver *drvthis, unsigned char *dat, size_t length)
{ {
@@ -58,6 +74,21 @@ serialVFD_write_serial (Driver *drvthis, unsigned char *dat, size_t length)
write(p->fd,dat,length); write(p->fd,dat,length);
} }
/**
* Write bytes to the parallel port.
*
* Timing can be modified by inserting additional delays according to the
* \c PortWait setting in \c LCDd.conf: \n
* Portwait = 0; no delays, only BUSY bit checked\n
* Portwait = 1; additional WR off to check BUSY delay\n
* Portwait = 2; as 1 + additional WR pulse width\n
* Portwait = 3; as 2 + additional WR setup delay\n
* Portwait >= 4; as 3 + additional wait delay to next command
*
* \param drvthis Pointer to driver
* \param dat Pointer to array storing the data
* \param length Number of bytes to write
*/
void void
serialVFD_write_parallel (Driver *drvthis, unsigned char *dat, size_t length) serialVFD_write_parallel (Driver *drvthis, unsigned char *dat, size_t length)
{ {
@@ -71,31 +102,45 @@ serialVFD_write_parallel (Driver *drvthis, unsigned char *dat, size_t length)
for (i_para = 0; i_para < length; i_para++) { for (i_para = 0; i_para < length; i_para++) {
port_out(p->port, dat[i_para]); port_out(p->port, dat[i_para]);
if (p->para_wait > 2) // some displays need a little time to rest /* data to WR enable delay */
if (p->para_wait > 2)
port_in(p->port+1); port_in(p->port+1);
port_out(p->port+2, WR_on); port_out(p->port+2, WR_on);
if (p->para_wait > 1) // some displays need a little time to rest /* additional WR pulse width */
if (p->para_wait > 1)
port_in(p->port+1); port_in(p->port+1);
port_out(p->port+2, WR_off); port_out(p->port+2, WR_off);
if (p->para_wait > 0) // some displays need a little time to rest /* additional BUSY delay time */
if (p->para_wait > 0)
port_in(p->port+1); port_in(p->port+1);
/*
* Check MAXBUSY times if the BUSY bit is set. Note: BUSY bit
* on parallel port is hardware inverted, but VFD is ready
* if its BUSY bit is cleared (thus high on PC).
*/
for (j_para = 0; j_para < MAXBUSY; j_para++) { for (j_para = 0; j_para < MAXBUSY; j_para++) {
if ((port_in(p->port+1)) & Busy) if ((port_in(p->port+1)) & BUSY)
break; break;
} }
for (j_para = 3; j_para < p->para_wait; j_para++) // some displays need a little longer time to rest /* wait time of next WR */
for (j_para = 3; j_para < p->para_wait; j_para++)
port_in(p->port+1); port_in(p->port+1);
} }
#endif #endif
} }
/**
* Open a serial port according to the settings in \c serialVFD_private_data.
* \param drvthis Pointer to driver
* \return -1 on error, 0 on success
*/
int int
serialVFD_init_serial (Driver *drvthis) serialVFD_init_serial (Driver *drvthis)
{ {
@@ -113,12 +158,12 @@ serialVFD_init_serial (Driver *drvthis)
tcgetattr(p->fd, &portset); tcgetattr(p->fd, &portset);
// We use RAW mode /* We use RAW mode */
#ifdef HAVE_CFMAKERAW #ifdef HAVE_CFMAKERAW
// The easy way /* The easy way */
cfmakeraw( &portset ); cfmakeraw( &portset );
#else #else
// The hard way /* The hard way */
portset.c_iflag &= ~( IGNBRK | BRKINT | PARMRK | ISTRIP portset.c_iflag &= ~( IGNBRK | BRKINT | PARMRK | ISTRIP
| INLCR | IGNCR | ICRNL | IXON ); | INLCR | IGNCR | ICRNL | IXON );
portset.c_oflag &= ~OPOST; portset.c_oflag &= ~OPOST;
@@ -127,15 +172,20 @@ serialVFD_init_serial (Driver *drvthis)
portset.c_cflag |= CS8 | CREAD | CLOCAL ; portset.c_cflag |= CS8 | CREAD | CLOCAL ;
#endif #endif
// Set port speed /* Set port speed */
cfsetospeed(&portset, p->speed); cfsetospeed(&portset, p->speed);
cfsetispeed(&portset, B0); cfsetispeed(&portset, B0);
// Do it... /* Do it... */
tcsetattr(p->fd, TCSANOW, &portset); tcsetattr(p->fd, TCSANOW, &portset);
return 0; return 0;
} }
/**
* Open a parallel port according to the settings in \c serialVFD_private_data.
* \param drvthis Pointer to driver
* \return -1 on error, 0 on success
*/
int int
serialVFD_init_parallel (Driver *drvthis) serialVFD_init_parallel (Driver *drvthis)
{ {
@@ -153,6 +203,10 @@ serialVFD_init_parallel (Driver *drvthis)
#endif #endif
} }
/**
* Close serial port.
* \param drvthis Pointer to driver
*/
void void
serialVFD_close_serial (Driver *drvthis) serialVFD_close_serial (Driver *drvthis)
{ {
@@ -161,6 +215,10 @@ serialVFD_close_serial (Driver *drvthis)
close(p->fd); close(p->fd);
} }
/**
* Close parallel port.
* \param drvthis Pointer to driver
*/
void void
serialVFD_close_parallel (Driver *drvthis) serialVFD_close_parallel (Driver *drvthis)
{ {
+29 -44
View File
@@ -1,47 +1,31 @@
/* This is the LCDproc driver for various serial VFD Devices /*-
* Copyright (C) 2006 Stefan Herdler
*
* This driver is based on wirz-sli.c, hd44780.c, drv_base.c and NoritakeVFD
* driver. It may contain parts of other drivers of this package too.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*/
Copyright (C) 2006 Stefan Herdler /*
* 2006-05-16 Version 0.3: 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
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */
#ifndef SERIALVFD_IO_H #ifndef SERIALVFD_IO_H
#define 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_serial (Driver *drvthis);
int serialVFD_init_parallel (Driver *drvthis); int serialVFD_init_parallel (Driver *drvthis);
void serialVFD_write_serial (Driver *drvthis, unsigned char *dat, size_t length); void serialVFD_write_serial (Driver *drvthis, unsigned char *dat, size_t length);
@@ -49,20 +33,21 @@ void serialVFD_write_parallel (Driver *drvthis, unsigned char *dat, size_t lengt
void serialVFD_close_serial (Driver *drvthis); void serialVFD_close_serial (Driver *drvthis);
void serialVFD_close_parallel (Driver *drvthis); void serialVFD_close_parallel (Driver *drvthis);
/** Function list for low-level I/O routines */
typedef struct Port_fkt { typedef struct Port_fkt {
void (*write_fkt) (Driver *drvthis, unsigned char *dat, size_t length); void (*write_fkt) (Driver *drvthis, unsigned char *dat, size_t length);
int (*init_fkt) (Driver *drvthis); int (*init_fkt) (Driver *drvthis);
void (*close_fkt) (Driver *drvthis); void (*close_fkt) (Driver *drvthis);
} Port_fkt; } Port_fkt;
/**
* Array with function pointers to low-level I/O routines.
* Port_Function[0] stores routines for serial ports, Port_Function[1] those
* for parallel ports.
*/
static const Port_fkt Port_Function[] = { static const Port_fkt Port_Function[] = {
// initialisation function
// write function
{serialVFD_write_serial, serialVFD_init_serial, serialVFD_close_serial}, {serialVFD_write_serial, serialVFD_init_serial, serialVFD_close_serial},
{serialVFD_write_parallel, serialVFD_init_parallel, serialVFD_close_parallel} {serialVFD_write_parallel, serialVFD_init_parallel, serialVFD_close_parallel}
}; };
#endif #endif