From 42e23909e0118d73b2657f9d4423cffd1a0ea3a0 Mon Sep 17 00:00:00 2001 From: reinelt <> Date: Fri, 15 Aug 2003 07:54:07 +0000 Subject: [lcd4linux @ 2003-08-15 07:54:07 by reinelt] HD44780 4 bit mode implemented --- HD44780.c | 124 ++++++++++++++++++++++++++++++++++++++++++++------------------ M50530.c | 13 ++++--- T6963.c | 13 ++++--- parport.c | 56 +++++++++++++++++++++++----- parport.h | 8 +++- 5 files changed, 158 insertions(+), 56 deletions(-) diff --git a/HD44780.c b/HD44780.c index 3aedffb..ce54b24 100644 --- a/HD44780.c +++ b/HD44780.c @@ -1,4 +1,4 @@ -/* $Id: HD44780.c,v 1.30 2003/08/12 05:10:31 reinelt Exp $ +/* $Id: HD44780.c,v 1.31 2003/08/15 07:54:07 reinelt Exp $ * * driver for display modules based on the HD44780 chip * @@ -24,6 +24,9 @@ * * * $Log: HD44780.c,v $ + * Revision 1.31 2003/08/15 07:54:07 reinelt + * HD44780 4 bit mode implemented + * * Revision 1.30 2003/08/12 05:10:31 reinelt * first version of HD44780 4Bit-Mode patch * @@ -188,12 +191,12 @@ #define T_PW 400 // Enable pulse width #define T_AS 20 // Address setup time #define T_H 40 // Data hold time -// Fixme: hejl: genau verdreht?? static LCD Lcd; static char Txt[4][40]; +static int Bits=0; static int GPO=0; static unsigned char SIGNAL_RW; @@ -240,18 +243,26 @@ static void HD_byte (unsigned char data, unsigned char RS) static void HD_command (unsigned char cmd, int delay) { - // put data on DB1..DB8 - parport_data (cmd); + if (Bits==8) { + + // put data on DB1..DB8 + parport_data (cmd); - // clear RW and RS - parport_control (SIGNAL_RW | SIGNAL_RS, 0); + // clear RW and RS + parport_control (SIGNAL_RW | SIGNAL_RS, 0); - // Address set-up time - ndelay(T_AS); + // Address set-up time + ndelay(T_AS); - // send command - parport_toggle (SIGNAL_ENABLE, 1, T_PW); - + // send command + parport_toggle (SIGNAL_ENABLE, 1, T_PW); + + } else { + + HD_byte (cmd, 0); + + } + // wait for command completion udelay(delay); @@ -260,24 +271,40 @@ static void HD_command (unsigned char cmd, int delay) static void HD_write (char *string, int len, int delay) { - // clear RW, set RS - parport_control (SIGNAL_RW | SIGNAL_RS, SIGNAL_RS); - // Address set-up time - ndelay(40); - - while (len--) { - - // put data on DB1..DB8 - parport_data (*(string++)); - - // send command - // Enable cycle time = 230ns - parport_toggle (SIGNAL_ENABLE, 1, 230); + if (Bits==8) { + + // clear RW, set RS + parport_control (SIGNAL_RW | SIGNAL_RS, SIGNAL_RS); + + // Address set-up time + ndelay(T_AS); - // wait for command completion - udelay(delay); + while (len--) { + + // put data on DB1..DB8 + parport_data (*(string++)); + + // send command + parport_toggle (SIGNAL_ENABLE, 1, T_PW); + + // wait for command completion + udelay(delay); + } + + } else { // 4 bit mode + + while (len--) { + + // send data with RS enabled + HD_byte (*(string++), SIGNAL_RS); + + // wait for command completion + udelay(delay); + } + } + } static void HD_setGPO (int bits) @@ -356,27 +383,54 @@ int HD_init (LCD *Self) Self->gpos=gpos; Lcd=*Self; - if ((SIGNAL_RW=parport_wire ("RW", "GND"))==0xff) return -1; - if ((SIGNAL_RS=parport_wire ("RS", "AUTOFD"))==0xff) return -1; - if ((SIGNAL_ENABLE=parport_wire ("ENABLE", "STROBE"))==0xff) return -1; - if ((SIGNAL_GPO=parport_wire ("GPO", "INIT"))==0xff) return -1; + s=cfg_get("Bits", "8"); + if ((Bits=strtol(s, &e, 0))==0 || *e!='\0' || (Bits!=4 && Bits!=8)) { + error ("HD44780: bad Bits '%s' in %s, should be '4' or '8'", s, cfg_file()); + return -1; + } + info ("wiring: using %d bit mode", Bits); + if (Bits==8) { + if ((SIGNAL_RS = parport_wire_ctrl ("RS", "AUTOFD"))==0xff) return -1; + if ((SIGNAL_RW = parport_wire_ctrl ("RW", "GND") )==0xff) return -1; + if ((SIGNAL_ENABLE = parport_wire_ctrl ("ENABLE", "STROBE"))==0xff) return -1; + if ((SIGNAL_GPO = parport_wire_ctrl ("GPO", "INIT") )==0xff) return -1; + } else { + if ((SIGNAL_RS = parport_wire_data ("RS", "DB4"))==0xff) return -1; + if ((SIGNAL_RW = parport_wire_data ("RW", "DB5"))==0xff) return -1; + if ((SIGNAL_ENABLE = parport_wire_data ("ENABLE", "DB6"))==0xff) return -1; + if ((SIGNAL_GPO = parport_wire_data ("GPO", "DB7"))==0xff) return -1; + } + if (parport_open() != 0) { error ("HD44780: could not initialize parallel port!"); return -1; } // clear RW - parport_control (SIGNAL_RW, 0); + if (Bits==8) { + parport_control (SIGNAL_RW, 0); + } else { + parport_data (0); + } // set direction: write parport_direction (0); // initialize display - HD_command (0x30, 4100); // 8 Bit mode, wait 4.1 ms - HD_command (0x30, 100); // 8 Bit mode, wait 100 us - HD_command (0x30, 4100); // 8 Bit mode, wait 4.1 ms - HD_command (0x38, 40); // 8 Bit mode, 1/16 duty cycle, 5x8 font + if (Bits==8) { + HD_command (0x30, 4100); // 8 Bit mode, wait 4.1 ms + HD_command (0x30, 100); // 8 Bit mode, wait 100 us + HD_command (0x30, 4100); // 8 Bit mode, wait 4.1 ms + HD_command (0x38, 40); // 8 Bit mode, 1/16 duty cycle, 5x8 font + } else { + HD_nibble(0x03); udelay(4100); // 4 Bit mode, wait 4.1 ms + HD_nibble(0x03); udelay(100); // 4 Bit mode, wait 100 us + HD_nibble(0x03); udelay(4100); // 4 Bit mode, wait 4.1 ms + HD_nibble(0x02); udelay(100); // 4 Bit mode, wait 100 us + HD_command (0x28, 40); // 4 Bit mode, 1/16 duty cycle, 5x8 font + } + HD_command (0x08, 40); // Display off, cursor off, blink off HD_command (0x0c, 1640); // Display on, cursor off, blink off, wait 1.64 ms HD_command (0x06, 40); // curser moves to right, no shift diff --git a/M50530.c b/M50530.c index e079463..402e597 100644 --- a/M50530.c +++ b/M50530.c @@ -1,4 +1,4 @@ -/* $Id: M50530.c,v 1.9 2003/07/24 04:48:09 reinelt Exp $ +/* $Id: M50530.c,v 1.10 2003/08/15 07:54:07 reinelt Exp $ * * driver for display modules based on the M50530 chip * @@ -20,6 +20,9 @@ * * * $Log: M50530.c,v $ + * Revision 1.10 2003/08/15 07:54:07 reinelt + * HD44780 4 bit mode implemented + * * Revision 1.9 2003/07/24 04:48:09 reinelt * 'soft clear' needed for virtual rows * @@ -202,10 +205,10 @@ int M5_init (LCD *Self) Self->gpos=gpos; Lcd=*Self; - if ((SIGNAL_EX=parport_wire ("EX", "STROBE"))==0xff) return -1; - if ((SIGNAL_IOC1=parport_wire ("IOC1", "SELECT"))==0xff) return -1; - if ((SIGNAL_IOC2=parport_wire ("IOC2", "AUTOFD"))==0xff) return -1; - if ((SIGNAL_GPO=parport_wire ("GPO", "INIT"))==0xff) return -1; + if ((SIGNAL_EX = parport_wire_ctrl ("EX", "STROBE"))==0xff) return -1; + if ((SIGNAL_IOC1 = parport_wire_ctrl ("IOC1", "SELECT"))==0xff) return -1; + if ((SIGNAL_IOC2 = parport_wire_ctrl ("IOC2", "AUTOFD"))==0xff) return -1; + if ((SIGNAL_GPO = parport_wire_ctrl ("GPO", "INIT") )==0xff) return -1; if (parport_open() != 0) { error ("M50530: could not initialize parallel port!"); diff --git a/T6963.c b/T6963.c index 47bcf8b..20221bf 100644 --- a/T6963.c +++ b/T6963.c @@ -1,4 +1,4 @@ -/* $Id: T6963.c,v 1.8 2003/08/01 05:15:42 reinelt Exp $ +/* $Id: T6963.c,v 1.9 2003/08/15 07:54:07 reinelt Exp $ * * driver for display modules based on the Toshiba T6963 chip * @@ -20,6 +20,9 @@ * * * $Log: T6963.c,v $ + * Revision 1.9 2003/08/15 07:54:07 reinelt + * HD44780 4 bit mode implemented + * * Revision 1.8 2003/08/01 05:15:42 reinelt * last cleanups for 0.9.9 * @@ -342,10 +345,10 @@ int T6_init (LCD *Self) return -1; } - if ((SIGNAL_CE=parport_wire ("CE", "STROBE"))==0xff) return -1; - if ((SIGNAL_CD=parport_wire ("CD", "SELECT"))==0xff) return -1; - if ((SIGNAL_RD=parport_wire ("RD", "AUTOFD"))==0xff) return -1; - if ((SIGNAL_WR=parport_wire ("WR", "INIT"))==0xff) return -1; + if ((SIGNAL_CE=parport_wire_ctrl ("CE", "STROBE"))==0xff) return -1; + if ((SIGNAL_CD=parport_wire_ctrl ("CD", "SELECT"))==0xff) return -1; + if ((SIGNAL_RD=parport_wire_ctrl ("RD", "AUTOFD"))==0xff) return -1; + if ((SIGNAL_WR=parport_wire_ctrl ("WR", "INIT") )==0xff) return -1; if (parport_open() != 0) { error ("HD44780: could not initialize parallel port!"); diff --git a/parport.c b/parport.c index 2b22469..a1714ed 100644 --- a/parport.c +++ b/parport.c @@ -1,4 +1,4 @@ -/* $Id: parport.c,v 1.2 2003/04/07 06:03:05 reinelt Exp $ +/* $Id: parport.c,v 1.3 2003/08/15 07:54:07 reinelt Exp $ * * generic parallel port handling * @@ -20,6 +20,9 @@ * * * $Log: parport.c,v $ + * Revision 1.3 2003/08/15 07:54:07 reinelt + * HD44780 4 bit mode implemented + * * Revision 1.2 2003/04/07 06:03:05 reinelt * further parallel port abstraction * @@ -40,10 +43,14 @@ * closes parallel port * returns 0 if ok, -1 on failure * - * unsigned char parport_wire (char *name, char *deflt) + * unsigned char parport_wire_ctrl (char *name, char *deflt) * reads wiring for one control signal from config * returns PARPORT_CONTROL_* or 255 on error * + * unsigned char parport_wire_data (char *name, char *deflt) + * reads wiring for one data signal from config + * returns 1<[DISPLAY:%s]", name); + info ("wiring: [DISPLAY:%s]<==>[PARPORT:STROBE]", name); } if (w&PARPORT_CONTROL_AUTOFD) { - info ("wiring: [PARPORT:AUTOFD]==>[DISPLAY:%s]", name); + info ("wiring: [DISPLAY:%s]<==>[PARPORT:AUTOFD]", name); } if (w&PARPORT_CONTROL_INIT) { - info ("wiring: [PARPORT:INIT]==>[DISPLAY:%s]", name); + info ("wiring: [DISPLAY:%s]<==>[PARPORT:INIT]", name); } if (w&PARPORT_CONTROL_SELECT) { - info ("wiring: [PARPORT:SELECT]==>[DISPLAY:%s]", name); + info ("wiring: [DISPLAY:%s]<==>[PARPORT:SELECT]", name); } if (w==0) { - info ("wiring: [PARPORT:GND]==>[DISPLAY:%s]", name); + info ("wiring: [DISPLAY:%s]<==>[PARPORT:GND]", name); } return w; } +unsigned char parport_wire_data (char *name, unsigned char *deflt) +{ + unsigned char w; + char wire[256]; + int is_data=0; + char *s; + + snprintf (wire, sizeof(wire), "Wire.%s", name); + s=cfg_get (wire,deflt); + if(strlen(s)==3 && strncasecmp(s,"DB",2)==0 && s[2]>='0' && s[2]<='7') { + w=s[2]-'0'; + } else if(strcasecmp(s,"GND")==0) { + w=0; + } else { + error ("parport: unknown signal <%s> for wire <%s>", s, name); + error (" should be DB..7 or GND"); + return 0xff; + } + + if (w==0) { + info ("wiring: [DISPLAY:%s]<==>[PARPORT:GND]", name); + } else { + info ("wiring: [DISPLAY:%s]<==>[PARPORT:DB%d]", name, w); + } + + w=1<