[comp.sys.hp] GPIO interface

camiel@eutnv1.UUCP (Camiel Severijns) (11/23/89)

We have been building an interface to attach an HP9000/330 to a
bus developed in our department. Our interface is connected to
the 330 using a GPIO interface. For our application the device
driver written by HP is not very efficient. Therefore we would
like to map the GPIO interface in user space and use our own
driver. Does anyone know where we can find information on the
registers of the GPIO interface and how we can map it in user
space ?
Thanks in advance,

-- 
| Camiel Severijns
| Dept. of Physics, Eindhoven University of Technology
| Den Dolech 2, POBox 513, 5600 MB, Eindhoven, The Netherlands
| UUCP: eutnv1.uucp!camiel

hooft@finch.prl.philips.nl (Peter van Hooft) (11/24/89)

camiel@eutnv1.UUCP (Camiel Severijns) writes:
[ wants to know about accessing device registers ]

See iomap(7). 
As the address mentioned in iomap(7), use 60H+(your selectcode).

Example: 
  vme card, selectcode == 0x18, the card has an address space of 128kB:
  mknod vme_mapped c 10 0x007802

If you need more of a working example, email me.

You can find info about the registers of the GPIO card in the manual.
(surprise :-)). 

About this manual:
`HP 98622A GPIO Interface Installation'
Part No. 98622-90000

if (! this_helps()) 
 email_me();

peter

pej@hpfinote.HP.COM (Phil Jensen) (11/25/89)

> From camiel@eutnv1.UUCP Thu Nov 23 08:06:47 1989
> From: camiel@eutnv1.UUCP (Camiel Severijns)
> We have been building an interface to attach an HP9000/330 to a
> bus developed in our department. Our interface is connected to
> the 330 using a GPIO interface. For our application the device
> driver written by HP is not very efficient. Therefore we would
> like to map the GPIO interface in user space and use our own
> driver. Does anyone know where we can find information on the
> registers of the GPIO interface and how we can map it in user
> space ?
> Thanks in advance,

> -- 
> | Camiel Severijns
> | Dept. of Physics, Eindhoven University of Technology
> | Den Dolech 2, POBox 513, 5600 MB, Eindhoven, The Netherlands
> | UUCP: eutnv1.uucp!camiel

The following should help you use the gpio as a bus driver. You will have two
control lines ctl0 and ctl1 that can be used as a read/write line, a select
line or whatever works for your application. With some slight additions you
can use the two input lines as interupts or whatever. This is considerably 
faster than the dil library stuff but it also allows you some real good 
opportunities to hang up the system.  

Standard Disclaimer: This information is in no way official HP software and
is not supported in any way nor is this presented as an official HP
response (I just happen to work here). 
|---------------------------------------
| Phil Jensen 
| Hewlett-Packard Co.
| Colorado Integrated Circuit Division
| pej@hpfipej.HP.COM
|---------------------------------------

/**************************************************************************/
The following mknod command will create the necessary device file to perform 
memory mapped access to a DIO card at select code 12 (remember, you must be 
superuser). 
 
# mknod /dev/mappedio c 10 0x006c01
# ll /dev/mappedio
crw-rw-rw-   1 root     other     10 0x006c01 Jun  2 11:16 /dev/mappedio

Refer to section 1M of the reference manual for a generic description of mknod.
All memory mapped files must be character ("c") special files.  The major 
number (driver) must be (decimal) 10; the minor number is composed of two 
parts.  The upper four (hex) digits are the base address of the region to be 
mapped, divided by 0x10000 (i.e., shifted right 4 hex digits).  For a card at 
select code 12, the base address is

0x00600000 + (decimal 12 * 0x10000) = 0x006c0000.

The division yields the 4 hex digits 0x006c.  The lower two hex digits of the
minor number are the number of 64k (0x10000) byte blocks to be allocated; since
each IO card spans this much space, it should be set to one.  

/**************************************************************************/

The following will allow you to open a mapped device and read and write
16-bit values to/from it and then close it. It is the code that I used
(with some extractions) for an application similar to what you describe.

|----------------------Cut Here--------------------------------------|
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/iomap.h>

extern	int	errno;
static	char	*ioaddr;
static	int	eid;

/************************************************************************/
/* outputs the 16 bit value in dobus to the output bus of the gpio      */
/* the value in  ctl sets the values of the gpio control lines          */
/* addr is the iomapped address from qmapio				*/	
/************************************************************************/
output_data(dobus,addr,ctl)
   unsigned int dobus,ctl;
   char *addr;
{
   char dobuf[2];
   int iostat;

   /* psts must be high or this returns an error */
   if ((*(addr+7) & 8) == 0) {
      printw( "output_data: PSTS not OK! \n");
      return(-1);      
   }

   /* Wait for ready status .. this could probably use an alarm call 	*/
   /* in the event that the hardware hangs. 				*/
   /* This makes the assumption that the pctl and pflg lines are tied   */
   /* together. To implement a handshake, gate this connection.         */
   while ((*addr & 1) != 1)
   {}

   *(addr+7) = ctl & 0x03;
   *(addr+4) = ((dobus >> 8) & 0xff);
   *(addr+5) = dobus & 0xff;
   *(addr) = 0x1;
}
/************************************************************************/
input_data(addr,ctl)
   char *addr;
   unsigned int ctl;
{
   char dibuf[2];
   int iostat;

/* set ctl0 and 1 for output						*/
   *(addr+7) = ctl & 0x03;

/* wait for psts							*/
   while ((*addr & 1) != 1)
   {}

/* get data								*/
   iostat = *(addr+4) | *(addr+5);
   *addr = 0x1;
   while ((*addr & 1) != 1)
   {}
   iostat = ((*(addr+4) & 0xff) << 8) | (*(addr+5) & 0xff);
   return( iostat );
}
/****************************************************************************/
/* this maps the gpio to the io space. it returns the user address location */
/****************************************************************************/
char *qmapio()
{
   char *devfil = "/dev/mappedio";

   if ((eid = open(devfil,O_RDWR)) == -1) {
      fprintf(stderr,"\nError occurred.  Errno = %d",errno);
   }
   
   ioaddr = (char *) 0;
   if (ioctl(eid,IOMAPMAP,&ioaddr) < 0) {
      fprintf(stderr,"\nIOMAP failed Errno = %d\n",errno);
   }
   return(ioaddr);
}
/****************************************************************************/
/* unmaps the gpio							    */	
/****************************************************************************/
qunmapio()
{
   if (ioctl(eid,IOMAPUNMAP,&ioaddr) < 0) {
      fprintf(stderr,"IOUNMAP failed\n");
      return(1);
   }
   close(eid);
}