From 72fd720c2d1a819d454771f99e86d852416e568e Mon Sep 17 00:00:00 2001 From: reinelt <> Date: Mon, 7 Apr 2003 06:03:10 +0000 Subject: [lcd4linux @ 2003-04-07 06:02:58 by reinelt] further parallel port abstraction --- HD44780.c | 32 +++++--- M50530.c | 23 ++++-- T6963.c | 259 +++++++++++++++++++++++------------------------------------- lcd4linux.c | 7 +- parport.c | 137 +++++++++++++++++++++++--------- parport.h | 8 +- 6 files changed, 245 insertions(+), 221 deletions(-) diff --git a/HD44780.c b/HD44780.c index ac17d8e..5367ac2 100644 --- a/HD44780.c +++ b/HD44780.c @@ -1,4 +1,4 @@ -/* $Id: HD44780.c,v 1.27 2003/04/04 06:01:59 reinelt Exp $ +/* $Id: HD44780.c,v 1.28 2003/04/07 06:02:58 reinelt Exp $ * * driver for display modules based on the HD44780 chip * @@ -20,6 +20,9 @@ * * * $Log: HD44780.c,v $ + * Revision 1.28 2003/04/07 06:02:58 reinelt + * further parallel port abstraction + * * Revision 1.27 2003/04/04 06:01:59 reinelt * new parallel port abstraction scheme * @@ -170,9 +173,10 @@ static LCD Lcd; static char Txt[4][40]; static int GPO=0; +static unsigned char SIGNAL_RW; static unsigned char SIGNAL_RS; static unsigned char SIGNAL_ENABLE; -static unsigned char SIGNAL_ENABLE_GPO; +static unsigned char SIGNAL_GPO; static void HD_command (unsigned char cmd, int delay) @@ -181,8 +185,8 @@ static void HD_command (unsigned char cmd, int delay) // put data on DB1..DB8 parport_data (cmd); - // clear RS - parport_control (SIGNAL_RS, 0); + // clear RW and RS + parport_control (SIGNAL_RW | SIGNAL_RS, 0); // Address set-up time ndelay(40); @@ -199,8 +203,8 @@ static void HD_command (unsigned char cmd, int delay) static void HD_write (char *string, int len, int delay) { - // set RS - parport_control (SIGNAL_RS, SIGNAL_RS); + // clear RW, set RS + parport_control (SIGNAL_RW | SIGNAL_RS, SIGNAL_RS); // Address set-up time ndelay(40); @@ -231,7 +235,7 @@ static void HD_setGPO (int bits) // send data // 74HCT573 enable pulse width = 24ns - parport_toggle (SIGNAL_ENABLE_GPO, 1, 230); + parport_toggle (SIGNAL_GPO, 1, 230); } } @@ -291,15 +295,23 @@ int HD_init (LCD *Self) Self->gpos=gpos; Lcd=*Self; - SIGNAL_RS=parport_wire ("RS", "AUTOFD"); - SIGNAL_ENABLE=parport_wire ("ENABLE", "STROBE"); - SIGNAL_ENABLE_GPO=parport_wire ("ENABLE_GPO", "INIT"); + 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; if (parport_open() != 0) { error ("HD44780: could not initialize parallel port!"); return -1; } + // clear RW + parport_control (SIGNAL_RW, 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 diff --git a/M50530.c b/M50530.c index afeb185..37ffe7c 100644 --- a/M50530.c +++ b/M50530.c @@ -1,4 +1,4 @@ -/* $Id: M50530.c,v 1.7 2003/04/04 06:01:59 reinelt Exp $ +/* $Id: M50530.c,v 1.8 2003/04/07 06:02:59 reinelt Exp $ * * driver for display modules based on the M50530 chip * @@ -20,6 +20,9 @@ * * * $Log: M50530.c,v $ + * Revision 1.8 2003/04/07 06:02:59 reinelt + * further parallel port abstraction + * * Revision 1.7 2003/04/04 06:01:59 reinelt * new parallel port abstraction scheme * @@ -79,7 +82,7 @@ static int GPO=0; static unsigned char SIGNAL_EX; static unsigned char SIGNAL_IOC1; static unsigned char SIGNAL_IOC2; -static unsigned char SIGNAL_ENABLE_GPO; +static unsigned char SIGNAL_GPO; static void M5_command (unsigned int cmd, int delay) { @@ -130,7 +133,7 @@ static void M5_setGPO (int bits) // send data // 74HCT573 enable pulse width = 24ns - parport_toggle (SIGNAL_ENABLE_GPO, 1, 24); + parport_toggle (SIGNAL_GPO, 1, 24); } } @@ -193,16 +196,20 @@ int M5_init (LCD *Self) Self->gpos=gpos; Lcd=*Self; - SIGNAL_EX=parport_wire ("EX", "STROBE"); - SIGNAL_EX=parport_wire ("IOC1", "SELECT"); - SIGNAL_EX=parport_wire ("IOC2", "AUTOFD"); - SIGNAL_EX=parport_wire ("ENABLE_GPO", "INIT"); - + 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 (parport_open() != 0) { error ("M50530: could not initialize parallel port!"); return -1; } + // set direction: write + parport_direction (0); + + // initialize display M5_command (0x00FA, 20); // set function mode M5_command (0x0020, 20); // set display mode M5_command (0x0050, 20); // set entry mode diff --git a/T6963.c b/T6963.c index 85aedbc..e7b7263 100644 --- a/T6963.c +++ b/T6963.c @@ -1,4 +1,4 @@ -/* $Id: T6963.c,v 1.5 2003/02/22 07:53:10 reinelt Exp $ +/* $Id: T6963.c,v 1.6 2003/04/07 06:03:00 reinelt Exp $ * * driver for display modules based on the Toshiba T6963 chip * @@ -20,6 +20,9 @@ * * * $Log: T6963.c,v $ + * Revision 1.6 2003/04/07 06:03:00 reinelt + * further parallel port abstraction + * * Revision 1.5 2003/02/22 07:53:10 reinelt * cfg_get(key,defval) * @@ -53,116 +56,82 @@ #include #include #include -#include -#include -#include #include -#include - -#if defined (HAVE_LINUX_PARPORT_H) && defined (HAVE_LINUX_PPDEV_H) -#define WITH_PPDEV -#include -#include -#else -#error The T6963 driver needs ppdev -#error cannot compile T6963 driver -#endif #include "debug.h" #include "cfg.h" #include "display.h" #include "bar.h" +#include "parport.h" #include "udelay.h" #include "pixmap.h" -/* - * /CE (Chip Enable) <==> /Strobe - * C/D (Command/Data) <==> /Select - * /RD (Read) <==> /AutoFeed - * /WR (Write) <==> Init - * - */ - -#define CE_L PARPORT_CONTROL_STROBE -#define CE_H 0 - -#define CD_L PARPORT_CONTROL_SELECT -#define CD_H 0 - -#define RD_L PARPORT_CONTROL_AUTOFD -#define RD_H 0 - -#define WR_L 0 -#define WR_H PARPORT_CONTROL_INIT - - #define XRES 6 #define YRES 8 static LCD Lcd; -static char *PPdev=NULL; -static int PPfd=-1; - unsigned char *Buffer1, *Buffer2; +static unsigned char SIGNAL_CE; +static unsigned char SIGNAL_CD; +static unsigned char SIGNAL_RD; +static unsigned char SIGNAL_WR; + + +// Fixme: +static int bug=0; + // perform normal status check void T6_status1 (void) { - int direction; int n; - unsigned char ctrl, data; - - // turn off data line drivers - direction=1; - ioctl (PPfd, PPDATADIR, &direction); - // lower RD and CE - ctrl = RD_L | WR_H | CE_L | CD_H; - ioctl (PPfd, PPWCONTROL, &ctrl); + // turn off data line drivers + parport_direction (1); - ndelay(150); // Access Time: 150 ns + // lower CE and RD + parport_control (SIGNAL_CE | SIGNAL_RD, 0); + // Access Time: 150 ns + ndelay(150); + // wait for STA0=1 and STA1=1 n=0; do { rep_nop(); if (++n>1000) { debug("hang in status1"); + bug=1; break; } - ioctl (PPfd, PPRDATA, &data); - } while ((data & 0x03) != 0x03); + } while ((parport_read() & 0x03) != 0x03); // rise RD and CE - ctrl = RD_H | WR_H | CE_H | CD_H; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_RD | SIGNAL_CE, SIGNAL_RD | SIGNAL_CE); - // turn on data line drivers - direction=0; - ioctl (PPfd, PPDATADIR, &direction); + // Output Hold Time: 50 ns + ndelay(50); + // turn on data line drivers + parport_direction (0); } -// Fixme: -static int bug=0; + // perform status check in "auto mode" void T6_status2 (void) { - int direction; int n; - unsigned char ctrl, data; // turn off data line drivers - direction=1; - ioctl (PPfd, PPDATADIR, &direction); - + parport_direction (1); + // lower RD and CE - ctrl = RD_L | WR_H | CE_L | CD_H; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_RD | SIGNAL_CE, 0); - ndelay(150); // Access Time: 150 ns + // Access Time: 150 ns + ndelay(150); // wait for STA3=1 n=0; @@ -173,114 +142,110 @@ void T6_status2 (void) bug=1; break; } - ioctl (PPfd, PPRDATA, &data); - } while ((data & 0x08) != 0x08); + } while ((parport_read() & 0x08) != 0x08); // rise RD and CE - ctrl = RD_H | WR_H | CE_H | CD_H; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_RD | SIGNAL_CE, SIGNAL_RD | SIGNAL_CE); + + // Output Hold Time: 50 ns + ndelay(50); // turn on data line drivers - direction=0; - ioctl (PPfd, PPDATADIR, &direction); + parport_direction (0); } static void T6_write_cmd (unsigned char cmd) { - unsigned char ctrl; - // wait until the T6963 is idle T6_status1(); // put data on DB1..DB8 - ioctl(PPfd, PPWDATA, &cmd); - + parport_data (cmd); + // lower WR and CE - ctrl = RD_H | WR_L | CE_L | CD_H; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_WR | SIGNAL_CE, 0); - ndelay(80); // Pulse width + // Pulse width + ndelay(80); // rise WR and CE - ctrl = RD_H | WR_H | CE_H | CD_H; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_WR | SIGNAL_CE, SIGNAL_WR | SIGNAL_CE); - ndelay(40); // Data Hold Time + // Data Hold Time + ndelay(40); } + static void T6_write_data (unsigned char data) { - unsigned char ctrl; - // wait until the T6963 is idle T6_status1(); // put data on DB1..DB8 - ioctl(PPfd, PPWDATA, &data); + parport_data (data); // lower C/D - ctrl = RD_H | WR_H | CE_H | CD_L; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_CD, 0); - ndelay(20); // C/D Setup Time + // C/D Setup Time + ndelay(20); // lower WR and CE - ctrl = RD_H | WR_L | CE_L | CD_L; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_WR | SIGNAL_CE, 0); - ndelay(80); // Pulse Width + // Pulse Width + ndelay(80); // rise WR and CE - ctrl = RD_H | WR_H | CE_H | CD_L; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_WR | SIGNAL_CE, SIGNAL_WR | SIGNAL_CE); - ndelay(40); // Data Hold Time + // Data Hold Time + ndelay(40); // rise CD - ctrl = RD_H | WR_H | CE_H | CD_H; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_CD, SIGNAL_CD); } + static void T6_write_auto (unsigned char data) { - unsigned char ctrl; - // wait until the T6963 is idle T6_status2(); // put data on DB1..DB8 - ioctl(PPfd, PPWDATA, &data); + parport_data (data); // lower C/D - ctrl = RD_H | WR_H | CE_H | CD_L; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_CD, 0); - ndelay(20); // C/D Setup Time + // C/D Setup Time + ndelay(20); // lower WR and CE - ctrl = RD_H | WR_L | CE_L | CD_L; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_WR | SIGNAL_CE, 0); - ndelay(80); // Pulse Width + // Pulse Width + ndelay(80); // rise WR and CE - ctrl = RD_H | WR_H | CE_H | CD_L; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_WR | SIGNAL_CE, SIGNAL_WR | SIGNAL_CE); - ndelay(40); // Data Hold Time + // Data Hold Time + ndelay(40); // rise CD - ctrl = RD_H | WR_H | CE_H | CD_H; - ioctl (PPfd, PPWCONTROL, &ctrl); + parport_control (SIGNAL_CD, SIGNAL_CD); } + static void T6_send_byte (unsigned char cmd, unsigned char data) { T6_write_data(data); T6_write_cmd(cmd); } + static void T6_send_word (unsigned char cmd, unsigned short data) { T6_write_data(data&0xff); @@ -288,6 +253,7 @@ static void T6_send_word (unsigned char cmd, unsigned short data) T6_write_cmd(cmd); } + static void T6_memset(unsigned short addr, unsigned char data, int len) { int i; @@ -324,40 +290,15 @@ static void T6_memcpy(unsigned short addr, unsigned char *data, int len) } -static int T6_open (void) -{ - 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; - } - - return 0; -} - int T6_clear (void) { int rows; rows=(Lcd.rows>8 ? 8 : Lcd.rows); - + T6_memset(0x0000, 0, Lcd.cols*rows); // clear text area T6_memset(0x0200, 0, Lcd.cols*rows*8); // clear graphic area - + if (Lcd.rows>8) { T6_memset(0x8000, 0, Lcd.cols*(Lcd.rows-rows)); // clear text area #2 T6_memset(0x8200, 0, Lcd.cols*(Lcd.rows-rows)*8); // clear graphic area #2 @@ -369,23 +310,10 @@ int T6_clear (void) return pix_clear(); } + int T6_init (LCD *Self) { - char *port; - Lcd=*Self; - - if (PPdev) { - free (PPdev); - PPdev=NULL; - } - - port=cfg_get ("Port",NULL); - if (port==NULL || *port=='\0') { - error ("T6963: no 'Port' entry in %s", cfg_file()); - return -1; - } - PPdev=strdup(port); if (pix_init (Lcd.rows, Lcd.cols, Lcd.xres, Lcd.yres)!=0) { error ("T6963: pix_init(%d, %d, %d, %d) failed", Lcd.rows, Lcd.cols, Lcd.xres, Lcd.yres); @@ -404,11 +332,23 @@ int T6_init (LCD *Self) return -1; } - udelay_init(); + 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 (T6_open()!=0) + if (parport_open() != 0) { + error ("HD44780: could not initialize parallel port!"); return -1; + } + + // rise CE, CD, RD and WR + parport_control (SIGNAL_CE | SIGNAL_CD | SIGNAL_RD | SIGNAL_WR, + SIGNAL_CE | SIGNAL_CD | SIGNAL_RD | SIGNAL_WR); + // set direction: write + parport_direction (0); + debug ("setting %d columns", Lcd.cols); T6_send_word (0x40, 0x0000); // Set Text Home Address @@ -428,16 +368,19 @@ int T6_init (LCD *Self) return 0; } + int T6_put (int row, int col, char *text) { return pix_put(row,col,text); } + int T6_bar (int type, int row, int col, int max, int len1, int len2) { return pix_bar(type,row,col,max,len1,len2); } + int T6_flush (void) { int i, j, e; @@ -470,19 +413,13 @@ int T6_flush (void) return 0; } + int T6_quit (void) { - 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; + return parport_close(); } + LCD T6963[] = { { name: "TLC1091", rows: 16, diff --git a/lcd4linux.c b/lcd4linux.c index 3afc6dd..fad7bd5 100644 --- a/lcd4linux.c +++ b/lcd4linux.c @@ -1,4 +1,4 @@ -/* $Id: lcd4linux.c,v 1.36 2003/02/22 07:53:10 reinelt Exp $ +/* $Id: lcd4linux.c,v 1.37 2003/04/07 06:03:01 reinelt Exp $ * * LCD4Linux * @@ -20,6 +20,9 @@ * * * $Log: lcd4linux.c,v $ + * Revision 1.37 2003/04/07 06:03:01 reinelt + * further parallel port abstraction + * * Revision 1.36 2003/02/22 07:53:10 reinelt * cfg_get(key,defval) * @@ -231,7 +234,7 @@ static void usage(void) int hello (void) { int i, x, y, flag; - char *line1[] = { "* LCD4Linux V" VERSION " *", + char *line1[] = { "* LCD4Linux " VERSION " *", "LCD4Linux " VERSION, "LCD4Linux", "L4Linux", diff --git a/parport.c b/parport.c index 6e7cbe4..2b22469 100644 --- a/parport.c +++ b/parport.c @@ -1,4 +1,4 @@ -/* $Id: parport.c,v 1.1 2003/04/04 06:02:03 reinelt Exp $ +/* $Id: parport.c,v 1.2 2003/04/07 06:03:05 reinelt Exp $ * * generic parallel port handling * @@ -20,6 +20,9 @@ * * * $Log: parport.c,v $ + * Revision 1.2 2003/04/07 06:03:05 reinelt + * further parallel port abstraction + * * Revision 1.1 2003/04/04 06:02:03 reinelt * new parallel port abstraction scheme * @@ -41,6 +44,10 @@ * reads wiring for one control signal from config * returns PARPORT_CONTROL_* or 255 on error * + * void parport_direction (int direction) + * 0 - write to parport + * 1 - read from parport + * * void parport_control (unsigned char mask, unsigned char value) * frobs control line and takes care of inverted signals * @@ -50,6 +57,11 @@ * void parport_data (unsigned char value) * put data bits on DB1..DB8 * + * unsigned char parport_read (void) + * reads a byte from the parallel port + * + * void parport_debug(void) + * prints status of control lines */ @@ -108,6 +120,7 @@ static unsigned char ctr = 0xc; static int PPfd=-1; #endif + int parport_open (void) { char *s, *e; @@ -172,9 +185,16 @@ int parport_open (void) { debug ("using raw port 0x%x", Port); - if (ioperm(Port, 3, 1)!=0) { - error ("parport: ioperm(0x%x) failed: %s", Port, strerror(errno)); - return -1; + if ((Port+3)<=0x3ff) { + if (ioperm(Port, 3, 1)!=0) { + error ("parport: ioperm(0x%x) failed: %s", Port, strerror(errno)); + return -1; + } + } else { + if (iopl(3)!=0) { + error ("parport: iopl(1) failed: %s", strerror(errno)); + return -1; + } } } return 0; @@ -197,9 +217,16 @@ int parport_close (void) #endif { debug ("closing raw port 0x%x", Port); - if (ioperm(Port, 3, 0)!=0) { - error ("parport: ioperm(0x%x) failed: %s", Port, strerror(errno)); - return -1; + if ((Port+3)<=0x3ff) { + if (ioperm(Port, 3, 0)!=0) { + error ("parport: ioperm(0x%x) failed: %s", Port, strerror(errno)); + return -1; + } + } else { + if (iopl(0)!=0) { + error ("parport: iopl(0) failed: %s", strerror(errno)); + return -1; + } } } return 0; @@ -211,7 +238,6 @@ unsigned char parport_wire (char *name, unsigned char *deflt) unsigned char w; char wire[256]; char *s; - int n; snprintf (wire, sizeof(wire), "Wire.%s", name); s=cfg_get (wire,deflt); @@ -223,52 +249,58 @@ unsigned char parport_wire (char *name, unsigned char *deflt) w=PARPORT_CONTROL_INIT; } else if(strcasecmp(s,"SELECT")==0) { w=PARPORT_CONTROL_SELECT; + } else if(strcasecmp(s,"GND")==0) { + w=0; } else { error ("parport: unknown signal <%s> for wire <%s>", s, name); - error (" should be STROBE, AUTOFD, INIT or SELECT"); - return 255; + error (" should be STROBE, AUTOFD, INIT, SELECT or GND"); + return 0xff; } - n=0; if (w&PARPORT_CONTROL_STROBE) { - n++; - info ("wiring: [DISPLAY:%s]==[PARPORT:STROBE]", name); + info ("wiring: [PARPORT:STROBE]==>[DISPLAY:%s]", name); } if (w&PARPORT_CONTROL_AUTOFD) { - n++; - info ("wiring: [DISPLAY:%s]==[PARPORT:AUTOFD]", name); + info ("wiring: [PARPORT:AUTOFD]==>[DISPLAY:%s]", name); } if (w&PARPORT_CONTROL_INIT) { - n++; - info ("wiring: [DISPLAY:%s]==[PARPORT:INIT]", name); + info ("wiring: [PARPORT:INIT]==>[DISPLAY:%s]", name); } if (w&PARPORT_CONTROL_SELECT) { - n++; - info ("wiring: [DISPLAY:%s]==[PARPORT:SELECT]", name); - } - if (n<1) { - error ("parport: no signal for wire <%s> found!", name); - return 255; + info ("wiring: [PARPORT:SELECT]==>[DISPLAY:%s]", name); } - if (n>1) { - error ("parport: more than one signal for wire <%s> found!", name); - return 255; + if (w==0) { + info ("wiring: [PARPORT:GND]==>[DISPLAY:%s]", name); } + return w; } -void parport_control (unsigned char mask, unsigned char value) +void parport_direction (int direction) { +#ifdef WITH_PPDEV + if (PPdev) { + ioctl (PPfd, PPDATADIR, &direction); + } else +#endif + { + // code stolen from linux/parport_pc.h + ctr = (ctr & ~0x20) ^ (direction?0x20:0x00); + outb (ctr, Port+2); + } +} - // sanity check - if (mask==0) { - error ("parport: internal error: control without signal called!"); - return; - } + +void parport_control (unsigned char mask, unsigned char value) +{ + // any signal affected? + // Note: this may happen in case a signal is hardwired to GND + if (mask==0) return; // Strobe, Select and AutoFeed are inverted! - value ^= PARPORT_CONTROL_STROBE|PARPORT_CONTROL_SELECT|PARPORT_CONTROL_AUTOFD; + value = mask & (value ^ (PARPORT_CONTROL_STROBE|PARPORT_CONTROL_SELECT|PARPORT_CONTROL_AUTOFD)); + // value ^= PARPORT_CONTROL_STROBE|PARPORT_CONTROL_SELECT|PARPORT_CONTROL_AUTOFD; #ifdef WITH_PPDEV if (PPdev) { @@ -289,13 +321,11 @@ void parport_control (unsigned char mask, unsigned char value) void parport_toggle (unsigned char bit, int level, int delay) { - // sanity check - if (bit==0) { - error ("parport: internal error: toggle without signal called!"); - return; - } + // any signal affected? + // Note: this may happen in case a signal is hardwired to GND + if (bit==0) return; - // Strobe, Select and AutoFeed are inverted! + // Strobe, Select and AutoFeed are inverted! if (bit & (PARPORT_CONTROL_STROBE|PARPORT_CONTROL_SELECT|PARPORT_CONTROL_AUTOFD)) { level=!level; } @@ -344,3 +374,32 @@ void parport_data (unsigned char data) } } +unsigned char parport_read (void) +{ + unsigned char data; + +#ifdef WITH_PPDEV + if (PPdev) { + ioctl (PPfd, PPRDATA, &data); + } else +#endif + { + data=inb (Port); + } + return data; +} + + +void parport_debug(void) +{ + unsigned char control; + + ioctl (PPfd, PPRCONTROL, &control); + + debug ("%cSTROBE %cAUTOFD %cINIT %cSELECT", + control & PARPORT_CONTROL_STROBE ? '-':'+', + control & PARPORT_CONTROL_AUTOFD ? '-':'+', + control & PARPORT_CONTROL_INIT ? '+':'-', + control & PARPORT_CONTROL_SELECT ? '-':'+'); + +} diff --git a/parport.h b/parport.h index c8170b2..a7e5d41 100644 --- a/parport.h +++ b/parport.h @@ -1,4 +1,4 @@ -/* $Id: parport.h,v 1.1 2003/04/04 06:02:03 reinelt Exp $ +/* $Id: parport.h,v 1.2 2003/04/07 06:03:10 reinelt Exp $ * * generic parallel port handling * @@ -20,6 +20,9 @@ * * * $Log: parport.h,v $ + * Revision 1.2 2003/04/07 06:03:10 reinelt + * further parallel port abstraction + * * Revision 1.1 2003/04/04 06:02:03 reinelt * new parallel port abstraction scheme * @@ -31,8 +34,11 @@ int parport_open (void); int parport_close (void); unsigned char parport_wire (char *name, char *deflt); +void parport_direction (int direction); void parport_control (unsigned char mask, unsigned char value); void parport_toggle (unsigned char bit, int level, int delay); void parport_data (unsigned char data); +unsigned char parport_read (void); +void parport_debug(void); #endif -- cgit v1.2.3