]> git.webhop.me Git - lcd4linux.git/commitdiff
[lcd4linux @ 2003-04-07 06:02:58 by reinelt]
authorreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Mon, 7 Apr 2003 06:03:10 +0000 (06:03 +0000)
committerreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Mon, 7 Apr 2003 06:03:10 +0000 (06:03 +0000)
further parallel port abstraction

git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@188 3ae390bd-cb1e-0410-b409-cd5a39f66f1f

HD44780.c
M50530.c
T6963.c
lcd4linux.c
parport.c
parport.h

index ac17d8eb3837c302dde7dc24f78255412cb51b47..5367ac2c8a9a8079add36c511f26252fd990abbf 100644 (file)
--- 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
index afeb1851813310d34eb0ccd1cc0ba65b88adda23..37ffe7c3960dac2ca8ec51568031e9440de07955 100644 (file)
--- 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 85aedbc94c62ad3fdb160a770690fd2da3e2d1f4..e7b72631240e747bdad56486646fdfc2d4c0497b 100644 (file)
--- 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)
  *
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <time.h>
 #include <errno.h>
-#include <sys/ioctl.h>
-
-#if defined (HAVE_LINUX_PARPORT_H) && defined (HAVE_LINUX_PPDEV_H)
-#define WITH_PPDEV
-#include <linux/parport.h>
-#include <linux/ppdev.h>
-#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,
index 3afc6dd78c7ed1a439ed0feed793aada8bc382a1..fad7bd5212c1c880a67f96d734dc4cd89ea42eb2 100644 (file)
@@ -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",
index 6e7cbe4d306834a76e74d7d8cc55fdef99613db5..2b2246996ddebad3b94c855d65d556ae2af59f3b 100644 (file)
--- 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
  *
  *   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
  *
  * 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 ? '-':'+');
+  
+}
index c8170b2f56c18d4aa8481a68b41f3c0a8f79168e..a7e5d41484c7dab1be847735820acb12c5ffd7c0 100644 (file)
--- 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
  *
 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