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); }