304 lines
12 KiB
C
304 lines
12 KiB
C
#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
|