[PARPORT] Problems in negotiating ECP/EPP mode with libieee1284

From: Gora Mohanty (gora@solar2.ucr.edu)
Date: Thu Dec 19 2002 - 20:31:05 EST

  • Next message: Matthew Duggan: "Re: [PARPORT] Problems in negotiating ECP/EPP mode with libieee1284"

    Hello,
      I have been trying to get a parallel port EPP or ECP communication
    going between two computers for the last several days, and am getting
    increasingly frustrated. Here is a synopsis of what I have tried so
    far. Any help would be appreciated, as I am new to much of this. I
    would like to get data transfer rates of at least ~1MByte/s:
    1. Both computers are running 2.4.19, and parport, parport_pc, ppdev,
       and lp were compiled as modules, with CONFIG_PARPORT_1284 and
       CONFIG_PARPORT_FIFO set. As far as I can tell from the /proc files
       and syslog messages everything is OK. Interrupts are enabled, the
       IRQ and DMA seem to be set up correctly. I can get PLIP to work between
       the two, but data transfer using sockets over PPP transfers data only
       at about 40kBytes/s with a null-printer cable. Below, for the IEEE
       1284 modes, I use a Belkin IEEE-1284 compliant cable (I believe that
       this is what is called a "straight-through" cable).
    2. Hardware: both computers support TRISTATE and ECP, and I have also
       tried using two computers with parallel ports supporting EPP. I
       believe that the ports are bi-directional, and have checked by
       setting bit 5 on BASEPORT + 2, and verifying that an outb() followed
       by an inb() on BASEPORT gives different values.
    3. ppdev: I tried using the example programs to open /dev/parport0,
       negotiate and set mode, followed by standard read() and write() on
       the file descriptor, but that does not work. It is quite possible
       that I am missing something here, so if anyone has a complete example
       code it would be very helpful.
    4. libieee1284: this looked like it would be very useful, and after
       looking at some example code for scanners, I wrote up a short test
       program. However, this fails while negotiating either ECP or EPP
       mode on the parallel port. ieee1284_negotiate() returns E1284_SYS,
       and looking up errno gives "Input/output error." (Actually, according
       to the documentation, ieee1284_negotiate() should not even return
       E1284_SYS, so I am a little puzzled.) A bare bones example program,
       with minimal error checking, is appended. A more detailed program
       with a Makefile can be downloaded from
         http://coyote.ucr.edu/~gora/parport.html
    Thanks in advance for any help. If anyone has got such communication
    to work, I would be grateful for example code. Thanks also for all
    the work on the Linux parallel port.

    Regards,
    Gora
    --------------------------------------------------------------------------
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
    #include <signal.h>
    #include <ieee1284.h>

    #define NCHAR 10

    static ssize_t ieee_epp_writen(struct parport* port, const char* buf,
                                   size_t len)
    {
      size_t nleft = len;
      while( nleft > 0 )
        {
          ssize_t nwritten = ieee1284_epp_write_data( port, F1284_FASTEPP, buf,
                                                      len );
          if( nwritten <= 0 )
            return nwritten;

          nleft -= nwritten;
          buf += nwritten;
        }
      return len;
    }
    static ssize_t ieee_ecp_writen(struct parport* port, const char* buf,
                                   size_t len)
    {
      size_t nleft = len;
      while( nleft > 0 )
        {
          ssize_t nwritten = ieee1284_ecp_write_data( port, F1284_RLE, buf, len );
          if( nwritten <= 0 )
            return nwritten;

          nleft -= nwritten;
          buf += nwritten;
        }
      return len;
    }
    static ssize_t ieee_writen(struct parport* port, int mode, const char* buf,
                               size_t len)
    {
      ssize_t retval;
      switch( mode )
        {
        case M1284_EPP:
          retval = ieee_epp_writen( port, buf, len);
          break;

        case M1284_ECP:
        case M1284_BECP:
        case M1284_ECPRLE:
          retval = ieee_ecp_writen( port, buf, len);
          break;

        default:
          fprintf( stderr, "Write not supported for mode %d.\n" );
          retval = E1284_NOTAVAIL;
          break;
        }
      return retval;
    }
    static ssize_t ieee_epp_readn(struct parport* port, char* buf, size_t len)
    {
      size_t nleft = len;
      while( nleft > 0 )
        {
          ssize_t nread = ieee1284_epp_read_data( port, F1284_FASTEPP, buf, len );
          if( nread <= 0 )
            return nread;

          nleft -= nread;
          buf += nread;
        }
      return len;
    }
    static ssize_t ieee_ecp_readn(struct parport* port, char* buf, size_t len)
    {
      size_t nleft = len;
      while( nleft > 0 )
        {
          ssize_t nread = ieee1284_ecp_read_data( port, F1284_RLE, buf, len );
          if( nread <= 0 )
            return nread;

          nleft -= nread;
          buf += nread;
        }
      return len;
    }
    static ssize_t ieee_readn(struct parport* port, int mode, char* buf,
                              size_t len)
    {
      ssize_t retval;
      switch( mode )
        {
        case M1284_EPP:
          retval = ieee_epp_readn( port, buf, len);
          break;

        case M1284_ECP:
        case M1284_BECP:
        case M1284_ECPRLE:
          retval = ieee_ecp_readn( port, buf, len);
          break;

        default:
          fprintf( stderr, "Read not supported for mode %d.\n" );
          retval = E1284_NOTAVAIL;
          break;
        }
      return retval;
    }
    int main(int argc, char *argv[])
    {
     int ieee1284_mode = M1284_EPP; /* or, an ECP mode. */
     int retval, capability;
     struct parport* port;
     struct parport_list port_list;
     char buf[NCHAR];
     int i;
     for( i = 0; i < NCHAR; i++ )
       buf[i] = i + 5; /* Some semi-meaningful values. */

     /* Find available parallel ports. */
     if( (retval = ieee1284_find_ports( &port_list, 0 )) != E1284_OK )
       {
         fprintf( stderr, "Failed to find ports." );
         exit( EXIT_FAILURE );
       }

     /* Use the first port. */
     port = port_list.portv[0];
     fprintf( stdout,"Using parallel port \"%s\"\n", port->name );
     if( (retval = ieee1284_open( port, 0, &capability )) != E1284_OK )
       {
         fprintf( stderr, "Unable to open port \"%s\" at base address "
                  "(0x%02x).\n", port->name, (unsigned int) port->base_addr );
         exit( EXIT_FAILURE );
       }

     /* Claim port. */
     if( (retval = ieee1284_claim( port )) != E1284_OK )
       {
         fprintf( stderr, "Unable to claim port \"%s\" at base address "
                  "(0x%02x).\n", port->name, (unsigned int) port->base_addr );
         exit( EXIT_FAILURE );
       }

     /* Negotiate mode. */
     if( ieee1284_mode != M1284_COMPAT &&
         (retval = ieee1284_negotiate( port, ieee1284_mode )) != E1284_OK )
       {
         fprintf( stderr, "Failed to negotiate mode %d on port \"%s\" at base "
                  "address (0x%02x).\n", ieee1284_mode, port->name,
                  (unsigned int) port->base_addr );
         ieee1284_release( port );
         if( (retval = ieee1284_close( port )) != E1284_OK )
           fprintf( stderr, "Error in closing port \"%s\" at base address "
                    "(0x%02x).\n", port->name, (unsigned int) port->base_addr );
         ieee1284_free_ports( &port_list );
         exit( EXIT_FAILURE );
       }

     /* Write by default, or if first argument is 0. */
     if( argc == 1 || atoi( argv[1] ) == 0 )
       {
         if( (retval = ieee_writen( port, ieee1284_mode, buf, NCHAR )) !=
             E1284_OK )
           {
             fprintf( stderr, "Error in writing to port \"%s\" at base address "
                      "(0x%02x).\n", port->name,
                      (unsigned int) port->base_addr );
             exit( EXIT_FAILURE );
           }
       }
     else /* Read if first argument is non-zero. */
       {
         if( (retval = ieee_readn( port, ieee1284_mode, buf, NCHAR )) !=
             E1284_OK )
           {
             fprintf( stderr, "Error in reading from port \"%s\" at base address "
                      "(0x%02x).\n", port->name,
                      (unsigned int) port->base_addr );
             exit( EXIT_FAILURE );
           }
       }

     ieee1284_terminate( port );
     ieee1284_release( port );
     if( (retval = ieee1284_close( port )) != E1284_OK )
       fprintf( stderr, "Error in closing port \"%s\" at base address "
                "(0x%02x).\n", port->name, (unsigned int) port->base_addr );
     ieee1284_free_ports( &port_list );
     exit( EXIT_SUCCESS );
    }
    --------------------------------------------------------------------------

    -- 
    # Gora Mohanty                                  Phone: +1 (909) 787-3911    #
    # 1432 Geology Bldg.                            FAX:   +1 (909) 787-4509    #
    # IGPP, University of California                E-mail: gora@solar2.ucr.edu #
    # Riverside, CA 92521                            Office: 2158 Physics       #
    

    -- To unsubscribe, send mail to: linux-parport-request@torque.net -- -- with the single word "unsubscribe" in the body of the message. --



    This archive was generated by hypermail 2b29 : Thu Dec 19 2002 - 20:42:16 EST