]> git.webhop.me Git - lcd4linux.git/commitdiff
[lcd4linux @ 2003-04-04 06:01:59 by reinelt]
authorreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Fri, 4 Apr 2003 06:02:04 +0000 (06:02 +0000)
committerreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Fri, 4 Apr 2003 06:02:04 +0000 (06:02 +0000)
new parallel port abstraction scheme

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

HD44780.c
M50530.c
USBLCD.c
configure
configure.in
parport.c [new file with mode: 0644]
parport.h [new file with mode: 0644]
udelay.c

index e5e254ed5f78a967641da41b0aa04f345c4be86e..ac17d8eb3837c302dde7dc24f78255412cb51b47 100644 (file)
--- a/HD44780.c
+++ b/HD44780.c
@@ -1,4 +1,4 @@
-/* $Id: HD44780.c,v 1.26 2003/02/22 07:53:09 reinelt Exp $
+/* $Id: HD44780.c,v 1.27 2003/04/04 06:01:59 reinelt Exp $
  *
  * driver for display modules based on the HD44780 chip
  *
@@ -20,6 +20,9 @@
  *
  *
  * $Log: HD44780.c,v $
+ * Revision 1.27  2003/04/04 06:01:59  reinelt
+ * new parallel port abstraction scheme
+ *
  * Revision 1.26  2003/02/22 07:53:09  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>
-
-#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
-#error cannot compile HD44780 driver
-#endif
 
 #include "debug.h"
 #include "cfg.h"
 #include "display.h"
 #include "bar.h"
+#include "parport.h"
 #include "udelay.h"
 
 #define XRES 5
 
 static LCD Lcd;
 
-
-static unsigned short Port=0;
-
-static char *PPdev=NULL;
-
-#ifdef WITH_PPDEV
-static int PPfd=-1;
-#endif
-
 static char Txt[4][40];
 static int  GPO=0;
 
-#ifdef WITH_PPDEV
-static void HD_toggle (int bit, int inv, int delay)
-{
-  struct ppdev_frob_struct frob;
-  frob.mask=bit;
-
-  // rise
-  frob.val=inv?0:bit;
-  ioctl (PPfd, PPFCONTROL, &frob);
-  
-  // pulse width
-  ndelay(delay);      
+static unsigned char SIGNAL_RS;
+static unsigned char SIGNAL_ENABLE;
+static unsigned char SIGNAL_ENABLE_GPO;
 
-  // lower
-  frob.val=inv?bit:0;
-  ioctl (PPfd, PPFCONTROL, &frob);
-}
-#endif
 
 static void HD_command (unsigned char cmd, int delay)
 {
-#ifdef WITH_PPDEV
-  if (PPdev) {
-
-    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
+  parport_data (cmd);
+  
+  // clear RS
+  parport_control (SIGNAL_RS, 0);
     
-    // Address set-up time
-    ndelay(40);
+  // Address set-up time
+  ndelay(40);
 
-    // send command
-    // Enable cycle time = 230ns
-    HD_toggle(PARPORT_CONTROL_STROBE, 1, 230);
+  // send command
+  // Enable cycle time = 230ns
+  parport_toggle (SIGNAL_ENABLE, 1, 230);
     
-    // wait for command completion
-    udelay(delay);
-
-  } else
+  // wait for command completion
+  udelay(delay);
 
-#endif
-
-    {
-      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
-      ndelay(230);         // Enable cycle time
-      outb (0x03, Port+2); // clear Enable
-      udelay (delay);      // wait for command completion
-    }
 }
 
+
 static void HD_write (char *string, int len, int delay)
 {
-#ifdef WITH_PPDEV
-  if (PPdev) {
+  // set RS
+  parport_control (SIGNAL_RS, SIGNAL_RS);
 
-    struct ppdev_frob_struct frob;
-
-    // set RS (inverted)
-    frob.mask=PARPORT_CONTROL_AUTOFD;
-    frob.val=0;
-    ioctl (PPfd, PPFCONTROL, &frob);
+  // Address set-up time
+  ndelay(40);
+  
+  while (len--) {
     
-    // Address set-up time
-    ndelay(40);
+    // put data on DB1..DB8
+    parport_data (*(string++));
     
-    while (len--) {
-
-      // put data on DB1..DB8
-      ioctl(PPfd, PPWDATA, string++);
-      
-      // send command
-      HD_toggle(PARPORT_CONTROL_STROBE, 1, 230);
-
-      // wait for command completion
-      udelay(delay);
-    }
+    // send command
+    // Enable cycle time = 230ns
+    parport_toggle (SIGNAL_ENABLE, 1, 230);
     
-  } else
-
-#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
-       ndelay(230);            // Enable cycle time
-       outb (0x01, Port+2);    // clear Enable
-       udelay (delay);
-      }
-    }
+    // wait for command completion
+    udelay(delay);
+  }
 }
 
 static void HD_setGPO (int bits)
 {
   if (Lcd.gpos>0) {
-
-#ifdef WITH_PPDEV
-
-
-    if (PPdev) {
-      
-      // put data on DB1..DB8
-      ioctl(PPfd, PPWDATA, &bits);
-
-      // 74HCT573 set-up time
-      ndelay(20);
-      
-      // toggle INIT
-      // 74HCT573 enable pulse width = 24ns
-      HD_toggle(PARPORT_CONTROL_INIT, 0, 24);
-      
-    } else
-      
-#endif
-      
-      {
-       outb (bits, Port);    // put data on DB1..DB8
-       ndelay(20);           // 74HCT573 set-up time
-       outb (0x05, Port+2);  // set INIT = bit 2 invertet
-       ndelay(24);           // 74HCT573 enable pulse width
-       outb (0x03, Port+2);  // clear INIT
-      }
+    
+    // put data on DB1..DB8
+    parport_data (bits);
+    
+    // 74HCT573 set-up time
+    ndelay(20);
+    
+    // send data
+    // 74HCT573 enable pulse width = 24ns
+    parport_toggle (SIGNAL_ENABLE_GPO, 1, 230);
   }
 }
 
 
-static int HD_open (void)
-{
-#ifdef WITH_PPDEV
-
-  if (PPdev) {
-    debug ("using ppdev %s", PPdev);
-    PPfd=open(PPdev, O_RDWR);
-    if (PPfd==-1) {
-      error ("HD44780: 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 ("HD44780: ioctl(%s, PPCLAIM) failed: %d %s", PPdev, errno, strerror(errno));
-      return -1;
-    }
-  } else
-
-#endif
-
-    {
-      debug ("using raw port 0x%x", Port);
-      if (ioperm(Port, 3, 1)!=0) {
-       error ("HD44780: ioperm(0x%x) failed: %s", Port, strerror(errno));
-       return -1;
-      }
-    }
-  
-  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
-  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
-
-  return 0;
-}
-
-
 static void HD_define_char (int ascii, char *buffer)
 {
   HD_command (0x40|8*ascii, 40);
@@ -418,34 +267,6 @@ int HD_init (LCD *Self)
   int rows=-1, cols=-1, gpos=-1;
   char *s, *e;
   
-  s=cfg_get ("Port",NULL);
-  if (s==NULL || *s=='\0') {
-    error ("HD44780: 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 ("HD44780: bad port '%s' in %s", s, cfg_file());
-    return -1;
-#endif
-  }
-  
-#ifdef USE_OLD_UDELAY
-  s=cfg_get ("Delay",NULL);
-  if (s==NULL || *s=='\0') {
-    error ("HD44780: no 'Delay' entry in %s", cfg_file());
-    return -1;
-  }
-  if ((loops_per_usec=strtol(s, &e, 0))==0 || *e!='\0') {
-    error ("HD44780: bad delay '%s' in %s", s, cfg_file());
-    return -1;
-  }    
-#endif
-  
   s=cfg_get("Size",NULL);
   if (s==NULL || *s=='\0') {
     error ("HD44780: no 'Size' entry in %s", cfg_file());
@@ -470,13 +291,24 @@ int HD_init (LCD *Self)
   Self->gpos=gpos;
   Lcd=*Self;
   
-#ifndef USE_OLD_UDELAY
-  udelay_init();
-#endif
+  SIGNAL_RS=parport_wire ("RS", "AUTOFD");
+  SIGNAL_ENABLE=parport_wire ("ENABLE", "STROBE");
+  SIGNAL_ENABLE_GPO=parport_wire ("ENABLE_GPO", "INIT");
 
-  if (HD_open()!=0)
+  if (parport_open() != 0) {
+    error ("HD44780: could not initialize parallel port!");
     return -1;
-  
+  }
+
+  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
+  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
+
+
   bar_init(rows, cols, XRES, YRES, CHARS);
   bar_add_segment(  0,  0,255, 32); // ASCII  32 = blank
   bar_add_segment(255,255,255,255); // ASCII 255 = block
@@ -562,26 +394,7 @@ int HD_flush (void)
 
 int HD_quit (void)
 {
-#ifdef WITH_PPDEV
-  if (PPdev) {
-    debug ("closing ppdev %s", PPdev);
-    if (ioctl(PPfd, PPRELEASE)) {
-      error ("HD44780: ioctl(%s, PPRELEASE) failed: %s", PPdev, strerror(errno));
-    }
-    if (close(PPfd)==-1) {
-      error ("HD44780: 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 ("HD44780: ioperm(0x%x) failed: %s", Port, strerror(errno));
-      return -1;
-    }
-  }
-  return 0;
+  return parport_close();
 }
 
 
index ed64b320addeda4ac5a2e14b3ac006a50055026e..afeb1851813310d34eb0ccd1cc0ba65b88adda23 100644 (file)
--- a/M50530.c
+++ b/M50530.c
@@ -1,4 +1,4 @@
-/* $Id: M50530.c,v 1.6 2003/02/22 07:53:10 reinelt Exp $
+/* $Id: M50530.c,v 1.7 2003/04/04 06:01:59 reinelt Exp $
  *
  * driver for display modules based on the M50530 chip
  *
@@ -20,6 +20,9 @@
  *
  *
  * $Log: M50530.c,v $
+ * Revision 1.7  2003/04/04 06:01:59  reinelt
+ * new parallel port abstraction scheme
+ *
  * Revision 1.6  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 M50530 driver needs ppdev
-#error cannot compile M50530 driver
-#endif
 
 #include "debug.h"
 #include "cfg.h"
 #include "display.h"
 #include "bar.h"
+#include "parport.h"
 #include "udelay.h"
 
 #define XRES 5
 
 static LCD Lcd;
 
-
-static char *PPdev=NULL;
-static int   PPfd=-1;
-
 static char Txt[8][40];
 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 void M5_command (unsigned int cmd, int delay)
 {
-  unsigned char data;
-  struct ppdev_frob_struct frob;
     
   // put data on DB1..DB8
-  data=cmd&0xff;
-  ioctl(PPfd, PPWDATA, &data);
+  parport_data (cmd&0xff);
     
   // 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);
+  parport_control (SIGNAL_IOC1|SIGNAL_IOC2, 
+                  (cmd&0x200?SIGNAL_IOC1:0) | 
+                  (cmd&0x100?SIGNAL_IOC2:0));
 
   // Control data setup time
   ndelay(200);
 
-  // rise EX (Strobe, inverted)
-  frob.mask=PARPORT_CONTROL_STROBE;
-  frob.val=0;
-  ioctl (PPfd, PPFCONTROL, &frob);
-    
-  // EX signal pulse width
+  // send command
+  // EX signal pulse width = 500ns
   // Fixme: why 500 ns? Datasheet says 200ns
-  ndelay(500);
+  parport_toggle (SIGNAL_EX, 1, 500);
 
-  // lower EX (Strobe, inverted)
-  frob.mask=PARPORT_CONTROL_STROBE;
-  frob.val=PARPORT_CONTROL_STROBE;
-  ioctl (PPfd, PPFCONTROL, &frob);
-    
   // wait
   udelay(delay);
 
@@ -150,61 +122,19 @@ static void M5_setGPO (int bits)
 {
   if (Lcd.gpos>0) {
 
-    struct ppdev_frob_struct frob;
-  
     // put data on DB1..DB8
-    ioctl(PPfd, PPWDATA, &bits);
+    parport_data (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);
+    // send data
+    // 74HCT573 enable pulse width = 24ns
+    parport_toggle (SIGNAL_ENABLE_GPO, 1, 24);
   }
 }
 
 
-static int M5_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;
-  }
-
-  M5_command (0x00FA, 20); // set function mode
-  M5_command (0x0020, 20); // set display mode
-  M5_command (0x0050, 20); // set entry mode
-  M5_command (0x0030, 20); // set display mode
-  M5_command (0x0001, 1250); // clear display
-
-  return 0;
-}
-
-
 static void M5_define_char (int ascii, char *buffer)
 {
   M5_command (0x300+192+8*ascii, 20);
@@ -237,18 +167,6 @@ int M5_init (LCD *Self)
   int rows=-1, cols=-1, gpos=-1;
   char *s, *e;
   
-  if (PPdev) {
-    free (PPdev);
-    PPdev=NULL;
-  }
-  
-  s=cfg_get ("Port",NULL);
-  if (s==NULL || *s=='\0') {
-    error ("M50530: no 'Port' entry in %s", cfg_file());
-    return -1;
-  }
-  PPdev=strdup(s);
-  
   s=cfg_get("Size",NULL);
   if (s==NULL || *s=='\0') {
     error ("M50530: no 'Size' entry in %s", cfg_file());
@@ -275,14 +193,25 @@ int M5_init (LCD *Self)
   Self->gpos=gpos;
   Lcd=*Self;
   
-  udelay_init();
+  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 (M5_open()!=0)
+  if (parport_open() != 0) {
+    error ("M50530: could not initialize parallel port!");
     return -1;
+  }
+  
+  M5_command (0x00FA, 20); // set function mode
+  M5_command (0x0020, 20); // set display mode
+  M5_command (0x0050, 20); // set entry mode
+  M5_command (0x0030, 20); // set display mode
+  M5_command (0x0001, 1250); // clear display
   
   bar_init(rows, cols, XRES, YRES, CHARS);
   bar_add_segment(0,0,255,32); // ASCII 32 = blank
-
+  
   M5_clear();
   
   return 0;
@@ -366,15 +295,7 @@ int M5_flush (void)
 
 int M5_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();
 }
 
 
index 2cee0dfaf86963c66cafe7b945df7bb0d580f77c..a2479e9fab04a22130d31554458088ce2a49e8a1 100644 (file)
--- a/USBLCD.c
+++ b/USBLCD.c
@@ -1,4 +1,4 @@
-/* $Id: USBLCD.c,v 1.8 2003/02/22 07:53:10 reinelt Exp $
+/* $Id: USBLCD.c,v 1.9 2003/04/04 06:01:59 reinelt Exp $
  *
  * Driver for USBLCD ( see http://www.usblcd.de )
  * This Driver is based on HD44780.c
@@ -22,6 +22,9 @@
  *
  *
  * $Log: USBLCD.c,v $
+ * Revision 1.9  2003/04/04 06:01:59  reinelt
+ * new parallel port abstraction scheme
+ *
  * Revision 1.8  2003/02/22 07:53:10  reinelt
  * cfg_get(key,defval)
  *
@@ -79,7 +82,6 @@
 #include "cfg.h"
 #include "display.h"
 #include "bar.h"
-#include "udelay.h"
 
 #define GET_HARD_VERSION       1
 #define GET_DRV_VERSION                2
index 077ca9c55fb2220ac60272d8908d36d61c6ed2aa..5a21ab8922bf4ef2d631d079faa2855be1e83838 100755 (executable)
--- a/configure
+++ b/configure
@@ -4573,6 +4573,7 @@ echo "$as_me:$LINENO: result: done" >&5
 echo "${ECHO_T}done" >&6
 
 RASTER="no"
+PARPORT="no"
 
 if test "$BECKMANNEGLE" = "yes"; then
    DRIVERS="$DRIVERS BeckmannEgle.o"
@@ -4602,6 +4603,7 @@ _ACEOF
 fi
 
 if test "$HD44780" = "yes"; then
+   PARPORT="yes"
    DRIVERS="$DRIVERS HD44780.o"
 
 cat >>confdefs.h <<\_ACEOF
@@ -4611,6 +4613,7 @@ _ACEOF
 fi
 
 if test "$M50530" = "yes"; then
+   PARPORT="yes"
    DRIVERS="$DRIVERS M50530.o"
 
 cat >>confdefs.h <<\_ACEOF
@@ -4620,6 +4623,7 @@ _ACEOF
 fi
 
 if test "$T6963" = "yes"; then
+   PARPORT="yes"
    DRIVERS="$DRIVERS T6963.o"
 
 cat >>confdefs.h <<\_ACEOF
@@ -4724,16 +4728,20 @@ _ACEOF
    fi
 fi
 
+if test "$DRIVERS" = ""; then
+   { { echo "$as_me:$LINENO: error: You should include at least one driver..." >&5
+echo "$as_me: error: You should include at least one driver..." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
 # Raster.o depends on PPM or PNG
 if test "$RASTER" = "yes"; then
    DRIVERS="$DRIVERS Raster.o"
 fi
 
-
-if test "$DRIVERS" = ""; then
-   { { echo "$as_me:$LINENO: error: You should include at least one driver..." >&5
-echo "$as_me: error: You should include at least one driver..." >&2;}
-   { (exit 1); exit 1; }; }
+# parport driver
+if test "$PARPORT" = "yes"; then
+   DRIVERS="$DRIVERS parport.o"
 fi
 
 
index 3d052a4b0f91ef62945f56fc8479a5a66a31449e..8648538ea65c50d2bc598a2d0561761c41826d9e 100644 (file)
@@ -121,6 +121,7 @@ done
 AC_MSG_RESULT([done])
 
 RASTER="no"
+PARPORT="no"
 
 if test "$BECKMANNEGLE" = "yes"; then
    DRIVERS="$DRIVERS BeckmannEgle.o"
@@ -138,16 +139,19 @@ if test "$CWLINUX" = "yes"; then
 fi
 
 if test "$HD44780" = "yes"; then
+   PARPORT="yes"
    DRIVERS="$DRIVERS HD44780.o"
    AC_DEFINE(WITH_HD44780,1,[junk])
 fi
 
 if test "$M50530" = "yes"; then
+   PARPORT="yes"
    DRIVERS="$DRIVERS M50530.o"
    AC_DEFINE(WITH_M50530,1,[junk])
 fi
 
 if test "$T6963" = "yes"; then
+   PARPORT="yes"
    DRIVERS="$DRIVERS T6963.o"
    AC_DEFINE(WITH_T6963,1,[junk])
 fi
@@ -209,16 +213,20 @@ if test "$X11" = "yes"; then
    fi
 fi
 
+if test "$DRIVERS" = ""; then
+   AC_MSG_ERROR([You should include at least one driver...])
+fi
+   
 # Raster.o depends on PPM or PNG
 if test "$RASTER" = "yes"; then
    DRIVERS="$DRIVERS Raster.o"
 fi
 
-
-if test "$DRIVERS" = ""; then
-   AC_MSG_ERROR([You should include at least one driver...])
+# parport driver
+if test "$PARPORT" = "yes"; then
+   DRIVERS="$DRIVERS parport.o"
 fi
-   
+
 AC_SUBST(DRIVERS)
 AC_SUBST(DRVLIBS)
 
diff --git a/parport.c b/parport.c
new file mode 100644 (file)
index 0000000..6e7cbe4
--- /dev/null
+++ b/parport.c
@@ -0,0 +1,346 @@
+/* $Id: parport.c,v 1.1 2003/04/04 06:02:03 reinelt Exp $
+ *
+ * generic parallel port handling
+ *
+ * Copyright 2003 by Michael Reinelt (reinelt@eunet.at)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * $Log: parport.c,v $
+ * Revision 1.1  2003/04/04 06:02:03  reinelt
+ * new parallel port abstraction scheme
+ *
+ */
+
+/* 
+ * exported functions:
+ * 
+ * int parport_open (void)
+ *   reads 'Port' entry from config and opens
+ *   the parallel port
+ *   returns 0 if ok, -1 on failure
+ *
+ * int parport_close (void)
+ *   closes parallel port
+ *   returns 0 if ok, -1 on failure
+ *
+ * unsigned char parport_wire (char *name, char *deflt)
+ *   reads wiring for one control signal from config
+ *   returns PARPORT_CONTROL_* or 255 on error
+ *
+ * void parport_control (unsigned char mask, unsigned char value)
+ *   frobs control line and takes care of inverted signals
+ *
+ * void parport_toggle (unsigned char bit, int level, int delay)
+ *   toggles the line <bit> to <level> for <delay> nanoseconds
+ *
+ * void parport_data (unsigned char value)
+ *   put data bits on DB1..DB8
+ *
+ */
+
+
+#include "config.h"
+
+#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>
+
+
+#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>
+#else
+#define PARPORT_CONTROL_STROBE    0x1
+#define PARPORT_CONTROL_AUTOFD    0x2
+#define PARPORT_CONTROL_INIT      0x4
+#define PARPORT_CONTROL_SELECT    0x8
+#endif
+
+#if !defined(WITH_OUTB) && !defined(WITH_PPDEV)
+#error neither outb() nor ppdev() possible
+#error cannot compile parallel port driver
+#endif
+
+
+#include "debug.h"
+#include "cfg.h"
+#include "udelay.h"
+#include "parport.h"
+
+
+static unsigned short Port=0;
+static char *PPdev=NULL;
+
+// initial value taken from linux/parport_pc.c
+static unsigned char ctr = 0xc;
+
+#ifdef WITH_PPDEV
+static int PPfd=-1;
+#endif
+
+int parport_open (void)
+{
+  char *s, *e;
+
+#ifdef USE_OLD_UDELAY
+  s=cfg_get ("Delay",NULL);
+  if (s==NULL || *s=='\0') {
+    error ("parport: no 'Delay' entry in %s", cfg_file());
+    return -1;
+  }
+  if ((loops_per_usec=strtol(s, &e, 0))==0 || *e!='\0') {
+    error ("parport: bad delay '%s' in %s", s, cfg_file());
+    return -1;
+  }    
+#else
+  udelay_init();
+#endif
+  
+  s=cfg_get ("Port",NULL);
+  if (s==NULL || *s=='\0') {
+    error ("parport: 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 ("parport: bad Port '%s' in %s", s, cfg_file());
+    return -1;
+#endif
+  }
+  
+  
+#ifdef WITH_PPDEV
+  
+  if (PPdev) {
+    debug ("using ppdev %s", PPdev);
+    PPfd=open(PPdev, O_RDWR);
+    if (PPfd==-1) {
+      error ("parport: open(%s) failed: %s", PPdev, strerror(errno));
+      return -1;
+    }
+    
+#if 0
+    // Fixme
+    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 ("parport: ioctl(%s, PPCLAIM) failed: %d %s", PPdev, errno, strerror(errno));
+      return -1;
+    }
+  } else
+    
+#endif
+    
+    {
+      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;
+      }
+    }
+  return 0;
+}
+
+
+int parport_close (void)
+{
+#ifdef WITH_PPDEV
+  if (PPdev) {
+    debug ("closing ppdev %s", PPdev);
+    if (ioctl(PPfd, PPRELEASE)) {
+      error ("parport: ioctl(%s, PPRELEASE) failed: %s", PPdev, strerror(errno));
+    }
+    if (close(PPfd)==-1) {
+      error ("parport: 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 ("parport: ioperm(0x%x) failed: %s", Port, strerror(errno));
+       return -1;
+      }
+    }
+  return 0;
+}
+
+
+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);
+  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 {
+    error ("parport: unknown signal <%s> for wire <%s>", s, name);
+    error ("         should be STROBE, AUTOFD, INIT or SELECT");
+    return 255;
+  }
+  
+  n=0;
+  if (w&PARPORT_CONTROL_STROBE) {
+    n++;
+    info ("wiring: [DISPLAY:%s]==[PARPORT:STROBE]", name);
+  }
+  if (w&PARPORT_CONTROL_AUTOFD) {
+    n++;
+    info ("wiring: [DISPLAY:%s]==[PARPORT:AUTOFD]", name);
+  }
+  if (w&PARPORT_CONTROL_INIT) {
+    n++;
+    info ("wiring: [DISPLAY:%s]==[PARPORT:INIT]", 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;
+  }
+  if (n>1) {
+    error ("parport: more than one signal for wire <%s> found!", name);
+    return 255;
+  }
+  return w;
+}
+
+
+void parport_control (unsigned char mask, unsigned char value)
+{
+
+  // sanity check
+  if (mask==0) {
+    error ("parport: internal error: control without signal called!");
+    return;
+  }
+
+  // Strobe, Select and AutoFeed are inverted!
+  value ^= PARPORT_CONTROL_STROBE|PARPORT_CONTROL_SELECT|PARPORT_CONTROL_AUTOFD;
+
+#ifdef WITH_PPDEV
+  if (PPdev) {
+    struct ppdev_frob_struct frob;
+    frob.mask=mask;
+    frob.val=value;
+    ioctl (PPfd, PPFCONTROL, &frob);
+  } else
+#endif
+    {
+      // code stolen from linux/parport_pc.h
+      ctr = (ctr & ~mask) ^ value;
+      outb (ctr, Port+2);
+    }
+}
+
+
+void parport_toggle (unsigned char bit, int level, int delay)
+{
+
+  // sanity check
+  if (bit==0) {
+    error ("parport: internal error: toggle without signal called!");
+    return;
+  }
+
+   // Strobe, Select and AutoFeed are inverted!
+  if (bit & (PARPORT_CONTROL_STROBE|PARPORT_CONTROL_SELECT|PARPORT_CONTROL_AUTOFD)) {
+    level=!level;
+  }
+#ifdef WITH_PPDEV
+  if (PPdev) {
+    struct ppdev_frob_struct frob;
+    frob.mask=bit;
+    
+    // rise
+    frob.val=level?bit:0;
+    ioctl (PPfd, PPFCONTROL, &frob);
+    
+    // pulse width
+    ndelay(delay);      
+    
+    // lower
+    frob.val=level?0:bit;
+    ioctl (PPfd, PPFCONTROL, &frob);
+  } else
+#endif
+    {
+      // rise
+      ctr = (ctr & ~bit) ^ (level?bit:0);
+      outb (ctr, Port+2);
+
+      // pulse width
+      ndelay(delay);      
+      
+      // lower
+      ctr = (ctr & ~bit) ^ (level?0:bit);
+      outb (ctr, Port+2);
+    }
+}
+
+
+void parport_data (unsigned char data)
+{
+#ifdef WITH_PPDEV
+  if (PPdev) {
+    ioctl(PPfd, PPWDATA, &data);
+  } else
+#endif
+    {
+      outb (data, Port);
+    }
+}
+
diff --git a/parport.h b/parport.h
new file mode 100644 (file)
index 0000000..c8170b2
--- /dev/null
+++ b/parport.h
@@ -0,0 +1,38 @@
+/* $Id: parport.h,v 1.1 2003/04/04 06:02:03 reinelt Exp $
+ *
+ * generic parallel port handling
+ *
+ * Copyright 2003 by Michael Reinelt (reinelt@eunet.at)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * $Log: parport.h,v $
+ * Revision 1.1  2003/04/04 06:02:03  reinelt
+ * new parallel port abstraction scheme
+ *
+ */
+
+#ifndef _PARPORT_H_
+#define _PARPORT_H_
+
+int parport_open (void);
+int parport_close (void);
+unsigned char parport_wire (char *name, char *deflt);
+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);
+
+#endif
index 2ba21f38ed8600430f9f8439dbab0bd32f746002..c33c6836395280f733621b1db7c1f426e809a2ee 100644 (file)
--- a/udelay.c
+++ b/udelay.c
@@ -1,4 +1,4 @@
-/* $Id: udelay.c,v 1.10 2003/02/27 07:43:11 reinelt Exp $
+/* $Id: udelay.c,v 1.11 2003/04/04 06:02:04 reinelt Exp $
  *
  * short delays
  *
@@ -20,6 +20,9 @@
  *
  *
  * $Log: udelay.c,v $
+ * Revision 1.11  2003/04/04 06:02:04  reinelt
+ * new parallel port abstraction scheme
+ *
  * Revision 1.10  2003/02/27 07:43:11  reinelt
  *
  * asm/msr.h: included hard-coded definition of rdtscl() if msr.h cannot be found.
@@ -217,6 +220,7 @@ static void getCPUinfo (int *hasTSC, double *MHz)
 
 }
 
+
 void udelay_init (void)
 {
   int tsc;
@@ -233,6 +237,7 @@ void udelay_init (void)
   }
 }
 
+
 void ndelay (unsigned long nsec)
 {