diff --git a/ChangeLog b/ChangeLog
index a945ee4..a530169 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -60,6 +60,7 @@ v.0.5dev (ongoing development)
* new make targets to compile & install server & clients separately
* autoconf fixes: check for pkg-config macros
+ new driver irtrans (Phant0m / Aron Parsons)
+ + serialVFD driver: support Siemens/Wincor Nixdorf BA63/66 (Stefan Herdler)
v.0.5.2
* fix switching on/off the Load screen in lcdproc client using the menu
diff --git a/LCDd.conf b/LCDd.conf
index 660123a..ea2f94f 100644
--- a/LCDd.conf
+++ b/LCDd.conf
@@ -887,6 +887,7 @@ Speed=9600
# 5 IEE S03601-96-080 (*)
# 6 Futaba NA202SD08FA (allmost IEE compatible)
# 7 Samsung 20S207DA4 and 20S207DA6
+# 8 Nixdorf BA6x / VT100
# (* most should work, not testet yet.)
Type=0
diff --git a/docs/lcdproc-user/drivers/serialVFD.docbook b/docs/lcdproc-user/drivers/serialVFD.docbook
index 25a131d..ad46cf0 100644
--- a/docs/lcdproc-user/drivers/serialVFD.docbook
+++ b/docs/lcdproc-user/drivers/serialVFD.docbook
@@ -64,7 +64,7 @@ Feedback is welcome.
KD Rev 2.1
AT90S.... microcontroller
Ok
- Ok
+ -
Yes
1, 0
@@ -166,6 +166,16 @@ Feedback is welcome.
5
+
+ Siemens/Wincor Nixdorf BA63/66
+ ?
+ Ok
+ -
+ Yes
+ 8
+ Display needs different connection, see below!
+ no Custom-Characters, no brightness-control
+
@@ -319,6 +329,19 @@ Pin 19 ------ RxD
]]>
+
+Siemens/Wincor Nixdorf BA63/66:
+This display doesn't need the inverter!
+It must be connected directly with the serial port.
+
+Check the serial port setup of the display, it has to be "9600 8N1". In most cases JP3 needs to be modified (closed) by the user!
+
+
+
+More detailed information can be found in the users manual of
+the display.
+
@@ -530,6 +553,10 @@ Number of Custom-Characters [default: Display-Type dependent]
7
Samsung 20S207DA?
+
+ 8
+ Siemens/Wincor Nixdorf BA63/66
+
diff --git a/server/drivers/serialVFD.c b/server/drivers/serialVFD.c
index 6c08bb8..4db881f 100644
--- a/server/drivers/serialVFD.c
+++ b/server/drivers/serialVFD.c
@@ -91,6 +91,7 @@ get_info Implemented.
#define init_cmds 7 //commands needed to initialize the display.
#define set_user_char 8 //set user character.
#define hor_tab 9 //moves cursor 1 chr right
+#define next_line 10 //moves cursor to the first character of the next line (= LF + CR)
#define LPTPORT 0x378
/* Vars for the server core */
@@ -103,6 +104,7 @@ MODULE_EXPORT char *symbol_prefix = "serialVFD_";
static void serialVFD_init_vbar (Driver *drvthis);
static void serialVFD_init_hbar (Driver *drvthis);
static void serialVFD_put_char (Driver *drvthis, int n);
+static void serialVFD_hw_write (Driver *drvthis, int i);
// Opens com port and sets baud correctly...
//
@@ -129,6 +131,7 @@ 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);
@@ -403,7 +406,7 @@ serialVFD_set_char (Driver *drvthis, int n, unsigned char *dat)
static void
serialVFD_put_char (Driver *drvthis, int n)
-{ // put char in display
+{ // put userchar in display
PrivateData *p = drvthis->private_data;
Port_Function[p->use_parallel].write_fkt(drvthis, &p->hw_cmd[set_user_char][1],\
@@ -413,7 +416,6 @@ serialVFD_put_char (Driver *drvthis, int n)
}
-
/////////////////////////////////////////////////////////////
// Blasts a single frame onscreen, to the lcd...
//
@@ -438,7 +440,7 @@ serialVFD_flush (Driver *drvthis)
}
if (p->refresh_timer > 500) { // Do a full refresh every 500 refreshs.
- // With this it is possible to switch display on and off while lcdproc is running
+ // 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],\
@@ -453,73 +455,107 @@ serialVFD_flush (Driver *drvthis)
p->refresh_timer++;
- if (p->display_type != 1) { //not KD Rev 2.1
+ 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
if (custom_char_changed[i])
serialVFD_put_char(drvthis, i);
- }
-
- if (custom_char_changed[p->last_custom])
- p->last_custom = -10;
-
- if (p->hw_cmd[mv_cursor][0] == 0) { // Workaround for Displays that doesn't support mv_cursor command
- 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
- */
-
- if ((p->framebuf[i] != p->backingstore[i]) ||
- ((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 (((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);
- }
- 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);
- }
- }
-
- 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)
- Port_Function[p->use_parallel].write_fkt(drvthis, "\x1A\xDB", 2);
- // overwrite selected character
- Port_Function[p->use_parallel].write_fkt(drvthis, &p->custom_char[(int)p->framebuf[i]][0], 7);
+ 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
+ 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
+ */
+
+ 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 (((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);
+ }
+ 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);
}
- Port_Function[p->use_parallel].write_fkt(drvthis, "\xDB", 1); // write character
- p->last_custom = p->framebuf[i];
- }
- else { // all other displays
- Port_Function[p->use_parallel].write_fkt(drvthis, (unsigned char *) &p->usr_chr_mapping[(int)p->framebuf[i]], 1);
}
+ serialVFD_hw_write(drvthis, i);
+ last_chr = i;
}
- 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 { // line mode Display (partitially borrowed from serialPOS.c)
+ for (j = 0; j < p->height; j++) {
+ // 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);
+ 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->framebuf[i], 1);
+ Port_Function[p->use_parallel].write_fkt(drvthis, &p->hw_cmd[next_line][1], p->hw_cmd[next_line][0]);
}
-
- last_chr = i;
+ // skip over identical lines
+ if ( memcmp(sp, sq, p->width) == 0) {
+ /* The lines are the same. */
+ continue;
+ }
+ for (i = 0; i < p->width; i++) {
+ serialVFD_hw_write(drvthis, (i + (j * p->width)));
+ }
+ last_chr = 10;
}
}
if (last_chr >= 0) { // update backingstore if something changed
memcpy(p->backingstore, p->framebuf, p->height * p->width);
-//report(RPT_WARNING, "%s: memcpy", drvthis->name);
+ //report(RPT_WARNING, "%s: memcpy", drvthis->name);
}
+
+}
+
+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->last_custom != p->framebuf[i]) {
+ // substitute and select character to overwrite (237)
+ Port_Function[p->use_parallel].write_fkt(drvthis, (unsigned char *)"\x1A\xDB", 2);
+ // 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
+ p->last_custom = p->framebuf[i];
+ }
+ 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
+ Port_Function[p->use_parallel].write_fkt(drvthis, &p->charmap[p->framebuf[i] - 127], 1);
+ }
+ else {
+ Port_Function[p->use_parallel].write_fkt(drvthis, &p->framebuf[i], 1);
+ }
}
diff --git a/server/drivers/serialVFD.h b/server/drivers/serialVFD.h
index 57b6821..e02238c 100644
--- a/server/drivers/serialVFD.h
+++ b/server/drivers/serialVFD.h
@@ -100,7 +100,7 @@ typedef struct driver_private_data {
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[10][4]; // hardwarespecific commands
+ 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
diff --git a/server/drivers/serialVFD_displays.c b/server/drivers/serialVFD_displays.c
index cb55369..8633a5f 100644
--- a/server/drivers/serialVFD_displays.c
+++ b/server/drivers/serialVFD_displays.c
@@ -40,7 +40,7 @@ void serialVFD_load_IEE_95B (Driver *drvthis);
void serialVFD_load_IEE_96 (Driver *drvthis);
void serialVFD_load_Futaba_NA202SD08FA(Driver *drvthis);
void serialVFD_load_Samsung (Driver *drvthis);
-
+void serialVFD_load_Nixdorf_BA6x (Driver *drvthis);
int serialVFD_load_display_data(Driver *drvthis)
{
@@ -70,6 +70,9 @@ int serialVFD_load_display_data(Driver *drvthis)
case 7:
serialVFD_load_Samsung(drvthis);
break;
+ case 8:
+ serialVFD_load_Nixdorf_BA6x(drvthis);
+ break;
default:
return -1;
break;
@@ -95,17 +98,22 @@ serialVFD_load_NEC_FIPC (Driver *drvthis)
// hw_cmd[Command][data] = {{commandlength , command 1},
// .....
// {commandlength , command N}}
- const char hw_cmd[10][4] = {{1 ,0x04}, // dark
+ const char hw_cmd[11][4] = {{1 ,0x04}, // dark
{1 ,0x03},
{1 ,0x02},
{1 ,0x01}, // bright
- {1 ,0x0D}, // pos1
+ {1 ,0x0D}, // pos1
+ // pos1 command is only used (and needed), when mv_cursor command is not supported
{1 ,0x1B}, // move cursor (set to 0 if not supported)
{1 ,0x0C}, // reset
{2 ,0x14, 0x11}, // init
{1 ,0x1A}, // set user char
- {1 ,0x09}}; // tab
- for (tmp = 0; tmp < 10; tmp++)
+ {1 ,0x09}, // tab
+ {0 }}; // next_line (only used in line mode)
+ // Line mode will be used if Next_line command is set!!!
+ // Do not set if the display supports normal mode (most displays should do this).
+
+ for (tmp = 0; tmp < 11; tmp++)
for (w = 0; w < 4; w++)
p->hw_cmd[tmp][w] = hw_cmd[tmp][w];
@@ -154,6 +162,15 @@ serialVFD_load_NEC_FIPC (Driver *drvthis)
{0xAF,0,0,0,0,0, 0x5F, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0, 0x5F, 0xE1, 0xE3, 0xE4};
for (tmp = 0; tmp < 31; tmp++)
p->usr_chr_mapping[tmp] = usr_chr_mapping[tmp];
+
+ // The following is only needet to set if the display needs a different setting
+ // for loading the usercharacters.
+ // Example: The character loaded to 0x00 will be shown at 0xFD.
+ // usr_chr_load_mapping[0] or usr_chr_load_mapping[1] has to be != 0
+ //const unsigned int usr_chr_load_mapping[31]=
+ //{ 0x02, 0x01, 0x00};
+ //for (tmp = 0; tmp < 31; tmp++)
+ // p->usr_chr_load_mapping[tmp] = usr_chr_load_mapping[tmp];
}
@@ -697,3 +714,76 @@ serialVFD_load_Samsung (Driver *drvthis)
for (tmp = 0; tmp < 31; tmp++)
p->usr_chr_mapping[tmp] = usr_chr_mapping[tmp];
}
+
+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
+
+ // hardwarespecific commands:
+ // hw_cmd[Command][data] = {{commandlength , command 1},
+ // .....
+ // {commandlength , command N}}
+ const char hw_cmd[11][10] = {{0 }, // dark
+ {0 },
+ {0 },
+ {0 }, // bright
+ {6 ,0x1B, 0x5B, '1', 0x3B, '1', 0x48}, // pos1
+ // pos1 command is only used (and needed), when mv_cursor command is not supported
+ {0 }, // move cursor
+ {4 ,0x1B, 0x5B, 0x32, 0x4A}, // reset
+ {3 ,0x1B, 0x52, 0x00}, // init
+ {0 }, // set user char
+ {0 }, // tab
+ {2 ,0x0D, 0x0A} // next_line
+ // Next_line command is only used in line mode.
+ // Line mode will be used if Next_line command is set!!!
+ // Set to "0" if display supports normal_mode!
+ };
+ for (tmp = 0; tmp < 11; tmp++)
+ for (w = 0; w < 10; w++)
+ p->hw_cmd[tmp][w] = hw_cmd[tmp][w];
+
+ // Translates ISO 8859-1 to display charset.
+ const unsigned char charmap[] = {
+ 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,
+ 144, 145, 146, 147, 148, 149, 150, 151,
+ 152, 153, 154, 155, 156, 157, 158, 159,
+ /* #160 = 0xA0 */
+ 160, 0xAD, 0x9B, 0x9C, 0xC8, 0x9D, 0x7C, 0xC0,
+ '"', '?', 0xA6, 0xAE, 0xAA, '-', '?', '?',
+ 0xEF, 0xCA, 0xC6, 0xC7, 0x27, 0xB8, '?', '.',
+ ',', '?', 0xA7, 0xAF, 0xAC, 0xAB, '?', 0xA8,
+ /* #192 = 0xC0 */
+ 0xD0, 'A', 0xD5, 'A', 0x8E, 0x8F, 0x92, 0x80,
+ 0xD1, 0x90, 0xD6, 0xD3, 'I', 'I', 0xD7, 0xD4,
+ 'D', 0xA5, 'O', 'O', 0xD8, 'O', 0x99, 'x',
+ '0', 0xD2, 'U', 0xD9, 0x9A, 'Y', 'p', 0xB1,
+ /* #224 = 0xE0 */
+ 0x85, 0xA0, 0x83, 'a', 0x84, 0x86, 0x91, 0x87,
+ 0x8A, 0x82, 0x88, 0x89, 0x8D, 0xA1, 0x8C, 0x8B,
+ 'o', 0xA4, 0x95, 0xA9, 0x93, 'o', 0x94, '/',
+ '0', 0x97, 0xA3, 0x96, 0x81, 'y', 'p', 0x89 };
+ for (tmp = 0; tmp < 129; tmp++)
+ p->charmap[tmp] = charmap[tmp];
+
+
+ // Where to place the usercharacters (0..30) in the asciicode.
+ // Also used to map standardcharacters in the usercharacterspace(0..30)
+ // (useful for displays with less then 30 usercharacters and predefined bars)
+ const unsigned int usr_chr_mapping[31]=
+ {0,0,0,0,0,0, ' ', ' ', 0xDC, 0xDC, 0xDC, 0xDB, 0, ' ', 0xDD, 0xDD, 0xDB};
+ for (tmp = 0; tmp < 31; tmp++)
+ p->usr_chr_mapping[tmp] = usr_chr_mapping[tmp];
+}
diff --git a/server/drivers/serialVFD_io.c b/server/drivers/serialVFD_io.c
index 0ef57e9..28e6a89 100644
--- a/server/drivers/serialVFD_io.c
+++ b/server/drivers/serialVFD_io.c
@@ -44,6 +44,9 @@
void
serialVFD_write_serial (Driver *drvthis, unsigned char *dat, size_t length)
{
+ if (length <= 0)
+ return;
+
PrivateData *p = drvthis->private_data;
write(p->fd,dat,length);
}
@@ -51,6 +54,9 @@ serialVFD_write_serial (Driver *drvthis, unsigned char *dat, size_t length)
void
serialVFD_write_parallel (Driver *drvthis, unsigned char *dat, size_t length)
{
+ if (length <= 0)
+ return;
+
#ifdef HAVE_PCSTYLE_LPT_CONTROL
PrivateData *p = drvthis->private_data;
int i_para, j_para;