Make the sed1520 driver work in 80-family connection style without requiring

an external inverter.
This commit is contained in:
mmdolze
2011-12-29 17:00:49 +00:00
parent cd22706496
commit 1d47d3abc3
4 changed files with 79 additions and 35 deletions
+1
View File
@@ -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)
+6 -1
View File
@@ -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]
+21 -17
View File
@@ -48,11 +48,12 @@ without having a datasheet to check against!</para>
<sect3 id="sed1520-80">
<title>80-style connection style</title>
<para>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.</para>
<para>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
(<ulink url="http://www.usblcd.de/lcdproc/sed1520.php4">SED1520 LPT Port</ulink>).
</para>
<table id="sed1520-connections-80-mapping">
<title>SED1520 80-style wiring schematic</title>
@@ -214,14 +215,6 @@ line. Writing is controlled by toggling the E1 and E2 line while /RW is low.
</tgroup>
</table>
<note>
<para>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.</para>
</note>
</sect3>
</sect2>
@@ -257,10 +250,11 @@ the other at the same time and the data bus got fuzzed.</para>
the level of the RESET line: 68-style MCU interface (high level) or
80-style MCU interface (low level).
</para><para>
Use value <literal>68</literal> 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 <literal>80</literal> (the default), 80-style style is selected
and the /WR line is cycled and /CS1 and /CS2 lines are required.
Use value <literal>68</literal> if your display is connected using
&quot;68 family MPU&quot; style. In this mode E1 and E2 lines are cycled to
write the data. If you use <literal>80</literal> (the default),
&quot;80 family MPU&quot; style is selected and the /WR line is cycled and
/CS1 and /CS2 lines are required.
</para></listitem>
</varlistentry>
@@ -276,6 +270,16 @@ the other at the same time and the data bus got fuzzed.</para>
lot, larger value should likely be avoided.
</para></listitem>
</varlistentry>
<varlistentry>
<term>
<property>haveInverter</property> = &parameters.yesdefno;
</term>
<listitem><para>
The original wiring by Robin used an inverter to drive the control lines.
If you do not use an inverter set this to <literal>no</literal>.
</para></listitem>
</varlistentry>
</variablelist>
</sect3>
+51 -17
View File
@@ -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);