changes for 3.14
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
|
||||
TOP=../../..
|
||||
|
||||
include $(TOP)/config/CONFIG_BASE
|
||||
|
||||
include $(TOP)/config/RULES_ARCHS
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
};
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
1439
src/drv/old/drvDvx.c
1439
src/drv/old/drvDvx.c
File diff suppressed because it is too large
Load Diff
@@ -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.
|
||||
*
|
||||
******************************************************************************/
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
);
|
||||
|
||||
1425
src/drv/old/drvMsg.c
1425
src/drv/old/drvMsg.c
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
};
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user