Further elaborate the GPIB driver. We now support a minimal subset of
the ibfoo() API.
This commit is contained in:
parent
d61902a5b4
commit
df05d0fb93
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=141398
@ -538,6 +538,7 @@ dev/ida/ida_pci.c optional ida pci
|
||||
dev/ie/if_ie.c optional ie isa nowerror
|
||||
dev/ie/if_ie_isa.c optional ie isa
|
||||
dev/ieee488/pcii.c optional pcii
|
||||
dev/ieee488/upd7210.c optional pcii
|
||||
dev/iicbus/if_ic.c optional ic
|
||||
dev/iicbus/iic.c optional iic
|
||||
dev/iicbus/iicbb.c optional iicbb
|
||||
|
147
sys/dev/ieee488/ibfoo_int.h
Normal file
147
sys/dev/ieee488/ibfoo_int.h
Normal file
@ -0,0 +1,147 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Poul-Henning Kamp
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file defines the ABI between the userland gpib library and the
|
||||
* kernel. This file should not be used anywhere else.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
typedef void ibsrq_t(void);
|
||||
enum ibfoo_id {
|
||||
__ID_INVALID = 0,
|
||||
__ID_IBASK,
|
||||
__ID_IBBNA,
|
||||
__ID_IBCAC,
|
||||
__ID_IBCLR,
|
||||
__ID_IBCMD,
|
||||
__ID_IBCMDA,
|
||||
__ID_IBCONFIG,
|
||||
__ID_IBDEV,
|
||||
__ID_IBDIAG,
|
||||
__ID_IBDMA,
|
||||
__ID_IBEOS,
|
||||
__ID_IBEOT,
|
||||
__ID_IBEVENT,
|
||||
__ID_IBFIND,
|
||||
__ID_IBGTS,
|
||||
__ID_IBIST,
|
||||
__ID_IBLINES,
|
||||
__ID_IBLLO,
|
||||
__ID_IBLN,
|
||||
__ID_IBLOC,
|
||||
__ID_IBONL,
|
||||
__ID_IBPAD,
|
||||
__ID_IBPCT,
|
||||
__ID_IBPOKE,
|
||||
__ID_IBPPC,
|
||||
__ID_IBRD,
|
||||
__ID_IBRDA,
|
||||
__ID_IBRDF,
|
||||
__ID_IBRDKEY,
|
||||
__ID_IBRPP,
|
||||
__ID_IBRSC,
|
||||
__ID_IBRSP,
|
||||
__ID_IBRSV,
|
||||
__ID_IBSAD,
|
||||
__ID_IBSGNL,
|
||||
__ID_IBSIC,
|
||||
__ID_IBSRE,
|
||||
__ID_IBSRQ,
|
||||
__ID_IBSTOP,
|
||||
__ID_IBTMO,
|
||||
__ID_IBTRAP,
|
||||
__ID_IBTRG,
|
||||
__ID_IBWAIT,
|
||||
__ID_IBWRT,
|
||||
__ID_IBWRTA,
|
||||
__ID_IBWRTF,
|
||||
__ID_IBWRTKEY,
|
||||
__ID_IBXTRC
|
||||
};
|
||||
|
||||
#define __F_HANDLE (1 << 0)
|
||||
#define __F_SPR (1 << 1)
|
||||
#define __F_BUFFER (1 << 2)
|
||||
#define __F_RETVAL (1 << 3)
|
||||
#define __F_BDNAME (1 << 4)
|
||||
#define __F_MASK (1 << 5)
|
||||
#define __F_PADVAL (1 << 6)
|
||||
#define __F_SADVAL (1 << 7)
|
||||
#define __F_CNT (1 << 8)
|
||||
#define __F_TMO (1 << 9)
|
||||
#define __F_EOS (1 << 10)
|
||||
#define __F_PPR (1 << 11)
|
||||
#define __F_EOT (1 << 12)
|
||||
#define __F_V (1 << 13)
|
||||
#define __F_VALUE (1 << 14)
|
||||
#define __F_SAD (1 << 15)
|
||||
#define __F_BOARDID (1 << 16)
|
||||
#define __F_OPTION (1 << 17)
|
||||
#define __F_FLNAME (1 << 18)
|
||||
#define __F_FUNC (1 << 19)
|
||||
#define __F_LINES (1 << 20)
|
||||
#define __F_PAD (1 << 21)
|
||||
#define __F_MODE (1 << 22)
|
||||
#define __F_LISTENFLAG (1 << 23)
|
||||
#define __F_EVENT (1 << 24)
|
||||
|
||||
struct ibfoo_iocarg {
|
||||
enum ibfoo_id __ident;
|
||||
unsigned int __field;
|
||||
int __retval;
|
||||
int __ibsts;
|
||||
int __iberr;
|
||||
int __ibcnt;
|
||||
int handle;
|
||||
char * spr;
|
||||
void * buffer;
|
||||
int * retval;
|
||||
char * bdname;
|
||||
int mask;
|
||||
int padval;
|
||||
int sadval;
|
||||
long cnt;
|
||||
int tmo;
|
||||
int eos;
|
||||
char * ppr;
|
||||
int eot;
|
||||
int v;
|
||||
int value;
|
||||
int sad;
|
||||
int boardID;
|
||||
int option;
|
||||
char * flname;
|
||||
ibsrq_t * func;
|
||||
short * lines;
|
||||
int pad;
|
||||
int mode;
|
||||
short * listenflag;
|
||||
short * event;
|
||||
};
|
||||
|
||||
#define GPIB_IBFOO _IOWR(4, 0, struct ibfoo_iocarg)
|
@ -6,22 +6,27 @@
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer as
|
||||
* the first lines of this file unmodified.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Driver for GPIB cards based on NEC µPD7210 and compatibles.
|
||||
*
|
||||
* This driver just hooks up to the hardware and leaves all the interesting
|
||||
* stuff to upd7210.c.
|
||||
*
|
||||
* Supported hardware:
|
||||
* PCIIA compatible cards.
|
||||
@ -29,13 +34,6 @@
|
||||
* Tested and known working:
|
||||
* "B&C Microsystems PC488A-0"
|
||||
*
|
||||
* A whole lot of wonderful things could be written for GPIB, but for now
|
||||
* I have just written it such that it is possible to capture data in the
|
||||
* mode known as "unaddressed listen only mode". This is what many plotters
|
||||
* and printers do on GPIB. This is enough to capture some output from
|
||||
* various test instruments.
|
||||
*
|
||||
* If you are interested in working on this, send me email.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
@ -43,53 +41,27 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/uio.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/rman.h>
|
||||
#include <isa/isavar.h>
|
||||
|
||||
/* ---> upd7210.h at some point. */
|
||||
|
||||
struct upd7210 {
|
||||
bus_space_handle_t reg_handle[8];
|
||||
bus_space_tag_t reg_tag[8];
|
||||
u_int reg_offset[8];
|
||||
|
||||
/* private stuff */
|
||||
struct mtx mutex;
|
||||
uint8_t rreg[8];
|
||||
uint8_t wreg[8];
|
||||
|
||||
int busy;
|
||||
u_char *buf;
|
||||
size_t bufsize;
|
||||
u_int buf_wp;
|
||||
u_int buf_rp;
|
||||
struct cdev *cdev;
|
||||
};
|
||||
|
||||
static void upd7210intr(void *);
|
||||
static void upd7210attach(struct upd7210 *);
|
||||
|
||||
|
||||
/* ----> pcii.c */
|
||||
#include <dev/ieee488/upd7210.h>
|
||||
|
||||
struct pcii_softc {
|
||||
int foo;
|
||||
struct resource *port[8];
|
||||
struct resource *irq;
|
||||
struct resource *dma;
|
||||
void *intr_handler;
|
||||
struct upd7210 upd7210;
|
||||
};
|
||||
|
||||
#define HERE() printf("pcii HERE %s:%d\n", __FILE__, __LINE__)
|
||||
|
||||
static devclass_t pcii_devclass;
|
||||
|
||||
static int pcii_probe(device_t dev);
|
||||
@ -190,8 +162,16 @@ pcii_attach(device_t dev)
|
||||
upd7210intr, &sc->upd7210, &sc->intr_handler);
|
||||
}
|
||||
}
|
||||
if (!error) {
|
||||
rid = 0;
|
||||
sc->dma = bus_alloc_resource_any(dev,
|
||||
SYS_RES_DRQ, &rid, RF_ACTIVE | RF_SHAREABLE);
|
||||
if (sc->dma == NULL)
|
||||
sc->upd7210.dmachan = -1;
|
||||
else
|
||||
sc->upd7210.dmachan = rman_get_start(sc->dma);
|
||||
}
|
||||
if (error) {
|
||||
device_printf(dev, "error = %d\n", error);
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (sc->port[i] == NULL)
|
||||
break;
|
||||
@ -209,215 +189,3 @@ device_printf(dev, "error = %d\n", error);
|
||||
|
||||
DRIVER_MODULE(pcii, isa, pcii_driver, pcii_devclass, 0, 0);
|
||||
DRIVER_MODULE(pcii, acpi, pcii_driver, pcii_devclass, 0, 0);
|
||||
|
||||
/* ---> upd7210.c at some point */
|
||||
|
||||
enum upd7210_wreg {
|
||||
CDOR = 0, /* Command/data out */
|
||||
IMR1 = 1, /* Interrupt mask 1 */
|
||||
IMR2 = 2, /* Interrupt mask 2 */
|
||||
SPMR = 3, /* Serial poll mode */
|
||||
ADMR = 4, /* Address mode */
|
||||
AUXMR = 5, /* Auxilliary mode */
|
||||
ADR = 6, /* Address */
|
||||
EOSR = 7, /* End-of-string */
|
||||
};
|
||||
|
||||
enum upd7210_rreg {
|
||||
DIR = 0, /* Data in */
|
||||
ISR1 = 1, /* Interrupt status 1 */
|
||||
ISR2 = 2, /* Interrupt status 2 */
|
||||
SPSR = 3, /* Serial poll status */
|
||||
ADSR = 4, /* Address status */
|
||||
CPTR = 5, /* Command pass though */
|
||||
ADR0 = 6, /* Address 1 */
|
||||
ADR1 = 7, /* Address 2 */
|
||||
};
|
||||
|
||||
#define AUXMR_PON 0x00
|
||||
#define AUXMR_CRST 0x02
|
||||
#define AUXMR_RFD 0x03
|
||||
#define AUXMR_SEOI 0x06
|
||||
#define AUXMR_GTS 0x10
|
||||
#define AUXMR_TCA 0x11
|
||||
#define AUXMR_TCS 0x12
|
||||
#define AUXMR_TCSE 0x1a
|
||||
#define AUXMR_DSC 0x14
|
||||
#define AUXMR_CIFC 0x16
|
||||
#define AUXMR_SIFC 0x1e
|
||||
#define AUXMR_CREN 0x17
|
||||
#define AUXMR_SREN 0x1f
|
||||
#define AUXMR_ICTR 0x20
|
||||
#define AUXMR_PPR 0x60
|
||||
#define AUXMR_RA 0x80
|
||||
#define AUXMR_RB 0xa0
|
||||
#define AUXMR_RE 0xc0
|
||||
|
||||
|
||||
/* upd7210 generic stuff */
|
||||
|
||||
static u_int
|
||||
read_reg(struct upd7210 *u, enum upd7210_rreg reg)
|
||||
{
|
||||
u_int r;
|
||||
|
||||
r = bus_space_read_1(
|
||||
u->reg_tag[reg],
|
||||
u->reg_handle[reg],
|
||||
u->reg_offset[reg]);
|
||||
u->rreg[reg] = r;
|
||||
return (r);
|
||||
}
|
||||
|
||||
static void
|
||||
write_reg(struct upd7210 *u, enum upd7210_wreg reg, u_int val)
|
||||
{
|
||||
bus_space_write_1(
|
||||
u->reg_tag[reg],
|
||||
u->reg_handle[reg],
|
||||
u->reg_offset[reg], val);
|
||||
u->wreg[reg] = val;
|
||||
}
|
||||
|
||||
static void
|
||||
upd7210intr(void *arg)
|
||||
{
|
||||
int i;
|
||||
u_int isr1, isr2;
|
||||
struct upd7210 *u;
|
||||
|
||||
u = arg;
|
||||
mtx_lock(&u->mutex);
|
||||
isr1 = read_reg(u, ISR1);
|
||||
isr2 = read_reg(u, ISR2);
|
||||
if (isr1 & 1) {
|
||||
i = read_reg(u, DIR);
|
||||
u->buf[u->buf_wp++] = i;
|
||||
u->buf_wp &= (u->bufsize - 1);
|
||||
i = (u->buf_rp + u->bufsize - u->buf_wp) & (u->bufsize - 1);
|
||||
if (i < 8)
|
||||
write_reg(u, IMR1, 0);
|
||||
wakeup(u->buf);
|
||||
} else {
|
||||
printf("upd7210intr [%02x %02x %02x",
|
||||
read_reg(u, DIR), isr1, isr2);
|
||||
printf(" %02x %02x %02x %02x %02x]\n",
|
||||
read_reg(u, SPSR),
|
||||
read_reg(u, ADSR),
|
||||
read_reg(u, CPTR),
|
||||
read_reg(u, ADR0),
|
||||
read_reg(u, ADR1));
|
||||
}
|
||||
mtx_unlock(&u->mutex);
|
||||
}
|
||||
|
||||
static int
|
||||
gpib_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
|
||||
{
|
||||
struct upd7210 *u;
|
||||
|
||||
u = dev->si_drv1;
|
||||
|
||||
mtx_lock(&u->mutex);
|
||||
if (u->busy)
|
||||
return (EBUSY);
|
||||
u->busy = 1;
|
||||
mtx_unlock(&u->mutex);
|
||||
|
||||
u->buf = malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK);
|
||||
u->bufsize = PAGE_SIZE;
|
||||
u->buf_wp = 0;
|
||||
u->buf_rp = 0;
|
||||
|
||||
write_reg(u, AUXMR, AUXMR_CRST);
|
||||
DELAY(10000);
|
||||
write_reg(u, AUXMR, AUXMR_ICTR | 8);
|
||||
DELAY(1000);
|
||||
write_reg(u, ADR, 0x60);
|
||||
write_reg(u, ADR, 0xe0);
|
||||
write_reg(u, ADMR, 0x70);
|
||||
write_reg(u, AUXMR, AUXMR_PON);
|
||||
write_reg(u, IMR1, 0x01);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
gpib_close(struct cdev *dev, int oflags, int devtype, struct thread *td)
|
||||
{
|
||||
struct upd7210 *u;
|
||||
|
||||
u = dev->si_drv1;
|
||||
|
||||
mtx_lock(&u->mutex);
|
||||
u->busy = 0;
|
||||
write_reg(u, AUXMR, AUXMR_CRST);
|
||||
DELAY(10000);
|
||||
write_reg(u, IMR1, 0x00);
|
||||
write_reg(u, IMR2, 0x00);
|
||||
free(u->buf, M_DEVBUF);
|
||||
u->buf = NULL;
|
||||
mtx_unlock(&u->mutex);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
gpib_read(struct cdev *dev, struct uio *uio, int ioflag)
|
||||
{
|
||||
struct upd7210 *u;
|
||||
int error;
|
||||
size_t z;
|
||||
|
||||
u = dev->si_drv1;
|
||||
error = 0;
|
||||
|
||||
mtx_lock(&u->mutex);
|
||||
while (u->buf_wp == u->buf_rp) {
|
||||
error = msleep(u->buf, &u->mutex, PZERO | PCATCH,
|
||||
"gpibrd", hz);
|
||||
if (error && error != EWOULDBLOCK) {
|
||||
mtx_unlock(&u->mutex);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
while (uio->uio_resid > 0 && u->buf_wp != u->buf_rp) {
|
||||
if (u->buf_wp < u->buf_rp)
|
||||
z = u->bufsize - u->buf_rp;
|
||||
else
|
||||
z = u->buf_wp - u->buf_rp;
|
||||
if (z > uio->uio_resid)
|
||||
z = uio->uio_resid;
|
||||
mtx_unlock(&u->mutex);
|
||||
error = uiomove(u->buf + u->buf_rp, z, uio);
|
||||
mtx_lock(&u->mutex);
|
||||
if (error)
|
||||
break;
|
||||
u->buf_rp += z;
|
||||
u->buf_rp &= (u->bufsize - 1);
|
||||
}
|
||||
if (u->wreg[IMR1] == 0)
|
||||
write_reg(u, IMR1, 0x01);
|
||||
mtx_unlock(&u->mutex);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct cdevsw gpib_cdevsw = {
|
||||
.d_version = D_VERSION,
|
||||
.d_name = "gpib",
|
||||
.d_open = gpib_open,
|
||||
.d_close = gpib_close,
|
||||
.d_read = gpib_read,
|
||||
};
|
||||
|
||||
static void
|
||||
upd7210attach(struct upd7210 *u)
|
||||
{
|
||||
int unit = 0;
|
||||
|
||||
mtx_init(&u->mutex, "gpib", NULL, MTX_DEF);
|
||||
u->cdev = make_dev(&gpib_cdevsw, unit,
|
||||
UID_ROOT, GID_WHEEL, 0444,
|
||||
"gpib%ul", unit);
|
||||
u->cdev->si_drv1 = u;
|
||||
}
|
||||
|
152
sys/dev/ieee488/ugpib.h
Normal file
152
sys/dev/ieee488/ugpib.h
Normal file
@ -0,0 +1,152 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Poul-Henning Kamp <phk@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _DEV_IEEE488_UGPIB_H_
|
||||
#define _DEV_IEEE488_UGPIB_H_
|
||||
|
||||
/* ibfoo() return values */
|
||||
#define EDVR 0 /* System error */
|
||||
#define ECIC 1 /* Not Active Controller */
|
||||
#define ENOL 2 /* Nobody listening */
|
||||
#define EADR 3 /* Controller not addressed */
|
||||
#define EARG 4 /* Invalid argument */
|
||||
#define ESAC 5 /* Not System Controller */
|
||||
#define EABO 6 /* I/O Aborted/Time out */
|
||||
#define ENEB 7 /* No such controller */
|
||||
#define EOIP 10 /* Async I/O in progress */
|
||||
#define ECAP 11 /* No such capability */
|
||||
#define EFSO 12 /* File system error */
|
||||
#define EBUS 14 /* Command byte xfer error */
|
||||
#define ESTB 15 /* Serial poll status byte lost */
|
||||
#define ESRQ 16 /* SRQ line stuck */
|
||||
#define ETAB 20 /* Table problem */
|
||||
|
||||
/* ibsta bits */
|
||||
#define ERR (1<<15) /* Error */
|
||||
#define TIMO (1<<14) /* Timeout */
|
||||
#define END (1<<13) /* EOI/EOS */
|
||||
#define SRQI (1<<12) /* SRQ */
|
||||
#define RQS (1<<11) /* Device requests service */
|
||||
#define SPOLL (1<<10) /* Serial Poll */
|
||||
#define EVENT (1<<9) /* Event occured */
|
||||
#define CMPL (1<<8) /* I/O complete */
|
||||
#define LOK (1<<7) /* Lockout */
|
||||
#define REM (1<<6) /* Remote */
|
||||
#define CIC (1<<5) /* CIC */
|
||||
#define ATN (1<<4) /* ATN */
|
||||
#define TACS (1<<3) /* Talker */
|
||||
#define LACS (1<<2) /* Listener */
|
||||
#define DTAS (1<<1) /* Device trigger status */
|
||||
#define DCAS (1<<0) /* Device clear state */
|
||||
|
||||
/* Timeouts */
|
||||
#define TNONE 0
|
||||
#define T10us 1
|
||||
#define T30us 2
|
||||
#define T100us 3
|
||||
#define T300us 4
|
||||
#define T1ms 5
|
||||
#define T3ms 6
|
||||
#define T10ms 7
|
||||
#define T30ms 8
|
||||
#define T100ms 9
|
||||
#define T300ms 10
|
||||
#define T1s 11
|
||||
#define T3s 12
|
||||
#define T10s 13
|
||||
#define T30s 14
|
||||
#define T100s 15
|
||||
#define T300s 16
|
||||
#define T1000s 17
|
||||
|
||||
/* EOS bits */
|
||||
#define REOS (1 << 10)
|
||||
#define XEOS (1 << 11)
|
||||
#define BIN (1 << 12)
|
||||
|
||||
/* Bus commands */
|
||||
#define LAD 0x20 /* Listen address */
|
||||
#define UNL 0x3F /* Unlisten */
|
||||
#define TAD 0x40 /* Talk address */
|
||||
#define UNT 0x5F /* Untalk */
|
||||
|
||||
#ifndef _KERNEL
|
||||
|
||||
extern int ibcnt, iberr;
|
||||
|
||||
int ibask(int handle, int option, int *retval);
|
||||
int ibbna(int handle, char *bdname);
|
||||
int ibcac(int handle, int v);
|
||||
int ibclr(int handle);
|
||||
int ibcmd(int handle, void *buffer, long cnt);
|
||||
int ibcmda(int handle, void *buffer, long cnt);
|
||||
int ibconfig(int handle, int option, int value);
|
||||
int ibdev(int boardID, int pad, int sad, int tmo, int eot, int eos);
|
||||
int ibdiag(int handle, void *buffer, long cnt);
|
||||
int ibdma(int handle, int v);
|
||||
int ibeos(int handle, int eos);
|
||||
int ibeot(int handle, int v);
|
||||
int ibevent(int handle, short *event);
|
||||
int ibfind(char *bdname);
|
||||
int ibgts(int handle, int v);
|
||||
int ibist(int handle, int v);
|
||||
int iblines(int handle, short *lines);
|
||||
int ibllo(int handle);
|
||||
int ibln(int handle, int padval, int sadval, short *listenflag);
|
||||
int ibloc(int handle);
|
||||
int ibonl(int handle, int v);
|
||||
int ibpad(int handle, int v);
|
||||
int ibpct(int handle);
|
||||
int ibpoke(int handle, int option, int value);
|
||||
int ibppc(int handle, int v);
|
||||
int ibrd(int handle, void *buffer, long cnt);
|
||||
int ibrda(int handle, void *buffer, long cnt);
|
||||
int ibrdf(int handle, char *flname);
|
||||
int ibrdkey(int handle, void *buffer, int cnt);
|
||||
int ibrpp(int handle, char *ppr);
|
||||
int ibrsc(int handle, int v);
|
||||
int ibrsp(int handle, char *spr);
|
||||
int ibrsv(int handle, int v);
|
||||
int ibsad(int handle, int v);
|
||||
int ibsgnl(int handle, int v);
|
||||
int ibsic(int handle);
|
||||
int ibsre(int handle, int v);
|
||||
int ibsrq(void (*func)(void));
|
||||
int ibstop(int handle);
|
||||
int ibtmo(int handle, int tmo);
|
||||
int ibtrap(int mask, int mode);
|
||||
int ibtrg(int handle);
|
||||
int ibwait(int handle, int mask);
|
||||
int ibwrt(int handle, void *buffer, long cnt);
|
||||
int ibwrta(int handle, void *buffer, long cnt);
|
||||
int ibwrtf(int handle, char *flname);
|
||||
int ibwrtkey(int handle, void *buffer, int cnt);
|
||||
int ibxtrc(int handle, void *buffer, long cnt);
|
||||
#endif /* _KERNEL */
|
||||
#endif /* _DEV_IEEE488_UGPIB_H_ */
|
1026
sys/dev/ieee488/upd7210.c
Normal file
1026
sys/dev/ieee488/upd7210.c
Normal file
File diff suppressed because it is too large
Load Diff
213
sys/dev/ieee488/upd7210.h
Normal file
213
sys/dev/ieee488/upd7210.h
Normal file
@ -0,0 +1,213 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Poul-Henning Kamp <phk@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* Locating an actual µPD7210 data book has proven quite impossible for me.
|
||||
* There are a fair number of newer chips which are supersets of the µPD7210
|
||||
* but they are particular eager to comprehensively mark what the extensions
|
||||
* are and what is in the base set. Some even give the registers and their
|
||||
* bits new names.
|
||||
*
|
||||
* The following information is based on a description of the µPD7210 found
|
||||
* in an old manual for a VME board which used the chip.
|
||||
*/
|
||||
|
||||
/* upd7210 interface definitions */
|
||||
|
||||
struct upd7210;
|
||||
|
||||
struct ibfoo;
|
||||
|
||||
void upd7210intr(void *);
|
||||
void upd7210attach(struct upd7210 *);
|
||||
|
||||
typedef int upd7210_irq_t(struct upd7210 *);
|
||||
|
||||
struct upd7210 {
|
||||
bus_space_handle_t reg_handle[8];
|
||||
bus_space_tag_t reg_tag[8];
|
||||
u_int reg_offset[8];
|
||||
u_int dmachan;
|
||||
|
||||
/* private stuff */
|
||||
struct timeval deadline;
|
||||
struct mtx mutex;
|
||||
uint8_t rreg[8];
|
||||
uint8_t wreg[8 + 8];
|
||||
|
||||
upd7210_irq_t *irq;
|
||||
|
||||
int busy;
|
||||
u_char *buf;
|
||||
size_t bufsize;
|
||||
u_int buf_wp;
|
||||
u_int buf_rp;
|
||||
struct cdev *cdev;
|
||||
|
||||
struct ibfoo *ibfoo;
|
||||
};
|
||||
|
||||
/* upd7210 hardware definitions. */
|
||||
|
||||
/* Write registers */
|
||||
enum upd7210_wreg {
|
||||
CDOR = 0, /* Command/Data Out Register */
|
||||
IMR1 = 1, /* Interrupt Mask Register 1 */
|
||||
IMR2 = 2, /* Interrupt Mask Register 2 */
|
||||
SPMR = 3, /* Serial Poll Mode Register */
|
||||
ADMR = 4, /* ADdress Mode Register */
|
||||
AUXMR = 5, /* AUXilliary Mode Register */
|
||||
ICR = 5, /* Internal Counter Register */
|
||||
PPR = 5, /* Parallel Poll Register */
|
||||
AUXRA = 5, /* AUXilliary Register A */
|
||||
AUXRB = 5, /* AUXilliary Register B */
|
||||
AUXRE = 5, /* AUXilliary Register E */
|
||||
ADR = 6, /* ADdress Register */
|
||||
EOSR = 7, /* End-Of-String Register */
|
||||
};
|
||||
|
||||
/* Read registers */
|
||||
enum upd7210_rreg {
|
||||
DIR = 0, /* Data In Register */
|
||||
ISR1 = 1, /* Interrupt Status Register 1 */
|
||||
ISR2 = 2, /* Interrupt Status Register 2 */
|
||||
SPSR = 3, /* Serial Poll Status Register */
|
||||
ADSR = 4, /* ADdress Status Register */
|
||||
CPTR = 5, /* Command Pass Though Register */
|
||||
ADR0 = 6, /* ADdress Register 0 */
|
||||
ADR1 = 7, /* ADdress Register 1 */
|
||||
};
|
||||
|
||||
/* Bits for ISR1 and IMR1 */
|
||||
#define IXR1_DI (1 << 0) /* Data In */
|
||||
#define IXR1_DO (1 << 1) /* Data Out */
|
||||
#define IXR1_ERR (1 << 2) /* Error */
|
||||
#define IXR1_DEC (1 << 3) /* Device Clear */
|
||||
#define IXR1_ENDRX (1 << 4) /* End Received */
|
||||
#define IXR1_DET (1 << 5) /* Device Execute Trigger */
|
||||
#define IXR1_APT (1 << 6) /* Address Pass-Through */
|
||||
#define IXR1_CPT (1 << 7) /* Command Pass-Through */
|
||||
|
||||
/* Bits for ISR2 and IMR2 */
|
||||
#define IXR2_ADSC (1 << 0) /* Addressed Status Change */
|
||||
#define IXR2_REMC (1 << 1) /* Remote Change */
|
||||
#define IXR2_LOKC (1 << 2) /* Lockout Change */
|
||||
#define IXR2_CO (1 << 3) /* Command Out */
|
||||
#define ISR2_REM (1 << 4) /* Remove */
|
||||
#define IMR2_DMAI (1 << 4) /* DMA In Enable */
|
||||
#define ISR2_LOK (1 << 5) /* Lockout */
|
||||
#define IMR2_DMAO (1 << 5) /* DMA Out Enable */
|
||||
#define IXR2_SRQI (1 << 6) /* Service Request Input */
|
||||
#define ISR2_INT (1 << 7) /* Interrupt */
|
||||
|
||||
#define SPSR_PEND (1 << 6) /* Pending */
|
||||
#define SPMR_RSV (1 << 6) /* Request SerVice */
|
||||
|
||||
#define ADSR_MJMN (1 << 0) /* MaJor MiNor */
|
||||
#define ADSR_TA (1 << 1) /* Talker Active */
|
||||
#define ADSR_LA (1 << 2) /* Listener Active */
|
||||
#define ADSR_TPAS (1 << 3) /* Talker Primary Addr. State */
|
||||
#define ADSR_LPAS (1 << 4) /* Listener Primary Addr. State */
|
||||
#define ADSR_SPMS (1 << 5) /* Serial Poll Mode State */
|
||||
#define ADSR_ATN (1 << 6) /* Attention */
|
||||
#define ADSR_CIC (1 << 7) /* Controller In Charge */
|
||||
|
||||
#define ADMR_ADM0 (1 << 0) /* Address Mode 0 */
|
||||
#define ADMR_ADM1 (1 << 1) /* Address Mode 1 */
|
||||
#define ADMR_TRM0 (1 << 4) /* Transmit/Receive Mode 0 */
|
||||
#define ADMR_TRM1 (1 << 5) /* Transmit/Receive Mode 1 */
|
||||
#define ADMR_LON (1 << 6) /* Listen Only */
|
||||
#define ADMR_TON (1 << 7) /* Talk Only */
|
||||
|
||||
/* Constant part of overloaded write registers */
|
||||
#define C_ICR 0x20
|
||||
#define C_PPR 0x60
|
||||
#define C_AUXA 0x80
|
||||
#define C_AUXB 0xa0
|
||||
#define C_AUXE 0xc0
|
||||
|
||||
#define AUXMR_PON 0x00 /* Immediate Execute pon */
|
||||
#define AUXMR_CPP 0x01 /* Clear Parallel Poll */
|
||||
#define AUXMR_CRST 0x02 /* Chip Reset */
|
||||
#define AUXMR_RFD 0x03 /* Finish Handshake */
|
||||
#define AUXMR_TRIG 0x04 /* Trigger */
|
||||
#define AUXMR_RTL 0x05 /* Return to local */
|
||||
#define AUXMR_SEOI 0x06 /* Send EOI */
|
||||
#define AUXMR_NVSA 0x07 /* Non-Valid Secondary cmd/addr */
|
||||
/* 0x08 undefined/unknown */
|
||||
#define AUXMR_SPP 0x09 /* Set Parallel Poll */
|
||||
/* 0x0a undefined/unknown */
|
||||
/* 0x0b undefined/unknown */
|
||||
/* 0x0c undefined/unknown */
|
||||
/* 0x0d undefined/unknown */
|
||||
/* 0x0e undefined/unknown */
|
||||
#define AUXMR_VSA 0x0f /* Valid Secondary cmd/addr */
|
||||
#define AUXMR_GTS 0x10 /* Go to Standby */
|
||||
#define AUXMR_TCA 0x11 /* Take Control Async (pulsed) */
|
||||
#define AUXMR_TCS 0x12 /* Take Control Synchronously */
|
||||
#define AUXMR_LISTEN 0x13 /* Listen */
|
||||
#define AUXMR_DSC 0x14 /* Disable System Control */
|
||||
/* 0x15 undefined/unknown */
|
||||
#define AUXMR_SIFC 0x16 /* Set IFC */
|
||||
#define AUXMR_CREN 0x17 /* Clear REN */
|
||||
/* 0x18 undefined/unknown */
|
||||
/* 0x19 undefined/unknown */
|
||||
#define AUXMR_TCSE 0x1a /* Take Control Sync on End */
|
||||
#define AUXMR_LCM 0x1b /* Listen Continuously Mode */
|
||||
#define AUXMR_LUNL 0x1c /* Local Unlisten */
|
||||
#define AUXMR_EPP 0x1d /* Execute Parallel Poll */
|
||||
#define AUXMR_CIFC 0x1e /* Clear IFC */
|
||||
#define AUXMR_SREN 0x1f /* Set REN */
|
||||
|
||||
#define PPR_U (1 << 4) /* Unconfigure */
|
||||
#define PPR_S (1 << 3) /* Status Polarity */
|
||||
|
||||
#define AUXA_HLDA (1 << 0) /* Holdoff on All */
|
||||
#define AUXA_HLDE (1 << 1) /* Holdoff on END */
|
||||
#define AUXA_REOS (1 << 2) /* End on EOS received */
|
||||
#define AUXA_XEOS (1 << 3) /* Transmit END with EOS */
|
||||
#define AUXA_BIN (1 << 4) /* Binary */
|
||||
|
||||
#define AUXB_CPTE (1 << 0) /* Cmd Pass Through Enable */
|
||||
#define AUXB_SPEOI (1 << 1) /* Send Serial Poll EOI */
|
||||
#define AUXB_TRI (1 << 2) /* Three-State Timing */
|
||||
#define AUXB_INV (1 << 3) /* Invert */
|
||||
#define AUXB_ISS (1 << 4) /* Individual Status Select */
|
||||
|
||||
#define AUXE_DHDT (1 << 0) /* DAC Holdoff on DTAS */
|
||||
#define AUXE_DHDC (1 << 1) /* DAC Holdoff on DCAS */
|
||||
|
||||
#define ADR0_DL0 (1 << 5) /* Disable Listener 0 */
|
||||
#define ADR0_DT0 (1 << 6) /* Disable Talker 0 */
|
||||
|
||||
#define ADR_DL (1 << 5) /* Disable Listener */
|
||||
#define ADR_DT (1 << 6) /* Disable Talker */
|
||||
#define ADR_ARS (1 << 7) /* Address Register Select */
|
||||
|
||||
#define ADR1_DL1 (1 << 5) /* Disable Listener 1 */
|
||||
#define ADR1_DT1 (1 << 6) /* Disable Talker 1 */
|
||||
#define ADR1_EOI (1 << 7) /* End or Identify */
|
||||
|
Loading…
Reference in New Issue
Block a user