diff options
-rw-r--r-- | HD44780.c | 64 | ||||
-rw-r--r-- | M50530.c | 238 |
2 files changed, 129 insertions, 173 deletions
@@ -1,4 +1,4 @@ -/* $Id: HD44780.c,v 1.20 2001/09/09 12:26:03 reinelt Exp $ +/* $Id: HD44780.c,v 1.21 2002/04/30 07:20:15 reinelt Exp $ * * driver for display modules based on the HD44780 chip * @@ -20,6 +20,10 @@ * * * $Log: HD44780.c,v $ + * Revision 1.21 2002/04/30 07:20:15 reinelt + * + * implemented the new ndelay(nanoseconds) in all parallel port drivers + * * Revision 1.20 2001/09/09 12:26:03 reinelt * GPO bug: INIT is _not_ inverted * @@ -202,15 +206,20 @@ static SEGMENT Segment[128] = {{ len1:0, len2:0, type:255, used:0, ascii:32 { len1:255, len2:255, type:255, used:0, ascii:255 }}; #ifdef WITH_PPDEV -static void HD_toggle (int bit, int inv) +static void HD_toggle (int bit, int inv, int delay) { struct ppdev_frob_struct frob; - frob.mask=bit; - frob.val=inv?0:bit; // rise + + // rise + frob.val=inv?0:bit; ioctl (PPfd, PPFCONTROL, &frob); - udelay(1); - frob.val=inv?bit:0; // lower + + // pulse width + ndelay(delay); + + // lower + frob.val=inv?bit:0; ioctl (PPfd, PPFCONTROL, &frob); } #endif @@ -222,18 +231,22 @@ static void HD_command (unsigned char cmd, int delay) struct ppdev_frob_struct frob; + // put data on DB1..DB8 + ioctl(PPfd, PPWDATA, &cmd); + // clear RS (inverted) frob.mask=PARPORT_CONTROL_AUTOFD; frob.val=PARPORT_CONTROL_AUTOFD; ioctl (PPfd, PPFCONTROL, &frob); - // put data on DB1..DB8 - ioctl(PPfd, PPWDATA, &cmd); - + // Address set-up time + ndelay(40); + // send command - HD_toggle(PARPORT_CONTROL_STROBE, 1); + // Enable cycle time = 230ns + HD_toggle(PARPORT_CONTROL_STROBE, 1, 230); - // wait + // wait for command completion udelay(delay); } else @@ -242,11 +255,12 @@ static void HD_command (unsigned char cmd, int delay) { outb (cmd, Port); // put data on DB1..DB8 + outb (0x03, Port+2); // clear RS = bit 2 invertet + ndelay(40); // Address set-up time outb (0x02, Port+2); // set Enable = bit 0 invertet - udelay (1); + ndelay(230); // Enable cycle time outb (0x03, Port+2); // clear Enable - udelay (delay); - + udelay (delay); // wait for command completion } } @@ -262,16 +276,18 @@ static void HD_write (char *string, int len, int delay) frob.val=0; ioctl (PPfd, PPFCONTROL, &frob); + // Address set-up time + ndelay(40); + while (len--) { // put data on DB1..DB8 ioctl(PPfd, PPWDATA, string++); - udelay(1); // send command - HD_toggle(PARPORT_CONTROL_STROBE, 1); + HD_toggle(PARPORT_CONTROL_STROBE, 1, 230); - // wait + // wait for command completion udelay(delay); } @@ -280,10 +296,12 @@ static void HD_write (char *string, int len, int delay) #endif { + outb (0x01, Port+2); // set RS = bit 2 invertet + ndelay(40); // Address set-up time while (len--) { outb (*string++, Port); // put data on DB1..DB8 outb (0x00, Port+2); // set Enable = bit 0 invertet - udelay (1); + ndelay(230); // Enable cycle time outb (0x01, Port+2); // clear Enable udelay (delay); } @@ -302,8 +320,12 @@ static void HD_setGPO (int bits) // put data on DB1..DB8 ioctl(PPfd, PPWDATA, &bits); + // 74HCT573 set-up time + ndelay(20); + // toggle INIT - HD_toggle(PARPORT_CONTROL_INIT, 0); + // 74HCT573 enable pulse width = 24ns + HD_toggle(PARPORT_CONTROL_INIT, 0, 24); } else @@ -311,10 +333,10 @@ static void HD_setGPO (int bits) { outb (bits, Port); // put data on DB1..DB8 + ndelay(20); // 74HCT573 set-up time outb (0x05, Port+2); // set INIT = bit 2 invertet - udelay (1); + ndelay(24); // 74HCT573 enable pulse width outb (0x03, Port+2); // clear INIT - udelay (1); } } } @@ -1,4 +1,4 @@ -/* $Id: M50530.c,v 1.1 2001/09/11 05:31:37 reinelt Exp $ +/* $Id: M50530.c,v 1.2 2002/04/30 07:20:15 reinelt Exp $ * * driver for display modules based on the M50530 chip * @@ -20,6 +20,10 @@ * * * $Log: M50530.c,v $ + * Revision 1.2 2002/04/30 07:20:15 reinelt + * + * implemented the new ndelay(nanoseconds) in all parallel port drivers + * * Revision 1.1 2001/09/11 05:31:37 reinelt * M50530 driver * @@ -45,25 +49,12 @@ #include <errno.h> #include <sys/ioctl.h> -#ifdef HAVE_SYS_IO_H -#include <sys/io.h> -#define WITH_OUTB -#else -#ifdef HAVE_ASM_IO_H -#include <asm/io.h> -#define WITH_OUTB -#endif -#endif - #if defined (HAVE_LINUX_PARPORT_H) && defined (HAVE_LINUX_PPDEV_H) #define WITH_PPDEV #include <linux/parport.h> #include <linux/ppdev.h> -#endif - - -#if !defined(WITH_OUTB) && !defined(WITH_PPDEV) -#error neither outb() nor ppdev() possible +#else +#error The M50530 driver needs ppdev #error cannot compile M50530 driver #endif @@ -95,13 +86,8 @@ typedef struct { static LCD Lcd; -static unsigned short Port=0; - static char *PPdev=NULL; - -#ifdef WITH_PPDEV static int PPfd=-1; -#endif static char Txt[8][40]; static BAR Bar[8][40]; @@ -112,48 +98,44 @@ static SEGMENT Segment[128] = {{ len1:0, len2:0, type:255, used:0, ascii:32 }}; static void M5_command (unsigned int cmd, int delay) { -#ifdef WITH_PPDEV - if (PPdev) { - - unsigned char data; - struct ppdev_frob_struct frob; + unsigned char data; + struct ppdev_frob_struct frob; - // set I/OC1 (Select inverted) - // set I/OC2 (AutoFeed inverted) - frob.mask=PARPORT_CONTROL_SELECT | PARPORT_CONTROL_AUTOFD; - frob.val=0; - if (!(cmd & 0x200)) { - frob.val|=PARPORT_CONTROL_SELECT; - } - if (!(cmd & 0x100)) { - frob.val|=PARPORT_CONTROL_AUTOFD; - } - ioctl (PPfd, PPFCONTROL, &frob); - - // rise EX (Strobe, inverted) - frob.mask=PARPORT_CONTROL_STROBE; - frob.val=0; - ioctl (PPfd, PPFCONTROL, &frob); + // put data on DB1..DB8 + data=cmd&0xff; + ioctl(PPfd, PPWDATA, &data); - // put data on DB1..DB8 - data=cmd&0xff; - ioctl(PPfd, PPWDATA, &data); - - // lower EX (Strobe, inverted) - frob.mask=PARPORT_CONTROL_STROBE; - frob.val=PARPORT_CONTROL_STROBE; - ioctl (PPfd, PPFCONTROL, &frob); - - // wait - udelay(delay); + // set I/OC1 (Select inverted) + // set I/OC2 (AutoFeed inverted) + frob.mask=PARPORT_CONTROL_SELECT | PARPORT_CONTROL_AUTOFD; + frob.val=0; + if (!(cmd & 0x200)) { + frob.val|=PARPORT_CONTROL_SELECT; + } + if (!(cmd & 0x100)) { + frob.val|=PARPORT_CONTROL_AUTOFD; + } + ioctl (PPfd, PPFCONTROL, &frob); - } else + // Control data setup time + ndelay(200); -#endif + // rise EX (Strobe, inverted) + frob.mask=PARPORT_CONTROL_STROBE; + frob.val=0; + ioctl (PPfd, PPFCONTROL, &frob); + + // EX signal pulse width + ndelay(200); + + // lower EX (Strobe, inverted) + frob.mask=PARPORT_CONTROL_STROBE; + frob.val=PARPORT_CONTROL_STROBE; + ioctl (PPfd, PPFCONTROL, &frob); + + // wait + udelay(delay); - { - // Fixme: not implemented - } } static void M5_write (unsigned char *string, int len) @@ -170,68 +152,49 @@ static void M5_setGPO (int bits) { if (Lcd.gpos>0) { -#ifdef WITH_PPDEV - - if (PPdev) { - - struct ppdev_frob_struct frob; + struct ppdev_frob_struct frob; - // put data on DB1..DB8 - ioctl(PPfd, PPWDATA, &bits); - - // toggle INIT - frob.mask=PARPORT_CONTROL_INIT; - frob.val=PARPORT_CONTROL_INIT; // rise - ioctl (PPfd, PPFCONTROL, &frob); - udelay(1); - frob.val=0; // lower - ioctl (PPfd, PPFCONTROL, &frob); - - } else - -#endif - - { - // Fixme: not implemented - } + // put data on DB1..DB8 + ioctl(PPfd, PPWDATA, &bits); + + // 74HCT573 set-up time + ndelay(20); + + // toggle INIT + frob.mask=PARPORT_CONTROL_INIT; + frob.val=PARPORT_CONTROL_INIT; // rise + ioctl (PPfd, PPFCONTROL, &frob); + + // 74HCT573 enable pulse width + ndelay(24); + + frob.val=0; // lower + ioctl (PPfd, PPFCONTROL, &frob); } } static int M5_open (void) { -#ifdef WITH_PPDEV - if (PPdev) { - debug ("using ppdev %s", PPdev); - PPfd=open(PPdev, O_RDWR); - if (PPfd==-1) { - error ("open(%s) failed: %s", PPdev, strerror(errno)); - return -1; - } + debug ("using ppdev %s", PPdev); + PPfd=open(PPdev, O_RDWR); + if (PPfd==-1) { + error ("open(%s) failed: %s", PPdev, strerror(errno)); + return -1; + } #if 0 - if (ioctl(PPfd, PPEXCL)) { - debug ("ioctl(%s, PPEXCL) failed: %s", PPdev, strerror(errno)); - } else { - debug ("ioctl(%s, PPEXCL) succeded."); - } -#endif - - if (ioctl(PPfd, PPCLAIM)) { - error ("ioctl(%s, PPCLAIM) failed: %d %s", PPdev, errno, strerror(errno)); - return -1; - } - } else - + if (ioctl(PPfd, PPEXCL)) { + debug ("ioctl(%s, PPEXCL) failed: %s", PPdev, strerror(errno)); + } else { + debug ("ioctl(%s, PPEXCL) succeded."); + } #endif - { - debug ("using raw port 0x%x", Port); - if (ioperm(Port, 3, 1)!=0) { - error ("M50530: ioperm(0x%x) failed: %s", Port, strerror(errno)); - return -1; - } - } + if (ioctl(PPfd, PPCLAIM)) { + error ("ioctl(%s, PPCLAIM) failed: %d %s", PPdev, errno, strerror(errno)); + return -1; + } M5_command (0x00FA, 20); // set function mode M5_command (0x0020, 20); // set display mode @@ -423,7 +386,7 @@ int M5_clear (void) } } GPO=0; - M5_setGPO (GPO); // All GPO's off + M5_setGPO (GPO); // All GPO's off M5_command (0x0001, 1250); // clear display return 0; } @@ -433,33 +396,17 @@ int M5_init (LCD *Self) int rows=-1, cols=-1, gpos=-1; char *s, *e; - s=cfg_get ("Port"); - if (s==NULL || *s=='\0') { - error ("M50530: no 'Port' entry in %s", cfg_file()); - return -1; - } - PPdev=NULL; - if ((Port=strtol(s, &e, 0))==0 || *e!='\0') { -#ifdef WITH_PPDEV - Port=0; - PPdev=s; -#else - error ("M50530: bad port '%s' in %s", s, cfg_file()); - return -1; -#endif + if (PPdev) { + free (PPdev); + PPdev=NULL; } -#ifdef USE_OLD_UDELAY - s=cfg_get ("Delay"); + s=cfg_get ("Port"); if (s==NULL || *s=='\0') { - error ("M50530: no 'Delay' entry in %s", cfg_file()); + error ("M50530: no 'Port' entry in %s", cfg_file()); return -1; } - if ((loops_per_usec=strtol(s, &e, 0))==0 || *e!='\0') { - error ("M50530: bad delay '%s' in %s", s, cfg_file()); - return -1; - } -#endif + PPdev=strdup(s); s=cfg_get("Size"); if (s==NULL || *s=='\0') { @@ -485,9 +432,7 @@ int M5_init (LCD *Self) Self->gpos=gpos; Lcd=*Self; -#ifndef USE_OLD_UDELAY udelay_init(); -#endif if (M5_open()!=0) return -1; @@ -641,24 +586,13 @@ int M5_flush (void) int M5_quit (void) { -#ifdef WITH_PPDEV - if (PPdev) { - debug ("closing ppdev %s", PPdev); - if (ioctl(PPfd, PPRELEASE)) { - error ("ioctl(%s, PPRELEASE) failed: %s", PPdev, strerror(errno)); - } - if (close(PPfd)==-1) { - error ("close(%s) failed: %s", PPdev, strerror(errno)); - return -1; - } - } else -#endif - { - debug ("closing raw port 0x%x", Port); - if (ioperm(Port, 3, 0)!=0) { - error ("M50530: ioperm(0x%x) failed: %s", Port, strerror(errno)); - return -1; - } + debug ("closing ppdev %s", PPdev); + if (ioctl(PPfd, PPRELEASE)) { + error ("ioctl(%s, PPRELEASE) failed: %s", PPdev, strerror(errno)); + } + if (close(PPfd)==-1) { + error ("close(%s) failed: %s", PPdev, strerror(errno)); + return -1; } return 0; } |