From 1d47d3abc3903e9e995d1941f65f43421ae846b5 Mon Sep 17 00:00:00 2001 From: mmdolze Date: Thu, 29 Dec 2011 17:00:49 +0000 Subject: [PATCH] Make the sed1520 driver work in 80-family connection style without requiring an external inverter. --- ChangeLog | 1 + LCDd.conf | 7 ++- docs/lcdproc-user/drivers/sed1520.docbook | 38 +++++++------ server/drivers/sed1520.c | 68 +++++++++++++++++------ 4 files changed, 79 insertions(+), 35 deletions(-) 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);