From bfb21afcce72f135ad49f408c8e59d7dce879587 Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Mon, 13 Sep 1999 18:54:51 +0000 Subject: [PATCH] changes for 3.14 --- src/drv/old/Makefile | 7 - src/drv/old/Makefile.Vx | 61 - src/drv/old/README | 22 - src/drv/old/drvBB232.c | 589 ------ src/drv/old/drvBB232.h | 66 - src/drv/old/drvBb902.c | 204 --- src/drv/old/drvBb910.c | 214 --- src/drv/old/drvBitBus.c | 2934 ------------------------------ src/drv/old/drvBitBus.h | 299 --- src/drv/old/drvBitBusErr.h | 43 - src/drv/old/drvBitBusInterface.h | 273 --- src/drv/old/drvComet.c | 636 ------- src/drv/old/drvCompuSm.c | 868 --------- src/drv/old/drvDvx.c | 1439 --------------- src/drv/old/drvExampleVxi.c | 240 --- src/drv/old/drvFp.c | 532 ------ src/drv/old/drvFpm.c | 440 ----- src/drv/old/drvGpib.c | 2902 ----------------------------- src/drv/old/drvGpib.h | 315 ---- src/drv/old/drvGpibErr.h | 44 - src/drv/old/drvGpibInterface.h | 180 -- src/drv/old/drvHiDEOSGpib.h | 12 - src/drv/old/drvJgvtr1.c | 641 ------- src/drv/old/drvJgvtr1.h | 43 - src/drv/old/drvMsg.c | 1425 --------------- src/drv/old/drvMsg.h | 485 ----- src/drv/old/drvOms.c | 701 ------- src/drv/old/drvOms.h | 74 - src/drv/old/drvRs232.c | 541 ------ src/drv/old/drvRs232.h | 51 - src/drv/old/drvTy232.h | 74 - src/drv/old/drvVmi4100.c | 205 --- src/drv/old/drvXy010.c | 182 -- src/drv/old/drvXy210.c | 189 -- src/drv/old/drvXy220.c | 223 --- src/drv/old/drvXy240.c | 524 ------ src/drv/old/drvXy566.c | 1149 ------------ src/drv/old/module_types.c | 241 --- src/drv/old/steppermotor.h | 66 - 39 files changed, 19134 deletions(-) delete mode 100644 src/drv/old/Makefile delete mode 100644 src/drv/old/Makefile.Vx delete mode 100644 src/drv/old/README delete mode 100644 src/drv/old/drvBB232.c delete mode 100644 src/drv/old/drvBB232.h delete mode 100644 src/drv/old/drvBb902.c delete mode 100644 src/drv/old/drvBb910.c delete mode 100644 src/drv/old/drvBitBus.c delete mode 100644 src/drv/old/drvBitBus.h delete mode 100644 src/drv/old/drvBitBusErr.h delete mode 100644 src/drv/old/drvBitBusInterface.h delete mode 100644 src/drv/old/drvComet.c delete mode 100644 src/drv/old/drvCompuSm.c delete mode 100644 src/drv/old/drvDvx.c delete mode 100644 src/drv/old/drvExampleVxi.c delete mode 100644 src/drv/old/drvFp.c delete mode 100644 src/drv/old/drvFpm.c delete mode 100644 src/drv/old/drvGpib.c delete mode 100644 src/drv/old/drvGpib.h delete mode 100644 src/drv/old/drvGpibErr.h delete mode 100644 src/drv/old/drvGpibInterface.h delete mode 100644 src/drv/old/drvHiDEOSGpib.h delete mode 100644 src/drv/old/drvJgvtr1.c delete mode 100644 src/drv/old/drvJgvtr1.h delete mode 100644 src/drv/old/drvMsg.c delete mode 100644 src/drv/old/drvMsg.h delete mode 100644 src/drv/old/drvOms.c delete mode 100644 src/drv/old/drvOms.h delete mode 100644 src/drv/old/drvRs232.c delete mode 100644 src/drv/old/drvRs232.h delete mode 100644 src/drv/old/drvTy232.h delete mode 100644 src/drv/old/drvVmi4100.c delete mode 100644 src/drv/old/drvXy010.c delete mode 100644 src/drv/old/drvXy210.c delete mode 100644 src/drv/old/drvXy220.c delete mode 100644 src/drv/old/drvXy240.c delete mode 100644 src/drv/old/drvXy566.c delete mode 100644 src/drv/old/module_types.c delete mode 100644 src/drv/old/steppermotor.h diff --git a/src/drv/old/Makefile b/src/drv/old/Makefile deleted file mode 100644 index 784cf01d0..000000000 --- a/src/drv/old/Makefile +++ /dev/null @@ -1,7 +0,0 @@ - -TOP=../../.. - -include $(TOP)/config/CONFIG_BASE - -include $(TOP)/config/RULES_ARCHS - diff --git a/src/drv/old/Makefile.Vx b/src/drv/old/Makefile.Vx deleted file mode 100644 index 53d3bd7ef..000000000 --- a/src/drv/old/Makefile.Vx +++ /dev/null @@ -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 - diff --git a/src/drv/old/README b/src/drv/old/README deleted file mode 100644 index c44f40197..000000000 --- a/src/drv/old/README +++ /dev/null @@ -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 diff --git a/src/drv/old/drvBB232.c b/src/drv/old/drvBB232.c deleted file mode 100644 index bd0b4bca6..000000000 --- a/src/drv/old/drvBB232.c +++ /dev/null @@ -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 -#include -#include - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -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 */ -}; diff --git a/src/drv/old/drvBB232.h b/src/drv/old/drvBB232.h deleted file mode 100644 index 77f543bb4..000000000 --- a/src/drv/old/drvBB232.h +++ /dev/null @@ -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 diff --git a/src/drv/old/drvBb902.c b/src/drv/old/drvBb902.c deleted file mode 100644 index d8ce1d6b6..000000000 --- a/src/drv/old/drvBb902.c +++ /dev/null @@ -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 -#include -#include -#include -#include - -#include -#include -#include - -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); - } - } - -} diff --git a/src/drv/old/drvBb910.c b/src/drv/old/drvBb910.c deleted file mode 100644 index dfc680ea1..000000000 --- a/src/drv/old/drvBb910.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include - -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< 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); - } - } - } - } - } - } diff --git a/src/drv/old/drvBitBus.c b/src/drv/old/drvBitBus.c deleted file mode 100644 index c9e461336..000000000 --- a/src/drv/old/drvBitBus.c +++ /dev/null @@ -1,2934 +0,0 @@ -/* #define XYCOM_DO_RESET_AND_OFFLINE */ -/* #define PEP_DO_RESET_AND_OFFLINE */ - - -/* - changes to UI: - - XYCOM_BB_MAX_OUTSTAND_MSGS -> XycomMaxOutstandMsgs - - - - TODO: - - 1) Synthetic delays after 91s. - 2) Rebuild the link kill stuff so that it does not mess with the WDtask. - 3) Verify race conditions on the slave reset function. - 4) Write a callable bug-syncer that uses the RAC get function ID command. - 5) Merge the watchdog tasks into one. - 6) Try merging the TX and RX tasks. - -*/ - -/* - * Original Author: Ned Arnold - * Author: John Winans - * Date: 09-10-91 - * XVME-402 and PB-bit 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 Completely redesigned and rewritten - * .02 12-02-91 jrw Changed priority info to arrays - * .03 12-16-91 jrw Made the data portion of the message a pointer - * .04 01-21-91 jrw moved the task parameters into task_params.h - * .05 02-12-92 jrw removed IRQ based transmission. - * .06 04-08-92 jrw moved the device configs into module_types.h - * .07 09-28-92 jrw upped the reset delay time to 1/2 second - * .08 08-02-93 mrk Added call to taskwdInsert - * .09 06-28-94 jrw Major work on RAC_RESET and NODE_OFFLINE stuff. - * .10 07-01-94 jrw Merged PEP and Xycom versions together. - * ANSIficated this code - * .20 06-30-97 nda removed alot of "debugging" code now that the - * PEP board is finally behaving. - * Added device support for waveforms so the - * bitbus timeouts per node can be monitored - * via EPICS. - * - * NOTES: - * This driver currently needs work on error message generation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* used by device support routines */ -#include -#include -#include -#include -#include -#include - -#include -#include "drvBitBus.h" - -#define STATIC static - -#define BB_DEFAULT_RETIRE_TIME 5 /* Seconds to wait for a response */ - -STATIC long reportBB(void); -STATIC long initBB(void); -STATIC long qBBReq(struct dpvtBitBusHead *pdpvt, int prio); - -STATIC int xvmeReset(int link); -STATIC int xvmeTmoHandler(int link); -STATIC int xvmeRxTask(int link); -STATIC int xvmeTxTask(int link); -STATIC int xvmeWdTask(int link); -STATIC int xvmeIrqRdav(int link); -STATIC int xvmeIrqRcmd(int link); - -STATIC int pepReset(int link); -STATIC int pepTmoHandler(int link); -STATIC int pepRxTask(int link); -STATIC int pepTxTask(int link); -STATIC int pepWdTask(int link); -STATIC int pepIrqRdav(int link); - -STATIC int bbKill(int link); -STATIC void BBrebootFunc(void); - -STATIC int txStuck(int link); -int BBConfig(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); -int __BBConfig(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); - -#ifdef BB_SUPER_DEBUG -int BBHistDump(int link); -STATIC int BBDumpXactHistory(XactHistStruct *pXact); -#endif - -long pulseSysMon(); - - -/***************************************************************************** - * - * Used to limit the TOTAL number of simultaneous messages that can be - * outstanding on a single Xycom/PEP link. (Shell settable.) PEP limit - * of 7 is a magic number. Anything more and PEP board will throw away - * your transaction resulting in a TIMEOUT. Ugh. - * - *****************************************************************************/ -int XycomMaxOutstandMsgs = XYCOM_BB_MAX_OUTSTAND_MSGS; -int PepMaxOutstandMsgs = 7; /* constraint of PEP discovered in 80C152 - source code */ - -/***************************************************************************** - * - * Create an artificial delay to prevent back-to-back message - * loading of the PEP FIFO, since this has proven to induce protocol - * errors. If the global PepLinkDelay variable is non-zero, - * use a software spin loop for the delay. (these values can be set to 0 - * if a "patched PROM" is used on the PB-BIT board). - * - *****************************************************************************/ -int PepLinkLoadDelay = 0; /* set to 450 if a "non-patched" PB-BIT is used */ - -/* On a bitbus error, if link and node match the following global variables, - write to the System Monitor board to generate a trigger */ - -int bbErrorTrigNode = 1; /* Set to -1 for all nodes */ -int bbErrorTrigLink = 0; - -/* Used to keep track of errors per node */ -#define BB_NUM_NODES 100 -unsigned short bbNodeTMO[BB_NUM_LINKS][BB_NUM_NODES]; -unsigned short bbNode91[BB_NUM_LINKS][BB_NUM_NODES]; - -/***************************************************************************** - * - * Debugging flags that may be set from the shell. - * - * bbDebug Used to get status information from the driver's internals. - * May be set with a value from 0 to 40. the higher the number - * the more information. 0 will provide no internal debugging. - * - * bbDebugLink Used to get general status information about a single slave - * bbDebugNode node. - * To disable this feature, set one of them to -1. - * - *****************************************************************************/ -int bbDebug = 1; -int bbDebugLink=-1; -int bbDebugNode=-1; - -#ifdef BB_SUPER_DEBUG -static int BBSetHistEvent(int link, struct dpvtBitBusHead *pXact, int State); -#endif - -/****************************************************************************** - * - * This structure contains a list of the outside-callable functions. - * - ******************************************************************************/ -struct drvBitBusEt drvBitBus = { - 3, - reportBB, - initBB, - qBBReq -}; - -#if 0 -/* JRW --> get rid of this crap */ -STATIC char BitbusInitCalled = 0; /* to insure that init is done first */ -STATIC void *short_base; /* base of short address space */ -#endif - - -STATIC BitbusLinkStruct *pBBLink[BB_NUM_LINKS]; /* NULL if link not config'd */ - /*************************************************************************** - * - * User-callable configuration function. - * - * This function is used to configure the type of link as well as to - * initialize it for operation. - * - *****************************************************************************/ -int BBConfig(unsigned long Link, - unsigned long LinkType, - unsigned long BaseAddr, - unsigned long IrqVector, - unsigned long IrqLevel) -{ - __BBConfig(Link, LinkType, BaseAddr, IrqVector, IrqLevel); - return(0); -} - -int __BBConfig(unsigned long Link, - unsigned long LinkType, - unsigned long BaseAddr, - unsigned long IrqVector, - unsigned long IrqLevel) -{ - void *pVoid; - int j; - static int FirstTime = 1; - char nameTemp[30]; - int taskId; - - if (FirstTime) - { - rebootHookAdd(BBrebootFunc); - FirstTime = 0; - } - if (Link >= BB_NUM_LINKS) - { - logMsg("Error: Invalid link (%d) specified in BBConfig()\n", Link); - return(-1); - } - if ((LinkType != BB_CONF_TYPE_XYCOM) && (LinkType != BB_CONF_TYPE_PEP)) - { - logMsg("Error: Invalid link type (%d) specified in BBConfig()\n", LinkType); - return(-1); - } - if (pBBLink[Link] != NULL) - { - logMsg("Error: BBConfig() Attempt to reconfigure link %d!\n", Link); - return(-1); - } - - if ((pBBLink[Link] = (BitbusLinkStruct *) malloc(sizeof(BitbusLinkStruct))) == NULL) - { - logMsg("Error: BBConfig() cannot malloc\n"); - return(-1); - } - - pBBLink[Link]->LinkType = BB_CONF_HOSED; /* Changed if all goes well */ - pBBLink[Link]->BaseAddr = BaseAddr; - pBBLink[Link]->IrqVector = IrqVector; - pBBLink[Link]->IrqLevel = IrqLevel; - -#ifdef BB_SUPER_DEBUG - /* Init the history FIFO to empty */ - pBBLink[Link]->History.sem = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - pBBLink[Link]->History.Next = 0; - pBBLink[Link]->History.Num = 0; -#endif - - pBBLink[Link]->linkEventSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - - if (sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO , BaseAddr, &pVoid) != OK) - { - logMsg("Error: BBConfig() can not translate requested A16 address(0x%8.8X\n", BaseAddr); - pBBLink[Link] = NULL; - return(-1); - } - - /* - * Interface specific I/O mapping and registration - */ - - switch (LinkType) - { - case BB_CONF_TYPE_XYCOM: - pBBLink[Link]->l.XycomLink.rxInt = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - pBBLink[Link]->l.XycomLink.bbRegs = (XycomBBRegsStruct *)pVoid; - if (devRegisterAddress("Xycom Bitbus", atVMEA16, (void*)BaseAddr, sizeof(XycomBBRegsStruct), NULL) != 0) - { - logMsg("Error: BBConfig() can not register address %8.8X\n", pVoid); - pBBLink[Link] = NULL; - return(-1); /* BUG */ - } - break; - case BB_CONF_TYPE_PEP: - pBBLink[Link]->l.PepLink.rxInt = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - pBBLink[Link]->l.PepLink.bbRegs = (PepBBRegsStruct *)pVoid; - if (devRegisterAddress("PEP Bitbus", atVMEA16, (void*)BaseAddr, sizeof(PepBBRegsStruct), NULL) != 0) - { - logMsg("Error: BBConfig() can not register address %8.8X\n", pVoid); - pBBLink[Link] = NULL; - return(-1); /* BUG */ - } - break; - } - - /* - * Common data structure initialization. - */ - - /* Init the prioritized queue lists */ - for (j=0; jqueue[j].head = NULL; - pBBLink[Link]->queue[j].tail = NULL; - pBBLink[Link]->queue[j].sem = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - pBBLink[Link]->queue[j].elements = 0; - } - - /* Init the busy message list */ - pBBLink[Link]->busyList.sem = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - pBBLink[Link]->busyList.head = NULL; - pBBLink[Link]->busyList.tail = NULL; - pBBLink[Link]->busyList.elements = 0; - - for (j=0; jdeviceStatus[j] = BB_IDLE; - pBBLink[Link]->syntheticDelay[j] = 0; - } - pBBLink[Link]->DelayCount = 0; - - pBBLink[Link]->watchDogId = wdCreate(); - pBBLink[Link]->watchDogSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - - /* Clear the link abort status */ - pBBLink[Link]->abortFlag = 0; - pBBLink[Link]->txAbortAck = 0; - pBBLink[Link]->rxAbortAck = 0; - - /* - * Interface type specific initialization of management tasks. - */ - - if (LinkType == BB_CONF_TYPE_XYCOM) - { - /* BOARD SPECIFIC INIT CODE for XYCOM */ - if (xvmeReset(Link) != 0) - { - pBBLink[Link] = NULL; - return(-1); - } - - pBBLink[Link]->LinkType = LinkType; - - /* attach the interrupt handler routines */ - intConnect((BB_IVEC_BASE + 1 + (Link*4)) * 4, xvmeIrqRcmd, Link); - intConnect((BB_IVEC_BASE + 3 + (Link*4)) * 4, xvmeIrqRdav, Link); - - /* Start a task to manage the TX link */ - sprintf(nameTemp, "%s%d-xy", BBTXLINK_NAME, Link); - if ((taskId=taskSpawn(nameTemp, BBTXLINK_PRI, BBTXLINK_OPT, BBTXLINK_STACK, xvmeTxTask, Link)) == ERROR) - { - logMsg("BBConfig(): failed to start TX link task for link %d\n", Link); - } - taskwdInsert(taskId,NULL,NULL); - /* Start a task to manage the RX link */ - sprintf(nameTemp, "%s%d-xy", BBRXLINK_NAME, Link); - if ((taskId=taskSpawn(nameTemp, BBRXLINK_PRI, BBRXLINK_OPT, BBRXLINK_STACK, xvmeRxTask, Link)) == ERROR) - { - logMsg("BBConfig(): failed to start RX link task for link %d\n", Link); - } - taskwdInsert(taskId,NULL,NULL); - /* Start a task to keep an eye on the busy list */ - sprintf(nameTemp, "%s%d-xy", BBWDTASK_NAME, Link); - if ((taskId=taskSpawn(nameTemp, BBWDTASK_PRI, BBWDTASK_OPT, BBWDTASK_STACK, xvmeWdTask, Link)) == ERROR) - { - logMsg("BBConfig(): failed to start watchdog task for link %d\n", Link); - } - taskwdInsert(taskId,NULL,NULL); - } - else if (LinkType == BB_CONF_TYPE_PEP) - { - /* PEP specific init code */ - if (pepReset(Link) != 0) - { - pBBLink[Link] = NULL; - return(-1); - } - - pBBLink[Link]->LinkType = LinkType; - - /* attach the interrupt handler routines */ - intConnect(INUM_TO_IVEC(PEP_BB_IVEC_BASE + (Link*2)), pepIrqRdav, Link); - - /* Start a task to manage the TX link */ - sprintf(nameTemp, "%s%d-pep", BBTXLINK_NAME, Link); - if ((taskId=taskSpawn(nameTemp, BBTXLINK_PRI, BBTXLINK_OPT, BBTXLINK_STACK, pepTxTask, Link)) == ERROR) - { - logMsg("BBConfig(): failed to start TX link task for link %d\n", Link); - } - taskwdInsert(taskId,NULL,NULL); - /* Start a task to manage the RX link */ - sprintf(nameTemp, "%s%d-pep", BBRXLINK_NAME, Link); - if ((taskId=taskSpawn(nameTemp, BBRXLINK_PRI, BBRXLINK_OPT, BBRXLINK_STACK, pepRxTask, Link)) == ERROR) - { - logMsg("BBConfig(): failed to start RX link task for link %d\n", Link); - } - taskwdInsert(taskId,NULL,NULL); - /* Start a task to keep an eye on the busy list */ - sprintf(nameTemp, "%s%d-pep", BBWDTASK_NAME, Link); - if ((taskId=taskSpawn(nameTemp, BBWDTASK_PRI, BBWDTASK_OPT, BBWDTASK_STACK, pepWdTask, Link)) == ERROR) - { - logMsg("BBConfig(): failed to start watchdog task for link %d\n", Link); - } - taskwdInsert(taskId,NULL,NULL); - } - sysIntEnable(IrqLevel); - return(0); -} - /****************************************************************** - * - * The EPICS init routine is not needed. - * - ******************************************************************/ -STATIC long initBB(void) -{ - return(0); -} - -/****************************************************************** - * FUNCTION: reportBB() - * PURPOSE : Prints a message indicating the presence of each - * bitbus module found in system. - * ARGS IN : none - * ARGS OUT: none - * GLOBALS: checks pBBLink[i] for NULL - ******************************************************************/ - -STATIC long reportBB(void) -{ - int i; - - if (bbDebug>1) - printf("Bitbus debugging flag is set to %d\n", bbDebug); - - for (i=0; i< BB_NUM_LINKS; i++) - { - if (pBBLink[i] != NULL) - { - if (pBBLink[i]->LinkType == BB_CONF_TYPE_XYCOM) - printf("Bitbus link %d present at %p IV=0x%2.2X IL=%d (XYCOM)\n", i, pBBLink[i]->l.XycomLink.bbRegs, pBBLink[i]->IrqVector, pBBLink[i]->IrqLevel); - else if (pBBLink[i]->LinkType == BB_CONF_TYPE_PEP) - printf("Bitbus link %d present at %p IV=0x%2.2X IL=%d (PEP)\n", i, pBBLink[i]->l.PepLink.bbRegs, pBBLink[i]->IrqVector, pBBLink[i]->IrqLevel); - } - } - return(OK); -} - /****************************************************************** - * FUNCTION: pepReset() - * PURPOSE : Performs firmware reset of PB-BIT module corresponding - * to link. Attempts to empty any data sitting in receive - * FIFO. Interrupts are disabled and Rx task is unblocked. - * ARGS IN : xvmeRegs ptr to register structure of PB-BIT module - * link link number serviced by PB-BIT module - * ARGS OUT: none - * GLOBALS: twiddles board - ******************************************************************/ -STATIC int -pepReset(int link) -{ - char trash; - int j; - int lockKey; - int probeValue; - - if (bbDebug) - printf("pepReset(%d): Resetting pep module\n", link); - - probeValue = 0; - if (vxMemProbe(&(pBBLink[link]->l.PepLink.bbRegs->int_vec), WRITE, 1, &probeValue) < OK) - { /* no BB board present here */ - logMsg("ERROR: PEP Bitbus link %d not present at 0x%8.8X\n", link, pBBLink[link]->l.PepLink.bbRegs); - return(-1); - } - - /* Write firmware reset package (2 bytes) to board */ - pBBLink[link]->l.PepLink.bbRegs->data = 0x83; - pBBLink[link]->l.PepLink.bbRegs->stat_ctl = 0x01; - - taskDelay(20); /* give the 80152 time to self check */ - - if ((pBBLink[link]->l.PepLink.bbRegs->stat_ctl & 0x10) != 0x0) - { - if (bbDebug) - printf("pepReset(%d): PB-BIT firmware reset failed!\n", link); - return(ERROR); - } - - j = 1026; /* 1K deep receive fifo */ - /* flush receive fifo if junk in it */ - while ((pBBLink[link]->l.PepLink.bbRegs->stat_ctl & PEP_BB_RFNE) && --j) - trash = pBBLink[link]->l.PepLink.bbRegs->data; - - if (!j) - { - if (bbDebug) - printf("pepReset(%d): receive fifo will not clear after reset!\n", link); - return(ERROR); - } - - /* Disable interrupts */ - lockKey = intLock(); - pBBLink[link]->l.PepLink.bbRegs->int_vec = 0; - intUnlock(lockKey); - - /* Tell pepRxTask to Re-enable ints */ - semGive(pBBLink[link]->l.PepLink.rxInt); - - return(OK); -} - /**************************************************************************** - * - * Reset an xvme-402 BitBus card by cycling the reset bit in the fifo - * status register. - * - ****************************************************************************/ -STATIC int xvmeReset(int link) -{ - char trash; - int j; - int lockKey; - unsigned char probeValue; - - - if (bbDebug) - printf("xvmeReset(%d): Resetting xvme module\n", link); - - probeValue = XVME_RESET; - if (vxMemProbe(&(pBBLink[link]->l.XycomLink.bbRegs->fifo_stat), WRITE, 1, &probeValue) < OK) - { /* no BB board present here */ - logMsg("ERROR: Xycom Bitbus link %d not present at 0x%8.8X\n", link, pBBLink[link]->l.XycomLink.bbRegs); - return(-1); - } - -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, NULL, XACT_HIST_STATE_RESET); -#endif - - taskDelay(2); - pBBLink[link]->l.XycomLink.bbRegs->fifo_stat = 0; /* clear reset pulse */ - taskDelay(30); /* give the 8044 time to self check */ - - j = 100; /* give up after this */ - while ((pBBLink[link]->l.XycomLink.bbRegs->fifo_stat & XVME_RCMD) && --j) - trash = pBBLink[link]->l.XycomLink.bbRegs->cmnd; /* flush command buffer if junk in it */ - - if (!j) - { - if (bbDebug) - printf("xvmeReset(%d): Command buffer will not clear after reset!\n", link); - return(ERROR); - } - - j = 100; - while ((pBBLink[link]->l.XycomLink.bbRegs->fifo_stat & XVME_RFNE) && --j) - trash = pBBLink[link]->l.XycomLink.bbRegs->data; /* flush data buffer if junk in it */ - - if (!j) - { - if (bbDebug) - printf("xvmeReset(%d): Data buffer will not clear after reset!\n", link); - return(ERROR); - } - - if ((pBBLink[link]->l.XycomLink.bbRegs->fifo_stat & XVME_FSVALID) != XVME_FSIDLE) - { - if (bbDebug) - printf("xvmeReset(%d): XVME board not returning to idle status after reset!\n", link); - return(ERROR); - } - - /* set the interrupt vector */ - lockKey = intLock(); - pBBLink[link]->l.XycomLink.bbRegs->stat_ctl = 0; /* disable all interupts */ - pBBLink[link]->l.XycomLink.bbRegs->int_vec = BB_IVEC_BASE + (link*4);/* set the int vector */ - intUnlock(lockKey); - - semGive(pBBLink[link]->l.XycomLink.rxInt); /* Tell xvmeRxTask to Re-enable interrupts */ - - return(OK); -} - /**************************************************************************** - * - * This function is used to add a node to the HEAD of a list. - * - ****************************************************************************/ -static int -listAddHead(struct bbList *plist, struct dpvtBitBusHead *pnode) -{ - pnode->prev = NULL; - pnode->next = plist->head; - - if (plist->head != NULL) - plist->head->prev = pnode; - - if (plist->tail == NULL) - plist->tail = pnode; - - plist->head = pnode; - - plist->elements++; - - return(0); -} -/****************************************************************************** - * - * This function is used to add a node to the TAIL of a list. - * - ******************************************************************************/ -static int -listAddTail(struct bbList *plist, struct dpvtBitBusHead *pnode) -{ - pnode->next = NULL; /* No next node if this is the TAIL */ - pnode->prev = plist->tail; /* previous node is the 'old' TAIL node */ - - if (plist->tail != NULL) - plist->tail->next = pnode; /* link the 'old' tail to the 'new' tail node */ - - if (plist->head == NULL) - plist->head = pnode; - - plist->tail = pnode; /* this is the 'new' tail node */ - - plist->elements++; - - return(0); -} - /*************************************************************************** - * - * This function is used to delete a node from a list. - * - ***************************************************************************/ -static int -listDel(struct bbList *plist, struct dpvtBitBusHead *pnode) -{ - if (pnode->next != NULL) - pnode->next->prev = pnode->prev; - - if (pnode->prev != NULL) - pnode->prev->next = pnode->next; - - if (plist->head == pnode) - plist->head = pnode->next; - - if (plist->tail == pnode) - plist->tail = pnode->prev; - - plist->elements--; - - return(0); -} - /**************************************************************************** - * - * xycom IRQ handler for receiver data bytes. - * - ****************************************************************************/ -static int -xvmeIrqRdav(int link) -{ - if (bbDebug > 30) - logMsg("bitbus rx IRQ on link %d\n", link); - semGive(pBBLink[link]->l.XycomLink.rxInt); /* deliver the groceries */ - return(0); -} - -/**************************************************************************** - * - * xycom IRQ handler invoked when the BitBus controller has completed the - * transfer of a RECEIVED message. - * - ****************************************************************************/ -static int -xvmeIrqRcmd(int link) -{ - if (bbDebug > 30) - logMsg("bitbus rcmd IRQ on link %d\n", link); - semGive(pBBLink[link]->l.XycomLink.rxInt); /* deliver the groceries */ - return(0); -} - /****************************************************************** - * FUNCTION: pepIrqRdav() - * PURPOSE : Invoked when PB-BIT module has received a complete - * bitbus message (ie. not on a byte-by-byte basis). - * ARGS IN : link link number upon which message has arrived - * ARGS OUT: none - * GLOBALS: unblocks Rx task (if it is not already running) - ******************************************************************/ -STATIC int -pepIrqRdav(int link) -{ - pBBLink[link]->l.PepLink.bbRegs->int_vec = 0; /* disable IRQs */ - - if (bbDebug > 30) - logMsg("PEP bitbus rx IRQ on link %d\n", link); - - semGive(pBBLink[link]->l.PepLink.rxInt); /* unblock it */ - return(0); -} - /****************************************************************** - * FUNCTION: pepTmoHandler() - * PURPOSE : Invoked whenever a watchdog timer times out. Watchdogs - * are running whenever the busyList has any elements on - * it. The idea here is that the watchdog handler scans - * through the busyList, looking for old requests that have - * not been replied to in too long a time. If there are - * any old ones around, they are removed from the list, - * and the associated node is reset and marked offline. - * - * ARGS IN : link - * ARGS OUT: none - * GLOBALS: none - ******************************************************************/ -STATIC int -pepTmoHandler(int link) -{ - if (bbDebug > 25) - logMsg("pepTmoHandler(%d): Watch dog interrupt\n", link); - - semGive(pBBLink[link]->watchDogSem); /* unblock Wd task */ - return(0); -} - -/****************************************************************************** - * - * Watchdogs are running when ever the busy list has any elements in it. - * The idea here is that the watchdog handler scans thru the busy list, - * looking for old requests that have not been replied to in too long - * a time. If there are any old ones around, they are removed from the - * list and marked as un-replied to. - * - ******************************************************************************/ -static int -xvmeTmoHandler(int link) -{ - if (bbDebug > 25) - logMsg("xvmeTmoHandler(%d): Watch dog interrupt\n", link); - - semGive(pBBLink[link]->watchDogSem); - return(0); -} - /**************************************************************************** - * - * Given a link number, make sure it is valid. - * - ****************************************************************************/ -static int -checkLink(int link) -{ - if ((link<0) || (link>BB_NUM_LINKS)) - return(ERROR); /* link number out of range */ - - if (pBBLink[link] == NULL) - return(ERROR); /* link number has no card installed */ - - return(OK); -} - /*************************************************************************** - * - * This function is started as a task during driver init time. It's purpose - * is to read messages that are received from the bitbus link. After a message - * is received, the soliciting message's completion routines are started by - * the use of semaphores and/or a callbackRequest(). - * - ***************************************************************************/ -static int -xvmeRxTask(int link) -{ - int rxState; /* current state of the receiver */ -#define BBRX_HEAD 1 -#define BBRX_DATA 2 -#define BBRX_RCMD 3 -#define BBRX_IGN 4 - - unsigned char rxHead[5]; /* room for header of current rx msg */ - unsigned char *rxMsg; /* where to place next byte (after header) */ - int rxTCount; /* byte counter for data in rxHead */ - unsigned char ch; - struct dpvtBitBusHead *rxDpvtHead; /* for message currently receiving */ - - struct dpvtBitBusHead UselessMsg; /* to hold unsolicited responses */ - unsigned char UselessData[BB_MAX_MSG_LENGTH]; - - int lockKey; /* used for intLock calls */ - - rxMsg = (unsigned char *) NULL; - rxState = BBRX_HEAD; - rxTCount = 0; - rxDpvtHead = (struct dpvtBitBusHead *) NULL; - - /* Dummy up the UselessMsg fields so we can use it */ - UselessMsg.rxMaxLen = BB_MAX_MSG_LENGTH; - UselessMsg.rxMsg.data = UselessData; - UselessMsg.link = link; - UselessMsg.ageLimit = 0; - UselessMsg.retire = 0; - - while (1) - { - /* Wait for RX interrupts, but only if no chars are ready */ - if ((pBBLink[link]->l.XycomLink.bbRegs->fifo_stat & XVME_RFNE) == 0) - { - /* Enable interrupts and check again because xycom blew it */ - lockKey = intLock(); - pBBLink[link]->l.XycomLink.bbRegs->stat_ctl = XVME_ENABLE_INT | XVME_RX_INT; - intUnlock(lockKey); - - while (((pBBLink[link]->l.XycomLink.bbRegs->fifo_stat & XVME_RFNE) == 0) && (pBBLink[link]->abortFlag == 0)) - { - /* Re-enable ints here each time in case board got reset */ - lockKey = intLock(); - pBBLink[link]->l.XycomLink.bbRegs->stat_ctl = XVME_ENABLE_INT | XVME_RX_INT; - intUnlock(lockKey); - - /* Wait for groceries */ - semTake(pBBLink[link]->l.XycomLink.rxInt, WAIT_FOREVER); - } - /* Disable RX Interrupts (prevents unnecessary context switching) */ - lockKey = intLock(); - pBBLink[link]->l.XycomLink.bbRegs->stat_ctl = 0; - intUnlock(lockKey); - } - if (pBBLink[link]->abortFlag == 0) - { - /* check to see if we got a data byte or a command byte */ - if ((pBBLink[link]->l.XycomLink.bbRegs->fifo_stat & XVME_RCMD) == XVME_RCMD) - rxState = BBRX_RCMD; - - switch (rxState) { - case BBRX_HEAD: /* getting the head of a new message */ - rxHead[rxTCount] = pBBLink[link]->l.XycomLink.bbRegs->data; - if (bbDebug>21) - printf("xvmeRxTask(%d): >%2.2X< (Header)\n", link, rxHead[rxTCount]); - - if (++rxTCount == 5) - { /* find the message this is a reply to */ - rxTCount += 2; /* adjust for the link field space */ - - /* Lock the busy list */ - semTake(pBBLink[link]->busyList.sem, WAIT_FOREVER); - - rxDpvtHead = pBBLink[link]->busyList.head; - while (rxDpvtHead != NULL) - { - if (bbDebug>19) - printf("xvmeRxTask(%d): checking reply against %p\n", link, rxDpvtHead); - - /* see if node's match */ - if (rxDpvtHead->txMsg.node == rxHead[2]) - { /* see if the tasks match */ - if (rxDpvtHead->txMsg.tasks == rxHead[3]) - { /* They match, finish putting response into the rxMsg buffer */ - if (bbDebug>4) - printf("xvmeRxTask(%d): reply to %p\n", link, rxDpvtHead); - - /* Delete the node from the list */ - listDel(&(pBBLink[link]->busyList), rxDpvtHead); - - /* If busy list is empty, stop the dog */ - if (pBBLink[link]->busyList.head == NULL) - wdCancel(pBBLink[link]->watchDogId); - - if (rxHead[4] == 0x91) - { /* something bad happened... inject a delay to the */ - /* requested timeout duration. */ - - if ((link == bbErrorTrigLink) && - ((bbErrorTrigNode < 0) || (bbErrorTrigNode == rxHead[2]))) - pulseSysMon(); - - /* keep track of timeouts per node */ - if(rxHead[2] < BB_NUM_NODES) { - bbNode91[link][rxHead[2]]++; - } - - if (bbDebug) - printf("xvmeRxTask(%d): 0x91 from node %d, invoking synthetic delay\n", link, rxHead[2]); - (pBBLink[link]->syntheticDelay[rxDpvtHead->txMsg.node]) = rxDpvtHead->retire; - pBBLink[link]->DelayCount++; - } - else - { /* decrement the number of outstanding messages to the node */ - (pBBLink[link]->deviceStatus[rxDpvtHead->txMsg.node])--; - } - - /* Wake up Link Task in case was waiting on "this" node */ - semGive(pBBLink[link]->linkEventSem); - -#if 0 - semGive(pXvmeLink[link]->pbbLink->busyList.sem); - - rxDpvtHead->rxMsg.length = rxHead[0]; - rxDpvtHead->rxMsg.route = rxHead[1]; - rxDpvtHead->rxMsg.node = rxHead[2]; - rxDpvtHead->rxMsg.tasks = rxHead[3]; - rxDpvtHead->rxMsg.cmd = rxHead[4]; - rxMsg = rxDpvtHead->rxMsg.data; - - rxDpvtHead->status = BB_OK; /* OK, unless BB_LENGTH */ - rxState = BBRX_DATA; /* finish reading till RCMD */ -#endif - break; /* get out of the while() */ - } - } - rxDpvtHead = rxDpvtHead->next; /* Keep looking */ - } - - semGive(pBBLink[link]->busyList.sem); - - /* Couldn't find a match... fake one so can print the bad message */ - if (rxDpvtHead == NULL) - rxDpvtHead = &UselessMsg; - - rxDpvtHead->rxMsg.length = rxHead[0]; - rxDpvtHead->rxMsg.route = rxHead[1]; - rxDpvtHead->rxMsg.node = rxHead[2]; - rxDpvtHead->rxMsg.tasks = rxHead[3]; - rxDpvtHead->rxMsg.cmd = rxHead[4]; - rxMsg = rxDpvtHead->rxMsg.data; - - rxDpvtHead->status = BB_OK; /* OK, unless BB_LENGTH */ - rxState = BBRX_DATA; /* finish reading till RCMD */ - } - break; - - case BBRX_DATA: /* finish reading data portion of message */ - ch = pBBLink[link]->l.XycomLink.bbRegs->data; - if (rxTCount >= rxDpvtHead->rxMaxLen) - { - rxState = BBRX_IGN; /* toss the rest of the data */ - rxDpvtHead->status = BB_LENGTH; /* set driver status */ - if (bbDebug>22) - printf("xvmeRxTask(%d): %2.2X (Ignored)\n", link, ch); - } - else - { - *rxMsg = ch; - if (bbDebug>22) - printf("xvmeRxTask(%d): %2.2X (Data)\n", link, ch); - rxMsg++; - rxTCount++; - } - break; - - case BBRX_IGN: - ch = pBBLink[link]->l.XycomLink.bbRegs->data; - if (bbDebug>22) - printf("xvmeRxTask(%d): %2.2X (Ignored)\n", link, ch); - break; - - case BBRX_RCMD: - if (rxDpvtHead == NULL) - { - ch = pBBLink[link]->l.XycomLink.bbRegs->cmnd; - if (bbDebug) - printf("xvmeRxTask(%d): got unexpected XVME_RCMD\n", link); -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, NULL, XACT_HIST_STATE_RX_URCMD); -#endif - } - else if (rxDpvtHead == &UselessMsg) - { - rxDpvtHead->status = BB_OK; /* XXX -- ??? */ - rxDpvtHead->rxCmd = pBBLink[link]->l.XycomLink.bbRegs->cmnd; - - if (bbDebug) - { - printf("xvmeRxTask(%d): msg from node %d unsolicited:", link, rxDpvtHead->rxMsg.node); - drvBitBusDumpMsg(&(rxDpvtHead->rxMsg)); - } -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, rxDpvtHead, XACT_HIST_STATE_RX_UNSOLICITED); -#endif - } - else - { - rxDpvtHead->status = BB_OK; /* XXX -- ??? */ - rxDpvtHead->rxCmd = pBBLink[link]->l.XycomLink.bbRegs->cmnd; - - if (bbDebug>24) - printf("xvmeRxTask(%d):RX command byte = %2.2X\n", link, rxDpvtHead->rxCmd); - -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, rxDpvtHead, XACT_HIST_STATE_RX); -#endif - if (rxDpvtHead->finishProc != NULL) - { - if (bbDebug>8) - printf("xvmeRxTask(%d): invoking the callbackRequest\n", link); - callbackRequest(rxDpvtHead); /* schedule completion processing */ - } - else - { - /* If there is a semaphore for synchronous I/O, unlock it */ - if (rxDpvtHead->psyncSem != NULL) - semGive(*(rxDpvtHead->psyncSem)); - } - } - /* Reset the state of the RxTask to expect a new message */ - rxMsg = (unsigned char *) NULL; - rxState = BBRX_HEAD; - rxTCount = 0; - rxDpvtHead = (struct dpvtBitBusHead *) NULL; - - break; - } - } - else - { /* Link abort state is active reset receiver link status now */ - if (rxDpvtHead != NULL) - { /* This xact is not on the busy list, put it back on */ - semTake(pBBLink[link]->busyList.sem, WAIT_FOREVER); - (pBBLink[link]->deviceStatus[rxDpvtHead->txMsg.node])++; - listAddTail(&(pBBLink[link]->busyList), rxDpvtHead); - semGive(pBBLink[link]->busyList.sem); - } - -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, rxDpvtHead, XACT_HIST_STATE_RX_ABORT); -#endif - rxMsg = (unsigned char *) NULL; - rxState = BBRX_HEAD; - rxTCount = 0; - rxDpvtHead = (struct dpvtBitBusHead *) NULL; - - /* Tell the watch dog I am ready for the reset (reset in the dog task) */ - pBBLink[link]->rxAbortAck = 1; - - if (bbDebug) - printf("xvmeRxTask(%d): resetting due to abort status\n", link); - - /* wait for link state to become active again */ - while (pBBLink[link]->abortFlag != 0) - taskDelay(RESET_POLL_TIME); - - if (bbDebug) - printf("xvmeRxTask(%d): restarting after abort\n", link); - } - } -} - -/****************************************************************************** - * - * A user callable link resetter. This sets a flag and releases the dog - * task to reset the link. - * - ******************************************************************************/ -int -bbReset(int link) -{ - if (checkLink(link) != ERROR) - { - pBBLink[link]->nukeEm = 1; - semGive(pBBLink[link]->watchDogSem); - } - else - printf("Link %d not installed.\n", link); - - return(0); -} - -/****************************************************************************** - * - * BUG -- this does not do the nuke=2 reset and kill link operations like - * the PEP does. - * - ******************************************************************************/ -static int -xvmeWdTask(int link) -{ - struct dpvtBitBusHead *pnode; - struct dpvtBitBusHead *npnode; - unsigned long now; - -#ifdef XYCOM_DO_RESET_AND_OFFLINE - SEM_ID syncSem; - - struct dpvtBitBusHead resetNode; - unsigned char resetNodeData; /* 1-byte data field for RAC_OFFLINE */ - - /* init the SEM used when sending the reset message */ - syncSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - - /* - * Hand-craft a RAC_OFFLINE message to use when a message times out. - * NOTE that having only one copy is OK provided that the dog waits for - * a response before sending it again! - */ - resetNode.finishProc = NULL; /* no callback routine used */ - resetNode.psyncSem = &syncSem;/* do a semGive on this SEM when done sending */ - resetNode.link = link; /* which bitbus link to send message out on */ - resetNode.rxMaxLen = 7; /* Chop off the response... we don't care */ - resetNode.ageLimit = sysClkRateGet()*100; /* make sure this never times out */ - - resetNode.txMsg.length = 8; - resetNode.txMsg.route = BB_STANDARD_TX_ROUTE; - resetNode.txMsg.node = 0xff; - resetNode.txMsg.tasks = 0x0; - resetNode.txMsg.cmd = RAC_OFFLINE; - resetNode.txMsg.data = &resetNodeData; -#endif - - pBBLink[link]->nukeEm = 0; /* Make sure the nuke status is clear */ - while(1) - { - semTake(pBBLink[link]->watchDogSem, WAIT_FOREVER); - now = tickGet(); /* what time is it? */ - - if (pBBLink[link]->nukeEm != 0) - printf("Bitbus manual reset being issued on link %d\n", link); - - if (bbDebug>4) - printf("xvmeWdTask(%d): (Watchdog) checking busy list\n", link); - - pBBLink[link]->rxAbortAck = 0; /* In case we need to use them */ - pBBLink[link]->txAbortAck = 0; - - if (pBBLink[link]->nukeEm != 0) - { /* set abort status and wait for the abort acks */ - pBBLink[link]->abortFlag = 1; - - /* wake up the Tx task so it can observe the abort status */ - semGive(pBBLink[link]->linkEventSem); - - /* wake up the Rx task so it can observe the abort ststus */ - semGive(pBBLink[link]->l.XycomLink.rxInt); - - /* sleep until abort ack from Tx & Rx tasks */ - while ((pBBLink[link]->rxAbortAck == 0) && (pBBLink[link]->txAbortAck == 0)) - taskDelay(RESET_POLL_TIME); - -#ifdef BB_SUPER_DEBUG - if (pBBLink[link]->nukeEm < 2) - { /* Do a history dump since this is not supposed to happen */ - BBHistDump(link); - } -#endif - } - /* - * Run thru entire busy list to see if there are any transactions - * that have been waiting on a response for too long a period. - */ - semTake(pBBLink[link]->busyList.sem, WAIT_FOREVER); - pnode = pBBLink[link]->busyList.head; - - while (pnode != NULL) - { - npnode = pnode->next; /* remember where we were in the list */ - - if ((pBBLink[link]->nukeEm != 0) || (pnode->retire <= now)) - { - /* Get rid of the request and set error status etc... */ - listDel(&(pBBLink[link]->busyList), pnode); - - if (bbDebug) - { -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, pnode, XACT_HIST_STATE_WD_TIMEOUT); -#endif - printf("xvmeWdTask(%d): TIMEOUT on bitbus message:\n", link); - drvBitBusDumpMsg(&pnode->txMsg); - } - - if(pnode->txMsg.node < BB_NUM_NODES) { - bbNodeTMO[link][pnode->txMsg.node]++; - } - - - /* BUG -- do this here or defer until RX gets a response? */ - (pBBLink[link]->deviceStatus[pnode->txMsg.node])--; /* fix device status */ - pnode->status = BB_TIMEOUT; - -#ifdef XYCOM_DO_RESET_AND_OFFLINE - /* BUG ----- wait for the response from the last one first? */ - - /* Do now in case we need it later */ - resetNodeData = pnode->txMsg.node; /* mark the node number */ -#endif - - /* Make the callbackRequest if one was spec'd */ - if(pnode->finishProc != NULL) - { - callbackRequest(pnode); /* schedule completion processing */ - } - else - { - /* Release a completion lock if one was spec'd */ - if (pnode->psyncSem != NULL) - semGive(*(pnode->psyncSem)); - } - -#ifdef XYCOM_DO_RESET_AND_OFFLINE - /* If we are not going to reboot the link... */ - if (pBBLink[link]->nukeEm == 0) - { /* Send out a RAC_NODE_OFFLINE to the controller */ - semGive(pBBLink[link]->busyList.sem); - - if (bbDebug) - printf("issuing a node offline for link %d node %d\n", link, resetNodeData); - - semTake(pBBLink[link]->queue[BB_Q_HIGH].sem, WAIT_FOREVER); - listAddHead(&(pBBLink[link]->queue[BB_Q_HIGH]), &resetNode); - semGive(pBBLink[link]->queue[BB_Q_HIGH].sem); - - semGive(pBBLink[link]->linkEventSem); /* Tell TxTask to send the message */ - - if (semTake(syncSem, sysClkRateGet()/4) == ERROR) - { - if (bbDebug) - printf("xvmeWdTask(%d): link dead, trying manual reboot\n", link); - pBBLink[link]->nukeEm = 1; - - pBBLink[link]->abortFlag = 1; /* Start the abort sequence */ - semGive(pBBLink[link]->linkEventSem); /* Let Tx task observe abort status */ - semGive(pBBLink[link]->l.XycomLink.rxInt); /* Let Rx task observe abort ststus */ - - /* sleep until abort ack from Tx & Rx tasks */ - while ((pBBLink[link]->rxAbortAck == 0) && (pBBLink[link]->txAbortAck == 0)) - taskDelay(RESET_POLL_TIME); - } - /* Start over since released the busy list */ - - semTake(pBBLink[link]->busyList.sem, WAIT_FOREVER); - npnode = pBBLink[link]->busyList.head; - } -#else - semGive(pBBLink[link]->linkEventSem); -#endif - } - pnode = npnode; - } - if (pBBLink[link]->busyList.head != NULL) - { /* Restart the dog timer */ - - if (bbDebug>5) - printf("xvmeWdTask(%d): restarting watch dog timer\n", link); - - wdStart(pBBLink[link]->watchDogId, pBBLink[link]->busyList.head->retire - now, xvmeTmoHandler, link); - } - semGive(pBBLink[link]->busyList.sem); - - /* Finish the link reboot if necessary */ - if (pBBLink[link]->nukeEm != 0) - { - xvmeReset(link); - - /* clear the abort_flag */ - pBBLink[link]->abortFlag = 0; - - pBBLink[link]->nukeEm = 0; - } - } -} - -/****************************************************************************** - * - * This function is started as a task during driver init time. It's purpose - * is to keep the link busy. It awaits user-calls to qBbReq() with new work - * as well as wake-up calls from the watchdog timer. - * - * At the time this function is started as its own task, the linked list - * structures will have been created and initialized. - * - ******************************************************************************/ -static int -xvmeTxTask(int link) -{ - struct dpvtBitBusHead *pnode; - int prio; - int working; - int dogStart; - int stuck; - - int txTCount; - int txCCount; - unsigned char *txMsg; - register int x; - unsigned long now; - SEM_ID resetNodeSem; - struct dpvtBitBusHead resetNode; - unsigned char resetNodeData; /* 1-byte data field for RAC_OFFLINE */ - - if (bbDebug) - printf("xvmeTxTask started for link %d\n", link); - - /* hand-craft a RAC_OFFLINE message for use with RAC_RESET_SLAVE commands */ - /* NOTE that having only one copy is OK provided that this message is */ - /* sent immediately following the RAC_RESET_SLAVE message. */ - - resetNodeSem = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - - resetNode.finishProc = NULL; - resetNode.psyncSem = &resetNodeSem; - resetNode.link = link; - resetNode.rxMaxLen = 7; /* Chop it off, we don't care */ - resetNode.ageLimit = sysClkRateGet(); - - resetNode.txMsg.length = 8; - resetNode.txMsg.route = BB_STANDARD_TX_ROUTE; - resetNode.txMsg.node = 0xff; - resetNode.txMsg.tasks = 0x0; - resetNode.txMsg.cmd = RAC_OFFLINE; - resetNode.txMsg.data = &resetNodeData; - - while(1) - { - if (pBBLink[link]->abortFlag != 0) - { - pBBLink[link]->txAbortAck = 1; /* let the dog know we are ready */ -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, NULL, XACT_HIST_STATE_TX_ABORT); -#endif - - if (bbDebug) - printf("xvmeTxTask(%d): resetting due to abort status\n", link); - - while (pBBLink[link]->abortFlag != 0) - taskDelay(RESET_POLL_TIME); /* wait for link to reset */ - - if (bbDebug) - printf("xvmeTxTask(%d): restarting after abort\n", link); - } - else - { - if (pBBLink[link]->DelayCount) - semTake(pBBLink[link]->linkEventSem, 2 * sysClkRateGet()); - else - semTake(pBBLink[link]->linkEventSem, WAIT_FOREVER); - } - - if (bbDebug>5) - printf("xvmeTxTask(%d): got an event\n", link); - - working = 1; - while ((working != 0) && (pBBLink[link]->abortFlag == 0) && (pBBLink[link]->busyList.elements < XycomMaxOutstandMsgs)) - { - working = 0; - - prio = BB_NUM_PRIO-1; - while ((prio >= 0) && (pBBLink[link]->abortFlag == 0)) - { - /* see if the queue has anything in it */ - semTake(pBBLink[link]->queue[prio].sem, WAIT_FOREVER); - - if ((pnode = pBBLink[link]->queue[prio].head) != NULL) - { - now = tickGet(); - while (pBBLink[link]->deviceStatus[pnode->txMsg.node] == BB_BUSY) - { - if ((pBBLink[link]->syntheticDelay[pnode->txMsg.node] != 0) - && (pBBLink[link]->syntheticDelay[pnode->txMsg.node] < now)) - { - if (bbDebug) - printf("xvmeTxTask(%d): terminating synthetic idle on node %d\n", link, pnode->txMsg.node); - (pBBLink[link]->deviceStatus[pnode->txMsg.node])--; - pBBLink[link]->syntheticDelay[pnode->txMsg.node] = 0; - pBBLink[link]-> DelayCount--; - } - else - { - if ((pnode = pnode->next) == NULL) - break; - } - } - } - if (pnode != NULL) - { /* have an xact to start processing */ - working = 1; /* indicate work being done */ - - /* delete the node from the inbound fifo queue */ - listDel(&(pBBLink[link]->queue[prio]), pnode); - - semGive(pBBLink[link]->queue[prio].sem); - -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, pnode, XACT_HIST_STATE_TX); -#endif - if (bbDebug>3) - printf("xvmeTxTask(%d): got xact, pnode=%p\n", link, pnode); - - /* Send the message in polled mode */ - - txTCount = pnode->txMsg.length - 2; - txCCount = 0; - txMsg = &(pnode->txMsg.length); - - while ((txCCount <= txTCount) && (pBBLink[link]->abortFlag == 0)) - { - stuck = 1000; - while (((pBBLink[link]->l.XycomLink.bbRegs->fifo_stat & XVME_TFNF) != XVME_TFNF) && (pBBLink[link]->abortFlag == 0) && --stuck) - for(x=0;x<100;x++); /* wait for TX ready */ - - if (!stuck) - { -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, pnode, XACT_HIST_STATE_TX_STUCK); -#endif - txStuck(link); /* will end up setting abortFlag */ - } - else if (txCCount < txTCount) /* on last time, just wait, no data */ - { - pBBLink[link]->l.XycomLink.bbRegs->data = *txMsg; /* send next byte */ - if (bbDebug>30) - printf("xvmeTxTask(%d): outputting %2.2X\n", link, *txMsg); - - /* On 5th byte, we are dun w/header, set start w/data buffer */ - if (txCCount != 4) - txMsg++; - else - txMsg = pnode->txMsg.data; - } - txCCount++; - } - - if (pBBLink[link]->abortFlag == 0) - { - - /* All data bytes have been sent, put on busy list and release */ - - /* Don't add to busy list if was a RAC_RESET_SLAVE */ - if ((pnode->txMsg.cmd == RAC_RESET_SLAVE) && (pnode->txMsg.tasks == 0)) - { /* Finish the transaction here if was a RAC_RESET_SLAVE */ -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, pnode, XACT_HIST_STATE_TX_RESET); -#endif - if (bbDebug) - printf("xvmeTxTask(%d): RAC_RESET_SLAVE sent, resetting node %d\n", link, pnode->txMsg.node); - - pnode->status = BB_OK; - - if (pnode->finishProc != NULL) - { - if (bbDebug>4) - printf("xvmeTxTask(%d): invoking callbackRequest\n", link); - - callbackRequest(pnode); /* schedule completion processing */ - } - else - { - /* If there is a semaphore for synchronous I/O, unlock it */ - if (pnode->psyncSem != NULL) - semGive(*(pnode->psyncSem)); - } - - /* Wait for last NODE_OFFLINE to finish (if still pending) */ - semTake(resetNodeSem, WAIT_FOREVER); - - /* have to reset the master so it won't wait on a response */ - resetNodeData = pnode->txMsg.node; /* mark the node number */ - semTake(pBBLink[link]->queue[BB_Q_HIGH].sem, WAIT_FOREVER); - listAddHead(&(pBBLink[link]->queue[BB_Q_HIGH]), &resetNode); - semGive(pBBLink[link]->queue[BB_Q_HIGH].sem); - - /* taskDelay(15); */ /* wait while bug is resetting */ - } - else - { - /* Lock the busy list */ - semTake(pBBLink[link]->busyList.sem, WAIT_FOREVER); - - /* set the retire time */ - pnode->retire = tickGet(); - if (pnode->ageLimit) - pnode->retire += pnode->ageLimit; - else - pnode->retire += BB_DEFAULT_RETIRE_TIME * sysClkRateGet(); - - if (pBBLink[link]->busyList.head == NULL) - dogStart = 1; - else - dogStart = 0; - - /* Add pnode to the busy list */ - listAddTail(&(pBBLink[link]->busyList), pnode); - - /* Count the outstanding messages */ - (pBBLink[link]->deviceStatus[pnode->txMsg.node])++; - - semGive(pBBLink[link]->busyList.sem); - - /* If just added something to an empty busy list, start the dog */ - if (dogStart) - { - now = tickGet(); - wdStart(pBBLink[link]->watchDogId, pBBLink[link]->busyList.head->retire - now, xvmeTmoHandler, link); - } - } - - /* Tell the 8044 to fire out the message now */ - pBBLink[link]->l.XycomLink.bbRegs->cmnd = BB_SEND_CMD; /* forward it now */ - } - else - { /* Aborted transmission operation, re-queue the message */ - semTake(pBBLink[link]->queue[BB_Q_HIGH].sem, WAIT_FOREVER); - listAddHead(&(pBBLink[link]->queue[BB_Q_HIGH]), pnode); - semGive(pBBLink[link]->queue[BB_Q_HIGH].sem); -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, pnode, XACT_HIST_STATE_TX_ABORT); -#endif - if (bbDebug) - { - printf("Message in progress when abort issued:\n"); - drvBitBusDumpMsg(&pnode->txMsg); - } - } -/* BUG -- I don't really need this */ - /* break;*/ /* stop checking the fifo queues */ - } - else - { /* we have no xacts that can be processed at this time */ - semGive(pBBLink[link]->queue[prio].sem); - } - prio--; /* look at the next prio queue */ - } - } - } -} - -/****************************************************************************** - * - * This gets called by the transmit task if it gets stuck waiting to send a - * byte to the transmit fifo. - * - ******************************************************************************/ -STATIC int txStuck(int link) -{ - if (bbDebug) - printf("bitbus transmitter task stuck, resetting link %d\n", link); - - bbReset(link); - while (pBBLink[link]->abortFlag == 0) - taskDelay(1); - - return(OK); -} - -/****************************************************************************** - * - * This function is called by user programs to queue an I/O transaction request - * for the BB driver. It is the only user-callable function provided in this - * driver. - * - ******************************************************************************/ -STATIC long qBBReq(struct dpvtBitBusHead *pdpvt, int prio) -{ - static linkErrFlags[BB_NUM_LINKS]; /* Supposedly init'd to zero */ - char message[200]; - - if ((prio < 0) || (prio >= BB_NUM_PRIO)) - { - sprintf(message, "invalid priority requested in call to qbbreq(%p, %d)\n", pdpvt, prio); - errMessage(S_BB_badPrio, message); - return(ERROR); - } - if (checkLink(pdpvt->link) == ERROR) - { - if (pdpvt->link >= BB_NUM_LINKS) - { - sprintf(message, "qbbreq(%p, %d) %d\n", pdpvt, prio, pdpvt->link); - errMessage(S_BB_badlink, message); - } - else if (linkErrFlags[pdpvt->link] == 0) - { /* Anti-message swamping check */ - linkErrFlags[pdpvt->link] = 1; - sprintf(message, "qbbreq(%p, %d) %d... card not present\n", pdpvt, prio, pdpvt->link); - errMessage(S_BB_badlink, message); - } - return(ERROR); - } - -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(pdpvt->link, pdpvt, XACT_HIST_STATE_QUEUE); -#endif - - if (bbDebug>5) - printf("qbbreq(%p, %d): transaction queued\n", pdpvt, prio); - if (bbDebug>6) - drvBitBusDumpMsg(&(pdpvt->txMsg)); - - semTake(pBBLink[pdpvt->link]->queue[prio].sem, WAIT_FOREVER); - - /* Add to the end of the queue of waiting transactions */ - listAddTail(&(pBBLink[pdpvt->link]->queue[prio]), pdpvt); - - semGive(pBBLink[pdpvt->link]->queue[prio].sem); - - semGive(pBBLink[pdpvt->link]->linkEventSem); - - return(OK); -} - - -/****************************************************************** - * - * Reset hook function... takes down ALL the bitbus links and leaves - * them down. - * - ******************************************************************/ -STATIC void BBrebootFunc(void) -{ - int i; - - for (i=0; inukeEm = 2; - semGive(pBBLink[link]->watchDogSem); - } - else - printf("Link %d not installed.\n", link); - - return(0); -} - - - /****************************************************************** - * - * Super debugging facility. - * - ******************************************************************/ -int -drvBitBusDumpMsg(struct bitBusMsg *pbbMsg) -{ - char ascBuf[15]; /* for ascii xlation part of the dump */ - int x; - int y; - int z; - - printf("Link 0x%4.4X, length 0x%2.2X, route 0x%2.2X, node 0x%2.2X, tasks 0x%2.2X, cmd %2.2X\n", pbbMsg->link, pbbMsg->length, pbbMsg->route, pbbMsg->node, pbbMsg->tasks, pbbMsg->cmd); - - x = BB_MSG_HEADER_SIZE; - y = pbbMsg->length; - z = 0; - - while (x < y) - { - printf("%2.2X ", pbbMsg->data[z]); - ascBuf[z] = pbbMsg->data[z]; - - if (!((ascBuf[z] >= 0x20) && (ascBuf[z] <= 0x7e))) - ascBuf[z] = '.'; - - x++; - z++; - } - - while (x < BB_MAX_MSG_LENGTH) - { - printf(" "); - x++; - } - - ascBuf[z] = '\0'; - printf(" *%s*\n", ascBuf); - return(OK); -} - -#ifdef BB_SUPER_DEBUG -/* - * Place an event into the history buffer. - */ -static int BBSetHistEvent(int link, struct dpvtBitBusHead *pXact, int State) -{ - semTake(pBBLink[link]->History.sem, WAIT_FOREVER); - - - pBBLink[link]->History.Num++; - - pBBLink[link]->History.Xact[pBBLink[link]->History.Next].Time = tickGet(); - pBBLink[link]->History.Xact[pBBLink[link]->History.Next].State = State; - if (pXact != NULL) - memcpy (&pBBLink[link]->History.Xact[pBBLink[link]->History.Next].Xact, pXact, sizeof(struct dpvtBitBusHead)); - - if (link==bbDebugLink && pBBLink[link]->History.Xact[pBBLink[link]->History.Next].Xact.txMsg.node==bbDebugNode) - BBDumpXactHistory(&pBBLink[link]->History.Xact[pBBLink[link]->History.Next]); - - if (++pBBLink[link]->History.Next == BB_SUPER_DEBUG_HIST_SIZ) - pBBLink[link]->History.Next = 0; - - semGive(pBBLink[link]->History.sem); - return(0); -} - -int BBHistDump(int link) -{ - int count; - int ix; - - if (checkLink(link) == ERROR) - { - printf(" Link %d is not valid\n", link); - return(-1); - } - printf("Dumping bitbus history for link %d\n", link); - semTake(pBBLink[link]->History.sem, WAIT_FOREVER); - - if (pBBLink[link]->History.Num < BB_SUPER_DEBUG_HIST_SIZ) - { - count = pBBLink[link]->History.Num; - ix = 0; - } - else - { - count = BB_SUPER_DEBUG_HIST_SIZ; - ix = pBBLink[link]->History.Next; - } - - while(count) - { - printf("%8.8d:", pBBLink[link]->History.Xact[ix].Time); - - if (BBDumpXactHistory(&pBBLink[link]->History.Xact[ix]) != 0) - count = 0; - else - --count; - - if (++ix >= BB_SUPER_DEBUG_HIST_SIZ) - ix = 0; - } - - semGive(pBBLink[link]->History.sem); - return(0); -} -STATIC int BBDumpXactHistory(XactHistStruct *pXact) -{ - switch (pXact->State) - { - /* No BB message present */ - case XACT_HIST_STATE_RESET: - printf("Link Reset:\n"); - break; - case XACT_HIST_STATE_RX_ABORT: - printf("Link RX aborted\n"); - break; - case XACT_HIST_STATE_TX_ABORT: - printf("Link TX aborted\n"); - break; - case XACT_HIST_STATE_RX_URCMD: - printf("Link RX got unexpected RCMD\n"); - break; - - /* TX message only */ - case XACT_HIST_STATE_QUEUE: - printf("Message Queued:\n"); - goto do_tx_only; - case XACT_HIST_STATE_TX: - printf("Message Transmitted:\n"); - goto do_tx_only; - case XACT_HIST_STATE_WD_TIMEOUT: - printf("Watchdog Timeout:\n"); - goto do_tx_only; - case XACT_HIST_STATE_TX_STUCK: - printf("Transmitter stuck:\n"); - goto do_tx_only; - case XACT_HIST_STATE_TX_RESET: - printf("TX just sent a RAC RESET:\n"); - - do_tx_only: - drvBitBusDumpMsg(&pXact->Xact.txMsg); - break; - - /* RX message only */ - case XACT_HIST_STATE_RX_UNSOLICITED: - printf("RX unsolicited message:\n"); - drvBitBusDumpMsg(&pXact->Xact.rxMsg); - break; - - /* TX and RX messages present */ - case XACT_HIST_STATE_RX: - printf("RX response... complete transaction:\n"); - drvBitBusDumpMsg(&pXact->Xact.txMsg); - drvBitBusDumpMsg(&pXact->Xact.rxMsg); - break; - - default: - printf("Corrupt bitbus debug state!\n"); - return(-1); - } - return(0); -} -#endif - -/****************************************************************************** - * - * A user callable function that may be used to reset the specified slave - * node. - * - * This routine is NOT reenterant but contains a monitor so that it always - * operates properly. - * - ******************************************************************************/ -int ResetBug(int node, int link) -{ - static int FirstTime = 1; - static SEM_ID monLock; - static SEM_ID syncSem; /* Semaphore to use for completion */ - struct dpvtBitBusHead resetNode; /* actual message to send out */ - unsigned char resetNodeData; /* 1-byte data field for RAC_RESET */ - - if (FirstTime) - { - monLock = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - syncSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - FirstTime = 0; - } - - semTake(monLock, WAIT_FOREVER); - - resetNode.finishProc = NULL; /* no callback routine used */ - resetNode.psyncSem = &syncSem;/* do a semGive on this SEM when done sending */ - resetNode.link = link; /* which bitbus link to send message out on */ - resetNode.rxMaxLen = 7; /* Chop off the response... we don't care */ - resetNode.ageLimit = sysClkRateGet()*2; - - resetNode.txMsg.length = 8; - resetNode.txMsg.route = BB_STANDARD_TX_ROUTE; - resetNode.txMsg.node = node; - resetNode.txMsg.tasks = 0x0; - resetNode.txMsg.cmd = RAC_RESET_SLAVE; - resetNode.txMsg.data = &resetNodeData; - - qBBReq(&resetNode, 0); - semTake(syncSem, WAIT_FOREVER); - semGive(monLock); - - return(0); -} - /****************************************************************** - * FUNCTION: pepRxTask() - * PURPOSE : This function is started as a task during driver init - * time. It's purpose is to read messages off the receive - * FIFO. After a complete message is read, the soliciting - * message's completion routines are started by the use - * of semaphores and/or a callbackRequest(). - * ARGS IN : link - * ARGS OUT: none - * GLOBALS: none - ******************************************************************/ -STATIC int -pepRxTask(int link) -{ - int rxState; /* current state of the receiver */ -#define BBRX_HEAD 1 -#define BBRX_DATA 2 -#define BBRX_RCMD 3 -#define BBRX_IGN 4 - - unsigned char rxHead[7]; /* room for header of current rx msg */ - unsigned char *rxMsg; /* where to place next byte (after header) */ - int rxTCount; /* byte counter for data in rxHead */ - unsigned char ch; - struct dpvtBitBusHead *rxDpvtHead; /* for message currently receiving */ - - struct dpvtBitBusHead UselessMsg; /* to hold unsolicited responses */ - unsigned char UselessData[BB_MAX_MSG_LENGTH]; - - int lockKey; /* used for intLock calls */ - int packageComplete; /* indicates end of package read */ - - rxMsg = (unsigned char *) NULL; - rxState = BBRX_HEAD; - rxTCount = 0; - rxDpvtHead = (struct dpvtBitBusHead *) NULL; - packageComplete = 0; - - /* Dummy up the UselessMsg fields so we can use it */ - UselessMsg.rxMaxLen = BB_MAX_MSG_LENGTH; - UselessMsg.rxMsg.data = UselessData; - UselessMsg.link = link; - UselessMsg.ageLimit = 0; - UselessMsg.retire = 0; - - while (1) - { - /* Wait for RX interrupts, but only if no chars are ready */ - if ((pBBLink[link]->l.PepLink.bbRegs->stat_ctl & PEP_BB_RFNE) == 0) - { - /* Enable interrupts and check again in case PB-BIT blew it */ - lockKey = intLock(); - pBBLink[link]->l.PepLink.bbRegs->int_vec = PEP_BB_IVEC_BASE +(link*2); - intUnlock(lockKey); - - while (((pBBLink[link]->l.PepLink.bbRegs->stat_ctl & PEP_BB_RFNE) == 0) - && (pBBLink[link]->abortFlag == 0)) - { - /* Re-enable ints here each time in case board got reset */ - lockKey = intLock(); - pBBLink[link]->l.PepLink.bbRegs->int_vec = PEP_BB_IVEC_BASE +(link*2); - intUnlock(lockKey); - - if (bbDebug>35) - printf("pepRxTask(%d): waiting on IRQ\n", link); - - /* wait for data bytes */ - semTake(pBBLink[link]->l.PepLink.rxInt, WAIT_FOREVER); - } - /* Disable RX Interrupts (prevents unnecessary context switching) */ - lockKey = intLock(); - pBBLink[link]->l.PepLink.bbRegs->int_vec = 0; - intUnlock(lockKey); - } - - if (pBBLink[link]->abortFlag == 0) - { - /* READ ONE CHAR FROM RECEIVE FIFO */ - ch = pBBLink[link]->l.PepLink.bbRegs->data; - - /* check to see if we got a data byte or a command byte */ - if ((pBBLink[link]->l.PepLink.bbRegs->stat_ctl & PEP_BB_RCMD) == PEP_BB_RCMD) - packageComplete = 1; - - switch (rxState) { - case BBRX_HEAD: /* getting the head of a new message */ - if (rxTCount > 1) /* Toss the 2 PEP specific header bytes */ - rxHead[rxTCount] = ch; - if (bbDebug>21) - printf("pepRxTask(%d): >%2.2X< (Header)\n", link, ch); - - if (++rxTCount == 7) - { - /* find the message this is a reply to */ - /* rxTCount += 2; PEP header bytes already messed up the count (jrw)*/ - - /* Lock the busy list */ - semTake(pBBLink[link]->busyList.sem, WAIT_FOREVER); - - rxDpvtHead = pBBLink[link]->busyList.head; - while (rxDpvtHead != NULL) { - if (bbDebug>19) - printf("pepRxTask(%d): checking reply against %p\n", - link, rxDpvtHead); - - /* see if node's match */ - if (rxDpvtHead->txMsg.node == rxHead[4]) { - /* see if the tasks match */ - /* if (rxDpvtHead->txMsg.tasks == rxHead[5]) */ - { - /* They match, finish putting response into the rxMsg buffer */ - if (bbDebug>4) - printf("pepRxTask(%d): reply to %p\n", - link, rxDpvtHead); - - /* Delete the node from the list */ - listDel(&(pBBLink[link]->busyList), rxDpvtHead); - - /* If busy list is empty, stop the dog */ - if (pBBLink[link]->busyList.head == NULL) - wdCancel(pBBLink[link]->watchDogId); - - if (rxHead[6] == 0x91) - { /* something bad happened... inject a delay to the */ - /* requested timeout duration. */ - - if ((link == bbErrorTrigLink) && - ((bbErrorTrigNode < 0) || (bbErrorTrigNode == rxHead[2]))) - pulseSysMon(); - - /* keep track of timeouts per node */ - if(rxHead[4] < BB_NUM_NODES) { - bbNode91[link][rxHead[4]]++; - } - - if (bbDebug) - printf("pepRxTask(%d): 0x91 from node %d, invoking synthetic delay\n", link, rxHead[4]); - (pBBLink[link]->syntheticDelay[rxDpvtHead->txMsg.node]) = rxDpvtHead->retire; - pBBLink[link]->DelayCount++; - } - else - { /* decrement the number of outstanding messages to the node */ - (pBBLink[link]->deviceStatus[rxDpvtHead->txMsg.node])--; - } - - /* Wake up Link Task in case was waiting on "this" node */ - semGive(pBBLink[link]->linkEventSem); -#if 0 - semGive(pXvmeLink[link]->pbbLink->busyList.sem); - - rxDpvtHead->rxMsg.length = rxHead[2]; - rxDpvtHead->rxMsg.route = rxHead[3]; - rxDpvtHead->rxMsg.node = rxHead[4]; - rxDpvtHead->rxMsg.tasks = rxHead[5]; - rxDpvtHead->rxMsg.cmd = rxHead[6]; - rxMsg = rxDpvtHead->rxMsg.data; - - rxDpvtHead->status = BB_OK; /* OK, unless BB_LENGTH */ - rxState = BBRX_DATA; /* finish reading till RCMD */ -#endif - break; /* get out of the while() */ - } - } - rxDpvtHead = rxDpvtHead->next; /* Keep looking */ - } - - semGive(pBBLink[link]->busyList.sem); - - /* Couldn't find a match... fake one so can print the bad message */ - if (rxDpvtHead == NULL) - rxDpvtHead = &UselessMsg; - - rxDpvtHead->rxMsg.length = rxHead[2]; - rxDpvtHead->rxMsg.route = rxHead[3]; - rxDpvtHead->rxMsg.node = rxHead[4]; - rxDpvtHead->rxMsg.tasks = rxHead[5]; - rxDpvtHead->rxMsg.cmd = rxHead[6]; - rxMsg = rxDpvtHead->rxMsg.data; - - rxDpvtHead->status = BB_OK; /* OK, unless BB_LENGTH */ - rxState = BBRX_DATA; /* finish reading till RCMD */ - } - break; - - case BBRX_DATA: /* finish reading data portion of message */ - if (rxTCount >= rxDpvtHead->rxMaxLen) { - rxState = BBRX_IGN; /* toss the rest of the data */ - rxDpvtHead->status = BB_LENGTH; /* set driver status */ - if (bbDebug>22) - printf("pepRxTask(%d): %2.2X (Ignored)\n", link, ch); - - } - else { - *rxMsg = ch; - if (bbDebug>22) - printf("pepRxTask(%d): %2.2X (Data)\n", link, ch); - rxMsg++; - rxTCount++; - } - break; - - case BBRX_IGN: - if (bbDebug>22) - printf("pepRxTask(%d): %2.2X (Ignored)\n", link, ch); - break; - } - - if (packageComplete) - { - if (rxDpvtHead == NULL) - { - if (bbDebug > 22) - printf("pepRxTask(%d): got unexpected completion status\n", link); -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, NULL, XACT_HIST_STATE_RX_URCMD); -#endif - } - else if (rxDpvtHead == &UselessMsg) - { - rxDpvtHead->status = BB_OK; - if (bbDebug) - { - printf("pepRxTask(%d): msg from node %d unsolicited:\n", link, rxDpvtHead->rxMsg.node); - drvBitBusDumpMsg(&(rxDpvtHead->rxMsg)); - } -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, rxDpvtHead, XACT_HIST_STATE_RX_UNSOLICITED); -#endif - } - else - { - rxDpvtHead->status = BB_OK; - if (bbDebug>24) - printf("pepRxTask(%d): RX command byte = %2.2X\n", link, ch); - -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, rxDpvtHead, XACT_HIST_STATE_RX); -#endif - - if (rxDpvtHead->finishProc != NULL) - { - if (bbDebug>8) - printf("pepRxTask(%d): invoking the callbackRequest\n", link); - callbackRequest(rxDpvtHead); /* schedule completion processing */ - } - else - { - /* If there is a semaphore for synchronous I/O, unlock it */ - if (rxDpvtHead->psyncSem != NULL) - semGive(*(rxDpvtHead->psyncSem)); - } - } - /* Reset the state of the RxTask to expect a new message */ - rxMsg = (unsigned char *) NULL; - rxState = BBRX_HEAD; - rxTCount = 0; - rxDpvtHead = (struct dpvtBitBusHead *) NULL; - packageComplete = 0; - } - } - else - { - /* Link abort state is active reset receiver link status now */ - if (rxDpvtHead != NULL) - { - /* This xact is not on the busy list, put it back on */ - semTake(pBBLink[link]->busyList.sem, WAIT_FOREVER); - (pBBLink[link]->deviceStatus[rxDpvtHead->txMsg.node])++; - listAddTail(&(pBBLink[link]->busyList), rxDpvtHead); - semGive(pBBLink[link]->busyList.sem); - } -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, rxDpvtHead, XACT_HIST_STATE_RX_ABORT); -#endif - - rxMsg = (unsigned char *) NULL; - rxState = BBRX_HEAD; - rxTCount = 0; - rxDpvtHead = (struct dpvtBitBusHead *) NULL; - - /* Tell the watch dog I am ready for the reset (reset in the dog task) */ - pBBLink[link]->rxAbortAck = 1; - - if (bbDebug) - printf("pepRxTask(%d): resetting due to abort status\n", link); - - /* wait for link state to become active again */ - while (pBBLink[link]->abortFlag != 0) - taskDelay(RESET_POLL_TIME); - - if (bbDebug) - printf("pepRxTask(%d): restarting after abort\n", link); - } - } -} - -/****************************************************************** - * FUNCTION: pepWdTask() - * PURPOSE : - * - * ARGS IN : none - * ARGS OUT: none - * GLOBALS: none - ******************************************************************/ -STATIC int pepWdTask(int link) -{ - struct dpvtBitBusHead *pnode; - struct dpvtBitBusHead *npnode; - unsigned long now; - -#ifdef PEP_DO_RESET_AND_OFFLINE - SEM_ID syncSem; - - struct dpvtBitBusHead resetNode; - unsigned char resetNodeData; /* 1-byte data field for RAC_RESET */ - unsigned char responseData; - - struct dpvtBitBusHead offlnNode; - unsigned char offlnNodeData; /* 1-byte data field for RAC_OFFLN */ - unsigned char response1Data; /* 1-byte response data field */ - - /* init the SEM used when sending the RAC_OFFLNE message */ - syncSem = semBCreate(SEM_Q_PRIORITY,SEM_EMPTY); - - /* - * Hand-craft a RAC_RESET and RAC_OFFLINE message to use when - * a message times out. - * NOTE that having only one copy is OK provided that the dog waits for - * a response before sending it again! - */ - resetNode.finishProc = NULL; /* no callback routine used */ - resetNode.psyncSem = NULL; - resetNode.link = link; /* which bitbus link to send message out on */ - resetNode.rxMaxLen = 10; - resetNode.ageLimit = sysClkRateGet()*100; /* make sure this never times out */ - - resetNode.txMsg.length = 8; - resetNode.txMsg.route = BB_STANDARD_TX_ROUTE; - resetNode.txMsg.tasks = 0x0; - resetNode.txMsg.data = &resetNodeData; - resetNode.rxMsg.data = &responseData; - - offlnNode.finishProc = NULL; /* no callback routine used */ - offlnNode.psyncSem = &syncSem;/* do a semGive on this SEM when responded to*/ - offlnNode.link = link; /* which bitbus link to send message out on */ - offlnNode.rxMaxLen = 10; - offlnNode.ageLimit = sysClkRateGet()*100; /* make sure this never times out */ - - offlnNode.txMsg.length = 8; - offlnNode.txMsg.route = BB_STANDARD_TX_ROUTE; - offlnNode.txMsg.tasks = 0x0; - offlnNode.txMsg.data = &offlnNodeData; - offlnNode.rxMsg.data = &response1Data; -#endif - - pBBLink[link]->nukeEm = 0; /* Make sure the nuke status is clear */ - while(1) { - /* SLEEP UNTIL WATCHDOG TIMER ROUTINE GIVES SEMAPHORE */ - semTake(pBBLink[link]->watchDogSem, WAIT_FOREVER); - now = tickGet(); /* what time is it? */ - - if (pBBLink[link]->nukeEm != 0) - printf("Bitbus manual reset being issued on link %d\n", link); - - if (bbDebug>4) - printf("pepWdTask(%d): (Watchdog) checking busy list\n", link); - - pBBLink[link]->rxAbortAck = 0; - pBBLink[link]->txAbortAck = 0; - - if (pBBLink[link]->nukeEm != 0) { - /* set abort status and wait for the abort acks */ - pBBLink[link]->abortFlag = 1; - - /* wake up the Tx task so it can observe the abort status */ - semGive(pBBLink[link]->linkEventSem); - - /* wake up the Rx task so it can observe the abort status */ - semGive(pBBLink[link]->l.PepLink.rxInt); - - /* sleep until abort ack from Tx & Rx tasks */ - while ((pBBLink[link]->rxAbortAck == 0) && - (pBBLink[link]->txAbortAck == 0)) - taskDelay(RESET_POLL_TIME); - -#ifdef BB_SUPER_DEBUG - if (pBBLink[link]->nukeEm < 2) - { /* Do a history dump since this is not supposed to happen */ - BBHistDump(link); - } -#endif - } - /* - * Run thru entire busy list to see if there are any transactions - * that have been waiting on a response for too long a period. - */ - semTake(pBBLink[link]->busyList.sem, WAIT_FOREVER); - pnode = pBBLink[link]->busyList.head; - - while (pnode != NULL) { - npnode = pnode->next; /* remember where we were in the list */ - - if ((pBBLink[link]->nukeEm != 0) || (pnode->retire <= now)) { - /* Get rid of the request and set error status etc... */ - listDel(&(pBBLink[link]->busyList), pnode); - -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, pnode, XACT_HIST_STATE_WD_TIMEOUT); -#endif - if (bbDebug) - { - printf("pepWdTask(%d): TIMEOUT on bitbus message:\n", link); - drvBitBusDumpMsg(&pnode->txMsg); - } - - if(pnode->txMsg.node < BB_NUM_NODES) { - bbNodeTMO[link][pnode->txMsg.node]++; - } - - /* BUG -- do this here or defer until RX gets a response? */ - (pBBLink[link]->deviceStatus[pnode->txMsg.node])--; /* fix device status */ - pnode->status = BB_TIMEOUT; - -#ifdef PEP_DO_RESET_AND_OFFLINE - /* Gotta do this now in case we need the info after the completion */ - resetNode.txMsg.node = pnode->txMsg.node; - offlnNodeData = pnode->txMsg.node; /* mark the node number */ -#endif - /* Make the callbackRequest if one was spec'd */ - if(pnode->finishProc != NULL) - { - if (bbDebug>2) - { - printf("pepWdTask(%d): invoking the callbackRequest %p %d\n", link, pnode->finishProc, pnode->priority); - } - callbackRequest(pnode); /* schedule completion processing */ - } - else - { - /* Release a completion lock if one was spec'd */ - if (pnode->psyncSem != NULL && pBBLink[link]->nukeEm == 0) - semGive(*(pnode->psyncSem)); - } - -#ifdef PEP_DO_RESET_AND_OFFLINE - /* If we are not going to reboot the link... */ - if ( pBBLink[link]->nukeEm == 0 ) { - /* Send out a RAC_RESET/RAC_OFFLINE pair */ - semGive(pBBLink[link]->busyList.sem); - - /* Configure message for a RAC_RESET */ - resetNode.txMsg.cmd = 0x00; - - /* Configure message for a RAC_OFFLINE */ - offlnNode.txMsg.cmd = RAC_OFFLINE; - offlnNode.txMsg.node = 0xff; - - /* Queue the messages (high priority, reset first) */ - - semTake(pBBLink[link]->queue[BB_Q_HIGH].sem, WAIT_FOREVER); - listAddHead(&(pBBLink[link]->queue[BB_Q_HIGH]), &offlnNode); -/* listAddHead(&(pBBLink[link]->queue[BB_Q_HIGH]), &resetNode); */ - semGive(pBBLink[link]->queue[BB_Q_HIGH].sem); - - semGive(pBBLink[link]->linkEventSem); /* Tell TxTask to send the messages */ - - if (semTake(syncSem, (sysClkRateGet()) ) == ERROR) - { - if (bbDebug) - printf("pepWdTask(%d): link dead, trying manual reboot\n", link); - - pBBLink[link]->nukeEm = 1; - pBBLink[link]->abortFlag = 1; - semGive(pBBLink[link]->linkEventSem); - semGive(pBBLink[link]->rxInt); - - /* sleep until abort ack from Tx & Rx tasks */ - while ((pBBLink[link]->rxAbortAck == 0) && - (pBBLink[link]->txAbortAck == 0)) - taskDelay(RESET_POLL_TIME); - } - - /* Start over since released the busy list */ - semTake(pBBLink[link]->busyList.sem, WAIT_FOREVER); - npnode = pBBLink[link]->busyList.head; - } -#endif - - } - pnode = npnode; - } - - /* Finish the link reboot if necessary */ - if (pBBLink[link]->nukeEm != 0) - { - /* shut down the bitbus card. */ - pepReset(link); - - if (pBBLink[link]->nukeEm == 2) - { - /* - * Stop the watchdog task so the link stays dead. - * Since the busy list is locked and the nukeEm flag is still set, - * this link can not do any more work. - */ - abort(); - } - - /* clear the abort_flag */ - pBBLink[link]->abortFlag = 0; - - pBBLink[link]->nukeEm = 0; - } - - if (pBBLink[link]->busyList.head != NULL) { - /* Restart the dog timer */ - if (bbDebug>5) - printf("pepWdTask(%d): restarting watch dog timer\n", link); - - wdStart(pBBLink[link]->watchDogId, pBBLink[link]->busyList.head->retire - now, - pepTmoHandler, link); - } - - semGive(pBBLink[link]->busyList.sem); - - /* In case the TX is waiting on a node that just timed out */ - semGive(pBBLink[link]->linkEventSem); - } -} - -/****************************************************************** - * FUNCTION: pepTxTask() - * PURPOSE : This function is started as a task during driver init - * time. It's purpose is to keep the link busy with - * outgoing messages. It awaits user-calls to qBBReq() - * (new message to send). It also awaits wake up calls - * from the Wd timer (a timed out message to a node, - * once handled, means Tx is free to send again to that - * node). - * - * ARGS IN : link - * ARGS OUT: none - * GLOBALS: none - ******************************************************************/ -STATIC int pepTxTask(int link) -{ - struct dpvtBitBusHead *pnode; - int prio; - int working; - int dogStart; - int stuck; - - int txTCount; - int txCCount; - unsigned char *txMsg; - register int x; - unsigned long now; - - if (bbDebug>1) - printf("pepTxTask started for link %d\n", link); - - while(1) { - if (pBBLink[link]->abortFlag != 0) { - /* let the dog know we are ready */ - pBBLink[link]->txAbortAck = 1; - -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, NULL, XACT_HIST_STATE_TX_ABORT); -#endif - - if (bbDebug) - printf("pepTxTask(%d): resetting due to abort status\n", link); - - while (pBBLink[link]->abortFlag != 0) - taskDelay(RESET_POLL_TIME); /* wait for link to reset */ - - if (bbDebug) - printf("pepTxTask(%d): restarting after abort\n", link); - } - else - { - if (pBBLink[link]->DelayCount) - semTake(pBBLink[link]->linkEventSem, 2 * sysClkRateGet()); - else - semTake(pBBLink[link]->linkEventSem, WAIT_FOREVER); - } - - if (bbDebug>5) - printf("pepTxTask(%d): got an event\n", link); - - working = 1; - while ((working != 0) && (pBBLink[link]->abortFlag == 0) && - (pBBLink[link]->busyList.elements < PepMaxOutstandMsgs)) { - working = 0; - - prio = BB_NUM_PRIO-1; - while ((prio >= 0) && (pBBLink[link]->abortFlag == 0)) { - /* see if the queue has anything in it */ - semTake(pBBLink[link]->queue[prio].sem, WAIT_FOREVER); - - if ((pnode = pBBLink[link]->queue[prio].head) != NULL) - { - now = tickGet(); - while (pBBLink[link]->deviceStatus[pnode->txMsg.node] == BB_BUSY) - { - if ((pBBLink[link]->syntheticDelay[pnode->txMsg.node] != 0) - && (pBBLink[link]->syntheticDelay[pnode->txMsg.node] < now)) - { - if (bbDebug) - printf("pepTxTask(%d): terminating synthetic idle on node %d\n", link, pnode->txMsg.node); - (pBBLink[link]->deviceStatus[pnode->txMsg.node])--; - pBBLink[link]->syntheticDelay[pnode->txMsg.node] = 0; - pBBLink[link]->DelayCount--; - } - else - { - if ((pnode = pnode->next) == NULL) - break; - } - } - } - - /* Start of unpleasant patch. - Create an artificial delay to prevent back-to-back message - loading of the PEP FIFO, since this has proven to induce protocol - errors. - */ - if (PepLinkLoadDelay > 0) { - for (x=0 ; x < PepLinkLoadDelay ; x++); - } - /* End unpleasant patch */ - - if (pnode != NULL) { /* have an xact to start processing */ - working = 1; - - /* delete the node from the inbound fifo queue */ - listDel(&(pBBLink[link]->queue[prio]), pnode); - - semGive(pBBLink[link]->queue[prio].sem); -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, pnode, XACT_HIST_STATE_TX); -#endif - - - if (bbDebug>3) - printf("pepTxTask(%d): got xact, pnode=%p\n", link, pnode); - - /* Send the message in polled mode */ - txTCount = pnode->txMsg.length; - - /* BUG -- would be nice if we verify the length >6 here */ - - txCCount = 0; - txMsg = &(pnode->txMsg.length); - - while ((txCCount < txTCount -1) && (pBBLink[link]->abortFlag == 0)) { - - stuck = 1000; - while (((pBBLink[link]->l.PepLink.bbRegs->stat_ctl & PEP_BB_TFNF) - != PEP_BB_TFNF) && - (pBBLink[link]->abortFlag == 0) && - --stuck) - for(x=0;x<100;x++); /* wait for TX ready */ - - if (!stuck) - { -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, pnode, XACT_HIST_STATE_TX_STUCK); -#endif - txStuck(link); - } - else if (txCCount == 0) { /* first byte is package type */ - if (bbDebug>30) - printf("pepTxTask(%d): outputting %2.2X\n",link,0x81); - pBBLink[link]->l.PepLink.bbRegs->data = 0x81; - } - else if (txCCount == 1) { /* unused 2nd byte of package */ - if (bbDebug>30) - printf("pepTxTask(%d): outputting %2.2X\n",link,0x00); - pBBLink[link]->l.PepLink.bbRegs->data = 0x00; -#if 0 - } else if (txCCount == (txTCount -1)) { /* last byte of package */ - pBBLink[link]->l.PepLink.bbRegs->stat_ctl = *txMsg; - if (bbDebug>30) - printf("pepTxTask(%d): outputting last byte %2.2X\n", - link,*txMsg); -#endif - } else { /* regular ol' message byte */ - pBBLink[link]->l.PepLink.bbRegs->data = *txMsg; - if (bbDebug>30) - printf("pepTxTask(%d): outputting %2.2X\n",link,*txMsg); - if (txCCount != 6) - txMsg++; - else - txMsg = pnode->txMsg.data; - } - txCCount++; - } - - if (pBBLink[link]->abortFlag == 0) { - - /* don't add to busy list if was a RAC_RESET_SLAVE */ - if ((pnode->txMsg.cmd == RAC_RESET_SLAVE) && (pnode->txMsg.tasks == 0)) - { -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, pnode, XACT_HIST_STATE_TX_RESET); -#endif - if (bbDebug) - printf("pepTxTask(%d): RAC_RESET_SLAVE sent\n", link); - - pBBLink[link]->l.PepLink.bbRegs->stat_ctl = *txMsg; - if (bbDebug>30) - printf("pepTxTask(%d): outputting last byte %2.2X\n", - link,*txMsg); - - pnode->status = BB_OK; - - if (pnode->finishProc != NULL) { - if (bbDebug>4) - printf("pepTxTask(%d): invoking the callbackRequest\n", - link); - callbackRequest(pnode); /* schedule completion processing */ - } - else - { - /* If there is a semaphore for synchronous I/O, unlock it */ - if (pnode->psyncSem != NULL) - semGive(*(pnode->psyncSem)); - } - taskDelay(15); - } - else - { - /* Lock the busy list */ - semTake(pBBLink[link]->busyList.sem, WAIT_FOREVER); - - pBBLink[link]->l.PepLink.bbRegs->stat_ctl = *txMsg; - if (bbDebug>30) - printf("pepTxTask(%d): outputting last byte %2.2X\n", - link,*txMsg); - - /* set the retire time */ - pnode->retire = tickGet(); - if (pnode->ageLimit) - pnode->retire += pnode->ageLimit; - else - pnode->retire += BB_DEFAULT_RETIRE_TIME * sysClkRateGet(); - - if (pBBLink[link]->busyList.head == NULL) - dogStart = 1; - else - dogStart = 0; - - /* Add pnode to the busy list */ - listAddTail(&(pBBLink[link]->busyList), pnode); - - /* Count the outstanding messages */ - (pBBLink[link]->deviceStatus[pnode->txMsg.node])++; - - semGive(pBBLink[link]->busyList.sem); - - /* If something just added to empty busy list, start the dog */ - if (dogStart) { - now = tickGet(); - wdStart(pBBLink[link]->watchDogId, - pBBLink[link]->busyList.head->retire - now, - pepTmoHandler, link); - } - } - } else { /* if abortFlag != 0 */ - /* Aborted transmission operation, re-queue the message */ - semTake(pBBLink[link]->queue[BB_Q_HIGH].sem, WAIT_FOREVER); - listAddHead(&(pBBLink[link]->queue[BB_Q_HIGH]), pnode); - semGive(pBBLink[link]->queue[BB_Q_HIGH].sem); -#ifdef BB_SUPER_DEBUG - BBSetHistEvent(link, pnode, XACT_HIST_STATE_TX_ABORT); -#endif - } - - } else { /* if pnode == NULL */ - /* we have no xacts that can be processed at this time */ - semGive(pBBLink[link]->queue[prio].sem); - } - prio--; /* look at the next prio queue */ - } - } - } -} - /****************************************************************** - * FUNCTION: dumpStat() - * PURPOSE : Temporary function. Shows contents of status - * register on PB-BIT module corresponding to link. - * ARGS IN : link - * ARGS OUT: none - * GLOBALS: none - ******************************************************************/ -int pepDumpStat(int link) -{ - unsigned char stat_ctl; - - stat_ctl = pBBLink[link]->l.PepLink.bbRegs->stat_ctl; - - printf("stat_ctl reg: %2X\n",stat_ctl); - return(OK); -} - -/* pulseSysMon.c */ -/* Function for pulsing a bit on System Monitor Board */ -/* TEMPORARY ROUTINE TO FIND BITBUS PROBLEMS*/ -typedef struct SysmonStruct { - char Pad[36]; /*** nF0 - nF17 36 bytes ***/ - unsigned short SysmonStatusLink; /*** nF18 ***/ - unsigned short SysmonDio; /*** nF19 ***/ - unsigned short SysmonIntMask; /*** nF20 ***/ - unsigned short SysmonTemperature; /*** nF21 ***/ - unsigned short SysmonWatchdog; /*** nF22 ***/ - unsigned short SysmonVXIVector; /*** nF23 ***/ - unsigned short SysmonIntVector; /*** nF24 ***/ - unsigned short SysmonIRQ1; /*** nF25 ***/ - unsigned short SysmonIRQ2; /*** nF26 ***/ - unsigned short SysmonIRQ3; /*** nF27 ***/ - unsigned short SysmonIRQ4; /*** nF28 ***/ - unsigned short SysmonIRQ5; /*** nF29 ***/ - unsigned short SysmonIRQ6; /*** nF30 ***/ - unsigned short SysmonIRQ7; /*** nF31 ***/ -} SysmonStruct; - -int bitbusTriggerWidth = 1500; - -long pulseSysMon() { - volatile SysmonStruct *SysmonBase; - volatile unsigned short *pReg; - int i; - unsigned short probeVal; - volatile int j = 0; - - if (sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO, (char *)0x8b80, - (char **)&(SysmonBase)) == ERROR) { - printf("can't convert to local address, aborting\n"); - return(1); - } - pReg = &(SysmonBase->SysmonDio); - - if(bbDebug) printf("Error Trigger\n"); - - probeVal = 0xffff; - vxMemProbe((char*) pReg, WRITE, 2, (char*)&probeVal); - for (i=0 ; i < bitbusTriggerWidth ; i++) { - j++; - j--; - } - probeVal = 0x0000; - vxMemProbe((char*) pReg, WRITE, 2, (char*)&probeVal); - - return(0); -} - - -long bbDump() { - int i,j; - - for (j=0; jinp.type) { - case (VME_IO) : - if(pwf->inp.value.vmeio.card >= BB_NUM_LINKS) { - epicsPrintf("%s.INP >> card number invalid\n", pwf->name); - pwf->pact = 1; /* don't allow processing */ - return -1; - } - if(pwf->ftvl != menuFtypeUSHORT) { - epicsPrintf("%s.FTVL >> expected USHORT \n", pwf->name); - pwf->pact = 1; /* don't allow processing */ - return -1; - } - pwf->nord = 0; - break; - default : - epicsPrintf("%s.INP >> expected VME_IO INP field\n", pwf->name); - pwf->pact = 1; /* don't allow processing */ - return -1; - } - return(0); -} - - -static long read_91s(pwf) - struct waveformRecord *pwf; -{ - long nRequest = BB_NUM_NODES; - - if(pwf->nelm < BB_NUM_NODES) nRequest = pwf->nelm; - - memcpy( pwf->bptr, (void *)&bbNode91[pwf->inp.value.vmeio.card][0], - nRequest * 2); - - pwf->nord = nRequest; - - return(0); -} - -static long read_TMOs(pwf) - struct waveformRecord *pwf; -{ - long nRequest = BB_NUM_NODES; - - if(pwf->nelm < BB_NUM_NODES) nRequest = pwf->nelm; - - memcpy( pwf->bptr, (void *)&bbNodeTMO[pwf->inp.value.vmeio.card][0], - nRequest * 2); - - pwf->nord = nRequest; - - return(0); -} - - -static long init_bo_record(pbo) - struct boRecord *pbo; -{ - - - /* bo.out must be a VME_IO type such that Cx indicates the bitbus link - * that isdesired to be cleared. - */ - switch (pbo->out.type) { - case (VME_IO) : - if(pbo->out.value.vmeio.card >= BB_NUM_LINKS) { - epicsPrintf("%s.OUT >> card number invalid\n", pbo->name); - pbo->pact = 1; /* don't allow processing */ - return -1; - } - break; - default : - epicsPrintf("%s.OUT >> expected VME_IO type\n", pbo->name); - pbo->pact = 1; /* don't allow processing */ - return -1; - } - return(0); -} - - -static long clear_stats(pbo) - struct boRecord *pbo; -{ - int i; - - if(pbo->out.value.vmeio.card < BB_NUM_LINKS) { - for (i=1;iout.value.vmeio.card][i] = 0; - bbNode91[pbo->out.value.vmeio.card][i] = 0; - } - } - else { - epicsPrintf("%s.OUT >> card number invalid\n", pbo->name); - } - - return(0); -} - diff --git a/src/drv/old/drvBitBus.h b/src/drv/old/drvBitBus.h deleted file mode 100644 index bea3ca763..000000000 --- a/src/drv/old/drvBitBus.h +++ /dev/null @@ -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 diff --git a/src/drv/old/drvBitBusErr.h b/src/drv/old/drvBitBusErr.h deleted file mode 100644 index 160861d25..000000000 --- a/src/drv/old/drvBitBusErr.h +++ /dev/null @@ -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 /* 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 diff --git a/src/drv/old/drvBitBusInterface.h b/src/drv/old/drvBitBusInterface.h deleted file mode 100644 index 911649ba4..000000000 --- a/src/drv/old/drvBitBusInterface.h +++ /dev/null @@ -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 - -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 - diff --git a/src/drv/old/drvComet.c b/src/drv/old/drvComet.c deleted file mode 100644 index 483bab6ec..000000000 --- a/src/drv/old/drvComet.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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= 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); -} - diff --git a/src/drv/old/drvCompuSm.c b/src/drv/old/drvCompuSm.c deleted file mode 100644 index 863e0e853..000000000 --- a/src/drv/old/drvCompuSm.c +++ /dev/null @@ -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 -#include -#include -#include -#include /* library for semaphore support */ -#include /* library for semaphore support */ -#include /* library for semaphore support */ -#include /* library for semaphore support */ -#include -#include /* library for ring buffer support */ - -/* drvCompuSm.c - Driver Support Routines for CompuSm */ - -#include -#include -#include -#include -#include -#include -#include - - -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); - } - } - } diff --git a/src/drv/old/drvDvx.c b/src/drv/old/drvDvx.c deleted file mode 100644 index 98b0f11f8..000000000 --- a/src/drv/old/drvDvx.c +++ /dev/null @@ -1,1439 +0,0 @@ -/* share/src/drv/drvDvx.c - * base/src/drv $Id$ - * - * subroutines which are used to interface with the analogic 2502 - * A/D scanner cards - * - * Author: Matthew Stettler - * Date: 5-23-90 - * - * AT-8 hardware design - * - * Modules: - * - * dvx_driver_init Finds and initializes all 2502 cards - * dvx_dma_init Initializes Am9516 DMA controller - * dvx_driver Reads data from 2502 - * dvx_int Interrupt service routine - * - * Test Routines: - * - * dvx_dump dumps RAM buffer - * dvx_dread command line interface to dvx_driver - * dvx_fempty clears fifo from command line - * dvx_dma_stat displays DMA channel status - * - * 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: - * ----------------- - * MS 6/22/90 Modifications to aid in debugging interface to Mizar timing - * system. Interrupt service routine now counts words when clearing - * fifo, dvx_dump provides fifo status, and dvx_fempty added to - * clear fifo from command line. - * - * MS 7/9/90 Modifications to speed up interrupt service routine. - * - * MS 7/23/90 Added DMA control logic. - * - * MS 8/20/90 Added support for interrupt scanned records. - * - * MS 9/20/90 Changed data conversion to offset binary - * (only test routines affected) - * - * JH 07/25/91 added dvx_reset() and dvx_reset() on control X reboot - * - * JH 11/14/91 changed a sysBCLSet to sysIntEnable so ioc_core - * will load into the nat inst cpu030 - * - * JH 11/14/91 removed sysBCLSet enabling STD non priv and super - * access since this is already enabled if we are - * processor 0 - * JH 11/14/91 changed DVX_INTLEV from a mask to a level - * to support use of sysIntEnable() which - * is architecture independent - * BG 4/22/92 added sysBusToLocalAddr() for both short and standard - * addresses for this module. Moved DVX_ADDR0 to - * ai_addrs[DVX2502]in module_types.h. Also moved DVX_IVECO - * to module_types.h. - * BG 6/23/92 combined dvx_driver.c and drvDvx.c - * BG 06/26/92 added level to dvx_io_report in drvDvx structure. - * JH 06/29/92 moved the rest of the dvx io_report here - * BG 7/2/92 removed the semaphores from dvx_io_report - * JH 08/03/92 Removed hkv2f dependent base addr - * JH 08/03/92 moved interrupt vector base to module_types.h - * JH 08/05/92 dvx driver init is called from drvDvx now - * JH 08/10/92 merged dvx private include file into this source - * JH 09/09/92 ran through UNIX C beautifier and converted to ANSI C - * JH 09/09/92 check to see if A24 is open prior to mapping - * the seq ram. - * JH 09/14/92 Made taskDelays() CPU tick rate independent - * tick rate - * JH 09/15/92 made interrupt vector CPU independent - * MRK 09/16/92 Added support for new I/O event scanning - * JH 09/16/92 dont write wordcnt every time the fifo is unloaded - * JH 09/16/92 Use sysLocalToBusAdrs() to translate from an internal - * to a VME A24 address in case the internal base for A24 - * addressed local memory is not on a 16MB boundary. - * sysLocalToBusAdrs() is called for each malloc'ed - * pointer used by the DVX to verify that each one is - * within the portion of local memory mapped to A24. - * JH 09/17/92 one more sysLocalToBusAdrs() address translation - * needed - * JRW 01/18/92 Replaced init code to allow user to select the interrupt - * level value and to select the ports that are to be read. - * MGB 08/04/93 Removed V5/V4 and EPICS_V2 conditionals - * FRL 11/17/93 Added gain parameter to dvx_program - * - * - * NOTE (JRW 11-18-92): - * In a phone conversation with Analogic, Tech support said that when the start - * signal is de-asserted (when using external start/stop mode), the DMAC is - * told to start transferring more data. This is in case the sampling - * completes with less than 512 bytes in the fifo. - * - * In another phone conversation with Analogic, tech support told me that when - * the start signal is de-asserted (when using external start/stop mode), the - * sequence program pointer is reset to 0 (zero). This is fine and dandy, but - * it can cause the mux stage/pipeline to start improperly. Thus causing the - * first data sample to be corrupt. - * - * BUGS: - * The driver should inspect the VXI make and model codes and use a data type - * for the DMA buffer that is appropriate. - * - * $Log$ - * Revision 1.3 1997/04/30 19:02:04 mrk - * Fixed many compiler warning messages - * - * Revision 1.2 1995/09/01 14:36:35 winans - * Added ability to change default clock speed from shell. - * - * Revision 1.1 1995/03/30 19:35:14 jba - * Seperated drv files into ansi and old dirs. Added combine dir. - * - * Revision 1.22 1995/01/06 17:03:43 winans - * Added some ifdef'd out test code to see if the end of the sequence program - * could be updated to NOT cause an extra sample from port zero to be taken - * at the end of the sequence. As it turns out, it causes more harm than - * good. There must be something wrong with my understanding on how it works. - * For now, the misfeature of the extra sample at the end of the sequence will - * have to stay. - * - * - */ - -static char *SccsId = "$Id$"; - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -/* general constants */ -#define DVX_ID 0xCFF5 /* analogic ID code */ -#define MAX_DVX_CARDS 5 /* max # of 2502 cards per IOC */ -#define MAX_PORTS 3 /* max # of 2601 cards per 2502 */ -#define DVX_DRATE 0xFFEC /* default scan rate of 184 KHz */ -#define DVX_SRATE 0xF201 /* slow scan used for run away mode */ -#define DVX_RAMSIZE 2048 /* sequence RAM size (words) */ -#define DVX_NBUF 1 /* default # of input buffers */ - -/* modes of operation */ -#define INIT_MODE 0 /* initialization mode */ -#define RUN_MODE 1 /* aquisition mode */ - -/* self test constants */ -#define TST_RATE 0x3ED /* self test scan rate */ -#define TST_THRESH 0xD00 /* mux card test threshold reg value */ - -/* csr command bits */ -#define CSR_RESET 0x01 /* software reset */ -#define CSR_M_START 0x10 /* internal scan start */ -#define CSR_M_ETRIG 0x40 /* external trigger enable */ -#define CSR_M_ESTART 0x20 /* external start enable */ -#define CSR_M_SYSFINH 0x02 /* system fail inhibit */ -#define CSR_M_A24 0x8000 /* enable sequence RAM */ -#define CSR_M_INT 0x80 /* interrupt enable */ -#define CSR_M_MXTST 0x3A /* mux card test bits */ - -/* csr status bits */ -#define S_NEPTY 0x02 /* fifo not empty when = 1 */ - -/* Sequence Program control codes */ -#define GAIN_CHANNEL 0x80 -#define ADVANCE_TRACK 0x40 -#define ADVANCE_HOLD 0xC0 -#define RESTART 0x00 - -/* Analogic 2502 memory structure */ -struct dvx_2502 -{ - unsigned short dev_id; /* device id code (CFF5) */ - unsigned short dev_type; /* type code (B100) */ - unsigned short csr; /* control and status register */ - unsigned short seq_offst; /* sequence RAM offset register */ - unsigned short mem_attr; /* memory attribute register */ - unsigned short samp_rate; /* sample rate register */ - unsigned short dma_point; /* DMA pointer register */ - unsigned short dma_data; /* DMA data register */ - unsigned short thresh; /* threshold register */ - unsigned short fifo; /* input fifo */ - unsigned short end_pad[54]; /* pad to 64 byte boundary */ -}; - -/* input buffer */ -struct dvx_inbuf -{ - struct dvx_inbuf *link; /* link to next buffer */ - int wordcnt; /* # of words read to clear fifo */ - short *data; /* data buffer */ -}; - -/* Analogic 2502 control structure */ -struct dvx_rec -{ - struct dvx_2502 *pdvx2502; /* pointer to device registers */ - short *sr_ptr; /* pointer to sequence RAM */ - struct dvx_inbuf *inbuf; /* pointer to current buffer */ - short unsigned csr_shadow; /* csr shadow register */ - short mode; /* operation mode (init or run) */ - int int_vector; /* interrupt vector */ - int intcnt; /* interrupt count # */ - int cnum; /* card number */ - - int dmaSize; /* samples to read before IRQ */ - unsigned int numChan; /* total number of ports to read */ - unsigned long pgmMask[8]; /* ports to be read by seq-program */ - unsigned short gain[8]; /* port gains */ - - int RearmMode; /* zero if auto-rearm, else manual */ - - unsigned short ScanRate; /* User settable scan rate */ - - IOSCANPVT *pioscanpvt; -}; - -/* dma chain table size */ -#define DVX_CTBL 34 /* max size of chain table */ - -/* am9516 register select constants. - * The DMA control registers are accessed through the dvx2502 registers - * dma_point and dma_data. The constants below are the addresses which must - * be loaded into the pointer register to access the named register through - * the data register. All dual registers are commented as #2. To access channel - * #1, OR the value M_CH1 with the channel #2 address. - */ -#define DMA_MMR 0x38 /* master mode register */ -#define DMA_CSR 0x2C /* command/status register #2 */ -#define DMA_CARAH 0x18 /* current address reg A high #2 */ -#define DMA_CARAL 0x08 /* current address reg A low #2 */ -#define DMA_CARBH 0x10 /* current address reg B high #2 */ -#define DMA_CARBL 0x00 /* current address reg B low #2 */ -#define DMA_BARAH 0x1C /* base address reg A high #2 */ -#define DMA_BARAL 0x0C /* base address reg A low #2 */ -#define DMA_BARBH 0x14 /* base address reg B high #2 */ -#define DMA_BARBL 0x04 /* base address reg B low #2 */ -#define DMA_COC 0x30 /* current operation count #2 */ -#define DMA_BOC 0x34 /* base operation count #2 */ -#define DMA_ISR 0x28 /* interrupt save register #2 */ -#define DMA_IVR 0x58 /* interrupt vector register #2 */ -#define DMA_CMRH 0x54 /* channel mode register #2 */ -#define DMA_CMRL 0x50 /* channel mode register #2 */ -#define DMA_CARH 0x24 /* chain address reg high #2 */ -#define DMA_CARL 0x20 /* chain address reg low #2 */ -#define M_CH1 0x2 /* mask for chan 1 reg addresses */ - -/* am9516 command constants - * All dual commands are commented as #1. To command channel #2, OR the - * valur M_CH2 with the channel #1 command. - */ -#define MMR_ENABLE 0x0D /* chip enable value */ -#define CMR_RESET 0x0 /* reset all channels */ -#define CMR_START 0xA0 /* start channel #1 */ -#define CMR_SSR 0x42 /* set software request #1 */ -#define CMR_CSR 0x40 /* clear software request #1 */ -#define CMR_SHM 0x82 /* set hardware mask #1 */ -#define CMR_CHM 0x80 /* clear hardware mask #1 */ -#define CMR_SC 0x22 /* set CIE/IP #1 */ -#define CMR_CC 0x20 /* clear CIE/IP #1 */ -#define CMR_SFB 0x62 /* set flip bit #1 */ -#define CMR_CFB 0x60 /* clear flip bit #1 */ -#define M_CIE 0x10 /* int enable bit mask (SC/CC cmd) */ -#define M_IP 0x4 /* int pending bit mask (SC/CC cmd) */ -#define M_CH2 0x1 /* mask for channel #2 commands */ - -/* am9516 chain reload constants */ -#define R_CAR 0x1 /* chain address */ -#define R_CMR 0x2 /* channel mode */ -#define R_IVR 0x4 /* interrupt vector */ -#define R_PMR 0x8 /* pattern and mask */ -#define R_BOC 0x10 /* base operation count */ -#define R_BAB 0x20 /* base address register B */ -#define R_BAA 0x40 /* base address register A */ -#define R_COC 0x80 /* current operation count */ -#define R_CAB 0x100 /* current address register B */ -#define R_CAA 0x200 /* current address register A */ - -/* If any of the following does not exist replace it with #define <> NULL */ -long dvx_io_report(int level); -static long dvx_driver_init(void); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvDvx={ - 2, - dvx_io_report, - dvx_driver_init}; - -static struct dvx_rec dvx[MAX_DVX_CARDS] = { -{ NULL, NULL, NULL, -1, -1, -1, -1, -1, 128, 0, {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff} -,{0, 0, 0, 0, 0, 0, 0, 0}, -0 , DVX_DRATE, NULL -}, -{ NULL, NULL, NULL, -1, -1, -1, -1, -1, 128, 0, {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff} -,{0, 0, 0, 0, 0, 0, 0, 0}, -0, DVX_DRATE, NULL -}, -{ NULL, NULL, NULL, -1, -1, -1, -1, -1, 128, 0, {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff} -,{0, 0, 0, 0, 0, 0, 0, 0}, -0, DVX_DRATE, NULL -}, -{ NULL, NULL, NULL, -1, -1, -1, -1, -1, 128, 0, {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff} -,{0, 0, 0, 0, 0, 0, 0, 0}, -0, DVX_DRATE, NULL -} -}; - -static int DVX_INTLEV=5; /* allow this to be user setable */ -static int dvxOnline = 0; /* 1 after init invoked */ - -#ifdef __STDC__ -int lclToA24(void *pLocal, void **ppA24); -static void dvx_reset(void); -static void dvx_int(struct dvx_rec *dvxptr); -static int muxtst(int card); -static int sramld(int card); -static int dvx_driver( int card, int chan, short *pval); -int dvx_dread(int card,int chan); -int dvx_dump(int card,int firstchan,int lastchan); -int dvx_chan_print(int dvx_card, int firstchan, int lastchan); -static int dvx_fempty(int card); -static int dvx_dma_init(struct dvx_rec *ptr); -static int dvx_dma_reset(struct dvx_rec *ptr); -int dvx_dma_stat(int card, int chan); -#else /* __STDC__ */ - -int lclToA24(); -static void dvx_reset(); -static void dvx_int(); -static int muxtst(); -static int sramld(); -int dvx_driver(); -int dvx_dread(); -int dvx_dump(); -int dvx_chan_print(); -static int dvx_fempty(); -static int dvx_dma_init(); -static int dvx_dma_reset(); -int dvx_dma_stat(); - - -#endif /* __STDC__ */ - - -int dvxDebug = 0; - - -/* - * dvx_int - * - * interrupt service routine - * - */ -LOCAL void -dvx_int(struct dvx_rec *dvxptr) -{ - /* BUG --- why are there STATIC variables in here????? */ - - static short i, junk; - register struct dvx_2502 *cptr; - - cptr = dvxptr->pdvx2502; - cptr->dma_point = DMA_CSR; - cptr->dma_data = CMR_CC | M_IP | M_CH2; /* clear dma int channel #2 */ - cptr->csr = dvxptr->csr_shadow & 0xff5f; /* disable fifo interrupts */ - switch (dvxptr->mode) - { - /* - * interrupt recieved during initialization - * - empty fifo and throw away data - */ - case INIT_MODE: - if(dvxDebug) - logMsg("dvx_int: INIT_MODE\n"); - dvxptr->intcnt = 0; /* initialize interrupt count */ - for (i = 0; cptr->csr & 0x2; i++) - junk = cptr->fifo; - break; - /* - * interrupt recieved during data aquisition - * - empty fifo into next input buffer, then make it current - */ - case RUN_MODE: - if(dvxDebug) - logMsg("dvx_int: RUN_MODE\n"); - dvxptr->intcnt++; /* incriment interrupt count */ - - dvxptr->inbuf = dvxptr->inbuf->link; /* update current data buffer */ - - for (i = 0; cptr->csr & S_NEPTY; i++, junk = cptr->fifo); - - dvxptr->inbuf->wordcnt = i; /* record # of words to clear fifo */ - - if (dvxptr->RearmMode == 0) - { - /* enable DMA opeations */ - cptr->dma_point = DMA_CSR; - - /* enable int channel #2 */ - cptr->dma_data = CMR_SC | M_CIE | M_CH2; - - /* start channel #2 */ - cptr->dma_data = CMR_START | M_CH2; - } - - scanIoRequest(*(dvxptr->pioscanpvt)); - break; - } - cptr->csr = dvxptr->csr_shadow; -} - -int dvx_SetScanRate(int Card, unsigned int Rate) -{ - /* make sure hardware exists */ - if ((Card >= ai_num_cards[DVX2502]) || (Card < 0)) - return(-1); - - dvx[Card].ScanRate = Rate & 0x0000FFFF; - dvx[Card].pdvx2502->samp_rate = dvx[Card].ScanRate; - return(0); -} -int dvx_RearmModeSet(int card, int mode) -{ - /* make sure hardware exists */ - if ((card >= ai_num_cards[DVX2502]) || (card < 0)) - return(-1); - - dvx[card].RearmMode = mode; - return(0); -} - -int dvx_rearm(int card) -{ - struct dvx_rec *dvxptr; - struct dvx_2502 *cptr; - int i; - short junk; - - /* make sure hardware exists */ - if ((card >= ai_num_cards[DVX2502]) || (card < 0)) - return(-1); - else if(dvx[card].pdvx2502 == NULL) - return(-2); - - dvxptr = &dvx[card]; - cptr = dvxptr->pdvx2502; - - if (dvxptr->RearmMode == 0) - return(-3); - -#if 0 - cptr = dvxptr->pdvx2502; - cptr->dma_point = DMA_CSR; - cptr->dma_data = CMR_CC | M_IP | M_CH2; /* clear dma int channel #2 */ - cptr->csr = dvxptr->csr_shadow & 0xff5f; /* disable fifo interrupts */ -#endif - - /* Drain the fifo of any crud */ - for (i = 0; cptr->csr & S_NEPTY; i++, junk = cptr->fifo); - - if (dvxDebug) - printf("dvx_rearm(%d) fifo residual = %d\n", card, i); - - /* enable DMA opeations */ - cptr->dma_point = DMA_CSR; - - /* enable int channel #2 */ - cptr->dma_data = CMR_SC | M_CIE | M_CH2; - - /* start channel #2 */ - cptr->dma_data = CMR_START | M_CH2; - - return(0); -} - - -/* - * dvx_driver_init - * - * initialization for 2502 cards - * - */ -LOCAL long dvx_driver_init(void) -{ - int i; - int j; - int status; - unsigned short card_id; - struct dvx_inbuf *ibptr; - struct dvx_inbuf *ibptra; - int intvec = DVX_IVEC0; - struct dvx_2502 *pDvxA16; - short *pDvxA24; - short *pDvxA24Bus; - - /* - * dont continue DMA while vxWorks is control X - * rebooting (and changing bus arbitration mode) - * joh 072591 - */ - rebootHookAdd(dvx_reset); - - dvxOnline = 1; /* do not allow any more user config modifications */ - - status = sysBusToLocalAdrs( - VME_AM_SUP_SHORT_IO, - ai_addrs[DVX2502], - &pDvxA16); - if (status != OK){ - logMsg( "%s: A16 base addr problems DVX 2502\n", - __FILE__); - return ERROR; - } - - - /* - * search for DVX cards - */ - for ( i = 0, pDvxA24Bus = (short *)ai_memaddrs[DVX2502]; - i < ai_num_cards[DVX2502]; - i++, pDvxA16++, pDvxA24Bus += DVX_RAMSIZE) - { -# ifdef DEBUG - logMsg("Probing for DVX at %x\n", pDvxA16); -# endif - - dvx[i].pdvx2502 = NULL; - status = vxMemProbe ( - &pDvxA16->dev_id, - READ, - sizeof(card_id), - &card_id); - if (status <0){ - continue; - } - if (card_id != DVX_ID){ /* see if detected card is a 2502 */ - logMsg("%s: Card installed at addr=0X%x is not a dvx2502\n", - __FILE__, - pDvxA16); - continue; - } - - /* Card found! Finish the init for it. */ - - dvx[i].cnum = i; /* record card number */ - pDvxA16->csr = CSR_RESET; /* software reset */ - - status = sysBusToLocalAdrs( - VME_AM_STD_SUP_DATA, - pDvxA24Bus, - &pDvxA24); - if (status != OK){ - logMsg( "%s: A24 base addr problems DVX 2502 A24=%x\n", - __FILE__, - pDvxA24Bus); - continue; - } - - /* - * check for incorrectly addressed card in A24 - */ - status = vxMemProbe (pDvxA24, READ, sizeof(card_id), &card_id); - if (status == OK){ - logMsg( "%s: A24 responding where DVX should be addr=%x\n", - __FILE__, - pDvxA24); - logMsg( "%s: DVX card=%d ignored\n", - __FILE__, - i); - continue; - } - - - if ((dvx[i].pioscanpvt = (IOSCANPVT *) malloc(sizeof(IOSCANPVT))) == NULL) - return(-1); - if (dvx[i].dmaSize == 0) - { - logMsg("%s: No channels selected on card %d, init aborted\n", i); - continue; - } - - dvx[i].mode = INIT_MODE; /* initialization mode */ - /* create linked list of input buffers */ - for ( j = 0, ibptra = NULL; - j < DVX_NBUF; - j++, ibptra = ibptr) - { - - ibptr = (struct dvx_inbuf *)malloc(sizeof (struct dvx_inbuf)); - /* - * exit with error if buffer allocation fails - */ - if (ibptr == NULL) - return -1; /* unsuccessfull */ - - /* Needs to come from A24 mappable memory...? */ -#if 0 - if ((ibptr->data = (short *) malloc(dvx[i].dmaSize * sizeof(short))) == NULL) -#else - if ((ibptr->data = (short *) devLibA24Malloc(dvx[i].dmaSize * sizeof(short))) == NULL) -#endif - return(-1); - - if (dvxDebug) - printf("dvx_driver_init(%d) allocated ibp at %p buffer at %p\n", i, ibptr, ibptr->data); - if (j == 0){ - dvx[i].inbuf = ibptr; /* initialize if first */ - } - - ibptr->wordcnt = 0; - ibptr->link = ibptra; /* LINK TO last buffer */ - } - dvx[i].inbuf->link = ibptr; /* close list */ - - /* - * locate sequence RAM in an unassigned portion of VME A24 - * - * Use the A24 bus address since the processor may not have placed - * A24 on a 16 MB boundary - */ - pDvxA16->seq_offst = (int)pDvxA24Bus>>8; - dvx[i].csr_shadow = CSR_M_A24; /* enable sequence RAM (shadow csr) */ - pDvxA16->csr = dvx[i].csr_shadow; /* enable sequence RAM */ - - /* - * record card address and allocate input buffers - */ - dvx[i].pdvx2502 = pDvxA16; /* record card address */ - - /* - * locate and enable sequence RAM - */ - dvx[i].sr_ptr = pDvxA24; /* record seq RAM address */ - - /* - * set up interrupt handler - */ - dvx[i].csr_shadow |= (intvec<<8); /* load int vector (shadow csr) */ - pDvxA16->csr = dvx[i].csr_shadow; /* load int vector */ - dvx[i].int_vector = intvec; /* save interrupt vector # */ - status = intConnect(INUM_TO_IVEC(intvec),dvx_int,&dvx[i]); - if (status != OK) - return -2; /* abort if can't connect */ - sysIntEnable(DVX_INTLEV); /* enable interrupt level */ - - /* make sure the DMA chip is fully disabled */ - dvx_dma_reset(dvx[i].pdvx2502); - - dvx[i].csr_shadow |= CSR_M_INT; /* enable fifo int (shadow csr) */ - pDvxA16->csr = dvx[i].csr_shadow; /* enable fifo interrupts */ - intvec++; /* advance to next vector # */ - - /* - * test mux cards and load sequence RAM - */ - muxtst(i); /* test mux cards */ - sramld(i); /* load scan program */ - - dvx[i].csr_shadow ^= CSR_M_INT; /* disable fifo int (shadow csr) */ - pDvxA16->csr = dvx[i].csr_shadow; /* disable fifo interrupts */ - /* - * initialize DMA - */ - dvx_dma_init(&dvx[i]); /* initialize DMA controller */ - /* - * set scan rate and enable external start - */ -#if 0 - pDvxA16->samp_rate = DVX_DRATE; /* scan rate of 184 KHz */ -#else - pDvxA16->samp_rate = dvx[i].ScanRate; /* Set scan rate */ -#endif - dvx[i].csr_shadow |= CSR_M_ESTART; /* enable ext start (shadow csr) */ - pDvxA16->csr = dvx[i].csr_shadow; /* enable external start */ - dvx[i].mode = RUN_MODE; /* ready to aquire data */ - scanIoInit(dvx[i].pioscanpvt); - } - - return 0; /* return 0 to database */ -} - - -/* - * muxtst - * - * test multiplexer cards - * I suspect this test does nothing more than light the pass LED on all - * the 2601 multiplexer cards. - * - */ -LOCAL int muxtst(int card) -{ - int i; - short *ramptr; - - /* - * inhibit sys fail and load test setup parameters - */ - dvx[card].pdvx2502->csr = dvx[card].csr_shadow | CSR_M_SYSFINH; - ramptr = dvx[card].sr_ptr; /* pointer to sequence RAM */ - dvx[card].pdvx2502->thresh = TST_THRESH; /* load test threshold */ - dvx[card].pdvx2502->samp_rate = TST_RATE; /* test sample rate */ - /* - * load test program into sequence RAM - */ - for (i = 0; i < MAX_PORTS; i++) - { - *ramptr++ = GAIN_CHANNEL; /* first sequence RAM value */ - *ramptr++ = ADVANCE_HOLD | i; /* mux card select */ - } - *ramptr++ = RESTART; /* end of scan */ - *ramptr = RESTART; - /* - * run test and restore csr - */ - dvx[card].pdvx2502->csr = dvx[card].csr_shadow | CSR_M_MXTST; - taskDelay(sysClkRateGet()); /* let test run */ - dvx[card].pdvx2502->csr = dvx[card].csr_shadow; - dvx[card].pdvx2502->thresh = 0; /* restore threshold */ - return(0); -} - -/* - * dvx_program() is used to define what ports on what boards to scan - * when taking a sample. Each time a start pulse is supplied to the DVX - * board, it will read from the ports in the specified by the user. When - * dmaSize samples have been taken (possibly after many start pulses) the DMA - * controller will terminate transferring data and generate a completion event. - * After this event, the whole process starts over again with the next start - * pulse. - * - * The dvx_program() parms are simply a bit mask of what ports to read from - * each board. There may be up to 8 boards on one DVX master. The bit masks - * are 32 bit unsigned numbers that should be assigned during the startup - * script when booting the IOC. - * - * To program a DVX card (card 0) to read all ports from 2 S/H muxes (boards 2 - * and 6) and 1 mux (board 1). You may do the following. - * - * dvx_program(0, 2, 0x0000ffff, 0, 0) -- 16 ports from board 2 gain = 1 - * dvx_program(0, 6, 0x0000ffff, 0, 2) -- 16 ports from board 6 gain = 4 - * dvx_program(0, 1, 0xffffffff, 64, 3) -- 32 ports from board 1 gain = 8 - * - * The 64 on the last line specified that we want to read 64 samples before the - * DMA is considered complete. The last dvx_program() value for the dma size - * is the only one that is used, all previous are discarded. - * - * If so desired, the above example could have used 128 for the DMA size value. - * in this case, the dvx 'system' would not consider the sample complete until - * all the ports were read twice. - * - * NOTE: Each card has its own notion of DMA size. Each card also has its - * own notion of default values. If no programming is done for a - * specific card number, its default values will be used. - * - * The ports are read from the lowest board number and lowest port number first. - */ -int -dvx_program(int card, int board, unsigned long mask, int dmaSize, int gain) -{ - static int firstTime = 1; - - if (dvxOnline) - { - printf("DVX cards are already on line, no modifications allowed\n"); - return(-1); - } - if ((card < 0) || (card > ai_num_cards[DVX2502])) - { - printf("dvx_program(%d, %d, 0x%8.8X): invalid card number specified\n", card, board, mask); - return(1); - } - if ((board < 0) || (board > 7)) - { - printf("dvx_program(%d, %d, 0x%8.8X): invalid board number specified\n", card, board, mask); - return(2); - } - if ((gain < 0) || (gain > 3)) - { - errPrintf(-1, __FILE__, __LINE__, - "dvx_program(%d, %d, 0x%8.8X, %d, %d): invalid gain specified\n", card, board, - mask, dmaSize, gain); - return(2); - } - if (firstTime) - { /* Clear out the default port numbers, this is the first dvx_program call */ - int i; - - firstTime=0; - for (i=0; i<8; i++) - dvx[card].pgmMask[i] = 0; - } - - dvx[card].pgmMask[board] = mask; - dvx[card].dmaSize = dmaSize; - dvx[card].gain[board] = gain; - - return(0); -} - -/* - * Allow the user to specify the interrupt level number - * - * It returns the 'old' IRQ level value. - * - * NOTE that off the shelf DVX2502s are set to use IRQ level 1 - */ - -int dvx_setIrqLevel(int level) -{ - int i; - - if (dvxOnline) - { - printf("DVX card(s) already initialized at level %d, new IRQ level ignored\n", DVX_INTLEV); - return(DVX_INTLEV); - } - i = DVX_INTLEV; - DVX_INTLEV = level; - return(i); -} - -/* - * This can be called by a user program to get information about how - * the dvx card is programmed. - */ -int dvx_getProgram(int card, int *dmaSize, int *numChan) -{ - *dmaSize = dvx[card].dmaSize; - *numChan = dvx[card].numChan; - - if (dvxDebug) - printf("total DMA samples=%d, total number of physical channels=%d\n", *dmaSize, *numChan); - - return(-1); -} - -/* - * This version of the sequence program loader allows the number of channels - * to be programmable. It is assumed that the programmable constants will - * be fetched from the user. - * - */ -LOCAL -int sramld(int card) -{ - short *ramptr; - int i, port, firstPort; - unsigned long mask; - - /* load sequence program */ - ramptr = dvx[card].sr_ptr; /* point to sequence RAM */ - dvx[card].numChan = 0; - - for (i=0; i<8; i++) - { - mask = 1; - port = 0; - firstPort = -1; - - while(port < 32) - { - if (mask & dvx[card].pgmMask[i]) - { /* I need to read a sample from this port */ - if (firstPort == -1) - { /* save this one for prescan */ - firstPort = port; - } - else - { - *ramptr++ = GAIN_CHANNEL | (dvx[card].gain[i] <<3) | ((port >> 3) & 3); - *ramptr++ = ADVANCE_HOLD | ((port & 0x07) << 3) | i; - dvx[card].numChan++; - if (dvxDebug) - printf("board %d, port %d\n", i, port); - } - } - mask <<= 1; - port++; - } - if (firstPort != -1) - { /* Put the first port number to read on each board, last in scan list. */ - *ramptr++ = GAIN_CHANNEL | (dvx[card].gain[i] << 3) | ((firstPort >> 3) & 3); - *ramptr++ = ADVANCE_HOLD | ((firstPort & 0x07) << 3) | i; - dvx[card].numChan++; - if (dvxDebug) - printf("board %d, port %d\n", i, firstPort); - } - } - if (dvxDebug) - printf("Total channels read in %d\n", dvx[card].numChan); - -#if 1 /* This causes an extra sample to be taken at the end of the scan */ - *ramptr++ = 0; /* mark the end of the sequence program */ - *ramptr++ = 0; -#else /* This was supposed to get rid of the extra one, but does not work */ - *(ramptr-1) &= 0xff3f; - *ramptr = *(ramptr-1); -#endif - - /* set scan rate and run it once */ -#if 0 - dvx[card].pdvx2502->samp_rate = DVX_DRATE; -#else - dvx[card].pdvx2502->samp_rate = dvx[card].ScanRate; /* Set scan rate */ -#endif - dvx[card].pdvx2502->csr = dvx[card].csr_shadow | CSR_M_START; - taskDelay(sysClkRateGet()); /* let scan run */ - dvx[card].pdvx2502->csr = dvx[card].csr_shadow; /* restore csr */ - return(0); -} - - -/* - * dvx_driver - * - * interface to analog input buffer - * - */ -int dvx_driver( -int card, -int chan, -short *pval -) -{ - - if ((card >= ai_num_cards[DVX2502]) || (card < 0)) /* make sure hardware exists */ - return -1; - else if (dvx[card].pdvx2502 == NULL) - return -2; - else if (chan > dvx[card].dmaSize) - return -2; - - *pval = dvx[card].inbuf->data[chan]; - return 0; -} - -/* - * dvxReadWf - * - * Allows a waveform record to read all samples from the dvx buffer as a - * waveform. - */ -int dvxReadWf(int card, int start, int num, short *pwf, unsigned long *numRead) -{ - int dataIndex; - - if(dvxDebug) - printf("dvxReadWf(%d, %d, %d, 0x%8.8X, 0x%8.8X)\n", card, start, num, pwf, numRead); - - *numRead = 0; /* in case we have an error condition */ - - /* make sure hardware exists */ - if ((card >= ai_num_cards[DVX2502]) || (card < 0)) - return(-1); - else if ((dvx[card].pdvx2502 == NULL)||(start > dvx[card].dmaSize)|| - (start < 0)||(num < 1)) - return(-2); - - /* if user asked for too many, chop off the length to that available */ - if (start+num > dvx[card].dmaSize) - num -= (start+num) - dvx[card].dmaSize; - - dataIndex = start+num; - *numRead = num; - - if (dvxDebug) - printf("dvxReadWf(): Actual elements read: %d\n", num); - - while(num) - { - num--; - dataIndex--; - pwf[num] = dvx[card].inbuf->data[dataIndex]; - } - return(0); -} - - -/* - * dvx_dread - * - * stand alone interface to dvx_driver - * - */ -int dvx_dread(int card,int chan) -{ - short stat; - short unsigned data; - float volts; - - stat = dvx_driver(card,chan,(short *)&data); - volts = data * 10./32767. - 10; - printf("channel # %d\tdata = %x\tvolts = %f\n" - ,chan,data,volts); - return(0); -} - - -/* - * dvx_dump - * - * dump RAM buffer - * - */ -int dvx_dump(int card,int firstchan,int lastchan) -{ - int i, port, ix, printing, tmp; - unsigned long mask; - float volts; - - printf("Entering dvx_dump with card = %d,firstchan = %d,lastchan = %d\n",card,firstchan, - lastchan); - if ((card >= ai_num_cards[DVX2502]) || (card < 0)) - return -1; - else if (dvx[card].pdvx2502 == 0) - return -2; - printf("buffer address = %x word count = %d interrupt count = %d\n", - dvx[card].inbuf,dvx[card].inbuf->wordcnt,dvx[card].intcnt); - if (dvx[card].pdvx2502->csr & 0x2) - printf("fifo status = not empty,"); - else - printf("fifo status = empty,"); - printf(" current input channel = %x\n", - (dvx[card].pdvx2502->csr & 0x3fc0)>>6); - - ix = 0; - printing= 1; - while ((ix < dvx[card].dmaSize) && (ix < lastchan) && printing) - { - printing = 0; - for (i=0; i<8; i++) - { - mask = 1; - port = 0; - while(port < 32) - { - if (mask & dvx[card].pgmMask[i]) - { - if (ix >= firstchan) - { - tmp = dvx[card].inbuf->data[ix]; - tmp &= 0x0000ffff; - - volts = tmp * 10./32767.; - printf("signal %2d, board %d, port %2d, data 0x%4.4X, voltage %f\n", ix, i, port, tmp, volts); - } - - ix++; - printing = 1; - } - mask <<= 1; - port++; - } - } - } - - printf("end of list\n"); - - return 0; -} - -int dvx_getioscanpvt(int card, IOSCANPVT *scanpvt) -{ - if ((card >= ai_num_cards[DVX2502]) || (card < 0))return(0); - if (dvx[card].pdvx2502 == 0) return(0); - *scanpvt = *(dvx[card].pioscanpvt); - return(0); -} - -/* - * - * dvx_io_report - * - * -*/ -long dvx_io_report(int level) -{ - short int i; - - for (i = 0; i < ai_num_cards[DVX2502]; i++){ - if (!dvx[i].pdvx2502) - continue; - - /* If detected card is a 2502 print out its number. */ - printf("AI: DVX2505:\tcard %d\n",i); - - if(level > 0 ){ - int firstchan; - int lastchan; - - printf("Enter number of the first channel you wish to read:\n"); - scanf("%d",&firstchan); - printf("First channel is %d\n",firstchan); - printf("Enter number of the last channel you wish to read:\n"); - scanf("%d",&lastchan); - printf("Last channel is %d\n",lastchan); - dvx_dump(i,firstchan,lastchan); - } - } - - return OK; -} - - - -/* - * dvx_fempty - * - * empty fifo - * - */ -LOCAL int dvx_fempty(int card) -{ - int i, junk; - - if ((card>= ai_num_cards[DVX2502]) || (card < 0)) - return -1; - else if (dvx[card].pdvx2502 == 0) - return -2; - for (i = 0; dvx[card].pdvx2502->csr & 0x2; i++) - junk = dvx[card].pdvx2502->fifo; - printf("%d words read from fifo\n",i); - return 0; -} - - -LOCAL int dvx_dma_reset(struct dvx_2502 *dev) -{ - dev->dma_point = DMA_CSR; - dev->dma_data = CMR_RESET; /* reset the thing */ - return(0); -} - -/* - * dvx_dma_init - * - * am9516 DMA controller initialization - * - * local to A24 bus addr conversions below are necessary on processors - * that dont place the local base for A24 on an even 16 MB boundary - */ -LOCAL int dvx_dma_init(struct dvx_rec *ptr) -{ - int i; - int status; - short *cptr, *cptra, *cptr0; - short *BusPtr; - struct dvx_2502 *dev; - struct dvx_inbuf *bpnt; - - dev = ptr->pdvx2502; /* point to hardware */ - - dvx_dma_reset(dev); /* reset the DMA chip */ - - /* build chain table, needs to come from A24 mappable memory */ -#if 0 - if ((cptr = cptr0 = (short *)malloc(DVX_CTBL)) == NULL) -#else - if ((cptr = cptr0 = (short *)devLibA24Malloc(DVX_CTBL)) == NULL) -#endif - return -1; - dev->dma_point = DMA_MMR; /* enable chip */ - dev->dma_data = MMR_ENABLE; - - /* - * The 2502 uses A24 priv data VME addr mods - * for its DMAchain operations - */ - status = sysLocalToBusAdrs( - VME_AM_STD_SUP_DATA, - cptr, - &BusPtr); - if(status < 0){ - logMsg( "%s:Local chain addr 0x%X does not map to A24 bus addr\n", - __FILE__, - cptr); - return -1; - } - dev->dma_point = DMA_CARH; /* load init chain address */ - dev->dma_data = (int) BusPtr>>8 & 0xff00; - dev->dma_point = DMA_CARL; - dev->dma_data = (int) BusPtr & 0xffff; - - for ( i = 0, bpnt = ptr->inbuf->link; - i < DVX_NBUF; - i++, cptr = cptra, bpnt = bpnt->link) - { /* create chain for each input buffer */ - if ((i + 1) == DVX_NBUF) - cptra = cptr0; /* close list */ - else - /* needs to come from A24 mapped memory */ -#if 0 - if ((cptra = (short *)malloc(DVX_CTBL)) == NULL) -#else - if ((cptra = (short *)devLibA24Malloc(DVX_CTBL)) == NULL) -#endif - return -1; /* allocate next chain */ - - /* Set the reload word */ - *cptr++ = R_CAA | R_CAB | R_COC | R_CMR | R_CAR; /* load mask */ - - /* - * - * source options: - * 1) data (not chain) operation - * 2) hold (dont auto incr or decr) the src address - * - * The src addr here is ignored by the dvx2502 hardware - * and is therefore set to zero. The source is always - * the dvx 2502 fifo. - */ - *cptr++ = 0xd0; - *cptr++ = 0; /* address reg A (src) */ - - /* - * The 2502 uses A24 non-priv data VME addr mods - * for its DMA data transfers - */ - status = sysLocalToBusAdrs( - VME_AM_STD_USR_DATA, - bpnt->data, - &BusPtr); - if(status < 0){ - logMsg( "%s: Local dest addr 0x%X does not map to A24 addr\n", - __FILE__, - bpnt->data); - return -1; - } - *cptr++ = (((int)BusPtr>>8) & 0xff00) | 0xc0; - *cptr++ = (int) BusPtr & 0xffff; /* address reg B (dest) */ - - *cptr++ = ptr->dmaSize; /* operation count */ - *cptr++ = 0x4; - *cptr++ = 0x0252; /* dma mode control */ - - /* - * The 2502 uses A24 priv data VME addr mods - * for its DMA chain operations - */ - status = sysLocalToBusAdrs( - VME_AM_STD_SUP_DATA, - cptra, - &BusPtr); - if(status < 0){ - logMsg( "%s:Local addr 0x%X does not map to A24 addr\n", - __FILE__, - cptra); - return -1; - } - *cptr++ = (int)BusPtr>>8 & 0xff00; - *cptr = (int)BusPtr& 0xffff; /* next chain address */ - } - /* enable DMA opeations */ - dev->dma_point = DMA_CSR; - dev->dma_data = CMR_SC | M_CIE | M_CH2; /* enable int channel #2 */ - dev->dma_data = CMR_START | M_CH2; /* start channel #2 */ - return 0; -} - - -/* - * dvx_dma_stat - * - * reads status of dma channel - * - */ -int dvx_dma_stat(int card, int chan) -{ - struct dvx_2502 *ptr; - short unsigned temp; - - if ((card < 0) || (card > ai_num_cards[DVX2502])) - return -1; - else if (dvx[card].pdvx2502 == 0) - return -2; - else - { - ptr = dvx[card].pdvx2502; - temp = (chan & 0x1)<<1; - ptr->dma_point = DMA_CSR | temp; - printf("dma status = %X\n",ptr->dma_data); - ptr->dma_point = DMA_MMR; - printf("master mode register = %X\n",ptr->dma_data); - ptr->dma_point = DMA_CARH | temp; - printf("chain address = %4.4X",ptr->dma_data); - ptr->dma_point = DMA_CARL | temp; - printf("%4.4X\n",ptr->dma_data); - ptr->dma_point = DMA_CARAH | temp; - printf("current address register A = %4.4X",ptr->dma_data); - ptr->dma_point = DMA_CARAL | temp; - printf("%4.4X\n",ptr->dma_data); - ptr->dma_point = DMA_CARBH | temp; - printf("current address register B = %4.4X",ptr->dma_data); - ptr->dma_point = DMA_CARBL | temp; - printf("%4.4X\n",ptr->dma_data); - ptr->dma_point = DMA_BARAH | temp; - printf("base address register A = %4.4X",ptr->dma_data); - ptr->dma_point = DMA_BARAL | temp; - printf("%4.4X\n",ptr->dma_data); - ptr->dma_point = DMA_BARBH | temp; - printf("base address register B = %4.4X",ptr->dma_data); - ptr->dma_point = DMA_BARBL | temp; - printf("%4.4X\n",ptr->dma_data); - ptr->dma_point = DMA_COC | temp; - printf("current operation count = %4.4X\n",ptr->dma_data); - ptr->dma_point = DMA_BOC | temp; - printf("base operation count = %4.4X\n",ptr->dma_data); - } - return 0; -} - - - -/* - * - * dvx_reset - * joh 072591 - * - */ -#if 0 /* This is hideous... should reset only those we started! */ -LOCAL void -dvx_reset(void) -{ - struct dvx_2502 *pDvxA16; - unsigned short card_id; - int i; - int status; - int card_found = FALSE; - - status = sysBusToLocalAdrs( - VME_AM_SUP_SHORT_IO, - ai_addrs[DVX2502], - &pDvxA16); - if (status != OK){ - logMsg( "%s: A16 base addr problems DVX 2502\n", - __FILE__); - return; - } - - /* - * search for cards - */ - for (i = 0; i < ai_num_cards[DVX2502]; i++, pDvxA16++){ - status = vxMemProbe ( - &pDvxA16->dev_id, - READ, - sizeof(card_id), - &card_id); - if (status != OK) - continue; - /* - * see if detected card is a 2502 - * and reset if so - */ - if (card_id == DVX_ID){ - /* reset the DMA controller */ - dvx_dma_reset(pDvxA16); - - pDvxA16->csr = CSR_RESET; - card_found = TRUE; - } - } - - /* - * wait long enough for the current DMA to end - * - * 1 sec - */ - if(card_found){ - printf("Waiting for DVX 2502 DMA to complete..."); - taskDelay(sysClkRateGet()); - printf("done\n"); - } -} -#else -LOCAL void -dvx_reset(void) -{ - int i; - int CardFound = 0; - - /* - * search for cards - */ - for (i = 0; i < ai_num_cards[DVX2502]; i++) - { - if (dvx[i].pdvx2502 != NULL) - { - dvx_dma_reset(dvx[i].pdvx2502); - dvx[i].pdvx2502->csr = CSR_RESET; - CardFound = 1; - } - } - /* - * wait long enough for the current DMA to end - * - * 1 sec - */ - if(CardFound) - { - printf("Waiting for DVX 2502 DMA to complete..."); - taskDelay(sysClkRateGet()); - printf("done\n"); - } -} -#endif diff --git a/src/drv/old/drvExampleVxi.c b/src/drv/old/drvExampleVxi.c deleted file mode 100644 index fd79b6c52..000000000 --- a/src/drv/old/drvExampleVxi.c +++ /dev/null @@ -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 -#include -#include -#include - -#include -#include -#include -#include -#include - -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. - * - ******************************************************************************/ diff --git a/src/drv/old/drvFp.c b/src/drv/old/drvFp.c deleted file mode 100644 index 9885943a6..000000000 --- a/src/drv/old/drvFp.c +++ /dev/null @@ -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 /* in h/68k if this is compiling for a 68xxx */ - -#include "module_types.h" -#include -#include -#include -#include - -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); -} diff --git a/src/drv/old/drvFpm.c b/src/drv/old/drvFpm.c deleted file mode 100644 index 3c9daca9e..000000000 --- a/src/drv/old/drvFpm.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include /* in h/68k if this is compiling for a 68xxx */ -#include "module_types.h" -#include -#include - -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); -} diff --git a/src/drv/old/drvGpib.c b/src/drv/old/drvGpib.c deleted file mode 100644 index e211b26ff..000000000 --- a/src/drv/old/drvGpib.c +++ /dev/null @@ -1,2902 +0,0 @@ -/****************************************************************************** - * - * TODO: - * - Autodetect the need to use a bounce buffer (saves time on boards that have - * "malloc"-able A24 space. - * - * - Launch campaign against the use of National Instruments hardware. - * - ****************************************************************************** - * - * Author: John Winans - * Date: 09-10-91 - * GPIB driver for the NI-1014 and NI-1014D VME cards. - * - * 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 :-( - * Much of the code in physIo() was stolen from - * a gpib driver that came from Los Alamos. It - * referenced little more than National - * Instruments and Bob Daly (from ANL) in its - * credits. - * .02 12-03-91 jrw changed the setup of the ibLink and niLink structs - * .03 01-21-92 jrw moved task parameters into task_params.h - * .04 01-31-92 jrw added ibSrqLock code - * .05 02-26-92 jrw changed pnode references in the link task's - * busy-list checking, was an endless loop - * .06 04-10-92 jrw moved the device configs into module_types.h - * .07 08-02-92 mrk Added call to taskwdInsert - * - ****************************************************************************** - * - * Notes: - * If 1014D cards are used, make sure that the W7 switch is set to LMR. - * The internals of the 1014D are such that the DMAC can NEVER be hard-reset - * unless the SYSRESET* vme line is asserted. The LMR mode allows the - * initGpib() function to reset the DMAC properly. - * - * - * $Log$ - * Revision 1.8 1998/01/20 21:51:53 mrk - * add includes for error messages - * - * Revision 1.7 1997/04/30 19:02:08 mrk - * Fixed many compiler warning messages - * - * Revision 1.6 1996/05/03 19:05:36 winans - * Added the EOS logic from Mark Rivers. (It is only supported for HiDEOS - * GPIB interfaces.) - * - * Revision 1.5 1996/03/06 14:17:34 mrk - * Made STATIC static - * - * Revision 1.4 1995/07/31 19:44:18 winans - * Changed the parameter table and associated support routines to support - * buffer length specifications of size long instead of short. - * - * Revision 1.3 1995/04/25 15:32:23 winans - * Changed name of HiDEOS link configuration command/function. - * - * Revision 1.2 1995/04/12 19:31:41 winans - * Added support for the HiDEOS system as a GPIB bus transport agent. - * - * Revision 1.28 1995/02/14 22:33:01 winans - * Cleaned up some Hideos hacking and commented out the LANL debug code because - * APS has had some add behaviour from GPIB lately and it is one of few things - * that has changed WRT to it. - * - * Revision 1.27 1994/12/14 22:29:14 winans - * Removed DMAC command chaining structure(s) from the ibLink - * structure so they can be malloc'd seperately. This keeps - * the usage of A24 space restricted to ONLY those structures - * that have to be there. - * - * Revision 1.26 1994/12/12 16:03:00 winans - * Rewrote the init code so that it always returns a zero (don't kill the - * startup.cmd file.) It is possible that this could cause some confusion - * to the database, should it decide to then use a link that did not init - * properly. - * - * Revision 1.25 1994/10/28 19:55:30 winans - * Added VME bus violation prevention code/bug fix from LANL. - * - * Revision 1.24 1994/10/04 18:42:46 winans - * Added an extensive debugging facility. - * - */ - -#define INCLUDE_HIDEOS_INTERFACE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* idiots at WRS have undocumented stuff in here */ - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "devLib.h" -#include "ellLib.h" -#include "task_params.h" -#include "module_types.h" -#include "drvSup.h" -#include "link.h" -#include "fast_lock.h" -#include "taskwd.h" - -#ifdef INCLUDE_HIDEOS_INTERFACE -#include "drvHiDEOSGpib.h" -#endif -#include "drvGpibInterface.h" -#include "drvBitBusInterface.h" -#include "drvGpib.h" - -#define STATIC static - -long reportGpib(void); -/*STATIC*/ long initGpib(void); -STATIC int niIrq(); -STATIC int niIrqError(int link); -STATIC int niTmoHandler(); -STATIC int srqIntEnable(); -STATIC int srqIntDisable(); - -STATIC int qGpibReq(); -STATIC int registerSrqCallback(); -STATIC int writeIb(); -STATIC int readIb(); -STATIC int writeIbCmd(); -STATIC int ioctlIb(); - int srqPollInhibit(); - int readIbEos(); - -STATIC int ibLinkInit(); -STATIC int ibLinkStart(); -STATIC int ibLinkTask(); -struct bbIbLink *findBBLink(); - -int ibDebug = 0; /* Turns on debug messages from this driver */ -int bbibDebug = 0; /* Turns on ONLY bitbus related messages */ -int ibSrqDebug = 0; /* Turns on ONLY srq related debug messages */ -int niIrqOneShot = 0; /* Used for a one shot peek at the DMAC */ -int ibSrqLock = 0; /* set to 1 to stop ALL srq checking & polling */ - -#define STD_ADDRESS_MODE D_SUP|D_S24 /* mode to use when DMAC accesses RAM */ - -/* - * The bounce buffer is where the DMA IO operation(s) take place. If it - * is not large enough, it will be reallocated at that time. However, - * It should be made large enough such this need not happen. - */ -#define DEFAULT_BOUNCE_BUFFER_SIZE 10*1024 - -STATIC int defaultTimeout; /* in 60ths, for GPIB timeouts */ - -static char init_called = 0; /* To insure that init is done first */ -STATIC char *short_base; /* Base of short address space */ - -STATIC int timeoutSquelch = 0; /* Used to quiet timeout msgs during polling */ - -/* DMA timing bus error problem debugging in niPhysIo */ -int ibDmaDebug = 0; /* Turns on DMA debug messages from this driver */ -int ibDmaTimingError = 0; /* count "bad memProbes"/call of niPhysIo */ -int ibDmaTimingErrorTotal = 0; /* count total "bad memProbes" in niPhysIo */ -int ibDmaMaxError = 0; /* max # bad calls per call of niPhysIo */ -STATIC char testWrite; /* test char to write to 1014 card */ - - -/****************************************************************************** - * - * GPIB driver block. - * - ******************************************************************************/ -struct drvGpibSet drvGpib={ - 10, - reportGpib, - initGpib, - qGpibReq, - registerSrqCallback, - writeIb, - readIb, - readIbEos, - writeIbCmd, - ioctlIb, - srqPollInhibit -}; - -/****************************************************************************** - * - * Reference to the bitbus driver block. - * - ******************************************************************************/ -extern struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; - DRVSUPFUN qReq; -} drvBitBus; - -/****************************************************************************** - * - * This structure is used to build array-chained DMA operations. See the - * physIo() function and the National Instruments docs for more info. - * - ******************************************************************************/ -struct cc_ary -{ - void *cc_ccb; - short cc_ONE; - void *cc_n_1addr; - short cc_TWO; -}; - -typedef struct DmaStuffStruct -{ - struct cc_ary cc_array; - char cc_byte; -}DmaStuffStruct; -/****************************************************************************** - * - * This structure is used to hold the hardware-specific information for a - * single GPIB link. There is one for each link constructed in initGpib(). - * - ******************************************************************************/ -struct niLink { - struct ibLink ibLink; - - char tmoFlag; /* timeout has occurred */ - SEM_ID ioSem; /* DMA I/O operation complete or WD timeout */ - WDOG_ID watchDogId; /* watchdog for timeouts */ - struct ibregs *ibregs;/* pointer to board registers */ - - DmaStuffStruct *DmaStuff; - - char r_isr1; - char r_isr2; - int first_read; - - unsigned long cmdSpins; /* total taskDelays while in niGpibCmd() */ - unsigned long maxSpins; /* most taskDelays in one call to niGpibCmd() */ - - char *A24BounceBuffer; /* Where to DMA to */ - unsigned long A24BounceSize; -}; - -STATIC struct niLink *pNiLink[NIGPIB_NUM_LINKS]; /* NULL if link not present */ -STATIC int pollInhibit[NIGPIB_NUM_LINKS][IBAPERLINK]; - /* 0=pollable, 1=user inhibited, 2=no device found */ - -/****************************************************************************** - * - * This structure is used to hold the hardware-specific information for a - * single BitBus GPIB link. They are dynamically allocated (and an ibLinkTask - * started for it) when an IOCTL command requests it. - * - * The IOCTL requests to initiate a BBGPIB_IO link comes from the device support - * init code. When it finds a BBGPIB_IO link it issues an IOCTL for the link & - * bug-node specified in the record. The driver will then initialize the - * required data structures and start a link task for it. It is OK to request - * the initialization of the same link more than 1 time, the driver will ignore - * all but the first request. - * - ******************************************************************************/ -struct bbIbLink { - struct ibLink ibLink; /* associated ibLink structure */ - - SEM_ID syncSem; /* used for syncronous I/O calls */ - struct bbIbLink *next; /* Next BitBus link structure in list */ -}; - -STATIC struct bbIbLink *rootBBLink = NULL; /* Head of bitbus structures */ - -#ifdef INCLUDE_HIDEOS_INTERFACE -/****************************************************************************** - * - ******************************************************************************/ -typedef struct HideosIbLinkStruct -{ - struct ibLink ibLink; /* Associated ibLink */ - struct HideosIbLinkStruct *pNext; /* Next in struct list */ - int BoardId; /* Hideos CPU board number */ - char TaskName[100]; /* Hideos GPIB task name */ - void *remote_td; - -}HideosIbLinkStruct; - -STATIC SEM_ID RootHideosIbLinklock; -STATIC HideosIbLinkStruct *RootHideosIbLink = NULL; - -STATIC GPIB_HIDEOS_INIT_FUNC LHideosInit = NULL; -STATIC GPIB_HIDEOS_WRITE_FUNC LHideosWrite = NULL; -STATIC GPIB_HIDEOS_READ_FUNC LHideosRead = NULL; -STATIC GPIB_HIDEOS_WRITEREAD_FUNC LHideosWriteRead = NULL; -STATIC GPIB_HIDEOS_WRITECMD_FUNC LHideosWriteCmd = NULL; - -#endif - -/****************************************************************************** - * - * This function prints a message indicating the status of each possible GPIB - * card found in the system. - * - ******************************************************************************/ -long -reportGpib(void) -{ - int i; - - if (init_called) - { - for (i=0; i< NIGPIB_NUM_LINKS; i++) - { - if (pNiLink[i]) - { - printf("Link %d (address %p) present and initialized.\n", i, pNiLink[i]->ibregs); - printf(" total niGpibCmd() taskDelay() calls = %lu\n", pNiLink[i]->cmdSpins); - printf(" worst case delay in niGpibCmd() = %lu\n", pNiLink[i]->maxSpins); - } - else - { - printf("Link %d not installed.\n", i); - } - } - printf("DMA timing: error = %d, total = %d, max = %d\n", - ibDmaTimingError, ibDmaTimingErrorTotal, ibDmaMaxError); - - } - else - { - printf("Gpib driver has not yet been initialized.\n"); - } - return(OK); -} - -STATIC void rebootFunc(void) -{ - int i; - char probeValue; - char msg[100]; - - for (i=0;iibLink, 0, msg, 1); - probeValue = 0; - vxMemProbe(&(pNiLink[i]->ibregs->ch1.ccr), WRITE, 1, (char *)&probeValue); - vxMemProbe(&(pNiLink[i]->ibregs->ch0.ccr), WRITE, 1, (char *)&probeValue); - taskDelay(1); /* Let it settle */ - - vxMemProbe(&(pNiLink[i]->ibregs->cfg2), WRITE, 1, (char *)&probeValue); - probeValue = D_LMR; - vxMemProbe(&(pNiLink[i]->ibregs->cfg2), WRITE, 1, (char *)&probeValue); - } - } - taskDelay(2); - return; -} -/****************************************************************************** - * - * Called by the iocInit processing. - * initGpib, probes the gpib card addresses and if one is present, it - * is initialized for use. It should only be called one time. - * - * The loops in this function are logically 1 large one. They were seperated - * so that the 1014D cards could be initialized properly. [Both ports must - * have some of their registers set at the same time and then not later - * altered... for example the LMR reset bit.] - * - ******************************************************************************/ -/* BUG -- this should be static */ -/*STATIC*/ long -initGpib(void) -{ - int i; - int probeValue; - struct ibregs *pibregs; - char s; - - if (init_called) - { - if (ibDebug) - logMsg("initGpib() driver already initialized!\n"); - return(OK); - } - -#ifdef INCLUDE_HIDEOS_INTERFACE - RootHideosIbLinklock = semBCreate(SEM_Q_PRIORITY, SEM_FULL); -#endif - - defaultTimeout = sysClkRateGet(); - - /* figure out where the short address space is */ - sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO , 0, &short_base); - - if (ibDebug) - { - logMsg("Gpib NI1014 driver initializing\n"); - logMsg("short_base %p\n", short_base); - logMsg("NIGPIB_SHORT_OFF 0x%8.8X\n", NIGPIB_SHORT_OFF); - logMsg("NIGPIB_NUM_LINKS 0x%8.8X\n", NIGPIB_NUM_LINKS); - } - - /* When probing, send out a reset signal to reset the DMAC and the TLC */ - probeValue = D_LMR | D_SFL; - - rebootHookAdd(rebootFunc); - - pibregs = (struct ibregs *)((unsigned int)short_base + NIGPIB_SHORT_OFF); - /* Gotta do all the probing first because the 1014D's LMRs are shared :-( */ - for (i=0; icfg2), WRITE, 1, (char *)&probeValue) < OK) - { /* no GPIB board present here */ - pNiLink[i] = (struct niLink *) NULL; - - if (ibDebug) - logMsg("Probing of address %p failed\n", pibregs); - - } - else - { /* GPIB board found... reserve space for structures & reset the thing */ - if (ibDebug) - logMsg("GPIB card found at address %p\n", pibregs); - - if ((pNiLink[i] = (struct niLink *)malloc(sizeof(struct niLink))) == NULL) - { /* This better never happen! */ - logMsg("initGpib(): Can't malloc memory for NI-link data structures!\n"); - return(ERROR); - } - - /* Allocate and init the sems and linked lists */ - pNiLink[i]->ibLink.linkType = GPIB_IO; /* spec'd in link.h */ - pNiLink[i]->ibLink.linkId = i; /* link number */ - pNiLink[i]->ibLink.bug = -1; /* this is not a bug link */ - - - /* Clear out the bouncer */ - pNiLink[i]->A24BounceBuffer = NULL; - pNiLink[i]->A24BounceSize = 0; - - taskDelay(1); /* Wait at least 10 msec before continuing */ - - ibLinkInit(&(pNiLink[i]->ibLink)); /* allocate the sems etc... */ - - pibregs->cfg2 = D_SFL; /* can't set all bits at same time */ - pibregs->cfg2 = D_SFL | D_SC; /* put board in operating mode */ - - pNiLink[i]->ibregs = pibregs; - pNiLink[i]->ioSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - pNiLink[i]->watchDogId = wdCreate(); - pNiLink[i]->tmoFlag = 0; - pNiLink[i]->cmdSpins = 0; - pNiLink[i]->maxSpins = 0; - - if ((pNiLink[i]->DmaStuff = (DmaStuffStruct *)devLibA24Malloc(sizeof(DmaStuffStruct))) == NULL) - { /* This better never happen! */ - logMsg("initGpib(): Can't malloc A24 memory for DMAC control structures!\n"); - return(ERROR); - } - pNiLink[i]->DmaStuff->cc_array.cc_ccb = 0; /* DMAC chaining structure */ - pNiLink[i]->DmaStuff->cc_array.cc_ONE = 1; - pNiLink[i]->DmaStuff->cc_array.cc_n_1addr = 0; - pNiLink[i]->DmaStuff->cc_array.cc_TWO = 2; - - pNiLink[i]->first_read = 1; /* used in physIo() */ - } - pibregs++; /* ready for next board window */ - } - - /* Bring up the cards (has to be done last because the 1014D has to have */ - /* both ports reset before either one is initialized. */ - - for (i=0; iibregs->cptr; - pNiLink[i]->r_isr1 = pNiLink[i]->ibregs->isr1; - pNiLink[i]->r_isr2 = pNiLink[i]->ibregs->isr2; - - /* disable all interrupts from the 7210 */ - pNiLink[i]->ibregs->imr1 = 0; /* DMA and ERROR IRQ mask reg */ - pNiLink[i]->ibregs->imr2 = 0; /* SRQ IRQ mask reg */ - pNiLink[i]->ibregs->spmr = 0; /* serial poll mode register */ - - pNiLink[i]->ibregs->adr = 0; /* device address = 0 */ - pNiLink[i]->ibregs->adr = HR_ARS|HR_DT|HR_DL; /* no secondary addressing */ - pNiLink[i]->ibregs->admr = HR_TRM1|HR_TRM0|HR_ADM0; - pNiLink[i]->ibregs->eosr = 0; /* end of string value */ - pNiLink[i]->ibregs->auxmr = ICR|8; /* internal counter = 8 */ - pNiLink[i]->ibregs->auxmr = PPR|HR_PPU; /* paralell poll unconfigure */ - pNiLink[i]->ibregs->auxmr = AUXRA|0; - pNiLink[i]->ibregs->auxmr = AUXRB|0; - pNiLink[i]->ibregs->auxmr = AUXRE|0; - - /* DMAC setup */ - - pNiLink[i]->ibregs->cfg1 = (NIGPIB_IRQ_LEVEL << 5)|D_BRG3|D_DBM; - pNiLink[i]->ibregs->ch1.niv = NIGPIB_IVEC_BASE + i*2; /* normal IRQ vector */ - pNiLink[i]->ibregs->ch1.eiv = NIGPIB_IVEC_BASE+1+i*2; /* error IRQ vector */ - pNiLink[i]->ibregs->ch0.niv = NIGPIB_IVEC_BASE + i*2; /* normal IRQ vector */ - pNiLink[i]->ibregs->ch0.eiv = NIGPIB_IVEC_BASE+1+i*2; /* error IRQ vector */ - pNiLink[i]->ibregs->ch1.ccr = D_EINT; /* stop operation, allow ints */ - pNiLink[i]->ibregs->ch0.ccr = 0; /* stop all channel operation */ - pNiLink[i]->ibregs->ch0.cpr = 3; /* highest priority */ - pNiLink[i]->ibregs->ch1.cpr = 3; /* highest priority */ - pNiLink[i]->ibregs->ch1.dcr = D_CS|D_IACK|D_IPCL; - pNiLink[i]->ibregs->ch0.dcr = D_CS|D_IACK|D_IPCL; - pNiLink[i]->ibregs->ch1.scr = 0; /* no counting during DMA */ - pNiLink[i]->ibregs->ch0.scr = D_MCU; /* count up during DMA cycles */ - pNiLink[i]->ibregs->ch0.mfc = STD_ADDRESS_MODE; - pNiLink[i]->ibregs->ch1.mfc = STD_ADDRESS_MODE; - pNiLink[i]->ibregs->ch1.bfc = STD_ADDRESS_MODE; - - - /* attach the interrupt handler routines */ - intConnect(INUM_TO_IVEC(NIGPIB_IVEC_BASE+i*2), niIrq, i); - intConnect(INUM_TO_IVEC(NIGPIB_IVEC_BASE+(i*2)+1), niIrqError, i); - } - } - - /* should have interrups running before I do any I/O */ - sysIntEnable(NIGPIB_IRQ_LEVEL); - - /* Fire up the TLCs and nudge all the addresses on the GPIB bus */ - /* by doing a serial poll on all of them. If someone did a */ - /* srqPollInhibit() on a specific link, then skip it and continue. */ - - for (i=0; iibregs->auxmr = AUX_PON; /* release pon state */ - - if (ibLinkStart(&(pNiLink[i]->ibLink)) == ERROR) /* start up the link */ - pNiLink[i] = NULL; /* kill the link to prevent flood of problems */ - } - } - - init_called = 1; /* let reportGpib() know init occurred */ - return(OK); -} - -STATIC int -niDumpDmac(int link) -{ - logMsg("ch0: ccr=%2.2X csr=%2.2X cer=%2.2X mtc=%4.4X mar=%8.8X btc=%4.4X bar=%8.8X\n", - pNiLink[link]->ibregs->ch0.ccr & 0xff, - pNiLink[link]->ibregs->ch0.csr & 0xff, - pNiLink[link]->ibregs->ch0.cer & 0xff, - pNiLink[link]->ibregs->ch0.mtc & 0xffff, - niRdLong(&(pNiLink[link]->ibregs->ch0.mar)), - pNiLink[link]->ibregs->ch0.btc & 0xffff, - niRdLong(&(pNiLink[link]->ibregs->ch0.bar))); - - logMsg("ch1: ccr=%2.2X csr=%2.2X cer=%2.2X mtc=%4.4X mar=%8.8X btc=%4.4X bar=%8.8X\n", - pNiLink[link]->ibregs->ch1.ccr & 0xff, - pNiLink[link]->ibregs->ch1.csr & 0xff, - pNiLink[link]->ibregs->ch1.cer & 0xff, - pNiLink[link]->ibregs->ch1.mtc & 0xffff, - niRdLong(&(pNiLink[link]->ibregs->ch1.mar)), - pNiLink[link]->ibregs->ch1.btc & 0xffff, - niRdLong(&(pNiLink[link]->ibregs->ch1.bar))); - - return(OK); -} -/****************************************************************************** - * - * Interrupt handler for all normal DMAC interrupts. - * - * This is invoked at the termination of a DMA operation or if the TLC - * requests an un-masked interrupt (typically SRQ from the GPIB bus.) - * - * Keep in mind that channel0's interrupts are related to the SRQs and that - * the ints from channel1 are related to the DMA operations completing. - * - * Note: - * The isr2 status should always be read first since reading isr1 can reset - * some of the isr2 status. - * - ******************************************************************************/ -STATIC int -niIrq(link) -int link; -{ - if (ibDebug) - logMsg("GPIB interrupt from link %d\n", link); - - if (NIGPIB_IRQ_LEVEL == 4) /* gotta ack ourselves on HK boards */ - sysBusIntAck(NIGPIB_IRQ_LEVEL); - - if (niIrqOneShot) - { - niDumpDmac(link); - niIrqOneShot--; - } - - /* Check the DMA error status bits first */ - if (pNiLink[link]->ibregs->ch0.csr & D_ERR || pNiLink[link]->ibregs->ch1.csr & D_ERR) - { - logMsg("GPIB error during DMA from link %d\n", link); - - /* read the status regs to clear any int status from the TLC */ - pNiLink[link]->r_isr2 |= pNiLink[link]->ibregs->isr2; - pNiLink[link]->r_isr1 |= pNiLink[link]->ibregs->isr1; - - niDumpDmac(link); - - logMsg("r_isr1=%2.2X r_isr2=%2.2X\n", - pNiLink[link]->r_isr1 & 0xff, - pNiLink[link]->r_isr2 & 0xff); - - pNiLink[link]->ibregs->ch0.csr = ~D_PCLT; /* Keep srq int status */ - pNiLink[link]->ibregs->ch1.csr = D_CLEAR; - pNiLink[link]->ibregs->imr1 = 0; - pNiLink[link]->ibregs->imr2 = 0; - - /* No semaphores are given in here because we don't know why we got */ - /* here. It is best to let I/O time out if any was going on. */ - return(ERROR); - } - - /* channel 0 PCL status is the SRQ line for the link */ - - if ((pNiLink[link]->ibregs->ch0.csr) & D_PCLT) - { - pNiLink[link]->ibregs->ch0.csr = D_PCLT; /* Reset srq status */ - pNiLink[link]->ibLink.srqIntFlag = 1; - - if (ibDebug|| ibSrqDebug) - logMsg("GPIB SRQ interrupt on link %d\n", link); - - semGive(pNiLink[link]->ibLink.linkEventSem); - - return(0); - } - -/* BUG -- perhaps set a flag so the WD system knows I proceeded here? */ - - /* if there was a watch-dog timer tie, let the timeout win. */ - if (pNiLink[link]->tmoFlag == FALSE) - { - if (pNiLink[link]->ibregs->ch1.csr & D_PCLT) - { - if (ibDebug) - logMsg("GPIB DMA completion interrupt from link %d\n", link); - /* read the status regs to clear any int status from the TLC */ - /* changed these to = from |= because they never got cleared! */ - pNiLink[link]->r_isr2 = pNiLink[link]->ibregs->isr2; - pNiLink[link]->r_isr1 = pNiLink[link]->ibregs->isr1; - - if (pNiLink[link]->ibregs->ch1.csr & D_COC) - { - /* this should not be set because we ALWAYS ask for 1 too */ - /* many bytes to be transfered. See 1014 docs on ints */ - logMsg("GPIB COC bit set after DMA on channel 1 link %d\n", link); - } - /* DMA complete via sync detect */ - pNiLink[link]->ibregs->imr1 = 0; - pNiLink[link]->ibregs->imr2 = 0; - pNiLink[link]->ibregs->ch1.csr = D_CLEAR; - /* Leave Channel 0's ints alone since it did not generate the interrupt */ - semGive(pNiLink[link]->ioSem); - - return(0); - } - } - else - { - /* The DMAC should get reset by the watch-dog handling code if I get here */ - if (ibDebug) - logMsg("GPIB DMA completion interrupt but wd expired already on link %d\n", link); - } - return(0); -} - -/****************************************************************************** - * - * An interrupt handler that catches the DMAC error interrupts. These should - * never occur. - * - ******************************************************************************/ -STATIC int -niIrqError(int link) -{ - logMsg("GPIB error interrupt generated on link %d\n", link); - - niDumpDmac(link); - - pNiLink[link]->ibregs->ch0.ccr = D_SAB; - pNiLink[link]->ibregs->ch1.ccr = D_SAB; - return(0); -} - -/****************************************************************************** - * - * niGpibCmd() - * - * This function is used to output a command string to the GPIB bus. - * - * The controller is placed in the active state prior to the outputting of - * the first command. - * - * Before calling niGpibCmd() the first time, an niGpibIoctl(IBIFC) call must - * be made to init the bus and enable the interface card. - * - ******************************************************************************/ -#define TOOLONG 100 /* how many times to try to send the same byte */ -#define IDELAY 1000 /* how long to busy wait while sending a byte */ - -STATIC int -niGpibCmd(link, buffer, length) -int link; -char *buffer; -int length; -{ - int iDelay; /* how long to spin before doing a taskWait */ - int tooLong; /* how long should I tolerate waiting */ - int lenCtr; - unsigned spins; /* how many taskDelay() calls made in this function */ - - lenCtr = length; - spins = 0; - - if (ibDebug) - logMsg("niGpibCmd(%d, 0x%8.8X, %d): command string >%s<\n", link, buffer, length, buffer); - - tooLong = TOOLONG; /* limit to wait for ctrlr's command buffer */ - pNiLink[link]->ibregs->auxmr = AUX_TCA; /* take control of the bus */ - - while (lenCtr) - { - pNiLink[link]->r_isr2 &= ~HR_CO; - iDelay = IDELAY; /* wait till the ctlr is ready */ - while (iDelay && (((pNiLink[link]->r_isr2 |= pNiLink[link]->ibregs->isr2) & HR_CO) == 0)) - iDelay--; - - if (iDelay) - { - pNiLink[link]->ibregs->cdor = *buffer++; /* output a byte */ - lenCtr--; - tooLong = TOOLONG; /* reset the limit again */ - } - else - { - if (!(tooLong--)) - { - /* errMsg() */ - logMsg("niGpibCmd(%d, 0x%8.8X, %d): Timeout while writing command >%s<\n", link, buffer, length, buffer); - pNiLink[link]->ibregs->auxmr = AUX_GTS; - if (spins > pNiLink[link]->maxSpins) - pNiLink[link]->maxSpins = spins; - return(ERROR); - } - spins++; - pNiLink[link]->cmdSpins++; - taskDelay(1); /* ctlr is taking too long */ - } - } - tooLong = TOOLONG; - while(tooLong--) - { - pNiLink[link]->r_isr2 &= ~HR_CO; - iDelay = IDELAY; /* wait till the ctlr is ready */ - while (iDelay && (((pNiLink[link]->r_isr2 |= pNiLink[link]->ibregs->isr2) & HR_CO) == 0)) - iDelay--; - - if(iDelay) - { - pNiLink[link]->ibregs->auxmr = AUX_GTS; - if (spins > pNiLink[link]->maxSpins) - pNiLink[link]->maxSpins = spins; - return(length); - } - else - { - spins++; - pNiLink[link]->cmdSpins++; - taskDelay(1); - } - } - /* errMsg() */ - logMsg("niGpibCmd(%d, 0x%8.8X, %d): Timeout after writing command >%s<\n", link, buffer, length, buffer); - pNiLink[link]->ibregs->auxmr = AUX_GTS; - if (spins > pNiLink[link]->maxSpins) - pNiLink[link]->maxSpins = spins; - return(ERROR); -} - -/****************************************************************************** - * - * Read a buffer via Ni-based link. - * - ******************************************************************************/ -STATIC int -niGpibRead(link, buffer, length, time) -int link; -char *buffer; -int length; -int time; -{ - int err; - - if(ibDebug) - logMsg("niGpibRead(%d, 0x%8.8X, %d, %d)\n",link, buffer, length, time); - - if (niCheckLink(link) == ERROR) - { - /* bad link number */ - return(ERROR); - } - - err = niPhysIo(READ, link, buffer, length, time); - pNiLink[link]->r_isr1 &= ~HR_END; - - return(err ? err : length - niGpibResid(link)); -} - - -/****************************************************************************** - * - * Write a buffer out an Ni-based link. - * - ******************************************************************************/ -STATIC int -niGpibWrite(link, buffer, length, time) -int link; -char *buffer; -int length; -int time; -{ - int err; - - if(ibDebug) - logMsg("niGpibWrite(%d, 0x%8.8X, %d, %d)\n",link, buffer, length, time); - - if (niCheckLink(link) == ERROR) - { - /* bad link number */ - return(ERROR); - } - - err = niPhysIo(WRITE, link, buffer, length, time); - - return(err ? err : length - niGpibResid(link)); -} - -/****************************************************************************** - * - * This function is used to figure out the difference in the transfer-length - * requested in a read or write request, and that actually transfered. - * - ******************************************************************************/ -STATIC int -niGpibResid(link) -int link; -{ - register int cnt; - - cnt = pNiLink[link]->ibregs->ch0.mtc; - if (pNiLink[link]->ibregs->ch1.mtc == 2 || cnt) /* add one if carry-cycle */ - cnt++; /* never started */ - - return(cnt); -} - - -/****************************************************************************** - * - * This function is used to validate all non-BitBus -> GPIB link numbers that - * are passed in from user requests. - * - ******************************************************************************/ -STATIC int -niCheckLink(link) -int link; -{ - if (link<0 || link >= NIGPIB_NUM_LINKS) - { - /* link number out of range */ - return(ERROR); - } - if (pNiLink[link] == NULL) - { - /* link number has no card installed */ - return(ERROR); - } - return(OK); -} - -/****************************************************************************** - * - * This function provides access to the GPIB protocol operations on the NI - * interface board. - * - ******************************************************************************/ -STATIC int -niGpibIoctl(link, cmd, v, p) -int link; -int cmd; -int v; -caddr_t p; -{ - int stat = OK; - - if(ibDebug) - logMsg("niGpibIoctl(%d, %d, %d, %8.8X)\n",link, cmd, v, p); - - if (cmd != IBGENLINK && niCheckLink(link) == ERROR) - { - /* bad link number */ - return(ERROR); - } - - switch (cmd) { - case IBTMO: /* set the timeout value for the next transaction */ - /* pNiLink[link]->tmoLimit = v; */ - logMsg("Old NI driver call entered IBTMO ignored\n"); - break; - case IBIFC: /* fire out an Interface Clear pulse */ - pNiLink[link]->ibregs->auxmr = AUX_SIFC; /* assert the line */ - taskDelay(10); /* wait a little while */ - pNiLink[link]->ibregs->auxmr = AUX_CIFC; /* clear the line */ - taskDelay(10); /* wait a little while */ - break; - case IBREN: /* turn on or off the REN line */ - pNiLink[link]->ibregs->auxmr = (v ? AUX_SREN : AUX_CREN); - break; - case IBGTS: /* go to standby (ATN off etc...) */ - pNiLink[link]->ibregs->auxmr = AUX_GTS; - break; - case IBGTA: /* go to active (ATN on etc...) (IBIFC must also be called */ - pNiLink[link]->ibregs->auxmr = AUX_TCA; - break; - case IBNILNK: /* returns the max number of NI links possible */ - stat = NIGPIB_NUM_LINKS; - break; - case IBGENLINK: /* request the creation of a link */ - break; /* this is automatic for NI based links */ - case IBGETLINK: /* return pointer to ibLink structure */ - *(struct ibLink **)p = &(pNiLink[link]->ibLink); - break; - default: - return(ERROR); - } - return(stat); -} - -/****************************************************************************** - * - * This routine does DMA based I/O with the GPIB bus. It sets up the NI board's - * DMA registers, initiates the transfer and waits for it to complete. It uses - * a watchdog timer in case the transfer dies. It returns OK, or ERROR - * depending on if the transfer succeeds or not. - * - ******************************************************************************/ - -STATIC int -niPhysIo(dir, link, buffer, length, time) -int dir; /* direction (READ or WRITE) */ -int link; /* link number to do the I/O with */ -char *buffer; /* data to transfer */ -int length; /* number of bytes to transfer */ -int time; /* time to wait on the DMA operation */ -{ - int status = ERROR; - unsigned short cnt; - struct ibregs *b; - char w_imr2; - int temp_addr; - int tmoTmp; - -#ifdef NI_GPIB_LOOP_LENGTH -#define NI_GPIB_CHUNKSIZE 0x0ffff - while (length > 0) - { - if (length > NI_GPIB_CHUNKSIZE) - { - cnt = NI_GPIB_CHUNKSIZE; - length -= NI_GPIB_CHUNKSIZE; - } - else - { - cnt = length; - length = 0; - } -#else - cnt = length; - - if (cnt > 0x0fffe) - { - errMessage(S_IB_SIZE, "NI-1014 max length (65535) exceeded"); - return(ERROR); - } -#endif - - if (pNiLink[link]->A24BounceBuffer == NULL) - { - if ((pNiLink[link]->A24BounceBuffer = devLibA24Malloc(DEFAULT_BOUNCE_BUFFER_SIZE)) == NULL) - { - errMessage(S_IB_A24 ,"niPhysIo ran out of A24 memory!"); - return(ERROR); - } - pNiLink[link]->A24BounceSize = DEFAULT_BOUNCE_BUFFER_SIZE; - if(ibDebug > 5) - logMsg("Got a bouncer at 0x%8.8X\n", pNiLink[link]->A24BounceBuffer); - } - - if (pNiLink[link]->A24BounceSize < cnt) - { /* Reallocate a larger bounce buffer */ - - devLibA24Free(pNiLink[link]->A24BounceBuffer); /* Loose the old one */ - - if ((pNiLink[link]->A24BounceBuffer = devLibA24Malloc(cnt)) == NULL) - { - errMessage(S_IB_A24 ,"niPhysIo ran out of A24 memory!"); - pNiLink[link]->A24BounceSize = 0; - pNiLink[link]->A24BounceBuffer = NULL; - return(ERROR); - } - pNiLink[link]->A24BounceSize = cnt; - if(ibDebug > 5) - logMsg("Got a new bouncer at 0x%8.8X\n", pNiLink[link]->A24BounceBuffer); - } - - b = pNiLink[link]->ibregs; - - b->auxmr = AUX_GTS; /* go to standby mode */ - b->ch1.ccr = D_SAB; /* halt channel activity */ - b->ch0.ccr = D_SAB; /* halt channel activity */ - - b->ch1.csr = D_CLEAR; - b->ch0.csr = D_CLEAR & ~D_PCLT; - - b->imr2 = 0; /* set these bits last */ - status = OK; - - if (dir == READ) - { - if (pNiLink[link]->first_read == 0) - b->auxmr = AUX_FH; /* finish handshake */ - else - pNiLink[link]->first_read = 0; - - b->auxmr = AUXRA | HR_HLDE; /* hold off on end */ - - if (cnt != 1) - pNiLink[link]->DmaStuff->cc_byte = AUXRA | HR_HLDA; /* (cc) holdoff on all */ - else - pNiLink[link]->DmaStuff->cc_byte = b->auxmr = AUXRA | HR_HLDA; /* last byte, do now */ - b->ch0.ocr = D_DTM | D_XRQ; - /* make sure I only alter the 1014D port-specific fields here! */ - b->cfg1 = D_ECC | D_IN | (NIGPIB_IRQ_LEVEL << 5) | D_BRG3 | D_DBM; - b->ch1.ocr = D_DTM | D_ACH | D_XRQ; - b->ch1.ocr = D_DTM | D_ACH | D_XRQ; - - /* enable interrupts and dma */ - b->imr1 = HR_ENDIE; - w_imr2 = HR_DMAI; - } - else /* (dir == READ) */ - { - /* We will be writing, copy data into the bounce buffer */ - memcpy(pNiLink[link]->A24BounceBuffer, buffer, cnt); - - if (cnt != 1) - pNiLink[link]->DmaStuff->cc_byte = AUX_SEOI; /* send EOI with last byte */ - else - b->auxmr = AUX_SEOI; /* last byte, do it now */ - - b->ch0.ocr = D_MTD | D_XRQ; - /* make sure I only alter the 1014D port-specific fields here! */ - b->cfg1 = D_ECC | D_OUT | (NIGPIB_IRQ_LEVEL << 5) | D_BRG3 | D_DBM; - b->ch1.ocr = D_MTD | D_ACH | D_XRQ; - - /* enable interrupts and dma */ - b->imr1 = 0; - w_imr2 = HR_DMAO; - } /* dir == READ) */ - - /* setup channel 1 (carry cycle) */ - - if(ibDebug > 5) - logMsg("PhysIO: readying to xlate cc pointers at %8.8X and %8.8X\n", &(pNiLink[link]->DmaStuff->cc_byte), &pNiLink[link]->A24BounceBuffer[cnt - 1]); - - if (sysLocalToBusAdrs(VME_AM_STD_SUP_DATA, &(pNiLink[link]->DmaStuff->cc_byte), &(pNiLink[link]->DmaStuff->cc_array.cc_ccb)) == ERROR) - return(ERROR); - - if (sysLocalToBusAdrs(VME_AM_STD_SUP_DATA, &(pNiLink[link]->A24BounceBuffer[cnt - 1]), &(pNiLink[link]->DmaStuff->cc_array.cc_n_1addr)) == ERROR) - return(ERROR); - - if(ibDebug > 5) - logMsg("PhysIO: &cc_byte=%8.8X, &pNiLink[link]->A24BounceBuffer[cnt-1]=%8.8X, ", pNiLink[link]->DmaStuff->cc_array.cc_ccb, pNiLink[link]->DmaStuff->cc_array.cc_n_1addr); - - cnt--; - if (sysLocalToBusAdrs(VME_AM_STD_SUP_DATA, &(pNiLink[link]->DmaStuff->cc_array), &temp_addr) == ERROR) - return(ERROR); - - if(ibDebug > 5) - logMsg("&cc_array=%8.8X, ", temp_addr); - - niWrLong(&b->ch1.bar, temp_addr); - b->ch1.btc = 2; - - /* setup channel 0 (main transfer) */ - b->ch0.mtc = cnt ? cnt : 1; - - if (sysLocalToBusAdrs(VME_AM_STD_SUP_DATA, pNiLink[link]->A24BounceBuffer, &temp_addr) == ERROR) - return(ERROR); - - if(ibDebug > 5) - logMsg("pNiLink[link]->A24BounceBuffer=%8.8X\n", temp_addr); - - niWrLong(&b->ch0.mar, temp_addr); - - /* setup GPIB response timeout handler */ - if (time == 0) - time = defaultTimeout; /* 0 = take the default */ - pNiLink[link]->tmoFlag = FALSE; /* assume no timeout */ - wdStart(pNiLink[link]->watchDogId, time, niTmoHandler, link); - - /* start dma (ch1 first) */ - if (cnt) - b->ch1.ccr = D_EINT | D_SRT; /* enable interrupts */ - else - b->ch1.ccr = D_EINT; - -#ifdef INCLUDE_LANL_DMA_TIMING_CHECKER - /************************************************************************* - * DMAC BUS ERROR CATCH - * The following lines are included because of a possible VME protocol - * violation by the NI1014D gpib board. Occasionally, the board is not - * ready to respond to the "b->ch0.ccr = D_SRT;" line (write to interrupt - * mask register 2) and generates a bus error. Since this problem occurred - * initially with the 68020, faster CPUs may run into this problem more - * often. Thus, while the following set of debugging lines actually provide - * enough of a delay that the problem disappears for the 68020, they are left - * in for possible debugging for the faster CPUs. - **************************************************************************/ - ibDmaTimingError = 0; - while (vxMemProbe(&b->ch0.ccr, WRITE, 1, &testWrite) < 0) - ibDmaTimingError++; - ibDmaTimingErrorTotal += ibDmaTimingError; - if (ibDmaTimingError > ibDmaMaxError) - ibDmaMaxError = ibDmaTimingError; - if (ibDmaDebug) - logMsg("DMA timing: error = %d, total = %d, max = %d\n", - ibDmaTimingError, ibDmaTimingErrorTotal, ibDmaMaxError); - /***************************************************************************/ -#endif - - b->ch0.ccr = D_SRT; - -#ifdef INCLUDE_LANL_DMA_TIMING_CHECKER - /**************************** - * DMAC BUS ERROR CATCH - *****************************/ - ibDmaTimingError = 0; - while (vxMemProbe(&b->imr2, WRITE, 1, &testWrite) < 0) - ibDmaTimingError++; - ibDmaTimingErrorTotal += ibDmaTimingError; - if (ibDmaTimingError > ibDmaMaxError) - ibDmaMaxError = ibDmaTimingError; - if (ibDmaDebug) - logMsg("DMA timing: error = %d, total = %d, max = %d\n", - ibDmaTimingError, ibDmaTimingErrorTotal, ibDmaMaxError); - /***************************************************************************/ -#endif - - b->imr2 = w_imr2; /* this must be done last */ - - /* check for error in DMAC initialization */ - if ((b->ch0.csr & D_ERR) || (b->ch1.csr & D_ERR)) - { - /* errMsg() */ - logMsg("DMAC error initialization on link %d.\n", link); - return (ERROR); - } - if (cnt) - { - if (ibDebug == 1) - logMsg("Link %d waiting for DMA int or WD timeout.\n", link); - semTake(pNiLink[link]->ioSem, WAIT_FOREVER); /* timeout or DMA finish */ - } - else - if (b->ch0.mtc) - { - if (ibDebug == 1) - logMsg("wd cnt =0 wait\n"); - tmoTmp = 0; - while (b->ch0.mtc) - { - taskDelay(1); - if (++tmoTmp == time) - { - pNiLink[link]->tmoFlag = TRUE; - break; - } - } - } - if (pNiLink[link]->tmoFlag == TRUE) - { - status = ERROR; - /* reset */ - pNiLink[link]->r_isr2 |= pNiLink[link]->ibregs->isr2; - pNiLink[link]->r_isr1 |= pNiLink[link]->ibregs->isr1; - pNiLink[link]->ibregs->imr1 = 0; - pNiLink[link]->ibregs->imr2 = 0; - pNiLink[link]->ibregs->ch1.csr = D_CLEAR; - /* errMsg() */ - if (!timeoutSquelch) - logMsg("TIMEOUT GPIB DEVICE on link %d\n", link); - } - else - { - wdCancel(pNiLink[link]->watchDogId); - status = OK; - if (b->ch0.csr & D_ERR) - { - logMsg("DMAC error on link %d, channel 0 = %x\n", link, b->ch0.cer); - status = ERROR; - } - if (b->ch1.csr & D_ERR) - { - logMsg("DMAC error on link %d, channel 1 = %x\n", link, b->ch1.cer); - status = ERROR; - } - } - /* - * DMA transfer complete. Reset as per instructions in GPIB - * 'Programming Considerations' 5-14 - */ - -/* BUG -- Should halt and spin a while before aborting (NI recommendation) */ - b->ch0.ccr = D_SAB; /* halt channel activity */ - b->ch0.csr = D_CLEAR & ~D_PCLT; - b->ch1.ccr = D_SAB; - b->ch1.csr = D_CLEAR; - - b->imr2 = 0; - /* make sure I only alter the 1014D port-specific fields here! */ - b->cfg1 = (NIGPIB_IRQ_LEVEL << 5) | D_BRG3 | D_DBM; - - if (dir == READ) - { /* Copy data from the bounce buffer to the user's buffer */ - memcpy(buffer, pNiLink[link]->A24BounceBuffer, cnt); - } -#ifdef NI_GPIB_LOOP_LENGTH - - buffer += NI_GPIB_CHUNKSIZE; - } -#endif - return (status); -} - -/****************************************************************************** - * - * This function is called by the watch-dog timer if it expires while waiting - * for a GPIB transaction to complete. - * - ******************************************************************************/ -STATIC int -niTmoHandler(link) -int link; -{ - pNiLink[link]->tmoFlag = TRUE; /* indicate that timeout occurred */ - semGive(pNiLink[link]->ioSem); /* wake up the phys I/O routine */ - return(0); -} - -/****************************************************************************** - * - * Mark a given device as non-pollable. - * - ******************************************************************************/ -STATIC int -niSrqPollInhibit(link, gpibAddr) -int link; -int gpibAddr; -{ - if (niCheckLink(link) == ERROR) - { - logMsg("drvGpib: niSrqPollInhibit(%d, %d): invalid link number specified\n", link, gpibAddr); - return(ERROR); - } - pollInhibit[link][gpibAddr] = 1; /* mark it as inhibited */ - return(OK); -} - -/****************************************************************************** - * - * Sometimes we have to make sure that regs on the GPIB board are accessed as - * 16-bit values. This function writes out a 32-bit value in 2 16-bit pieces. - * - ******************************************************************************/ -STATIC int -niWrLong(loc, val) -short *loc; -int val; -{ - register short *ptr = loc; - - *ptr = val >> 16; - *(ptr + 1) = val & 0xffff; -} - int -niRdLong(loc) -unsigned short *loc; -{ - register unsigned short *ptr = loc; - int val; - - val = (unsigned long) (*ptr << 16) + (unsigned long) (*(ptr+1) & 0xffff); - return(val); -} - -/****************************************************************************** - * - * This function is used to enable the generation of VME interupts upon the - * detection of an SRQ status on the GPIB bus. - * - ******************************************************************************/ -STATIC int -niSrqIntEnable(link) -int link; -{ - int lockKey; - - if(ibDebug || ibSrqDebug) - logMsg("niSrqIntEnable(%d): ch0.csr = 0x%2.2X, gsr=0x%2.2X\n", link, pNiLink[link]->ibregs->ch0.csr, pNiLink[link]->ibregs->gsr); - - lockKey = intLock(); /* lock out ints because something likes to glitch */ - - if (!((pNiLink[link]->ibregs->ch0.csr) & D_NSRQ)) - { /* SRQ line is CURRENTLY active, just give the event sem and return */ - pNiLink[link]->ibLink.srqIntFlag = 1; - semGive(pNiLink[link]->ibLink.linkEventSem); - - if(ibDebug || ibSrqDebug) - logMsg("niSrqIntEnable(%d): found SRQ active, setting srqIntFlag\n", link); - - /* Clear the PCLT status if is already set to prevent unneeded int later */ - pNiLink[link]->ibregs->ch0.csr = D_PCLT; - } - else - pNiLink[link]->ibregs->ch0.ccr = D_EINT; /* Allow SRQ ints */ - - intUnlock(lockKey); - return(OK); -} - - -/****************************************************************************** - * - * This function is used to disable the generation of VME interupts associated - * with the detection of an SRQ status on the GPIB bus. - * - ******************************************************************************/ -STATIC int -niSrqIntDisable(link) -int link; -{ - int lockKey; - - if(ibDebug || ibSrqDebug) - logMsg("niSrqIntDisable(%d): ch0.csr = 0x%2.2X, gsr=0x%2.2X\n", link, pNiLink[link]->ibregs->ch0.csr, pNiLink[link]->ibregs->gsr); - - lockKey = intLock(); /* lock out ints because something likes to glitch */ - pNiLink[link]->ibregs->ch0.ccr = 0; /* Don't allow SRQ ints */ - intUnlock(lockKey); - - return(OK); -} - -/****************************************************************************** - * - * The following section of GPIB driver is written such that it can operate - * in a device independant fashon. It does this by simply not making - * references to any architecture-specific data areas. - * - * When the architecture-specific information is needed, processing - * is sent to the architecture-specific routines. - * - ******************************************************************************/ - -/****************************************************************************** - * - * Routine used to initialize the values of the fields in an ibLink structure. - * - ******************************************************************************/ -STATIC int -ibLinkInit(plink) -struct ibLink *plink; -{ - int j; - - if(ibDebug || bbibDebug) - logMsg("ibLinkInit(%8.8X): entered, type %d, link %d, bug %d\n", plink, plink->linkType, plink->linkId, plink->bug); - -#ifdef GPIB_SUPER_DEBUG - plink->History.Sem = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - plink->History.Next = 0; - plink->History.Num = 0; -#endif - - plink->srqIntFlag = 0; /* no srq ints set now */ - plink->linkEventSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - - ellInit(&(plink->hiPriList)); /* init the list as empty */ - plink->hiPriSem = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - - ellInit(&(plink->loPriList)); /* init the list as empty */ - plink->loPriSem = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - - plink->srqRing = rngCreate(SRQRINGSIZE * sizeof(struct srqStatus)); - - for (j=0; jsrqHandler[j] = NULL; /* no handler is registered */ - plink->deviceStatus[j] = IDLE; /* assume device is IDLE */ - } - return(OK); -} - -/****************************************************************************** - * - * Init and start an ibLinkTask - * - ******************************************************************************/ -STATIC int -ibLinkStart(struct ibLink *plink) -{ - int j; - int taskId; - char tName[20]; - - if (ibDebug || bbibDebug) - logMsg("ibLinkStart(%8.8X): entered for linkType %d, link %d\n", plink, plink->linkType, plink->linkId); - - /* fire out an interface clear */ - ioctlIb(plink->linkType, plink->linkId, plink->bug, IBIFC, -1, NULL); - /* turn on the REN line */ - ioctlIb(plink->linkType, plink->linkId, plink->bug, IBREN, 1, NULL); - -/* BUG -- why not just forget this & only poll registered devices? */ -/* BUG -- the pollinhibit array stuff has to be fixed! */ - - - if ((plink->linkType == GPIB_IO) && (ibSrqLock == 0)) - { - /* poll all available adresses to see if will respond */ - speIb(plink); - for (j=1; j<31; j++) /* poll 1 thru 31 (no 0 or 32) */ - { - if (pollInhibit[plink->linkId][j] != 1);/* User block it out ? */ - { - if (pollIb(plink, j, 0, POLLTIME) == ERROR) - pollInhibit[plink->linkId][j] = 2; /* not pollable */ - } - } - spdIb(plink); - } - - if (plink->linkType == GPIB_IO) - { - if (plink->linkId > NIGPIB_NUM_LINKS) - sprintf(tName, "hib-%2.2d", plink->linkId); - else - sprintf(tName, "ib-%2.2d", plink->linkId); - } - else if (plink->linkType == BBGPIB_IO) - sprintf(tName, "bbib-%2.2d.%2.2d", plink->linkId, plink->bug); - else - strcpy(tName, GPIBLINK_NAME); - - /* Start a task to manage the link */ - if ((taskId = taskSpawn(tName, GPIBLINK_PRI, GPIBLINK_OPT, GPIBLINK_STACK, ibLinkTask, plink)) == ERROR) - { - logMsg("ibLinkStart(): failed to start link task for link %d\n", plink->linkId); - return(ERROR); - } - taskwdInsert(taskId,NULL,NULL); - taskDelay(10); /* give it a chance to start running */ - return(OK); -} - -/***************************************************************************** - * - * At the time this function is started as its own task, the linked list - * structures will have been created and initialized. - * - * This function is spawned as a task for each GPIB bus present in the - * system. That is one for each Ni card port, and one for each Bit Bus - * bug that contains a GPIB port on it. - * - * All global data areas referenced by this task are limited to the non-port - * specific items (no niLink[] references allowed.) so that the same task - * can operate all forms of GPIB busses. - * - *****************************************************************************/ -STATIC int -ibLinkTask(plink) -struct ibLink *plink; /* a reference to the link structures covered */ -{ - struct dpvtGpibHead *pnode; - struct srqStatus ringData; - int pollAddress; - int pollActive; - int working; - - - if (ibDebug) - logMsg("ibLinkTask started for link type %d, link %d\n", plink->linkType, plink->linkId); - - /* send out a UNL and UNT to test-drive the link */ - if (writeIbCmd(plink, "?_", 2) == ERROR) - { - logMsg("ibLinkTask(%8.08X): init failed for link type %d, link %d\n", plink->linkType, plink, plink->linkId); - return(ERROR); - } - - working = 1; /* check queues for work the first time */ - while (1) - { - if (!working) - { - if (ibSrqLock == 0) - { - /* Enable SRQ interrupts while waiting for an event */ - srqIntEnable(plink->linkType, plink->linkId, plink->bug); - } - - /* wait for an event associated with this GPIB link */ - semTake(plink->linkEventSem, WAIT_FOREVER); - - /* Disable SRQ interrupts while processing an event */ - srqIntDisable(plink->linkType, plink->linkId, plink->bug); - - if (ibDebug) - { - logMsg("ibLinkTask(%d, %d): got an event\n", plink->linkType, plink->linkId); - } - } - working = 0; /* Assume will do nothing */ - - /* Check if an SRQ interrupt has occurred recently */ - - /* - * If link is currently doing DMA, this function/task will be performing - * the work. Therfore, it will not be here trying to poll devices, so - * is no need to worry about locking the GPIB link here. - */ - - if ((plink->srqIntFlag) && (ibSrqLock == 0)) - { - if (ibDebug || ibSrqDebug) - logMsg("ibLinkTask(%d, %d): srqIntFlag set.\n", plink->linkType, plink->linkId); - - plink->srqIntFlag = 0; - pollActive = 0; - - pollAddress = 1; /* skip 0 and 31, poll 1-30 */ - while (pollAddress < 31) - { - if (!(pollInhibit[plink->linkId][pollAddress])) /* zero if allowed */ - { - if (!pollActive) - { /* set the serial poll enable mode if not done so yet */ - pollActive = 1; - speIb(plink); - } - if (ibDebug || ibSrqDebug) - logMsg("ibLinkTask(%d, %d): poling device %d\n", plink->linkType, plink->linkId, pollAddress); - if ((ringData.status = pollIb(plink, pollAddress, 1, POLLTIME)) & 0x40) - { - ringData.device = pollAddress; - if (ibDebug || ibSrqDebug) - logMsg("ibLinkTask(%d, %d): device %d srq status = 0x%2.2X\n", plink->linkType, plink->linkId, pollAddress, ringData.status); - if (plink->srqHandler[ringData.device] != NULL) - { /* there is a registered SRQ handler for this device */ - rngBufPut(plink->srqRing, (char *) &ringData, sizeof(ringData)); - } - else - if (ibDebug || ibSrqDebug) - logMsg("ibLinkTask(%d, %d): got an srq from device %d... ignored\n", plink->linkType, plink->linkId, pollAddress); - } - } - pollAddress++; - } - if (pollActive) - { /* unset serial poll mode if it got set above */ - pollActive = 0; - spdIb(plink); - } - else - { - logMsg("ibLinkTask(%d, %d): got an SRQ, but have no pollable devices!\n", plink->linkType, plink->linkId); - } - /* - * If the SRQ link is again/still active, it will be seen on the next - * call to srqIntEnable above. - */ - } - - /* - * See if there is a need to process an SRQ solicited transaction. - * Do all of them before going on to other transactions. - */ - while (rngBufGet(plink->srqRing, (char *)&ringData, sizeof(ringData))) - { - if (ibDebug || ibSrqDebug) - logMsg("ibLinkTask(%d, %d): dispatching srq handler for device %d\n", plink->linkType, plink->linkId, ringData.device); - plink->deviceStatus[ringData.device] = (*(plink->srqHandler)[ringData.device])(plink->srqParm[ringData.device], ringData.status); - working=1; - } - - /* - * see if the Hi priority queue has anything in it - */ - semTake(plink->hiPriSem, WAIT_FOREVER); - - if ((pnode = (struct dpvtGpibHead *)ellFirst(&(plink->hiPriList))) != NULL) - { - while (plink->deviceStatus[pnode->device] == BUSY) - if ((pnode = (struct dpvtGpibHead *)ellNext(pnode)) == NULL) - break; - } - if (pnode != NULL) - ellDelete(&(plink->hiPriList), pnode); - - semGive(plink->hiPriSem); - - if (pnode != NULL) - { - if (ibDebug) - logMsg("ibLinkTask(%d, %d): got Hi Pri xact, pnode= 0x%8.8X\n", plink->linkType, plink->linkId, pnode); - - plink->deviceStatus[pnode->device] = (*(pnode->workStart))(pnode); - working=1; - } - else - { - semTake(plink->loPriSem, WAIT_FOREVER); - if ((pnode = (struct dpvtGpibHead *)ellFirst(&(plink->loPriList))) != NULL) - { - while (plink->deviceStatus[pnode->device] == BUSY) - if ((pnode = (struct dpvtGpibHead *)ellNext(pnode)) == NULL) - break; - } - if (pnode != NULL) - ellDelete(&(plink->loPriList), pnode); - - semGive(plink->loPriSem); - - if (pnode != NULL) - { - if(ibDebug) - logMsg("ibLinkTask(%d, %d): got Lo Pri xact, pnode= 0x%8.8X\n", plink->linkType, plink->linkId, pnode); - plink->deviceStatus[pnode->device] = (*(pnode->workStart))(pnode); - working=1; - } - } - } -} - -/****************************************************************************** - * - * The following are functions used to take care of serial polling. They - * are called from the ibLinkTask. - * - ******************************************************************************/ -/****************************************************************************** - * - * Pollib sends out an SRQ poll and returns the poll response. - * If there is an error during polling (timeout), the value -1 is returned. - * - ******************************************************************************/ -STATIC int -pollIb(plink, gpibAddr, verbose, time) -struct ibLink *plink; -int gpibAddr; -int verbose; /* set to 1 if should log any errors */ -int time; -{ - char pollCmd[4]; - int status; - int tsSave; - unsigned char pollResult[3]; - - - if(verbose && (ibDebug || ibSrqDebug)) - logMsg("pollIb(0x%8.8X, %d, %d, %d)\n", plink, gpibAddr, verbose, time); - - tsSave = timeoutSquelch; - timeoutSquelch = !verbose; /* keep the I/O routines quiet if desired */ - - /* raw-read back the response from the instrument */ - if (readIb(plink, gpibAddr, pollResult, sizeof(pollResult), time) == ERROR) - { - if(verbose) - logMsg("pollIb(%d, %d): data read error\n", plink->linkId, gpibAddr); - status = ERROR; - } - else - { - status = pollResult[0]; - if (ibDebug || ibSrqDebug) - { - logMsg("pollIb(%d, %d): poll status = 0x%2.2X\n", plink->linkId, gpibAddr, status); - } - } - - timeoutSquelch = tsSave; /* return I/O error logging to normal */ - return(status); -} - -/****************************************************************************** - * - * speIb is used to send out a Serial Poll Enable command on the GPIB - * bus. - * - ******************************************************************************/ -STATIC int -speIb(plink) -struct ibLink *plink; -{ - /* write out the Serial Poll Enable command */ - writeIbCmd(plink, "\030", 1); - - return(0); -} - - -/****************************************************************************** - * - * spdIb is used to send out a Serial Poll Disable command on the GPIB - * bus. - * - ******************************************************************************/ -STATIC int -spdIb(plink) -struct ibLink *plink; -{ - /* write out the Serial Poll Disable command */ - writeIbCmd(plink, "\031", 1); - - return(0); -} - -/****************************************************************************** - * - * Functions used to enable and disable SRQ interrupts. These only make - * sense on a Ni based link, so they are ignored in the BitBus case. - * (In the BitBus, SRQ status is passed back via query. So there is no - * asynchronous interupt associated with it.) - * - * The interrupts referred to here are the actual VME bus interrupts that are - * generated by the GPIB interface when it sees the SRQ line go high. - * - ******************************************************************************/ -STATIC int -srqIntEnable(int linkType, int link, int bug) -{ - if (linkType == GPIB_IO) - { - if (link > NIGPIB_NUM_LINKS) - return(OK); - else - return(niSrqIntEnable(link)); - } - if (linkType == BBGPIB_IO) - return(OK); /* Bit Bus does not use interrupts for SRQ handeling */ - - return(ERROR); /* Invalid link type specified on the call */ -} - -STATIC int -srqIntDisable(int linkType, int link, int bug) -{ - if (linkType == GPIB_IO) - { - if (link > NIGPIB_NUM_LINKS) - return(0); - else - return(niSrqIntDisable(link)); - } - if (linkType == BBGPIB_IO) - return(0); /* BitBus does not use interrupts for SRQs */ - - return(ERROR); /* Invlaid link type specified on the call */ -} - -/****************************************************************************** - * - * Check the link number and bug number (if is a BBGPIB_IO link) to see if they - * are valid. - * - ******************************************************************************/ -STATIC int -checkLink(int linkType, int link, int bug) -{ - if (linkType == GPIB_IO) - { - if (link > NIGPIB_NUM_LINKS) - return(HiDEOSCheckLink(link)); - else - return(niCheckLink(link)); - } - if (linkType == BBGPIB_IO) - return(bbCheckLink(link, bug)); - - return(ERROR); /* bad link type specefied */ -} - -/**************************************************************************** - * - * The following routines are the user-callable entry points to the GPIB - * driver. - * - ****************************************************************************/ -/****************************************************************************** - * - * A device support module may call this function to request that the GPIB - * driver NEVER poll a given device. - * - * Devices are polled when an SRQ event is present on the GPIB link. Some - * devices are too dumb to deal with being polled. - * - * This is NOT a static function, because it must be invoked from the startup - * script BEFORE iocInit is called. - * - * BUG -- - * This could change if we decide to poll them during the second call to init() - * - ******************************************************************************/ -int -srqPollInhibit( -int linkType, /* link type (defined in link.h) */ -int link, /* the link number the handler is related to */ -int bug, /* the bug node address if on a bitbus link */ -int gpibAddr) /* the device address the handler is for */ -{ - if (ibDebug || ibSrqDebug) - logMsg("srqPollInhibit(%d, %d, %d, %d): called\n", linkType, link, bug, gpibAddr); - - if (linkType == GPIB_IO) - { - if (link > NIGPIB_NUM_LINKS) - return(HiDEOSSrqPollInhibit(link, gpibAddr)); - else - return(niSrqPollInhibit(link, gpibAddr)); - } - - if (linkType == BBGPIB_IO) - { - return(bbSrqPollInhibit(link, bug, gpibAddr)); - } - - logMsg("drvGpib: srqPollInhibit(%d, %d, %d, %d): invalid link type specified\n", linkType, link, bug, gpibAddr); - return(ERROR); -} - -/****************************************************************************** - * - * This allows a device support module to register an SRQ event handler. - * - * It is used to specify a function to call when an SRQ event is detected - * on the specified link and device. When the SRQ handler is called, it is - * passed the requested parm and the poll-status from the gpib device. - * - ******************************************************************************/ -STATIC int -registerSrqCallback( -struct ibLink *pibLink, -int device, -int (*handler)(), /* Function invoked upon SRQ detection */ -void *parm) /* So caller can have a parm passed back */ -{ - if(ibDebug || ibSrqDebug) - logMsg("registerSrqCallback(%8.8X, %d, 0x%8.8X, %8.8X)\n", pibLink, device, handler, parm); - - pibLink->srqHandler[device] = handler; - pibLink->srqParm[device] = parm; - return(OK); -} - -/****************************************************************************** - * - * Allow users to operate the internal functions of the driver. - * - * This can be fatal to the driver... make sure you know what you are doing! - * - ******************************************************************************/ -STATIC int -ioctlIb( - int linkType, /* link type (defined in link.h) */ - int link, /* the link number to use */ - int bug, /* node number if is a bitbus -> gpib link */ - int cmd, - int v, - void *p) -{ - - if (linkType == GPIB_IO) - { - if (link > NIGPIB_NUM_LINKS) - return(HiDEOSGpibIoctl(link, cmd, v, p)); - else - return(niGpibIoctl(link, cmd, v, p)); - } - if (linkType == BBGPIB_IO) - return(bbGpibIoctl(link, bug, cmd, v, p)); - - if (ibDebug || bbibDebug) - logMsg("ioctlIb(%d, %d, %d, %d, %8.8X, %8.8X): invalid link type\n", linkType, link, bug, cmd, v, p); - - return(ERROR); -} - -/****************************************************************************** - * - * This function allows a user program to queue a GPIB work request for - * future execution. It is the ONLY way a user function can initiate - * a GPIB message transaction. - * - * A work request represents a function that the ibLinkTask is to call (when - * ready) to allow the user program access to the readIb, readIbEos, writeIb, - * and writeIbCmd functions. The user programs should never call these - * functions at any other times. - * - * Returns OK, or ERROR. - * - ******************************************************************************/ -STATIC int -qGpibReq( -struct dpvtGpibHead *pdpvt, /* pointer to the device private structure */ -int prio) -{ - - if (pdpvt->pibLink == NULL) - { - logMsg("qGpibReq(%8.8X, %d): dpvt->pibLink == NULL!\n", pdpvt, prio); - return(ERROR); - } - - switch (prio) { - case IB_Q_LOW: /* low priority transaction request */ - semTake(pdpvt->pibLink->loPriSem, WAIT_FOREVER); - ellAdd(&(pdpvt->pibLink->loPriList), pdpvt); - semGive(pdpvt->pibLink->loPriSem); - semGive(pdpvt->pibLink->linkEventSem); - break; - case IB_Q_HIGH: /* high priority transaction request */ - semTake(pdpvt->pibLink->hiPriSem, WAIT_FOREVER); - ellAdd(&(pdpvt->pibLink->hiPriList), pdpvt); - semGive(pdpvt->pibLink->hiPriSem); - semGive(pdpvt->pibLink->linkEventSem); - break; - default: /* invalid priority */ - logMsg("invalid priority requested in call to qgpibreq(%8.8X, %d)\n", pdpvt, prio); - return(ERROR); - } - if (ibDebug) - logMsg("qgpibreq(0x%8.8X, %d): transaction queued\n", pdpvt, prio); - return(OK); -} - -/****************************************************************************** - * - * The following functions are defined for use by device support modules. - * They may ONLY be called by the linkTask. - * - ******************************************************************************/ -/****************************************************************************** - * - * A device support callable entry point used to write data to GPIB devices. - * - * This function returns the number of bytes written out. - * - ******************************************************************************/ -STATIC int -writeIb( -struct ibLink *pibLink, -int gpibAddr, /* The device number to write the data to */ -char *data, /* The data buffer to write out */ -int length, /* Number of bytes to write out */ -int time) -{ - char attnCmd[5]; - int stat; - - if(ibDebug || (bbibDebug & (pibLink->linkType == BBGPIB_IO))) - logMsg("writeIb(%8.8X, %d, 0x%8.8X, %d, %d)\n", pibLink, gpibAddr, data, length, time); - - if (pibLink->linkType == GPIB_IO) - { - if (pibLink->linkId > NIGPIB_NUM_LINKS) - return(HiDEOSGpibWrite(pibLink, gpibAddr, data, length, time)); - else - { - attnCmd[0] = '?'; /* global unlisten */ - attnCmd[1] = '_'; /* global untalk */ - attnCmd[2] = gpibAddr+LADBASE; /* lad = gpibAddr */ - attnCmd[3] = 0+TADBASE; /* mta = 0 */ - attnCmd[4] = '\0'; /* in case debugging prints it */ - - if (writeIbCmd(pibLink, attnCmd, 4) != 4) - return(ERROR); - stat = niGpibWrite(pibLink->linkId, data, length, time); - - if (writeIbCmd(pibLink, attnCmd, 2) != 2) - return(ERROR); - } - } - else if (pibLink->linkType == BBGPIB_IO) - stat = bbGpibWrite(pibLink, gpibAddr, data, length, time); - else - return(ERROR); - return(stat); -} - -/****************************************************************************** - * - * A device support callable entry point used to read data from GPIB devices. - * - * This function returns the number of bytes read from the device, or ERROR - * if the read operation failed. - * - * This routine just calls readIbEos with the eos parameter=-1, which means - * ignore eos. It is written this way to provide backwards compatibility - * since readIbEos was added later. - * - ******************************************************************************/ -STATIC int -readIb( -struct ibLink *pibLink, -int gpibAddr, /* the device number to read the data from */ -char *data, /* the buffer to place the data into */ -int length, /* max number of bytes to place into the buffer */ -int time) /* max time to allow for read operation */ -{ - return readIbEos(pibLink, gpibAddr, data, length, time, -1); -} -/****************************************************************************** - * - * A device support callable entry point used to read data from GPIB devices. - * - * This function returns the number of bytes read from the device, or ERROR - * if the read operation failed. - * - * This routine can terminate a read on receipt of the end-of-string (Eos) - * character. Note that this is presently only supported for HiDEOS. The - * EOS parameter is presently ignored by the NI and Bitbus routines. Support - * for EOS on these may be added in the future. - * - ******************************************************************************/ -int readIbEos( -struct ibLink *pibLink, -int gpibAddr, /* the device number to read the data from */ -char *data, /* the buffer to place the data into */ -int length, /* max number of bytes to place into the buffer */ -int time, /* max time to allow for read operation */ -int eos) /* End-of-string character, -1 if none */ -{ - char attnCmd[5]; - int stat; - - if(ibDebug || (bbibDebug & (pibLink->linkType == BBGPIB_IO))) - logMsg("readIb(%8.8X, %d, 0x%8.8X, %d)\n", pibLink, gpibAddr, data, length); - - if (pibLink->linkType == GPIB_IO) - { - if (pibLink->linkId > NIGPIB_NUM_LINKS) - return(HiDEOSGpibRead(pibLink, gpibAddr, data, length, time, eos)); - else - { - attnCmd[0] = '_'; /* global untalk */ - attnCmd[1] = '?'; /* global unlisten */ - attnCmd[2] = gpibAddr+TADBASE; /* tad = gpibAddr */ - attnCmd[3] = 0+LADBASE; /* mta = 0 */ - attnCmd[4] = '\0'; - - if (writeIbCmd(pibLink, attnCmd, 4) != 4) - return(ERROR); - - stat = niGpibRead(pibLink->linkId, data, length, time); - - if (writeIbCmd(pibLink, attnCmd, 2) != 2) - return(ERROR); - } - } - else if (pibLink->linkType == BBGPIB_IO) - { - stat = bbGpibRead(pibLink, gpibAddr, data, length, time); - } - else - { /* incorrect link type specified! */ - return(ERROR); - } - return(stat); -} - -/****************************************************************************** - * - * A device support callable entry point that is used to write commands - * to GPIB devices. (this is the same as a regular write except that the - * ATN line is held high during the write. - * - * This function returns the number of bytes written out. - * - ******************************************************************************/ -STATIC int -writeIbCmd( -struct ibLink *pibLink, -char *data, /* The data buffer to write out */ -int length) /* Number of bytes to write out */ -{ - - if(ibDebug || (bbibDebug & (pibLink->linkType == BBGPIB_IO))) - logMsg("writeIbCmd(%8.8X, %8.8X, %d)\n", pibLink, data, length); - - if (pibLink->linkType == GPIB_IO) - { - if (pibLink->linkId > NIGPIB_NUM_LINKS) - return(HiDEOSGpibCmd(pibLink, data, length)); - else - return(niGpibCmd(pibLink->linkId, data, length)); - } - if (pibLink->linkType == BBGPIB_IO) - return(bbGpibCmd(pibLink, data, length)); - - return(ERROR); -} - -/****************************************************************************** - * - * These are the BitBus architecture specific functions. - * - ******************************************************************************/ - -/****************************************************************************** - * - * Read a GPIB message via the BitBus driver. - * - ******************************************************************************/ -STATIC int -bbGpibRead(pibLink, device, buffer, length, time) -struct ibLink *pibLink; -int device; -char *buffer; -int length; -int time; -{ - /* The bbIbLink structure starts with the ibLink, so this is OK */ - struct bbIbLink *pbbIbLink = (struct bbIbLink *) pibLink; - - struct dpvtBitBusHead bbdpvt; - int bytesRead; - char msg[150]; - - sprintf(msg, "bbGpibRead(%p, %d, %p, %d, %d): entered", pibLink, device, buffer, length, time); - GpibDebug(pibLink, device, msg, 1); - - bytesRead = 0; - - bbdpvt.finishProc = NULL; /* no callback, synchronous I/O mode */ - bbdpvt.psyncSem = &(pbbIbLink->syncSem); - bbdpvt.link = pibLink->linkId; - - bbdpvt.rxMsg.data = (unsigned char *) buffer; - - bbdpvt.txMsg.route = BB_STANDARD_TX_ROUTE; - bbdpvt.txMsg.node = pibLink->bug; - bbdpvt.txMsg.tasks = BB_GPIB_TASK; - bbdpvt.txMsg.cmd = BB_IBCMD_READ_XACT | device; - bbdpvt.txMsg.length = 7; /* send header only */ - - bbdpvt.rxMsg.cmd = 0; /* init for the while loop */ - bbdpvt.status = BB_OK; - - while (length && (bbdpvt.status == BB_OK) && (!(bbdpvt.rxMsg.cmd & (BB_IBSTAT_EOI|BB_IBSTAT_TMO)))) - { - bbdpvt.rxMaxLen = length > BB_MAX_DAT_LEN ? BB_MAX_DAT_LEN+7 : length+7; - bbdpvt.ageLimit = 0; - if ((*(drvBitBus.qReq))(&bbdpvt, BB_Q_LOW) != OK) - { - bbdpvt.status = BB_NONODE; - return(ERROR); - } - semTake(*(bbdpvt.psyncSem), WAIT_FOREVER); /* wait for response */ - - sprintf(msg, "bbGpibRead(): %2.2X >%.13s< driver status 0x%2.2X", bbdpvt.rxMsg.cmd, bbdpvt.rxMsg.data, bbdpvt.status); - GpibDebug(pibLink, device, msg, 1); - - bbdpvt.txMsg.cmd = BB_IBCMD_READ; /* in case have more reading to do */ - bbdpvt.rxMsg.data += bbdpvt.rxMsg.length - 7; - length -= bbdpvt.rxMsg.length - 7; - bytesRead += bbdpvt.rxMsg.length - 7; - } - if ((bbdpvt.rxMsg.cmd & BB_IBSTAT_TMO) || (bbdpvt.status != BB_OK)) - return(ERROR); - else - return(bytesRead); -} - -/****************************************************************************** - * - * Write a GPIB message by way of the bitbus driver. - * - ******************************************************************************/ -STATIC int -bbGpibWrite(pibLink, device, buffer, length, time) -struct ibLink *pibLink; -int device; -char *buffer; -int length; -int time; -{ - /* The bbIbLink structure starts with the ibLink, so this is OK */ - struct bbIbLink *pbbIbLink = (struct bbIbLink *) pibLink; - - struct dpvtBitBusHead bbdpvt; - unsigned char dbugBuf[BB_MAX_DAT_LEN + 1]; - unsigned char more2GoCommand; - unsigned char lastCommand; - int bytesSent; - char msg[150]; - - sprintf(msg, "bbGpibWrite(%p, %d, %p, %d, %d): entered", pibLink, device, buffer, length, time); - GpibDebug(pibLink, device, msg, 1); - - bytesSent = length; /* we either get an error or send them all */ - - bbdpvt.finishProc = NULL; /* no callback, synchronous I/O mode */ - bbdpvt.psyncSem = &(pbbIbLink->syncSem); - bbdpvt.link = pibLink->linkId; - bbdpvt.rxMaxLen = 7; /* only get the header back */ - - bbdpvt.txMsg.route = BB_STANDARD_TX_ROUTE; - bbdpvt.txMsg.node = pibLink->bug; - bbdpvt.txMsg.tasks = BB_GPIB_TASK; - - bbdpvt.txMsg.data = (unsigned char *) buffer; - - bbdpvt.rxMsg.cmd = 0; /* Init for error checking */ - bbdpvt.status = BB_OK; - - /* if more than BB_MAX_DAT_LEN bytes */ - more2GoCommand = BB_IBCMD_ADDR_WRITE | device; - - /* if less than BB_MAX_DAT_LEN+1 bytes */ - lastCommand = BB_IBCMD_WRITE_XACT | device; - - while (length && (bbdpvt.status == BB_OK) && (!(bbdpvt.rxMsg.cmd & BB_IBSTAT_TMO))) - { - if (length > BB_MAX_DAT_LEN) - { - bbdpvt.txMsg.length = BB_MAX_DAT_LEN+7; - bbdpvt.txMsg.cmd = more2GoCommand; /* Write to device */ - length -= BB_MAX_DAT_LEN; /* Ready for next chunk */ - - more2GoCommand = BB_IBCMD_WRITE; - lastCommand = BB_IBCMD_WRITE_EOI; - } - else - { - bbdpvt.txMsg.length = length+7; - bbdpvt.txMsg.cmd = lastCommand; - length = 0; /* This is the last one */ - } -#if 0 - if (ibDebug || bbibDebug) - { - bcopy(bbdpvt.txMsg.data, dbugBuf, bbdpvt.txMsg.length-7); - dbugBuf[bbdpvt.txMsg.length-7] = '\0'; - logMsg("bbGpibWrite():sending %2.2X >%s<", bbdpvt.txMsg.cmd, dbugBuf); - } -#else - bcopy(bbdpvt.txMsg.data, dbugBuf, bbdpvt.txMsg.length-7); - dbugBuf[bbdpvt.txMsg.length-7] = '\0'; - sprintf(msg, "bbGpibWrite():sending %2.2X >%s<", bbdpvt.txMsg.cmd, dbugBuf); - GpibDebug(pibLink, device, msg, 1); -#endif - - bbdpvt.ageLimit = 0; - if ((*(drvBitBus.qReq))(&bbdpvt, BB_Q_HIGH) != OK) - { - bbdpvt.status = BB_NONODE; - return(ERROR); - } - - semTake(*(bbdpvt.psyncSem), WAIT_FOREVER); /* wait for response */ - - sprintf(msg, " RAC status = 0x%2.2X driver status = 0x%2.2X", bbdpvt.rxMsg.cmd, bbdpvt.status); - GpibDebug(pibLink, device, msg, 1); - - bbdpvt.txMsg.data += BB_MAX_DAT_LEN; /* in case there is more */ - } - - /* All done, check to see if we died due to an error */ - - if ((bbdpvt.rxMsg.cmd & BB_IBSTAT_TMO) || (bbdpvt.status != BB_OK)) - return(ERROR); - else - return(bytesSent); -} - -/******************************************************************************/ -STATIC int -bbGpibCmd(pibLink, buffer, length) -struct ibLink *pibLink; -char *buffer; -int length; -{ - /* The bbIbLink structure starts with the ibLink, so this is OK */ - struct bbIbLink *pbbIbLink = (struct bbIbLink *) pibLink; - - struct dpvtBitBusHead bbdpvt; - int bytesSent; - char msg[150]; - - sprintf(msg, "bbGpibCmd(%p, %p, %d): entered", pibLink, buffer, length); - GpibDebug(pibLink, 0, msg, 1); - - bytesSent = length; - - bbdpvt.finishProc = NULL; /* no callback, synchronous I/O mode */ - bbdpvt.psyncSem = &(pbbIbLink->syncSem); - bbdpvt.link = pibLink->linkId; - bbdpvt.rxMaxLen = 7; /* only get the header back */ - - bbdpvt.status = BB_OK; /* prime these for the while loop */ - bbdpvt.rxMsg.cmd = 0; - - bbdpvt.txMsg.route = BB_STANDARD_TX_ROUTE; - bbdpvt.txMsg.node = pibLink->bug; - bbdpvt.txMsg.tasks = BB_GPIB_TASK; - bbdpvt.txMsg.cmd = BB_IBCMD_WRITE_CMD; - bbdpvt.txMsg.data = (unsigned char *) buffer; - - while ((length > BB_MAX_DAT_LEN) && (bbdpvt.status == BB_OK) && (!(bbdpvt.rxMsg.cmd & BB_IBSTAT_TMO))) - { - bbdpvt.txMsg.length = BB_MAX_DAT_LEN+7; /* send a chunk */ - bbdpvt.ageLimit = 0; - if ((*(drvBitBus.qReq))(&bbdpvt, BB_Q_HIGH) != OK) - { - bbdpvt.status = BB_NONODE; - return(ERROR); - } - semTake(*(bbdpvt.psyncSem), WAIT_FOREVER); /* wait for response */ - - length -= BB_MAX_DAT_LEN; /* ready for next chunk */ - bbdpvt.txMsg.data += BB_MAX_DAT_LEN; - } - if ((bbdpvt.status == BB_OK) && (!(bbdpvt.rxMsg.cmd & BB_IBSTAT_TMO))) - { - if (semTake(*(bbdpvt.psyncSem), 0) == OK) - { - sprintf(msg, "bbGpibCmd() able to take the dang sync sem before queueing!"); - GpibDebug(pibLink, 0, msg, 1); - } - bbdpvt.txMsg.length = length+7; /* send the last chunk */ - bbdpvt.ageLimit = 0; - if ((*(drvBitBus.qReq))(&bbdpvt, BB_Q_HIGH) != OK) - { - bbdpvt.status = BB_NONODE; - return(ERROR); - } - semTake(*(bbdpvt.psyncSem), WAIT_FOREVER); /* wait for response */ -/* BUG -- check bitbus response */ - } - return(bytesSent); -} - -/******************************************************************************/ -STATIC int -bbCheckLink(link, bug) -int link; -int bug; -{ - if (findBBLink(link, bug) != NULL) - return(OK); - else - return(ERROR); -} - -/******************************************************************************/ -STATIC int -bbSrqPollInhibit(link, bug, gpibAddr) -int link; -int bug; -int gpibAddr; -{ - logMsg("bbSrqPollInhibit called for link %d, bug %d, device %d\n", link, bug, gpibAddr); - return(ERROR); -} - -/****************************************************************************** - * - * Initialize all required structures and start an ibLinkTask() for use with - * a BBGPIB_IO based link. - * - ******************************************************************************/ -STATIC int -bbGenLink(link, bug) -int link; -int bug; -{ - struct bbIbLink *bbIbLink; - - if (ibDebug || bbibDebug) - logMsg("bbGenLink(%d, %d): entered\n", link, bug); - - /* First check to see if there is already a link set up */ - bbIbLink = findBBLink(link, bug); - - if (bbIbLink != NULL) - { /* Already have initialized the link for this guy... */ - if (bbibDebug || ibDebug) - logMsg("bbGenLink(%d, %d): link already initialized\n", link, bug); - - return(OK); - } - - /* This link is not started yet, initialize all the required stuff */ - - if ((bbIbLink = (struct bbIbLink *) malloc(sizeof(struct bbIbLink))) == NULL) - { - logMsg("bbGenLink(%d, %d): can't malloc memory for link structure\n", link, bug); - return(ERROR); - } - - bbIbLink->ibLink.linkType = BBGPIB_IO; - bbIbLink->ibLink.linkId = link; - bbIbLink->ibLink.bug = bug; - - bbIbLink->syncSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - - ibLinkInit(&(bbIbLink->ibLink)); - - /* BUG -- should have a lock in the rootBBLink list! */ - bbIbLink->next = rootBBLink; - rootBBLink = bbIbLink; /* link the new one into the list */ - - return(ibLinkStart(&(bbIbLink->ibLink))); -/* BUG -- I should free up the stuff if the init failed for some reason */ -} - -/****************************************************************************** - * - * IOCTL control function for BBGPIB_IO based links. - * - ******************************************************************************/ -STATIC int -bbGpibIoctl(int link, int bug, int cmd, int v, caddr_t p) -{ - int stat = ERROR; - struct bbIbLink *pbbIbLink; - struct dpvtBitBusHead bbDpvt; - unsigned char buf[BB_MAX_DAT_LEN]; - - if (ibDebug || bbibDebug) - logMsg("bbGpibIoctl(%d, %d, %d, %8.8X, %8.8X): called\n", link, bug, cmd, v, p); - -/* No checkLink() is done, because findBBLink() is done when needed */ - - switch (cmd) { - case IBTMO: /* set timeout time for next transaction only */ - /* find the ibLink structure for the requested link & bug */ - if ((pbbIbLink = (struct bbIbLink *)&(findBBLink(link, bug)->ibLink)) != NULL) - { - /* build a TMO message to send to the bug */ - bbDpvt.txMsg.length = 7; - bbDpvt.txMsg.route = BB_STANDARD_TX_ROUTE; - bbDpvt.txMsg.node = bug; - bbDpvt.txMsg.tasks = BB_GPIB_TASK; - bbDpvt.txMsg.cmd = BB_IBCMD_SET_TMO; - bbDpvt.txMsg.data = buf; - - buf[0] = v; - - bbDpvt.rxMsg.route = 0; - bbDpvt.rxMaxLen = 7; /* will only get header back anyway */ - bbDpvt.finishProc = NULL; /* no callback when receive reply */ - bbDpvt.psyncSem = &(pbbIbLink->syncSem); - bbDpvt.link = link; - bbDpvt.ageLimit = 0; - - /* send it to the bug */ - if ((*(drvBitBus.qReq))(&bbDpvt, BB_Q_HIGH) != OK) - { - bbDpvt.status = BB_NONODE; - return(ERROR); - } - semTake(*(bbDpvt.psyncSem), WAIT_FOREVER); /* wait for finish */ - if ((bbDpvt.status == BB_OK) && (!(bbDpvt.rxMsg.cmd & BB_IBSTAT_TMO))) - stat = OK; - else - stat = ERROR; - } - break; - - case IBIFC: /* send an Interface Clear pulse */ - /* find the ibLink structure for the requested link & bug */ - if ((pbbIbLink = (struct bbIbLink *)&(findBBLink(link, bug)->ibLink)) != NULL) - { - /* build an IFC message to send to the bug */ - bbDpvt.txMsg.length = 7; - bbDpvt.txMsg.route = BB_STANDARD_TX_ROUTE; - bbDpvt.txMsg.node = bug; - bbDpvt.txMsg.tasks = BB_GPIB_TASK; - bbDpvt.txMsg.cmd = BB_IBCMD_IFC; - - bbDpvt.rxMsg.route = 0; - bbDpvt.rxMaxLen = 7; /* will only get header back */ - bbDpvt.finishProc = NULL; /* no callback when get reply */ - bbDpvt.psyncSem = &(pbbIbLink->syncSem); - bbDpvt.priority = 0; - bbDpvt.link = link; - bbDpvt.ageLimit = 0; - - /* send it to the bug */ - if ((*(drvBitBus.qReq))(&bbDpvt, BB_Q_HIGH) != OK) - { - bbDpvt.status = BB_NONODE; - return(ERROR); - } - semTake(*(bbDpvt.psyncSem), WAIT_FOREVER); /* wait for finish */ - if ((bbDpvt.status == BB_OK) && (!(bbDpvt.rxMsg.cmd & BB_IBSTAT_TMO))) - stat = OK; - else - stat = ERROR; - } - break; - case IBREN: /* turn the Remote Enable line on or off */ - case IBGTS: /* go to standby (ATN off etc... ) */ - case IBGTA: /* go to active (ATN on etc... ) */ - stat = OK; - break; - case IBGENLINK: /* request the initialization of a link */ - stat = bbGenLink(link, bug); - break; - case IBGETLINK: /* request the address of the ibLink structure */ - *(struct ibLink **)p = &(findBBLink(link, bug)->ibLink); - break; - default: - logMsg("bbGpibIoctl(%d, %d, %d, %8.8X, %8.8X): invalid command requested\n", link, bug, cmd, v, p); - } - return(stat); -} - -/****************************************************************************** - * - * Find a bbIbLink structure given a link number and a bug number. - * - ******************************************************************************/ -struct bbIbLink * -findBBLink(link, bug) -int link; -int bug; -{ - struct bbIbLink *bbIbLink; - - bbIbLink = rootBBLink; - while (bbIbLink != NULL) - { - if ((bbIbLink->ibLink.linkId == link) && (bbIbLink->ibLink.bug == bug)) - break; - else - bbIbLink = bbIbLink->next; - } - if (ibDebug || bbibDebug) - logMsg("findBBLink(%d, %d): returning %8.8X\n", link, bug, bbIbLink); - - return(bbIbLink); -} - /******************************************************************************/ -STATIC int GpibDebug(struct ibLink *pIbLink, int Address, char *Msg, int DBLevel) -{ -#ifdef GPIB_SUPER_DEBUG - semTake(pIbLink->History.Sem, WAIT_FOREVER); - - pIbLink->History.Hist[pIbLink->History.Next].Time = tickGet(); - pIbLink->History.Hist[pIbLink->History.Next].DevAddr = Address; - strncpy(pIbLink->History.Hist[pIbLink->History.Next].Msg, Msg, GPIB_SUPER_DEBUG_HISTORY_STRLEN); - - if (++pIbLink->History.Next == GPIB_SUPER_DEBUG_HISTORY_SIZ) - pIbLink->History.Next = 0; - - if (pIbLink->History.Num < GPIB_SUPER_DEBUG_HISTORY_SIZ) - ++pIbLink->History.Num; - - semGive(pIbLink->History.Sem); -#endif - - if (ibDebug > DBLevel) - { - if (pIbLink->linkType == GPIB_IO) - logMsg("GPIB-L%d-D%d:%s\n", pIbLink->linkId, Address, Msg); - else if (pIbLink->linkType == BBGPIB_IO) - logMsg("BBIB-L%d-B%d-D%d:%s\n", pIbLink->linkId, pIbLink->bug, Address, Msg); - } - - return(0); -} -#ifdef GPIB_SUPER_DEBUG -IBHistDump(int type, int link, int bug) -{ - struct ibLink *pibLink; - int i; - int count; - - if (type == 0) - { /* NI gpib link */ - logMsg("Only bitbus links supported for history dumps\n"); - return(-1); - } - else - { /* Bitbus link */ - if ((pibLink = &(findBBLink(link, bug)->ibLink)) == NULL) - { - logMsg("Invalid link and/or bug specified\n"); - return(-1); - } - } - semTake(pibLink->History.Sem, WAIT_FOREVER); - /* pibLink now represents the link to dump history on */ - if (pibLink->History.Num < GPIB_SUPER_DEBUG_HISTORY_SIZ) - { - i = 0; - count = pibLink->History.Num; - } - else - { - i = pibLink->History.Next; - count = GPIB_SUPER_DEBUG_HISTORY_SIZ; - } - - while(count) - { - if (pibLink->linkType == GPIB_IO) - { - logMsg("%d GPIB-L%d-D%d: %s\n", pibLink->History.Hist[i].Time, - pibLink->linkId, pibLink->History.Hist[i].DevAddr, - pibLink->History.Hist[i].Msg); - } - else if (pibLink->linkType == BBGPIB_IO) - { - logMsg("%d BBIB-l%d-B%d-D%d: %s\n", pibLink->History.Hist[i].Time, - pibLink->linkId, pibLink->bug, pibLink->History.Hist[i].DevAddr, - pibLink->History.Hist[i].Msg); - } - - if (++i == GPIB_SUPER_DEBUG_HISTORY_SIZ) - i = 0; - --count; - } - - semGive(pibLink->History.Sem); - return(0); -} -#endif - -/****************************************************************************** - * - * These are the HiDEOS architecture specific functions. - * - ******************************************************************************/ - -/****************************************************************************** - * - * Find a HiDEOS link structure given a link number. - * - ******************************************************************************/ -STATIC HideosIbLinkStruct *findHiDEOSIbLink(int link) -{ - HideosIbLinkStruct *pHideosIbLink; - - pHideosIbLink = RootHideosIbLink; - pHideosIbLink->pNext = RootHideosIbLink; - - while (pHideosIbLink != NULL) - { - if (pHideosIbLink->ibLink.linkId == link) - break; - else - pHideosIbLink = pHideosIbLink->pNext; - } - if (ibDebug) - logMsg("findHiDEOSIbLink(%d): returning %8.8X\n", link, pHideosIbLink); - - return(pHideosIbLink); -} -/****************************************************************************** - * - * Read a GPIB message via the HiDEOS subsystem. - * - ******************************************************************************/ -STATIC int -HiDEOSGpibRead( - struct ibLink *pibLink, - int DevAddr, - char *Buf, - int BufLen, - int time, - int Eos) -{ - int Actual; - HideosIbLinkStruct *pHLink = (HideosIbLinkStruct*)pibLink; - - if (LHideosRead(pHLink->remote_td, Buf, BufLen, &Actual, DevAddr, time, Eos)==0) - return(Actual); - - return(-1); -} - -/****************************************************************************** - * - * Write a GPIB message by way of the bitbus driver. - * - ******************************************************************************/ -STATIC int -HiDEOSGpibWrite( - struct ibLink *pibLink, - int DevAddr, - char *Buf, - int BufLen, - int time) -{ - HideosIbLinkStruct *pHLink = (HideosIbLinkStruct*)pibLink; - return(LHideosWrite(pHLink->remote_td, Buf, BufLen, DevAddr, time)); -} - -/******************************************************************************/ -STATIC int -HiDEOSGpibCmd( - struct ibLink *pibLink, - char *Buf, - int BufLen) -{ - HideosIbLinkStruct *pHLink = (HideosIbLinkStruct*)pibLink; - return(LHideosWriteCmd(pHLink->remote_td, Buf, BufLen, 100)); -} - -/******************************************************************************/ -STATIC int -HiDEOSCheckLink(int link) -{ - if (findHiDEOSIbLink(link) != NULL) - return(OK); - else - return(ERROR); -} - -/******************************************************************************/ -STATIC int -HiDEOSSrqPollInhibit(int link, int gpibAddr) -{ - logMsg("HiDEOSSrqPollInhibit for link %d, device %d\n", link, gpibAddr); - return(ERROR); -} - -/****************************************************************************** - * - * Initialize all required structures and start an ibLinkTask() for use with - * a GPIB_IO based link to a HiDEOS interface. - * - ******************************************************************************/ -int -HiDEOSGpibLinkConfig(int link, int BoardId, char *TaskName) -{ - SYM_TYPE stype; - HideosIbLinkStruct *pHiDEOSIbLink; - - if (ibDebug) - logMsg("HiDEOSGpibLinkConfig(%d): entered\n", link); - - /* First check to see if there is already a link set up */ - pHiDEOSIbLink = findHiDEOSIbLink(link); - - if (pHiDEOSIbLink != NULL) - { /* Already have initialized the link for this guy... */ - if (ibDebug) - logMsg("HiDEOSGpibLinkConfig(%d): link already initialized\n", link); - - return(OK); - } - if ((pHiDEOSIbLink = (HideosIbLinkStruct *) malloc(sizeof(HideosIbLinkStruct))) == NULL) - { - logMsg("HiDEOSGpibLinkConfig(%d): can't malloc memory for link structure\n", link); - return(ERROR); - } - - if ((symFindByNameEPICS(sysSymTbl,"_GpibHideosInit", (char**)&LHideosInit,&stype)==ERROR) - || (symFindByNameEPICS(sysSymTbl,"_GpibHideosWrite", (char**)&LHideosWrite,&stype)==ERROR) - || (symFindByNameEPICS(sysSymTbl,"_GpibHideosRead", (char**)&LHideosRead,&stype)==ERROR) - || (symFindByNameEPICS(sysSymTbl,"_GpibHideosWriteRead", (char**)&LHideosWriteRead,&stype)==ERROR) - || (symFindByNameEPICS(sysSymTbl,"_GpibHideosWriteCmd", (char**)&LHideosWriteCmd,&stype)==ERROR)) - { - free (pHiDEOSIbLink); - logMsg("HiDEOSGpibLinkConfig: Can not locate Hideos GPIB services\n"); - return(-1); - } - /* get a logical connection into HiDEOS-land */ - if ((pHiDEOSIbLink->remote_td = LHideosInit(BoardId, TaskName)) == NULL) - { - free (pHiDEOSIbLink); - logMsg("HiDEOSGpibLinkConfig: Can not locate Hideos task %s\n", TaskName); - return(-1); - } - - pHiDEOSIbLink->ibLink.linkType = GPIB_IO; - pHiDEOSIbLink->ibLink.linkId = link; - pHiDEOSIbLink->ibLink.bug = -1; - pHiDEOSIbLink->BoardId = BoardId; - strcpy(pHiDEOSIbLink->TaskName, TaskName); - - ibLinkInit(&(pHiDEOSIbLink->ibLink)); - - semTake(RootHideosIbLinklock, WAIT_FOREVER); - pHiDEOSIbLink->pNext = RootHideosIbLink; - RootHideosIbLink = pHiDEOSIbLink; - semGive(RootHideosIbLinklock); - - return(ibLinkStart(&(pHiDEOSIbLink->ibLink))); -} - -/****************************************************************************** - * - * IOCTL control function for BBGPIB_IO based links. - * - ******************************************************************************/ -STATIC int -HiDEOSGpibIoctl(int link, int cmd, int v, void *p) -{ - int stat = ERROR; - - if (ibDebug) - logMsg("HiDEOSGpibIoctl(%d, %d, %8.8X, %8.8X): called\n", link, cmd, v, p); - - switch (cmd) { - case IBTMO: /* set timeout time for next transaction only */ - /* Can't do this yet!!! */ - stat = OK; - break; - - case IBIFC: /* send an Interface Clear pulse */ - /* Can't do this yet!!! */ - stat = OK; - break; - - case IBREN: /* turn the Remote Enable line on or off */ - case IBGTS: /* go to standby (ATN off etc... ) */ - case IBGTA: /* go to active (ATN on etc... ) */ - stat = OK; - break; - case IBGENLINK: /* Done manually in startup.cmd */ - stat = OK; - break; - case IBGETLINK: /* request the address of the ibLink structure */ - *(struct ibLink **)p = &(findHiDEOSIbLink(link)->ibLink); - break; - default: - logMsg("HiDEOSGpibIoctl(%d, %d, %8.8X, %8.8X): invalid command requested\n", link, cmd, v, p); - } - return(stat); -} diff --git a/src/drv/old/drvGpib.h b/src/drv/old/drvGpib.h deleted file mode 100644 index cbf4f6290..000000000 --- a/src/drv/old/drvGpib.h +++ /dev/null @@ -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 */ - diff --git a/src/drv/old/drvGpibErr.h b/src/drv/old/drvGpibErr.h deleted file mode 100644 index ac7512ff9..000000000 --- a/src/drv/old/drvGpibErr.h +++ /dev/null @@ -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 /* 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 diff --git a/src/drv/old/drvGpibInterface.h b/src/drv/old/drvGpibInterface.h deleted file mode 100644 index ea4a96b67..000000000 --- a/src/drv/old/drvGpibInterface.h +++ /dev/null @@ -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 -#include -#include -#include /* 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 diff --git a/src/drv/old/drvHiDEOSGpib.h b/src/drv/old/drvHiDEOSGpib.h deleted file mode 100644 index 0f67b7cd6..000000000 --- a/src/drv/old/drvHiDEOSGpib.h +++ /dev/null @@ -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 diff --git a/src/drv/old/drvJgvtr1.c b/src/drv/old/drvJgvtr1.c deleted file mode 100644 index 7ae1e6aad..000000000 --- a/src/drv/old/drvJgvtr1.c +++ /dev/null @@ -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 -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -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; -} diff --git a/src/drv/old/drvJgvtr1.h b/src/drv/old/drvJgvtr1.h deleted file mode 100644 index f4c3f6454..000000000 --- a/src/drv/old/drvJgvtr1.h +++ /dev/null @@ -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 -); - diff --git a/src/drv/old/drvMsg.c b/src/drv/old/drvMsg.c deleted file mode 100644 index 77e592eb9..000000000 --- a/src/drv/old/drvMsg.c +++ /dev/null @@ -1,1425 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * Author: John Winans - * Date: 04-14-92 - * EPICS Generic message based I/O 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 04-14-92 jrw created - * .02 05-26-92 jrw changed enumeration of the record types - * .03 08-02-93 mrk Added call to taskwdInsert - * - */ - -#include -#include -#include - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -int msgDebug = 0; - -#ifndef INVALID_ALARM -#define INVALID_ALARM VALID_ALARM -#endif - -static long drvMsg_write(), drvMsg_AiFmt(); -static long drvMsg_AoFmt(); -long drvMsg_proc(); -static long drvMsg_BiFmt(), drvMsg_BoFmt(), drvMsg_MiFmt(), drvMsg_MoFmt(); -static long drvMsg_LiFmt(), drvMsg_LoFmt(), drvMsg_SiFmt(), drvMsg_SoFmt(); -static long drvMsg_SiRaw(), drvMsg_SoRaw(); -static long drvMsg_CheckAck(); - -static void drvMsg_callbackFunc(); -static int msgTask(); - -static long (*(msgSupFun[]))() = { - NULL, /* MSG_OP_NOP */ - drvMsg_write, /* MSG_OP_WRITE */ - drvMsg_AiFmt, /* MSG_OP_FAI */ - drvMsg_AoFmt, /* MSG_OP_FAO */ - drvMsg_BiFmt, /* MSG_OP_FBI */ - drvMsg_BoFmt, /* MSG_OP_FBO */ - drvMsg_MiFmt, /* MSG_OP_FMI */ - drvMsg_MoFmt, /* MSG_OP_FMO */ - drvMsg_LiFmt, /* MSG_OP_FLI */ - drvMsg_LoFmt, /* MSG_OP_FLO */ - drvMsg_SiFmt, /* MSG_OP_FSI */ - drvMsg_SoFmt, /* MSG_OP_FSO */ - drvMsg_SiRaw, /* MSG_OP_RSI */ - drvMsg_SoRaw, /* MSG_OP_RSO */ - drvMsg_CheckAck /* MSG_OP_ACK */ -}; -#define NUM_VALID_OPS sizeof(msgSupFun)/sizeof(msgSupFun[0]) - -/****************************************************************************** - * - * These are the msgRecEnum structures that are used to define the - * types of records supported by the message based driver system. - * - * This list may be extended by the application developer in the device support - * module if necessary. - * - ******************************************************************************/ -msgRecEnum drvMsgAi = { "Analog In" }; -msgRecEnum drvMsgAo = { "Analog Out" }; -msgRecEnum drvMsgBi = { "Binary In" }; -msgRecEnum drvMsgBo = { "Binary Out" }; -msgRecEnum drvMsgMi = { "Multibit In" }; -msgRecEnum drvMsgMo = { "Multibit Out" }; -msgRecEnum drvMsgLi = { "Long In" }; -msgRecEnum drvMsgLo = { "Long Out" }; -msgRecEnum drvMsgSi = { "String In" }; -msgRecEnum drvMsgSo = { "String Out" }; -msgRecEnum drvMsgWf = { "Waveform" }; - -/****************************************************************************** - * - * Driver entry table for the message based I/O driver - * - ******************************************************************************/ -struct drvet drvMsg = { 2, drvMsg_reportMsg, drvMsg_initMsg }; - -/****************************************************************************** - * - ******************************************************************************/ -long -drvMsg_reportMsg(pdset) -msgDset *pdset; -{ - printf("Message driver report\n"); - - if (pdset->pparmBlock->pdrvBlock->drvIoctl != NULL) - return((*(pdset->pparmBlock->pdrvBlock->drvIoctl))(MSGIOCTL_REPORT, NULL)); - - return(OK); -} - - -/****************************************************************************** - * - ******************************************************************************/ -long -drvMsg_initMsg(parm, pdset) -int parm; -msgDset *pdset; -{ - - msgDrvIniParm initParms; - - initParms.parm = parm; - initParms.pdset = pdset; - - if (msgDebug) - printf("Message init routine entered %d, %p\n", parm, pdset); - - if(pdset->pparmBlock->pdrvBlock->drvIoctl != NULL) - return((*(pdset->pparmBlock->pdrvBlock->drvIoctl))(MSGIOCTL_INIT, &initParms)); - - return(OK); -} - -/****************************************************************************** - * - ******************************************************************************/ -int drvMsg_xactListAddHead(plist, pnode) -xactQueue *plist; -msgXact *pnode; -{ - pnode->prev = NULL; - pnode->next = plist->head; - - if (plist->head != NULL) - plist->head->prev = pnode; - - if (plist->tail == NULL) - plist->tail = pnode; - - plist->head = pnode; - - return(0); -} -/****************************************************************************** - * - ******************************************************************************/ -int drvMsg_xactListAddTail(plist, pnode) -xactQueue *plist; -msgXact *pnode; -{ - pnode->next = NULL; /* No next node if this is the TAIL */ - pnode->prev = plist->tail; /* previous node is the 'old' TAIL node */ - - if (plist->tail != NULL) - plist->tail->next = pnode; /* link the 'old' tail to the 'new' tail node */ - - if (plist->head == NULL) - plist->head = pnode; - - plist->tail = pnode; /* this is the 'new' tail node */ - - return(0); -} -/****************************************************************************** - * - ******************************************************************************/ -int drvMsg_xactListDel(plist, pnode) -xactQueue *plist; -msgXact *pnode; -{ - if (pnode->next != NULL) - pnode->next->prev = pnode->prev; - - if (pnode->prev != NULL) - pnode->prev->next = pnode->next; - - if (plist->head == pnode) - plist->head = pnode->next; - - if (plist->tail == pnode) - plist->tail = pnode->prev; - - return(0); -} - -/****************************************************************************** - * - * Generate a transaction structure and initialize it. - * - ******************************************************************************/ -msgXact * -drvMsg_genXact(pparmBlock, plink, prec) -msgParmBlock *pparmBlock; -struct link *plink; /* I/O link structure from record */ -struct dbCommon *prec; -{ - msgXact *pmsgXact; - msgDrvGenXParm genXactParm; - char message[200]; - - /* allocate and fill in msg specific part */ - if ((pmsgXact = malloc(sizeof (msgXact))) == NULL) - { - sprintf(message, "drvMsg_genXact:%s out of memory\n", prec->name); - errMessage(S_db_badField, message); - return(NULL); - } - pmsgXact->pparmBlock = pparmBlock; - pmsgXact->prec = prec; - - genXactParm.plink = plink; - genXactParm.pmsgXact = pmsgXact; - - /* fill in communication-link specific portion and phwpvt */ - if ((*(pparmBlock->pdrvBlock->drvIoctl))(MSGIOCTL_GENXACT, &genXactParm) == ERROR) - { - /* free-up the xact structure and clean up */ - - /* errMessage() */ - printf("(Message driver): An error occurred while initializing %s\n", prec->name); - return(NULL); - } - /* Verify that the parm number is within range */ - if (pmsgXact->parm >= pparmBlock->numCmds) - { - sprintf(message, "(Message driver) %s parm number %d invalid\n", prec->name, pmsgXact->parm); - errMessage(S_db_badField, message); - return(NULL); - } - - /* Make a simple check to see if the parm entry makes sense */ - if ((pparmBlock->pcmds[pmsgXact->parm].flags & READ_DEFER) && (pparmBlock->pcmds[pmsgXact->parm].readOp.p == NULL)) - { - sprintf(message, "(Message driver) %s parm number %d specifies a deferred read, but no read operation\n", prec->name, pmsgXact->parm); - errMessage(S_db_badField, message); - return(NULL); - } - return(pmsgXact); -} - -/****************************************************************************** - * - * Generate a hardware private structure and initialize it. - * This is called by pparmBlock->pdrvBlock->drvIoctl(MSGIOCTL_GENXACT) when it - * finds that a hardware private structure is not present when a transaction - * structure is being initialized for it. - * - ******************************************************************************/ -msgHwpvt * -drvMsg_genHwpvt(pparmBlock, plink) -msgParmBlock *pparmBlock; -struct link *plink; /* I/O link structure from record */ -{ - msgHwpvt *pmsgHwpvt; - msgDrvGenHParm genHParms; - - if (msgDebug) - printf("In drvMsg_genHwpvt\n"); - - /* allocate and fill in msg specific part */ - if((pmsgHwpvt = malloc(sizeof(msgHwpvt))) == NULL) - return(NULL); - - /* Link it into the msgParmBlock list */ - pmsgHwpvt->next = pparmBlock->pmsgHwpvt; - pparmBlock->pmsgHwpvt = pmsgHwpvt; - - pmsgHwpvt->tmoVal = 0; - pmsgHwpvt->tmoCount = 0; - - genHParms.pparmBlock = pparmBlock; - genHParms.plink = plink; - genHParms.pmsgHwpvt = pmsgHwpvt; - - if ((*(pparmBlock->pdrvBlock->drvIoctl))(MSGIOCTL_GENHWPVT, &genHParms) == ERROR) - { - /* Free up the hardware private structure and clean up */ - /* It is still first on the list, so don't have to look for it */ - return(NULL); - } - - return(pmsgHwpvt); -} - -/****************************************************************************** - * - * Generate a message queue link structure and start a task to manage it. - * This is called by pparmBlock->pdrvBlock->drvIoctl(MSGIOCTL_GENHWPVT) when - * it finds that a specific link structure is not present that is needed when - * initializing a hardware private structure. - * - ******************************************************************************/ -msgLink * -drvMsg_genLink(pparmBlock, plink) -msgParmBlock *pparmBlock; -struct link *plink; /* I/O link structure from record */ -{ - msgDrvGenLParm genlParms; - msgLink *pmsgLink; - char name[20]; - long status; - int j; - int taskId; - - if (msgDebug) - printf("In drvMsg_genLink\n"); - - /* Allocate and fill in the msg specific part */ - if ((pmsgLink = malloc(sizeof(msgLink))) == NULL) - return(NULL); - - /* init all the prioritized transaction queues */ - for(j=0; jqueue[j].head = NULL; - pmsgLink->queue[j].tail = NULL; - FASTLOCKINIT(&(pmsgLink->queue[j].lock)); - } - pmsgLink->linkEventSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - - genlParms.pmsgLink = pmsgLink; - genlParms.plink = plink; - genlParms.op = MSG_GENLINK_CREATE; - genlParms.pparmBlock = pparmBlock; - - /* do the driver-specific init */ - if ((*(pparmBlock->pdrvBlock->drvIoctl))(MSGIOCTL_GENLINK, &genlParms) == ERROR) - { - /* free the pmsgLink structure and clean up */ - return(NULL); - } - sprintf(name, "%s", pparmBlock->pdrvBlock->taskName); - if ((taskId = taskSpawn( - name, pparmBlock->pdrvBlock->taskPri, pparmBlock->pdrvBlock->taskOpt, - pparmBlock->pdrvBlock->taskStack, msgTask, pparmBlock->pdrvBlock, - pmsgLink, - 0,0,0,0,0,0,0,0)) == ERROR) { - printf("Message driver: Failed to start link task %s\n", name); -/* BUG --delete the FASTLOCK in here */ - status = ERROR; - } else { - taskwdInsert(taskId,NULL,NULL); - status = OK; - } - - if (status == ERROR) - { - genlParms.op = MSG_GENLINK_ABORT; - - (*(pparmBlock->pdrvBlock->drvIoctl))(MSGIOCTL_GENLINK, &genlParms); - free(pmsgLink); - return(NULL); - } - return(pmsgLink); -} - -/****************************************************************************** - * - * Check to verify that a given parameter number is within range for the - * given device type. - * - ******************************************************************************/ -long -drvMsg_checkParm(prec, recTyp) -struct dbCommon *prec; -char *recTyp; -{ - unsigned int parm; - char message[100]; - - if (prec->dpvt != NULL) - { - parm = ((msgXact *)(prec->dpvt))->parm; - if ((((msgXact *)(prec->dpvt))->pparmBlock->pcmds)[parm].recTyp != ((struct msgDset *)(prec->dset))->precEnum) - { - sprintf(message, "Message driver-checkParm: %s parm number %d not valid for %s record type\n", prec->name, parm, recTyp); - errMessage(S_db_badField, message); - prec->pact = TRUE; - return(S_db_badField); - } - return(0); - } - return(S_db_badField); -} - -/****************************************************************************** - * - * Callback function used to complete async-record processing. - * - ******************************************************************************/ -static void -drvMsg_callbackFunc(pcallback) -CALLBACK *pcallback; -{ - dbScanLock(((msgXact *)(pcallback->user))->prec); - (*(struct rset *)(((msgXact *)(pcallback->user))->prec->rset)).process(((msgXact *)(pcallback->user))->prec); - dbScanUnlock(((msgXact *)(pcallback->user))->prec); -} - -/****************************************************************************** - * - * Function used to initialize the callback structure within the transaction - * structure. This sets it up so that it is used to perform the completion - * phase of the async record processing. - * - ******************************************************************************/ -long -drvMsg_initCallback(prec) -struct dbCommon *prec; -{ - ((msgXact *)(prec->dpvt))->callback.callback = drvMsg_callbackFunc; - /* ((msgXact *)(prec->dpvt))->callback.priority = prec->prio; */ - ((msgXact *)(prec->dpvt))->callback.user = (void *)(prec->dpvt); - - return(OK); -} - -/****************************************************************************** - * - * Queue a transaction for the link task. - * - ******************************************************************************/ -long -drvMsg_qXact(xact, prio) -msgXact *xact; -int prio; -{ - msgLink *pmsgLink = xact->phwpvt->pmsgLink; - - /* The link verification is done at record-init time & not needed here. */ - - if ((prio < 0) || (prio >= NUM_CALLBACK_PRIORITIES)) - { - xact->status = XACT_BADPRIO; - return(ERROR); - } - - xact->callback.priority = prio; /* Callback processing priority */ - - FASTLOCK(&(pmsgLink->queue[prio].lock)); - drvMsg_xactListAddTail(&(pmsgLink->queue[prio]), xact); - FASTUNLOCK(&(pmsgLink->queue[prio].lock)); - semGive(pmsgLink->linkEventSem); - - return(OK); -} - -/****************************************************************************** - * - * Message-driver link-task. - * - * This function is spawned as a task during iocInit(). It waits on a semaphore - * that is given when either a message (transaction) is queued for a device - * associated with the link, or an event of some kind was detected from a device - * associated with the link. - * - * When the task wakes up, it checks to see if it was due to an event. If so, - * the support function that identified the event will also specify a - * transaction structure to process. If no event occurred, then the - * transaction request queues are checked. - * - * If a transaction was found, either due to an event or the work queues, it - * is processed. Processing a transaction consists of two optional phases. - * These phases are called the write and read phases, but either of them - * may do either writing, reading, or nothing. In the typical case, the - * first phase will do some writing (either setting a condition or soliciting a - * response) and the second phase will do some reading (reading back a solicited - * response) or nothing (in cases where no response will be generated to some - * write command.) - * - ******************************************************************************/ -static int msgTask(pdrvBlock, pmsgLink) -msgDrvBlock *pdrvBlock; -msgLink *pmsgLink; -{ - int working; - int prio; - msgXact *xact; - int event; - msgCmd *pmsgCmd; - msgChkEParm checkEventParms; - - if (msgDebug) - printf("Message driver link task %s started\n", pdrvBlock->taskName); - - checkEventParms.pdrvBlock = pdrvBlock; - checkEventParms.pmsgLink = pmsgLink; - checkEventParms.pxact = &xact; - - working = 1; /* Force a first time check on events and xact queues */ - - while (1) - { - if (!working) - semTake(pmsgLink->linkEventSem, WAIT_FOREVER); - - working = 0; - xact = NULL; - - /* Check to see if we woke up because of a device event */ - event = (*(pdrvBlock->drvIoctl))(MSGIOCTL_CHECKEVENT, &checkEventParms); - - if (event == MSG_EVENT_NONE) - { /* No device events pending, check the request queues for work */ - prio = 0; - while ((xact == NULL) && prio < NUM_CALLBACK_PRIORITIES) - { - FASTLOCK(&(pmsgLink->queue[prio].lock)); - if ((xact = pmsgLink->queue[prio].head) != NULL) - { - drvMsg_xactListDel(&(pmsgLink->queue[prio]), xact); - FASTUNLOCK(&(pmsgLink->queue[prio].lock)); - } - else - FASTUNLOCK(&(pmsgLink->queue[prio].lock)); - - prio++; - } - } - if (xact != NULL) - { - working = 1; - xact->status = XACT_OK; /* All well, so far */ - pmsgCmd = &(xact->pparmBlock->pcmds[xact->parm]); - - if ((pmsgCmd->writeOp.op != MSG_OP_NOP) && ((event == MSG_EVENT_NONE)||(event & MSG_EVENT_WRITE))) - { /* Perform the write portion of a transaction operation */ - (*(xact->pparmBlock->doOp))(xact, &(pmsgCmd->writeOp)); - } - - if ((xact->status == XACT_OK) && (pmsgCmd->readOp.op != MSG_OP_NOP)) - { /* There is a read opertaion spec'd, check to see if I can do it now */ - if (((pmsgCmd->flags & READ_DEFER) == 0)||(event & MSG_EVENT_READ)) - { /* Not a deferred readback parm -or- it is and is time to read */ - (*(xact->pparmBlock->doOp))(xact, &(pmsgCmd->readOp)); - - if (xact->callback.callback != NULL) - callbackRequest(xact); - - if (xact->psyncSem != NULL) - semGive(*(xact->psyncSem)); - } - /* else -- is a defered readback, must wait for readback event */ - } - else - { /* There is no read operation specified, finish the xact opetation */ - if (xact->callback.callback != NULL) - callbackRequest(xact); - - if (xact->psyncSem != NULL) - semGive(*(xact->psyncSem)); - } - } - } -} - -/****************************************************************************** - * - * These functions encapsulates the calls made to the device-specific read and - * write functions. The idea here is that we can monitor and/or buffer I/O - * operations from here. - * - * At the moment, this is used to do cehcks on the read-cache's time-to-live. - * - ******************************************************************************/ -long -drvMsg_drvWrite(pxact, pparm) -msgXact *pxact; -msgStrParm *pparm; -{ - return(pxact->pparmBlock->pdrvBlock->drvWrite(pxact, pparm)); -} - -/****************************************************************************** - * - ******************************************************************************/ -long -drvMsg_drvRead(pxact, pparm) -msgXact *pxact; -msgStrParm *pparm; -{ - return((*(pxact->pparmBlock->pdrvBlock->drvRead))(pxact, pparm)); -} - -/****************************************************************************** - * - * This function is called to handle the processing of a transaction. - * The idea here is that xact->pparmBlock->doOp could point to this - * function if there are not any custom operations, or to it's own - * function that could check to see if the operation is local/custom and - * then call this if it is not. - * - ******************************************************************************/ -long -drvMsg_xactWork(pxact, pop) -msgXact *pxact; -msgCmdOp *pop; -{ - if ((pop->op > 0) && (pop->op < NUM_VALID_OPS)) - return((*(msgSupFun[pop->op]))(pxact, pop->p)); - - printf("drvMsg_xactWork: Invalid operation code %d encountered\n", pop->op); - pxact->status = XACT_BADCMD; - return(XACT_BADCMD); -} - -/****************************************************************************** - * - * Write a string to the device w/o any formatting. - * - ******************************************************************************/ -static long -drvMsg_write(pxact, pparm) -msgXact *pxact; -msgStrParm *pparm; -{ - return(drvMsg_drvWrite(pxact, pparm)); -} - -/****************************************************************************** - * - * Read a string and see if it contains the substring provided in the - * msgAkParm structure. This is useful to check the ack string from a - * device because it will cause the record to go into a INVALID alarm - * state if the ACK does not match the provided string. - * - * If the provided substring is a zero-length string, it will match - * any possible ACK string. - * - ******************************************************************************/ -static long -drvMsg_CheckAck(pxact, packParm) -msgXact *pxact; -msgAkParm *packParm; -{ - msgStrParm strParm; -/* BUG -- the buffer size will have to be configurable */ - char buf[100]; - char *ach; - char *rch; - - strParm.buf = buf; - strParm.len = packParm->len; - - drvMsg_drvRead(pxact, &strParm); - if (msgDebug > 5) - printf("drvMsg_CheckAck comparing >%s< at %d against >%s<\n", buf, packParm->index, packParm->str); - - if (pxact->status == XACT_OK) - { - ach = &(packParm->str[packParm->index]); - rch = buf; - while (*ach != '\0') - { - if (*ach != *rch) - { - *ach = '\0'; /* stop the while loop */ - pxact->status = XACT_IOERR; - } - else - { - ach++; - rch++; - } - } - } - return(pxact->status); -} - -/****************************************************************************** - * - * Read a string and use the format string to extract the value field - * - ******************************************************************************/ -static long -drvMsg_AiFmt(pxact, pfiParm) -msgXact *pxact; -msgFiParm *pfiParm; -{ - msgStrParm strParm; -/* BUG -- some how the buffer length will have to be made configurable */ - char buf[100]; - - strParm.buf = buf; - strParm.len = pfiParm->len; - - drvMsg_drvRead(pxact, &strParm); - - if (pxact->status == XACT_OK) - { - if (sscanf(buf, &(pfiParm->format[pfiParm->startLoc]), &(((struct aiRecord *)(pxact->prec))->val)) != 1) - pxact->status = XACT_IOERR; - } - return(pxact->status); -} - -/****************************************************************************** - * - * Read a string and use the format string to extract the value field - * - * NOTE: The rval is filled in for the BI record so that conversion may - * take place in record support. - * - ******************************************************************************/ -static long -drvMsg_BiFmt(pxact, pfiParm) -msgXact *pxact; -msgFiParm *pfiParm; -{ - msgStrParm strParm; -/* BUG -- some how the buffer length will have to be made configurable */ - char buf[100]; - - strParm.buf = buf; - strParm.len = pfiParm->len; - - drvMsg_drvRead(pxact, &strParm); - - if (pxact->status == XACT_OK) - { - if (sscanf(buf, &(pfiParm->format[pfiParm->startLoc]), &(((struct biRecord *)(pxact->prec))->rval)) != 1) - pxact->status = XACT_IOERR; - } - return(pxact->status); -} - -/****************************************************************************** - * - * Read a string and use the format string to extract the value field - * - * NOTE: The rval is filled in for the MBBI record so that conversion may - * take place in record support. - * - ******************************************************************************/ -static long -drvMsg_MiFmt(pxact, pfiParm) -msgXact *pxact; -msgFiParm *pfiParm; -{ - msgStrParm strParm; -/* BUG -- some how the buffer length will have to be made configurable */ - char buf[100]; - - strParm.buf = buf; - strParm.len = pfiParm->len; - - drvMsg_drvRead(pxact, &strParm); - - if (pxact->status == XACT_OK) - { - if (sscanf(buf, &(pfiParm->format[pfiParm->startLoc]), &(((struct mbbiRecord *)(pxact->prec))->rval)) != 1) - pxact->status = XACT_IOERR; - } - return(pxact->status); -} - -/****************************************************************************** - * - * Read a string and use the format string to extract the value field - * - ******************************************************************************/ -static long -drvMsg_LiFmt(pxact, pfiParm) -msgXact *pxact; -msgFiParm *pfiParm; -{ - msgStrParm strParm; -/* BUG -- some how the buffer length will have to be made configurable */ - char buf[100]; - - strParm.buf = buf; - strParm.len = pfiParm->len; - - drvMsg_drvRead(pxact, &strParm); - - if (pxact->status == XACT_OK) - { - if (sscanf(buf, &(pfiParm->format[pfiParm->startLoc]), &(((struct longinRecord *)(pxact->prec))->val)) != 1) - pxact->status = XACT_IOERR; - } - return(pxact->status); -} - -/****************************************************************************** - * - * Read a string and use the format string to extract the value field - * - ******************************************************************************/ -static long -drvMsg_SiFmt(pxact, pfiParm) -msgXact *pxact; -msgFiParm *pfiParm; -{ - msgStrParm strParm; -/* BUG -- some how the buffer length will have to be made configurable */ - char buf[100]; - - strParm.buf = buf; - strParm.len = pfiParm->len; - - drvMsg_drvRead(pxact, &strParm); - - if (pxact->status == XACT_OK) - { - if (sscanf(buf, &(pfiParm->format[pfiParm->startLoc]), (((struct stringinRecord *)(pxact->prec))->val)) != 1) - pxact->status = XACT_IOERR; - } - return(pxact->status); -} - -/****************************************************************************** - * - * Read a string - * - ******************************************************************************/ -static long -drvMsg_SiRaw(pxact, parm) -msgXact *pxact; -void *parm; -{ - msgStrParm strParm; - - strParm.buf = ((struct stringinRecord *)(pxact->prec))->val; - strParm.len = sizeof(((struct stringinRecord *)(pxact->prec))->val); - - drvMsg_drvRead(pxact, &strParm); - - return(pxact->status); -} - -/****************************************************************************** - * - * This function is used to write a string that includes the VAL field of an - * analog output record, to an RS-232 device. - * - ******************************************************************************/ -static long -drvMsg_AoFmt(pxact, pfoParm) -msgXact *pxact; -msgFoParm *pfoParm; -{ - msgStrParm wrParm; -/* BUG -- some how the buffer length will have to be made configurable */ - char buf[100]; - - wrParm.buf = buf; - - sprintf(buf, pfoParm->format, ((struct aoRecord *)(pxact->prec))->val); - wrParm.len = -1; /* write until reach NULL character */ - - drvMsg_drvWrite(pxact, &wrParm); - return(pxact->status); -} - -static long -drvMsg_BoFmt(pxact, pfoParm) -msgXact *pxact; -msgFoParm *pfoParm; -{ - msgStrParm wrParm; - char buf[100]; - - wrParm.buf = buf; - - sprintf(buf, pfoParm->format, ((struct boRecord *)(pxact->prec))->val); - wrParm.len = -1; /* write until reach NULL character */ - - drvMsg_drvWrite(pxact, &wrParm); - return(pxact->status); -} - -/****************************************************************************** - * - * NOTE: The formatting of the MBBO value uses the RVAL field so that the - * conversion from VAL to RVAL in the record (the movement of one of the - * onvl, twvl,... fields to the rval field during record processing.) - * - ******************************************************************************/ -static long -drvMsg_MoFmt(pxact, pfoParm) -msgXact *pxact; -msgFoParm *pfoParm; -{ - msgStrParm wrParm; - char buf[100]; - - wrParm.buf = buf; - - sprintf(buf, pfoParm->format, ((struct mbboRecord *)(pxact->prec))->rval); - wrParm.len = -1; /* write until reach NULL character */ - - drvMsg_drvWrite(pxact, &wrParm); - return(pxact->status); -} - -static long -drvMsg_LoFmt(pxact, pfoParm) -msgXact *pxact; -msgFoParm *pfoParm; -{ - msgStrParm wrParm; - char buf[100]; - - wrParm.buf = buf; - - sprintf(buf, pfoParm->format, ((struct longoutRecord *)(pxact->prec))->val); - wrParm.len = -1; /* write until reach NULL character */ - - drvMsg_drvWrite(pxact, &wrParm); - return(pxact->status); -} - -static long -drvMsg_SoFmt(pxact, pfoParm) -msgXact *pxact; -msgFoParm *pfoParm; -{ - msgStrParm wrParm; - char buf[100]; - - wrParm.buf = buf; - - sprintf(buf, pfoParm->format, ((struct stringoutRecord *)(pxact->prec))->val); - wrParm.len = -1; /* write until reach NULL character */ - - drvMsg_drvWrite(pxact, &wrParm); - return(pxact->status); -} - -static long -drvMsg_SoRaw(pxact, parm) -msgXact *pxact; -void *parm; -{ - msgStrParm wrParm; - - wrParm.buf = ((struct stringoutRecord *)(pxact->prec))->val; - wrParm.len = -1; /* write until reach NULL character */ - - drvMsg_drvWrite(pxact, &wrParm); - return(pxact->status); -} - -/****************************************************************************** - * - * The following functions are called from record support. - * They are used to initialize a record's DPVT (xact structure) for - * processing by the message driver later when the record is processed. - * - ******************************************************************************/ -/****************************************************************************** - * - * Init record routine for AI - * - ******************************************************************************/ -long -drvMsg_initAi(pai) -struct aiRecord *pai; -{ - long status; - - pai->dpvt = drvMsg_genXact(((struct msgDset *)(pai->dset))->pparmBlock, &(pai->inp), pai); - - if (pai->dpvt != NULL) - { - status = drvMsg_checkParm(pai, "AI"); - if (status == 0) - drvMsg_initCallback(pai); /* Init for async record completion callback */ - else - pai->pact = 1; /* mark so is never scanned */ - - return(status); - } - pai->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} -/****************************************************************************** - * - * Init record routine for AO - * - ******************************************************************************/ -long -drvMsg_initAo(pao) -struct aoRecord *pao; -{ - long status; - - pao->dpvt = drvMsg_genXact(((struct msgDset *)(pao->dset))->pparmBlock, &(pao->out), pao); - - if (pao->dpvt != NULL) - { - status = drvMsg_checkParm(pao, "AO"); - if (status == 0) - { - drvMsg_initCallback(pao); /* Init for async record completion callback */ - return(2); /* Don't convert RVAL to VAL at this time */ - } - else - pao->pact = 1; /* mark so is never scanned */ - - return(status); - } - pao->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} - -/****************************************************************************** - * - * init record routine for BI - * - ******************************************************************************/ -long -drvMsg_initBi(pbi) -struct biRecord *pbi; -{ - long status; - - pbi->dpvt = drvMsg_genXact(((struct msgDset *)(pbi->dset))->pparmBlock, &(pbi->inp), pbi); - - if (pbi->dpvt != NULL) - { - status = drvMsg_checkParm(pbi, "BI"); - if (status == 0) - drvMsg_initCallback(pbi); /* Init for async record completion callback */ - else - pbi->pact = 1; /* mark so is never scanned */ - - return(status); - } - pbi->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} -/****************************************************************************** - * - * Init record routine for BO - * - ******************************************************************************/ -long -drvMsg_initBo(pbo) -struct boRecord *pbo; -{ - long status; - - pbo->dpvt = drvMsg_genXact(((struct msgDset *)(pbo->dset))->pparmBlock, &(pbo->out), pbo); - - if (pbo->dpvt != NULL) - { - status = drvMsg_checkParm(pbo, "BO"); - if (status == 0) - { - drvMsg_initCallback(pbo); /* Init for async record completion callback */ - return(2); /* Don't convert RVAL to VAL at this time */ - } - else - pbo->pact = 1; /* mark so is never scanned */ - - return(status); - } - pbo->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} - -/****************************************************************************** - * - * init record routine for MI - * - ******************************************************************************/ -long -drvMsg_initMi(pmi) -struct mbbiRecord *pmi; -{ - long status; - - pmi->dpvt = drvMsg_genXact(((struct msgDset *)(pmi->dset))->pparmBlock, &(pmi->inp), pmi); - - if (pmi->dpvt != NULL) - { - status = drvMsg_checkParm(pmi, "MBBI"); - if (status == 0) - drvMsg_initCallback(pmi); /* Init for async record completion callback */ - else - pmi->pact = 1; /* mark so is never scanned */ - - return(status); - } - pmi->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} -/****************************************************************************** - * - * Init record routine for MO - * - ******************************************************************************/ -long -drvMsg_initMo(pmo) -struct mbboRecord *pmo; -{ - long status; - - pmo->dpvt = drvMsg_genXact(((struct msgDset *)(pmo->dset))->pparmBlock, &(pmo->out), pmo); - - if (pmo->dpvt != NULL) - { - status = drvMsg_checkParm(pmo, "MBBO"); - if (status == 0) - { - drvMsg_initCallback(pmo); /* Init for async record completion callback */ - return(2); /* Don't convert RVAL to VAL at this time */ - } - else - pmo->pact = 1; /* mark so is never scanned */ - - return(status); - } - pmo->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} - -/****************************************************************************** - * - * init record routine for LI - * - ******************************************************************************/ -long -drvMsg_initLi(pli) -struct longinRecord *pli; -{ - long status; - - pli->dpvt = drvMsg_genXact(((struct msgDset *)(pli->dset))->pparmBlock, &(pli->inp), pli); - - if (pli->dpvt != NULL) - { - status = drvMsg_checkParm(pli, "LI"); - if (status == 0) - drvMsg_initCallback(pli); /* Init for async record completion callback */ - else - pli->pact = 1; /* mark so is never scanned */ - - return(status); - } - pli->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} -/****************************************************************************** - * - * init record routine for LO - * - ******************************************************************************/ -long -drvMsg_initLo(plo) -struct longoutRecord *plo; -{ - long status; - - plo->dpvt = drvMsg_genXact(((struct msgDset *)(plo->dset))->pparmBlock, &(plo->out), plo); - - if (plo->dpvt != NULL) - { - status = drvMsg_checkParm(plo, "LO"); - if (status == 0) - drvMsg_initCallback(plo); /* Init for async record completion callback */ - else - plo->pact = 1; /* mark so is never scanned */ - - return(status); - } - plo->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} - -/****************************************************************************** - * - * init record routine for SI - * - ******************************************************************************/ -long -drvMsg_initSi(psi) -struct stringinRecord *psi; -{ - long status; - - psi->dpvt = drvMsg_genXact(((struct msgDset *)(psi->dset))->pparmBlock, &(psi->inp), psi); - - if (psi->dpvt != NULL) - { - status = drvMsg_checkParm(psi, "SI"); - if (status == 0) - drvMsg_initCallback(psi); /* Init for async record completion callback */ - else - psi->pact = 1; /* mark so is never scanned */ - - return(status); - } - psi->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} -/****************************************************************************** - * - * init record routine for SO - * - ******************************************************************************/ -long -drvMsg_initSo(pso) -struct stringoutRecord *pso; -{ - long status; - - pso->dpvt = drvMsg_genXact(((struct msgDset *)(pso->dset))->pparmBlock, &(pso->out), pso); - - if (pso->dpvt != NULL) - { - status = drvMsg_checkParm(pso, "SI"); - if (status == 0) - drvMsg_initCallback(pso); /* Init for async record completion callback */ - else - pso->pact = 1; /* mark so is never scanned */ - - return(status); - } - pso->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} - -/****************************************************************************** - * - * init record routine for WF - * - ******************************************************************************/ -long -drvMsg_initWf(pwf) -struct waveformRecord *pwf; -{ - long status; - - pwf->dpvt = drvMsg_genXact(((struct msgDset *)(pwf->dset))->pparmBlock, &(pwf->inp), pwf); - - if (pwf->dpvt != NULL) - { - status = drvMsg_checkParm(pwf, "WAVEFORM"); - if (status == 0) - drvMsg_initCallback(pwf); /* Init for async record completion callback */ - else - pwf->pact = 1; /* mark so is never scanned */ - - return(status); - } - pwf->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} - -/****************************************************************************** - * - * These functions are called by record support. - * - * Service routines to process a input records. - * - ******************************************************************************/ -long -drvMsg_procAi(pai) -struct aiRecord *pai; -{ - return(drvMsg_proc(pai, 2)); /* no conversion */ -} -long -drvMsg_procBi(pbi) -struct biRecord *pbi; -{ - return(drvMsg_proc(pbi, 0)); /* convert RVAL to VAL */ -} -long -drvMsg_procMi(pmi) -struct mbbiRecord *pmi; -{ - return(drvMsg_proc(pmi, 0)); /* convert RVAL to VAL */ -} -long -drvMsg_procLi(pli) -struct longinRecord *pli; -{ - return(drvMsg_proc(pli, 2)); /* no conversion */ -} -long -drvMsg_procSi(psi) -struct stringinRecord *psi; -{ - return(drvMsg_proc(psi, 2)); /* no conversion */ -} -long -drvMsg_procWf(pwf) -struct waveformRecord *pwf; -{ - return(drvMsg_proc(pwf, 2)); /* no conversion */ -} - -/****************************************************************************** - * - * These functions are called by record support. - * - * Service routine to process output records. - * - * It does not make sense to return a conversion code to record support from - * processing an output record. - * - ******************************************************************************/ -long -drvMsg_procAo(pao) -struct aoRecord *pao; -{ - return(drvMsg_proc(pao, 0)); -} -long -drvMsg_procBo(pbo) -struct boRecord *pbo; -{ - return(drvMsg_proc(pbo, 0)); -} -long -drvMsg_procMo(pmo) -struct mbboRecord *pmo; -{ - return(drvMsg_proc(pmo, 0)); -} -long -drvMsg_procLo(plo) -struct longoutRecord *plo; -{ - return(drvMsg_proc(plo, 0)); -} -long -drvMsg_procSo(pso) -struct stringoutRecord *pso; -{ - return(drvMsg_proc(pso, 0)); -} - -/****************************************************************************** - * - * Generic service routine to process a record. - * - ******************************************************************************/ - -/* - * BUG -- I should probably figure out the return code from the conversion - * routine. Not from a hard-coded value passed in from above. - */ - -long -drvMsg_proc(prec, ret) -struct dbCommon *prec; /* record to process */ -int ret; /* If all goes well, return this value */ -{ - if (prec->pact) /* if already actively processing, finish up */ - { - if (((msgXact *)(prec->dpvt))->status != XACT_OK) - { /* something went wrong during I/O processing */ - if (msgDebug) - printf("Setting an alarm on record %s\n", prec->name); - - recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); - } - else - if (ret == 2) - prec->udf = FALSE; /* Set only if I return 2 (I filled in VAL) */ - - return(ret); - } - /* Not already actively processing, start things going */ - - prec->pact = TRUE; - if (drvMsg_qXact(prec->dpvt, prec->prio) == ERROR) - printf("Error during drvMsg_qXact\n"); - - return(ret); -} diff --git a/src/drv/old/drvMsg.h b/src/drv/old/drvMsg.h deleted file mode 100644 index c2c66a69b..000000000 --- a/src/drv/old/drvMsg.h +++ /dev/null @@ -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 diff --git a/src/drv/old/drvOms.c b/src/drv/old/drvOms.c deleted file mode 100644 index 2910e1e67..000000000 --- a/src/drv/old/drvOms.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include /* library for ring buffer support */ -#include -#include /* library to support sysBusToLocalAdrs. */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#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; - } - } - -} diff --git a/src/drv/old/drvOms.h b/src/drv/old/drvOms.h deleted file mode 100644 index 065074afa..000000000 --- a/src/drv/old/drvOms.h +++ /dev/null @@ -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 */ - diff --git a/src/drv/old/drvRs232.c b/src/drv/old/drvRs232.c deleted file mode 100644 index 831b22282..000000000 --- a/src/drv/old/drvRs232.c +++ /dev/null @@ -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 -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -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 -}; diff --git a/src/drv/old/drvRs232.h b/src/drv/old/drvRs232.h deleted file mode 100644 index 14b75deb0..000000000 --- a/src/drv/old/drvRs232.h +++ /dev/null @@ -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 diff --git a/src/drv/old/drvTy232.h b/src/drv/old/drvTy232.h deleted file mode 100644 index 6b5a46527..000000000 --- a/src/drv/old/drvTy232.h +++ /dev/null @@ -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 diff --git a/src/drv/old/drvVmi4100.c b/src/drv/old/drvVmi4100.c deleted file mode 100644 index 2ba6c2dc2..000000000 --- a/src/drv/old/drvVmi4100.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#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; - } - diff --git a/src/drv/old/drvXy010.c b/src/drv/old/drvXy010.c deleted file mode 100644 index 48232f8fd..000000000 --- a/src/drv/old/drvXy010.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include - -#include -#include - - -/* - * 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; -} - - diff --git a/src/drv/old/drvXy210.c b/src/drv/old/drvXy210.c deleted file mode 100644 index 1b9b16d17..000000000 --- a/src/drv/old/drvXy210.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include - -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 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); - } - } -} diff --git a/src/drv/old/drvXy220.c b/src/drv/old/drvXy220.c deleted file mode 100644 index 0b6537fe2..000000000 --- a/src/drv/old/drvXy220.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include "module_types.h" -#include - -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<high_value << 16) /* high */ - + pbo_xy220s[card]->low_value; /* low */ - printf("BO: XY220: card %d value=0x%8.8x\n",card,value); - } - } - - } diff --git a/src/drv/old/drvXy240.c b/src/drv/old/drvXy240.c deleted file mode 100644 index e46838089..000000000 --- a/src/drv/old/drvXy240.c +++ /dev/null @@ -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 -#include -#include -#include - -#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<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); - } - } -} - diff --git a/src/drv/old/drvXy566.c b/src/drv/old/drvXy566.c deleted file mode 100644 index b67e8d2ac..000000000 --- a/src/drv/old/drvXy566.c +++ /dev/null @@ -1,1149 +0,0 @@ -/* base/src/drv $Id$ */ -/* drvXy566.c - Driver Support Routines for xy566 - * - * 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: - * ----------------- - * .00 09-14-88 lrd check for IGEN card present before initing - * .01 9-27-88 lrd removed test code - * .02 09-27-88 lrd removed call to xy_mem_init - * .03 10-04-88 lrd remove IGEN support - * .04 10-07-88 lrd add support for the Xycom 085 arm mechanism - * added external latched AI and made - * others scan continuously - * .05 11-10-88 lrd change addresses per HW Tech Note #2 - * .06 02-08-89 lrd moved module addresses into a table in - * module_types.h from ai_driver.h - * .07 02-24-89 lrd modify for vxWorks 4.0 - * changed sysSetBCL to sysIntEnable - * .08 04-17-89 lrd add callback mechanism for data take complete - * .09 05-10-89 lrd increased performance for xycom 566 interface - * by keeping the address of the memory buffers - * thus removing the need to calculate on each - * read - * .10 07-27-89 lrd modified to use channel 0 not channel 1 - * .11 11-20-89 joh added call to the at5vxi ai driver - * .12 02-15-90 lrd modified for new 085 card - * 02/04/91 ges Change taskDelay from 6 to 2 in - * "xy566DoneTask". Allows rearm and data reads - * for successive waveform scans up thru - * 10 Hz rates. - * .13 08-27-91 bg broke the 566 driver out of ai_driver.c - * and moved it to this file. Moved io_report code - * to this file. - * added arguments and raw value read out - * for analog in cards. - * .14 10/30/91 bg Combined the xy566 waveform driver with the - * xy566 analog in drivers. Changed addressing to - * use sysBusToLocalAddrs and VME_AM_STD_SUP or - * VME_AM_SUP_SHORT_IO - * .15 11-30-91 bg Added sysBusToLocalAdrs to both ai and - * waveform sections. - * .16 02-05-92 bg Changed io_report so it has an argument - * level and so if the level > 1, the raw - * value from the card will be printed out - * for analog ins only. - * .17 03/20/92 bg Added the argument level to io_report, - * but so far it doesn't do anything. Will - * add ability to report ability to read out - * raw value if there is a demand. - * .18 08-10-92 joh cleaned up the merge of the xy566 wf and ai - * drivers - * .19 08-25-92 mrk replaced call to ai_driver by ai_xy566_driver - * .20 08-26-92 mrk support epics I/O event scan - * .21 08-27-92 joh fixed routines which return with and without - * status - * .22 08-27-92 joh fixed nonexsistant EPICS init - * .23 08-02-93 mrk Added call to taskwdInsert - * .24 08-04-93 mgb Removed V5/V4 and EPICS_V2 conditionals - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static char SccsId[] = "@(#)drvXy566.c 1.14\t8/4/93 "; - -/* - * Code Portions - * - * xy566DoneTask Task to handle data take completion for the 566 waveform - * xy566_init Initializes the 566 waveform cards - * senb/senw Writes to the 566 where the call provides a req'd delay - */ - -/* If any of the following does not exist replace it with #define <> NULL */ - - -static long report(); -static long init(); - -#if 0 -static long xy566_io_report(); -static long ai_566_init(); -#endif - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvXy566={ - 2, - report, - init}; - -static long init() -{ - ai_566_init(); - xy566_init(); - return(0); -} - -static long report() -{ - ai_xy566_io_report(); - xy566_io_report(); - return(0); -} - -#define MAX_SE_CARDS (ai_num_cards[XY566SE]) -#define MAX_DI_CARDS (ai_num_cards[XY566DI]) -#define MAX_DIL_CARDS (ai_num_cards[XY566DIL]) - -#define XY566_MEM_INCR 0x10000 /* size of data memory area */ - -/* memory structure of the 566 interface */ -struct ai566 { /* struct XVME 566 */ - char dum[0x80]; /* odd bytes 1 - 3f contain - module identification */ - unsigned short a566_csr; /* control status register */ - unsigned char soft_start; /* software start register */ - unsigned char int_vect; /* interrupt vector register */ - unsigned short dram_ptr; /* pointer to data ram */ - char dum1; /* unused */ - unsigned char sram_ptr; /* sequence ram pointer */ - char dum2[0xc0 - 0x88]; - unsigned short stc_data; /* timing chip data port */ - unsigned short stc_control; /* timing chip control port */ - char dum3[0x101 - 0xc4]; - unsigned char gram_base; /* base of gain ram 101,103 to 13f */ - char dum5[0x201 - 0x102]; - unsigned char sram_base; /* base of sequence ram 210,203 to 3ff */ - char dum6[0x3ff -0x202]; - unsigned char card_number; /* logical card number */ -}; - -/* memory structure of the 566 interface */ -struct wf085 { /* struct XVME 566 */ - char dum[0x80]; /* odd bytes 1 - 3f contain - module identification */ - unsigned short csr; /* control status register */ - unsigned char soft_start; /* software start register */ - unsigned char int_vect; /* interrupt vector register */ - unsigned short dram_ptr; /* pointer to data ram */ - char dum1; /* unused */ - unsigned char sram_ptr; /* sequence ram pointer */ - char dum2[0xc0 - 0x88]; - unsigned short stc_data; /* timing chip data port */ - unsigned short stc_control; /* timing chip control port */ - char dum3[0x101 - 0xc4]; - unsigned char gram_base; /* base of gain ram 101,103,.. - ... to 13f */ - char dum5[0x201 - 0x102]; - unsigned char sram_base; /* base of sequence ram 210,203, - ... to 3ff */ - char dum6[0x400 -0x202]; -}; - -/* arrays which keep track of which cards are found at initialization */ -struct ai566 **pai_xy566se; -struct ai566 **pai_xy566di; -struct ai566 **pai_xy566dil; -unsigned short **pai_xy566se_mem; -unsigned short **pai_xy566di_mem; -unsigned short **pai_xy566dil_mem; -static IOSCANPVT *paioscanpvt; - - -/* reset the counter interrupt 0x8000 */ -/* reset the sequence interrupt 0x2000 */ -/* enable the sequence interrupt 0x1000 */ -/* reset the trigger clock interrupt 0x0800 */ -/* enable the sequence controller 0x0100 */ -/* read values into first 32 words on each read 0x0040 */ -/* read in sequential mode (bit 0x0020 == 0) 0x0000 */ -/* interrupt enable 0x0008 */ -/* leds green-on red-off 0x0003 */ - -#define XY566L_CSR 0xb94b -#define XY566_INT_LEVEL 6 - - -/* max card and channel definitions move to module types.h */ -#define MAX_WF_XY_CARDS (wf_num_cards[XY566WF]) - -/* card interface */ -#define WF_XY566_BASE (wf_addrs[XY566WF]) /* XYCOM 566 waveform */ -#define WF_XY085_BASE (wf_armaddrs[XY566WF]) /* XYCOM 085 arm */ - -/* Data RAM area into which the 566 stores the latched data */ -/* This needs to be different for each type of IO card */ -#define WF_XY566_MEMBASE ((unsigned short *)0x1080000) - -/* figure out what these are */ -#define WF566_MEM_INCR 0x10000 /* 65535 bytes per waveform */ -#define WF566_VNUM 0xf1 /* this is currently incorrect */ - - -#define WF_READ 0x00 /* read a waveform */ -#define WF_ARM 0x01 /* arm a waveform */ -#define WF_LATCH 0x02 /* latch a waveform */ -#define WF_SETUP 0x03 /* set up a waveform */ - -/* xycom 085 encoder pulse mechanism */ -#define XY_ARM 0x10 /* arm the encoder pulse circuitry */ -#define XY_BUSY 0x20 /* indicates the waveform is still being taken */ -#define XY_LED 0x3 /* set the Xycom status LEDs to OK */ -#define XY_SOFTRESET 0x10 /* reset the IO card */ - - -/* arrays which keep track of which cards are found at initialization */ -struct ai566 **pwf_xy566; -struct wf085 **pwf_xy085; -char **pwf_mem; - -/* the routine to call when the data is read and the argument to send */ -unsigned int **pargument; -unsigned int **proutine; - -/* VME memory Short Address Space is set up in gta_init */ - -int wfDoneId; /* waveform done task ID */ - -/* forward references */ -static void senw(); -static VOID xy566_reset(); -static int ai_xy566_init(); -static int ai_xy566l_init(); -static VOID rval_convert(); -static VOID xy566_rval_report(); - - -static int acro_intr(ap) -register struct acroregs *ap; -{ - return(0); -} - -/* The following two subroutines introduce a delay between - * successive writes to the 566. This is necessary for some - * parts of the card (i.e. the AM9513). It also insures - * that a value is actually written, instead of compiler - * generated bset or bclr instructions. - */ -static void senw (addr, val) -unsigned short *addr; -unsigned short val; -{ - *addr = val; -} - -void senb (addr, val) -unsigned char *addr; -unsigned char val; -{ - *addr = val; -} - -int ai566_intr(i) -short i; -{ - register struct ai566 *ap; - - ap = pai_xy566dil[i]; - - scanIoRequest(paioscanpvt[i]); - - /* reset the CSR - needed to allow next interrupt */ - senw(&ap->a566_csr,XY566L_CSR); - return(0); -} - -/* - * ai_566_init () - * - * Initialize all VME analog input cards - */ - -long ai_566_init() -{ - /* intialize the Xycom 566 Unipolar Single Ended Analog Inputs */ - ai_xy566_init(&pai_xy566se,ai_addrs[XY566SE],ai_num_channels[XY566SE], - ai_num_cards[XY566SE],ai_memaddrs[XY566SE],&pai_xy566se_mem); - - /* intialize the Xycom 566 Unipolar Differential Analog Inputs */ - ai_xy566_init(&pai_xy566di,ai_addrs[XY566DI],ai_num_channels[XY566DI], - ai_num_cards[XY566DI],ai_memaddrs[XY566DI],&pai_xy566di_mem); - - - /* intialize the Xycom 566 Unipolar Differential Analog Inputs Latched */ - ai_xy566l_init(&pai_xy566dil,ai_addrs[XY566DIL],ai_num_channels[XY566DIL], - ai_num_cards[XY566DIL],ai_memaddrs[XY566DIL],&pai_xy566dil_mem); - - return (0); -} - - -/* - * ai_XY566_INIT - * - * intialize the xycom 566 analog input card - */ -int ai_xy566_init(pppcards_present,base_addr,num_channels,num_cards,paimem,pppmem_present) -register struct ai566 ***pppcards_present; -register unsigned short *base_addr; -register short num_channels; -short num_cards; -register char *paimem; /* mem loc of I/O buffer */ -register short ***pppmem_present; -{ - short shval; - register short i,n; - struct ai566 *pai566; /* memory location of cards */ - char *pai566io; /* mem loc of I/O buffer */ - short status; - struct ai566 **ppcards_present; - short **ppmem_present; - - *pppcards_present = (struct ai566 **) - calloc(num_cards, sizeof(**pppcards_present)); - if(!*pppcards_present){ - return ERROR; - } - - *pppmem_present = (short **) - calloc(num_cards, sizeof(**pppmem_present)); - if(!*pppmem_present){ - return ERROR; - } - - ppcards_present = *pppcards_present; - ppmem_present = *pppmem_present; - - /* map the io card into the VRTX short address space */ - status = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO, base_addr, &pai566); - if(status != OK){ - logMsg("%s: failed to map XY566 A16 base addr A16=%x\n", - __FILE__, - base_addr); - return ERROR; - } - - /* map the io card into the standard address space */ - status = sysBusToLocalAdrs(VME_AM_STD_SUP_DATA,paimem, &pai566io); - if(status != OK){ - logMsg( "%s: failed to map XY566 A24 base addr A24=%x\n", - __FILE__, - paimem); - return ERROR; - } - - /* mark each card present into the card present array */ - for (i = 0; i < num_cards; - i++, pai566++, ppcards_present++, pai566io+=XY566_MEM_INCR,ppmem_present++) { - if (vxMemProbe(pai566,READ,sizeof(short),&shval) != OK){ - *ppcards_present = 0; - continue; - } - if (vxMemProbe(pai566io,READ,sizeof(short),&shval) != OK){ - *ppcards_present = 0; - continue; - } - - *ppcards_present = pai566; - *ppmem_present = (short *)pai566io; - - /* reset the Xycom 566 board */ - senw(&pai566->a566_csr,0x00); /* off seq control */ - senw(&pai566->a566_csr,XY_SOFTRESET); /* reset */ - senw(&pai566->a566_csr,XY_LED); /* reset off,red off,green on */ - - /* Am9513 commands */ - /* initialize the Am9513 chip on the XY566 */ - senw(&pai566->stc_control,0xffff); /* master reset */ - senw(&pai566->stc_control,0xff5f); /* disarm all counters */ - senw(&pai566->stc_control,0xffef); /* 16 bit mode */ - - /* master mode register */ - senw(&pai566->stc_control,0xff17); /* select master mode reg */ - senw(&pai566->stc_data,0x2200); /* 16 bit, divide by 4 */ - - /* counter two is used to set the time between sequences */ - senw(&pai566->stc_control,0xff02); /*sel counter 2 */ - senw(&pai566->stc_data,0x0b02); /* TC toggle mode */ - senw(&pai566->stc_control,0xffea); /* TC output high */ - - /* counter four is used as time between sequence elements */ - senw(&pai566->stc_control,0xff04); /* sel counter 4 */ - senw(&pai566->stc_data,0x0b02); /* TC toggle mode */ - senw(&pai566->stc_control,0xffec); /* TC output high */ - - /* counter five is used as an event counter */ - senw(&pai566->stc_control,0xff05); /* sel counter 5 */ - senw(&pai566->stc_data,0x0b02); /* TC toggle mode */ - senw(&pai566->stc_control,0xffed); /* TC output high */ - - /* set time between sequences */ - senw(&pai566->stc_control,0xff04); /* sel counter 4 */ - senw(&pai566->stc_data,0x9525); /* see Am9513A manual */ - senw(&pai566->stc_data,0x0014); /* downcount value */ - senw(&pai566->stc_control,0xff68); /* load & arm cntr 4 */ - - senw(&pai566->stc_control,0xff05); /* sel counter 4 */ - senw(&pai566->stc_data,0x97ad); /* see Am9513A manual */ - senw(&pai566->stc_data,0x0100); /* downcount value */ - senw(&pai566->stc_control,0xff70); /* load & arm cntr 4 */ - /* end of the Am9513 commands */ - - /* for each channel set gain and place into the scan list */ - for (n=0; n < num_channels; n++) { - senb((&pai566->gram_base + n*2),0); /* gain == 1 */ - /* end of sequnce = 0x80 | channel */ - /* stop = 0x40 | channel */ - senb((&pai566->sram_base+n*2),(n==num_channels-1)? n|0x80:n); - } - senw(&pai566->dram_ptr, 0); /* data ram at 0 */ - senb(&pai566->sram_ptr, 0); /* seq ram also at 0 */ - - /* set the Xycom 566 board */ - /* reset the counter interrupt 0x8000 */ - /* reset the sequence interrupt 0x2000 */ - /* reset the trigger clock interrupt 0x0800 */ - /* enable the sequence controller 0x0100 */ - /* read values into first 32 words on each read 0x0040 */ - /* read in sequential mode (bit 0x0020 == 0) 0x0000 */ - /* leds green-on red-off 0x0003 */ - senw(&pai566->a566_csr,0xa943 ); /* init csr */ - - /* latch in the first bunch of data and start continuous scan */ - senb(&pai566->soft_start,0); - } - - return OK; -} - -/* - * AI_XY566L_INIT - * - * intialize the xycom 566 latched analog input card - */ -int ai_xy566l_init(pppcards_present,base_addr,num_channels,num_cards,paimem,pppmem_present) -register struct ai566 ***pppcards_present; -register unsigned short *base_addr; -register short num_channels; -short num_cards; -register char *paimem; /* mem loc of I/O buffer */ -register short ***pppmem_present; -{ - short shval; - register short i,n; - struct ai566 *pai566; /* memory location of cards */ - char *pai566io; /* mem loc of I/O buffer */ - int status; - struct ai566 **ppcards_present; - short **ppmem_present; - - *pppcards_present = (struct ai566 **) - calloc(num_cards, sizeof(**pppcards_present)); - if(!*pppcards_present){ - return ERROR; - } - - paioscanpvt = (IOSCANPVT *)calloc(num_cards, sizeof(*paioscanpvt)); - if(!paioscanpvt) { - return ERROR; - } - { - int i; - for(i=0; icard_number,i); - - /* set up the interrupt vector */ - /* taken from the XYCOM-566 Manual. Figure 4-6 Page 4-19 */ - pai566->int_vect = AI566_VNUM + i; - - intConnect(INUM_TO_IVEC(AI566_VNUM + i), ai566_intr, i); - sysIntEnable(XY566_INT_LEVEL); - - /* reset the Xycom 566 board */ - senw(&pai566->a566_csr,0x00); /* off seq control */ - senw(&pai566->a566_csr,XY_SOFTRESET); /* reset */ - senw(&pai566->a566_csr,XY_LED); /* reset off,red off,green on */ - - /* Am9513 commands */ - /* initialize the Am9513 chip on the XY566 */ - senw(&pai566->stc_control,0xffff); /* master reset */ - senw(&pai566->stc_control,0xff5f); /* disarm all counters */ - senw(&pai566->stc_control,0xffef); /* 16 bit mode */ - - /* master mode register */ - senw(&pai566->stc_control,0xff17); /* select master mode reg */ - senw(&pai566->stc_data,0x2200); /* 16 bit, divide by 4 */ - - /* counter two is used to set the time between sequences */ - senw(&pai566->stc_control,0xff02); /*sel counter 2 */ - senw(&pai566->stc_data,0x0b02); /* TC toggle mode */ - senw(&pai566->stc_control,0xffea); /* TC output high */ - - /* counter four is used as time between sequence elements */ - senw(&pai566->stc_control,0xff04); /* sel counter 4 */ - senw(&pai566->stc_data,0x0b02); /* TC toggle mode */ - senw(&pai566->stc_control,0xffec); /* TC output high */ - - /* counter five is used as an event counter */ - senw(&pai566->stc_control,0xff05); /* sel counter 5 */ - senw(&pai566->stc_data,0x0b02); /* TC toggle mode */ - senw(&pai566->stc_control,0xffed); /* TC output high */ - - /* set time between sequences */ - senw(&pai566->stc_control,0xff04); /* sel counter 4 */ - senw(&pai566->stc_data,0x9525); /* see Am9513A manual */ - senw(&pai566->stc_data,0x0014); /* downcount value */ - senw(&pai566->stc_control,0xff68); /* load & arm cntr 4 */ - - senw(&pai566->stc_control,0xff05); /* sel counter 4 */ - senw(&pai566->stc_data,0x97ad); /* see Am9513A manual */ - senw(&pai566->stc_data,0x0100); /* downcount value */ - senw(&pai566->stc_control,0xff70); /* load & arm cntr 4 */ - /* end of the Am9513 commands */ - - /* for each channel set gain and place into the scan list */ - for (n=0; n < num_channels; n++) { - senb((&pai566->gram_base + n*2), 0); /* gain == 1 */ - - /* end of sequnce = 0x80 | channel */ - /* stop = 0x40 | channel */ - /* interrupt = 0x20 | channel */ - senb((&pai566->sram_base+n*2),(n==num_channels-1)? n|0xe0:n); - } - senw(&pai566->dram_ptr,0); /* data ram at 0 */ - senb(&pai566->sram_ptr,0); /* seq ram also at 0 */ - - /* initialize the control status register */ - /* reset the sequence interrupt 0x2000 */ - /* enable the sequence interrupt 0x1000 */ - /* reset the trigger clock interrupt 0x0800 */ - /* enable the sequence controller 0x0100 */ - /* read values into first 32 words on each read 0x0040 */ - /* read in sequential mode (bit 0x0020 == 0) 0x0000 */ - /* interrupt enable 0x0008 */ - /* leds green-on red-off 0x0003 */ - senw(&pai566->a566_csr,XY566L_CSR); - - } - - return OK; -} - -int ai_xy566_getioscanpvt(card,scanpvt) -unsigned short card; -IOSCANPVT *scanpvt; -{ - if((card<=(unsigned short)MAX_DIL_CARDS) && paioscanpvt[card]) *scanpvt = paioscanpvt[card]; - return(0); -} - -int ai_xy566_driver(card,chan,type,prval) -register short card; -short chan; -register unsigned int type; -register unsigned short *prval; -{ - /* the register short i is used to calculate the delay for the */ - /* conversion of the XYCOM 566. Make sure it stays a register */ - - /* check on the card and channel number as kept in module_types.h */ - if (card >= ai_num_cards[type]) return(-1); - if (chan >= ai_num_channels[type]) return(-2); - - switch (type){ - - case (XY566SE): - { - - /* check card specified exists */ - if (pai_xy566se[card] == 0) return(-1); - - /* read the value from the Xycom data RAM area */ - *prval = pai_xy566se_mem[card][chan]; - - return (0); - } - - case (XY566DI): - { - - /* check card specified exists */ - if (pai_xy566di[card] == 0) return(-1); - - /* read the value form the Xycom data RAM area */ - - *prval = pai_xy566di_mem[card][chan]; - - rval_convert(prval); - return (0); - } - - case (XY566DIL): - { - - /* check card specified exists */ - if (pai_xy566dil[card] == 0) return(-1); - - /* read the value form the Xycom data RAM area */ - *prval = pai_xy566dil_mem[card][chan]; - - rval_convert(prval); - return (0); - } - - - } - - return (-3); -} - -/* - * rval_convert - * For 566_card - values for XY566DI and XY566DIL - * come from the card as signed hex numbers( -0x7ff to +0x7ff). - * This subrountine converts them to unsigned hex numbers (0x0 - - * 0x7ff. Then it strips off the sign bit. - * -*/ -VOID rval_convert(rval) - unsigned short *rval; -{ - - *rval = *rval + 0x800; - - /* remove the sign bits. */ - - *rval &= 0xfff; -} - -/* - * - * xy566_reset- Called for ctl X reboot. The idea is to disable - * bits 3 and 12 of the CSR. - * -*/ - -VOID xy566_reset(){ - unsigned short csr_val,shval; - short int i; - struct ai566 *pai566; /* memory location of cards */ - short int status; - - status = sysBusToLocalAdrs( - VME_AM_SUP_SHORT_IO, - ai_addrs[XY566DIL], - &pai566); - if (status != OK){ - logMsg("%s: unable to map A16 XY566 base\n", __FILE__); - return; - } - - for (i=0;ia566_csr = csr_val; - } -} - - - - -/* - * io_report (or dbior) subroutine for 566 card. - * - * - */ -long ai_xy566_io_report(level) - char level; -{ - short i; - - - for (i = 0; i < MAX_SE_CARDS; i++){ - if (pai_xy566se[i]){ - printf("AI: XY566-SE:\tcard %d\n",i); - if (level == 1){ - xy566_rval_report(i,XY566SE); - } - - } - } - for (i = 0; i < MAX_DI_CARDS; i++){ - if (pai_xy566di[i]){ - printf("AI: XY566-DI:\tcard %d\n",i); - if (level == 1){ - xy566_rval_report(i,XY566DI); - } - } - - } - - for (i = 0; i < MAX_DIL_CARDS; i++){ - if (pai_xy566dil[i]){ - printf("AI: XY566-DIL:\tcard %d\n",i); - if (level == 1){ - xy566_rval_report(i,XY566DIL); - } - } - } - return OK; -} - -/* - * xy566_rval_report -reports the raw value for every channel on the card - * - * called by ai_xy566_io_report if level is 1 - * - */ -VOID xy566_rval_report(card,type) - short int card,type; - { - short j,k,l,m,num_chans; - unsigned short jrval,krval,lrval,mrval; - - printf("\n"); - - num_chans = ai_num_channels[type]; - - 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){ - if( ai_xy566_driver(card,j,type,&jrval) == 0){ - printf("Chan %d = %x \t",j,jrval); - }else - printf("READ_ALARM\n"); - } - - if(k < num_chans){ - if(ai_xy566_driver(card,k,type,&krval) == 0){ - printf("Chan %d = %x \t",k,krval); - } else - printf("READ_ALARM\n"); - } - if(l < num_chans){ - if( ai_xy566_driver(card,l,type,&lrval) == 0){ - printf("Chan %d = %x \t",l,lrval); - } else - printf("READ_ALARM\n"); - } - if(m < num_chans){ - if( ai_xy566_driver(card,m,type,&mrval) == 0){ - printf("Chan %d = %x \n",m,mrval); - } - else - printf("READ_ALARM\n"); - } - } - } - - - -/* forward references */ - - -/* - * xy566_driver - * - */ -int xy566_driver(slot,pcbroutine,parg) -register unsigned short slot; -register unsigned int *pcbroutine; -register unsigned int *parg; /* number of values read */ -{ - register struct ai566 *pwf566; - register struct wf085 *pwf085; - - /* slot range checking occurs in wf_driver.c */ - - /* is the Xycom 566 card present */ - if ((pwf566 = pwf_xy566[slot]) == 0) - return(-1); - if ((pwf085 = pwf_xy085[slot]) == 0) - return(-1); - - /* armed already by someone else */ - if (proutine[slot] != 0) - return(-2); /* by someone else */ - - /* set the Xycom 566 board */ - senw(&pwf566->dram_ptr,0); /* RAM pointer to 0 */ - senw(&pwf566->sram_ptr,0); /* sequence pointer to 0 */ - - /* keep the pointer to the value field */ - proutine[slot] = pcbroutine; - pargument[slot] = parg; - - /* arm the encoder pulse mechanism */ - senw(&pwf085->csr,XY_ARM | XY_LED | 0x20); /* set high */ - senw(&pwf085->csr,XY_LED | 0x20); /* set low */ - - return(0); -} - -/* - * xy566DoneTask - * - * polls the busy bit on the Xycom 566 latched waveform records - * The busy bit is set externally when data collection is completed - */ -int xy566DoneTask() -{ - register unsigned int **pproutines; - register unsigned int (*pcbroutine)(); - register short i; - - while(TRUE){ - pproutines = proutine; - for (i=0; icsr & XY_BUSY) == 0){ - /* callback routine when data take completed */ - (unsigned int *)pcbroutine = *pproutines; - (*pcbroutine) - (pargument[i],pwf_xy566[i]->dram_ptr,pwf_mem[i]); - - /* reset for someelse to claim */ - *pproutines = 0; - pargument[i] = 0; - } - } - - /* sleep for .1 second - system degrade will slow this task */ - /* that's OK */ - taskDelay(2); /* ges: changed from 6 ticks to 2 ticks 2/4/91 */ - } -} - -/* - * XY566_INIT - * - * intialize the xycom 566 waveform input card - */ -int xy566_init() -{ - register struct ai566 **pcards_present = pwf_xy566; - register struct wf085 **parms_present = pwf_xy085; - register char **pmem_present = pwf_mem; - - short shval,status; - register short i,got_one; - struct ai566 *pwf566; /* VME location of cards */ - struct wf085 *pwf085; /* VME location of arm */ - char *pwfMem; /* VME 566 memory buffer */ - - pwf_xy566 = (struct ai566 **) - calloc(wf_num_cards[XY566WF], sizeof(*pwf_xy566)); - if(!pwf_xy566){ - return ERROR; - } - pwf_xy085 = (struct wf085 **) - calloc(wf_num_cards[XY566WF], sizeof(*pwf_xy085)); - if(!pwf_xy085){ - return ERROR; - } - pwf_mem = (char **) - calloc(wf_num_cards[XY566WF], sizeof(*pwf_mem)); - if(!pwf_mem){ - return ERROR; - } - pargument = (unsigned int **) - calloc(wf_num_cards[XY566WF], sizeof(*pargument)); - if(!pargument){ - return ERROR; - } - proutine = (unsigned int **) - calloc(wf_num_cards[XY566WF], sizeof(*proutine)); - if(!proutine){ - return ERROR; - } - - pcards_present = pwf_xy566; - parms_present = pwf_xy085; - pmem_present = pwf_mem; - - /* map the io card into the VME short address space */ - status = sysBusToLocalAdrs( - VME_AM_SUP_SHORT_IO, - WF_XY566_BASE, - &pwf566); - if(status<0){ - logMsg("%s: unable to map A16 XY566 base\n", __FILE__); - return ERROR; - } - - status = sysBusToLocalAdrs( - VME_AM_SUP_SHORT_IO, - WF_XY085_BASE, - &pwf085); - if(status<0){ - logMsg("%s: unable to map A16 XY085 base\n", __FILE__); - return ERROR; - } - - status = sysBusToLocalAdrs( - VME_AM_STD_SUP_DATA, - wf_memaddrs[XY566WF], - &pwfMem); - if (status != OK){ - logMsg("%s: unable to map A24 XY566 base\n", __FILE__); - return ERROR; - } - - /* mark each card present into the card present array */ - got_one = 0; - for (i = 0; - i < wf_num_cards[XY566WF]; - i++, pwf566++,pwf085++,pwfMem += XY566_MEM_INCR, pcards_present += 1) { - - /* is the Xycom 566 here */ - if (vxMemProbe(pwf566,READ,sizeof(short),&shval) != OK){ - *pcards_present = 0; - continue; - } - /* is the Xycom 566 memory here */ - if (vxMemProbe(pwfMem,READ,sizeof(short),&shval) != OK){ - *pcards_present = 0; - continue; - } - /* is the Xycom 085 used as the arming mechanism present */ - if (vxMemProbe(pwf085,READ,sizeof(short),&shval) != OK){ - *pcards_present = 0; - continue; - } - - got_one = 1; - *pcards_present = pwf566; - *parms_present = pwf085; - *pmem_present = pwfMem; - - /* taken from the XYCOM-566 Manual. Figure 4-6 Page 4-19 */ - /* reset the Xycom 566 board */ - senw (&pwf566->a566_csr,0x00); /* off seq control */ - senw (&pwf566->a566_csr,XY_SOFTRESET); /* reset */ - senw (&pwf566->a566_csr,XY_LED); /* reset off,red off,green on */ - - /* Am9513 commands */ - /* initialize the Am9513 chip on the XY566 */ - senw (&pwf566->stc_control, 0xffff); /* master reset */ - senw(&pwf566->stc_control, 0xff5f); /* disarm all counters */ - senw(&pwf566->stc_control, 0xffef); /* 16 bit mode */ - - /* master mode register */ - senw(&pwf566->stc_control, 0xff17); /* select master mode reg */ - senw(&pwf566->stc_data, 0x2200); /* 16 bit, divide by 4 */ - - /* counter two is used to set the time between sequences */ - senw(&pwf566->stc_control, 0xff02); /*sel counter 2 */ - senw(&pwf566->stc_data, 0x0b02); /* TC toggle mode */ - senw(&pwf566->stc_control, 0xffea); /* TC output high */ - - /* counter four is used as time between sequence elements */ - senw(&pwf566->stc_control, 0xff04); /* sel counter 4 */ - senw(&pwf566->stc_data, 0x0b02); /* TC toggle mode */ - senw(&pwf566->stc_control, 0xffec); /* TC output high */ - - /* counter five is used as an event counter */ - senw(&pwf566->stc_control, 0xff05); /* sel counter 5 */ - senw(&pwf566->stc_data, 0x0b02); /* TC toggle mode */ - senw(&pwf566->stc_control, 0xffed); /* TC output high */ - - /* set counter 4 */ - /* active high level gate N 0x8000 */ - /* count on the falling edge 0x1000 */ - /* SRC 5 0x0500 */ - /* disable special gate 0x0080 = 0 */ - /* reload from load 0x0040 = 0 */ - /* count repetitively 0x0020 = 1 */ - /* binary count 0x0010 = 0 */ - /* count down 0x0008 = 0 */ - /* active low terminal count pulse 0x0007 = 5 */ - senw(&pwf566->stc_control,0xff04); /* sel counter 4 */ - senw(&pwf566->stc_data,0x9525); /* see comment above*/ - senw(&pwf566->stc_data,0x0014); /* downcount value */ - senw(&pwf566->stc_control,0xff68); /* load & arm cntr 4 */ - - /* set counter 5 */ - /* active high level gate N 0x8000 */ - /* count on the falling edge 0x1000 */ - /* GATE 2 0x0700 */ - /* enable special gate 0x0080 = 1 */ - /* reload from load 0x0040 = 0 */ - /* count repetitively 0x0020 = 1 */ - /* binary count 0x0010 = 0 */ - /* count up 0x0008 = 1 */ - /* active low terminal count pulse 0x0007 = 5 */ - senw(&pwf566->stc_control,0xff05); /* sel counter 5 */ - senw(&pwf566->stc_data,0x97ad); /* see comment above */ - senw(&pwf566->stc_data,0x0100); /* count value */ - senw(&pwf566->stc_control,0xff70); /* load & arm cntr 5*/ - /* end of the Am9513 commands */ - - /* Xycom gain RAM */ - senb(&pwf566->gram_base,0); /* set gain to 1 ch0*/ - - /* Xycom sequence RAM */ - senb(&pwf566->sram_base,0xc0); /* read only the 0th channel */ - - /* Xycom data RAM index */ - senw(&pwf566->dram_ptr,0); /* data ram at 0 */ - - /* Xycom sequential RAM index */ - senb(&pwf566->sram_ptr,0); /* seq ram also at 0 */ - - /* set the Xycom 566 board */ - /* reset the counter interrupt 0x8000 */ - /* reset the sequence interrupt 0x2000 */ - /* reset the trigger clock interrupt 0x0800 */ - /* enable the sequence controller 0x0100 */ - /* read values into data RAM contiguously (bit 0x0040 == 0) 0x0000 */ - /* read in sequential mode (bit 0x0020 == 0) 0x0000 */ - /* leds green-on red-off 0x0003 */ - senw(&pwf566->a566_csr,0xa903); /* init csr */ - - /* initialize the xycom 085 used as the arming mechanism */ - /* leds green-on red-off 0x0003 */ - senw(&pwf085->csr,XY_LED | 0x20); /* init csr */ - } - - /* start the 566 waveform readback task */ - if (got_one) - wfDoneId = - taskSpawn( - WFDONE_NAME, - WFDONE_PRI, - WFDONE_OPT, - WFDONE_STACK, - xy566DoneTask); - taskwdInsert(wfDoneId,NULL,NULL); - - return 0; -} - - -/* - * XY566_IO_REPORT - * - * - * - * - */ -long -xy566_io_report(level) -short int level; -{ - int i; - - /* report all of the xy566 waveform inputs present */ - for (i = 0; i < wf_num_cards[XY566WF]; i++) - if (pwf_xy566[i]){ - printf("WF: XY566: card %d\n",i); - } - - return(0); -} - - diff --git a/src/drv/old/module_types.c b/src/drv/old/module_types.c deleted file mode 100644 index e1be8bcd3..000000000 --- a/src/drv/old/module_types.c +++ /dev/null @@ -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 - -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); -} diff --git a/src/drv/old/steppermotor.h b/src/drv/old/steppermotor.h deleted file mode 100644 index 86e4b95c0..000000000 --- a/src/drv/old/steppermotor.h +++ /dev/null @@ -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