Files
epics-base/src/drv/drvBitBus.h

304 lines
12 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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.
*
* $Log$
* Revision 1.8 1994/10/04 18:42:44 winans
* Added an extensive debugging facility.
*
*
*/
/*****************************************************************************
*
* 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