From: Frank Sergeant
Subject: direct parallel port access from Lisp (x86, Linux, CLISP or CMUCL)
Date: 
Message-ID: <87acylr1on.fsf@bed.utoh.org>
I am accessing a relay board attached to a Linux x86 box using CLISP.
The relay board has 8 relays.  Each relay is controlled by one of the 8
data bits on the parallel port.

Lisp calls a small executable (named 'simpleparport', written in C).
For example, to turn 4 relays on and 4 off:

   (shell (format nil "./simpleparport ~D ~D" #x378  #xA5))

To to turn on the bit0 relay and then off again:

   (shell (format nil "./simpleparport ~D ~D" #x378  1))
   (shell (format nil "./simpleparport ~D ~D" #x378  0))

I wonder if I am doing it the hard way.  Is there an easier way to do it
directly from Lisp?  (Especially CMUCL or CLISP)

Below is the C program (stripped of error handling) in case there isn't
an easier way, in case it's useful to anyone.  The executable needs to
run as root in order to set io permissions.  The Linux
IO-Port-Programming HOWTO provided the key information.  Apparently, the
optimision level ('-O2') is important.  The resulting executable can be
run directly from the command line, or called from CLISP with EXECUTE or
SHELL.  The arguments must be in decimal for this simple version of the
program. 

    ------- simpleparport.c -------

/* Compile with `gcc -O2 -o simpleparport simpleparport.c' */

#include <stdio.h>
#include <unistd.h>
#include <asm/io.h>

int main (int argc, char *argv[]) {
    int ioaddress, value;
    sscanf (argv[1], "%d", &ioaddress);
    sscanf (argv[2], "%d", &value);
    if (ioperm (ioaddress, 3, 1)) {
       perror ("ioperm"); 
       exit (1);
    }
    outb (value, ioaddress);
    exit (0);
}

-- 
Frank

From: Andreas Hinze
Subject: Re: direct parallel port access from Lisp (x86, Linux, CLISP or CMUCL)
Date: 
Message-ID: <cbu6pd$cl9$1@news.eusc.inter.net>
"Frank Sergeant" <·····@pygmy.utoh.org> schrieb im Newsbeitrag ···················@bed.utoh.org...
> I am accessing a relay board attached to a Linux x86 box using CLISP.
> The relay board has 8 relays.  Each relay is controlled by one of the 8
> data bits on the parallel port.
>

[snip]

> I wonder if I am doing it the hard way.  Is there an easier way to do it
> directly from Lisp?  (Especially CMUCL or CLISP)
>

> Below is the C program (stripped of error handling) in case there isn't
> an easier way, in case it's useful to anyone.  The executable needs to
> run as root in order to set io permissions.  The Linux
> IO-Port-Programming HOWTO provided the key information.  Apparently, the
> optimision level ('-O2') is important.

Hi Frank

The optimation level is important due to the outb() function. Refer to the outb man
page and to the io.h file for more details.
However, both CLisp & CMUCL provide a foreign function interface (FFI) that allows you to
access foreign object files and system libraries. You will find usefull information in their manuals
(i.e. implnotes.html for CLisp).
The main problem again is the outb function which is not a "real" function. It is expanded to
an inline assembler call by the C compiler (thats why you need the -O). That simple means that
there is no function _outb in the libc.so that you can call from lisp.
If you want to make it callable you need to write a kind of wrapper, compile it to an .o file and
load the .o into your lisp image via FFI.
(Another way is to use the /dev/lp device to write the command byte to the printer port. But i
have never tried this).

Hope that helps
AHz
From: Frank Sergeant
Subject: Re: direct parallel port access from Lisp (x86, Linux, CLISP or CMUCL)
Date: 
Message-ID: <873c4botik.fsf@bed.utoh.org>
"Andreas Hinze" <···@snafu.de> writes:

> > I am accessing a relay board attached to a Linux x86 box using
> > CLISP.  
  [by calling an external program with SHELL or EXECUTE to access the
   parallel port]

Thanks for the details about outb() and the suggestions about FFI, etc.

> (Another way is to use the /dev/lp device to write the command byte to
> the printer port. But i have never tried this).

My attempts at that have failed so far but I might try again.

Meanwhile, calling the external program is working well, so I'll
probably consider that the "easy way" for now.


-- 
Frank
From: nabla
Subject: Re: direct parallel port access from Lisp (x86, Linux, CLISP or CMUCL)
Date: 
Message-ID: <cc3ie8$30b$1@www.abg.com.pl>
Frank Sergeant wrote:

> I am accessing a relay board attached to a Linux x86 box using CLISP.
> The relay board has 8 relays.  Each relay is controlled by one of the 8
> data bits on the parallel port.


You should use /dev/parport device. See 7.3 section from 
http://www.kernelnewbies.org/documents/kdoc/parportbook.pdf.

Direct IO access from userland it's not the *nix way.

-- 
Pozdrawiam,
Rafal Strzalinski (nabla)
http://nablaone.blogspot.com/
From: Rob Warnock
Subject: Re: direct parallel port access from Lisp (x86, Linux, CLISP or CMUCL)
Date: 
Message-ID: <IOedndMVxoEpjXvd4p2dnA@speakeasy.net>
nabla  <···············@o2.pl> wrote:
+---------------
| Frank Sergeant wrote:
| > I am accessing a relay board attached to a Linux x86 box using CLISP.
| > The relay board has 8 relays.  Each relay is controlled by one of the 8
| > data bits on the parallel port.
| 
| You should use /dev/parport device. See 7.3 section from 
| http://www.kernelnewbies.org/documents/kdoc/parportbook.pdf.
+---------------

Or for FreeBSD, /dev/ppi{N}, the user-space interface to the ppbus
parallel 'geek' port, may be more convenient and/or flexible. From
"man 4 ppi":

    The ppi driver provides a convenient means for user applications
    to manipulate the state of the parallel port, enabling easy
    low-speed I/O operations without the security problems inherent
    with the use of the /dev/io interface.

However, if that's not good enough, /dev/io is always an option.

+---------------
| Direct IO access from userland it's not the *nix way.
+---------------

I beg to differ!! I have been doing direct I/O access from user mode
under various flavors of Unix since 1981! ...and from within Scheme
or Common Lisp under Unix since 1992 -- including doing DMA to/from
(pinned) user pages. It can be a *very* effective way to do hardware
debugging and/or driver development.


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607