From 68d4903b4b5f2498aa3940a22c629ed45aab5c51 Mon Sep 17 00:00:00 2001 From: mmdolze Date: Thu, 9 Dec 2010 21:25:42 +0000 Subject: [PATCH] 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. --- server/drivers/serialVFD.c | 289 ++++++++++----------- server/drivers/serialVFD.h | 89 ++++--- server/drivers/serialVFD_displays.c | 387 +++++++++++++++++----------- server/drivers/serialVFD_displays.h | 44 ++-- server/drivers/serialVFD_io.c | 142 +++++++--- server/drivers/serialVFD_io.h | 73 +++--- 6 files changed, 576 insertions(+), 448 deletions(-) diff --git a/server/drivers/serialVFD.c b/server/drivers/serialVFD.c index b9ddace..c750d82 100644 --- a/server/drivers/serialVFD.c +++ b/server/drivers/serialVFD.c @@ -1,66 +1,46 @@ /** \file server/drivers/serialVFD.c * 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 - - 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. - -*/ + * 2006-05-16 Version 0.3: everything should work (not all hardware tested!) + */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif #include #include @@ -69,22 +49,18 @@ get_info Implemented. #include #include #include -#include - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include "lcd.h" -#include "serialVFD.h" - #include "report.h" #include "lcd_lib.h" #include "adv_bignum.h" +#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 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 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 LPTPORT 0x378 /* Vars for the server core */ MODULE_EXPORT char *api_version = API_VERSION; @@ -123,6 +98,8 @@ serialVFD_init (Driver *drvthis) PrivateData *p; + debug(RPT_INFO, "%s(%p)", __FUNCTION__, drvthis); + /* Allocate and store private data */ p = (PrivateData *) calloc(1, sizeof(PrivateData)); if (p == NULL) @@ -138,25 +115,20 @@ serialVFD_init (Driver *drvthis) p->refresh_timer = 480; p->hw_brightness = 0; p->para_wait = DEFAULT_PARA_WAIT; - p->hw_cmd[next_line][0] = 0; - - - debug(RPT_INFO, "%s(%p)", __FUNCTION__, drvthis); - -/* Read config file */ + p->hw_cmd[next_line][0] = 0; /* disable line / set normal mode */ + /* Connection type: parallel or serial? */ p->use_parallel = drvthis->config_get_bool(drvthis->name, "use_parallel", 0, 0); - /* Which device should be used */ - strncpy(p->device, drvthis->config_get_string(drvthis->name, "Device", 0, DEFAULT_DEVICE), sizeof(p->device)); - p->device[sizeof(p->device)-1] = '\0'; - report(RPT_INFO, "%s: using Device %s", drvthis->name, p->device); + /* Which device should be used */ + strncpy(p->device, drvthis->config_get_string(drvthis->name, "Device", 0, DEFAULT_DEVICE), sizeof(p->device)); + p->device[sizeof(p->device)-1] = '\0'; + report(RPT_INFO, "%s: using Device %s", drvthis->name, p->device); 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 { - /* Which speed */ tmp = drvthis->config_get_int(drvthis->name, "Speed", 0, DEFAULT_SPEED); 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 == 115200) p->speed = B115200; } -// report(RPT_ERR, "%s: Port: %X", __FUNCTION__, p->port, strerror(errno)); /* Which 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); /* 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)) { report(RPT_WARNING, "%s: The number of Custom-Characters must be between 0 and 99. Using default", drvthis->name, 0); - tmp = -83; + tmp = CC_UNSET; } p->customchars = tmp; - -// report(RPT_ERR, "%s: Port: %X", __FUNCTION__, p->port, strerror(errno)); - -// Do connection type specific io-port init + /* 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; } -// 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) { @@ -246,8 +213,8 @@ serialVFD_init (Driver *drvthis) } memset(p->backingstore, 0, p->width * p->height); -//setup displayspecific data - memset(p->usr_chr_mapping, 0, 31); + /* setup displayspecific data */ + memset(p->usr_chr_mapping, 0, 31); /* no character mapping by default */ memset(p->usr_chr_load_mapping, 0, 31); if (serialVFD_load_display_data(drvthis) != 0) { 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; 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 memcpy(p->usr_chr_load_mapping, p->usr_chr_mapping, 31); } - -// report(RPT_ERR, "%s: Port: %X", drvthis->name, p->port, strerror(errno)); - -//initialise display + /* 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; - } @@ -387,64 +354,66 @@ serialVFD_flush (Driver *drvthis) 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", __FUNCTION__, i, j, strerror(errno)); - } + } p->custom_char_store[i][j] = p->custom_char[i][j]; } } - if (p->refresh_timer > 500) { // Do a full refresh every 500 refreshs. - // With this it is possible to switch the display on and off while LCDd is running + /* Do a full refresh every 500 refreshs. */ + 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[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; p->refresh_timer = 0; } 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]) p->last_custom = -10; } - else { // other Displays - for (i = 0; i < p->customchars; i++) // set customcharacters + else { /* other Displays */ + for (i = 0; i < p->customchars; i++) /* set customcharacters */ if (custom_char_changed[i]) serialVFD_put_char(drvthis, i); } - - if (p->hw_cmd[next_line][0] == 0) { // normal mode Display - if (p->hw_cmd[mv_cursor][0] == 0) { // Workaround for Displays that doesn't support mv_cursor command + /* normal mode Display */ + if (p->hw_cmd[next_line][0] == 0) { + /* 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]); last_chr = -1; } 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 - */ - + /* + * Backing-store implementation. If it's already + * on the screen, don't put it there again. + */ 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))) { - 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)) { Port_Function[p->use_parallel].write_fkt(drvthis, &p->hw_cmd[mv_cursor][1], p->hw_cmd[mv_cursor][0]); 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 { 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]); - //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); @@ -452,23 +421,25 @@ serialVFD_flush (Driver *drvthis) } } } - - else { // line mode Display (partitially borrowed from serialPOS.c) + /* line mode Display (partitially borrowed from serialPOS.c) */ + else { 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 *sq = p->backingstore + (j * p->width); + /* Move to start of line */ if (j == 0) { Port_Function[p->use_parallel].write_fkt(drvthis, &p->hw_cmd[pos1_cursor][1], p->hw_cmd[pos1_cursor][0]); } else { Port_Function[p->use_parallel].write_fkt(drvthis, &p->hw_cmd[next_line][1], p->hw_cmd[next_line][0]); } - // skip over identical lines - if ( memcmp(sp, sq, p->width) == 0) { - /* The lines are the same. */ + /* skip over identical lines */ + if (memcmp(sp, sq, p->width) == 0) { continue; } + /* write the data */ for (i = 0; i < p->width; i++) { 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); - //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--; y--; 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)) break; 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; int do_init = 0; - if (p->ccmode != CCMODE_BIGNUM) { // Are the customcharacters set up correctly? If not: - do_init = 1; // Lib_adv_bignum has to set the customcharacters. - p->ccmode = CCMODE_BIGNUM; // Switch customcharactermode to bignum. + if (p->ccmode != CCMODE_BIGNUM) { + /* If custom characters are not yet set up Lib_adv_bignum has + * 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); } @@ -631,7 +604,6 @@ serialVFD_icon (Driver *drvthis, int x, int y, int icon) b__XX_XX, b__XXXXX }; - // Yes we know, this is a VERY BAD implementation :-) switch (icon) { case ICON_BLOCK_FILLED: 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); break; default: - return -1; // Let the core do other icons + return -1; /* Let the core do other icons */ } return 0; } @@ -677,6 +649,10 @@ serialVFD_get_free_chars (Driver *drvthis) /** * 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 n Custom character to define [0 - (p->customchars)]. * \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 serialVFD_set_char (Driver *drvthis, int n, unsigned char *dat) -{ //set char in p->custom_char +{ PrivateData *p = drvthis->private_data; unsigned int byte, bit; @@ -699,6 +675,7 @@ serialVFD_set_char (Driver *drvthis, int n, unsigned char *dat) int letter = 0; 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]; if (pos > 0) { @@ -769,8 +746,10 @@ serialVFD_backlight (Driver *drvthis, int 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) + /* + * 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; @@ -817,7 +796,7 @@ serialVFD_init_vbar (Driver *drvthis) memset(vBar, 0x00, sizeof(vBar)); for (i = 1; i < p->cellheight; i++) { - // add pixel line per pixel line ... + /* add pixel line per pixel line ... */ vBar[p->cellheight - i] = 0xFF; serialVFD_set_char(drvthis, i, vBar); } @@ -845,7 +824,7 @@ serialVFD_init_hbar (Driver *drvthis) p->ccmode = CCMODE_HBAR; 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)); 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 serialVFD_put_char (Driver *drvthis, int n) -{ // put userchar in display +{ PrivateData *p = drvthis->private_data; 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, &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 serialVFD_hw_write (Driver *drvthis, int i) -{ // finally write character/usercharacter on the display +{ PrivateData *p = drvthis->private_data; - if (p->framebuf[i] <= 30) { // custom character - if (p->display_type == 1) { // KD Rev 2.1 only + if (p->framebuf[i] <= 30) { /* custom character */ + if (p->display_type == 1) { /* KD Rev 2.1 only */ 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); - // 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, (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]; } - 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); } } - 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); } else { diff --git a/server/drivers/serialVFD.h b/server/drivers/serialVFD.h index cb53cd1..5f307fc 100644 --- a/server/drivers/serialVFD.h +++ b/server/drivers/serialVFD.h @@ -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 - - 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 */ +/* + * 2006-05-16 Version 0.3: everything should work (not all hardware tested!) + */ #ifndef 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_HBAR 2 #define CCMODE_BIGNUM 3 @@ -45,6 +42,9 @@ #define DEFAULT_SIZE "20x2" #define DEFAULT_DISPLAYTYPE 0 #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); @@ -74,39 +74,38 @@ MODULE_EXPORT const char * serialVFD_get_info( Driver *drvthis ); /** private data for the \c serialVFD driver */ typedef struct serialVFD_private_data { - int use_parallel; // use parallel? - unsigned short port; // Port in parallel mode - char device[200]; // Device in serial mode - int fd; - int speed; // Speed in serial mode + int use_parallel; /**< use parallel port? */ + unsigned short port; /**< port in parallel mode */ + char device[200]; /**> device in serial mode */ + int fd; /**< file descriptor in serial mode */ + 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 predefined_hbar; - int predefined_vbar; + int predefined_hbar; /**< display has predefined hbar-characters */ + int predefined_vbar; /**< display has predefined vbar-characters */ int ISO_8859_1; unsigned int refresh_timer; unsigned int para_wait; unsigned char charmap[129]; - int display_type; // display type - int last_custom; // last custom character written - unsigned char custom_char[31][7]; // stored custom characters - unsigned char custom_char_store[31][7]; // custom characters backingstore - unsigned char hw_cmd[11][10]; // 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 - 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 vbar_cc_offset; // character offset of the bars + int display_type; /**< display type */ + int last_custom; /**< last custom character written */ + unsigned char custom_char[31][7]; /**< stored custom characters */ + unsigned char custom_char_store[31][7]; /**< custom characters backingstore */ + unsigned char hw_cmd[11][10]; /**< table of 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 */ + 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 vbar_cc_offset; /**< character offset of the bars */ char info[255]; } PrivateData; diff --git a/server/drivers/serialVFD_displays.c b/server/drivers/serialVFD_displays.c index b3e129d..dfc93ca 100644 --- a/server/drivers/serialVFD_displays.c +++ b/server/drivers/serialVFD_displays.c @@ -1,42 +1,99 @@ /** \file server/drivers/serialVFD_displays.c * 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 * 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. - - 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 - -*/ +/* + * 2006-05-16 Version 0.3: everything should work (not all hardware tested!) + */ +#include "lcd.h" #include "serialVFD_displays.h" #include "serialVFD.h" -#include "lcd.h" void serialVFD_load_NEC_FIPC (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_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) { PrivateData *p = (PrivateData*) drvthis->private_data; @@ -86,24 +148,26 @@ int serialVFD_load_display_data(Driver *drvthis) return 0; } - +/* Init data for NEC FIPS based VFD */ 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 custom characters the display provides - p->vbar_cc_offset = 5; // character offset of the bars - p->hbar_cc_offset = 12; // character offset of the bars - p->predefined_hbar = 1; // the display has predefined hbar-characters - p->predefined_vbar = 1; // the display has predefined vbar-characters + if (p->customchars == CC_UNSET) + p->customchars = 1; + p->vbar_cc_offset = 5; + p->hbar_cc_offset = 12; + p->predefined_hbar = 1; + p->predefined_vbar = 1; - // hardwarespecific commands: - // hw_cmd[Command][data] = {{commandlength , command 1}, - // ..... - // {commandlength , command N}} + /*- + * hardwarespecific commands: + * hw_cmd[Command][data] = {{commandlength , command 1}, + * ..... + * {commandlength , command N}}; + */ const char hw_cmd[11][4] = {{1 ,0x04}, // dark {1 ,0x03}, {1 ,0x02}, @@ -123,9 +187,9 @@ serialVFD_load_NEC_FIPC (Driver *drvthis) for (w = 0; w < 4; 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[] = { - 127, // the "filled-block"-character usually 127 + 127, /* the "filled-block"-character usually 127 */ /* #128 = 0x80 */ 128, 129, 130, 131, 132, 133, 134, 135, 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 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 custom characters the display provides - p->vbar_cc_offset = 0; // character offset of the bars - p->hbar_cc_offset = 0; // character offset of the bars - p->predefined_hbar = 0; // the display has predefined hbar-characters - p->predefined_vbar = 0; // the display has predefined vbar-characters + if (p->customchars == CC_UNSET) + p->customchars = 31; + p->vbar_cc_offset = 0; + p->hbar_cc_offset = 0; + p->predefined_hbar = 0; + p->predefined_vbar = 0; - // hardwarespecific commands: - // hw_cmd[Command][data] = {{commandlength , command 1}, - // ..... - // {commandlength , command N}} + /*- + * 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}, @@ -211,8 +278,9 @@ serialVFD_load_KD (Driver *drvthis) 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[] = { - 127, // the "filled-block"-character usually 127 + 127, /* the "filled-block"-character usually 127 */ /* #128 = 0x80 */ 128, 129, 130, 131, 132, 133, 134, 135, 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]; } - +/* Init data for Noritake VFD */ 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 custom characters the display provides - p->vbar_cc_offset = 0; // character offset of the bars - p->hbar_cc_offset = 0; // character offset of the bars - p->predefined_hbar = 0; // the display has predefined hbar-characters - p->predefined_vbar = 0; // the display has predefined vbar-characters + if (p->customchars == CC_UNSET) + p->customchars = 16; + p->vbar_cc_offset = 0; + p->hbar_cc_offset = 0; + p->predefined_hbar = 0; + p->predefined_vbar = 0; - // hardwarespecific commands: - // hw_cmd[Command][data] = {{commandlength , command 1}, - // ..... - // {commandlength , command N}} + /*- + * 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}, @@ -289,7 +359,7 @@ serialVFD_load_Noritake (Driver *drvthis) for (w = 0; w < 4; w++) p->hw_cmd[tmp][w] = hw_cmd[tmp][w]; - // no charmap needed + /* no charmap needed */ for (tmp = 0; tmp < 129; tmp++) p->charmap[tmp] = tmp+127; @@ -314,23 +384,26 @@ serialVFD_load_Noritake (Driver *drvthis) } +/* Init data for Futaba VFD */ 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 custom characters the display provides - p->vbar_cc_offset = 0; // character offset of the bars - p->hbar_cc_offset = 0; // character offset of the bars - p->predefined_hbar = 0; // the display has predefined hbar-characters - p->predefined_vbar = 0; // the display has predefined vbar-characters + if (p->customchars == CC_UNSET) + p->customchars = 3; + p->vbar_cc_offset = 0; + p->hbar_cc_offset = 0; + p->predefined_hbar = 0; + p->predefined_vbar = 0; - // hardwarespecific commands: - // hw_cmd[Command][data] = {{commandlength , command 1}, - // ..... - // {commandlength , command N}} + /*- + * 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}, @@ -345,9 +418,9 @@ serialVFD_load_Futaba (Driver *drvthis) for (w = 0; w < 4; 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[] = { - 127, // the "filled-block"-character usually 127 + 127, /* the "filled-block"-character usually 127 */ /* #128 = 0x80 */ 128, 129, 130, 131, 132, 133, 134, 135, 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 serialVFD_load_IEE_95B (Driver *drvthis) -{ //IEE_03601-95B_2x40_VFD +{ PrivateData *p = (PrivateData*) drvthis->private_data; int tmp, w; - if (p->customchars == -83) - p->customchars = 10; // number of custom characters the display provides - p->vbar_cc_offset = 0; // character offset of the bars - p->hbar_cc_offset = 0; // character offset of the bars - p->predefined_hbar = 0; // the display has predefined hbar-characters - p->predefined_vbar = 0; // the display has predefined vbar-characters + if (p->customchars == CC_UNSET) + p->customchars = 10; + p->vbar_cc_offset = 0; + p->hbar_cc_offset = 0; + p->predefined_hbar = 0; + p->predefined_vbar = 0; p->para_wait = 60; // the display needs more delay in the parallelport mode - // hardwarespecific commands: - // hw_cmd[Command][data] = {{commandlength , command 1}, - // ..... - // {commandlength , command N}} + /*- + * hardwarespecific commands: + * hw_cmd[Command][data] = {{commandlength , command 1}, + * ..... + * {commandlength , command N}}; + */ const char hw_cmd[10][4] = {{1 ,0x1C}, // dark {1 ,0x1D}, {1 ,0x1E}, @@ -422,9 +498,9 @@ serialVFD_load_IEE_95B (Driver *drvthis) 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[] = { - 0xEF, // the "filled-block"-character usually 127 + 0xEF, /* the "filled-block"-character usually 127 */ /* #128 = 0x80 */ 0x7F, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 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 serialVFD_load_IEE_96 (Driver *drvthis) -{ //IEE_03601-96_2x40_VFD +{ PrivateData *p = (PrivateData*) drvthis->private_data; int tmp, w; - if (p->customchars == -83) - p->customchars = 3; // number of custom characters the display provides - p->vbar_cc_offset = 0; // character offset of the bars - p->hbar_cc_offset = 0; // character offset of the bars - p->predefined_hbar = 0; // the display has predefined hbar-characters - p->predefined_vbar = 0; // the display has predefined vbar-characters + if (p->customchars == CC_UNSET) + p->customchars = 3; + p->vbar_cc_offset = 0; + p->hbar_cc_offset = 0; + p->predefined_hbar = 0; + p->predefined_vbar = 0; p->para_wait = 60; // the display needs more delay in the parallelport mode - // hardwarespecific commands: - // hw_cmd[Command][data] = {{commandlength , command 1}, - // ..... - // {commandlength , command N}} + /*- + * hardwarespecific commands: + * hw_cmd[Command][data] = {{commandlength , command 1}, + * ..... + * {commandlength , command N}}; + */ const char hw_cmd[10][4] = {{1 ,0x1C}, // dark {1 ,0x1D}, {1 ,0x1E}, @@ -511,9 +591,9 @@ serialVFD_load_IEE_96 (Driver *drvthis) 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[] = { - 0xEF, // the "filled-block"-character usually 127 + 0xEF, /* the "filled-block"-character usually 127 */ /* #128 = 0x80 */ 0x7F, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, @@ -565,27 +645,29 @@ serialVFD_load_IEE_96 (Driver *drvthis) { 0x02, 0x01, 0x00}; for (tmp = 0; tmp < 31; tmp++) p->usr_chr_load_mapping[tmp] = usr_chr_load_mapping[tmp]; - } + +/* Init data for Futaba NA202SD08FA */ void serialVFD_load_Futaba_NA202SD08FA (Driver *drvthis) -{ //IEE_03601-96_2x40_VFD +{ PrivateData *p = (PrivateData*) drvthis->private_data; int tmp, w; - //if (p->customchars == -83) // display doesn't support custom characters - p->customchars = 0; // number of custom characters the display provides - p->vbar_cc_offset = 5; // character offset of the bars - p->hbar_cc_offset = 12; // character offset of the bars - p->predefined_hbar = 1; // the display has predefined hbar-characters - p->predefined_vbar = 1; // the display has predefined vbar-characters + p->customchars = 0; /* display doesn't support custom characters */ + p->vbar_cc_offset = 5; + p->hbar_cc_offset = 12; + p->predefined_hbar = 1; + p->predefined_vbar = 1; p->para_wait = 25; // the display needs more delay in the parallelport mode - // hardwarespecific commands: - // hw_cmd[Command][data] = {{commandlength , command 1}, - // ..... - // {commandlength , command N}} + /*- + * 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}, @@ -600,9 +682,9 @@ serialVFD_load_Futaba_NA202SD08FA (Driver *drvthis) 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[] = { - 127, // the "filled-block"-character usually 127 + 127, /* the "filled-block"-character usually 127 */ /* #128 = 0x80 */ 128, 129, 130, 131, 132, 133, 134, 135, 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, ...} - 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++) 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}; for (tmp = 0; tmp < 31; tmp++) p->usr_chr_mapping[tmp] = usr_chr_mapping[tmp]; - - } + +/* Init data for Samsung 20S207DA4 & 20S207DA6 */ void serialVFD_load_Samsung (Driver *drvthis) -{ //Samsung 20S207DA4 & 20S207DA6 +{ PrivateData *p = (PrivateData*) drvthis->private_data; int tmp, w; - if (p->customchars == -83) - p->customchars = 16; // number of custom characters the display provides - p->vbar_cc_offset = 0; // character offset of the bars - p->hbar_cc_offset = 0; // character offset of the bars - p->predefined_hbar = 0; // the display has predefined hbar-characters - p->predefined_vbar = 0; // the display has predefined vbar-characters + if (p->customchars == CC_UNSET) + p->customchars = 16; + p->vbar_cc_offset = 0; + p->hbar_cc_offset = 0; + p->predefined_hbar = 0; + p->predefined_vbar = 0; - // hardwarespecific commands: - // hw_cmd[Command][data] = {{commandlength , command 1}, - // ..... - // {commandlength , command N}} + /*- + * 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}, @@ -674,9 +758,9 @@ serialVFD_load_Samsung (Driver *drvthis) for (w = 0; w < 4; 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[] = { - 127, // the "filled-block"-character usually 127 + 127, /* the "filled-block"-character usually 127 */ /* #128 = 0x80 */ 128, 129, 130, 131, 132, 133, 134, 135, 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]; } + +/* Init data for Nixdorf BA63 & BA66 */ void serialVFD_load_Nixdorf_BA6x (Driver *drvthis) -{ // Nixdorf BA63 & BA66 +{ PrivateData *p = (PrivateData*) drvthis->private_data; int tmp, w; - //if (p->customchars == -83) // display doesn't support custom characters - p->customchars = 0; // number of custom characters the display provides - p->vbar_cc_offset = 5; // character offset of the bars - p->hbar_cc_offset = 12; // character offset of the bars - p->predefined_hbar = 1; // the display has predefined hbar-characters - p->predefined_vbar = 1; // the display has predefined vbar-characters + p->customchars = 0; /* display doesn't support custom characters */ + p->vbar_cc_offset = 5; + p->hbar_cc_offset = 12; + p->predefined_hbar = 1; + p->predefined_vbar = 1; - // hardwarespecific commands: - // hw_cmd[Command][data] = {{commandlength , command 1}, - // ..... - // {commandlength , command N}} + /*- + * hardwarespecific commands: + * hw_cmd[Command][data] = {{commandlength , command 1}, + * ..... + * {commandlength , command N}}; + */ const char hw_cmd[11][10] = {{0 }, // dark {0 }, {0 }, @@ -758,9 +845,9 @@ serialVFD_load_Nixdorf_BA6x (Driver *drvthis) for (w = 0; w < 10; 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[] = { - 0xDB, // the "filled-block"-character usually 127 + 0xDB, /* the "filled-block"-character usually 127 */ /* #128 = 0x80 */ 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, diff --git a/server/drivers/serialVFD_displays.h b/server/drivers/serialVFD_displays.h index bf39ec0..6038d88 100644 --- a/server/drivers/serialVFD_displays.h +++ b/server/drivers/serialVFD_displays.h @@ -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!) - - 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 */ +/* + * 2006-05-16 Version 0.3: everything should work (not all hardware tested!) + */ #ifndef SERIALVFD_DISPLAYS_H #define SERIALVFD_DISPLAYS_H -#include "lcd.h" -#include "serialVFD.h" +#define CC_UNSET -83 /**< number of custom characters not set */ int serialVFD_load_display_data(Driver *drvthis); #endif diff --git a/server/drivers/serialVFD_io.c b/server/drivers/serialVFD_io.c index f641b4d..e9341ea 100644 --- a/server/drivers/serialVFD_io.c +++ b/server/drivers/serialVFD_io.c @@ -4,49 +4,65 @@ * 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 - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - -*/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include +#include +#include +#include +#include +#include "lcd.h" +#include "report.h" +#include "lpt-port.h" #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 +/* + * XXX: ENIRQ used to be set, although no IRQ handler is defined. As the + * schematic in the user guide shows BUSY connected to ACK, leave it as is. + */ +#define WR_on ((ENIRQ | STRB) ^ OUTMASK) /* STRB (1) is active low */ +#define WR_off (ENIRQ ^ OUTMASK) #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 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 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 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++) { 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_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_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); + /* + * 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++) { - if ((port_in(p->port+1)) & Busy) + if ((port_in(p->port+1)) & BUSY) 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); } #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 serialVFD_init_serial (Driver *drvthis) { @@ -113,12 +158,12 @@ serialVFD_init_serial (Driver *drvthis) tcgetattr(p->fd, &portset); - // We use RAW mode + /* We use RAW mode */ #ifdef HAVE_CFMAKERAW - // The easy way + /* The easy way */ cfmakeraw( &portset ); #else - // The hard way + /* The hard way */ portset.c_iflag &= ~( IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON ); portset.c_oflag &= ~OPOST; @@ -127,15 +172,20 @@ serialVFD_init_serial (Driver *drvthis) portset.c_cflag |= CS8 | CREAD | CLOCAL ; #endif - // Set port speed + /* Set port speed */ cfsetospeed(&portset, p->speed); cfsetispeed(&portset, B0); - // Do it... + /* Do it... */ tcsetattr(p->fd, TCSANOW, &portset); 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 serialVFD_init_parallel (Driver *drvthis) { @@ -153,6 +203,10 @@ serialVFD_init_parallel (Driver *drvthis) #endif } +/** + * Close serial port. + * \param drvthis Pointer to driver + */ void serialVFD_close_serial (Driver *drvthis) { @@ -161,6 +215,10 @@ serialVFD_close_serial (Driver *drvthis) close(p->fd); } +/** + * Close parallel port. + * \param drvthis Pointer to driver + */ void serialVFD_close_parallel (Driver *drvthis) { diff --git a/server/drivers/serialVFD_io.h b/server/drivers/serialVFD_io.h index 1aa0713..e73616c 100644 --- a/server/drivers/serialVFD_io.h +++ b/server/drivers/serialVFD_io.h @@ -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!) - - 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 */ +/* + * 2006-05-16 Version 0.3: everything should work (not all hardware tested!) + */ #ifndef SERIALVFD_IO_H #define SERIALVFD_IO_H -#include -#include -#include -#include -#include -#include -#include -#include - -#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, 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_parallel (Driver *drvthis); +/** Function list for low-level I/O routines */ typedef struct Port_fkt { void (*write_fkt) (Driver *drvthis, unsigned char *dat, size_t length); int (*init_fkt) (Driver *drvthis); void (*close_fkt) (Driver *drvthis); } 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[] = { - // initialisation function - // write function - {serialVFD_write_serial, serialVFD_init_serial, serialVFD_close_serial}, {serialVFD_write_parallel, serialVFD_init_parallel, serialVFD_close_parallel} }; - #endif