diff --git a/ChangeLog b/ChangeLog
index eabf82a..7c9d21b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -21,6 +21,7 @@ v0.5dev (ongoing development)
+ glcd driver: new connection type 'glcd2usb'
* lcdproc client: On FreeBSD show only unique processes in 'S' screen
* picolcd: Use libusb-1.0 asynchronous transfers to fix missed keys (M. Jones)
+ * sed1520: Make it work without using an external inverter
v0.5.5
+ sed1330 driver: Add support for HG25504 (L. Lagendijk)
diff --git a/LCDd.conf b/LCDd.conf
index ade7ce0..ee20de7 100644
--- a/LCDd.conf
+++ b/LCDd.conf
@@ -1029,13 +1029,18 @@ Port=0x378
# Select the interface type (wiring) for the display. Supported values are
# 68 for 68-style connection (RESET level high) and 80 for 80-style connection
# (RESET level low). [legal: 68, 80; default: 80]
-InterfaceType=68
+InterfaceType=80
# On fast machines it may be necessary to slow down transfer to the display.
# If this value is set to zero, delay is disabled. Any value greater than
# zero slows down each write by one microsecond. [legal: 0-1000; default: 1]
DelayMult=0
+# The original wiring used an inverter to drive the control lines. If you do
+# not use an inverter set haveInverter to off. [default: yes; legal: yes, no]
+haveInverter=no
+
+
## serial POS display driver ##
[serialPOS]
diff --git a/docs/lcdproc-user/drivers/sed1520.docbook b/docs/lcdproc-user/drivers/sed1520.docbook
index 4c0d479..f6c4ee9 100644
--- a/docs/lcdproc-user/drivers/sed1520.docbook
+++ b/docs/lcdproc-user/drivers/sed1520.docbook
@@ -48,11 +48,12 @@ without having a datasheet to check against!
80-style connection style
-This mode of operation is selected if the RESET line is wired to ground.
-The wiring used by this driver in 80-style mode requires the use of an external
-74HC04 inverter and assumes you have /CS1 and /CS2 lines available (thus you
-must have an external clock generator) and toggles the /RW line. This is the
-original wiring by Robin Adams.
+This mode of operation is selected if the RESET line is wired to
+ground. The wiring used by this driver in 80-style mode assumes you have
+/CS1 and /CS2 lines available (thus you must have an external clock
+generator) and toggles the /RW line. This is the original wiring by Robin Adams
+(SED1520 LPT Port).
+
SED1520 80-style wiring schematic
@@ -214,14 +215,6 @@ line. Writing is controlled by toggling the E1 and E2 line while /RW is low.
-
-This is the only wiring I was able to test. My display (Crystalfontz
-CFAG12232J-TFH-TA) has E1 and E2 lines. Trying to use it with 80-style wiring
-was not successful. I suspect that (as the E# line is used as /RD line in
-80-style mode) the wiring resulted in reading from one chip while writing to
-the other at the same time and the data bus got fuzzed.
-
-
@@ -257,10 +250,11 @@ the other at the same time and the data bus got fuzzed.
the level of the RESET line: 68-style MCU interface (high level) or
80-style MCU interface (low level).
- Use value 68 if your display is connected 68-style
- style. In this mode the E1 and E2 lines are cycled to write the data. If
- you use 80 (the default), 80-style style is selected
- and the /WR line is cycled and /CS1 and /CS2 lines are required.
+ Use value 68 if your display is connected using
+ "68 family MPU" style. In this mode E1 and E2 lines are cycled to
+ write the data. If you use 80 (the default),
+ "80 family MPU" style is selected and the /WR line is cycled and
+ /CS1 and /CS2 lines are required.
@@ -276,6 +270,16 @@ the other at the same time and the data bus got fuzzed.
lot, larger value should likely be avoided.
+
+
+
+ haveInverter = ¶meters.yesdefno;
+
+
+ The original wiring by Robin used an inverter to drive the control lines.
+ If you do not use an inverter set this to no.
+
+
diff --git a/server/drivers/sed1520.c b/server/drivers/sed1520.c
index 6cac7cc..11da781 100644
--- a/server/drivers/sed1520.c
+++ b/server/drivers/sed1520.c
@@ -57,6 +57,7 @@ typedef struct sed1520_private_data {
unsigned short port;
int interface;
int delayMult;
+ int haveInverter;
unsigned char *framebuf;
} PrivateData;
@@ -90,17 +91,31 @@ writecommand(PrivateData *p, int value, int chip)
}
else {
port_out(p->port, value);
- /*
- * lower WR, rise A0 and CS1 and/or CS2. Take bit inversion of parallel
- * port into account. External inverter required!
- */
- port_out(p->port + 2, WR + CS1 - (chip & CS1) + (chip & CS2));
- /* rise WR */
- port_out(p->port + 2, CS1 - (chip & CS1) + (chip & CS2));
- if (p->delayMult) uPause(p->delayMult);
- /* lower WR again */
- port_out(p->port + 2, WR + CS1 - (chip & CS1) + (chip & CS2));
- if (p->delayMult) uPause(p->delayMult);
+ if (p->haveInverter) {
+ /*
+ * lower WR, rise A0 and CS1 and/or CS2 taking bit inversion of
+ * parallel port into account. External inverter required!
+ */
+ port_out(p->port + 2, WR + CS1 - (chip & CS1) + (chip & CS2));
+ /* rise WR */
+ port_out(p->port + 2, CS1 - (chip & CS1) + (chip & CS2));
+ if (p->delayMult)
+ uPause(p->delayMult);
+ /* lower WR again */
+ port_out(p->port + 2, WR + CS1 - (chip & CS1) + (chip & CS2));
+ if (p->delayMult)
+ uPause(p->delayMult);
+ }
+ else { /* No inverter connected */
+ /* Note: CS?-(chip&CS?) drive the pin low if controller is set */
+ port_out(p->port + 2, (WR + CS1 - (chip & CS1) + CS2 - (chip & CS2)) ^ OUTMASK);
+ port_out(p->port + 2, (CS1 - (chip & CS1) + CS2 - (chip & CS2)) ^ OUTMASK);
+ if (p->delayMult)
+ uPause(p->delayMult);
+ port_out(p->port + 2, (WR + CS1 - (chip & CS1) + CS2 - (chip & CS2)) ^ OUTMASK);
+ if (p->delayMult)
+ uPause(p->delayMult);
+ }
}
}
@@ -123,12 +138,25 @@ writedata(PrivateData *p, int value, int chip)
}
else {
port_out(p->port, value);
- /* lower WR and A0, rise CS1 and/or CS2. See also writecommand. */
- port_out(p->port + 2, A0 + WR + CS1 - (chip & CS1) + (chip & CS2));
- port_out(p->port + 2, A0 + CS1 - (chip & CS1) + (chip & CS2));
- if (p->delayMult) uPause(p->delayMult);
- port_out(p->port + 2, A0 + WR + CS1 - (chip & CS1) + (chip & CS2));
- if (p->delayMult) uPause(p->delayMult);
+ if (p->haveInverter) {
+ /* lower WR and A0, rise CS1 and/or CS2. See also writecommand. */
+ port_out(p->port + 2, A0 + WR + CS1 - (chip & CS1) + (chip & CS2));
+ port_out(p->port + 2, A0 + CS1 - (chip & CS1) + (chip & CS2));
+ if (p->delayMult)
+ uPause(p->delayMult);
+ port_out(p->port + 2, A0 + WR + CS1 - (chip & CS1) + (chip & CS2));
+ if (p->delayMult)
+ uPause(p->delayMult);
+ }
+ else {
+ port_out(p->port + 2, (A0 + WR + CS1 - (chip & CS1) + CS2 - (chip & CS2)) ^ OUTMASK);
+ port_out(p->port + 2, (A0 + CS1 - (chip & CS1) + CS2 - (chip & CS2)) ^ OUTMASK);
+ if (p->delayMult)
+ uPause(p->delayMult);
+ port_out(p->port + 2, (A0 + WR + CS1 - (chip & CS1) + CS2 - (chip & CS2)) ^ OUTMASK);
+ if (p->delayMult)
+ uPause(p->delayMult);
+ }
}
}
@@ -255,6 +283,12 @@ sed1520_init(Driver * drvthis)
p->interface = 80;
}
+ /*
+ * The original wiring used an inverter to drive the control lines. As
+ * someone may still be using this, the following setting in ON by default.
+ */
+ p->haveInverter = drvthis->config_get_bool(drvthis->name, "haveInverter", 0, 1);
+
/* Initialize display */
writecommand(p, SOFT_RESET, CS1 + CS2);
writecommand(p, DISP_ON, CS1 + CS2);