changes for 3.14

This commit is contained in:
Marty Kraimer
1999-09-13 18:54:51 +00:00
parent 3c2e5070ef
commit bfb21afcce
39 changed files with 0 additions and 19134 deletions

View File

@@ -1,7 +0,0 @@
TOP=../../..
include $(TOP)/config/CONFIG_BASE
include $(TOP)/config/RULES_ARCHS

View File

@@ -1,61 +0,0 @@
TOP = ../../../..
include $(TOP)/config/CONFIG_BASE
CMPLR = TRAD
VX_WARN_YES = -Wall -pedantic
# Only the 68k cross-compiler has no "nobitfield" option -kuk-
ifeq ($(ARCH_CLASS),68k)
USR_CFLAGS = -fshared-data -fvolatile -mnobitfield
else
USR_CFLAGS = -fshared-data -fvolatile
endif
#The following have been unbundled. DONT USE THESE
#INC += drvBB232.h
#INC += drvBitBus.h
#INC += drvMsg.h
# drvBitBusErr and drvBitBusInterface APPEAR HERE AND IN UNBUNDLED - BIG PROBLEM
INC += drvBitBusErr.h
INC += drvBitBusInterface.h
#SRCS.c += ../drvBB232.c
#SRCS.c += ../drvBitBus.c
#SRCS.c += ../drvMsg.c
#SRCS.c += ../drvTranServ.c
#The following have not been used
#INC += drvRs232.h
#INC += drvTy232.h
INC += drvGpib.h
INC += drvGpibErr.h
INC += drvGpibInterface.h
INC += drvHiDEOSGpib.h
INC += drvJgvtr1.h
INC += drvOms.h
INC += steppermotor.h
SRCS.c += ../module_types.c
SRCS.c += ../drvBb902.c
SRCS.c += ../drvBb910.c
SRCS.c += ../drvComet.c
SRCS.c += ../drvCompuSm.c
SRCS.c += ../drvDvx.c
SRCS.c += ../drvFp.c
SRCS.c += ../drvFpm.c
SRCS.c += ../drvGpib.c
SRCS.c += ../drvJgvtr1.c
SRCS.c += ../drvOms.c
SRCS.c += ../drvVmi4100.c
SRCS.c += ../drvXy010.c
SRCS.c += ../drvXy210.c
SRCS.c += ../drvXy220.c
SRCS.c += ../drvXy240.c
SRCS.c += ../drvXy566.c
PROD = $(SRCS.c:../%.c=%.o)
include $(TOP)/config/RULES.Vx

View File

@@ -1,22 +0,0 @@
The following are unbundled
drvBB232.c
drvBB232.h
drvBitBus.c
drvBitBus.h
drvBitBusErr.h
drvBitBusInterface.h
drvMsg.h
drvMsg.c
drvRs232.h
The following should not be used
drvTy232.h
drvRs232.c
The following is a BIG PROBLEM because drvGpib.c include and uses it.
For now it is both here are in the unbundled version
drvBitBusInterface.h

View File

@@ -1,589 +0,0 @@
/* base/src/drv $Id$ */
/*
* Author: John Winans
* Date: 05-21-92
* EPICS BITBUS -> R/S-232 driver
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 09-30-91 jrw created
*
*/
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <dbDefs.h>
#include <epicsPrint.h>
#include <task_params.h>
#include <module_types.h>
#include <drvSup.h>
#include <devSup.h>
#include <dbCommon.h>
#include <dbAccess.h>
#include <link.h>
#include <callback.h>
#include <fast_lock.h>
#include <drvMsg.h>
#include <drvBitBusInterface.h>
#include <drvRs232.h>
#include <drvBB232.h>
int drvBB232Debug = 0;
int softBB232 = 0;
extern struct drvBitBusEt drvBitBus;
/******************************************************************************
*
******************************************************************************/
#define BB232LINK_PRI 50
#define BB232LINK_OPT VX_FP_TASK|VX_STDIO
#define BB232LINK_STACK 5000
/******************************************************************************
*
******************************************************************************/
static long
report()
{
printf("Report for BITBUS -> RS-232 driver\n");
return(OK);
}
/******************************************************************************
*
******************************************************************************/
static long
init(pparms)
msgDrvIniParm *pparms;
{
if (drvBB232Debug)
printf("Init for BITBUS -> RS-232 driver\n");
return(OK);
}
/******************************************************************************
*
* This function is called to allocate any structures needed to hold
* device-specific data that is added to the msgXact structure.
*
* It is also responsible for filling in the msgXact.phwpvt pointer.
*
******************************************************************************/
static long
genXact(p)
msgDrvGenXParm *p;
{
long stat = -1;
char message[100];
drvBB232Link *pdrvBB232Link;
struct dpvtBitBusHead *pdpvtBitBusHead;
if (p->plink->type != BITBUS_IO)
{
p->pmsgXact->prec->pact = TRUE;
sprintf("%s: invalid device type in devSup.ascii (%d)\n", p->pmsgXact->prec->name, p->plink->type);
errMessage(S_db_badField, message);
return(ERROR);
}
if (drvBB232Debug)
printf("BB232 genXact entered for link %d, bug %d, port %d, parm %s\n", p->plink->value.bitbusio.link, p->plink->value.bitbusio.node, p->plink->value.bitbusio.port, p->plink->value.bitbusio.parm);
p->pmsgXact->phwpvt = p->pmsgXact->pparmBlock->pmsgHwpvt;
/* try to find the hwpvt structure for the required link, bug, and port */
while ((p->pmsgXact->phwpvt != NULL) && (stat == -1))
{
pdrvBB232Link = (drvBB232Link *)(p->pmsgXact->phwpvt->pmsgLink->p);
if ((pdrvBB232Link->link == p->plink->value.bitbusio.link)
&& (pdrvBB232Link->node == p->plink->value.bitbusio.node)
&& (pdrvBB232Link->port == p->plink->value.bitbusio.port))
{
if (pdrvBB232Link->pparmBlock != p->pmsgXact->pparmBlock)
{
sprintf(message, "%s: Two different devices on same BB232 port\n", p->pmsgXact->prec->name);
errMessage(S_db_badField, message);
return(ERROR);
}
else
stat = 0; /* Found the correct hwpvt structure */
}
else
p->pmsgXact->phwpvt = p->pmsgXact->phwpvt->next;
}
if (stat != 0)
{ /* Could not find a msgHwpvt for the right link, create a new one */
if ((p->pmsgXact->phwpvt = drvMsg_genHwpvt(p->pmsgXact->pparmBlock, p->plink)) == NULL)
return(ERROR);
}
/* Set again in case hwpvt was just allocated (and to make compiler happy) */
pdrvBB232Link = (drvBB232Link *)(p->pmsgXact->phwpvt->pmsgLink->p);
p->pmsgXact->callback.callback = NULL;
p->pmsgXact->psyncSem = NULL;
/* Create the skeleton bitbus driver message */
pdpvtBitBusHead = (struct dpvtBitBusHead *) malloc(sizeof(struct dpvtBitBusHead));
(struct dpvtBitBusHead *)(p->pmsgXact->p) = pdpvtBitBusHead;
pdpvtBitBusHead->finishProc = NULL;
pdpvtBitBusHead->psyncSem = malloc(sizeof(SEM_ID));
*(pdpvtBitBusHead->psyncSem) = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
pdpvtBitBusHead->link = pdrvBB232Link->link;
pdpvtBitBusHead->txMsg.route = BB_STANDARD_TX_ROUTE;
pdpvtBitBusHead->txMsg.node = pdrvBB232Link->node;
pdpvtBitBusHead->txMsg.tasks = BB_232_TASK;
pdpvtBitBusHead->txMsg.cmd = 0xff;
pdpvtBitBusHead->rxMsg.data = (unsigned char *) malloc(BB_MAX_DAT_LEN);
/* in case I read before write */
pdpvtBitBusHead->rxMsg.cmd = 0;
pdpvtBitBusHead->rxMsg.length = BB_MSG_HEADER_SIZE;
pdpvtBitBusHead->status = BB_OK;
pdpvtBitBusHead->rxMaxLen = 0;
pdpvtBitBusHead->ageLimit = 0;
if (sscanf(p->plink->value.bitbusio.parm,"%d", &(p->pmsgXact->parm)) != 1)
{
p->pmsgXact->prec->pact = TRUE;
sprintf("%s: invalid parameter string >%s<\n", p->pmsgXact->prec->name, p->plink->value.bitbusio.parm);
errMessage(S_db_badField, message);
return(ERROR);
}
return(OK);
}
/******************************************************************************
*
* This function is called to allocate any structures needed to hold
* device-specific data that is added to the msgHwpvt structure.
*
* It is also responsible for filling in the msgHwpvt.pmsgLink pointer.
*
******************************************************************************/
static long
genHwpvt(p)
msgDrvGenHParm *p;
{
int stat = ERROR;
if (drvBB232Debug)
printf("BB232 genHwpvt entered\n");
p->pmsgHwpvt->pmsgLink = drvBB232Block.pmsgLink;
while ((p->pmsgHwpvt->pmsgLink != NULL) && (stat == ERROR))
{
if ((((drvBB232Link *)(p->pmsgHwpvt->pmsgLink->p))->link == p->plink->value.bitbusio.link)
&& (((drvBB232Link *)(p->pmsgHwpvt->pmsgLink->p))->node == p->plink->value.bitbusio.node)
&& (((drvBB232Link *)(p->pmsgHwpvt->pmsgLink->p))->port == p->plink->value.bitbusio.port))
stat = OK;
else
p->pmsgHwpvt->pmsgLink = p->pmsgHwpvt->pmsgLink->next;
}
if (stat != OK)
{
if ((p->pmsgHwpvt->pmsgLink = drvMsg_genLink(p->pparmBlock, p->plink)) == NULL)
return(ERROR);
}
return(OK);
}
/******************************************************************************
*
* This function is called to allocate any structures needed to hold
* device-specific data that is added to the msgLink structure.
*
******************************************************************************/
static long
genLink(p)
msgDrvGenLParm *p;
{
char message[100];
drvBB232Link *pdrvBB232Link;
if (drvBB232Debug)
printf("BB232 genLink, link = %d, node = %d port = %d\n",
p->plink->value.bitbusio.link, p->plink->value.bitbusio.node,
p->plink->value.bitbusio.port);
switch (p->op) {
case MSG_GENLINK_CREATE:
/* BUG -- verify that the link and node numbers are within range! */
if (p->plink->value.bitbusio.port & (~DD_232_PORT))
{
sprintf(message, "drvBB232: port number %d out of range\n", p->plink->value.bitbusio.port);
errMessage(S_db_badField, message);
return(ERROR);
}
if ((p->pmsgLink->p = malloc(sizeof(drvBB232Link))) == NULL)
return(ERROR);
pdrvBB232Link = (drvBB232Link *)(p->pmsgLink->p);
pdrvBB232Link->link = p->plink->value.bitbusio.link;
pdrvBB232Link->node = p->plink->value.bitbusio.node;
pdrvBB232Link->port = p->plink->value.bitbusio.port;
pdrvBB232Link->pparmBlock = p->pparmBlock;
return(OK);
case MSG_GENLINK_ABORT:
if (drvBB232Debug)
printf("BB232 genLink: called with abort status\n");
pdrvBB232Link = (drvBB232Link *)(p->pmsgLink->p);
/* BUG - free(p->pmsgLink->p); Don't forget to take it out of the list */
return(OK);
}
return(ERROR);
}
/******************************************************************************
*
* This function is called to allow the device to indicate that a device-related
* event has occurred. If an event had occurred, it would have to place the
* address of a valid transaction structure in pxact. This xact structure
* will then be processed by the message link task as indicated by the
* return code of this function.
*
* MSG_EVENT_NONE = no event has occurred, pxact not filled in.
* MSG_EVENT_WRITE = event occurred, process the writeOp assoc'd w/pxact.
* MSG_EVENT_READ = event occurred, process the readOp assoc'd w/pxact.
*
* Note that MSG_EVENT_READ only makes sense when returned with a transaction
* that has deferred readback specified for its readOp function. Because if
* it is NOT a deferred readback, it will be done immediately after the writeOp.
* Even if that writeOp was due to a MSG_EVENT_WRITE from this function.
*
******************************************************************************/
static long
checkEvent(p)
msgChkEParm *p;
{
return(MSG_EVENT_NONE);
}
/******************************************************************************
*
* This IOCTL function is used to handle non-I/O related operations required
* to operate the RS-232 interface.
*
******************************************************************************/
static long
command(p)
ioctlCommand *p;
{
msgXact *pxact;
struct dpvtBitBusHead *pdpvtBitBusHead;
drvBB232Link *pdrvBB232Link;
switch (p->cmd) {
case IOCTL232_BREAK: /* send a BREAK signal to the serial port. */
/* Build a break message to send */
pxact = (msgXact *) (p->pparm);
pdpvtBitBusHead = (struct dpvtBitBusHead *) pxact->p;
pdrvBB232Link = (drvBB232Link *)(pxact->phwpvt->pmsgLink->p);
pdpvtBitBusHead->status = BB_OK;
pdpvtBitBusHead->rxMaxLen = 0;
pdpvtBitBusHead->txMsg.length = BB_MSG_HEADER_SIZE;
pdpvtBitBusHead->txMsg.cmd = BB_232_BREAK + pdrvBB232Link->port;
pdpvtBitBusHead->rxMsg.cmd = 0;
if (drvBB232Debug > 7)
{
printf("drvBB232.control (tx L%d N%d P%d)\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port);
drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg));
}
(*(drvBitBus.qReq))(pdpvtBitBusHead, BB_Q_LOW);
semTake(*(pdpvtBitBusHead->psyncSem), WAIT_FOREVER);
if ((pdpvtBitBusHead->status == BB_OK) && !(pdpvtBitBusHead->rxMsg.cmd & 1))
return(OK);
else
return(ERROR);
}
if (drvBB232Debug)
printf("drvBB232.control: bad command 0x%2.2X\n", p->cmd);
return(ERROR);
}
/******************************************************************************
*
* This function is used to write a string of characters out to an RS-232
* device.
*
* Note that the BUGs reply to the write messages with the first 13 bytes
* of the machine's response string (if there is one.) This response string
* will be left in the pdpvtBitBusHead->rxMsg buffer when the drvRead()
* function is called later.
*
******************************************************************************/
static long
drvWrite(pxact, pwrParm)
msgXact *pxact;
msgStrParm *pwrParm;
{
int len;
drvBB232Link *pdrvBB232Link = (drvBB232Link *)(pxact->phwpvt->pmsgLink->p);
struct dpvtBitBusHead *pdpvtBitBusHead = (struct dpvtBitBusHead *) pxact->p;
unsigned char loopLen;
/* build a bitbus message and call the bitbus driver */
if (pwrParm->len == -1)
len = strlen(pwrParm->buf);
else
len = pwrParm->len;
pdpvtBitBusHead->txMsg.data = (unsigned char *) pwrParm->buf;
pdpvtBitBusHead->status = BB_OK;
pdpvtBitBusHead->rxMaxLen = BB_MAX_MSG_LENGTH;
pdpvtBitBusHead->txMsg.cmd = BB_232_CMD + pdrvBB232Link->port;
pdpvtBitBusHead->rxMsg.cmd = 0;
while (len && (pdpvtBitBusHead->status == BB_OK) &&
!(pdpvtBitBusHead->rxMsg.cmd & 1))
{
if (len > BB_MAX_DAT_LEN)
loopLen = BB_MAX_DAT_LEN;
else
loopLen = len;
pdpvtBitBusHead->txMsg.length = loopLen + BB_MSG_HEADER_SIZE;
if (softBB232)
{
printf("drvBB232.drvWrite(tx L%d N%d P%d):\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port);
drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg));
}
else
{
(*(drvBitBus.qReq))(pdpvtBitBusHead, BB_Q_LOW); /* do it */
semTake(*(pdpvtBitBusHead->psyncSem), WAIT_FOREVER); /* wait for completion */
if (drvBB232Debug > 10)
{
printf("drvBB232.drvWrite (tx L%d N%d P%d)\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port);
drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg));
}
}
pdpvtBitBusHead->txMsg.data += loopLen;
len -= loopLen;
}
if ((pdpvtBitBusHead->status != BB_OK) || (pdpvtBitBusHead->rxMsg.cmd & 1))
{
if (drvBB232Debug)
printf("BB232 write error on link %d, node %d, port %d, driver %2.2X, message %2.2X\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port, pdpvtBitBusHead->status, pdpvtBitBusHead->rxMsg.cmd);
pxact->status = XACT_IOERR;
}
return(pxact->status);
}
/******************************************************************************
*
* This function is used to read a string of characters from an RS-232 device.
*
* It is assumed that pdpvtBitBusHead->rxMsg has already got up to 13
* bytes of the response data already filled in (left there by the prior
* call to drvWrite().) If a call to this function is made when there is
* garbage in the initial pdpvtBitBusHead->rxMsg buffer, set the length field
* to 0 and the status field to BB_OK.
*
******************************************************************************/
static long
drvRead(pxact, prdParm)
msgXact *pxact;
msgStrParm *prdParm;
{
drvBB232Link *pdrvBB232Link = (drvBB232Link *)(pxact->phwpvt->pmsgLink->p);
struct dpvtBitBusHead *pdpvtBitBusHead = (struct dpvtBitBusHead *) pxact->p;
int len = prdParm->len;
int loopLen = 0;
/* check if data already loaded into pdpvtBitBusHead->rxMsg */
if ((pdpvtBitBusHead->rxMsg.length > BB_MSG_HEADER_SIZE) && (pdpvtBitBusHead->status == BB_OK))
{
loopLen = pdpvtBitBusHead->rxMsg.length - BB_MSG_HEADER_SIZE;
if (prdParm->len < loopLen)
loopLen = prdParm->len;
if (drvBB232Debug > 9)
{
printf("drvBB232.drvRead (rx L%d N%d P%d)\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port);
drvBitBusDumpMsg(&(pdpvtBitBusHead->rxMsg));
}
bcopy(pdpvtBitBusHead->rxMsg.data, prdParm->buf, loopLen);
len -= loopLen;
}
pdpvtBitBusHead->txMsg.length = BB_MSG_HEADER_SIZE;
pdpvtBitBusHead->txMsg.cmd = BB_232_CMD + pdrvBB232Link->port;
pdpvtBitBusHead->rxMsg.data = (unsigned char *) (&(prdParm->buf[loopLen]));
if (!(pdpvtBitBusHead->rxMsg.cmd & BB_232_EOI))
{ /* If we did not hit EOI yet, keep reading */
while (len && (pdpvtBitBusHead->status == BB_OK))
{
if (len > BB_MAX_DAT_LEN)
loopLen = BB_MAX_DAT_LEN;
else
loopLen = len;
pdpvtBitBusHead->rxMaxLen = loopLen + BB_MSG_HEADER_SIZE;
if (softBB232)
{
printf("drvBB232.drvRead(tx L%d N%d P%d)\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port);
drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg));
pdpvtBitBusHead->status = BB_232_EOI;
}
else
{
if (drvBB232Debug > 10)
{
printf("drvBB232.drvRead(tx L%d N%d P%d)\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port);
drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg));
}
(*(drvBitBus.qReq))(pdpvtBitBusHead, BB_Q_LOW); /* do it */
semTake(*(pdpvtBitBusHead->psyncSem), WAIT_FOREVER); /* wait for completion */
if (drvBB232Debug > 9)
{
printf("drvBB232.drvRead (rx L%d N%d P%d)\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port);
drvBitBusDumpMsg(&(pdpvtBitBusHead->rxMsg));
}
}
if (pdpvtBitBusHead->rxMsg.cmd & (~BB_232_EOI))
{ /* Something is wrong... */
if (drvBB232Debug > 6)
{
printf("drvBB232.drvRead (rx L%d N%d P%d) Error response from BUG\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port);
drvBitBusDumpMsg(&(pdpvtBitBusHead->rxMsg));
}
pxact->status = XACT_IOERR;
break; /* note that we will fall thru to the null-term code */
}
if (pdpvtBitBusHead->rxMsg.cmd & BB_232_EOI)
{
pdpvtBitBusHead->rxMsg.data += pdpvtBitBusHead->rxMsg.length - BB_MSG_HEADER_SIZE;
len -= pdpvtBitBusHead->rxMsg.length - BB_MSG_HEADER_SIZE;
break;
}
pdpvtBitBusHead->rxMsg.data += loopLen;
len -= loopLen;
}
}
/* Null-terminate the input string (if there is room) */
if (len)
*(pdpvtBitBusHead->rxMsg.data) = '\0';
else
pxact->status = XACT_LENGTH;
/* Note that the following error check, takes priority over a length error */
if (pdpvtBitBusHead->status != BB_OK)
{
if (drvBB232Debug)
printf("BB232 read error on link %d, node %d, port %d\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port);
pxact->status = XACT_IOERR;
}
/* BUG -- this can print unterminated strings !! */
if (drvBB232Debug > 7)
printf("drvRead: got >%s<\n", prdParm->buf);
pdpvtBitBusHead->rxMsg.length = BB_MSG_HEADER_SIZE; /* in case keep reading */
return(pxact->status);
}
/******************************************************************************
*
* This handles any IOCTL calls made to BB-232 devices.
*
******************************************************************************/
static long
drvIoctl(cmd, pparm)
int cmd;
void *pparm;
{
switch (cmd) {
case MSGIOCTL_REPORT:
return(report());
case MSGIOCTL_INIT:
return(init(pparm));
case MSGIOCTL_INITREC:
if (drvBB232Debug)
printf("drvBB232Block.drvIoctl got a MSGIOCTL_INITREC request!\n");
return(ERROR);
case MSGIOCTL_GENXACT:
return(genXact(pparm));
case MSGIOCTL_GENHWPVT:
return(genHwpvt(pparm));
case MSGIOCTL_GENLINK:
return(genLink(pparm));
case MSGIOCTL_CHECKEVENT:
return(checkEvent(pparm));
case MSGIOCTL_COMMAND:
return(command(pparm));
}
return(ERROR);
}
msgDrvBlock drvBB232Block = {
"BB232", /* taskName */
BB232LINK_PRI, /* taskPri */
BB232LINK_OPT, /* taskOpt */
BB232LINK_STACK, /* taskStack */
NULL, /* pmsgLink (linked list header) */
drvWrite, /* drvWrite */
drvRead, /* drvRead */
drvIoctl /* drvIoctl */
};

View File

@@ -1,66 +0,0 @@
/* share/epicsH $Id$ */
/*
* Author: John Winans
* Date: 5-21-92
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1988, 1989, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* All rights reserved. No part of this publication may be reproduced,
* stored in a retrieval system, transmitted, in any form or by any
* means, electronic, mechanical, photocopying, recording, or otherwise
* without prior written permission of Los Alamos National Laboratory
* and Argonne National Laboratory.
*
* Modification Log:
* -----------------
* .01 05-21-92 jrw Initial release
* .02 02-19-92 joh cpu independent clk rate
*/
#ifndef DRVBB232_H
#define DRVBB232_H
/******************************************************************************
*
* Additional fields needed for the msgParmBlock structure.
*
******************************************************************************/
typedef struct {
int dmaTimeout; /* Clock ticks to wait for DMA to complete */
int baud; /* baud rate to run the interface */
} drvBB232ParmBlock;
typedef struct {
int link; /* The BB card/link number */
int node; /* the bug's node number */
int port; /* The tty port number on that card */
/* The pparmBlock is used to make sure only 1 device type is requested */
/* on one single port. */
msgParmBlock *pparmBlock;
} drvBB232Link;
extern msgDrvBlock drvBB232Block;
#define BB232_DEFAULT_AGE (sysClkRateGet()) /* 1 second */
#define BB_232_EOI 0x20
#endif

View File

@@ -1,204 +0,0 @@
/* base/src/drv $Id$ */
/*
* subroutines that are used to interface to the binary output cards
*
* Author: Bob Dalesio
* Date: 5-26-88
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 10-31-91 bg broke bb902 code out of bo_driver.c
* .02 02-20-92 bg Added level to io_report. Added ability
* to read out raw values on card if level
* > 0.
* .03 08-10-92 joh made number of cards runtime configurable
* .04 08-25-92 mrk made masks a macro
* .05 09-14-93 mrk Let report just display one hex value
*
*/
static char SccsId[] = "@(#)drvBb902.c 1.6 9/14/92 ";
/*
* Code Portions:
*
* bo_drv_init Finds and initializes all binary output cards present
* bo_driver Interfaces to the binary output cards present
*/
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <vxLib.h>
#include <sysLib.h>
#include <vme.h>
#include <module_types.h>
#include <drvSup.h>
static long report();
static long init();
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvBb902={
2,
report,
init};
static long report(level)
int level;
{
bb902_io_report(level);
return(0);
}
static long init()
{
bb902_driver_init();
return(0);
}
#define MAX_BB_BO_CARDS (bo_num_cards[BB902])
/* Burr-Brown 902 binary output memory structure */
struct bo_bb902{
short csr; /* control status register */
unsigned short low_value; /* low order 16 bits value */
unsigned short high_value; /* high order 16 bits value */
char end_pad[0x100-6]; /* pad until next card */
};
static char *bb902_shortaddr;
/* pointers to the binary output cards */
struct bo_bb902 **pbo_bb902s; /* Burr-Brown 902s */
/*
* BO_DRIVER_INIT
*
* intialization for the binary output cards
*/
int bb902_driver_init(){
int bomode;
int status;
short i;
struct bo_bb902 *pbo_bb902;
pbo_bb902s = (struct bo_bb902 **)calloc(MAX_BB_BO_CARDS,
sizeof(*pbo_bb902s));
if(!pbo_bb902s){
return ERROR;
}
/* intialize the Burr-Brown 902 binary output cards */
/* base address of the burr-brown 902 binary output cards */
status = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,bo_addrs[BB902],&bb902_shortaddr);
if (status != OK){
printf("Addressing error in bb902 driver\n");
return (ERROR);
}
pbo_bb902 = (struct bo_bb902 *)bb902_shortaddr;
/* determine which cards are present */
for (i = 0; i < bo_num_cards[BB902]; i++,pbo_bb902++){
if (vxMemProbe(pbo_bb902,READ,sizeof(short),&bomode) == OK)
pbo_bb902s[i] = pbo_bb902;
else
pbo_bb902s[i] = 0;
}
return (0);
}
/*
* BB902_DRIVER
*
* interface to the Burr-Brown binary outputs
*/
int bb902_driver(card,val,mask)
unsigned short card;
unsigned long val;
unsigned long mask;
{
unsigned int work;
/* verify card exists */
if (!pbo_bb902s[card])
return (-1);
/* use structure to handle high and low short swap */
/* get current output */
work = (pbo_bb902s[card]->high_value << 16) /* high */
+ pbo_bb902s[card]->low_value; /* low */
/* alter specified bits */
work = (work & ~mask) | (val & mask);
/* write new output */
pbo_bb902s[card]->high_value = (unsigned short)(work >> 16);
pbo_bb902s[card]->low_value = (unsigned short)work;
return (0);
}
/*
* bb902_read
*
* read the binary output
*/
int bb902_read(card,mask,pval)
unsigned short card;
unsigned int mask;
unsigned int *pval;
{
/* verify card exists */
if (!pbo_bb902s[card]) return (-1);
/* readback */
*pval = (pbo_bb902s[card]->high_value << 16) /* high */
+ pbo_bb902s[card]->low_value; /* low */
*pval &= mask;
return(0);
}
void bb902_io_report(level)
short int level;
{
unsigned int value;
int card;
for (card = 0; card < MAX_BB_BO_CARDS; card++){
if (pbo_bb902s[card]){
value = (pbo_bb902s[card]->high_value << 16)
+ pbo_bb902s[card]->low_value;
printf("BO: BB902: card %d value=0x%8.8x\n",card,value);
}
}
}

View File

@@ -1,214 +0,0 @@
/* bb910_driver.c */
/* base/src/drv $Id$ */
/*
* subroutines that are used to interface to the binary input cards
*
* Author: Bob Dalesio
* Date: 6-13-88
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 02-09-89 lrd moved I/O addresses to module_types.h
* .02 11-20-89 joh added call to at5vxi driver
* .03 09-11-91 bg added bb910_io_report
* .04 10-31-91 bg broke bb910 code out of bi_driver.c
* .05 02-04-92 bg added the argument level to
* bb910_io_report() and gave it the ability
* to read raw values from card if level > 0
* .06 08-10-92 joh made the number of cards runtime
* .07 08-25-92 mrk made masks a macro
*/
/*
* Code Portions:
*
* bi_driver_init Finds and initializes all binary input cards present
* bi_driver Interfaces to the binary input cards present
*/
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <vxLib.h>
#include <sysLib.h>
#include <vme.h>
#include <module_types.h>
#include <drvSup.h>
static long report();
static long init();
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvBb910={
2,
report,
init};
static long report(level)
int level;
{
bb910_io_report(level);
return(0);
}
static long init()
{
bb910_driver_init();
return(0);
}
static char SccsId[] = "@(#)drvBb910.c 1.6\t6/3/93";
#define MAX_BB_BI_CARDS (bi_num_cards[BB910])
/* Burr-Brown 910 binary input memory structure */
/* Note: the high and low order words are switched from the io card */
struct bi_bb910{
unsigned short csr; /* control status register */
unsigned short low_value; /* low order 16 bits value */
unsigned short high_value; /* high order 16 bits value */
char end_pad[0x100-6]; /* pad until next card */
};
/* pointers to the binary input cards */
struct bi_bb910 **pbi_bb910s; /* Burr-Brown 910s */
/* test word for forcing bi_driver */
int bi_test;
static char *bb910_shortaddr;
/*
* BI_DRIVER_INIT
*
* intialization for the binary input cards
*/
int bb910_driver_init(){
int bimode;
int status;
register short i;
struct bi_bb910 *pbi_bb910;
pbi_bb910s = (struct bi_bb910 **)
calloc(MAX_BB_BI_CARDS, sizeof(*pbi_bb910s));
if(!pbi_bb910s){
return ERROR;
}
/* intialize the Burr-Brown 910 binary input cards */
/* base address of the burr-brown 910 binary input cards */
status=sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,bi_addrs[BB910],&bb910_shortaddr);
if (status != OK){
printf("Addressing error in bb910 driver\n");
return ERROR;
}
pbi_bb910 = (struct bi_bb910 *)bb910_shortaddr;
/* determine which cards are present */
for (i = 0; i < bi_num_cards[BB910]; i++,pbi_bb910++){
if (vxMemProbe(pbi_bb910,READ,sizeof(short),&bimode) == OK){
pbi_bb910s[i] = pbi_bb910;
}
else {
pbi_bb910s[i] = 0;
}
}
return (0);
}
int bb910_driver(card,mask,prval)
register unsigned short card;
unsigned int mask;
register unsigned int *prval;
{
register unsigned int work;
if (!pbi_bb910s[card])
return (-1);
/* read */
work = (pbi_bb910s[card]->high_value << 16) /* high */
+ pbi_bb910s[card]->low_value; /* low */
/* apply mask */
*prval = work & mask;
return (0);
}
#define masks(K) ((1<<K))
void bb910_io_report(level)
short int level;
{
register short i,j,k,l,m,num_chans;
unsigned int jval,kval,lval,mval;
for (i = 0; i < bi_num_cards[BB910]; i++){
if (pbi_bb910s[i]){
printf("BI: BB910: card %d\n",i);
if (level > 0){
num_chans = bi_num_channels[BB910];
for(j=0,k=1,l=2,m=3;j < num_chans,k < num_chans, l < num_chans,m < num_chans;
j+=IOR_MAX_COLS,k+= IOR_MAX_COLS,l+= IOR_MAX_COLS,m += IOR_MAX_COLS){
if(j < num_chans){
bb910_driver(i,masks(j),BB910,&jval);
if (jval != 0)
jval = 1;
printf("Chan %d = %x\t ",j,jval);
}
if(k < num_chans){
bb910_driver(i,masks(k),BB910,&kval);
if (kval != 0)
kval = 1;
printf("Chan %d = %x\t ",k,kval);
}
if(l < num_chans){
bb910_driver(i,masks(l),BB910,&lval);
if (lval != 0)
lval = 1;
printf("Chan %d = %x \t",l,lval);
}
if(m < num_chans){
bb910_driver(i,masks(m),BB910,&mval);
if (mval != 0)
mval = 1;
printf("Chan %d = %x \n",m,mval);
}
}
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,299 +0,0 @@
#ifndef EPICS_DRVBITBUS_H
#define EPICS_DRVBITBUS_H
/* #define BB_SUPER_DEBUG */
/*
* Author: John Winans
* Date: 09-10-91
* BitBus driver
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 09-30-91 jrw Written
* .02 12-10-91 jrw moved some stuff over to drvBitBusInterface.h
* .03 07-01-94 jrw Bigtime hacking... merged PEP and Xycom.
*
*
*/
/*****************************************************************************
*
* This history stuff below is used to save the recent history of operation.
* This history includes dumps of messages that are queued, transmitted and
* received. This information is saved along with the relative tick time.
*
*****************************************************************************/
#ifdef BB_SUPER_DEBUG
#define BB_SUPER_DEBUG_HIST_SIZ 50 /* How many messages to save */
typedef struct XactHistStruct
{
struct dpvtBitBusHead Xact; /* BB message operated on */
unsigned long Time; /* getTick() when operated on */
int State; /* What was being done to the message */
} XactHistStruct;
#define XACT_HIST_STATE_QUEUE 0 /* Some task queued a transaction */
#define XACT_HIST_STATE_TX 1 /* Transmitter sent a transaction */
#define XACT_HIST_STATE_RX 2 /* Receiver received a response */
#define XACT_HIST_STATE_WD_TIMEOUT 3 /* Watchdog times out a transaction */
#define XACT_HIST_STATE_RESET 4 /* No message... link was reset */
#define XACT_HIST_STATE_RX_UNSOLICITED 5 /* RX'd message not solicited */
#define XACT_HIST_STATE_RX_ABORT 6 /* RX task got a link about status */
#define XACT_HIST_STATE_TX_ABORT 7 /* TX task got a link about status */
#define XACT_HIST_STATE_RX_URCMD 8 /* RX task got unsolicited RCMD */
#define XACT_HIST_STATE_TX_RESET 9 /* TX task got a link about status */
#define XACT_HIST_STATE_TX_STUCK 10 /* TX fifo is stuck on the 8044 */
/* One of these is allocated for each bitbus link */
typedef struct HistoryStruct
{
SEM_ID sem; /* Use when 'making' history */
XactHistStruct Xact[BB_SUPER_DEBUG_HIST_SIZ];
int Next; /* Next history slot to use */
unsigned long Num; /* Total history messages */
} HistoryStruct;
static int BBSetHistEvent(int link, struct dpvtBitBusHead *pXact, int State);
#endif
/******************************************************************************
*
* The BUSY/IDLE notion is used to count the number of outstanding
* messages for a specific node. The idea is that up to BUSY messages
* can be sent to a node before waiting before deciding not to send any more.
* According to the BitBus specs, this value is 7. However, it also
* states that responses can come back out of order. If this is even true
* for messages sent to the SAME TASK ON THE SAME NODE, the received messages
* CAN NOT be routed back to their initiators properly. Because the node#
* and task# is all we have to identify what a response message is for,
* I am limiting the per-node maximum to 1.
*
******************************************************************************/
#define BB_BUSY 1 /* deviceStatus value if device is currently busy */
#define BB_IDLE 0 /* deviceStatus value if device is currently idle */
/******************************************************************************
*
* This list structure is used in the bitbus driver to represent its queues.
*
******************************************************************************/
struct bbList {
struct dpvtBitBusHead *head; /* head of the linked list */
struct dpvtBitBusHead *tail; /* tail of the linked list */
int elements; /* holds number of elements on the list */
SEM_ID sem; /* semaphore for the queue list */
};
/*****************************************************************************
* Memory Map of XVME-402 BITBUS CARD
*
* This board is rather stupid in that it wastes a whole Kilo of space
* for its 5 1-byte regs. So the dm* fields in the structure below are
* for those filler locations.
*
*****************************************************************************/
typedef struct XycomBBRegsStruct {
unsigned char dm0;
unsigned char stat_ctl;
unsigned char dm2;
unsigned char int_vec;
unsigned char dm4;
unsigned char data;
unsigned char dm6;
unsigned char cmnd;
unsigned char dm8;
unsigned char fifo_stat;
unsigned char dmA[1014]; /* Board occupies 1024 bytes in memory*/
} XycomBBRegsStruct;
#define XYCOM_BB_MAX_OUTSTAND_MSGS 4 /* per-link max pending messages */
#define RESET_POLL_TIME 10 /* time to sleep when waiting on a link abort */
#define BB_SEND_CMD 0x0 /* command to initiate sending of msg */
#define XVME_ENABLE_INT 0x08 /* Allow xvme interupts */
#define XVME_TX_INT 0x20 /* int enable TX only */
#define XVME_TX_PEND 0x10 /* transmit interrupt currently pending */
#define XVME_RX_INT 0x80 /* int exable RX only */
#define XVME_RX_PEND 0x40 /* receive interrupt currently pending */
#define XVME_NO_INT 0 /* disable all interrupts */
/******************************************************************************
*
* Fifo status register format for Xycom board
*
* +----+----+----+----+----+----+----+----+
* | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Bits
* +----+----+----+----+----+----+----+----+
* "1" "1" RCMD RFNE "1" "1" "1" TFNF data
*
* RCMD = "1"= command received ( end of message )
* "0"= No command
*
* RFNE = "1" = Receive Fifo Not Empty
* "0" = Receive Fifo empty
*
* TFNF = "1" = Transmit Fifo Not Full
* "0" = transmit fifo full
*
* NOTE:
* A write to bit 7 of the Fifo status register can be used to reset the
* xvme board.
*
*****************************************************************************/
#define XVME_RCMD 0x20 /* Command has been received */
#define XVME_RFNE 0x10 /* Receive Fifo is Not Empty */
#define XVME_TFNF 0x01 /* Transmit FIFO is Not Full */
#define XVME_FSVALID 0x31 /* these are the only valid status bits */
#define XVME_FSIDLE 0x01 /* fifo_stat & FSVALID = 0x1 when it is idle */
#define XVME_RESET 0x80 /* Write this and you reset the XVME card */
/******************************************************************************
*
* The XycomBBLinkStruct structure holds all the xvme-card specific data
* required for the operation of the link.
*
******************************************************************************/
typedef struct XycomBBLinkStruct {
volatile XycomBBRegsStruct *bbRegs;/* pointer to board registers */
SEM_ID rxInt; /* given when rx interrupts occur */
} XycomBBLinkStruct;
/****************************************************************************
* Memory Map of PEP Modular PB-BIT BITBUS CARD
*
* This board is rather stupid in that it wastes a bunch of bytes
* for its regs. So the dm* fields in the structure below are
* for those filler locations.
*
***************************************************************************/
typedef struct PepBBRegsStruct {
unsigned char dm0;
unsigned char data;
unsigned char dm2;
unsigned char stat_ctl;
unsigned char dm[29];
unsigned char int_vec;
} PepBBRegsStruct;
/******************************************************************************
*
* status register format for PEP's PB-BIT board
*
* +----+----+----+----+----+----+----+----+
* | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Bits
* +----+----+----+----+----+----+----+----+
* X X X STF LBP TFF RFNE IRQP
*
* STF = "1"= self-test failed
* "0"= passed
*
* LBP = "1"= last data byte was last of package
* "0"= 1+ bytes left
*
* TFF = "1"= only one more byte may be written to TFIFO
* "0"= 1+ more bytes may be written
*
* RFNE = "1"= Receive Fifo Not Empty
* "0"= Receive Fifo empty
*
* IRQP = "1"= no irq pending
* "0"= irq pending
*
*
*****************************************************************************/
#define PEP_BB_RCMD 0x08 /* Command has been received */
#define PEP_BB_RFNE 0x02 /* Receive Fifo is Not Empty */
#define PEP_BB_TFNF 0x04 /* Transmit FIFO is Not Full */
#define PEP_BB_FSVALID 0x1f /* these are the only valid status bits */
/******************************************************************************
*
* The PepBBLinkStruct structure holds all the card specific data required for
* the operation of the link.
*
******************************************************************************/
typedef struct PepBBLinkStruct {
volatile PepBBRegsStruct *bbRegs; /* pointer to board registers */
SEM_ID rxInt; /* given when rx interrupts occur */
} PepBBLinkStruct;
/*****************************************************************************
*
* Holds the user-configured board addresses etc. These MUST be set before
* the driver is initialized. And may not be changed after the init phase.
*
* NOTE:
* The setting of these items is intended to be done via records in the future.
*
* The busyList.sem is used to lock the busyList as well as the deviceStatus
* table.
*
*****************************************************************************/
typedef struct BitbusLinkStruct
{
unsigned long LinkType; /* Type of link (XYCOM, PEP,...) */
unsigned long BaseAddr; /* Base address within A16 */
unsigned long IrqVector; /* Irq vector base */
unsigned long IrqLevel; /* Irq level */
WDOG_ID watchDogId; /* watchdog for timeouts */
SEM_ID watchDogSem; /* set by the watch dog int handler */
unsigned char abortFlag; /* set to 1 if link is being reset by the dog */
unsigned char txAbortAck; /* set to 1 by txTask to ack abort Sequence */
unsigned char rxAbortAck; /* set to 1 by rxTask to ack abort Sequence */
int nukeEm; /* manual link restart flag */
SEM_ID linkEventSem; /* given when this link requires service */
struct bbList queue[BB_NUM_PRIO]; /* prioritized request queues */
struct bbList busyList; /* messages waiting on a response */
unsigned char deviceStatus[BB_APERLINK];/* mark a device as idle or busy */
unsigned long syntheticDelay[BB_APERLINK]; /* holds the wakeup time for 91-delays */
int DelayCount; /* holds total number of syntheticDelays in progress */
union
{
PepBBLinkStruct PepLink;
XycomBBLinkStruct XycomLink;
} l;
#ifdef BB_SUPER_DEBUG
HistoryStruct History;
#endif
} BitbusLinkStruct;
#define BB_CONF_HOSED 0 /* Link is not present */
#define BB_CONF_TYPE_XYCOM 1 /* Link is a Xycom board */
#define BB_CONF_TYPE_PEP 2 /* Link is a PEP board */
#endif

View File

@@ -1,43 +0,0 @@
/* share/src/drv/drvBitBusErr.h $Id$ */
/* Author: John Winans
* Date: 12-5-91
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 12-05-91 jrw Written
*/
#ifndef BITBUS_ERRORS
#define BITBUS_ERRORS
#include <errMdef.h> /* pick up the M_bitbus value */
#define S_BB_ok (M_bitbus|0| 0<<1) /* success */
#define S_BB_badPrio (M_bitbus|1| 1<<1) /* Invalid xact request queue priority */
#define S_BB_badlink (M_bitbus|1| 2<<2) /* Invalid bitbus link number */
#define S_BB_rfu2 (M_bitbus|1| 3<<2) /* reserved for future use #2 */
#define S_BB_rfu3 (M_bitbus|1| 4<<2) /* reserved for future use #3 */
#define S_BB_rfu4 (M_bitbus|1| 5<<2) /* reserved for future use #4 */
#endif

View File

@@ -1,273 +0,0 @@
/* drvBitBusInterface.h */
/* share/src/drv %W% %G% */
/* Author: John Winans
* Date: 09-10-91
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 09-30-91 jrw Written
* .02 12-02-91 jrw Added errMessage support
* .03 12-10-91 jrw moved in some stuff in from drvBitBus.h
*/
#ifndef BITBUS_INTERFACE
#define BITBUS_INTERFACE
#include <drvBitBusErr.h>
int drvBitBusDumpMsg();
#define BB_APERLINK 256 /* node 255 is the master */
#define BB_Q_LOW 0
#define BB_Q_HIGH 1
#define BB_NUM_PRIO 2 /* total number of priorities */
struct drvBitBusEt {
long number;
DRVSUPFUN report; /* Report on the status of the Bit Bus links */
DRVSUPFUN init; /* Init the xvme card */
DRVSUPFUN qReq; /* Queue a transaction request */
};
#define BB_MSG_HEADER_SIZE 7
#define BB_MAX_DAT_LEN 13 /* message data len on 8044 */
#define BB_MAX_MSG_LENGTH BB_MSG_HEADER_SIZE + BB_MAX_DAT_LEN
/* BitBus Transaction Message Structure */
struct bitBusMsg {
unsigned short link; /* account for this in length only! */
unsigned char length;
unsigned char route;
unsigned char node;
unsigned char tasks;
unsigned char cmd;
unsigned char *data;
};
/******************************************************************************
*
* Any I/O request made must consist of a structure that begins with the
* following fields.
*
******************************************************************************/
struct dpvtBitBusHead {
int (*finishProc)(); /* callback task invoked in not NULL with RX */
int priority; /* callback task priority */
SEM_ID *psyncSem; /* if not NULL, points to sem given w/RX */
struct dpvtBitBusHead *next; /* used to link dpvt's together */
struct dpvtBitBusHead *prev; /* used to link dpvt's together */
int link; /* xvme link number */
struct bitBusMsg txMsg; /* message to transmit on the link */
struct bitBusMsg rxMsg; /* response from the node */
int rxMaxLen; /* max length of the receive buffer */
int status; /* message xfer status */
unsigned char rxCmd; /* the command byte that signaled message end */
int ageLimit; /* Set in to max allowed age */
unsigned long retire; /* used by the driver to time out xacts */
};
/******************************************************************************
*
* Valid dpvtHead.status from the driver are:
*
******************************************************************************/
#define BB_OK 0 /* all went as expected */
#define BB_LENGTH 1 /* received message overflowed the buffer */
#define BB_NONODE 2 /* transmit message to non-existant node */
#define BB_TIMEOUT 3 /* response took too long from node */
#if 0 /* JRW moved to drvBitbus.h */
/******************************************************************************
*
* The BUSY/IDLE notion is used to count the number of outstanding
* messages for a specific node. The idea is that up to BUSY messages
* can be sent to a node before waiting before deciding not to send any more.
* According to the BitBus specs, this value is 7. However, it also
* states that responses can come back out of order. If this is even true
* for messages sent to the SAME TASK ON THE SAME NODE, the received messages
* CAN NOT be routed back to their initiators properly. Because the node#
* and task# is all we have to identify what a response message is for,
* I am limiting the per-node maximum to 1.
*
******************************************************************************/
#define BB_BUSY 1 /* deviceStatus value if device is currently busy */
#define BB_IDLE 0 /* deviceStatus value if device is currently idle */
struct bbList {
struct dpvtBitBusHead *head; /* head of the linked list */
struct dpvtBitBusHead *tail; /* tail of the linked list */
int elements; /* holds number of elements on the list */
SEM_ID sem; /* semaphore for the queue list */
};
/******************************************************************************
*
* The bbLink structure holds all the required link-specific queueing
* information.
*
******************************************************************************/
struct bbLink {
int linkType; /* the type of link (defined in link.h) */
int linkId; /* the link number of this structure */
int nukeEm; /* manual link restart flag */
SEM_ID linkEventSem; /* given when this link requires service */
struct bbList queue[BB_NUM_PRIO]; /* prioritized request queues */
/*
* In order to modify either the busyList entries or the deviceStatus
* table, the busyList.sem MUST be held first.
*/
struct bbList busyList; /* messages waiting on a response */
unsigned char deviceStatus[BB_APERLINK];/* mark a device as idle or busy */
};
#endif
#define BB_STANDARD_TX_ROUTE 0x40 /* Route value for TX message */
#define BB_RAC_TASK 0x00 /* RAC task ID */
#define BB_GPIB_TASK 0x01 /* GPIB task ID */
#define BB_232_TASK 0x01 /* RS232 task ID */
/******************************************************************************
*
* Common commands that are supported by all non-RAC tasks.
*
******************************************************************************/
#define BB_IDENTIFY 0x00 /* request ID word */
#define BB_ID_GPIB 1
#define BB_ID_232 2
#define BB_MOD_NONE 0 /* task not altered */
#define BB_MOD_DIG500 1 /* task altered to talk to DIG500 */
struct bbIdWord {
unsigned int taskType; /* One of BB_ID_* */
unsigned int taskMods; /* One of BB_MOD_* */
unsigned int revCode; /* Revision code number of the BUG's code */
};
/******************************************************************************
*
* List of GPIB command definitions (defined by the GPIB-BUG interface spec)
*
******************************************************************************/
#define BB_232_CMD 0x60 /* or'd with the port number */
#define DD_232_PORT 0x1F /* port number is lowest 5 bits */
#define BB_232_BREAK 0x40 /* or'd with the port number */
/******************************************************************************
*
* List of GPIB command definitions (defined by the GPIB-BUG interface spec)
*
******************************************************************************/
#define BB_IBCMD_IFC 1 /* set IFC for about 1/2 second */
#define BB_IBCMD_READ 2 /* read <=13 bytes from GPIB */
#define BB_IBCMD_WRITE 3 /* write <=13 bytes to GPIB */
#define BB_IBCMD_WRITE_EOI 4 /* write <=13 bytes w/EOI on last */
#define BB_IBCMD_WRITE_CMD 5 /* write <=13 bytes w/ATN high */
#define BB_IBCMD_SET_TMO 6 /* set the timeout delay value */
/* For the sake of completeness, an or-mask for the non-addressable commands */
#define BB_IBCMD_NOADDR 0x00 /* non-addressed command group */
/* to use the following commands, or the decice address with the command */
#define BB_IBCMD_WRITE_XACT 0x20 /* cmd|address writes 13 w/EOI */
#define BB_IBCMD_ADDR_WRITE 0x40 /* cmd|address writes 13 bytes */
#define BB_IBCMD_READ_XACT 0x60 /* cmd|address wite 13 & read back */
/*
* The status response bits to a GPIB command are set as follows:
*
* 7 - UNDEF
* 6 - UNDEF
* 5 - 1 if read ended with EOI
* 4 - 1 if SRQ is currently HIGH
* 3 - UNDEF
* 2 - UNDEF
* 1 - UNDEF
* 0 - 1 if timeout occurred
*/
#define BB_IBSTAT_EOI 0x20
#define BB_IBSTAT_SRQ 0x10
#define BB_IBSTAT_TMO 0x01
/******************************************************************************
*
* Partial List of RAC Command Definitions (defined in BitBus Specification)
*
******************************************************************************/
#define RAC_RESET_SLAVE 0x00
#define RAC_CREATE_TASK 0x01
#define RAC_DELETE_TASK 0x02
#define RAC_GET_FUNC_IDS 0x03
#define RAC_PROTECT 0x04
#define RAC_READ_IO 0x05
#define RAC_WRITE_IO 0x06
#define RAC_UPDATE_IO 0x07
#define RAC_UPLOAD_MEM 0x08
#define RAC_DOWNLOAD_MEM 0x09
#define RAC_OR_IO 0x0A
#define RAC_AND_IO 0x0B
#define RAC_XOR_IO 0x0C
#define RAC_STATUS_READ 0x0D
#define RAC_STATUS_WRITE 0x0E
#define RAC_NODE_INFO 0x0F
#define RAC_OFFLINE 0x10
#define RAC_UPLOAD_CODE 0x11
#define RAC_DOWNLOAD_CODE 0x12
/* Reply message Command Byte Definitions */
#define BB_NO_ERROR 0x00
/* 0x01 thru 0x7F are user defined */
#define BB_SEND_TMO 0x70
/* 0x80 thru 0xFF are defined by BitBus */
#define BB_NO_DEST_TASK 0x80
#define BB_TASK_OVERFLOW 0x81
#define BB_REG_BANK_OVERFLOW 0x82
#define BB_DUP_FUNC_ID 0x83
#define BB_NO_BUFFERS 0x84
#define BB_PROTOCOL_ERR 0x91
#define BB_NO_DEST_DEV 0x93
#define BB_RAC_PROTECTED 0x95
#define BB_UNKNOWN_RAC_CMND 0x96
#endif

View File

@@ -1,636 +0,0 @@
/* comet_driver.c */
/* base/src/drv $Id$ */
/*
* Author: Leo R. Dalesio
* Date: 5-92
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 joh 071092 added argument to calloc()
* .02 joh 071092 stripped the hkv2f specific portion off the comet
* std addr base specification and left it at base
* addr zero which is most likely wrong.
* .03 joh 071492 use extended (A32) address space
* instead of standard (A24) address space
* for the base address of the waveform memory
* (changed arg to sysBusToLocalAdrs()
* .04 joh 071592 fixed to use correct size when incrementing
* to the waveform memory of the second card
* .05 joh 071592 modified A16 & A32 base addr to match AT8
* address standard
* .06 bg 071792 moved addresses to module_types.h
* .07 joh 080592 added io report routines
* .08 ms 080692 added comet_mode routine, modified comet_driver
* and cometDoneTask to allow an external routine
* to control hardware scan mode. Added variable
* scan_control to flag operating mode.
* .09 mrk 082692 added DSET
* .10 joh 082792 fixed uninitialized csr pointer in comet_driver()
* function
* .11 lrd 091692 add signal support
* .12 joh 092992 card number validation now based on module_types.h.
* signal number checking now based on the array element
* count.
* .13 mrk 080293 Added call to taskwdInsert
* .14 mgb 080493 Removed V5/V4 and EPICS_V2 conditionals
*/
static char *sccsID = "@(#)drvComet.c 1.11\t9/16/92";
/*
* Code Portions
*
* comet_init()
* comet_driver(card, pcbroutine, parg)
* cometDoneTask()
* comet_io_report()
* comet_mode(card,mode,arg,val)
*
*/
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <iv.h>
#include <module_types.h>
#include <task_params.h>
#include <fast_lock.h>
#include <vme.h>
#include <drvSup.h>
#include <dbDefs.h>
#include <dbScan.h>
#include <taskwd.h>
#define COMET_NCHAN 4
#define COMET_CHANNEL_MEM_SIZE 0x20000 /* bytes */
#define COMET_DATA_MEM_SIZE (COMET_CHANNEL_MEM_SIZE*COMET_NCHAN)
static short scan_control; /* scan type/rate (if >0 normal, <=0 external control) */
/* comet conrtol register map */
struct comet_cr{
unsigned char csrh; /* control and status register - high byte */
unsigned char csrl; /* control and status register - low byte */
unsigned char lcrh; /* location status register - high byte */
unsigned char lcrl; /* location status register - low byte */
unsigned char gdcrh; /* gate duration status register - high byte*/
unsigned char gdcrl; /* gate duration status register - low byte */
unsigned char cdr; /* channel delay register */
unsigned char acr; /* auxiliary control register */
char pad[0x100-8];
};
/* defines for the control status register - high byte */
#define DIGITIZER_ACTIVE 0x80 /* 1- Active */
#define ARM_DIGITIZER 0x40 /* 1- Arm the digitizer */
#define CIRC_BUFFER_ENABLED 0x20 /* 0- Stop when memory is full */
#define WRAP_MODE_ENABLED 0x10 /* 0- Disable wrap around */
#define AUTO_RESET_LOC_CNT 0x08 /* 1- Reset addr to 0 on trigger */
#define EXTERNAL_TRIG_ENABLED 0x04 /* 1- use external clk to trigger */
#define EXTERNAL_GATE_ENABLED 0x02 /* 0- use pulse start conversion */
#define EXTERNAL_CLK_ENABLED 0x01 /* 0- uses the internal clock */
/* commands for the COMET digitizer */
#define COMET_INIT_CSRH
#define COMET_INIT_READ
/* mode commands for the COMET digitizer */
#define READREG 0
#define WRITEREG 1
#define SCANCONTROL 2
#define SCANSENSE 3
#define SCANDONE 4
/* register selects */
#define COMET_CSR 0
#define COMET_LCR 1
#define COMET_GDCR 2
#define COMET_CDACR 3
/* defines for the control status register - low byte */
#define SOFTWARE_TRIGGER 0x80 /* 1- generates a software trigger */
#define UNUSED 0x60
#define CHAN_DELAY_ENABLE 0x10 /* 0- digitize on trigger */
#define DIG_RATE_SELECT 0x0f
/* digitizer rates - not defined but available for 250KHz to 122Hz */
#define COMET_5MHZ 0x0000
#define COMET_2MHZ 0x0001
#define COMET_1MHZ 0x0002
#define COMET_500KHZ 0x0003
/* defines for the auxiliary control register */
#define ONE_SHOT 0x10
#define ALL_CHANNEL_MODE 0x80
/* comet configuration data */
struct comet_config{
struct comet_cr *pcomet_csr; /* pointer to the control/status register */
unsigned short *pdata; /* pointer to data area for this COMET card */
void (*psub)(); /* subroutine to call on end of conversion */
void *parg[4]; /* argument to return to the arming routine */
FAST_LOCK lock; /* mutual exclusion lock */
IOSCANPVT ioscanpvt;
unsigned long nelements; /* number of elements to digitize/read */
};
/* task ID for the comet done task */
int cometDoneTaskId;
struct comet_config *pcomet_config;
static long report();
static long init();
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvComet={
2,
report,
init};
/*
* cometDoneTask
*
* wait for comet waveform record cycle complete
* and call back to the database with the waveform size and address
*
*/
void
cometDoneTask()
{
register unsigned card;
register struct comet_config *pconfig;
while(TRUE)
{
if (scan_control <= 0)
taskDelay(2);
else
{
taskDelay(scan_control);
/* printf("DoneTask: entering for loop...\n"); */
/* check each card for end of conversion */
for(card=0, pconfig = pcomet_config; card < 2;card++, pconfig++)
{
/* is the card present */
if (!pconfig->pcomet_csr)
{
if (card == 0)
{
/*
printf("DoneTask: checking card present?...\n");
printf("DoneTask: pconfig->pcomet_csr %x...\n",pconfig->pcomet_csr);
*/
}
continue;
}
/* is the card armed */
if (!pconfig->psub)
{
if (card == 0)
{
/* printf("DoneTask: checking card armed?...\n"); */
}
continue;
}
/* is the digitizer finished conversion */
/* printf("pconfig->pdata: %x \n", pconfig->pdata); */
if (*(pconfig->pdata+pconfig->nelements) == 0xffff)
{
if (card == 0)
{
/* printf("DoneTask: finished conversion?...\n"); */
}
continue;
}
/* printf("DoneTask: pcomet_config->pcomet_csr %x...\n",pcomet_config->pcomet_csr); */
/* printf("DoneTask: DONE\n"); */
#if 0
/* reset each of the control registers */
pconfig->pcomet_csr->csrh = pconfig->pcomet_csr->csrl = 0;
pconfig->pcomet_csr->lcrh = pconfig->pcomet_csr->lcrl = 0;
pconfig->pcomet_csr->gdcrh = pconfig->pcomet_csr->gdcrl = 0;
pconfig->pcomet_csr->acr = 0;
#endif
/* clear the pointer to the subroutine to allow rearming */
/* pconfig->psub = NULL; */
/* post the event */
/* - is there a bus error for long references to this card?? copy into VME mem? */
if(pconfig->parg[0])
{
(*pconfig->psub)(pconfig->parg[0],pconfig->pdata);
}
if(pconfig->parg[1])
{
(*pconfig->psub)(pconfig->parg[1],(((char*)pconfig->pdata)+0x20000));
}
if(pconfig->parg[2])
{
(*pconfig->psub)(pconfig->parg[2],(((char*)pconfig->pdata)+0x40000));
}
if(pconfig->parg[3])
{
(*pconfig->psub)(pconfig->parg[3],(((char*)pconfig->pdata)+0x60000));
}
}
}
}
}
/*
* COMET_INIT
*
* intialize the driver for the COMET digitizer from omnibyte
*
*/
int comet_init()
{
register struct comet_config *pconfig;
short readback,got_one,card;
int status;
struct comet_cr *pcomet_cr;
unsigned char *extaddr;
/* free memory and delete tasks from previous initialization */
if (cometDoneTaskId)
{
taskwdRemove(cometDoneTaskId);
if ((status = taskDelete(cometDoneTaskId)) < 0)
logMsg("\nCOMET: Failed to delete cometDoneTask: %d",status);
}
else
{
pcomet_config = (struct comet_config *)calloc(wf_num_cards[COMET],sizeof(struct comet_config));
if (pcomet_config == 0)
{
logMsg("\nCOMET: Couldn't allocate memory for the configuration data");
return(0);
}
}
/* get the standard and short address locations */
if ((status = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,wf_addrs[COMET],&pcomet_cr)) != OK){
logMsg("\nCOMET: failed to map VME A16 base address\n");
return(0);
}
if ((status = sysBusToLocalAdrs(VME_AM_EXT_SUP_DATA,wf_memaddrs[COMET],&extaddr)) != OK){
logMsg("\nCOMET: failed to map VME A32 base address\n");
return(0);
}
/* determine which cards are present */
got_one = FALSE;
pconfig = pcomet_config;
for ( card = 0;
card < 2;
card++, pconfig++, pcomet_cr++, extaddr+= COMET_DATA_MEM_SIZE){
/* is the card present */
if (vxMemProbe(pcomet_cr,READ,sizeof(readback),&readback) != OK)
{
continue;
}
if (vxMemProbe(extaddr,READ,sizeof(readback),&readback) != OK)
{
logMsg("\nCOMET: Found CSR but not data RAM %x\n",extaddr);
continue;
}
/* initialize the configuration data */
pconfig->pcomet_csr = pcomet_cr;
pconfig->pdata = (unsigned short *) extaddr;
got_one = TRUE;
FASTLOCKINIT(&pcomet_config[card].lock);
/* initialize the card */
pcomet_cr->csrh = ARM_DIGITIZER | AUTO_RESET_LOC_CNT;
pcomet_cr->csrl = COMET_1MHZ;
pcomet_cr->lcrh = pcomet_cr->lcrl = 0;
pcomet_cr->gdcrh = 0;
pcomet_cr->gdcrl = 1;
pcomet_cr->cdr = 0;
/* run it once */
pcomet_cr->csrl |= SOFTWARE_TRIGGER;
taskDelay(1);
/* reset */
pcomet_cr->csrl = COMET_5MHZ;
pcomet_cr->acr = ONE_SHOT | ALL_CHANNEL_MODE;
scanIoInit(&pconfig->ioscanpvt);
} /*end of for loop*/
/* initialization for processing comet digitizers */
if(got_one)
{
/* start the waveform readback task */
scan_control = 2; /* scan rate in vxWorks clock ticks */
cometDoneTaskId = taskSpawn("cometWFTask",WFDONE_PRI,WFDONE_OPT,WFDONE_STACK,(FUNCPTR) cometDoneTask);
taskwdInsert(cometDoneTaskId,NULL,NULL);
}
return(0);
}
static long report(level)
int level;
{
comet_io_report(level);
return(0);
}
static long init()
{
comet_init();
return(0);
}
/*
* COMET_DRIVER
*
* initiate waveform read
*
*/
int comet_driver(card, signal, pcbroutine, parg, nelements)
register short card;
register unsigned short signal;
unsigned int *pcbroutine;
unsigned int *parg; /* pointer to the waveform record */
unsigned long nelements;
{
register struct comet_cr *pcomet_csr;
register struct comet_config *pconfig;
/* printf("comet_driver: BEGIN...\n"); */
/* printf("comet_driver: nelements: %d ...\n",nelements); */
/* check for valid card number */
if(card >= wf_num_cards[COMET])
return ERROR;
pconfig = (pcomet_config+card);
if(signal >= NELEMENTS(pconfig->parg))
return ERROR;
pconfig->nelements = nelements * 2;
/* printf("comet_driver: check for card present...\n"); */
/* check for card present */
if(!pconfig->pcomet_csr) return ERROR;
/* mutual exclusion area */
FASTLOCK(&pconfig->lock);
/* printf("comet_driver: mark the card as armed...\n"); */
/* mark the card as armed */
/* if (pconfig->parg[signal] != 0) */
pconfig->parg[signal] = parg;
/* if (pconfig->psub) return; */
pconfig->psub = (void (*)()) pcbroutine;
/* exit mutual exclusion area */
FASTUNLOCK(&pconfig->lock);
pcomet_csr = pconfig->pcomet_csr;
/* reset each of the control registers */
pcomet_csr->csrh = pcomet_csr->csrl = 0;
pcomet_csr->lcrh = pcomet_csr->lcrl = 0;
pcomet_csr->gdcrh = pcomet_csr->gdcrl = 0;
pcomet_csr->acr = 0;
/* arm the card */
*(pconfig->pdata+pconfig->nelements) = 0xffff;
/* printf("comet_driver: pconfig->pcomet_csr %x...\n",pconfig->pcomet_csr); */
if (scan_control > 0)
{
#if 0 /* for debugging purposes */
pcomet_csr->gdcrh = 0x03; /* # samples per channel */
pcomet_csr->gdcrl = 0xe8; /* # samples per channel */
#endif
pcomet_csr->gdcrh = (pconfig->nelements >> 8) & 0xff; /* # samples per channel */
pcomet_csr->gdcrl = pconfig->nelements & 0xff; /* # samples per channel */
pcomet_csr->acr = ONE_SHOT | ALL_CHANNEL_MODE; /* disarm after the trigger */
pcomet_csr->csrl = COMET_5MHZ; /* sample at 5MhZ */
/* arm, reset location counter to 0 on trigger, use external trigger */
pcomet_csr->csrh = ARM_DIGITIZER | AUTO_RESET_LOC_CNT | EXTERNAL_TRIG_ENABLED;
/* printf("comet_driver: gdcrh: %x gdcrl: %x nelements: %x\n ",pcomet_csr->gdcrh,pcomet_csr->gdcrl, pconfig->nelements); */
}
else
pcomet_csr->csrh |= ARM_DIGITIZER;
/* printf("comet_driver: pconfig->pcomet_csr %x...\n",pconfig->pcomet_csr); */
/* printf("comet_driver: END...\n"); */
return OK;
}
/*
* COMET_IO_REPORT
*
* print status for all cards in the specified COMET address range
*/
int comet_io_report(level)
short int level;
{
struct comet_config *pconfig;
unsigned card;
unsigned nelements;
int status;
pconfig = pcomet_config;
for(card=0; card < wf_num_cards[COMET]; card++){
if(!pconfig->pcomet_csr)
continue;
printf( "WF: COMET:\tcard=%d\n", card);
if (level >= 2){
printf("enter the number of elements to dump:");
status = scanf("%d",&nelements);
if(status == 1){
comet_dump(card, nelements);
}
}
pconfig++;
}
return OK;
}
/*
* comet_dump
*
*/
int comet_dump(card, n)
unsigned card;
unsigned n;
{
unsigned short *pdata;
unsigned short *psave;
unsigned short *pbegin;
unsigned short *pend;
if (card >= wf_num_cards[COMET])
return ERROR;
pdata = pcomet_config[card].pdata;
psave = (unsigned short *) malloc(n * sizeof(*psave));
if(!psave){
return ERROR;
}
pbegin = psave;
pend = &psave[n];
for( pdata = pcomet_config[card].pdata;
psave<pend;
pdata++,psave++){
*psave = *pdata;
}
psave = pbegin;
for( ;
psave<pend;
psave++){
if((psave-pbegin)%8 == 0){
printf("\n\t");
}
printf("%04X ", *psave);
}
printf("\n");
free(pbegin);
return OK;
}
/*
* comet_mode
*
* controls and reports operating mode
*
*/
int comet_mode(card,mode,arg,val)
short card;
unsigned short mode, arg, val;
{
unsigned char *cptr;
if (card >= wf_num_cards[COMET])
return ERROR;
if (!pcomet_config[card].pcomet_csr)
return ERROR;
switch (mode)
{
case READREG:
/*cptr = (unsigned char *)pcomet_config[card].pcomet_csr;
for (i = 0; i < 6; i++, cptr++)
printf("%x %x\n",cptr,*cptr);*/
cptr = (unsigned char *)pcomet_config[card].pcomet_csr; /* point to offset 0 */
cptr += arg<<1; /* build new offset */
val = (*cptr++)<<8; /* read value and return */
val |= *cptr;
return val;
break;
case WRITEREG:
cptr = (unsigned char *)pcomet_config[card].pcomet_csr;
cptr += arg<<1;
*cptr++ = val>>8;
*cptr = val;
break;
case SCANCONTROL:
scan_control = val;
break;
case SCANSENSE:
return scan_control;
break;
case SCANDONE:
if (!pcomet_config[card].psub)
return ERROR;
/*pcomet_config[card].psub = NULL;*/ /* clear the pointer to subroutine to allow rearming */
(*pcomet_config[card].psub)(pcomet_config[card].parg,0xffff,pcomet_config[card].pdata);
break;
default:
return ERROR;
}
return OK;
}
/*********************************************/
int cometGetioscanpvt(card,scanpvt)
short card;
IOSCANPVT *scanpvt;
{
register struct comet_config *pconfig;
pconfig=pcomet_config;
pconfig+=card;
if ((card >= wf_num_cards[COMET]) || (card < 0)) /* make sure hardware exists */
return(0);
/*
This is present in the mix driver...I don't know if I really need it.
if (!pconfig->present)
return(0);
*/
*scanpvt = pconfig->ioscanpvt;
return(0);
}

View File

@@ -1,868 +0,0 @@
/* drvCompuSm.c */
/* base/src/drv $Id$ */
/*
* subroutines and tasks that are used to interface to the Compumotor 1830
* stepper motor drivers
*
* Author: Bob Dalesio
* Date: 01-03-90
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 02-07-90 lrd add command to read the motor status
* .02 04-11-90 lrd made velocity mode motor go active
* .03 04-12-90 lrd only allow one connection to a motor
* .04 04-13-90 lrd add externally initiated motor motion monitoring
* .05 09-05-91 joh updated for v5 vxWorks
* .06 10-09-91 lrd monitor for external motion once every 2 seconds
* not at 30 Hz (.04 was not implemented correctly)
* .06 11-31-91 bg added compu_sm_io_report. Added sysBusToLocalAdrs()
* for addressing.
* .07 03-02-92 bg added level and ability to print raw values to
* compu_sm_io_report for level > 0.
* .08 05-04-92 bg added compu_sm_reset and rebootHookAdd so ioc can be
* rebooted with control X.
* .09 06-25-92 bg Combined drvCompuSm.c and compu_sm_driver.c
* .10 06-26-92 bg Added level to compu_sm_io_report in drvCompuSm
* structure
* .11 06-29-92 joh took file ptr arg out of io report
* .12 08-06-92 joh merged compu sm include file
* .13 08-27-92 joh silenced ANSI C function proto warning
* .14 08-27-92 joh fixed no epics init
* .15 08-02-93 mrk Added call to taskwdInsert
* .16 10-29-93 jba Fixed max number of cards to use module_types.c
* Fixed error in calculating card addresses
* .17 04-09-96 ric Added SM_FIND_LIMIT, SM_FIND_HOME
*/
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <vme.h>
#include <semLib.h> /* library for semaphore support */
#include <intLib.h> /* library for semaphore support */
#include <vxLib.h> /* library for semaphore support */
#include <rebootLib.h> /* library for semaphore support */
#include <wdLib.h>
#include <rngLib.h> /* library for ring buffer support */
/* drvCompuSm.c - Driver Support Routines for CompuSm */
#include <dbDefs.h>
#include <epicsPrint.h>
#include <drvSup.h>
#include <module_types.h>
#include <steppermotor.h>
#include <task_params.h>
#include <taskwd.h>
long compu_sm_io_report();
long compu_driver_init();
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvCompuSm={
2,
compu_sm_io_report,
compu_driver_init};
/* compumotor vme interface information */
#define MAX_COMPU_MOTORS 8
#define RESP_SZ 16 /* card returns 16 chars - cmd & resp */
#define RESPBUF_SZ (RESP_SZ+1) /* intr routine also passes motor no. */
/* Control Byte bit definitions for the Compumotor 1830 */
/* bits 0 and 1 are not used */
#define CBEND 0x04 /* end of command string */
#define CBLMR 0x08 /* last message byte read */
#define CBCR 0x10 /* command ready in cm_idb */
#define CBMA 0x20 /* message accepted from odb */
#define CBEI 0x40 /* enable interrupts */
#define CBBR 0x80 /* board reset */
#define SND_MORE CBCR | CBEI /* more chars to send */
#define SND_LAST CBEND | SND_MORE /* last char being sent */
#define RD_MORE CBMA | CBEI /* more chars to read */
#define RD_LAST CBLMR | RD_MORE /* last byte we need to read */
/* Status Byte bit definitions */
#define SBIRDY 0x10 /* idb is ready */
/* Structure used for communication with a Compumotor 1830
** Motor Controller. The data buffer is repeated 64 times
** on even word addresses (0xXXXXXX1,0xXXXXX5...) and the
** control location is repeated 64 times on odd word
** addresses (0xXXXXX3, 0xXXXXX7...). The registers must
** be read and written as bytes.
*/
struct compumotor {
char cm_d1; /* not accessable */
char cm_idb; /* input data buffer */
char cm_d2; /* not accessable */
char cm_cb; /* control byte */
char cm_d3[0x100-4]; /* fill to next standard address */
};
/* This file includes defines for all compumotor 1830 controller
** commands. */
#define SM_NULL 0x0 /* Null command */
#define SM_INT 0x1 /* Interrupt X */
#define SM_WRT_STAT 0x8 /* Write X to the user defined status bits */
#define SM_SET_STAT 0x9 /* Set user defined status bit number X */
#define SM_CLR_STAT 0xa /* Clear user defined status bit number X */
#define SM_SET_PROG 0xb /* Set programmable output bit X */
#define SM_CLR_PROG 0xc /* Clear programmable output bit X */
#define SM_WRT_PROG 0xd /* Write X to the programmable output bits */
#define SM_DEF_X_TO_Y 0xf /* Define bit X to indicate state Y */
#define SM_TOG_JOG 0x10 /* Disable/enable the JOG inputs */
#define SM_DEF_JOG 0x11 /* Define JOG input functions */
#define SM_TOG_REM_PWR 0x12 /* Turn off/on remote power shutdown */
#define SM_TOG_REM_SHUT 0x13 /* Disable/enable the "remote shutdown" bit */
#define SM_SET_CW_MOTN 0x14 /* Set CW motion equal to +- */
#define SM_TOG_POS_MTN 0x18 /* Turn off/on post-move position maintenance */
#define SM_TOG_STOP_STL 0x19 /* Turn off/on termination on stall detect */
#define SM_REP_X_Y 0x20 /* Repeat the following X commands Y times */
#define SM_REP_TIL_CONT 0x21 /* Repeat the following X commands
until a CONTINUE is received */
#define SM_WAIT_CONT 0x28 /* Wait for a CONTINUE */
#define SM_WAIT_MILLI 0x29 /* Wait X milliseconds */
#define SM_WAIT_SECOND 0x2a /* Wait X seconds */
#define SM_WAIT_MINUTE 0x2b /* Wait X minutes */
#define SM_WAIT_TRIGGER 0x2c /* Wait for trigger X to go active */
#define SM_DEF_A_OP_POS 0x2e /* Define the abs open-loop position as X */
#define SM_DEF_A_CL_POS 0x2f /* Define absolute closed-loop position */
#define SM_DEF_ABS_ZERO 0x30 /* Define the present position as the
absolute zero position */
#define SM_DEF_VEL_ACC 0x31 /* Define default velocity and acceleration */
#define SM_MOV_DEFAULT 0x32 /* Perform the default move (trapezoidal
continuous) */
#define SM_MOV_REL_POS 0x33 /* Go to relative position X at default
velocity and acceleration */
#define SM_MOV_ABS_POS 0x34 /* Go to absolute position X at default
velocity and acceleration */
#define SM_MOV_REL_ENC 0x35 /* Go to relative encoder position X */
#define SM_MOV_ABS_ENC 0x36 /* Go to absolute encoder position X */
#define SM_DEF_OP_HOME 0x38 /* Define HOME location (open loop */
#define SM_DEF_CL_HOME 0x38 /* Define HOME location (closed loop) */
#define SM_MOV_HOME_POS 0x39 /* Go HOME at the default velocity and
acceleration */
#define SM_MOV_HOME_ENC 0x3a /* Go to encoder HOME at the default
velocity and acceleration */
#define SM_DO_MOV_X 0x40 /* Perform move number X */
#define SM_DO_SEQ_X 0x41 /* Perform sequence buffer X */
#define SM_DO_VEL_STR 0x42 /* Perform the velocity streaming buffer */
#define SM_CONT 0x48 /* CONTINUE (perform next command) */
#define SM_OP_LOOP_MODE 0x50 /* Enter open loop indexer mode */
#define SM_VEL_DIS_MODE 0x51 /* Enter velocity-distance streaming mode */
#define SM_VEL_TIM_MODE 0x52 /* Enter velocity-time streaming mode */
#define SM_STOP 0x70 /* STOP motion */
#define SM_DSC_SEQ 0x71 /* Discontinue the sequence buffer */
#define SM_SSP_SEQ 0x72 /* Suspend the sequence buffer;
wait for a CONTINUE to resume */
#define SM_DSC_SNGL 0x73 /* Discontinue any singular command
currently being performed */
#define SM_STOP_ON_TRG 0x74 /* STOP motion when trigger X goes active */
#define SM_DSC_SEQ_TRG 0x75 /* Discontinue the sequence buffer when
trigger X goes active */
#define SM_SSP_SEQ_TRG 0x76 /* Suspend sequence buffer when trigger
X goes active */
#define SM_DSC_SNGL_TRG 0x77 /* Discontinue any singular command when
trigger X goes active */
#define SM_KILL 0x78 /* Kill motion */
#define SM_KILL_SEQ 0x79 /* Kill the sequence buffer */
#define SM_KILL_SEQ_SNGL 0x7a /* Kill current sequence singular command;
wait for CONTINUE */
#define SM_KILL_VEL_STR 0x7b /* Kill the velocity streaming buffer */
#define SM_KILL_ON_TRG 0x7c /* Kill motion when trigger X goes active */
#define SM_KILL_SEQ_TRG 0x7d /* Kill the sequence buffer when trigger
X goes active */
#define SM_KL_SQSNG_TRG 0x7e /* Kill current sequence singular command
when trigger X goes active; wait for
a continue */
#define SM_KL_VLSTR_TRG 0x7f /* Kill the velocity streaming buffer
when trigger X goes active */
#define SM_GET_B_REL_POS 0x80 /* Request position relative to the
beginning of the current move */
#define SM_GET_E_REL_POS 0x81 /* Request position relative to the
end of the current move */
#define SM_GET_H_REL_POS 0x82 /* Request position relative to the home
limit switch */
#define SM_GET_Z_REL_POS 0x83 /* Request position relative to the
absolute zero position */
#define SM_GET_CUR_DIR 0x84 /* Request current direction */
#define SM_GET_VEL 0x85 /* Request current velocity */
#define SM_GET_ACC 0x86 /* Request current acceleration */
#define SM_GET_MOV_STAT 0x88 /* Request current move status */
#define SM_GET_LIM_STAT 0x89 /* Request state of the limit switches */
#define SM_GET_HOME_STAT 0x8a /* Request state of the HOME switch */
#define SM_GET_TRV_DIR 0x8b /* Request direction of travel */
#define SM_GET_MOT_MOV 0x8c /* Request whether motor is moving or not */
#define SM_GET_MOT_CONST 0x8d /* Request whether motor is at constant,
nonzero velocity or not */
#define SM_GET_MOT_ACC 0x8e /* Request whether motor is or is not
accelerating */
#define SM_GET_MOT_DEC 0x8f /* Request whether motor is or is not
decelerating */
#define SM_GET_MODE 0x90 /* Request present mode */
#define SM_GET_MV_PARM 0x91 /* Request move parameters for move number X */
#define SM_GET_SEQ_CMMD 0x92 /* request commands stored in the
sequence buffer */
#define SM_GET_MVDEF_STAT 0x93 /* Request state of the move definitions */
#define SM_GET_TRG_STAT 0x94 /* Request state of trigger inputs */
#define SM_GET_JOG_STAT 0x95 /* Request state of JOG inputs */
#define SM_GET_Z_STAT 0x96 /* Request state of the Channel Z home input */
#define SM_GET_OUT_STAT 0x97 /* Request the state of the programmable
output bits */
#define SM_GET_REL_ENC 0x98 /* Request relative encoder count */
#define SM_GET_REL_ERR 0x99 /* Request relative error from desired
closed loop position */
#define SM_GET_ABS_ENC 0x9a /* Request absolute encoder count */
#define SM_GET_SLIP_STAT 0x9b /* Request slip detect status */
#define SM_GET_RATIO 0x9c /* Request motor pulse to encoder pulse ratio */
#define SM_GET_RESOLTN 0x9d /* Request motor resolution */
#define SM_GET_BACK_SIG 0x9e /* Request backlash sigma (motor steps)*/
#define SM_GET_ALG 0x9f /* Request position maintenance alg.
const, and max velocity */
#define SM_INT_NXT_MOV 0xa0 /* Interrupt at start of next move */
#define SM_INT_ALL_MOV 0xa1 /* Interrupt at the start of every move */
#define SM_INT_NXT_NZ 0xa2 /* Interrupt at constant nonzero velocity
of next move */
#define SM_INT_ALL_NZ 0xa3 /* Interrupt at constant nonzero velocity
of every move */
#define SM_INT_NXT_END 0xa4 /* Interrupt at next end of motion */
#define SM_INT_ALL_END 0xa5 /* Interrupt at every end of motion */
#define SM_INT_NXT_STL 0xa6 /* Interrupt on next stall detect */
#define SM_INT_ALL_STL 0xa7 /* Interrupt on every stall detect */
#define SM_INT_NXT_PLIM 0xa8 /* Interrupt the next time the motor
hits the positive limit */
#define SM_INT_ALL_PLIM 0xa9 /* Interrupt on every positive limit */
#define SM_INT_NXT_NLIM 0xaa /* Interrupt the next time the motor
hits the negative limit */
#define SM_INT_ALL_NLIM 0xab /* Interrupt on every negative limit */
#define SM_INT_TRG 0xac /* Interrupt on trigger X active */
#define SM_INT_INHBT 0xaf /* Inhibit all interrupts */
#define SM_DEF_RATIO 0xb0 /* Define motor pulse to encoder pulse ratio */
#define SM_DEF_RESOLTN 0xb1 /* Define motor resolution */
#define SM_DEF_BACK_SIG 0xb2 /* Define backlash sigma (motor steps)*/
#define SM_DEF_ALG 0xb3 /* Define position maintenance algorithm
const, and max velocity */
#define SM_DEF_TEETH 0xb4 /* Define the number of rotor teeth */
#define SM_DEF_DEADBAND 0xb5 /* Def the deadband region in encoder pulses */
#define SM_DEF_REL_TRP 0xc8 /* Define move X as a relative,
trapezoidal move */
#define SM_DEF_ABS_TRP 0xcb /* Define move X as an absolute
trapezoidal move */
#define SM_DEF_CONT 0xce /* Define move X as a continuous move */
#define SM_DEF_REL_CL 0xd4 /* Define move X, define it as relative,
closed-loop move */
#define SM_DEF_ABS_CL 0xd5 /* Def move X as an abs, closed- loop move */
#define SM_DEF_STSTP_VEL 0xd6 /* Define the start/stop velocity */
#define SM_DEL_MOV_X 0xd7 /* Delete move X */
#define SM_END_SEQ_DEF 0xd8 /* End definition of sequence buffer */
#define SM_BEG_SEQ_DEF 0xd9 /* Begin definition of sequence buffer */
#define SM_DEL_SEQ_X 0xda /* Delete sequence buffer X */
#define SM_LD_VD_DATA 0xe0 /* Place data into the velocity-distance buffer */
#define SM_LD_VT_DATA 0xe1 /* Place data into the velocity-time buffer */
#define SM_GET_FREE_BYT 0xe2 /* Request number of free bytes in vel-
streaming/sequence buffer */
#define SM_DEF_VS_CMMD 0xee /* Define command to be executed during
the velocity streaming buffer */
#define SM_GET_NUM_REV 0xfd /* Request software part number and revision */
#define SM_TEST_SWITCH 0xff /* Perform the test switch function */
#define VELOCITY_MODE 0
#define MAX_COMMANDS 256
#define COMPU_INT_LEVEL 5
/* array of pointers to stepper motor driver cards present in system */
struct compumotor *pcompu_motors[MAX_COMPU_MOTORS];
LOCAL SEM_ID compu_wakeup; /* compumotor data request task semaphore */
/* response variables */
LOCAL SEM_ID smRespSem; /* task semaphore */
LOCAL RING_ID smRespQ; /* ring buffer */
int smRespId; /* task id */
#define RESP_Q_SZ (RESPBUF_SZ * 50) /* response ring buffer size */
/* interrupt buffers */
unsigned char sm_responses[MAX_COMPU_MOTORS][RESPBUF_SZ];
unsigned short counts[MAX_COMPU_MOTORS];
/* counts for debugging */
long dbicounts; /* counts number of times through interrupt routine */
long dbrcounts; /* counts number of times through response routine */
long dbscounts; /* counts number of times through send routine */
/* VME memory Short Address Space is set up in gta_init */
static int *compu_addr;
/* motor information */
struct compu_motor{
short active; /* flag to tell the oms_task if the motor is moving */
int callback; /* routine in database library to call with status */
int callback_arg; /* argument to callback routine */
short update_count;
short mode;
short motor_resolution;
};
struct compu_motor compu_motor_array[MAX_COMPU_MOTORS];
/* Forward reference. */
VOID compu_sm_reset();
VOID compu_sm_stat();
/* motor status - returned to the database library routines */
struct motor_data compu_motor_data_array[MAX_COMPU_MOTORS];
/* moving status bit descriptions */
#define CW_LIMIT 0x01 /* clockwise???? limit */
#define CCW_LIMIT 0x02 /* counter-clockwise???? limit */
#define DIRECTION 0x08 /* direction bit */
#define MOVING 0x10 /* moving status bit */
#define CONSTANT_VEL 0x20 /* constant velocity */
/* directions in driver card-ese */
#define CLKW 0 /* clockwise direction */
#define CCLKW 1 /* counter clockwise direction */
/*
* Code Portions:
*
* smCmdTask Task which writes commands to the hardware
* smRespTask Task which places reponses from the hardware into resp buffers
* sm_intr Interrupt Handler - collects response data from the hardware
* sm_drv_init Initializes all motors, semaphores, ring buffers and interrupts
* sm_driver Subroutine for outside world to issue commands to motors
* motor_select Subroutine to setting callback arg and verifying no other user
* motor_deselect Subroutine to free the motor for other users
*
* Interaction Chart:
* -------------- -------------------
* / \ / \
* | smRespTask | | smCmdTask |
* \ / \ /
* --------------- -------------------
* ^ ^ |
* TAKES | | GETS |
* | | |
* -------------- --------------- |
* Resp Semaphore Response Queue |
* -------------- --------------- |
* ^ ^ |
* GIVES | | PUTS |
* | | |
* --------------- |
* / \ |
* | sm_intr | |
* \ / |
* --------------- |
* ^ reads responses writes commands |
* | from hardware to hardware V
*/
/*
* COMPU_RESP_TASK
*
* converts readback from the compumotor 1830 cards into a structure that
* is returned to the database library layer every .1 second while a motor
* is moving
*/
int compu_resp_task()
{
unsigned char resp[RESPBUF_SZ];
register struct motor_data *pmotor_data;
FOREVER {
/* wait for somebody to wake us up */
semTake (smRespSem, WAIT_FOREVER);
(dbrcounts < 0xFFFF ? dbrcounts++: 0);
/* the response buffer contains: */
/* 0 - motor number */
/* 1 - the command which solicited this response */
/* 2 - the first byte of the response */
/* process requests in the command ring buffer */
while (rngBufGet(smRespQ,(char *)resp,RESPBUF_SZ) == RESPBUF_SZ){
pmotor_data = &compu_motor_data_array[resp[0]];
/* convert argument */
switch(resp[1]){
case (SM_GET_VEL):
{
register long *pvelocity = (long *)(&resp[3]);
pmotor_data->velocity = *pvelocity;
break;
}
case (SM_GET_MOV_STAT):
{
register struct compu_motor *pcompu_motor;
register int (*psmcb_routine)();
pcompu_motor = &compu_motor_array[resp[0]];
pmotor_data->moving = (resp[2] & MOVING)?1:0;
pmotor_data->constant_velocity = (resp[2] & CONSTANT_VEL)?1:0;
pmotor_data->cw_limit = (resp[2] & CW_LIMIT)?1:0;
pmotor_data->ccw_limit = (resp[2] & CCW_LIMIT)?1:0;
pmotor_data->direction = (resp[2] & DIRECTION)?1:0;
/* post every .1 second or not moving */
if ((pcompu_motor->update_count-- <= 0)
|| (pmotor_data->moving == 0)){
if (pcompu_motor->callback != 0){
(int)psmcb_routine = pcompu_motor->callback;
(*psmcb_routine)(pmotor_data,pcompu_motor->callback_arg);
}
if (pmotor_data->moving){
/* motors are reported at 10 Hz */
pcompu_motor->update_count = 3;
}else{
pcompu_motor->active = FALSE;
pcompu_motor->update_count = 0;
}
}
break;
}
case (SM_GET_ABS_ENC):
{
register long *pencoder = (long *)(&resp[2]);
pmotor_data->encoder_position = *pencoder;
break;
}
case (SM_GET_Z_REL_POS):
{
register long *pmotor = (long *)(&resp[4]);
pmotor_data->motor_position = *pmotor;
break;
}
case (SM_GET_CUR_DIR):
pmotor_data->direction = (resp[2] == 0xff)?CLKW:CCLKW;
break;
}
}
}
}
/* Data request commands for the positional and velocity mode motors */
char compu_velo_reqs[] = { SM_GET_VEL, SM_GET_MOV_STAT };
#define NUM_VEL_REQS 2
char compu_pos_reqs[] = { SM_GET_ABS_ENC, SM_GET_Z_REL_POS, SM_GET_MOV_STAT };
#define NUM_POS_REQS 3
/*
* COMPU_TASK
*
* task to solicit currnet status from the compumotor 1830 cards while they
* are active
*/
int compu_task()
{
register short inactive_count;
register short card;
register short i;
register struct compumotor *pmotor;
register char *preqs;
/* inactive motors get monitored once every 2 seconds in case they are */
/* being moved manually */
inactive_count = 60;
while(1){
/* This task is run 30 times a second */
taskDelay(2);
for (card = 0; card < sm_num_cards[CM57_83E]; card++){
pmotor = pcompu_motors[card];
if (pmotor == 0) continue;
if ((compu_motor_array[card].active)
|| (inactive_count <=0)){
if (compu_motor_array[card].mode == VELOCITY_MODE){
preqs = &compu_velo_reqs[0];
/* request status data */
for (i = 0; i < NUM_VEL_REQS; i++,preqs++)
compu_send_msg(pmotor,preqs,1);
}else{
preqs = &compu_pos_reqs[0];
/* request status data */
for (i = 0; i < NUM_POS_REQS; i++,preqs++)
compu_send_msg(pmotor,preqs,1);
}
}
}
if (--inactive_count < 0) inactive_count = 60;
}
}
/*
* COMPU_INTR
*
* interrupt vector for the compumotor 1830 card
*/
int compu_intr(mdnum)
register int mdnum;
{
register struct compumotor *pmtr; /* memory port to motor card */
register int key;
key = intLock();
/* pointer to the compumotor card interface */
pmtr = pcompu_motors[mdnum];
if (pmtr == 0)
{
intUnlock(key);
return(0);
};
(dbicounts < 0xFFFF ? dbicounts++: 0);
/* place the response byte into the appropriate response buffer */
sm_responses[mdnum][counts[mdnum]] = pmtr->cm_idb;
counts[mdnum]++;
/* when the buffer is full pass it onto the repsonse task */
if (counts[mdnum] == RESPBUF_SZ){
if (rngBufPut(smRespQ,(char *)sm_responses[mdnum],RESPBUF_SZ) != RESPBUF_SZ)
logMsg("smRespQ %d - Full\n",mdnum);
else
semGive (smRespSem);
/* the zero-th byte is the motor number */
counts[mdnum] = 1; /* start with command */
/* inform the hardware that the response is complete */
pmtr->cm_cb = RD_LAST;
}else{
/* inform the hardware there is more to send */
pmtr->cm_cb = RD_MORE;
}
intUnlock(key);
return(0);
}
/*
* COMPU_DRIVER_INIT
*
* initialization for the compumotor 1830 card
*/
long
compu_driver_init(){
register short i;
int status;
struct compumotor *pmtr; /* memory port to motor card */
int cok = CBBR; /*to reset board */
short none_found; /* flags a steppermotor is present */
int taskId;
struct compumotor *pmtrb;
/* intialize each driver which is present */
none_found = TRUE;
rebootHookAdd((FUNCPTR)compu_sm_reset);
status = sysBusToLocalAdrs(
VME_AM_SUP_SHORT_IO,
sm_addrs[CM57_83E],
(int **)&compu_addr);
if (status != OK){
printf("%s: failed to map A16 base\n", __FILE__);
return ERROR;
}
pmtrb = (struct compumotor *)compu_addr;
for (i = 0; i < sm_num_cards[CM57_83E]; i++) {
pmtr = (struct compumotor *)((int)pmtrb + (i<<8));
/* initialize when card is present */
if (vxMemProbe(&pmtr->cm_cb,WRITE,1,&cok) != ERROR){
none_found = FALSE;
pcompu_motors[i] = pmtr; /* ptr to interface */
intConnect((MD_INT_BASE+i)*4,compu_intr,i); /* interrupt enable */
sysIntEnable(COMPU_INT_LEVEL);
/* init interrupt receive buffers */
sm_responses[i][0] = i; /* motor number */
counts[i] = 1; /* buffer index */
}else{
pcompu_motors[i] = 0; /* flags no board is present */
}
}
if (none_found) return(0);
/* initialize the response task ring buffer */
if ((smRespQ = rngCreate(RESP_Q_SZ)) == (RING_ID)NULL)
panic ("sm_init: cmRespQ\n");
/* intialize the semaphores which awakens the sleeping *
* stepper motor command task and the stepper motor response task */
if(!(smRespSem=semBCreate(SEM_Q_FIFO,SEM_EMPTY)))
errMessage(0,"semBcreate failed in compu_driver_init");
if(!(compu_wakeup=semBCreate(SEM_Q_FIFO,SEM_EMPTY)))
errMessage(0,"semBcreate failed in compu_driver_init");
/* spawn the sleeping motor driver command and response tasks */
smRespId =
taskSpawn("compu_resp_task",SMRESP_PRI,SMRESP_OPT,SMRESP_STACK,compu_resp_task);
taskwdInsert(smRespId,NULL,NULL);
taskId = taskSpawn("compu_task",SMRESP_PRI,SMRESP_OPT,2000,compu_task);
taskwdInsert(taskId,NULL,NULL);
return(0);
}
short trigger = 0;
/*
* COMPU_DRIVER
*
* driver interface to the database library layer
*/
int compu_driver(card, channel, value_flag,arg1,arg2)
register short card;
short channel;
short value_flag;
register int arg1;
register int arg2;
{
register int *pint;
register short *pshort;
short i;
char compu_msg[20];
i = 0;
/* verify the stepper motor driver card is present */
if ((card < 0) || (card > sm_num_cards[CM57_83E]) || (!pcompu_motors[card]))
return (-1);
switch (value_flag){
case (SM_MODE):
/* set the motor mode */
compu_motor_array[card].mode = arg1;
break;
case (SM_VELOCITY):
compu_motor_data_array[card].velocity = arg1;
compu_motor_data_array[card].accel = arg2;
/* set the velocity */
compu_msg[0] = SM_DEF_VEL_ACC;
compu_msg[1] = 0; /* time is in seconds */
compu_msg[2] = 0;
pint = (int *)&compu_msg[3]; /* velocity */
*pint = arg1;
pint++; /* acceleration */
*pint = arg2;
compu_send_msg(pcompu_motors[card],compu_msg,11);
break;
case (SM_FIND_HOME): /* Move to a home switch */
break; /* Not supported by this device */
case (SM_FIND_LIMIT): /* Move to a limit switch */
arg1 = arg1 >= 0 ? 0x000fffff : -0x000fffff;
/* break purposely left out to continue with SM_MOVE */
case (SM_MOVE):
if (compu_motor_array[card].mode == VELOCITY_MODE)
return(0);
/* move the motor */
i = 0;
compu_msg[i++] = SM_MOV_REL_POS;
pint = (int *)&compu_msg[i];
*pint = arg1;
i += 4;
compu_send_msg(pcompu_motors[card],compu_msg,i);
/* set the motor to active */
compu_motor_array[card].active = TRUE;
/* wakeup the compu task */
semGive(compu_wakeup);
break;
case (SM_MOTION):
if (arg1 == 0){
compu_msg[0] = SM_STOP;
compu_send_msg(pcompu_motors[card],compu_msg,1);
}else if (compu_motor_array[card].mode == VELOCITY_MODE){
compu_msg[0] = SM_MOV_DEFAULT;
compu_msg[1] = arg2; /* direction */
compu_send_msg(pcompu_motors[card],compu_msg,2);
compu_motor_array[card].active = TRUE;
}
/* wakeup the compu task */
semGive(compu_wakeup);
break;
case (SM_CALLBACK):
/* put the callback routine and argument into the data array */
i = 0;
if (compu_motor_array[card].callback != 0) return(-1);
compu_motor_array[card].callback = arg1;
compu_motor_array[card].callback_arg = arg2;
break;
case (SM_SET_HOME):
if (compu_motor_array[card].mode == VELOCITY_MODE)
return(OK);
/* set the motor and encoder position to zero */
compu_msg[0] = SM_DEF_ABS_ZERO;
compu_send_msg(pcompu_motors[card],compu_msg,1);
break;
case (SM_ENCODER_RATIO):
compu_motor_array[card].motor_resolution = arg1;
/* set the encoder ratio */
compu_msg[0] = SM_DEF_RATIO;
pshort = (short *)&compu_msg[1];
*pshort = arg1; /* motor resolution */
pshort++;
*pshort = arg2; /* encoder resolution */
compu_send_msg(pcompu_motors[card],compu_msg,5);
/* set the motor resolution */
compu_msg[0] = SM_DEF_RESOLTN;
pshort = (short *)&compu_msg[1];
*pshort = 0;
pshort++;
*pshort = arg1; /* motor resolution */
compu_send_msg(pcompu_motors[card],compu_msg,5);
break;
case (SM_READ):
/* set the motor to active */
compu_motor_array[card].active = TRUE;
/* wakeup the compu task */
semGive(compu_wakeup);
break;
}
return (OK);
}
/*
* COMPU_SEND_MSG
*
* send a message to the compumotor 1830
*/
int wait_count;
int compu_send_msg(pmotor,pmsg,count)
register struct compumotor *pmotor;
register char *pmsg;
register short count;
{
(dbscounts < 0xFFFF ? dbscounts++: 0);
/* write out this command one byte at a time */
while (count){
/* wait for the driver to be ready */
while ((pmotor->cm_cb & SBIRDY) == 0){
taskDelay(0);
wait_count++;
}
/* next byte in the input data buffer of compumotor */
pmotor->cm_idb = *pmsg;
pmsg++;
count--;
/* tell compumotor more or complete */
if (count == 0){
pmotor->cm_cb = SND_LAST;
}else{
pmotor->cm_cb = SND_MORE;
}
}
return(0);
}
/*
* COMPU_SM_IO_REPORT
*
* send a message to the compumotor 1830
*/
long compu_sm_io_report(level)
short int level;
{
register int i;
for (i = 0; i < sm_num_cards[CM57_83E]; i++){
if (pcompu_motors[i]){
printf("SM: CM1830: card %d\n",i);
if (level > 0)
compu_sm_stat(i);
}
}
return OK;
}
VOID compu_sm_stat(compu_num)
short int compu_num;
{
printf("\tCW limit = %d\t,CCW limit = %d\tMoving = %d\tDirection = %d\n",
compu_motor_data_array[compu_num].cw_limit,
compu_motor_data_array[compu_num].ccw_limit,
compu_motor_data_array[compu_num].moving,
compu_motor_data_array[compu_num].direction);
printf("\tConstant Velocity = %d\t, Velocity = %d\t \n",
compu_motor_data_array[compu_num].constant_velocity,
compu_motor_data_array[compu_num].velocity);
printf("\tAcceleration = %d\tEncoder Position = %d\tMotor Position = %d\n",
compu_motor_data_array[compu_num].accel,
compu_motor_data_array[compu_num].encoder_position,
compu_motor_data_array[compu_num].motor_position);
}
/*
*
* Subroutine to be called during a CTL X reboot. Inhibits interrupts.
*
*/
VOID compu_sm_reset()
{
short int i;
char compu_msg[20];
for (i = 0; i < sm_num_cards[CM57_83E]; i++){
if (pcompu_motors[i]){
compu_msg[0] = SM_INT_INHBT;
compu_send_msg(pcompu_motors[i],compu_msg,1);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,240 +0,0 @@
/* base/src/drv $Id$ */
/*
* Author: John Winans
* Date: 09-09-92
*
* Skeleton VXI driver module.
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 09-09-92 jrw written
* .02 08-24-93 joh updated for EPICS format return codes
* .03 08-24-93 joh converted to ANSI C
* .04 08-24-93 joh ran through -Wall
*
*/
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <rebootLib.h>
#include <dbDefs.h>
#include <epicsPrint.h>
#include <drvEpvxi.h>
#include <drvSup.h>
#include <devLib.h>
typedef long exVxiStat;
exVxiStat vti(int make, int model);
LOCAL exVxiStat example_init(void);
LOCAL void example_stat(unsigned card, int level);
LOCAL void example_init_card(unsigned addr);
LOCAL int example_shutdown(void);
LOCAL void example_shutdown_card(unsigned la);
struct drvet drvExample={
2,
NULL, /* VXI I/O report takes care of this */
example_init
};
static unsigned long exampleDriverID; /* ID used to identify this driver */
struct examplePrivate {
int j;
/*
* Define all per-card private variables here.
*/
};
#define PRIVATE_SIZE sizeof(struct examplePrivate)
int vxi_make_example = 0x100; /* Set to proper make of the card */
int vxi_model_example = 0x100; /* Set to proper model of the card */
/*
* This is a test entry point that allows a user to do a pseudo-init of
* a make and model of VXI cards.
*/
exVxiStat vti(int make, int model)
{
vxi_make_example = make;
vxi_model_example = model;
example_init();
printf("Driver ID is 0x%08X\n", exampleDriverID);
return(VXI_SUCCESS);
}
/******************************************************************************
*
* Initialize all cards controlled by the example driver.
*
******************************************************************************/
LOCAL exVxiStat example_init(void)
{
exVxiStat s;
epvxiDeviceSearchPattern dsp;
/*
* do nothing on crates without VXI
*/
if(!epvxiResourceMangerOK)
return VXI_SUCCESS;
if (rebootHookAdd(example_shutdown) < 0){
s = S_dev_internal;
errMessage(s, "rebootHookAdd failed");
return(s);
}
exampleDriverID = epvxiUniqueDriverID();
dsp.flags = VXI_DSP_make;
dsp.make = vxi_make_example;
s = epvxiLookupLA(&dsp, example_init_card, (void *)NULL);
return s;
}
/******************************************************************************
*
* initialize single example card
*
******************************************************************************/
LOCAL void example_init_card(unsigned addr)
{
exVxiStat s;
struct examplePrivate *ep; /* Per-card private variable area */
struct exampleCard *ec; /* Physical address of the card */
/* Tell the VXI sub-system that this driver is in charge of this card */
s = epvxiOpen(addr, exampleDriverID, PRIVATE_SIZE, example_stat);
if (s)
{
errPrintf(s, __FILE__, __LINE__, "LA=0X%X", addr);
return;
}
printf("example_init_card entered for card at LA 0x%02X, make 0x%02X, model 0x%02X\n", addr, vxi_make_example, vxi_model_example);
/* Allocate a private variable area for the card */
s = epvxiFetchPConfig(addr, exampleDriverID, ep);
if(s){
errMessage(s, NULL);
epvxiClose(addr, exampleDriverID);
return;
}
/* Get physical base address of the card */
ec = (struct exampleCard *) VXIBASE(addr);
/***********************************************
*
* Perform card-specific initialization in here.
*
***********************************************/
/* Register the card's model and make names for reporting purposes */
s = epvxiRegisterModelName(
vxi_make_example,
vxi_model_example,
"Example Model Name");
if(s){
errMessage(s, NULL);
}
s = epvxiRegisterMakeName(
vxi_make_example,
"Example Make Name");
if(s){
errMessage(s, NULL);
}
return;
}
/******************************************************************************
*
* Shut the cards down beacuse a soft-boot will be taking place soon.
*
******************************************************************************/
LOCAL int example_shutdown(void)
{
exVxiStat s;
epvxiDeviceSearchPattern dsp;
dsp.flags = VXI_DSP_make;
dsp.make = vxi_make_example;
s = epvxiLookupLA(&dsp, example_shutdown_card, (void *)NULL);
if(s){
errMessage(s, NULL);
}
return OK;
}
LOCAL void example_shutdown_card(unsigned la)
{
/*
* Perform proper operations here to disable the VXI card from
* generating interrupts and/or other backplane bus activity that
* could cause the CPUs and controllers problems during a soft-boot.
*/
return;
}
/******************************************************************************
*
* Print status for a single card.
*
******************************************************************************/
LOCAL void example_stat(
unsigned card,
int level
)
{
/*
* Perform proper operations to evaluate the current operating mode
* of the card and print a summary.
*/
return;
}
/******************************************************************************
*
* Place any user-required functions here.
*
******************************************************************************/

View File

@@ -1,532 +0,0 @@
/* drvFp.c */
/* base/src/drv $Id$
* routines which are used to test and interface with the
* FP10S fast protect module
*
* Author: Matthew Stettler
* Date: 6-92
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 joh 070992 integrated into GTACS & added std header
* .02 joh 070992 merged in include file fp.h
* .03 joh 070992 converted some symbols to LOCAL so they stay out
* of the vxWorks global symbol table
* .04 joh 070992 took out sysSetBCL() and substituted
* sysIntEnable() so this will not be hkv2f
* specific.
* .05 joh 070992 added INUM_TO_IVEC so this will be less
* 68k dependence (added include of iv.h)
* .06 joh 070992 FP_ILEV passed to call sysIntEnable() so that the
* interrupt level can be easily changed
* .07 joh 070992 changed some printf() calls to logMsg()
* so that driver diagnostics will show up in
* the log
* .08 joh 071092 now fetches base addr from module_types.h
* .09 joh 071092 added io_report routine
* .10 joh 071092 added scan task wakeup from ISR
* .11 joh 071092 moved ivec allocation to module_types.h
* .12 joh 072792 added soft reboot int disable
* .13 joh 082792 converted to V5 vxorks
* .14 mrk 090192 support epics I/O event scan, and added DRVET
* .15 mrk 080293 Add call to taskwdInsert
* .16 mgb 080493 Removed V5/V4 and EPICS_V2 conditionals
*/
/*
*
* Routines:
*
* fp_init Finds and initializes fast protect cards
* fp_driver System interface to FP10S modules
* fp_int Interrupt service routine
* fp_en Enables/disables interrupts (toggles)
* fp_mode Sets interrupt reporting mode
* fp_reboot Clean up for soft reboots
*
* Diagnostic Routines:
*
* fp_srd Reads current local inputs and enables
* fp_frd Reads last failure register
* fp_csrd Reads control/status register
* fp_read Command line interface to fp_driver
* fp_dump Prints all fast protect status to console
* fp_monitor Monitor all cards and print failure data to
* console
*
* Routines Return:
*
* -1 No card present
* -2 Interrupt connection error
* -3 Semaphore creation error
* -4 addressing error
* -5 no memory
* 0-8 successfull completion, or # of cards found
*
*/
static char *sccsId = "@(#)drvFp.c 1.12\t6/4/93";
#include "vxWorks.h"
#include "stdlib.h"
#include "stdio.h"
#include "intLib.h"
#include "rebootLib.h"
#include "vme.h"
#include "taskLib.h"
#include <iv.h> /* in h/68k if this is compiling for a 68xxx */
#include "module_types.h"
#include <dbDefs.h>
#include <drvSup.h>
#include <taskwd.h>
#include <dbScan.h>
static long report();
static long init();
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvFp={
2,
report,
init};
static long report()
{
fp_io_report();
return(0);
}
static long init()
{
fp_init(0);
return(0);
}
/* general constants */
#define FP_INTLEV 5 /* interrupt level */
#define FP_BUFSIZ 8 /* input buffer size */
/* csr bit definitions */
#define CSR_RST 0x1 /* reset status */
#define CSR_CMD1 0x2 /* force local fail */
#define CSR_IEN 0x4 /* interrupt enable */
#define CSR_UDEF0 0x8 /* undefined */
#define CSR_I0 0x10 /* interrupt level bit #1 */
#define CSR_I1 0x20 /* interrupt level bit #2 */
#define CSR_I2 0x40 /* interrupt level bit #3 */
#define CSR_UDEF1 0x80 /* undefined */
#define CSR_CARM0_L 0x100 /* latched carrier monitor #0 (one shot) */
#define CSR_CARM1_L 0x200 /* latched carrier monitor #1 (freq mon) */
#define CSR_OPTIC 0x400 /* optical carrier input enabled */
#define CSR_CARM 0x800 /* carrier OK */
#define CSR_LFAIL0 0x1000 /* local fail #0 (pal monitor) */
#define CSR_LFAIL1 0x2000 /* local fail #1 (fpga monitor) */
#define CSR_CMON 0x4000 /* clock fail (one shot) */
#define CSR_CHNG 0x8000 /* enable switch configuration change */
/* csr mask definitions */
#define CSR_STM 0xff00 /* status mask */
#define CSR_IM 0x70 /* interrupt level mask */
/* driver status */
#define DRV_MOM 0x010000 /* momentary fault */
#define DRV_LOC 0x020000 /* local fault */
#define DRV_REM 0x040000 /* remote fault */
#define DRV_CLR 0x080000 /* fault cleared */
#define DRV_HWF 0x800000 /* hardware fault */
/* operating modes */
#define FP_NMSG 0 /* no messages to console */
#define FP_TMSG 1 /* terse messages to console */
#define FP_FMSG 2 /* full messages to console */
#define FP_RUN 3 /* normal operating mode */
/* register address map for FP10s */
struct fp1
{
unsigned short csr; /* control and status register */
unsigned short srd; /* current status */
unsigned short frd; /* latched status */
unsigned short ivec; /* interrupt vector */
char end_pad[0xff-0x8]; /* pad to 256 byte boundary */
};
/* fast protect control structure */
struct fp_rec
{
struct fp1 *fptr; /* pointer to device registers */
unsigned int drvstat; /* fast protect physical inputs */
unsigned short lastswitch; /* previous enable switch data */
short type; /* device type */
short num; /* device number */
short fp_vector; /* interrupt vector */
short mode; /* operating mode */
unsigned int int_num; /* interrupt number */
IOSCANPVT ioscanpvt;
};
static struct fp_rec *fp; /* fast protect control structure */
static int fp_num; /* # of fast protect cards found -1 */
static SEM_ID fp_semid; /* semaphore for monitor task */
static void fp_reboot();
/*
* fp_int
*
* interrupt service routine
*
*/
int fp_int(card)
unsigned card;
{
register struct fp_rec *ptr = &fp[card];
register struct fp1 *regptr;
unsigned short temp0, temp1, temp2;
regptr = ptr->fptr;
temp0 = regptr->csr;
temp1 = regptr->frd;
temp2 = regptr->srd;
switch (ptr->mode)
{
case FP_TMSG:
logMsg("fast protect interrupt!\n");
logMsg("csr status = %x\n",temp0);
break;
case FP_FMSG:
logMsg("fast protect #%d fault! fault input = %x enable switches = %x\n",
ptr->num,temp1 & 0xff,temp2>>8);
logMsg("csr status = %x\n",temp0);
break;
case FP_RUN:
ptr->drvstat = temp2; /* save last switch data */
ptr->drvstat |= temp1<<16; /* save fault data */
ptr->drvstat |= (temp0 & 0xff00)<<16; /* csr status bits */
if ((temp1 ^ (temp2>>8)) || (temp0 & CSR_CHNG)) /* fault or enable change */
semGive(fp_semid); /* wake up monitor */
/*
* wakeup the interrupt driven scanner
*/
scanIoRequest(fp[card].ioscanpvt);
break;
}
ptr->int_num++; /* log interrupt */
regptr->csr |= CSR_RST; /* clear status and rearm */
regptr->csr ^= CSR_RST;
return(0);
}
/*
* fp_init
*
* initialization routine for FP10s fast protect modules
*
*
*/
int fp_init(addr)
unsigned int addr;
{
int i;
short junk;
short intvec = AT8FP_IVEC_BASE;
struct fp1 *ptr;
int status;
fp = (struct fp_rec *) calloc(bi_num_cards[AT8_FP10S_BI], sizeof(*fp));
if(!fp){
return -5;
}
if(!addr){
addr = bi_addrs[AT8_FP10S_BI];
}
status = sysBusToLocalAdrs( VME_AM_SUP_SHORT_IO, addr, &ptr);
if(status<0){
logMsg("VME shrt IO addr err in the slave fast protect driver\n");
return(-4);
}
status = rebootHookAdd(fp_reboot);
if(status<0){
logMsg("%s: reboot hook add failed\n", __FILE__);
}
for (i = 0;
(i < bi_num_cards[AT8_FP10S_BI]) && (vxMemProbe(ptr,READ,2,&junk) == OK);
i++,ptr++) {
/* register initialization */
ptr->csr = 0x0000; /* disable interface */
fp[i].fptr = ptr; /* hardware location */
fp[i].fp_vector = intvec++; /* interrupt vector */
ptr->ivec = fp[i].fp_vector; /* load vector */
fp[i].mode = FP_NMSG; /* set default mode (no messages) */
fp[i].int_num = 0; /* initialize interrupt number */
fp[i].type = 10; /* board type */
fp[i].num = i; /* board number */
/* initialize input buffer */
fp[i].drvstat = ptr->srd; /* initialize enable switch data */
fp[i].drvstat |= ptr->frd<<16; /* initialize fault data */
fp[i].drvstat |= (ptr->csr & 0xff00)<<16; /* csr status bits */
/* set up interrupt handler */
ptr->csr |= FP_INTLEV<<4; /* level 5 interrupt */
if (intConnect(INUM_TO_IVEC(fp[i].fp_vector),fp_int,i) != OK)
return(-2); /* abort if can't connect */
sysIntEnable(FP_INTLEV);
ptr->csr |= 0x0001;
ptr->csr ^= 0x0001; /* clear status bits */
if (ptr->csr & CSR_OPTIC)
logMsg("fast protect #%d optically coupled\n",i);
else
logMsg("fast protect #%d elecrically coupled\n",i);
/* start up module */
fp[i].fptr->csr |= CSR_IEN; /* enable interrupts */
fp[i].mode = FP_RUN; /* normal run mode */
scanIoInit(&fp[i].ioscanpvt);
}
fp_num = i - 1; /* record max card # */
/* create the semaphore */
fp_semid = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
if ((int)fp_semid == 0) /* abort if can't create semaphore */
return(-3);
return(i); /* return # found */
}
/*
*
* fp_reboot()
*
* turn off interrupts to avoid ctrl X reboot problems
*/
LOCAL
void fp_reboot()
{
int i;
if(!fp){
return;
}
for (i = 0; i < bi_num_cards[AT8_FP10S_BI]; i++){
if(!fp[i].fptr){
continue;
}
fp[i].fptr->csr &= ~CSR_IEN;
}
}
/*
* fp_en
*
* interrupt enable/disable
* (toggles the interrupt enable - joh)
*
*/
int fp_en(card)
short card;
{
if (card < 0 || (card > fp_num))
return -1;
fp[card].fptr->csr = fp[card].fptr->csr ^ CSR_IEN;
if (fp[card].fptr->csr & CSR_IEN)
printf("fast protect interrupts enabled\n");
else
printf("fast protect interrupts disabled\n");
return 0;
}
/*
* fp_mode
*
* set interrupt reporting mode
*
*/
int fp_mode(card,mode)
short card, mode;
{
if (card < 0 || (card > fp_num))
return -1;
fp[card].mode = mode;
return 0;
}
/*
* fp_srd
*
* read current local inputs and enable switches
*
*/
int fp_srd(card,option)
short card;
short option;
{
if (card > fp_num) return -1;
if (!option)
printf("local inputs = %x enable switches = %x\n",fp[card].fptr->srd & 0xff,
fp[card].fptr->srd>>8);
return fp[card].fptr->srd;
}
/*
* fp_frd
*
* read latched local inputs
*
*/
int fp_frd(card)
short card;
{
if (card < 0 || (card > fp_num))
return -1;
return fp[card].fptr->frd & 0xff;
}
/*
* fp_csrd
*
* read csr contents
*
*/
int fp_csrd(card)
short card;
{
if (card < 0 || (card > fp_num))
return -1;
return fp[card].fptr->csr & 0xff77;
}
/*
* fp_driver
*
* epics interface to fast protect
*
*/
int fp_driver(card,mask,prval)
register unsigned short card;
unsigned int mask;
register unsigned int *prval;
{
register unsigned int temp;
if (card > fp_num) return -1;
temp = fp[card].drvstat & 0xffff0000; /* latched status info */
temp |= fp[card].fptr->srd; /* current switches & inputs */
*prval = temp & mask;
return 0;
}
/*
* fp_read
*
* command line interface to fp_driver
*
*/
int fp_read(card)
short card;
{
unsigned int fpval,ret;
if ((ret = fp_driver(card,0xffffffff,&fpval)) != 0)
return ret;
printf("Card #%d enable switches = %x inputs = %x\n",card,(fpval & 0x0000ff00)>>8,
fpval & 0x000000ff);
printf("csr status = %x last fault = %x\n",fpval>>24,(fpval & 0x00ff0000)>>16);
printf("raw readback = %x\n",fpval);
return 0;
}
/*
* fp_dump
*
* dump fast protect status to console
*
*/
int fp_dump()
{
int i;
printf("Fast protect status (fault and CSR are latched):\n");
printf("Card#\tenables\tinputs\tfault\tCSR status\n");
for(i = 0; i < (fp_num + 1); i++)
printf("%d\t%x\t%x\t%x\t%x\n",i,fp[i].fptr->srd>>8,fp[i].fptr->srd & 0xff,
(fp[i].drvstat & 0x00ff0000)>>16,fp[i].drvstat>>24);
return i;
}
/*
* fp_monitor
*
* monitor fast protect cards and report failures to console
*
*/
void fp_mon()
{
for(semTake(fp_semid,WAIT_FOREVER);fp_dump() != 0;semTake(fp_semid,WAIT_FOREVER));
}
int fp_monitor()
{
static char *name = "fpmon";
int tid;
if ((tid = taskNameToId(name)) != ERROR) {
taskwdRemove(tid);
taskDelete(tid);
}
if((tid = taskSpawn(name,25,VX_SUPERVISOR_MODE|VX_STDIO,
1000,fp_mon)) == ERROR) return -1;
taskwdInsert(tid,NULL,NULL);
return 0;
}
int fp_io_report(level)
int level;
{
int i;
for(i=0; i<=fp_num; i++){
printf("BI: AT8-FP-S: card %d\n", i);
}
return(0);
}
int fp_getioscanpvt(card,scanpvt)
short card;
IOSCANPVT *scanpvt;
{
if ((card >= bi_num_cards[AT8_FP10S_BI])) return(0);
*scanpvt = fp[card].ioscanpvt;
return(0);
}

View File

@@ -1,440 +0,0 @@
/* drvFpm.c */
/* base/src/drv $Id$ */
/*
* control routines for use with the FP10M fast protect master modules
*
* routines which are used to test and interface with the
* FP10S fast protect module
*
* Author: Matthew Stettler
* Date: 6-92
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 joh 070992 integrated into GTACS & added std header
* .02 joh 070992 merged in include file fpm.h
* .03 joh 070992 converted some symbols to LOCAL so they stay out
* of the vxWorks global symbol table
* .04 joh 070992 took out sysSetBCL() and substituted
* sysIntEnable() so this will not be hkv2f
* specific.
* .05 joh 070992 added INUM_TO_IVEC so this will be less
* 68k dependence (added include of iv.h)
* .06 joh 070992 FP_ILEV passed to call sysIntEnable() so that the
* interrupt level can be easily changed
* .07 joh 071092 now fetches base addr from module_types.h
* .08 joh 071092 added io report routine
* .09 joh 071092 allocate config structure at run time so that
* the users can adjust the number of cards without
* recompilation
* .10 joh 071092 moved ivec allocation to module_types.h
* .11 joh 072792 added soft reboot int disable
* .12 mrk 090292 added DRVET
* .13 mgb 080493 Removed V5/V4 and EPICS_V2 conditionals
*
*
* Routines:
*
* fpm_init Finds and initializes FP10M cards
* fpm_driver System interface to FP10M modules
* fpm_read Carrier control readback
* fpm_reboot clean up before soft reboots
*
* Daignostic Routines
* fpm_en Enables/disables interrupts (diagnostic enable)
* fpm_mode Sets interrupt reporting mode (logs mode
* changes to console)
* fpm_cdis Disables carrier from console
* fpm_fail Sets carrier failure mode
* fpm_srd Reads current carrier status
* fpm_write Command line interface to fpm_driver
*
* Routines return:
*
* -1 Nonexistent card
* -2 Interrupt connection error
* -3 no memory
* -4 VME short IO bus nonexistent
* 0-2 Successfull completion, or # cards found
*
*/
static char *sccsId = "@(#)drvFpm.c 1.12\t8/4/93";
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <rebootLib.h>
#include <intLib.h>
#include <vxLib.h>
#include <vme.h>
#include <iv.h> /* in h/68k if this is compiling for a 68xxx */
#include "module_types.h"
#include <dbDefs.h>
#include <drvSup.h>
static long report();
static long init();
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvFpm={
2,
report,
init};
static long report()
{
fpm_io_report();
return(0);
}
static long init()
{
fpm_init(0);
return(0);
}
/* general constants */
#define FPM_INTLEV 5 /* interrupt level */
/* control register bit definitions */
#define CR_CDIS 0x1 /* software carrier disable */
#define CR_FS0 0x2 /* fail select 0 */
#define CR_FS1 0x4 /* fail select 1 */
#define CR_FS2 0x8 /* fail select 2 */
#define CR_I0 0x10 /* interrupt level bit 0 */
#define CR_I1 0x20 /* interrupt level bit 1 */
#define CR_I2 0x40 /* interrupt level bit 2 */
#define CR_IEN 0x80 /* interrupt enable */
/* control register mask definitions */
#define CR_IM 0x70 /* interrupt level mask */
/* status register bit definitions */
#define SR_S0 0x1 /* error sequencer state bit 0 */
#define SR_S1 0x2 /* error sequencer state bit 1 */
#define SR_S2 0x3 /* error sequencer state bit 2 */
/* status register mask definitions */
#define SR_EM 0x7 /* error state mask */
/* operating modes */
#define FPM_NMSG 0 /* no messages to console */
#define FPM_TMSG 1 /* terse messages to console */
#define FPM_FMSG 2 /* full messages to console */
/* register address map for FP10M */
struct fp10m
{
unsigned short cr; /* control register */
unsigned short sr; /* status register */
unsigned short ivec; /* interrupt vector */
char end_pad[0xff-0x6]; /* pad to 256 byte boundary */
};
/* control structure */
struct fpm_rec
{
struct fp10m *fmptr; /* pointer to device registers */
short type; /* device type */
short num; /* board number */
short vector; /* interrupt vector */
short mode; /* operating mode */
unsigned int int_num; /* interrupt number */
};
static struct fpm_rec *fpm; /* fast protect control structure */
static int fpm_num; /* # cards found - 1 */
static void fpm_reboot();
/*
* fpm_int
*
* interrupt service routine
*
*/
int fpm_int(ptr)
register struct fpm_rec *ptr;
{
register struct fp10m *regptr;
regptr = ptr->fmptr;
switch (ptr->mode)
{
case FPM_TMSG:
logMsg("fast protect master interrupt!\n");
break;
case FPM_FMSG:
logMsg("fast protect master interrupt!\n");
logMsg("cr = %x sr = %x\n",regptr->cr,regptr->sr & 0x7);
break;
}
ptr->int_num++;
return(0);
}
/*
* fpm_init
*
* initialization for fp10m fast protect master modules
*
*/
int fpm_init(addr)
unsigned int addr;
{
int i;
short junk;
short intvec = AT8FPM_IVEC_BASE;
struct fp10m *ptr;
int status;
fpm = (struct fpm_rec *) calloc(
bo_num_cards[AT8_FP10M_BO],
sizeof(*fpm));
if(!fpm){
return -3;
}
if(!addr){
addr = bo_addrs[AT8_FP10M_BO];
}
status = sysBusToLocalAdrs(
VME_AM_SUP_SHORT_IO,
addr,
&ptr);
if(status<0){
logMsg("VME shrt IO addr err in the master fast protect driver\n");
return -4;
}
status = rebootHookAdd(fpm_reboot);
if(status<0){
logMsg("%s: reboot hook add failed\n", __FILE__);
}
for (i = 0; (i < bo_num_cards[AT8_FP10M_BO]) && (vxMemProbe(ptr,READ,2,&junk) == OK);
i++,ptr++)
{
/*
register initialization
*/
ptr->cr = 0x00; /* disable interface */
fpm[i].fmptr = ptr; /* hardware location */
fpm[i].vector = intvec++; /* interrupt vector */
ptr->ivec = fpm[i].vector; /* load vector */
fpm[i].mode = FPM_NMSG; /* set default mode (no messages) */
fpm[i].int_num = 0; /* initialize interrupt number */
fpm[i].type = 2; /* board type */
fpm[i].num = i; /* board number */
/*
set up interrupt handler
*/
ptr->cr |= FPM_INTLEV<<4; /* set up board for level 5 interrupt */
if (intConnect(INUM_TO_IVEC(fpm[i].vector),fpm_int,&fpm[i]) != OK)
return -2; /* abort if can't connect */
sysIntEnable(FPM_INTLEV);
}
fpm_num = i - 1; /* record last card # */
return i; /* return # cards found */
}
/*
*
* fpm_reboot()
*
* turn off interrupts to avoid ctrl X reboot problems
*/
LOCAL
void fpm_reboot()
{
int i;
if(!fpm){
return;
}
for (i = 0; i < bo_num_cards[AT8_FP10M_BO]; i++){
if(!fpm[i].fmptr){
continue;
}
fpm[i].fmptr->cr &= ~CR_IEN;
}
}
/*
* fpm_en
*
* interrupt enable/disable
* (toggles the int enable state - joh)
*
*/
int fpm_en(card)
short card;
{
if (card < 0 || (card > fpm_num))
return -1;
fpm[card].fmptr->cr ^= CR_IEN;
if (fpm[card].fmptr->cr & CR_IEN)
printf("fast protect master interrupts enabled\n");
else
printf("fast protect master interrupts disabled\n");
return 0;
}
/*
* fpm_mode
*
* set interrupt reporting mode
*
*/
int fpm_mode(card,mode)
short card, mode;
{
if (card < 0 || (card > fpm_num))
return -1;
fpm[card].mode = mode;
return 0;
}
/*
* fpm_cdis
*
* carrier disable (1), enable (0)
*
*/
int fpm_cdis(card,disable)
short card, disable;
{
unsigned short temp;
if (card < 0 || (card > fpm_num))
return -1;
temp = fpm[card].fmptr->cr;
temp &= 0xfe;
temp |= (disable & 0x01);
fpm[card].fmptr->cr = temp;
return 0;
}
/*
* fpm_fail
*
* set failure mode
*
*/
int fpm_fail(card,mode)
short card, mode;
{
unsigned short temp;
if (card < 0 || (card > fpm_num))
return -1;
temp = fpm[card].fmptr->cr;
temp &= 0xf1;
temp |= (mode & 0x7)<<1;
fpm[card].fmptr->cr = temp;
return 0;
}
/*
* fpm_srd
*
* read status bits
*
*/
int fpm_srd(card)
short card;
{
if (card < 0 || ( card > fpm_num))
return -1;
return fpm[card].fmptr->sr & 0x7;
}
/*
* fpm_driver
*
* epics interface to fast protect master
*
*/
int fpm_driver(card,mask,prval)
register unsigned short card;
unsigned int mask;
register unsigned int prval;
{
register unsigned int temp;
if (card > fpm_num)
return -1;
temp = fpm[card].fmptr->cr;
fpm[card].fmptr->cr = (temp & (~mask | 0xf0)) | ((prval & mask) & 0xf);
return 0;
}
/*
* fpm_write
*
* command line interface to fpm_driver
*
*/
int fpm_write(card,val)
short card;
unsigned int val;
{
return fpm_driver(card,0xffffffff,val);
}
/*
* fpm_read
*
* read the current control register contents (readback)
*
*/
int fpm_read(card,mask,pval)
register unsigned short card;
unsigned int mask;
register unsigned int *pval;
{
if (card > fpm_num)
return -1;
*pval = fpm[card].fmptr->cr & 0x000f;
return 0;
}
/*
* fpm_io_report()
*
*/
int fpm_io_report(level)
int level;
{
int i;
for(i=0; i<=fpm_num; i++){
printf("BO: AT8-FP-M: card %d\n", i);
}
return(0);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,315 +0,0 @@
/* drvGpib.h */
/* base/src/drv $Id$ */
/*
* Origional Author: Unknown, probably National Instruments
* Author: John Winans
* Date: 10-27-91
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 10-27-91 winans moved into epics area
*/
/* GPIB-1014 engineering software package UNIX include file */
/*
* The following structure dma_chan defines the memory map of a single
* channel on the Hitachi 68450.
*/
struct dma_chan {
char csr; /* +0 channel status register */
char cer; /* +1 channel error register */
char f0[2];
char dcr; /* +4 device control register */
char ocr; /* +5 operation control register */
char scr; /* +6 sequence control register */
char ccr; /* +7 channel control register */
char f1[2];
unsigned short mtc; /* +10 memory transfer counter */
long mar; /* +12 memory address register */
char f2[4];
long dar; /* +20 device address register */
char f3[2];
unsigned short btc; /* +26 base transfer counter */
long bar; /* +28 base address register */
char f4[5];
char niv; /* +37 normal interrupt vector */
char f5;
char eiv; /* +39 error interrupt vector */
char f6;
char mfc; /* +41 memory function codes */
char f7[3];
char cpr; /* +45 channel priority register */
char f8[3];
char dfc; /* +49 device function codes */
char f9[7];
char bfc; /* +57 base function codes */
char fA[6];
};
/*
* The structure ibregs defines the address space of the GPIB-1014.
*/
struct ibregs {
struct dma_chan ch0; /* +0 dma channel 0 */
struct dma_chan ch1; /* +64 dma channel 1 */
struct dma_chan ch2; /* +128 dma channel 2 */
struct dma_chan ch3; /* +192 dma channel 3 */
#define gcr ch3.fA[5] /* +255 general control register */
char fB;
char cfg1; /* +257 config reg 1 */
#define gsr cfg1 /* +257 GSR */
char fC[3];
char cfg2; /* +261 config reg 2 */
char fD[10];
char fE, cdor; /* +273 byte out register */
char fF, imr1; /* +275 interrupt mask register 1 */
char f10,imr2; /* +277 interrupt mask register 2 */
char f11,spmr; /* +279 serial poll mode register */
char f12,admr; /* +281 address mode register */
char f13,auxmr; /* +283 auxiliary mode register */
char f14,adr; /* +285 address register 0/1 */
char f15,eosr; /* +287 end of string register */
char f16[512-289]; /* +289 filler to rest of window */
};
/*
* The structure srqTable defines the srq status of each of 31 possible devices
*/
struct srqTable {
short active;
char lad;
char tad;
unsigned char status;
SEM_ID pSem;
} ;
/* 7210 readable registers */
#define dir cdor
#define isr1 imr1
#define isr2 imr2
#define spsr spmr
#define adsr admr
#define cptr auxmr
#define adr0 adr
#define adr1 eosr
/* GPIB status register */
#define GSR_EOI 0x80
#define GSR_ATN 0x40
#define GSR_SRQ 0x20
#define GSR_REN 0x10
#define GSR_IFC 0x08
#define GSR_NRFD 0x04
#define GSR_NDAC 0x02
#define GSR_DAV 0x01
/* 68450 DMAC register definitions */
/* Device Control Register (dcr) bits */
#define D_CS 0x80 /* cycle steal mode */
#define D_CSM 0x80 /* cycle steal mode,with bus Monitor*/
#define D_CSH 0xC0 /* cycle steal with hold */
#define D_CSHM 0xC0 /* cycle steal with hold,with bus Monitor */
#define D_IACK 0x20 /* device with DMAACK, implicitly addressed */
#define D_P16 0x08 /* 16 bit device port size */
#define D_IPCL 0x01 /* PCL set to status input with interrupt */
/* Operation Control Register (ocr) bits */
#define D_MTD 0x00 /* direction is from memory to device */
#define D_DTM 0x80 /* direction is from device to memory */
#define D_TW 0x10 /* transfer size is word */
#define D_TL 0x30 /* transfer size is long word */
#define D_ACH 0x08 /* array chaining */
#define D_LACH 0x0C /* linked array chaining */
#define D_ARQ 0x03 /* auto request first transfer, then external*/
#define D_XRQ 0x02 /* external request mode */
#define D_ARM 0x01 /* auto request at maximum rate */
/* Sequence Control Register (scr) bits */
#define D_MCD 0x08 /* memory address counts down */
#define D_MCU 0x04 /* memory address counts up */
#define D_DCD 0x02 /* device address counts down */
#define D_DCU 0x01 /* device address counts up */
/* Channel Control Register (ccr) bits */
#define D_SRT 0x80 /* start channel operation */
#define D_CON 0x40 /* continue */
#define D_HLT 0x20 /* halt channel operation */
#define D_SAB 0x10 /* software abort */
#define D_EINT 0x08 /* enable channel interrupts */
/* Channel Status Register (csr) bits */
#define D_CLEAR 0xFF /* clear all bits */
#define D_COC 0x80 /* channel operation complete */
#define D_BTC 0x40 /* block transfer complete */
#define D_NDT 0x20 /* normal device termination */
#define D_ERR 0x10 /* error as coded in cer */
#define D_ACT 0x08 /* channel active */
#define D_PCLT 0x02 /* PCL transition occurred */
#define D_PCLH 0x01 /* PCL line is high */
#define D_NSRQ 0x01 /* Not SRQ (gpib line) */
/* Channel Error Register (cer) bits */
#define D_ECF 0x01 /* configuration error */
#define D_ETM 0x02 /* operation timing error */
#define D_EMA 0x05 /* memory address error */
#define D_EDA 0x06 /* device address error */
#define D_EBA 0x07 /* base address error */
#define D_EBUS 0x08 /* bus error */
#define D_ECT 0x0C /* transfer count error */
#define D_EEAB 0x01 /* external abort */
#define D_ESAB 0x11 /* software abort */
/* Channel Priority Register (cpr) bits */
#define D_PR1 0x01 /* priority 1 */
#define D_PR2 0x02 /* priority 2 */
#define D_PR3 0x03 /* priority 3 */
/* Function Code Register (fcr) bits */
#define D_SUP 0x04 /* supervisor access */
#define D_S24 0x02 /* standard 24 bit addressing */
#define D_PSA 0x01 /* program space access */
/* Configuration Register 1 (cfg1) bits */
#define D_OUT 0 /* direction memory to GPIB */
#define D_IN (1<<0) /* direction GPIB to memory */
#define D_DBM (1<<1) /* disarm Bus Monitor mode */
#define D_ECC (1<<2) /* arm automatic carry cycle feature */
#define D_BRG0 (00<<3) /* select bus request/grant line 1 */
#define D_BRG1 (01<<3) /* select bus request/grant line 1 */
#define D_BRG2 (02<<3) /* select bus request/grant line 2 */
#define D_BRG3 (03<<3) /* select bus request/grant line 3 */
/* Configuration Register 2 (cfg2) bits */
#define D_SC (1<<0) /* set system controller (SC) bit */
#define D_LMR (1<<1) /* set local master reset bit */
#define D_SPAC (1<<2) /* set supervisor only access to board */
#define D_SFL (1<<3) /* clear SYSFAIL line */
/* Control masks for hidden registers (auxmr) */
#define ICR 0040
#define PPR 0140
#define AUXRA 0200
#define AUXRB 0240
#define AUXRE 0300
#define CNT 0340 /* OR of all of above */
/* 7210 bits: POSITION 7210 reg */
#define HR_DI (1<<0) /* ISR1 */
#define HR_DO (1<<1) /* , */
#define HR_ERR (1<<2) /* , */
#define HR_DEC (1<<3) /* , */
#define HR_END (1<<4) /* , */
#define HR_DET (1<<5) /* , */
#define HR_APT (1<<6) /* , */
#define HR_CPT (1<<7) /* , */
#define HR_DIIE (1<<0) /* IMR1 */
#define HR_DOIE (1<<1) /* , */
#define HR_ERRIE (1<<2) /* , */
#define HR_DECIE (1<<3) /* , */
#define HR_ENDIE (1<<4) /* , */
#define HR_DETIE (1<<5) /* , */
#define HR_ADSC (1<<0) /* ISR2 */
#define HR_REMC (1<<1) /* , */
#define HR_LOKC (1<<2) /* , */
#define HR_CO (1<<3) /* , */
#define HR_REM (1<<4) /* , */
#define HR_LOK (1<<5) /* , */
#define HR_SRQI (1<<6) /* , */
#define HR_INT (1<<7) /* , */
#define HR_ACIE (1<<0) /* IMR2 */
#define HR_REMIE (1<<1) /* , */
#define HR_LOKIE (1<<2) /* , */
#define HR_COIE (1<<3) /* , */
#define HR_DMAI (1<<4) /* , */
#define HR_DMAO (1<<5) /* , */
#define HR_SRQIE (1<<6) /* , */
#define HR_PEND (1<<6) /* SPSR */
#define HR_RSV (1<<6) /* SPMR */
#define HR_MJMN (1<<0) /* ADSR */
#define HR_TA (1<<1) /* , */
#define HR_LA (1<<2) /* , */
#define HR_TPAS (1<<3) /* , */
#define HR_LPAS (1<<4) /* , */
#define HR_SPMS (1<<5) /* , */
#define HR_NATN (1<<6) /* , */
#define HR_CIC (1<<7) /* , */
#define HR_ADM0 (1<<0) /* ADMR */
#define HR_ADM1 (1<<1) /* , */
#define HR_TRM0 (1<<4) /* , */
#define HR_TRM1 (1<<5) /* , */
#define HR_LON (1<<6) /* , */
#define HR_TON (1<<7) /* , */
#define HR_DL (1<<5) /* ADR */
#define HR_DT (1<<6) /* , */
#define HR_ARS (1<<7) /* , */
#define HR_HLDA (1<<0) /* auxra */
#define HR_HLDE (1<<1) /* , */
#define HR_REOS (1<<2) /* , */
#define HR_XEOS (1<<3) /* , */
#define HR_BIN (1<<4) /* , */
#define HR_CPTE (1<<0) /* auxrb */
#define HR_SPEOI (1<<1) /* , */
#define HR_TRI (1<<2) /* , */
#define HR_INV (1<<3) /* , */
#define HR_ISS (1<<4) /* , */
#define HR_PPS (1<<3) /* ppr */
#define HR_PPU (1<<4) /* , */
/* 7210 Auxiliary Commands */
#define AUX_PON 000 /* Immediate Execute pon */
#define AUX_CR 002 /* Chip Reset */
#define AUX_FH 003 /* Finish Handshake */
#define AUX_TRIG 004 /* Trigger */
#define AUX_RTL 005 /* Return to local */
#define AUX_SEOI 006 /* Send EOI */
#define AUX_NVAL 007 /* Non-Valid Secondary Command or Address */
#define AUX_VAL 017 /* Valid Secondary Command or Address */
#define AUX_CPPF 001 /* Clear Parallel Poll Flag */
#define AUX_SPPF 011 /* Set Parallel Poll Flag */
#define AUX_TCA 021 /* Take Control Asynchronously */
#define AUX_TCS 022 /* Take Control Synchronously */
#define AUX_TCSE 032 /* Take Control Synchronously on End */
#define AUX_GTS 020 /* Go To Standby */
#define AUX_LTN 023 /* Listen */
#define AUX_LTNC 033 /* Listen in Continuous Mode */
#define AUX_LUN 034 /* Local Unlisten */
#define AUX_EPP 035 /* Execute Parallel Poll */
#define AUX_SIFC 036 /* Set IFC */
#define AUX_CIFC 026 /* Clear IFC */
#define AUX_SREN 037 /* Set REN */
#define AUX_CREN 027 /* Clear REN */
#define AUX_DSC 024 /* Disable System Control */

View File

@@ -1,44 +0,0 @@
/* share/epicsH/drvGpibErr.h $Id$ */
/* Author: John Winans
* Date: 12-5-91
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 09-13-91 jrw created
*/
#ifndef GPIB_ERRORS
#define GPIB_ERRORS
#include <errMdef.h> /* pick up the M_gpib value */
#define S_IB_ok (M_gpib|0| 0<<1) /* success */
#define S_IB_badPrio (M_gpib|1| 1<<1) /* invalid xact request queue priority */
#define S_IB_A24 (M_gpib|1| 2<<2) /* Out of A24 RAM */
#define S_IB_SIZE (M_gpib|1| 3<<2) /* GPIB I/O buffer size exceeded */
#define S_IB_rfu3 (M_gpib|1| 4<<2) /* reserved for future use #3 */
#define S_IB_rfu4 (M_gpib|1| 5<<2) /* reserved for future use #4 */
#endif

View File

@@ -1,180 +0,0 @@
/* #define GPIB_SUPER_DEBUG */
/* Author: John Winans
* Date: 09-10-91
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 09-13-91 jrw Written on Friday the 13th :-(
* .02 11-07-91 jrw added srqPollInhibit() to the drvGpibSet
* .03 01-07-92 jrw added a reference to ibLink in dpvtGpibHead
*
* $Log$
* Revision 1.1 1996/01/25 21:17:34 mrk
* moved include files from base/include
*
* Revision 1.11 1995/03/17 21:25:58 winans
* Got rid of the old bogus header in the dpvtGpibHead structure.
*
* Revision 1.10 1994/12/12 19:00:16 winans
* Disabled the GPIB_SUPER_DEBUG by default.
*
*/
#ifndef GPIB_INTERFACE
#define GPIB_INTERFACE
#include <callback.h>
#include <drvGpibErr.h>
#include <ellLib.h>
#include <drvBitBusInterface.h> /* To resolve the bitbus struct in dpvt */
#ifdef GPIB_SUPER_DEBUG
#define GPIB_SUPER_DEBUG_HISTORY_SIZ 200
#define GPIB_SUPER_DEBUG_HISTORY_STRLEN 150
/* Super untra detailed debugging stuff used to log everything. */
typedef struct HistoryMsg
{
unsigned long Time;
int DevAddr;
char Msg[GPIB_SUPER_DEBUG_HISTORY_STRLEN];
} HistoryMsgStruct;
typedef struct HistoryStruct
{
SEM_ID Sem;
unsigned long Next; /* Next slot to use in message table */
unsigned long Num; /* Total number of messages */
HistoryMsgStruct Hist[GPIB_SUPER_DEBUG_HISTORY_SIZ];
} HistoryStruct;
#endif
#define BUSY 1 /* deviceStatus value if device is currently busy */
#define IDLE 0 /* deviceStatus value if device is currently idle */
#define TADBASE 0x40 /* offset to GPIB listen address 0 */
#define LADBASE 0x20 /* offset to GPIB talk address 0 */
#define IB_Q_LOW 1 /* priority levels for qGpibReq() */
#define IB_Q_HIGH 2
#define IBAPERLINK 32 /* max number of gpib addresses per link */
/* IOCTL commands supported by the driver */
#define IBNILNK 0 /* returns the max allowable NI links */
#define IBTMO 3 /* one time timeout setting for next GPIB command */
#define IBIFC 4 /* send an interface clear pulse */
#define IBREN 5 /* turn on or off the REN line */
#define IBGTS 6 /* go to controller standby (ATN off...) */
#define IBGTA 7 /* go to active state */
#define IBGENLINK 8 /* ask the driver to start a link running */
#define IBGETLINK 9 /* request address of the ibLink structure */
#define SRQRINGSIZE 50 /* max number of events stored in the SRQ event ring */
#define POLLTIME 5 /* time to wait on DMA during polling */
/******************************************************************************
*
* This structure defines the device driver's entry points.
*
******************************************************************************/
struct drvGpibSet {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
int (*qGpibReq)();
int (*registerSrqCallback)();
int (*writeIb)();
int (*readIb)();
int (*readIbEos)();
int (*writeIbCmd)();
int (*ioctl)();
int (*srqPollInhibit)();
};
/******************************************************************************
*
* The ibLink structure holds all the required link-specific data.
*
******************************************************************************/
struct ibLink {
int linkType; /* the type of link (defined in link.h) */
int linkId; /* the link number of this structure */
int bug; /* bug address if is a bb->gpib connection */
SEM_ID linkEventSem; /* given when this link requires service */
ELLLIST hiPriList; /* list head for high priority queue */
SEM_ID hiPriSem; /* semaphore for high priority queue */
ELLLIST loPriList; /* list head for low priority queue */
SEM_ID loPriSem; /* semaphore for low priority queue */
RING_ID srqRing; /* srq event queue */
int (*srqHandler[IBAPERLINK])(); /* registered srq handlers for link */
caddr_t srqParm[IBAPERLINK]; /* parms to pass to the srq handlers */
char deviceStatus[IBAPERLINK]; /* mark a device as idle or busy */
char pollInhibit[IBAPERLINK]; /* mark a device as non-pollable */
char srqIntFlag; /* set to 1 if an SRQ interrupt has occurred */
#ifdef GPIB_SUPER_DEBUG
HistoryStruct History;
#endif
};
/******************************************************************************
*
* This structure represents the items that are placed on the ibLink->srqRing.
*
******************************************************************************/
struct srqStatus{
unsigned char device; /* device number */
unsigned char status; /* data from the srq poll */
};
/******************************************************************************
*
* All gpib records must have device private structures that begin with the
* following structure.
*
******************************************************************************/
struct dpvtGpibHead {
ELLNODE list;
CALLBACK callback;
int (*workStart)(); /* work start function for the transaction */
int link; /* GPIB link number */
int device; /* GPIB device address for transaction */
struct ibLink *pibLink; /* used by driver */
struct dpvtBitBusHead *bitBusDpvt; /* used on bitbus->gpib links */
int dmaTimeout;
};
int GpibDebug(struct ibLink *pIbLink, int Address, char *Msg, int DBLevel);
#endif

View File

@@ -1,12 +0,0 @@
#ifndef EPICS_DRVHIDEOSGPIB_H
#define EPICS_DRVHIDEOSGPIB_H
typedef int (*GPIB_HIDEOS_WRITECMD_FUNC)(void *td, char *Buf, unsigned long BufLen, unsigned long TimeOut);
typedef int (*GPIB_HIDEOS_WRITE_FUNC)(void *td, char *Buf, unsigned long BufLen, unsigned long devAddr, unsigned long TimeOut);
typedef void *(*GPIB_HIDEOS_INIT_FUNC)(int BoardId, char *TaskName);
typedef int (*GPIB_HIDEOS_READ_FUNC)(void *td, char *Buf, unsigned long BufLen, unsigned long *Actual, unsigned long devAddr, unsigned long TimeOut, long Eos);
typedef int (*GPIB_HIDEOS_WRITEREAD_FUNC)(void *td, char *WBuf, unsigned long WBufLen, char *RBuf, unsigned long RBufLen, unsigned long *RActual, unsigned long devAddr, unsigned long TimeOut, long Eos);
#endif

View File

@@ -1,641 +0,0 @@
/* drvJgvtr1.c */
/* base/src/drv $Id$ */
/*
* Author: Jeff Hill
* Date: 5-89
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* 110689 joh print mem not full message only once
* 120789 joh temporary removal of memory full check
* 050190 joh clear ptr to callback prior to calling
* it so they can rearm from inside the callback
* 071190 joh check STD address after cycle complete detected
* to avoid erroneous card misaddressed messages
* 071190 joh internal sample rate status is bit reversed on the
* card- I added a lookup table to untwist it.
* 020491 ges Change taskDelay from 20 to 2 in "jgvtr1DoneTask".
* To allow rearm and data reads from succesive
* waveform scans up thru 10Hz rates.
* 031491 lrd move data into a local memory area for each card
* 090591 joh converted to V5 vxWorks
* 110591 lrd initialization of cards other than 0 not
* allocating data buffer correctly
* 013092 bg added sysBusToLocalAdrs. Added levels to io_report
* and the ability to read out the Joerger's raw values
* in io_report if level is > 1.
* 031992 joh Took the vxMemProbe out of each arm and checked
* the card present bit instead.
* 062592 bg Combined drvJgvtr1.c and jgvtr_driver.c
* 062992 joh removed file pointer argument added to io
* report by bg
* 082792 joh added ANSI C function prototypes
* 080293 mrk added call to taskwdInsert
* 080493 mgb Removed V5/V4 and EPICS_V2 conditionals
*/
static char *sccsID = "@(#)drvJgvtr1.c 1.17\t9/9/93";
/*
* Code Portions
*
* jgvtr1_init()
* jgvtr1_driver(card, pcbroutine, parg)
* jgvtr1_int_service()
* jgvtr1DoneTask()
* jgvtr1_io_report()
* jgvtr1_stat(card)
*
*/
/* drvJgvtr1.c - Driver Support Routines for Jgvtr1 */
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <vme.h>
#include <iv.h>
#include <dbDefs.h>
#include <epicsPrint.h>
#include <drvSup.h>
#include <module_types.h>
#include <task_params.h>
#include <fast_lock.h>
#include <taskwd.h>
#include <devLib.h>
#include <drvJgvtr1.h>
LOCAL jgvtr1Stat jgvtr1_io_report(
unsigned level
);
LOCAL jgvtr1Stat jgvtr1_init(
void
);
#ifdef INTERRUPT_HARDWARE_FIXED
LOCAL void jgvtr1_int_service(
void
);
#endif
LOCAL void jgvtr1DoneTask(
void
);
LOCAL jgvtr1Stat jgvtr1_dump(
unsigned card,
unsigned n
);
LOCAL jgvtr1Stat jgvtr1_stat(
unsigned card,
int level
);
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvJgvtr1={
2,
jgvtr1_io_report,
jgvtr1_init};
static volatile char *stdaddr;
static volatile char *shortaddr;
#define JGVTR1MAXFREQ 25.0e6
/* NBBY - the number of bits per byte */
#define JGVTR1SHORTSIZE (1<<(NBBY*sizeof(uint8_t)))
#define JGVTR1STDSIZE (1<<(NBBY*sizeof(uint16_t)))
#define JGVTR1_INT_LEVEL 5
#define JGVTR1BASE(CARD)\
(shortaddr+wf_addrs[JGVTR1]+(CARD)*JGVTR1SHORTSIZE)
#define JGVTR1DATA(CARD)\
(stdaddr+wf_memaddrs[JGVTR1]+(CARD)*JGVTR1STDSIZE)
/*
Joerger fixed hardware bug by switching to an inverting tristate buffer
where these commands are read from the VME bus. As a result these commands
are complemented.
*/
#define JGVTR1ARM (~1)
#define JGVTR1START (~2)
#define JGVTR1STOP (~4)
/*
!! our compiler allocates bit fields starting from the ms bit !!
*/
struct jgvtr1_status{
volatile unsigned pad:8;
volatile unsigned internal_frequency:3;
volatile unsigned internal_clock:1;
volatile unsigned cycle_complete:1;
volatile unsigned interrupt:1;
volatile unsigned active:1;
volatile unsigned memory_full:1;
};
struct jgvtr1_config{
char present; /* card present */
char std_ok; /* std addr ok on first read */
void (*psub) /* call back routine */
(void *pprm, unsigned nbytes, uint16_t *pData);
void *pprm; /* call back parameter */
FAST_LOCK lock; /* mutual exclusion */
uint16_t *pdata; /* pointer to the data buffer */
};
/* amount of data to make available from the waveform */
#define JRG_MEM_SIZE 2048
LOCAL
struct jgvtr1_config *pjgvtr1_config;
LOCAL
int jgvtr1_max_card_count;
#ifdef INTERRUPT_HARDWARE_FIXED
LOCAL
SEM_ID jgvtr1_interrupt; /* interrupt event */
#endif
/*
* JGVTR1_INIT
*
* intialize the driver for the joerger vtr1
*
*/
jgvtr1Stat jgvtr1_init(void)
{
unsigned card;
unsigned card_count = 0;
struct jgvtr1_config *pconfig;
uint16_t readback;
jgvtr1Stat status;
status = sysBusToLocalAdrs(
VME_AM_SUP_SHORT_IO,
0,
(char **)&shortaddr);
if (status != OK){
status = S_dev_badA16;
errMessage(status,NULL);
return status;
}
status = sysBusToLocalAdrs(
VME_AM_STD_SUP_DATA,
0,
(char **)&stdaddr);
if (status != OK){
status = S_dev_badA24;
errMessage(status,NULL);
return status;
}
jgvtr1_max_card_count = wf_num_cards[JGVTR1];
if(pjgvtr1_config){
if(FASTLOCKFREE(&pjgvtr1_config->lock)<0)
return ERROR;
free(pjgvtr1_config);
}
pjgvtr1_config =
(struct jgvtr1_config *)
calloc(wf_num_cards[JGVTR1], sizeof(*pjgvtr1_config));
if(!pjgvtr1_config){
status = S_dev_noMemory;
errMessage(status,NULL);
return status;
}
for( card=0, pconfig=pjgvtr1_config;
card < wf_num_cards[JGVTR1];
pconfig++, card++){
FASTLOCKINIT(&pconfig->lock);
status = vxMemProbe( (char *)JGVTR1BASE(card),
READ,
sizeof(readback),
(char *)&readback);
if(status==ERROR)
continue;
pconfig->pdata =
(uint16_t *)malloc(JRG_MEM_SIZE);
/*
not easy to test for correct addressing in
standard address space since the module does
not respond if it has not clocked in data
- so I check this the first time data is ready
*/
pconfig->std_ok = FALSE; /* presumed guilty before tested */
pconfig->present = TRUE;
card_count++;
}
if(!card_count)
return OK;
# ifdef INTERRUPT_HARDWARE_FIXED
jgvtr1_interrupt = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
if(!jgvtr1_interrupt)
return ERROR;
# endif
/* start the waveform readback task */
status = taskSpawn( WFDONE_NAME,
WFDONE_PRI,
WFDONE_OPT,
WFDONE_STACK,
(FUNCPTR) jgvtr1DoneTask,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL);
if(status < 0){
status = S_dev_internal;
errMessage(status, "vxWorks taskSpawn failed");
return status;
}
taskwdInsert(status, NULL, NULL);
# ifdef INTERRUPT_HARDWARE_FIXED
status = intConnect( INUM_TO_IVEC(JGVTR1_INT_VEC),
jgvtr1_int_service,
NULL);
if(status != OK)
return S_dev_internal;
sysIntEnable(JGVTR_INT_LEVEL);
# endif
return JGVTR1_SUCCESS;
}
/*
* JGVTR1_DRIVER
*
* initiate waveform read
*
*/
jgvtr1Stat jgvtr1_driver(
unsigned card,
void (*pcbroutine)(void *, unsigned, uint16_t *),
void *parg
)
{
if(card >= jgvtr1_max_card_count)
return S_dev_badSignalNumber;
if(!pjgvtr1_config[card].present)
return S_dev_noDevice;
if(pjgvtr1_config[card].psub)
return S_dev_badRequest;
FASTLOCK(&pjgvtr1_config[card].lock);
*(volatile uint16_t *)JGVTR1BASE(card) = JGVTR1ARM;
pjgvtr1_config[card].pprm = parg;
pjgvtr1_config[card].psub = pcbroutine;
FASTUNLOCK(&pjgvtr1_config[card].lock);
return JGVTR1_SUCCESS;
}
/*
* JGVTR1_INT_SERVICE
*
* signal via the RTK that an interrupt occured from the joerger vtr1
*
*/
#ifdef INTERRUPT_HARDWARE_FIXED
LOCAL void jgvtr1_int_service(void)
{
semGive(jgvtr1_interrupt);
}
#endif
/*
* JGVTR1DONETASK
*
* wait for joerger vtr1 waveform record cycle complete
* and call back to the database with the waveform size and address
*
*/
LOCAL void jgvtr1DoneTask(void)
{
unsigned card;
struct jgvtr1_config *pconfig;
struct jgvtr1_status stat;
static char started = FALSE;
volatile uint16_t *pdata;
volatile uint16_t *pjgdata;
long i;
/* dont allow two of this task */
if(started)
exit(0);
started = TRUE;
while(TRUE){
# ifdef INTERRUPT_HARDWARE_FIXED
semTake(jgvtr1_interrupt, WAIT_FOREVER);
# else
/* ges: changed from 20 ticks to 2 ticks 2/4/91 */
taskDelay(2);
# endif
for( card=0, pconfig = pjgvtr1_config;
card < jgvtr1_max_card_count;
card++, pconfig++){
if(!pconfig->present)
continue;
if(!pconfig->psub)
continue;
stat = *(struct jgvtr1_status *) JGVTR1BASE(card);
/*
* Wait for the module to finish filling its memory
* or a stop trigger
*/
if(!stat.cycle_complete)
continue;
/*
clear ptr to function here so they
can rearm in the callback
*/
pconfig->psub = NULL;
/*
check the first time for module
correctly addressed
card does not respond at STD address
until it has data
*/
if(!pconfig->std_ok){
uint16_t readback;
int status;
status = vxMemProbe(
(char *)JGVTR1DATA(card),
READ,
sizeof(readback),
(char *)&readback);
if(status==ERROR){
errPrintf(
S_dev_badA24,
__FILE__,
__LINE__,
"jgvtr1 card %d incorrectly addressed- use std addr 0X%X",
card,
JGVTR1DATA(card));
pconfig->present = FALSE;
continue;
}
pconfig->std_ok = TRUE;
}
/*
Test for full memory
( card designer does not give a sample count register )
( instead a bus error returned when on the last sample
to test every location is a lot of overhead so a test
for memory full is used for now )
*/
if(!stat.memory_full){
errMessage(S_dev_internal,
"jgvtr1 driver: proceeding with partial mem");
errMessage(S_dev_internal,
"jgvtr1 driver: beware of bus errors");
}
/* copy the data into a local memory buffer */
/* this is to avoid any bus errors */
for(i = 0,
pdata = pconfig->pdata,
pjgdata = (volatile uint16_t *)JGVTR1DATA(card);
i < JRG_MEM_SIZE/sizeof(uint16_t);
i++, pdata++, pjgdata++){
*pdata = *pjgdata;
}
/*
Post waveform to the database
perhaps the size must be the size below+1 ?
(Joerger's documentation is not clear here)
*/
(*pconfig->psub)(pconfig->pprm,JRG_MEM_SIZE,pconfig->pdata);
}
}
}
/*
*
* JGVTR1_IO_REPORT
*
* print status for all cards in the specified joerger
* vtr1 address range
*
*
*/
LOCAL jgvtr1Stat jgvtr1_io_report(unsigned level)
{
unsigned card;
unsigned nelements;
jgvtr1Stat status;
for(card=0; card < wf_num_cards[JGVTR1]; card++){
status = jgvtr1_stat(card,level);
if(status){
continue;
}
if (level >= 2){
printf("enter the number of elements to dump:");
status = scanf("%d",&nelements);
if(status == 1){
jgvtr1_dump(card, nelements);
}
}
}
return JGVTR1_SUCCESS;
}
/*
*
* JGVTR1_STAT
*
* print status for a single card in the joerger vtr1 address range
*
*
*/
jgvtr1Stat jgvtr1_stat(
unsigned card,
int level
)
{
struct jgvtr1_status stat;
jgvtr1Stat status;
/*
internal freq status is bit reversed so I
use a lookup table
*/
static float sample_rate[8] = {
JGVTR1MAXFREQ/(1<<7),
JGVTR1MAXFREQ/(1<<3),
JGVTR1MAXFREQ/(1<<5),
JGVTR1MAXFREQ/(1<<1),
JGVTR1MAXFREQ/(1<<6),
JGVTR1MAXFREQ/(1<<2),
JGVTR1MAXFREQ/(1<<4),
JGVTR1MAXFREQ/(1<<0)};
static char *clock_status[] =
{"ext-clock", "internal-clk"};
static char *cycle_status[] =
{"cycling", "done"};
static char *interrupt_status[] =
{"", "int-pending"};
static char *activity_status[] =
{"", "active"};
static char *memory_status[] =
{"", "mem-full"};
status = vxMemProbe( (char *)JGVTR1BASE(card),
READ,
sizeof(stat),
(char *)&stat);
if(status != OK)
return ERROR;
if (level == 0)
printf("WF: JGVTR1:\tcard=%d \n",card);
else if (level > 0)
printf( "WF: JGVTR1:\tcard=%d Sample rate=%g %s %s %s %s %s \n",
card,
sample_rate[stat.internal_frequency],
clock_status[ stat.internal_clock ],
cycle_status[ stat.cycle_complete ],
interrupt_status[ stat.interrupt ],
activity_status[ stat.active ],
memory_status[ stat.memory_full ]);
return JGVTR1_SUCCESS;
}
/*
* jgvtr1_dump
*
*/
LOCAL jgvtr1Stat jgvtr1_dump(
unsigned card,
unsigned n
)
{
volatile uint16_t *pjgdata;
uint16_t *pread;
uint16_t *pdata;
unsigned nread;
jgvtr1Stat status;
/* Print out the data if user requests it. */
n = min(JRG_MEM_SIZE,n);
pdata = (uint16_t *)malloc(n * (sizeof(*pdata)));
if(!pdata){
return S_dev_noMemory;
}
pread = pdata;
nread = 0;
pjgdata = (volatile uint16_t *)JGVTR1DATA(card);
while(nread <= (n>>1)){
status = vxMemProbe(
(char *)pjgdata,
READ,
sizeof(*pread),
(char *)pread);
if(status<0){
break;
}
nread++;
pread++;
pjgdata++;
}
for(pread=pdata; pread<&pdata[nread]; pread++){
if ((pread-pdata)%8 == 0){
printf("\n\t");
}
printf( "%02X %02X ",
(unsigned char) ((*pread)>>8),
(unsigned char) *pread);
}
printf("\n");
free(pdata);
return JGVTR1_SUCCESS;
}

View File

@@ -1,43 +0,0 @@
/* drvJgvtr1.h */
/* base/src/drv $Id$ */
/*
* Author: Jeff Hill
* Date: 5-89
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
*/
typedef long jgvtr1Stat;
#define JGVTR1_SUCCESS 0
jgvtr1Stat jgvtr1_driver(
unsigned card,
void (*pcbroutine)(void *, unsigned, uint16_t *),
void *parg
);

File diff suppressed because it is too large Load Diff

View File

@@ -1,485 +0,0 @@
/* share/epicsH $Id$ */
/*
* Author: John Winans
* Date: 11-19-91
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1988, 1989, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* All rights reserved. No part of this publication may be reproduced,
* stored in a retrieval system, transmitted, in any form or by any
* means, electronic, mechanical, photocopying, recording, or otherwise
* without prior written permission of Los Alamos National Laboratory
* and Argonne National Laboratory.
*
* Modification Log:
* -----------------
* .02 05-26-92 jrw added enumeration of record types
* .03 08-10-92 jrw cleaned up the documentation
* & removed multi-parm stuff
*/
#ifndef DEVXXMSG_H
#define DEVXXMSG_H
/******************************************************************************
*
* This structure holds device-related data on a per-device basis and is
* referenced by the xact structures. They are built using a linked
* list starting from parmBlock.phwpvt. There is one linked list for each
* specific device type.
*
* Different types of device links could have different formatted hwpvt structs.
* The msgHwpvt structure includes those fields that are common to all device
* types. The customized part should be attached to msgHwpvt.p during the
* genHwpvt phase if the initilization process.
*
******************************************************************************/
struct msgHwpvt {
struct msgHwpvt *next; /* Next structure for same type device */
struct msgLink *pmsgLink; /* Associated link structure */
unsigned long tmoVal; /* Time last timeout occurred */
unsigned long tmoCount; /* Total timeouts since boot time */
void *p; /* Place to add device-specific fields */
};
typedef struct msgHwpvt msgHwpvt;
/******************************************************************************
*
* Any I/O request made must consist of the msgXact structure defined below.
*
* In general, one EPICS database record will have one and only one of these
* msgXact attached to it's dbCommon.dpvt field.
*
* The message driver system does not reference any database record fields that
* are not in dbCommon -- unless a user-provided function calls a
* record-specific support function.
*
******************************************************************************/
struct msgXact {
CALLBACK callback;
SEM_ID *psyncSem; /* if not NULL, points to sem given w/RX */
struct msgXact *next; /* used to link dpvt's together */
struct msgXact *prev; /* used to link dpvt's together */
struct msgHwpvt *phwpvt; /* assoc'd hwpvt structure */
struct msgParmBlock *pparmBlock; /* assoc'd parm block */
struct dbCommon *prec; /* useful to msg based device support */
unsigned int parm; /* operation parm number */
int status; /* transaction completion status */
void *p; /* A place to add on device specific data */
};
typedef struct msgXact msgXact;
/******************************************************************************
*
* Valid msgXact.status values are:
*
******************************************************************************/
#define XACT_OK 0 /* all went as expected */
#define XACT_LENGTH 1 /* received message overflowed the buffer */
#define XACT_TIMEOUT 3 /* response took too long from node */
#define XACT_BADLINK 4 /* request sent to an invalid link number */
#define XACT_BADPRIO 5 /* request had bad queueing priority */
#define XACT_IOERR 6 /* some sort of I/O error occurred */
#define XACT_BADCMD 7 /* bad command ID-number */
/******************************************************************************
*
* Transaction requests are placed on queues (by the drvMsg_qXact() function)
* when submitted. These queues are described with the xactQueue structure.
*
******************************************************************************/
struct xactQueue {
struct msgXact *head; /* head of the linked list */
struct msgXact *tail; /* tail of the linked list */
FAST_LOCK lock; /* semaphore for the queue list */
};
typedef struct xactQueue xactQueue;
/******************************************************************************
*
* A task is started to manage each message based link. It uses the msgLink
* structure to access the queues of work.
*
* A link is defined by the device-specific part of the genHwpvt() function.
* A link task will be started if the genHwpvt() function invokes the genLink()
* function to define a new link.
*
******************************************************************************/
struct msgLink{
struct xactQueue queue[NUM_CALLBACK_PRIORITIES]; /* prioritized request queues */
struct msgLink *next; /* next in msgDrvBlock list */
SEM_ID linkEventSem;
void *p; /* A place to add on device specific data */
};
typedef struct msgLink msgLink;
/******************************************************************************
*
* The msgParmBlock is defined by the user-contributed device support module.
* It is used to tell the message-driver what device driver to used to perform
* the I/O operations as well as to provide access to the command table, and
* other parameters.
*
* The msgParmBlock contains those parts that are common to all device types.
* Some devices may require more operating parameters. These additional
* parameters should be added via msgParmBlock.p.
*
******************************************************************************/
struct msgParmBlock{
int *debugFlag; /* pointer to debug flag */
struct msgHwpvt *pmsgHwpvt; /* pointer to the hwpvt list for device type */
struct msgCmd *pcmds; /* pointer to command list */
int numCmds; /* number of elements in the command list */
char *name; /* pointer to a string containing device name */
struct msgDrvBlock *pdrvBlock; /* link to the driver hook data structure */
DRVSUPFUN doOp; /* user spec'd operation wedge function */
void *p; /* A place to add device specific data */
};
typedef struct msgParmBlock msgParmBlock;
/******************************************************************************
*
* The msgCmd structure is used to define each entry in the command table.
* This table is used to define all the commands that a specific device type
* can handle.
*
* When a transaction is processed, the following happens:
*
* 1) if A defered read event has occurred, cmd.readOp is called.
* otherwise:
* 1) if cmd.writeOp is non-NULL, it is called and passed wrParm
* The job of writeOp is to send a string to the instrument
* 2) if cmd.readOp is non-NULL, it is called and passed rdParm
* The job of readOp is to read a string from the instrument
*
******************************************************************************/
struct msgCmdOp {
unsigned int op;
void *p;
};
typedef struct msgCmdOp msgCmdOp;
struct msgCmd{
struct msgRecEnum *recTyp;/* used to indicate record type supported */
unsigned int flags; /* 1 if readback is deferred, 0 if not */
struct msgCmdOp writeOp;
struct msgCmdOp readOp;
struct devMsgNames *namelist;/* pointer to name strings */
int companion;
};
typedef struct msgCmd msgCmd;
/* Possible values for msgCmd.flags (OR the set required together) */
#define READ_NDLY 0 /* Do read now */
#define READ_DEFER 1 /* Defer read, an event will signal it */
/******************************************************************************
*
* Valid writeOp and readOp values.
*
* Any user-add-on codes start at MSG_OP_USER and continue upward.
*
******************************************************************************/
#define MSG_OP_NOP 0 /* Do nothing */
#define MSG_OP_WRITE 1 /* Unformatted character write */
#define MSG_OP_FAI 2 /* Read and parse an analog input */
#define MSG_OP_FAO 3 /* Format and output an analog output */
#define MSG_OP_FBI 4 /* Read and parse */
#define MSG_OP_FBO 5 /* Format and output */
#define MSG_OP_FMI 6 /* Read and parse */
#define MSG_OP_FMO 7 /* Format and output */
#define MSG_OP_FLI 8 /* Read and parse */
#define MSG_OP_FLO 9 /* Format and output */
#define MSG_OP_FSI 10 /* Read and parse */
#define MSG_OP_FSO 11 /* Format and output */
#define MSG_OP_RSI 12 /* Read a string raw */
#define MSG_OP_RSO 13 /* Write a string raw */
#define MSG_OP_ACK 14 /* Read string and set alarm if not match */
#define MSG_OP_SBI 15 /* Read string, set BI on substring comparison */
/* NOT CURRENTLY SUPPORTED OPERATIONS */
#if FALSE
#define MSG_OP_EBI /* enumerated operations */
#define MSG_OP_EBO
#define MSG_OP_EMI
#define MSG_OP_EMO
#endif
#define MSG_OP_USER 200 /* Start of user added operation codes */
/******************************************************************************
*
* The following represent the op-codes that can be passed to the
* msgDrvBlock.genlink function.
*
******************************************************************************/
#define MSG_GENLINK_CREATE 0 /* Create structures for a new link */
#define MSG_GENLINK_ABORT 1 /* Link failed init */
/******************************************************************************
*
* Codes that can be returned from event checker routines.
*
******************************************************************************/
#define MSG_EVENT_NONE 0
#define MSG_EVENT_READ 1
#define MSG_EVENT_WRITE 2
/******************************************************************************
*
* This is used to define the strings that are used for button labels.
* These strings are put into the record's znam & onam foelds if the
* record is a BI or BO type and into the zrst, onst... fields of an
* MBBI or MBBO record.
*
* Before these strings are placed into the record, the record is
* check to see if there is already a string defined (could be user-entered
* with DCT.) If there is already a string present, it will be preserved.
*
* There MUST ALWAYS be 2 and only 2 entries in the names.item list
* for BI and BO records if a name list is being specified for them here.
* The names.count field is ignored for BI and BO record types, but
* should be properly specified as 2 for future compatibility.
*
* NOTE:
* If a name string is filled in an an MBBI/MBBO record, it's corresponding
* value will be filled in as well. For this reason, there MUST be
* a value array and a valid nobt value for every MBBI/MBBO record that
* contains an item array!
*
******************************************************************************/
struct drvMsgNames {
int count; /* CURRENTLY only used for MBBI and MBBO */
char **item;
unsigned long *value; /* CURRENTLY only used for MBBI and MBBO */
short nobt; /* CURRENTLY only used for MBBI and MBBO */
};
typedef struct drvMsgNames drvMsgNames;
/******************************************************************************
*
* Public functions available from the message driver.
*
******************************************************************************/
msgXact *drvMsg_genXact();
msgHwpvt *drvMsg_genHwpvt();
msgLink *drvMsg_genLink();
long drvMsg_qXact();
long drvMsg_reportMsg();
long drvMsg_initMsg();
long drvMsg_xactWork();
long drvMsg_initCallback();
long drvMsg_checkParm();
long drvMsg_drvWrite();
long drvMsg_drvRead();
long drvMsg_initAi(), drvMsg_initAo();
long drvMsg_initBi(), drvMsg_initBo();
long drvMsg_initMi(), drvMsg_initMo();
long drvMsg_initLi(), drvMsg_initLo();
long drvMsg_initSi(), drvMsg_initSo();
long drvMsg_initWf();
long drvMsg_procAi(), drvMsg_procAo();
long drvMsg_procBi(), drvMsg_procBo();
long drvMsg_procMi(), drvMsg_procMo();
long drvMsg_procLi(), drvMsg_procLo();
long drvMsg_procSi(), drvMsg_procSo();
long drvMsg_procWf();
long drvMsg_proc();
/******************************************************************************
*
* The msgDrvBlock is used by a message driver designer to specify functions
* that are to be invoked to initialize structures and to check for events
* that might have caused the link task to wake up. This is where hooks to
* device specific functions and data structures are added to the message
* based driver.
*
******************************************************************************/
struct msgDrvBlock{
char *taskName; /* Used for the taskSpawn and messages */
int taskPri; /* Used for the taskSpawn */
int taskOpt; /* Used for the taskSpawn */
int taskStack; /* Used for the taskSpawn */
struct msgLink *pmsgLink; /* associated msgLink list head */
DRVSUPFUN drvWrite; /* Write string from buffer */
DRVSUPFUN drvRead; /* Read string into buffer */
DRVSUPFUN drvIoctl; /* perform device specific control function */
};
typedef struct msgDrvBlock msgDrvBlock;
/* IOCTL functions that each message driver MUST support */
#define MSGIOCTL_REPORT 0
#define MSGIOCTL_INIT 1
#define MSGIOCTL_INITREC 2
#define MSGIOCTL_GENXACT 3
#define MSGIOCTL_GENHWPVT 4
#define MSGIOCTL_GENLINK 5
#define MSGIOCTL_CHECKEVENT 6
#define MSGIOCTL_COMMAND 7 /* device-type specific */
/******************************************************************************
*
* The parameter passed to the IOCTL function is different depending on the
* function-code used in the IOCTL call. These parameters are defined below.
*
******************************************************************************/
struct msgDrvIniParm {
int parm;
struct msgDset *pdset;
};
typedef struct msgDrvIniParm msgDrvIniParm;
struct msgDrvGenXParm {
struct link *plink;
struct msgXact *pmsgXact;
};
typedef struct msgDrvGenXParm msgDrvGenXParm;
struct msgDrvGenHParm {
struct msgParmBlock *pparmBlock;
struct link *plink;
struct msgHwpvt *pmsgHwpvt;
};
typedef struct msgDrvGenHParm msgDrvGenHParm;
struct msgDrvGenLParm {
struct msgLink *pmsgLink;
struct link *plink;
int op;
struct msgParmBlock *pparmBlock;
};
typedef struct msgDrvGenLParm msgDrvGenLParm;
struct msgChkEParm {
struct msgDrvBlock *pdrvBlock;
struct msgLink *pmsgLink;
struct msgXact **pxact;
};
typedef struct msgChkEParm msgChkEParm;
/******************************************************************************
*
* Each DSET ppoints to a msgRecEnum structure. This structure defines the
* type of record the dset represents. The idea here is that the address
* of this structure represents the enumeration value for a given record type.
*
* New record types may be added by the application developer
* by defining a msgRecEnum structure and then using its address in the
* DSET for the new record type.
*
* In the future it is intended that this structure be used to describe
* the locations and types of the I/O sensitive fields within a record.
*
******************************************************************************/
struct msgRecEnum{
char recType[20]; /* Holds string describing record type */
};
typedef struct msgRecEnum msgRecEnum;
extern msgRecEnum drvMsgAi;
extern msgRecEnum drvMsgAo;
extern msgRecEnum drvMsgBi;
extern msgRecEnum drvMsgBo;
extern msgRecEnum drvMsgMi;
extern msgRecEnum drvMsgMo;
extern msgRecEnum drvMsgLi;
extern msgRecEnum drvMsgLo;
extern msgRecEnum drvMsgSi;
extern msgRecEnum drvMsgSo;
extern msgRecEnum drvMsgWf;
/******************************************************************************
*
* This is a modified DSET that is used by device support modules that use
* the message driver's services. It starts the same as a regular DSET, and
* then includes 2 extra pointers. One to the parmBlock structure for the
* device type being defined. And one that points to the record-type
* enumeration structure.
*
******************************************************************************/
struct msgDset{
long number;
DEVSUPFUN funPtr[10];
msgParmBlock *pparmBlock;
msgRecEnum *precEnum;
};
typedef struct msgDset msgDset;
/******************************************************************************
*
* This represents the parameters that are passed to the raw read and raw
* write physical device drivers when data is to be transferred.
*
* It is assumed that the 'len' values found in the following structures
* is the number of valid characters to transfer. There is always a '\0'
* added to the ens of this buffer, so the actual buffer size must be at
* least len+1 bytes long.
*
******************************************************************************/
typedef struct {
char *buf; /* Buffer to hold the data bytes */
int len; /* Max number of bytes to read/write */
int actual; /* actual number of bytes transfered */
} msgStrParm;
/******************************************************************************
*
* The following are the parameters that are passed to the record-specific
* conversion functions. These functions are provided by the message driver
* for convenience only. They are only invoked if the command table contains
* the proper op-codes and/or if the user-supplied code calls them.
*
******************************************************************************/
typedef struct {
char *format; /* Format string for the sprintf function */
} msgFoParm;
typedef struct {
char *format; /* Format string for the sscanf function */
int startLoc; /* where to start scanning the input string from */
int len; /* Max number of bytes to read in */
} msgFiParm;
typedef struct {
char *str; /* value to compare response against */
int index; /* index to start location of comparison */
int len; /* max number of chars to read from device */
} msgAkParm;
typedef struct {
char *str; /* string to compare */
int index; /* character position to start comparison */
int len; /* max bytes to read from device */
} msgSBIParm;
#endif

View File

@@ -1,701 +0,0 @@
/* drvOms.c */
/* base/src/drv $Id$ */
/*
* subroutines and tasks that are used to interface to the
* Oregon Micro Systems six axis stepper motor drivers
*
* Author: Bob Dalesio
* Date: 12-28-89
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log
* -----------------
* .01 02-07-90 lrd add command to read status
* .02 02-09-90 lrd removed the clamp on the MR command
* .03 03-22-90 lrd added the acceleration
* .04 04-12-90 lrd only allow one record to connect to each motor
* .05 04-28-90 lrd request motor data at 10 Hz. Needed delay to let
* motor start moving
* .06 04-30-90 lrd fix interrupt vectors for more than one motor
* .07 07-31-90 lrd lock the communication to the oms card for
* one user
* .08 08-01-90 lrd fix turn off of auxilary output when move is
* complete
* .09 08-01-90 lrd fix the initialization of the card to only
* enable the buffer full interrupt
* .10 10-23-90 lrd clamp the send value to something the motor
* driver can handle
* .11 11-13-90 lrd add intelligence in looking for an OMS card with
* an encoder
* .12 05-15-91 lrd add initialization of encoder and motor position
* .13 09-05-91 joh updated for v5 vxWorks
* .14 12-10-91 bg added sysBusToLocalAddrs(). Added
* compu_sm_driver.c.
* .15 03-10-92 bg Added level to io_report and gave
* compu_sm_io_report() the ability to print out
* contents of motor_data array if level > 1.
* .16 06-26-92 bg Combined drvOms.c with oms_driver.c
* .17 06-29-92 joh took file pointer arg out of io report
* .18 08-11-92 joh io report format cleanup
* .19 08-02-93 mrk Added call to taskwdInsert
* .20 08-05-93 jbk took out 200000 pulse limit
* .21 02-28-94 mrk Replaced itob by cvtLongToString
* .22 05-05-94 kornke Now supports VMEX-8 and VMEX-44E
* (8 axis s'motors and 4 encoded s'motors)
* .23 04-09-96 ric Added SM_FIND_LIMIT, SM_FIND_HOME
*/
/* data requests are made from the oms_task at
* a rate of 10Hz when a motor is active
* post every .1 second or not moving
* requests are sent at 10Hz in oms_task
*/
/* drvOms.c - Driver Support Routines for Oms */
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <intLib.h>
#include <vxLib.h>
#include <rebootLib.h>
#include <taskLib.h>
#include <rngLib.h> /* library for ring buffer support */
#include <semLib.h>
#include <vme.h> /* library to support sysBusToLocalAdrs. */
#include <iv.h>
#include <logLib.h>
#include <string.h>
#include <dbDefs.h>
#include <epicsPrint.h>
#include <drvSup.h>
#include <module_types.h>
#include <drvOms.h>
#include <steppermotor.h>
#include <taskwd.h>
#define OMS_INT_LEV 5
/* If any of the following does not exist replace it with #define <> NULL */
static long report();
static long init();
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvOms={
2,
report,
init};
static long report(level)
int level;
{
oms_io_report(level);
return(0);
}
static long init()
{
oms_driver_init();
return(0);
}
/*
* a rate of 10Hz when a motor is active
* post every .1 second or not moving
* requests are sent at 10Hz in oms_task
*/
/* addresses of all motors present */
struct vmex_motor *oms_motor_present[MAX_OMS_CARDS];
char encoder_present[MAX_OMS_CARDS];
static char *localaddr; /* Local address used to address cards. */
/* motor information */
struct oms_motor oms_motor_array[MAX_OMS_CARDS][MAX_OMS_CHANNELS];
/* motor status - returned to the database library routines */
struct motor_data motor_data_array[MAX_OMS_CARDS][MAX_OMS_CHANNELS];
char oms_motor_specifier[MAX_OMS_CHANNELS+1] = {'X','Y','Z','T','U','V'};
/* scan task parameters */
LOCAL SEM_ID oms_wakeup; /* oms_task wakeup semaphore */
LOCAL SEM_ID oms_send_sem; /* oms_task wakeup semaphore */
/* response task variables */
LOCAL SEM_ID oms_resp_sem; /* wakeup semaphore for the resp task */
LOCAL RING_ID oms_resp_q; /* queue of responses */
/* interrupt routine message buffers */
int resp_inx[MAX_OMS_CARDS];
char read_buffer[MAX_OMS_CARDS][34];
/* forward reference. */
VOID oms_reset();
int oms_intr(card)
register short card;
{
register struct vmex_motor *pmotor;
register int key;
register char inp_char;
register int *pinx;
key = intLock();
/* pointer to this motor */
if ((pmotor = oms_motor_present[card]) == 0){
intUnlock(key);
return(0);
}
pinx = &resp_inx[card];
/* get the next character */
if (pmotor->status & INPUT_BUFFER_FULL){
/* check for end of command */
inp_char = pmotor->data;
if (((inp_char == 0xa) || (inp_char == 0xd)) && (*pinx > 0)){
/* check if the encoder command caused an error */
if (pmotor->status & (OMS_ENCODER | OMS_CMD_ERROR))
encoder_present[card] = FALSE;
else encoder_present[card] = TRUE;
/* terminate and send the message */
read_buffer[card][*pinx] = 0;
if (rngBufPut(oms_resp_q,read_buffer[card],OMS_MSG_SZ)
!= OMS_MSG_SZ){
logMsg("oms_resp_q full\n");
}else{
semGive (oms_resp_sem);
}
*pinx = 0; /* reset buffer */
/* save printable ascii characters */
}else if ((inp_char >= 0x20) && (inp_char < 0x7f)){
if (*pinx == 0){
read_buffer[card][*pinx] = card;
*pinx += 1;
}
if (*pinx < OMS_MSG_SZ){
read_buffer[card][*pinx] = inp_char;
*pinx += 1;
}else{
logMsg("oms intr buffer full\n");
}
}
}
intUnlock(key);
return(0);
}
/*
* STEPPER MOTOR RESPONSE TASK - REMOVES RESPONSES FROM the INTERRUPT QUEUE
*/
short oms_channel[MAX_OMS_CARDS];
short oms_state[MAX_OMS_CARDS];
char off_msg[40];
int oms_debug = 0;
int oms_compare = 3;
int oms_resp_task()
{
unsigned char resp[OMS_MSG_SZ*4];
register struct motor_data *pmotor_data_array;
register struct oms_motor *poms_motor_array;
short *pchannel;
int (*psmcb_routine)();
register short *pstate;
register short card;
int temp;
FOREVER {
/* wait for somebody to wake us up */
semTake (oms_resp_sem, WAIT_FOREVER);
/* process requests in the command ring buffer */
while (rngBufGet(oms_resp_q,resp,OMS_MSG_SZ) == OMS_MSG_SZ){
if (oms_debug)
printf("card: %d msg:%s\n",resp[0],&resp[1]);
/* get the card number and pointers to the state and channel */
card = resp[0];
pchannel = &oms_channel[card];
pstate = &oms_state[card];
pmotor_data_array = &motor_data_array[card][*pchannel];
poms_motor_array = &oms_motor_array[card][*pchannel];
/* motor selection */
if (resp[1] == 'A')
{
switch (resp[2])
{
case 'X':
*pchannel = 0;
break;
case 'Y':
*pchannel = 1;
break;
case 'Z':
*pchannel = 2;
break;
case 'T':
*pchannel = 3;
break;
case 'U':
*pchannel = 4;
break;
case 'V':
*pchannel = 5;
break;
case 'R':
*pchannel = 6;
break;
case 'S':
*pchannel = 7;
break;
}
*pstate = 0;
/* position readback */
}else if (resp[1] == 'R'){
if (resp[2] == 'E') *pstate = 1;
else if (resp[2] == 'P') *pstate = 2;
else if (resp[2] == 'A') *pstate = 3;
else *pstate = 0;
/* convert encoder position */
}else if (*pstate == 1){
sscanf(&resp[1],"%d",&temp);
pmotor_data_array->encoder_position = temp;
*pstate = 0;
/* convert motor position */
/* use the motor position for detecting end of motion because */
/* all motors use this, not all motors have encoders */
}else if (*pstate == 2){
sscanf(&resp[1],"%d",&temp);
if ((pmotor_data_array->motor_position == temp)
&& (poms_motor_array->active == TRUE)){
poms_motor_array->stop_count++;
if (poms_motor_array->stop_count >= oms_compare) {
poms_motor_array->active = FALSE;
strcpy(off_msg,"AB\nAN\n");
off_msg[1] = oms_motor_specifier[*pchannel];
oms_send_msg(oms_motor_present[card],off_msg);
poms_motor_array->stop_count = 0;
}
}else{
pmotor_data_array->motor_position = temp;
poms_motor_array->stop_count = 0;
}
*pstate = 0;
/* convert axis status */
}else if (*pstate == 3){
pmotor_data_array->ccw_limit = 0;
pmotor_data_array->cw_limit = 0;
if (resp[1] == 'P'){
pmotor_data_array->direction = 0;
if (resp[3] == 'L'){
pmotor_data_array->ccw_limit= 1;
}
}else{
pmotor_data_array->direction = 1;
if (resp[3] == 'L'){
pmotor_data_array->cw_limit = 1;
}
}
pmotor_data_array->moving = poms_motor_array->active;
*pstate = 0;
/* post every .1 second or not moving */
if ((poms_motor_array->update_count-- <= 0)
|| (pmotor_data_array->moving == 0)){
if (poms_motor_array->callback != 0){
(int)psmcb_routine = poms_motor_array->callback;
(*psmcb_routine)(pmotor_data_array,poms_motor_array->callback_arg);
}
if (pmotor_data_array->moving){
poms_motor_array->update_count = 2;
}else{
poms_motor_array->update_count = 0;
}
}
/* reset state */
}else{
*pstate = 0;
}
}
}
}
int oms_task()
{
register short motor_active;
register short card,channel;
char oms_msg[40];
register struct vmex_motor *pmotor;
while(1){
semTake(oms_wakeup, WAIT_FOREVER);
motor_active = TRUE;
while (motor_active){
motor_active = FALSE;
taskDelay(2);
for (channel = 0; channel < MAX_OMS_CHANNELS; channel++){
pmotor = oms_motor_present[0];
for (card = 0; card < MAX_OMS_CARDS; card++,pmotor++){
if (pmotor == 0) continue;
if (oms_motor_array[card][channel].active){
motor_active = TRUE;
/* request status data */
if ((channel <= 3) && (encoder_present[card]))
strcpy(oms_msg,"A?\nRE\nRP\nRA\n");
else
strcpy(oms_msg,"A?\nRP\nRA\n");
oms_msg[1] = oms_motor_specifier[channel];
oms_send_msg(oms_motor_present[card],oms_msg);
}
}
}
}
}
}
/*
* OMS_DRIVER_INIT
*
* initialize all oms drivers present
*/
int oms_driver_init(){
struct vmex_motor *pmotor;
short i,j,got_one;
int status;
short dummy;
int taskId;
for (i = 0; i < MAX_OMS_CARDS; i++){
resp_inx[i] = 0;
}
/* find all cards present */
got_one = FALSE;
status = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,sm_addrs[OMS_6AXIS], &localaddr);
if (status != OK){
logMsg("Addressing error in oms driver\n");
return(ERROR);
}
rebootHookAdd(oms_reset);
pmotor = (struct vmex_motor *)localaddr;
for (i = 0; i < MAX_OMS_CARDS; i++,pmotor++){
if (vxMemProbe(pmotor,READ,sizeof(short),&dummy) == OK){
got_one = TRUE;
/* intialize the motor */
pmotor->control = 0;
/* interrupt vector */
pmotor->vector = 0x80+i;
intConnect(INUM_TO_IVEC(0x80+i),oms_intr,i);
sysIntEnable(OMS_INT_LEV);
/* enable interrupt on input buffer full */
pmotor->control |= 0xa0;
/* mark the motor card as present */
oms_motor_present[i] = pmotor;
encoder_present[i] = TRUE;
}else{
/* mark the motor card as not present */
oms_motor_present[i] = 0;
}
for (j = 0; j < MAX_OMS_CHANNELS; j++){
oms_motor_array[i][j].active = FALSE;
oms_motor_array[i][j].callback = 0;
motor_data_array[i][j].encoder_position = 0;
motor_data_array[i][j].motor_position = 0;
}
}
if (got_one){
/* initialize the command task ring buffer */
if ((oms_resp_q = rngCreate(OMS_RESP_Q_SZ)) == (RING_ID)NULL)
panic ("oms_driver_init: oms_resp_q not created\n");
/* initialize the oms response task semaphore */
if(!(oms_resp_sem=semBCreate(SEM_Q_FIFO,SEM_EMPTY)))
errMessage(0,"semBcreate failed in oms_driver_init");
/* intialize the data request wakeup semaphore */
if(!(oms_wakeup=semBCreate(SEM_Q_FIFO,SEM_EMPTY)))
errMessage(0,"semBcreate failed in oms_driver_init");
/* oms card mutual exclusion semaphore */
if(!(oms_send_sem=semBCreate(SEM_Q_FIFO,SEM_FULL)))
errMessage(0,"semBcreate failed in oms_driver_init");
/* spawn the motor data request task */
taskId = taskSpawn("oms_task",42,VX_FP_TASK,8000,oms_task);
taskwdInsert(taskId,NULL,NULL);
/* spawn the motor data request task */
taskId = taskSpawn("oms_resp_task",42,VX_FP_TASK,8000,oms_resp_task);
taskwdInsert(taskId,NULL,NULL);
/* enable echo on each motor that is present */
pmotor = (struct vmex_motor *)localaddr;
for (i = 0; i < MAX_OMS_CARDS; i++,pmotor++){
if (oms_motor_present[i]){
/* give it the initialization commands */
oms_send_msg(pmotor,"EN\nWY\n");
}
}
}
return(0);
}
/*
* OMS_DRIVER
*
* interface routine called from the database library
*/
#define MOTOR_POS 1
int oms_driver(card,channel,value_flag,arg1,arg2)
register short card;
register short channel;
short value_flag;
register int arg1;
int arg2;
{
char oms_move_msg[100];
short i,count;
if (!oms_motor_present[card]) return(-1);
switch (value_flag){
case (SM_MODE): /* only supports positional mode */
break;
case (SM_VELOCITY):
/* set the velocity */
motor_data_array[card][channel].velocity = arg1;
strcpy(oms_move_msg,"A?\nVL");
oms_move_msg[MOTOR_POS] = oms_motor_specifier[channel];
count = cvtLongToString(arg1,&oms_move_msg[5]);
strcat(oms_move_msg,"\n");
oms_send_msg(oms_motor_present[card],oms_move_msg);
/* set the acceleration */
strcpy(oms_move_msg,"A?\nAC");
oms_move_msg[MOTOR_POS] = oms_motor_specifier[channel];
count = cvtLongToString(arg2,&oms_move_msg[5]);
strcat(oms_move_msg,"\n");
oms_send_msg(oms_motor_present[card],oms_move_msg);
break;
case (SM_FIND_HOME): /* Move to a home switch */
break; /* Not supported by this device */
case (SM_FIND_LIMIT): /* Move to a limit switch */
arg1 = arg1 >= 0 ? 0x000fffff : -0x000fffff;
/* break purposely left out to continue with SM_MOVE */
case (SM_MOVE):
/* move the motor */
strcpy(oms_move_msg,"A?\nAF\nMR");
oms_move_msg[1] = oms_motor_specifier[channel];
count = cvtLongToString(arg1,&oms_move_msg[8]);
strcat(oms_move_msg,"\nGO\n");
oms_send_msg(oms_motor_present[card],oms_move_msg);
/* set the motor to active */
oms_motor_array[card][channel].active = TRUE;
/* wakeup the oms task */
semGive(oms_wakeup);
break;
case (SM_MOTION):
/* stop the motor */
strcpy(oms_move_msg,"A?ST\n");
if (arg1 == 0){
oms_move_msg[1] = oms_motor_specifier[channel];
}else{
return(0);
}
oms_send_msg(oms_motor_present[card],oms_move_msg);
/* wakeup the oms task */
semGive(oms_wakeup);
break;
case (SM_CALLBACK):
i = 0;
if (oms_motor_array[card][channel].callback != 0) return(-1);
oms_motor_array[card][channel].callback = arg1;
oms_motor_array[card][channel].callback_arg = arg2;
break;
/* reset encoder and motor positions to zero */
case (SM_SET_HOME):
/* load the position to be zero */
strcpy(oms_move_msg,"A?\nLP0\n");
oms_move_msg[1] = oms_motor_specifier[channel];
oms_send_msg(oms_motor_present[card],oms_move_msg);
/* set the motor to active */
oms_motor_array[card][channel].active = TRUE;
/* wakeup the oms task */
semGive(oms_wakeup);
break;
case (SM_ENCODER_RATIO):
/* set the encoder ratio */
/* The "ER" command changes how far a pulse will move the */
/* motor. */
/* As this is not the desired action this command is not */
/* implemented here. */
break;
case (SM_READ):
/* set the motor to active */
oms_motor_array[card][channel].active = TRUE;
/* wakeup the oms task */
semGive(oms_wakeup);
break;
}
return(0);
}
char last_msg[80];
int oms_count,oms_icount,oms_illcmd,oms_sleep,oms_isleep;
/*
* OMS_SEND_MSG
*
* Gives messages to the OMS card
*/
int oms_send_msg(pmotor,pmsg)
struct vmex_motor *pmotor;
register char *pmsg;
{
int i;
i = 0;
/* take the mutual exclusion semaphore */
semTake(oms_send_sem, WAIT_FOREVER);
while (*pmsg){
if (pmotor->status & 0x01){
oms_illcmd++;
while ((pmotor->status & TRANSMIT_BUFFER_EMPTY) == 0){
oms_icount++;
if ((oms_icount % 5) == 0){
oms_isleep++;
/* A taskDelay makes a 68040 wait frequently */
/*taskDelay(1);*/
}
}
pmotor->data = 0x19; /* reset */
}else{
while ((pmotor->status & TRANSMIT_BUFFER_EMPTY) == 0){
oms_count++;
if ((oms_count % 5) == 0){
oms_sleep++;
/* A taskDelay makes a 68040 wait frequently */
/*taskDelay(1);*/
}
}
pmotor->data = *pmsg;
pmsg++;
}
}
/* release the mutual exclusion semaphore */
semGive(oms_send_sem);
return(0);
}
int oms_io_report(level)
short int level;
{
register short int i,j;
for (i = 0; i < MAX_OMS_CARDS; i++) {
if (oms_motor_present[i]){
printf("SM: OMS:\tcard %d\n",i);
for (j = 0; j < MAX_OMS_CHANNELS; j++){
if (level > 0)
oms_sm_stat(i,j);
}
}
}
return(0);
}
VOID oms_sm_stat(card,channel)
short int card,channel;
{
printf("SM: OMS: Card = %d,channel = %d\n",card,channel);
printf("\tCW limit = %d\tCCW limit = %d\tMoving = %d\tDirection = %d\n",
motor_data_array[card][channel].cw_limit,
motor_data_array[card][channel].ccw_limit,
motor_data_array[card][channel].moving,
motor_data_array[card][channel].direction);
printf("\tConstant Velocity = %ld\tVelocity = %ld\t \n",
motor_data_array[card][channel].constant_velocity,
motor_data_array[card][channel].velocity);
printf("\tAcceleration = %ld\tEncoder Position = %ld\tMotor Position = %ld\n",
motor_data_array[card][channel].accel,
motor_data_array[card][channel] .encoder_position,
motor_data_array[card][channel].motor_position);
}
/*
*
* Disables interrupts. Called on CTL X reboot.
*
*/
VOID oms_reset(){
short card;
struct vmex_motor *pmotor;
short dummy;
pmotor = (struct vmex_motor *)localaddr;
for (card = 0; card < MAX_OMS_CARDS; card++,pmotor++){
if(vxMemProbe(pmotor,READ,sizeof(short),&dummy) == OK){
pmotor->control &= 0x5f;
}
}
}

View File

@@ -1,74 +0,0 @@
/* oms_sm_driver.h */
/* base/src/drv $Id$ */
/*
* headers that are used to interface to the
* Oregon Micro Systems six axis stepper motor drivers
*
* Author: Bob Dalesio
* Date: 02-25-90
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 04-12-90 lrd only allow one connection to each motor
* .02 11-13-90 lrd add status bit definitions for encoder commands
* .03 05-05-94 kornke supports 8 OMS channels now
*/
#define MAX_OMS_CARDS 8
#define MAX_OMS_CHANNELS 8
/* motor information */
struct oms_motor{
short active; /* flag to tell the oms_task if the motor is moving */
int callback; /* routine in database library to call with status */
int callback_arg; /* argument to callback routine */
short update_count;
short stop_count;
};
#define MIRQE 0x80
#define TRANSMIT_BUFFER_EMPTY 0x40
#define INPUT_BUFFER_FULL 0x20
#define MDONE 0x10
#define OMS_ENCODER 0x04
#define OMS_CMD_ERROR 0x01
struct vmex_motor{
char unused0;
char data;
char unused1;
char done;
char unused2;
char control;
char unused3;
char status;
char unused4;
char vector;
char unused5[6];
};
/* oms message defines */
#define OMS_MSG_SZ 32 /* response message size */
#define OMS_RESP_Q_SZ (OMS_MSG_SZ*500) /* response ring buffer size */

View File

@@ -1,541 +0,0 @@
/* base/src/drv $Id$ */
/*
* Author: John Winans
* Date: 04-13-92
* EPICS R/S-232 driver for the VxWorks's tty driver
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 09-30-91 jrw created
*
*/
#define DRVRS232_C
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <dbDefs.h>
#include <epicsPrint.h>
#include <task_params.h>
#include <module_types.h>
#include <drvSup.h>
#include <devSup.h>
#include <dbCommon.h>
#include <dbAccess.h>
#include <link.h>
#include <callback.h>
#include <fast_lock.h>
#include <drvMsg.h>
#include <drvRs232.h>
#include <drvTy232.h>
int drv232Debug = 0;
static void callbackAbortSerial();
static void dogAbortSerial();
/******************************************************************************
*
******************************************************************************/
#define RSLINK_PRI 50
#define RSLINK_OPT VX_FP_TASK|VX_STDIO
#define RSLINK_STACK 5000
/******************************************************************************
*
******************************************************************************/
static long
report()
{
printf("Report for RS-232 driver\n");
return(OK);
}
/******************************************************************************
*
******************************************************************************/
static long
init(pparms)
msgDrvIniParm *pparms;
{
if (drv232Debug)
printf("Init for RS-232 driver\n");
return(OK);
}
/******************************************************************************
*
* This function is called to allocate any structures needed to hold
* device-specific data that is added to the msgXact structure.
*
* It is also responsible for filling in the msgXact.phwpvt pointer.
*
******************************************************************************/
static long
genXact(p)
msgDrvGenXParm *p;
{
long stat = -1;
char message[100];
devTy232Link *pdevTy232Link;
if (drv232Debug)
printf("RS-232 genXact entered for link %d, addr %d, parm %s\n", p->plink->value.gpibio.link, p->plink->value.gpibio.addr, p->plink->value.gpibio.parm);
p->pmsgXact->phwpvt = p->pmsgXact->pparmBlock->pmsgHwpvt;
while ((p->pmsgXact->phwpvt != NULL) && (stat == -1))
{
pdevTy232Link = (devTy232Link *)(p->pmsgXact->phwpvt->pmsgLink->p);
if ((pdevTy232Link->link == p->plink->value.gpibio.link)
&& (pdevTy232Link->port == p->plink->value.gpibio.addr))
{
if (pdevTy232Link->pparmBlock != p->pmsgXact->pparmBlock)
{
sprintf(message, "%s: Two different devices on same RS-232 port\n", p->pmsgXact->prec->name);
errMessage(S_db_badField, message);
return(ERROR);
}
else
stat = 0; /* Found the correct hwpvt structure */
}
else
p->pmsgXact->phwpvt = p->pmsgXact->phwpvt->next;
}
if (stat != 0)
{ /* Could not find a msgHwpvt for the right link, create a new one */
if ((p->pmsgXact->phwpvt = drvMsg_genHwpvt(p->pmsgXact->pparmBlock, p->plink)) == NULL)
return(ERROR);
}
p->pmsgXact->callback.callback = NULL;
p->pmsgXact->psyncSem = NULL;
if (sscanf(p->plink->value.gpibio.parm,"%d", &(p->pmsgXact->parm)) != 1)
{
p->pmsgXact->prec->pact = TRUE;
sprintf("%s: invalid parameter string >%s<\n", p->pmsgXact->prec->name, p->plink->value.gpibio.parm);
errMessage(S_db_badField, message);
return(ERROR);
}
return(OK);
}
/******************************************************************************
*
* This function is called to allocate any structures needed to hold
* device-specific data that is added to the msgHwpvt structure.
*
* It is also responsible for filling in the msgHwpvt.pmsgLink pointer.
*
******************************************************************************/
static long
genHwpvt(p)
msgDrvGenHParm *p;
{
int stat = ERROR;
if (drv232Debug)
printf("rs232-genHwpvt entered\n");
p->pmsgHwpvt->pmsgLink = drv232Block.pmsgLink;
while ((p->pmsgHwpvt->pmsgLink != NULL) && (stat == ERROR))
{
if ((((devTy232Link *)(p->pmsgHwpvt->pmsgLink->p))->link == p->plink->value.gpibio.link)
&& (((devTy232Link *)(p->pmsgHwpvt->pmsgLink->p))->port == p->plink->value.gpibio.addr))
stat = OK;
else
p->pmsgHwpvt->pmsgLink = p->pmsgHwpvt->pmsgLink->next;
}
if (stat != OK)
{
if ((p->pmsgHwpvt->pmsgLink = drvMsg_genLink(p->pparmBlock, p->plink)) == NULL)
return(ERROR);
}
return(OK);
}
/******************************************************************************
*
* This function is called to allocate any structures needed to hold
* device-specific data that is added to the msgLink structure.
*
******************************************************************************/
static long
genLink(p)
msgDrvGenLParm *p;
{
char name[20];
char message[100];
devTy232Link *pdevTy232Link;
if (drv232Debug)
printf("In RS-232's genLink, link = %d, addr = %d\n", p->plink->value.gpibio.link,p->plink->value.gpibio.addr);
switch (p->op) {
case MSG_GENLINK_CREATE:
if ((p->pmsgLink->p = malloc(sizeof(devTy232Link))) == NULL)
return(ERROR);
pdevTy232Link = (devTy232Link *)(p->pmsgLink->p);
pdevTy232Link->link = p->plink->value.gpibio.link;
pdevTy232Link->port = p->plink->value.gpibio.addr;
pdevTy232Link->pparmBlock = p->pparmBlock;
if ((pdevTy232Link->doggie = wdCreate()) == NULL)
{
printf("RS-232 driver can't create a watchdog\n");
/* errMessage(******, message); */
return(ERROR);
}
sprintf(name, "/tyCo/%d", p->plink->value.gpibio.addr);
if (drv232Debug)
printf ("in genlink opening >%s<, baud %d\n", name, ((devTy232ParmBlock *)(p->pparmBlock->p))->baud);
if ((((devTy232Link *)(p->pmsgLink->p))->ttyFd = open(name, O_RDWR, 0)) != -1)
{
if (drv232Debug)
printf("Successful open w/fd=%d\n", pdevTy232Link->ttyFd);
/* set baud rate and unbuffered mode */
(void) ioctl (pdevTy232Link->ttyFd, FIOBAUDRATE, ((devTy232ParmBlock *)(p->pparmBlock->p))->baud);
(void) ioctl (pdevTy232Link->ttyFd, FIOSETOPTIONS, ((devTy232ParmBlock *)(p->pparmBlock->p))->ttyOptions);
pdevTy232Link->callback.callback = callbackAbortSerial;
pdevTy232Link->callback.priority = priorityHigh;
pdevTy232Link->callback.user = (void *) pdevTy232Link;
return(OK);
}
else
{
printf("RS-232 genLink failed to open the tty port\n");
free(p->pmsgLink->p);
return(ERROR);
}
case MSG_GENLINK_ABORT:
if (drv232Debug)
printf("RS-232 genLink called with abort status\n");
pdevTy232Link = (devTy232Link *)(p->pmsgLink->p);
/* free(p->pmsgLink->p); Don't forget to take it out of the list */
return(OK);
}
return(ERROR);
}
/******************************************************************************
*
* This function is called to allow the device to indicate that a device-related
* event has occurred. If an event had occurred, it would have to place the
* address of a valid transaction structure in pxact. This xact structure
* will then be processed by the message link task as indicated by the
* return code of this function.
*
* MSG_EVENT_NONE = no event has occurred, pxact not filled in.
* MSG_EVENT_WRITE = event occurred, process the writeOp assoc'd w/pxact.
* MSG_EVENT_READ = event occurred, process the readOp assoc'd w/pxact.
*
* Note that MSG_EVENT_READ only makes sense when returned with a transaction
* that has deferred readback specified for its readOp function. Because if
* it is NOT a deferred readback, it will be done immediately after the writeOp.
* Even if that writeOp was due to a MSG_EVENT_WRITE from this function.
*
******************************************************************************/
static long
checkEvent(p)
msgChkEParm *p;
{
return(MSG_EVENT_NONE);
}
static void
dogAbortSerial(pdevTy232Link)
devTy232Link *pdevTy232Link;
{
logMsg("RS-232 driver watch-dog timeout on link %d, port %d, fd=%d\n", pdevTy232Link->link, pdevTy232Link->port, pdevTy232Link->ttyFd);
/* Annoying vxWorks implementation... can't IOCTL from here */
callbackRequest(&(pdevTy232Link->callback));
}
static void
callbackAbortSerial(p)
CALLBACK *p;
{
((devTy232Link *)(p->user))->dogAbort = TRUE;
ioctl(((devTy232Link *)(p->user))->ttyFd, FIOCANCEL);
/* I am not sure if I should really do this, but... */
ioctl(((devTy232Link *)(p->user))->ttyFd, FIOFLUSH);
}
/******************************************************************************
*
* This function is used to write a string of characters out to an RS-232
* device.
*
******************************************************************************/
static long
drvWrite(pxact, pwrParm)
msgXact *pxact;
msgStrParm *pwrParm;
{
devTy232Link *pdevTy232Link = (devTy232Link *)(pxact->phwpvt->pmsgLink->p);
int len;
char *out;
char in;
if (wdStart(pdevTy232Link->doggie, ((devTy232ParmBlock *)(pxact->pparmBlock->p))->dmaTimeout, dogAbortSerial, pdevTy232Link) == ERROR)
{
printf("RS-232 driver can not start watchdog timer\n");
/* errMessage(***,message); */
pxact->status = XACT_IOERR;
return(pxact->status);
}
if (((devTy232ParmBlock *)(pxact->pparmBlock->p))->flags & ECHO)
{ /* ping-pong the characters out */
/*BUG ??? This will only work if we are sure that the RX buffer is clean */
ioctl(pdevTy232Link->ttyFd, FIORFLUSH);
out = pwrParm->buf;
while ((*out != '\0') && (pxact->status == XACT_OK))
{
if (drv232Debug > 5)
printf("out >%c<\n", *out);
if (write(pdevTy232Link->ttyFd, out, 1) != 1)
{
printf("RS-232 write error on link %d, port %d\n", pdevTy232Link->link, pdevTy232Link->port);
pxact->status = XACT_IOERR;
}
else
{
if (read(pdevTy232Link->ttyFd, &in, 1) != 1)
{
printf("Read problem encountered in echo reading mode of a write operation\n");
if (pdevTy232Link->dogAbort)
pxact->status = XACT_TIMEOUT;
else
pxact->status = XACT_IOERR;
}
else
{
if (*out != in)
printf("echo response out of sync! sent >%c< got >%c<\n", *out, in);
if (drv232Debug > 5)
printf("in >%c<\n", in);
if ((*out == '\r') && (((devTy232ParmBlock *)(pxact->pparmBlock->p))->flags & CRLF))
{
if (read(pdevTy232Link->ttyFd, &in, 1) != 1)
{
printf("Read problem encountered in echo reading mode of a write operation\n");
if (pdevTy232Link->dogAbort)
pxact->status = XACT_TIMEOUT;
else
pxact->status = XACT_IOERR;
}
else
{
if (drv232Debug > 5)
printf("in >%c<\n", in);
}
}
}
}
out++;
}
}
else
{
if (pwrParm->len == -1)
len = strlen(pwrParm->buf);
else
len = pwrParm->len;
if (drv232Debug > 4)
printf("block-writing >%s<\n", pwrParm->buf);
if (write(pdevTy232Link->ttyFd, pwrParm->buf, len) != len)
{
printf("RS-232 write error on link %d, port %d\n", pdevTy232Link->link, pdevTy232Link->port);
pxact->status = XACT_IOERR;
}
}
if (wdCancel(pdevTy232Link->doggie) == ERROR)
printf("Can not cancel RS-232 watchdog timer\n");
return(pxact->status);
}
/******************************************************************************
*
* This function is used to read a string of characters from an RS-232 device.
*
******************************************************************************/
static long
drvRead(pxact, prdParm)
msgXact *pxact;
msgStrParm *prdParm;
{
devTy232Link *pdevTy232Link = (devTy232Link *)(pxact->phwpvt->pmsgLink->p);
int len;
int clen;
char *ch;
int flags;
int eoi;
devTy232ParmBlock *pdevTy232ParmBlock = (devTy232ParmBlock *)(pxact->pparmBlock->p);
pdevTy232Link->dogAbort = FALSE;
if (wdStart(pdevTy232Link->doggie, pdevTy232ParmBlock->dmaTimeout, dogAbortSerial, pdevTy232Link) == ERROR)
{
printf("RS-232 driver can not start watchdog timer\n");
/* errMessage(***,message); */
pxact->status = XACT_IOERR;
return(pxact->status);
}
ch = prdParm->buf;
len = prdParm->len - 1;
flags = pdevTy232ParmBlock->flags;
/* BUG -- This should have a timeout check specified in here */
if ((pdevTy232ParmBlock->eoi != -1) || (flags & KILL_CRLF))
{
eoi = 0;
while ((!eoi) && (len > 0))
{
if (read(pdevTy232Link->ttyFd, ch, 1) != 1)
{
printf("Read problem encountered in eoi/KILL_CRLF reading mode\n");
if (pdevTy232Link->dogAbort)
pxact->status = XACT_TIMEOUT;
else
pxact->status = XACT_IOERR;
eoi = 1;
}
else
{
if (drv232Debug > 6)
printf("in >%c<\n", *ch);
if (*ch == pdevTy232ParmBlock->eoi)
eoi = 1;
if (!(flags & KILL_CRLF) || ((*ch != '\n') && (*ch != '\r')))
{
ch++;
len--; /* To count the \n's and \r's or not to count... */
}
}
}
if (len == 0)
{
printf("buffer length overrun during read operation\n");
pxact->status = XACT_LENGTH;
}
*ch = '\0';
}
else
{ /* Read xact->rxLen bytes from the device */
while(len)
{
clen = read(pdevTy232Link->ttyFd, ch, len);
if (pdevTy232Link->dogAbort)
{
printf("Read problem encountered in raw mode\n");
pxact->status = XACT_TIMEOUT;
len = 0;
}
else
{
len -= clen;
ch += clen;
}
}
*ch = '\0';
}
if (drv232Debug)
printf("drvRead: got >%s<\n", prdParm->buf);
if (wdCancel(pdevTy232Link->doggie) == ERROR)
printf("Can not cancel RS-232 watchdog timer, dogAbort=%d \n", pdevTy232Link->dogAbort);
return(pxact->status);
}
static long
drvIoctl(cmd, pparm)
int cmd;
void *pparm;
{
switch (cmd) {
case MSGIOCTL_REPORT:
return(report());
case MSGIOCTL_INIT:
return(init(pparm));
case MSGIOCTL_INITREC:
printf("drv232Block.drvIoctl got a MSGIOCTL_INITREC request!\n");
return(ERROR);
case MSGIOCTL_GENXACT:
return(genXact(pparm));
case MSGIOCTL_GENHWPVT:
return(genHwpvt(pparm));
case MSGIOCTL_GENLINK:
return(genLink(pparm));
case MSGIOCTL_CHECKEVENT:
return(checkEvent(pparm));
case MSGIOCTL_COMMAND: /* BUG -- finish this routine! */
return(ERROR);
}
return(ERROR);
}
msgDrvBlock drv232Block = {
"RS232",
RSLINK_PRI,
RSLINK_OPT,
RSLINK_STACK,
NULL,
drvWrite,
drvRead,
drvIoctl
};

View File

@@ -1,51 +0,0 @@
/* share/epicsH $Id$ */
/*
* Author: John Winans
* Date: 04-16-92
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1988, 1989, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* All rights reserved. No part of this publication may be reproduced,
* stored in a retrieval system, transmitted, in any form or by any
* means, electronic, mechanical, photocopying, recording, or otherwise
* without prior written permission of Los Alamos National Laboratory
* and Argonne National Laboratory.
*
* Modification Log:
* -----------------
* .01 04-16-92 jrw Initial release
* .02 07-04-92 jrw Moved tty-specific stuff to devTy232.h
*
* This file contains the common parts of the RS-232 device support info.
*/
#ifndef EPICS_DRVRS232_H
#define EPICS_DRVRS232_H
typedef struct {
int cmd;
void *pparm;
} ioctlCommand;
#define IOCTL232_BREAK 1
#endif

View File

@@ -1,74 +0,0 @@
/* share/epicsH $Id$ */
/*
* Author: John Winans
* Date: 04-16-92
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1988, 1989, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* All rights reserved. No part of this publication may be reproduced,
* stored in a retrieval system, transmitted, in any form or by any
* means, electronic, mechanical, photocopying, recording, or otherwise
* without prior written permission of Los Alamos National Laboratory
* and Argonne National Laboratory.
*
* Modification Log:
* -----------------
* .01 04-16-92 jrw Initial release
*/
#ifndef EPICS_DEVTY232_H
#define EPICS_DEVTY232_H
/******************************************************************************
*
* Additional fields needed for the msgParmBlock structure.
*
******************************************************************************/
typedef struct {
int timeWindow; /* Clock ticks to skip after a timeout */
int dmaTimeout; /* Clock ticks to wait for DMA to complete */
int flags; /* set to FALSE if does NOT echo characters */
int eoi; /* eoi char value or -1 if none */
int baud; /* baud rate to run the interface */
int ttyOptions; /* ioctl options for the serial port */
} devTy232ParmBlock;
#define ECHO 1 /* Device echos characters sent to it */
/* The CRLF option is only valid when ECHO is set */
#define CRLF 2 /* Device does CR -> CR LF expansion */
#define KILL_CRLF 4 /* Remove all CR and LF characters from input */
typedef struct {
CALLBACK callback; /* Used to do the ioctl when the dog wakes up */
WDOG_ID doggie; /* For I/O timing */
int dogAbort; /* Used to flag a timeout */
int link; /* The tty card/link number */
int port; /* The tty port number on that card */
int ttyFd; /* The open file descriptor */
/* The pparmBlock is used to make sure only 1 device type is requested */
/* on one single port. */
msgParmBlock *pparmBlock;
} devTy232Link;
extern msgDrvBlock drv232Block;
#endif

View File

@@ -1,205 +0,0 @@
/* base/src/drv $Id$ */
/*
* subroutines that are used to interface to the vme analog output cards
*
* Author: Bob Dalesio
* Date: 9-26-88
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 11-09-88 lrd add LED light status to Ziomek-085
* .02 02-08-89 lrd addresses from module_types.h
* use 085 structure
* .03 03-17-89 lrd add ao_read routine
* .04 03-29-89 lrd return correct status on write
* .05 11-20-89 joh added call to the at5 vxi driver
* .06 06-08-90 mrk fixed bug (R Daly found) for VMI4100
* .07 10-31-91 bg broke vmi4100 driver out of ao_driver.c
* broke vmi4100 code out of io_report and
* created vmi400_io_report()
* .08 01-10-92 bg Added levels to io_report and warning message
* that raw values cannot be read from vmi4100
* card even it the level is 1.
* .09 08-05-92 joh arguments to init routine now conform with the
* standard
* .10 08-05-92 joh added EPICS driver dispatch table
* .11 08-05-92 joh moved parameters from ao_driver.h to here
* .12 08-11-92 joh num of cards now dyn configurable
* .13 08-24-93 mrk removed use of variable base_addr
*/
static char *sccsID = "@(#)drvVmi4100.c 1.5\t8/27/93";
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <vxLib.h>
#include <vme.h>
#include <dbDefs.h>
#include <drvSup.h>
#include "module_types.h"
/* VMIVME 4100 defines */
#define MAX_AO_VMI_CARDS (ao_num_cards[VMI4100])
#define VMI_MAXCHAN (ao_num_channels[VMI4100])
#define VMI_ENABLE_OUT 0xc100 /*Fail LED off, enable P3 output.*/
/* memory structure of the Xycom 4100 Interface */
union aoVMI{
unsigned short csr;
unsigned short data[16];
};
long vmi4100_io_report();
long vmi4100_init();
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvVmi4100={
2,
vmi4100_io_report,
vmi4100_init};
LOCAL
unsigned short **pao_vmi4100;
LOCAL
int vmi4100_addr;
/*
* vmi4100_init
*
* intialize the VMI analog outputs
*/
long vmi4100_init()
{
register unsigned short **pcards_present;
short shval;
int status;
register union aoVMI *pcard;
register short i;
pao_vmi4100 = (unsigned short **)
calloc(MAX_AO_VMI_CARDS, sizeof(*pao_vmi4100));
if(!pao_vmi4100){
return ERROR;
}
pcards_present = pao_vmi4100;
if ((status = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,ao_addrs[VMI4100], &vmi4100_addr)) != OK){
printf("Addressing error in vmi4100 driver\n");
return ERROR;
}
pcard = (union aoVMI *)((int)vmi4100_addr);
/* mark each card present into the card present array */
for (i = 0; i < ao_num_cards[VMI4100]; i++, pcard+= VMI_MAXCHAN, pcards_present += 1) {
if (vxMemProbe(pcard,READ,sizeof(short),&shval) == OK) {
*pcards_present = (unsigned short *)pcard;
pcard->csr = VMI_ENABLE_OUT;
}
else{
*pcards_present = 0;
}
}
return OK;
}
/*
* vmi4100_driver
*
* VMI4100 analog output driver
*/
int vmi4100_driver(card,chan,prval,prbval)
register unsigned short card;
register unsigned short chan;
unsigned short *prval;
unsigned short *prbval;
{
register union aoVMI *paoVMI;
/* check on the card and channel number as kept in module_types.h */
if ((paoVMI= (union aoVMI *)pao_vmi4100[card]) == 0)
return(-1);
paoVMI->data[chan] = *prval;
return (0);
}
/*
* vmi4100_read
*
* VME analog output driver
*/
int vmi4100_read(card,chan,pval)
register unsigned short card;
register unsigned short chan;
unsigned short *pval;
{
/* check on the card and channel number as kept in module_types.h */
*pval = 0; /* can't read the VMIC 4100 - good design! */
return (-1);
}
/*
* vmi4100_io_report
*
* VME analog output driver
*/
long vmi4100_io_report(level)
short int level;
{
register int i;
for (i = 0; i < MAX_AO_VMI_CARDS; i++){
if (pao_vmi4100[i]){
printf("AO: VMI4100: card %d ",i);
if(level >0){
printf("VMI4100 card cannot be read.\n");
}
else
printf("\n");
}
}
return OK;
}

View File

@@ -1,182 +0,0 @@
/*
* initialize the Xycom SRM010 bus controller card
*/
/* base/src/drv $Id$ */
/* Author: Betty Ann Gunther
* Date: 06-30-29
* Initialize xy010 bus controller
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .00 08-11-92 joh Verify the xy010's id to prevent confusion
* with the mv167's GCSR which with an unmodified
* sysLib.c will show up in the xy010's addr
* space
* .01 08-11-92 joh Moved base addr to module_types.h
* ...
*/
static char *sccsID = "@(#)drvXy010.c 1.3\t6/3/93";
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <sysLib.h>
#include <vxLib.h>
#include <vme.h>
#include <drvSup.h>
#include <module_types.h>
/*
* These will hopefully go away
* as the drivers become more autonomous
*/
static long xy010_id_check(char *);
static long xy010_io_report(int);
static long xy010_init(void);
static long xy010_map(void);
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvXy010={
2,
xy010_io_report,
xy010_init};
#define CSR_ADDR 0x81
#define XY010_ID "VMEIDXYC010"
#define XY_LED 0x3 /* set the Xycom status LEDs to OK */
LOCAL char *xy010_addr;
/*
* initialize the Xycom SRM010 bus controller card
*/
long
xy010_init()
{
char *pctlreg;
if(xy010_map()<0){
return ERROR;
}
if(xy010_id_check(xy010_addr)<0){
return OK;
}
/* Pointer to status control register. */
pctlreg = xy010_addr + CSR_ADDR;
*pctlreg = XY_LED;
return OK;
}
/*
*
* xy010_map()
*
*
*/
LOCAL
long xy010_map()
{
int status;
status = sysBusToLocalAdrs(
VME_AM_SUP_SHORT_IO,
xy010ScA16Base,
&xy010_addr);
if (status < 0){
printf("%s: xy010 A16 base addr map failed\n", __FILE__);
return ERROR;
}
return OK;
}
/*
*
* xy010_id_check()
*
*
*/
LOCAL
long xy010_id_check(pBase)
char *pBase;
{
char *pID;
char *pCmp;
char ID;
int status;
pID = pBase;
pCmp = XY010_ID;
while(*pCmp){
pID++; /* ID chars stored at odd addr */
status = vxMemProbe(pID, READ, sizeof(ID), &ID);
if(status < 0){
return ERROR;
}
if(*pCmp != ID){
return ERROR;
}
pID++;
pCmp++;
}
return OK;
}
/*
*
* xy010_io_report()
*
*
*/
long xy010_io_report(int level)
{
if(xy010_map()<0){
return ERROR;
}
if (xy010_id_check(xy010_addr) == OK) {
printf("SC: XY010:\tcard 0\n");
}
return OK;
}

View File

@@ -1,189 +0,0 @@
/* xy210_driver.c */
/* base/src/drv $Id$ */
/*
* subroutines that are used to interface to the binary input cards
*
* Author: Bob Dalesio
* Date: 6-13-88
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 02-09-89 lrd moved I/O addresses to module_types.h
* .02 11-20-89 joh added call to at5vxi driver
* .03 09-11-91 bg added bi_io_report
* .04 03-09-92 bg added levels to xy210_io_report. Gave
* xy210_io_report the ability to read raw
* values from card if level > 1
* .05 08-10-92 joh merged include file
* .06 08-25-92 mrk made masks a macro
* .07 08-25-92 mrk replaced bi_driver by xy210_driver
* .08 09-15-93 mrk Made report shorter
*/
/*
* Code Portions:
*
* bi_driver_init Finds and initializes all binary input cards present
* bi_driver Interfaces to the binary input cards present
*/
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <vxLib.h>
#include <sysLib.h>
#include <vme.h>
#include <module_types.h>
#include <drvSup.h>
static long report();
static long init();
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvXy210={
2,
report,
init};
static long report(level)
int level;
{
xy210_io_report(level);
return(0);
}
static long init()
{
xy210_driver_init();
return(0);
}
static char SccsId[] = "@(#)drvXy210.c 1.5\t9/20/93";
#define MAX_XY_BI_CARDS (bi_num_cards[XY210])
/* Xycom 210 binary input memory structure */
/* Note: the high and low order words are switched from the io card */
struct bi_xy210{
char begin_pad[0xc0]; /* nothing until 0xc0 */
/* unsigned short csr; */ /* control status register */
/* char pad[0xc0-0x82]; */ /* get to even 32 bit boundary */
unsigned short low_value; /* low order 16 bits value */
unsigned short high_value; /* high order 16 bits value */
char end_pad[0x400-0xc0-4]; /* pad until next card */
};
/* pointers to the binary input cards */
struct bi_xy210 **pbi_xy210s; /* Xycom 210s */
/* test word for forcing bi_driver */
int bi_test;
static char *xy210_addr;
/*
* BI_DRIVER_INIT
*
* intialization for the binary input cards
*/
int xy210_driver_init(){
int bimode;
int status;
register short i;
struct bi_xy210 *pbi_xy210;
pbi_xy210s = (struct bi_xy210 **)
calloc(MAX_XY_BI_CARDS, sizeof(*pbi_xy210s));
if(!pbi_xy210s){
return ERROR;
}
/* initialize the Xycom 210 binary input cards */
/* base address of the xycom 210 binary input cards */
if ((status = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,bi_addrs[XY210],&xy210_addr)) != OK){
printf("Addressing error in xy210 driver\n");
return ERROR;
}
pbi_xy210 = (struct bi_xy210 *)xy210_addr;
/* determine which cards are present */
for (i = 0; i <bi_num_cards[XY210]; i++,pbi_xy210++){
if (vxMemProbe(pbi_xy210,READ,sizeof(short),&bimode) == OK){
pbi_xy210s[i] = pbi_xy210;
} else {
pbi_xy210s[i] = 0;
}
}
return (0);
}
/*
* XY210_DRIVER
*
* interface to the xy210 binary inputs
*/
int xy210_driver(card, mask, prval)
register unsigned short card;
unsigned int mask;
register unsigned int *prval;
{
register unsigned int work;
/* verify card exists */
if (!pbi_xy210s[card]){
return (-1);
}
/* read */
work = (pbi_xy210s[card]->high_value << 16) /* high */
+ pbi_xy210s[card]->low_value; /* low */
/* apply mask */
*prval = work & mask;
return (0);
}
void xy210_io_report(level)
short int level;
{
int card;
unsigned int value;
for (card = 0; card < bi_num_cards[XY210]; card++){
if (pbi_xy210s[card]){
value = (pbi_xy210s[card]->high_value << 16) /* high */
+ pbi_xy210s[card]->low_value; /* low */
printf("BI: XY210: card %d value=0x%8.8x\n",card,value);
}
}
}

View File

@@ -1,223 +0,0 @@
/* xy220_driver.c */
/* base/src/drv $Id$ */
/*
* subroutines that are used to interface to the binary output cards
*
* Author: Bob Dalesio
* Date: 5-26-88
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 10-31-91 bg broke xy220 driver out of bo_driver.c
* broke xy220 code out of io_report and
* created xy220_io_report().
* Added sysBusToLocalAdrs.
* .02 02-03-92 bg Gave xy220_io_report the ability to
* read raw values from card if level > 1.
* .03 08-10-92 joh merged potions of bo_driver.h
* .04 08-25-92 mrk made masks a macro
*/
static char SccsId[] = "@(#)drvXy220.c 1.6\t9/20/93";
/*
* Code Portions:
*
* bo_drv_init Finds and initializes all binary output cards present
* bo_driver Interfaces to the binary output cards present
*/
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <sysLib.h>
#include <vxLib.h>
#include <vme.h>
#include "module_types.h"
#include <drvSup.h>
static long report();
static long init();
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvXy220={
2,
report,
init};
static long report(level)
int level;
{
xy220_io_report(level);
return(0);
}
static long init()
{
xy220_driver_init();
return(0);
}
#define XY_LED 0x3 /* set the Xycom status LEDs to OK */
#define XY_SOFTRESET 0x10 /* reset the IO card */
/* maximum number of VME binary output cards per IOC */
#define MAX_XY220_BO_CARDS bo_num_cards[XY220]
/* Xycom 220 binary output memory structure */
struct bo_xy220{
char begin_pad[0x80]; /* nothing until 0x80 */
short csr; /* control status register */
unsigned short low_value; /* low order 16 bits value */
unsigned short high_value; /* high order 16 bits value */
char end_pad[0x400-0x80-6]; /* pad until next card */
};
/* pointers to the binary output cards */
struct bo_xy220 **pbo_xy220s; /* Xycom 220s */
/*
* XY220_DRIVER_INIT
*
* intialization for the xy220 binary output cards
*/
int xy220_driver_init(){
int bomode;
int status;
register short i;
struct bo_xy220 *pbo_xy220;
pbo_xy220s = (struct bo_xy220 **)
calloc(MAX_XY220_BO_CARDS, sizeof(*pbo_xy220s));
if(!pbo_xy220s){
return ERROR;
}
/* initialize the Xycom 220 binary output cards */
/* base address of the xycom 220 binary output cards */
status = sysBusToLocalAdrs(
VME_AM_SUP_SHORT_IO,
bo_addrs[XY220],
&pbo_xy220);
if (status != OK){
printf("%s: xy220 A16 base map failure\n", __FILE__);
return ERROR;
}
/* determine which cards are present */
for (i = 0; i < MAX_XY220_BO_CARDS; i++,pbo_xy220++){
if (vxMemProbe(pbo_xy220,READ,sizeof(short),&bomode) == OK){
pbo_xy220s[i] = pbo_xy220;
pbo_xy220s[i]->csr = XY_SOFTRESET;
pbo_xy220s[i]->csr = XY_LED;
}else{
pbo_xy220s[i] = 0;
}
}
return(0);
}
/*
* XY220_DRIVER
*
* interface to the xy220 binary outputs
*/
int xy220_driver(card,val,mask)
register unsigned short card;
register unsigned int *val;
unsigned int mask;
{
register unsigned int work;
/* verify card exists */
if (!pbo_xy220s[card])
return (-1);
/* use structure to handle high and low short swap */
/* get current output */
work = (pbo_xy220s[card]->high_value << 16)
+ pbo_xy220s[card]->low_value;
/* alter specified bits */
work = (work & ~mask) | ((*val) & mask);
/* write new output */
pbo_xy220s[card]->high_value = (unsigned short)(work >> 16);
pbo_xy220s[card]->low_value = (unsigned short)work;
return (0);
}
/*
* xy220_read
*
* read the binary output
*/
int xy220_read(card,mask,pval)
register unsigned short card;
unsigned int mask;
register unsigned int *pval;
{
/* verify card exists */
if (!pbo_xy220s[card])
return (-1);
/* readback */
*pval = (pbo_xy220s[card]->high_value << 16) + pbo_xy220s[card]->low_value;
*pval &= mask;
return(0);
}
#define masks(K) ((1<<K))
/*
* XY220_IO_REPORT
*
*
*/
void xy220_io_report(level)
short int level;
{
int card;
unsigned int value;
for (card = 0; card < MAX_XY220_BO_CARDS; card++){
if (pbo_xy220s[card]){
value = (pbo_xy220s[card]->high_value << 16) /* high */
+ pbo_xy220s[card]->low_value; /* low */
printf("BO: XY220: card %d value=0x%8.8x\n",card,value);
}
}
}

View File

@@ -1,524 +0,0 @@
/* xy240_driver.c */
/* base/src/drv $Id$ */
/*
* routines used to test and interface with Xycom240
* digital i/o module
*
* Author: B. Kornke
* Date: 11/20/91
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 06-25-92 bg Added driver to code. Added xy240_io_report
* to it. Added copyright disclaimer.
* .02 08-10-92 joh merged xy240_driver.h into this source
* .03 08-11-92 joh fixed use of XY240 where XY240_BI or XY240_BO
* should have been used
* .04 08-11-92 joh now allows for runtime reconfiguration of
* the addr map
* .05 08-25-92 mrk added DSET; made masks a macro
* .06 08-26-92 mrk support epics I/O event scan
* .07 08-26-92 joh task params from task params header
* .08 08-26-92 joh removed STDIO task option
* .09 08-26-92 joh increased stack size for V5
* .10 08-26-92 joh increased stack size for V5
* .11 08-27-92 joh fixed no status return from bo driver
* .12 09-03-92 joh fixed wrong index used when testing for card
* present
* .13 09-03-92 joh fixed structural problems in the io
* report routines which caused messages to
* be printed even when no xy240's are present
* .14 09-17-92 joh io report now tabs over detailed info
* .15 09-18-92 joh documentation
* .16 08-02-93 mrk Added call to taskwdInsert
* .17 08-04-93 mgb Removed V5/V4 and EPICS_V2 conditionals
*/
#include "vxWorks.h"
#include "taskLib.h"
#include "vme.h"
#include "module_types.h"
#include "task_params.h"
#include <drvSup.h>
#include <dbDefs.h>
#include <dbScan.h>
#include <taskwd.h>
#define XY240_ADDR0 (bi_addrs[XY240_BI])
#define XY240_MAX_CARDS (bi_num_cards[XY240_BI])
#define XY240_MAX_CHANS (bi_num_channels[XY240_BI])
#define masks(K) ((1<<K))
/*xy240 memory structure*/
struct dio_xy240{
char begin_pad[0x80]; /*go to interface block*/
unsigned short csr; /*control status register*/
unsigned short isr; /*interrupt service routine*/
unsigned short iclr_vec; /*interrupt clear/vector*/
unsigned short flg_dir; /*flag&port direction*/
unsigned short port0_1; /*port0&1 16 bits value*/
unsigned short port2_3; /*por2&3 16 bits value*/
unsigned short port4_5; /*port4&5 16 bits value*/
unsigned short port6_7; /*port6&7 16 bits value*/
char end_pad[0x400-0x80-16]; /*pad til next card*/
};
/*create dio control structure record*/
struct dio_rec
{
struct dio_xy240 *dptr; /*pointer to registers*/
short num; /*device number*/
short mode; /*operating mode*/
unsigned short sport0_1; /*saved inputs*/
unsigned short sport2_3; /*saved inputs*/
IOSCANPVT ioscanpvt;
/*short dio_vec;*/ /*interrupt vector*/
/*unsigned int intr_num;*/ /*interrupt count*/
};
LOCAL
struct dio_rec *dio; /*define array of control structures*/
static long report();
static long init();
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvXy240={
2,
report,
init};
static long report(level)
int level;
{
xy240_io_report(level);
return(0);
}
void xy240_bi_io_report(int card);
void xy240_bo_io_report(int card);
static long init()
{
xy240_init();
return(0);
}
/*dio_int
*
*interrupt service routine
*
*/
#if 0
dio_int(ptr)
register struct dio_rec *ptr;
{
register struct dio_xy240 *regptr;
regptr = ptr->dptr;
}
#endif
/*
*
*dio_scan
*
*task to check for change of state
*
*/
int dio_scan()
{
int i;
int first_scan,first_scan_complete;
for(;;){
if(interruptAccept) break;
taskDelay(vxTicksPerSecond/30);
}
first_scan_complete = FALSE;
first_scan = TRUE;
for (;;)
{
for (i = 0; i < XY240_MAX_CARDS; i++)
{
if (dio[i].dptr)
if (((dio[i].dptr->port0_1) ^ (dio[i].sport0_1)) ||
((dio[i].dptr->port2_3) ^ (dio[i].sport2_3))
|| first_scan)
{
/* printf("io_scanner_wakeup for card no %d\n",i); */
scanIoRequest(dio[i].ioscanpvt);
dio[i].sport0_1 = dio[i].dptr->port0_1;
dio[i].sport2_3 = dio[i].dptr->port2_3;
}
}
if (first_scan){
first_scan = 0;
first_scan_complete = 1;
}
taskDelay(vxTicksPerSecond/30);
}
}
/*DIO DRIVER INIT
*
*initialize xy240 dig i/o card
*/
int xy240_init()
{
short junk;
register short i;
struct dio_xy240 *pdio_xy240;
int tid;
int status;
int at_least_one_present = FALSE;
/*
* allow for runtime reconfiguration of the
* addr map
*/
dio = (struct dio_rec *) calloc(XY240_MAX_CARDS, sizeof(*dio));
if(!dio){
return ERROR;
}
status = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,XY240_ADDR0,&pdio_xy240);
if (status != OK){
printf("%s: Unable to map the XY240 A16 base addr\n", __FILE__);
return ERROR;
}
for (i = 0; i < XY240_MAX_CARDS; i++, pdio_xy240++){
if (vxMemProbe(pdio_xy240,READ,2,&junk) != OK){
dio[i].dptr = 0;
continue;
}
/*
* register initialization
*/
pdio_xy240->csr = 0x3;
pdio_xy240->iclr_vec = 0x00; /*clear interrupt input register latch*/
pdio_xy240->flg_dir = 0xf0; /*ports 0-3,input;ports 4-7,output*/
dio[i].sport2_3 = pdio_xy240->port2_3; /*read and save high values*/
dio[i].dptr = pdio_xy240;
at_least_one_present = TRUE;
scanIoInit(&dio[i].ioscanpvt);
}
if (at_least_one_present)
{
if ((tid = taskNameToId(XY240_NAME)) != ERROR){
taskwdRemove(tid);
taskDelete(tid);
}
status = taskSpawn(
XY240_NAME,
XY240_PRI,
XY_240_OPT,
XY_240_STACK,
dio_scan);
if (status == ERROR){
printf("Unable to create XY240 scan task\n");
}
else taskwdInsert(status,NULL,NULL);
}
return OK;
}
int xy240_getioscanpvt(card,scanpvt)
short card;
IOSCANPVT *scanpvt;
{
if ((card >= XY240_MAX_CARDS) || (!dio[card].dptr)) return(0);
*scanpvt = dio[card].ioscanpvt;
return(0);
}
/*
* XY240_BI_DRIVER
*
*interface to binary inputs
*/
int xy240_bi_driver(card,mask,prval)
register short card;
unsigned int mask;
register unsigned int *prval;
{
register unsigned int work;
if ((card >= XY240_MAX_CARDS) || (!dio[card].dptr))
return -1;
work = (dio[card].dptr->port0_1 << 16)
+ dio[card].dptr->port2_3;
*prval = work & mask;
return(0);
}
/*
*
*XY240_BO_READ
*
*interface to binary outputs
*/
int xy240_bo_read(card,mask,prval)
register short card;
unsigned int mask;
register unsigned int *prval;
{
register unsigned int work;
if ((card >= XY240_MAX_CARDS) || (!dio[card].dptr)){
return -1;
}
/* printf("%d\n",dio[card].num); */
work = (dio[card].dptr->port4_5 << 16)
+ dio[card].dptr->port6_7;
*prval = work &= mask;
return(0);
}
/* XY240_DRIVER
*
*interface to binary outputs
*/
int xy240_bo_driver(card,val,mask)
register short card;
unsigned int mask;
register unsigned int val;
{
register unsigned int work;
if ((card >= XY240_MAX_CARDS) || (!dio[card].dptr))
return ERROR;
/* use structure to handle high and low short swap */
/* get current output */
work = (dio[card].dptr->port4_5 << 16)
+ dio[card].dptr->port6_7;
work = (work & ~mask) | (val & mask);
dio[card].dptr->port4_5 = (unsigned short)(work >> 16);
dio[card].dptr->port6_7 = (unsigned short)work;
return OK;
}
/*dio_out
*
*test routine for xy240 output
*/
int dio_out(card,port,val)
short card,port,val;
{
if ((card > XY240_MAX_CARDS-1)) /*test to see if card# is allowable*/
{
printf("card # out of range\n");
return -1;
}
else if (!dio[card].dptr) /*see if card exists*/
{
printf("can't find card %d\n", card);
return -2;
}
else if ((port >7) || (port <4)) /*make sure they're output ports*/
{
printf("use ports 4-7\n");
return -3;
}
else if (port == 4)
{
dio[card].dptr->port4_5 = val<< 8;
return -4;
}
else if (port == 5)
{
dio[card].dptr->port4_5 = val;
return -5;
}
else if (port == 6)
{
dio[card].dptr->port6_7 = val<< 8;
return -6;
}
else if (port == 7)
{
dio[card].dptr->port6_7 = val;
return -7;
}
else{
printf("use ports 4-7\n");
return -8;
}
}
/*XY240_WRITE
*
*command line interface to test bo driver
*
*/
int xy240_write(card,val)
short card;
unsigned int val;
{
return xy240_bo_driver(card,val,0xffffffff);
}
long
xy240_io_report(level)
short int level;
{
int card;
for (card = 0; card < XY240_MAX_CARDS; card++){
if(dio[card].dptr){
printf("B*: XY240:\tcard %d\n",card);
if (level >= 1){
xy240_bi_io_report(card);
xy240_bo_io_report(card);
}
}
}
return(0);
}
void xy240_bi_io_report(int card)
{
short int num_chans,j,k,l,m;
int jval,kval,lval,mval;
num_chans = XY240_MAX_CHANS;
if(!dio[card].dptr){
return;
}
printf("\tXY240 BINARY IN CHANNELS:\n");
for( j=0,k=1,l=2,m=3;
j < num_chans,k < num_chans, l< num_chans, m < num_chans;
j+=IOR_MAX_COLS,k+= IOR_MAX_COLS,l+= IOR_MAX_COLS, m += IOR_MAX_COLS){
if(j < num_chans){
xy240_bi_driver(card,masks(j),&jval);
if (jval != 0)
jval = 1;
printf("\tChan %d = %x\t ",j,jval);
}
if(k < num_chans){
xy240_bi_driver(card,masks(k),&kval);
if (kval != 0)
kval = 1;
printf("Chan %d = %x\t ",k,kval);
}
if(l < num_chans){
xy240_bi_driver(card,masks(l),&lval);
if (lval != 0)
lval = 1;
printf("Chan %d = %x \t",l,lval);
}
if(m < num_chans){
xy240_bi_driver(card,masks(m),&mval);
if (mval != 0)
mval = 1;
printf("Chan %d = %x \n",m,mval);
}
}
}
void xy240_bo_io_report(int card)
{
short int num_chans,j,k,l,m;
int jval,kval,lval,mval;
num_chans = XY240_MAX_CHANS;
if(!dio[card].dptr){
return;
}
printf("\tXY240 BINARY OUT CHANNELS:\n");
for( j=0,k=1,l=2,m=3;
j < num_chans,k < num_chans, l < num_chans,m < num_chans;
j+=IOR_MAX_COLS,k+= IOR_MAX_COLS,l+= IOR_MAX_COLS, m += IOR_MAX_COLS){
if(j < num_chans){
xy240_bo_read(card,masks(j),&jval);
if (jval != 0)
jval = 1;
printf("\tChan %d = %x\t ",j,jval);
}
if(k < num_chans){
xy240_bo_read(card,masks(k),&kval);
if (kval != 0)
kval = 1;
printf("Chan %d = %x\t ",k,kval);
}
if(l < num_chans){
xy240_bo_read(card,masks(l),&lval);
if (lval != 0)
lval = 1;
printf("Chan %d = %x \t",l,lval);
}
if(m < num_chans){
xy240_bo_read(card,masks(m),&mval);
if (mval != 0)
mval = 1;
printf("Chan %d = %x \n",m,mval);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,241 +0,0 @@
/* module_types.c */
/* base/src/drv $Id$ */
/*
* Author: Marty Kraimer
* Date: 08-23-93
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 08-23-93 mrk Initial Version
*/
#include <module_types.h>
int module_types()
{
ai_num_cards[AB1771IL] = 12;
ai_num_cards[AB1771IFE] = 12;
ai_num_cards[AB1771IXE] = 12;
ai_num_cards[XY566SE] = 2;
ai_num_cards[XY566DI] = 2;
ai_num_cards[XY566DIL] = 2;
ai_num_cards[VXI_AT5_AI] = 32;
ai_num_cards[AB1771IFE_SE] = 12;
ai_num_cards[AB1771IFE_4to20MA] = 12;
ai_num_cards[DVX2502] = 1;
ai_num_cards[AB1771IFE_0to5V] = 12;
ai_num_cards[KSCV215] = 32;
ai_num_channels[AB1771IL] = 8;
ai_num_channels[AB1771IFE] = 8;
ai_num_channels[AB1771IXE] = 8;
ai_num_channels[XY566SE] = 32;
ai_num_channels[XY566DI] = 16;
ai_num_channels[XY566DIL] = 16;
ai_num_channels[VXI_AT5_AI] = 8;
ai_num_channels[AB1771IFE_SE] = 16;
ai_num_channels[AB1771IFE_4to20MA] = 8;
ai_num_channels[DVX2502] = 127;
ai_num_channels[AB1771IFE_0to5V] = 8;
ai_num_channels[KSCV215] = 32;
ai_addrs[AB1771IL] = 0;
ai_addrs[AB1771IFE] = 0;
ai_addrs[AB1771IXE] = 0;
ai_addrs[XY566SE] = 0x6000;
ai_addrs[XY566DI] = 0x7000;
ai_addrs[XY566DIL] = 0x7800;
ai_addrs[VXI_AT5_AI] = 0xc014;
ai_addrs[AB1771IFE_SE] = 0;
ai_addrs[AB1771IFE_4to20MA] = 0;
ai_addrs[DVX2502] = 0xff00;
ai_addrs[AB1771IFE_0to5V] = 0;
ai_addrs[KSCV215] = 0;
ai_memaddrs[AB1771IL] = 0;
ai_memaddrs[AB1771IFE] = 0;
ai_memaddrs[AB1771IXE] = 0;
ai_memaddrs[XY566SE] = 0x000000;
ai_memaddrs[XY566DI] = 0x040000;
ai_memaddrs[XY566DIL] = 0x0c0000;
ai_memaddrs[VXI_AT5_AI] = 0;
ai_memaddrs[AB1771IFE_SE] = 0;
ai_memaddrs[AB1771IFE_4to20MA] = 0;
ai_memaddrs[DVX2502] = 0x100000;
ai_memaddrs[AB1771IFE_0to5V] = 0;
ai_memaddrs[KSCV215] = 0;
ao_num_cards[AB1771OFE] = 12;
ao_num_cards[VMI4100] = 4;
ao_num_cards[ZIO085] = 1;
ao_num_cards[VXI_AT5_AO] = 32;
ao_num_channels[AB1771OFE] = 4;
ao_num_channels[VMI4100] = 16;
ao_num_channels[ZIO085] = 32;
ao_num_channels[VXI_AT5_AO] = 16;
ao_addrs[AB1771OFE] = 0;
ao_addrs[VMI4100] = 0x4100;
ao_addrs[ZIO085] = 0x0800;
ao_addrs[VXI_AT5_AO] = 0xc000;
bi_num_cards[ABBI_08_BIT] = 12;
bi_num_cards[ABBI_16_BIT] = 12;
bi_num_cards[BB910] = 4;
bi_num_cards[XY210] = 2;
bi_num_cards[VXI_AT5_BI] = 32;
bi_num_cards[HPE1368A_BI] = 32;
bi_num_cards[AT8_FP10S_BI] = 8;
bi_num_cards[XY240_BI] = 2;
bi_num_channels[ABBI_08_BIT] = 8;
bi_num_channels[ABBI_16_BIT] = 16;
bi_num_channels[BB910] = 32;
bi_num_channels[XY210] = 32;
bi_num_channels[VXI_AT5_BI] = 32;
bi_num_channels[HPE1368A_BI] = 16;
bi_num_channels[AT8_FP10S_BI] = 32;
bi_num_channels[XY240_BI] = 32;
bi_addrs[ABBI_08_BIT] = 0;
bi_addrs[ABBI_16_BIT] = 0;
bi_addrs[BB910] = 0xb800;
bi_addrs[XY210] = 0xa000;
bi_addrs[VXI_AT5_BI] = 0xc000;
bi_addrs[HPE1368A_BI] = 0xc000;
bi_addrs[AT8_FP10S_BI] = 0x0e00;
bi_addrs[XY240_BI] = 0x3000;
bo_num_cards[ABBO_08_BIT] = 12;
bo_num_cards[ABBO_16_BIT] = 12;
bo_num_cards[BB902] = 4;
bo_num_cards[XY220] = 1;
bo_num_cards[VXI_AT5_BO] = 32;
bo_num_cards[HPE1368A_BO] = 32;
bo_num_cards[AT8_FP10M_BO] = 2;
bo_num_cards[XY240_BO] = 2;
bo_num_channels[ABBO_08_BIT] = 8;
bo_num_channels[ABBO_16_BIT] = 16;
bo_num_channels[BB902] = 32;
bo_num_channels[XY220] = 32;
bo_num_channels[VXI_AT5_BO] = 32;
bo_num_channels[HPE1368A_BO] = 16;
bo_num_channels[AT8_FP10M_BO] = 32;
bo_num_channels[XY240_BO] = 32;
bo_addrs[ABBO_08_BIT] = 0;
bo_addrs[ABBO_16_BIT] = 0;
bo_addrs[BB902] = 0x0400;
bo_addrs[XY220] = 0xa800;
bo_addrs[VXI_AT5_BO] = 0xc000;
bo_addrs[HPE1368A_BO] = 0xc000;
bo_addrs[AT8_FP10M_BO] = 0xc000;
bo_addrs[XY240_BO] = 0x3000;
sm_num_cards[CM57_83E] = 4;
sm_num_cards[OMS_6AXIS] = 4;
sm_num_channels[CM57_83E] = 1;
sm_num_channels[OMS_6AXIS] = 6;
sm_addrs[CM57_83E] = 0x8000;
sm_addrs[OMS_6AXIS] = 0x4000;
wf_num_cards[XY566WF] = 2;
wf_num_cards[CAMAC_THING] = 4;
wf_num_cards[JGVTR1] = 4;
wf_num_cards[COMET] = 4;
wf_num_channels[XY566WF] = 1;
wf_num_channels[CAMAC_THING] = 1;
wf_num_channels[JGVTR1] = 1;
wf_num_channels[COMET] = 4;
wf_addrs[XY566WF] = 0x9000;
wf_addrs[CAMAC_THING] = 0;
wf_addrs[JGVTR1] = 0xB000;
wf_addrs[COMET] = 0xbc00;
wf_armaddrs[XY566WF] = 0x5400;
wf_armaddrs[CAMAC_THING]= 0;
wf_armaddrs[JGVTR1] = 0;
wf_armaddrs[COMET] = 0;
wf_memaddrs[XY566WF] = 0x080000;
wf_memaddrs[CAMAC_THING]= 0;
wf_memaddrs[JGVTR1] = 0xb80000;
wf_memaddrs[COMET] = 0xe0000000;
tm_num_cards[MZ8310] = 4;
tm_num_cards[DG535] = 1;
tm_num_cards[VXI_AT5_TIME] = 32;
tm_num_channels[MZ8310] = 10;
tm_num_channels[DG535] = 1;
tm_num_channels[VXI_AT5_TIME] = 10;
tm_addrs[MZ8310] = 0x1000;
tm_addrs[DG535] = 0;
tm_addrs[VXI_AT5_TIME] = 0xc000;
AT830X_1_addrs = 0x0400;
AT830X_1_num_cards = 2;
AT830X_addrs = 0xaa0000;
AT830X_num_cards = 2;
xy010ScA16Base = 0x0000;
EPICS_VXI_LA_COUNT = 32;
EPICS_VXI_A24_BASE = (char *) 0x900000;
EPICS_VXI_A24_SIZE = 0x100000;
EPICS_VXI_A32_BASE = (char *) 0x90000000;
EPICS_VXI_A32_SIZE = 0x10000000;
AI566_VNUM = 0xf8;
DVX_IVEC0 = 0xd0;
MD_INT_BASE = 0xf0;
MZ8310_INT_VEC_BASE = 0xe8;
AB_VEC_BASE = 0x60;
JGVTR1_INT_VEC = 0xe0;
AT830X_1_IVEC0 = 0xd4;
AT830X_IVEC0 = 0xd6;
AT8FP_IVEC_BASE = 0xa2;
AT8FPM_IVEC_BASE= 0xaa;
BB_SHORT_OFF = 0x1800;
BB_IVEC_BASE = 0xa0;
BB_IRQ_LEVEL = 5;
PEP_BB_SHORT_OFF= 0x1c00;
PEP_BB_IVEC_BASE= 0xe8;
NIGPIB_SHORT_OFF = 0x5000;
NIGPIB_IVEC_BASE = 100;
NIGPIB_IRQ_LEVEL = 5;
return(0);
}

View File

@@ -1,66 +0,0 @@
/* steppermotor.h */
/* base/src/drv $Id$ */
/*
* header file to support database library interface to motor drivers
*
* Author: Bob Dalesio
* Date: 12-11-89
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 mm-dd-yy iii Comment
*/
/* readback data passed to the database library routine from the motor driver */
struct motor_data{
short cw_limit;
short ccw_limit;
short moving;
short direction;
short constant_velocity;
long velocity;
long encoder_position;
long motor_position;
long accel;
};
/*
* Sets values for the database library based on the value flag:
* 0 - set the mode of the motor (position/velocity)
* 1 - set the velocity of the motor
* 2 - set the poistion of the motor
* 3 - start motor rotating
* 4 - set the callback routine for a motor
*/
#define SM_MODE 0
#define SM_VELOCITY 1
#define SM_MOVE 2
#define SM_MOTION 3
#define SM_CALLBACK 4
#define SM_SET_HOME 5
#define SM_ENCODER_RATIO 6
#define SM_MOTOR_RESOLUTION 7
#define SM_READ 8
#define SM_FIND_LIMIT 9
#define SM_FIND_HOME 10