From de0ea2d2bb15e857583dcb4560d2c7437d386902 Mon Sep 17 00:00:00 2001 From: reinelt <> Date: Sat, 18 Sep 2004 15:58:57 +0000 Subject: [lcd4linux @ 2004-09-18 15:58:57 by reinelt] even more HD44780 cleanups, hardwiring for LCM-162 --- drv_HD44780.c | 85 ++++++++++++++++++++++++++++++---------------- drv_generic_parport.c | 93 ++++++++++++++++++++++++++++++++------------------- drv_generic_parport.h | 12 ++++++- lcd4linux.conf.sample | 7 +--- 4 files changed, 128 insertions(+), 69 deletions(-) diff --git a/drv_HD44780.c b/drv_HD44780.c index 50ab383..fff9f5a 100644 --- a/drv_HD44780.c +++ b/drv_HD44780.c @@ -1,4 +1,4 @@ -/* $Id: drv_HD44780.c,v 1.36 2004/09/18 10:57:29 reinelt Exp $ +/* $Id: drv_HD44780.c,v 1.37 2004/09/18 15:58:57 reinelt Exp $ * * new style driver for HD44780-based displays * @@ -29,6 +29,9 @@ * * * $Log: drv_HD44780.c,v $ + * Revision 1.37 2004/09/18 15:58:57 reinelt + * even more HD44780 cleanups, hardwiring for LCM-162 + * * Revision 1.36 2004/09/18 10:57:29 reinelt * more parport/i2c cleanups * @@ -280,20 +283,21 @@ typedef struct { #define CAP_PARPORT (1<<0) #define CAP_I2C (1<<1) -#define CAP_BRIGHTNESS (1<<2) -#define CAP_BUSY4BIT (1<<3) -#define CAP_HD66712 (1<<4) -#define CAP_LCM162 (1<<5) +#define CAP_GPO (1<<2) +#define CAP_BRIGHTNESS (1<<3) +#define CAP_BUSY4BIT (1<<4) +#define CAP_HD66712 (1<<5) +#define CAP_LCM162 (1<<6) #define BUS_PP CAP_PARPORT #define BUS_I2C CAP_I2C static MODEL Models[] = { - { 0x01, "generic", CAP_PARPORT|CAP_I2C }, - { 0x02, "Noritake", CAP_PARPORT|CAP_I2C|CAP_BRIGHTNESS }, + { 0x01, "generic", CAP_PARPORT|CAP_I2C|CAP_GPO }, + { 0x02, "Noritake", CAP_PARPORT|CAP_I2C|CAP_GPO|CAP_BRIGHTNESS }, { 0x03, "Soekris", CAP_PARPORT|CAP_BUSY4BIT }, - { 0x04, "HD66712", CAP_PARPORT|CAP_I2C|CAP_HD66712 }, + { 0x04, "HD66712", CAP_PARPORT|CAP_I2C|CAP_GPO|CAP_HD66712 }, { 0x05, "LCM-162", CAP_PARPORT|CAP_LCM162 }, { 0xff, "Unknown", 0 } }; @@ -567,6 +571,12 @@ static int drv_HD_PP_load (const char *section) error ("%s: bad %s.Bits '%d' from %s, should be '4' or '8'", Name, section, Bits, cfg_source()); return -1; } + + /* LCM-162 only supports 8-bit-mode */ + if (Capabilities & CAP_LCM162 && Bits != 8) { + error ("%s: Model '%s' does not support %d bit mode!", Name, Models[Model].name, Bits); + Bits = 8; + } info ("%s: using %d bit mode", Name, Bits); if (drv_generic_parport_open(section, Name) != 0) { @@ -574,18 +584,27 @@ static int drv_HD_PP_load (const char *section) return -1; } - if (Bits==8) { - if ((SIGNAL_RS = drv_generic_parport_wire_ctrl ("RS", "AUTOFD"))==0xff) return -1; - if ((SIGNAL_RW = drv_generic_parport_wire_ctrl ("RW", "GND" ))==0xff) return -1; - if ((SIGNAL_ENABLE = drv_generic_parport_wire_ctrl ("ENABLE", "STROBE"))==0xff) return -1; - if ((SIGNAL_ENABLE2 = drv_generic_parport_wire_ctrl ("ENABLE2", "GND" ))==0xff) return -1; - if ((SIGNAL_GPO = drv_generic_parport_wire_ctrl ("GPO", "GND" ))==0xff) return -1; + /* the LCM-162 is hardwired */ + if (Capabilities & CAP_LCM162) { + if ((SIGNAL_RS = drv_generic_parport_hardwire_ctrl ("RS", "SELECT"))==0xff) return -1; + if ((SIGNAL_RW = drv_generic_parport_hardwire_ctrl ("RW", "INIT" ))==0xff) return -1; + if ((SIGNAL_ENABLE = drv_generic_parport_hardwire_ctrl ("ENABLE", "AUTOFD"))==0xff) return -1; + if ((SIGNAL_ENABLE2 = drv_generic_parport_hardwire_ctrl ("ENABLE2", "GND" ))==0xff) return -1; + if ((SIGNAL_GPO = drv_generic_parport_hardwire_ctrl ("GPO", "GND" ))==0xff) return -1; } else { - if ((SIGNAL_RS = drv_generic_parport_wire_data ("RS", "DB4"))==0xff) return -1; - if ((SIGNAL_RW = drv_generic_parport_wire_data ("RW", "DB5"))==0xff) return -1; - if ((SIGNAL_ENABLE = drv_generic_parport_wire_data ("ENABLE", "DB6"))==0xff) return -1; - if ((SIGNAL_ENABLE2 = drv_generic_parport_wire_data ("ENABLE2", "GND"))==0xff) return -1; - if ((SIGNAL_GPO = drv_generic_parport_wire_data ("GPO", "GND"))==0xff) return -1; + if (Bits==8) { + if ((SIGNAL_RS = drv_generic_parport_wire_ctrl ("RS", "AUTOFD"))==0xff) return -1; + if ((SIGNAL_RW = drv_generic_parport_wire_ctrl ("RW", "GND" ))==0xff) return -1; + if ((SIGNAL_ENABLE = drv_generic_parport_wire_ctrl ("ENABLE", "STROBE"))==0xff) return -1; + if ((SIGNAL_ENABLE2 = drv_generic_parport_wire_ctrl ("ENABLE2", "GND" ))==0xff) return -1; + if ((SIGNAL_GPO = drv_generic_parport_wire_ctrl ("GPO", "GND" ))==0xff) return -1; + } else { + if ((SIGNAL_RS = drv_generic_parport_wire_data ("RS", "DB4"))==0xff) return -1; + if ((SIGNAL_RW = drv_generic_parport_wire_data ("RW", "DB5"))==0xff) return -1; + if ((SIGNAL_ENABLE = drv_generic_parport_wire_data ("ENABLE", "DB6"))==0xff) return -1; + if ((SIGNAL_ENABLE2 = drv_generic_parport_wire_data ("ENABLE2", "GND"))==0xff) return -1; + if ((SIGNAL_GPO = drv_generic_parport_wire_data ("GPO", "GND"))==0xff) return -1; + } } /* clear all signals */ @@ -608,7 +627,7 @@ static int drv_HD_PP_load (const char *section) drv_HD_PP_nibble (allControllers, 0x03); udelay(T_INIT2); /* 4 Bit mode, wait 100 us */ drv_HD_PP_nibble (allControllers, 0x03); udelay(T_INIT1); /* 4 Bit mode, wait 4.1 ms */ drv_HD_PP_nibble (allControllers, 0x02); udelay(T_INIT2); /* 4 Bit mode, wait 100 us */ - drv_HD_PP_command (allControllers, 0x28, T_EXEC); /* 4 Bit mode, 1/16 duty cycle, 5x8 font */ + drv_HD_PP_command (allControllers, 0x28, T_EXEC); /* 4 Bit mode, 1/16 duty cycle, 5x8 font */ } /* maybe use busy-flag from now on */ @@ -617,7 +636,7 @@ static int drv_HD_PP_load (const char *section) /* make sure we don't use the busy flag with RW wired to GND */ if (UseBusy && !SIGNAL_RW) { - error("%s: Busyflag is to be used, but RW is wired to GND", Name); + error("%s: busy-flag checking is impossible with RW wired to GND!", Name); UseBusy=0; } @@ -625,12 +644,17 @@ static int drv_HD_PP_load (const char *section) /* at the moment this is inly possible with Martin Hejl's gpio driver, */ /* which allows to use 4 bits as input and 4 bits as output */ if (UseBusy && Bits==4 && !(Capabilities&CAP_BUSY4BIT)) { - error("%s: Model '%s' does not support busy-flag checking in 4-bit-mode", Name, Models[Model].name); + error("%s: Model '%s' does not support busy-flag checking in 4 bit mode", Name, Models[Model].name); UseBusy=0; } - info("%s: %susing busy-flag checking", Name, UseBusy?"":"not "); + info("%s: %susing busy-flag checking", Name, UseBusy ? "" : "not "); + /* The LCM-162 should really use BusyFlag checking */ + if (!UseBusy && (Capabilities & CAP_LCM162)) { + error("%s: Model '%s' should definitely use busy-flag checking!", Name, Models[Model].name); + } + return 0; } @@ -828,6 +852,7 @@ static int drv_HD_start (const char *section, const int quiet) if (model) free (model); return -1; } + free (model); bus=cfg_get(section, "Bus", "parport"); if (bus==NULL && *bus=='\0') { @@ -860,12 +885,10 @@ static int drv_HD_start (const char *section, const int quiet) /* sanity check: Model can use bus */ if (!(Capabilities & Bus)) { - error ("%s: Model '%s' cannot be used on the %s bus.", Name, model, bus); - free (model); + error ("%s: Model '%s' cannot be used on the %s bus!", Name, Models[Model].name, bus); free (bus); return -1; } - free(model); free(bus); size=cfg_get(section, "Size", NULL); @@ -884,7 +907,7 @@ static int drv_HD_start (const char *section, const int quiet) DCOLS = cols; if (cfg_number(section, "Controllers", 1, 1, 2, &numControllers)<0) return -1; - info ("%s: using display with %d controllers", Name, numControllers); + info ("%s: using %d controller(s)", Name, numControllers); /* current controller */ currController=1; @@ -893,8 +916,14 @@ static int drv_HD_start (const char *section, const int quiet) allControllers = numControllers==2 ? 3 : 1; if (cfg_number(section, "GPOs", 0, 0, 8, &gpos)<0) return -1; + if (gpos > 0 && !(Capabilities & CAP_GPO)) { + error ("%s: Model '%s' does not support GPO's!", Name, Models[Model].name); + gpos = 0; + } GPOS = gpos; - info ("%s: controlling %d GPO's", Name, GPOS); + if (gpos > 0) { + info ("%s: using %d GPO's", Name, GPOS); + } if (drv_HD_load(section) < 0) { error ("%s: start display failed!", Name); diff --git a/drv_generic_parport.c b/drv_generic_parport.c index 72e5423..5ec6bbd 100644 --- a/drv_generic_parport.c +++ b/drv_generic_parport.c @@ -1,4 +1,4 @@ -/* $Id: drv_generic_parport.c,v 1.10 2004/09/18 09:48:29 reinelt Exp $ +/* $Id: drv_generic_parport.c,v 1.11 2004/09/18 15:58:57 reinelt Exp $ * * generic driver helper for serial and parport access * @@ -23,6 +23,9 @@ * * * $Log: drv_generic_parport.c,v $ + * Revision 1.11 2004/09/18 15:58:57 reinelt + * even more HD44780 cleanups, hardwiring for LCM-162 + * * Revision 1.10 2004/09/18 09:48:29 reinelt * HD44780 cleanup and prepararation for I2C backend * LCM-162 submodel framework @@ -251,48 +254,70 @@ int drv_generic_parport_close (void) } -unsigned char drv_generic_parport_wire_ctrl (const char *name, const char *deflt) +static unsigned char drv_generic_parport_signal_ctrl (const char *name, const char *signal) { - unsigned char w; - char wire[256]; - char *s; - - qprintf(wire, sizeof(wire), "Wire.%s", name); - s=cfg_get (Section, wire, deflt); - if (strcasecmp(s,"STROBE")==0) { - w=PARPORT_CONTROL_STROBE; - } else if(strcasecmp(s,"AUTOFD")==0) { - w=PARPORT_CONTROL_AUTOFD; - } else if(strcasecmp(s,"INIT")==0) { - w=PARPORT_CONTROL_INIT; - } else if(strcasecmp(s,"SELECT")==0) { - w=PARPORT_CONTROL_SELECT; - } else if(strcasecmp(s,"GND")==0) { - w=0; - } else { - error ("%s: unknown signal <%s> for wire <%s>", Driver, s, name); - error ("%s: should be STROBE, AUTOFD, INIT, SELECT or GND", Driver); - return 0xff; - } - free(s); + unsigned char wire; - if (w&PARPORT_CONTROL_STROBE) { + if (strcasecmp(signal,"STROBE") == 0) { + wire = PARPORT_CONTROL_STROBE; info ("%s: wiring: [DISPLAY:%s]<==>[PARPORT:STROBE]", Driver, name); - } - if (w&PARPORT_CONTROL_AUTOFD) { + } else if(strcasecmp(signal,"AUTOFD") == 0) { + wire = PARPORT_CONTROL_AUTOFD; info ("%s: wiring: [DISPLAY:%s]<==>[PARPORT:AUTOFD]", Driver, name); - } - if (w&PARPORT_CONTROL_INIT) { + } else if(strcasecmp(signal,"INIT") == 0) { + wire = PARPORT_CONTROL_INIT; info ("%s: wiring: [DISPLAY:%s]<==>[PARPORT:INIT]", Driver, name); - } - if (w&PARPORT_CONTROL_SELECT) { + } else if(strcasecmp(signal,"SELECT") == 0) { + wire = PARPORT_CONTROL_SELECT; info ("%s: wiring: [DISPLAY:%s]<==>[PARPORT:SELECT]", Driver, name); - } - if (w==0) { + } else if(strcasecmp(signal,"GND") == 0) { + wire = 0; info ("%s: wiring: [DISPLAY:%s]<==>[PARPORT:GND]", Driver, name); + } else { + error ("%s: unknown signal <%s> for wire <%s>", Driver, signal, name); + error ("%s: should be STROBE, AUTOFD, INIT, SELECT or GND", Driver); + return 0xff; } - return w; + return wire; +} + + +unsigned char drv_generic_parport_wire_ctrl (const char *name, const char *deflt) +{ + unsigned char wire; + char key[256]; + char *val; + + qprintf(key, sizeof(key), "Wire.%s", name); + val = cfg_get (Section, key, deflt); + + wire = drv_generic_parport_signal_ctrl (name, val); + + free (val); + + return wire; +} + + +unsigned char drv_generic_parport_hardwire_ctrl (const char *name, const char *signal) +{ + unsigned char wire; + char key[256]; + char *val; + + qprintf(key, sizeof(key), "Wire.%s", name); + val = cfg_get (Section, key, ""); + + /* maybe warn the user */ + if (*val != '\0' && strcasecmp (signal, val) != 0) { + error ("%s: ignoring configured signal <%s> for wire <%s>", Driver, val, name); + } + free (val); + + wire = drv_generic_parport_signal_ctrl (name, signal); + + return wire; } diff --git a/drv_generic_parport.h b/drv_generic_parport.h index 0455951..2edf044 100644 --- a/drv_generic_parport.h +++ b/drv_generic_parport.h @@ -1,4 +1,4 @@ -/* $Id: drv_generic_parport.h,v 1.6 2004/09/18 08:22:59 reinelt Exp $ +/* $Id: drv_generic_parport.h,v 1.7 2004/09/18 15:58:57 reinelt Exp $ * * generic driver helper for parallel port displays * @@ -23,6 +23,9 @@ * * * $Log: drv_generic_parport.h,v $ + * Revision 1.7 2004/09/18 15:58:57 reinelt + * even more HD44780 cleanups, hardwiring for LCM-162 + * * Revision 1.6 2004/09/18 08:22:59 reinelt * drv_generic_parport_status() to read status lines * @@ -66,6 +69,13 @@ * reads wiring for one control signal from config * returns DRV_GENERIC_PARPORT_CONTROL_* or 255 on error * + * unsigned char drv_generic_parport_hardwire_ctrl (char *name) + * returns hardwiring for one control signal + * same as above, but does not read from config, + * but cheks the config and emits a warning that the config + * entry will be ignored + * returns DRV_GENERIC_PARPORT_CONTROL_* or 255 on error + * * unsigned char drv_generic_parport_wire_data (char *name, char *deflt) * reads wiring for one data signal from config * returns 1<