Removed CANbus and IPAC support, these have been unbundled for some
time and the versions here were very out of date.
This commit is contained in:
@@ -5,21 +5,15 @@
|
||||
TOP = ../../../..
|
||||
include $(TOP)/config/CONFIG_BASE
|
||||
|
||||
INC += canBus.h
|
||||
INC += drvAb.h
|
||||
INC += drvAt5Vxi.h
|
||||
INC += drvEpvxi.h
|
||||
INC += drvHp1404a.h
|
||||
INC += drvHpe1368a.h
|
||||
INC += drvIpac.h
|
||||
INC += drvKscV215.h
|
||||
INC += drvMz8310.h
|
||||
INC += drvStc.h
|
||||
INC += drvTip810.h
|
||||
INC += epvxi.h
|
||||
INC += ipModules.h
|
||||
INC += ipic.h
|
||||
INC += pca82c200.h
|
||||
|
||||
SRCS.c += ../drvAb.c
|
||||
SRCS.c += ../drvAt5Vxi.c
|
||||
@@ -32,12 +26,6 @@ SRCS.c += ../drvKscV215.c
|
||||
SRCS.c += ../drvMz8310.c
|
||||
SRCS.c += ../drvStc.c
|
||||
#SRCS.c += ../drvCaenV265.c
|
||||
|
||||
SRCS.c += ../drvVipc310.c
|
||||
SRCS.c += ../drvVipc610.c
|
||||
SRCS.c += ../drvIpMv162.c
|
||||
SRCS.c += ../drvIpac.c
|
||||
SRCS.c += ../drvTip810.c
|
||||
#SRCS.c += ../drvVmic2534.c
|
||||
|
||||
PROD = $(SRCS.c:../%.c=%.o)
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Project:
|
||||
Gemini/UKIRT CAN Bus Driver for EPICS
|
||||
|
||||
File:
|
||||
canBus.h
|
||||
|
||||
Description:
|
||||
CANBUS specific constants
|
||||
|
||||
Author:
|
||||
Andrew Johnson
|
||||
Created:
|
||||
25 July 1995
|
||||
|
||||
(c) 1995 Royal Greenwich Observatory
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
#ifndef INCcanBusH
|
||||
#define INCcanBusH
|
||||
|
||||
|
||||
#define CAN_IDENTIFIERS 2048
|
||||
#define CAN_DATA_SIZE 8
|
||||
|
||||
#define CAN_BUS_OK 0
|
||||
#define CAN_BUS_ERROR 1
|
||||
#define CAN_BUS_OFF 2
|
||||
|
||||
|
||||
#ifndef M_can
|
||||
#define M_can (811<<16)
|
||||
#endif
|
||||
|
||||
#define S_can_badMessage (M_can| 1) /*illegal CAN message contents*/
|
||||
#define S_can_badAddress (M_can| 2) /*CAN address syntax error*/
|
||||
#define S_can_noDevice (M_can| 3) /*CAN bus name does not exist*/
|
||||
|
||||
typedef struct {
|
||||
ushort_t identifier; /* 0 .. 2047 with holes! */
|
||||
enum {
|
||||
SEND = 0, RTR = 1
|
||||
} rtr; /* Remote Transmission Request */
|
||||
uchar_t length; /* 0 .. 8 */
|
||||
uchar_t data[CAN_DATA_SIZE];
|
||||
} canMessage_t;
|
||||
|
||||
typedef struct {
|
||||
char *busName;
|
||||
int timeout;
|
||||
ushort_t identifier;
|
||||
ushort_t offset;
|
||||
signed int parameter;
|
||||
void *canBusID;
|
||||
} canIo_t;
|
||||
|
||||
typedef void canMsgCallback_t(void *pprivate, canMessage_t *pmessage);
|
||||
typedef void canSigCallback_t(void *pprivate, int status);
|
||||
|
||||
extern int canOpen(char *busName, void **pcanBusID);
|
||||
extern int canRead(void *canBusID, canMessage_t *pmessage, int timeout);
|
||||
extern int canWrite(void *canBusID, canMessage_t *pmessage, int timeout);
|
||||
extern int canMessage(void *canBusID, ushort_t identifier,
|
||||
canMsgCallback_t callback, void *pprivate);
|
||||
extern int canSignal(void *canBusID, canSigCallback_t callback, void *pprivate);
|
||||
extern int canIoParse(char *canString, canIo_t *pcanIo);
|
||||
|
||||
|
||||
#endif /* INCcanBusH */
|
||||
|
||||
@@ -1,341 +0,0 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Project:
|
||||
Gemini/UKIRT CAN Bus Driver for EPICS
|
||||
|
||||
File:
|
||||
drvIpMv162.c
|
||||
|
||||
Description:
|
||||
IPAC Carrier Driver for the IndustryPack carriers on the Motorola
|
||||
MVME162 CPU board, provides the interface between IPAC driver and the
|
||||
hardware.
|
||||
|
||||
Author:
|
||||
Andrew Johnson
|
||||
Created:
|
||||
6 July 1995
|
||||
|
||||
(c) 1995 Royal Greenwich Observatory
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <vme.h>
|
||||
#include <sysLib.h>
|
||||
#include <vxLib.h>
|
||||
#include "drvIpac.h"
|
||||
#include "ipic.h"
|
||||
|
||||
|
||||
/* Characteristics of the card */
|
||||
|
||||
#define SLOTS 4
|
||||
#define IO_SPACES 2 /* Address spaces in A16 */
|
||||
#define IPAC_IRQS 2 /* Interrupts per module */
|
||||
#define IPIC_BASE 0xfffbc000
|
||||
|
||||
|
||||
/* Base Addresses of IO and ID spaces */
|
||||
|
||||
#define REGS_A 0xfff58000
|
||||
#define PROM_A 0xfff58080
|
||||
#define REGS_B 0xfff58100
|
||||
#define PROM_B 0xfff58180
|
||||
#define REGS_C 0xfff58200
|
||||
#define PROM_C 0xfff58280
|
||||
#define REGS_D 0xfff58300
|
||||
#define PROM_D 0xfff58380
|
||||
#define REGS_AB 0xfff58400
|
||||
#define REGS_CD 0xfff58500
|
||||
|
||||
|
||||
/* IPIC chip */
|
||||
|
||||
ipic_t *ipic = (ipic_t *) IPIC_BASE;
|
||||
|
||||
|
||||
/* IP Recovery Timers */
|
||||
|
||||
LOCAL const uchar_t recoveryTime[] = {
|
||||
IPIC_GEN_RT_0,
|
||||
IPIC_GEN_RT_2,
|
||||
IPIC_GEN_RT_2,
|
||||
IPIC_GEN_RT_4,
|
||||
IPIC_GEN_RT_4,
|
||||
IPIC_GEN_RT_8,
|
||||
IPIC_GEN_RT_8,
|
||||
IPIC_GEN_RT_8,
|
||||
IPIC_GEN_RT_8
|
||||
};
|
||||
|
||||
|
||||
/* Carrier Base Address structure, only one instance can exist! */
|
||||
|
||||
LOCAL long mBase[IPAC_ADDR_SPACES][SLOTS] = {
|
||||
PROM_A, PROM_B, PROM_C, PROM_D,
|
||||
REGS_A, REGS_B, REGS_C, REGS_D,
|
||||
REGS_AB, NULL, REGS_CD, NULL,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Routine:
|
||||
initialise
|
||||
|
||||
Purpose:
|
||||
Initialises the MVME162 IPIC chip with settings given in cardParams
|
||||
|
||||
Description:
|
||||
|
||||
|
||||
Parameters:
|
||||
|
||||
|
||||
Examples:
|
||||
"A:m=0x80000000,1024 l=4;B:l=2,2;C:m=0x80100000,64"
|
||||
|
||||
Returns:
|
||||
0 = OK,
|
||||
S_IPAC_tooMany = Carrier already registered
|
||||
S_IPAC_badDriver = IPIC chip not found
|
||||
S_IPAC_badAddress = Parameter string error, or address not reachable
|
||||
|
||||
*/
|
||||
|
||||
LOCAL int initialise (
|
||||
char *cardParams,
|
||||
void **pprivate
|
||||
) {
|
||||
static int initialised = FALSE;
|
||||
ushort_t slot;
|
||||
int count, p1, p2, next;
|
||||
char dummy, cmd;
|
||||
|
||||
if (initialised) {
|
||||
return S_IPAC_tooMany;
|
||||
}
|
||||
|
||||
if (vxMemProbe((void *)&ipic->chipId, READ, 1, &dummy) ||
|
||||
ipic->chipId != IPIC_CHIP_ID) {
|
||||
return S_IPAC_badDriver;
|
||||
}
|
||||
|
||||
/* Initialise the IPIC chip */
|
||||
for (slot = 0; slot < SLOTS; slot++) {
|
||||
ipic->intCtrl[slot][0] = IPIC_INT_ICLR;
|
||||
ipic->intCtrl[slot][1] = IPIC_INT_ICLR;
|
||||
ipic->genCtrl[slot] = IPIC_GEN_WIDTH_16 | IPIC_GEN_RT_0;
|
||||
}
|
||||
|
||||
/* Parse the parameter string */
|
||||
slot = 0;
|
||||
while ((cmd = *cardParams++) != '\0') {
|
||||
switch (cmd) {
|
||||
case 'A':
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'D':
|
||||
slot = cmd - 'A';
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
p1 = p2 = 0;
|
||||
count = sscanf(cardParams, "=%p,%d%n",
|
||||
(void **) &p1, &p2, &next);
|
||||
if (count != 2 ||
|
||||
p1 < (long) sysMemTop() ||
|
||||
p1 & 0xffff != 0 ||
|
||||
p2 < 64 || p2 > 16384 ||
|
||||
p1 + (p2*1024) > 0xfff00000) {
|
||||
return S_IPAC_badAddress;
|
||||
}
|
||||
|
||||
ipic->memBase[slot] = p1 >> 16;
|
||||
ipic->memSize[slot] = (p2 / 64) - 1;
|
||||
ipic->genCtrl[slot] |= IPIC_GEN_MEN;
|
||||
mBase[ipac_addrMem][slot] = p1;
|
||||
cardParams += next;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
p1 = p2 = 0;
|
||||
count = sscanf(cardParams, "=%d%n,%d%n", &p1, &next, &p2, &next);
|
||||
if (count < 1 || count > 2 ||
|
||||
p1 < 0 || p1 > 7 ||
|
||||
p2 < 0 || p2 > 7) {
|
||||
return S_IPAC_badAddress;
|
||||
}
|
||||
|
||||
ipic->intCtrl[slot][0] = (p1 & IPIC_INT_LEVEL) |
|
||||
(ipic->intCtrl[slot][0] & ~IPIC_INT_LEVEL);
|
||||
ipic->intCtrl[slot][1] = (p2 & IPIC_INT_LEVEL) |
|
||||
(ipic->intCtrl[slot][1] & ~IPIC_INT_LEVEL);
|
||||
cardParams += next;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
p1 = 0;
|
||||
count = sscanf(cardParams, "=%d%n", &p1, &next);
|
||||
if (count != 1 ||
|
||||
p1 < 0 || p1 > 8) {
|
||||
return S_IPAC_badAddress;
|
||||
}
|
||||
|
||||
ipic->genCtrl[slot] = (ipic->genCtrl[slot] & ~IPIC_GEN_RT) |
|
||||
recoveryTime[p1];
|
||||
cardParams += next;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
p1 = 0;
|
||||
count = sscanf(cardParams, "=%d%n", &p1, &next);
|
||||
if (count != 1) {
|
||||
return S_IPAC_badAddress;
|
||||
}
|
||||
|
||||
switch (p1) {
|
||||
case 8:
|
||||
ipic->genCtrl[slot] = IPIC_GEN_WIDTH_8 |
|
||||
(ipic->genCtrl[slot] & ~IPIC_GEN_WIDTH);
|
||||
break;
|
||||
case 16:
|
||||
ipic->genCtrl[slot] = IPIC_GEN_WIDTH_16 |
|
||||
(ipic->genCtrl[slot] & ~IPIC_GEN_WIDTH);
|
||||
break;
|
||||
case 32:
|
||||
if (slot & 1) {
|
||||
/* Illegal for odd-numbered slots */
|
||||
return S_IPAC_badAddress;
|
||||
}
|
||||
ipic->genCtrl[slot] = IPIC_GEN_WIDTH_32 |
|
||||
(ipic->genCtrl[slot] & ~IPIC_GEN_WIDTH);
|
||||
ipic->genCtrl[slot+1] &= ~(IPIC_GEN_WIDTH |
|
||||
IPIC_GEN_MEN);
|
||||
break;
|
||||
default:
|
||||
return S_IPAC_badAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
initialised = TRUE;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Routine:
|
||||
baseAddr
|
||||
|
||||
Purpose:
|
||||
Returns the base address for the requested slot & address space
|
||||
|
||||
Description:
|
||||
This routine only has to do a table lookup in the mBase array.
|
||||
Note that no parameter checking is required - the IPAC driver which
|
||||
calls this routine handles that.
|
||||
|
||||
Returns:
|
||||
The requested address, or NULL if the slot has no memory in the
|
||||
requested address space.
|
||||
|
||||
*/
|
||||
|
||||
LOCAL void *baseAddr (
|
||||
void *private,
|
||||
ushort_t slot,
|
||||
ipac_addr_t space
|
||||
) {
|
||||
return (void *) mBase[space][slot];
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Routine:
|
||||
irqCmd
|
||||
|
||||
Purpose:
|
||||
Handles interrupter commands and status requests
|
||||
|
||||
Description:
|
||||
The IPIC chip allows a lot of control over the IP interrupters, thus
|
||||
all commands perform the requested action.
|
||||
|
||||
Returns:
|
||||
ipac_irqGetLevel returns the current interrupt level,
|
||||
ipac_irqPoll returns >0 if interrupt line active else 0,
|
||||
other calls return 0 = OK.
|
||||
|
||||
*/
|
||||
|
||||
LOCAL int irqCmd (
|
||||
void *private,
|
||||
ushort_t slot,
|
||||
ushort_t irqNumber,
|
||||
ipac_irqCmd_t cmd
|
||||
) {
|
||||
switch (cmd) {
|
||||
case ipac_irqLevel0:
|
||||
case ipac_irqLevel1:
|
||||
case ipac_irqLevel2:
|
||||
case ipac_irqLevel3:
|
||||
case ipac_irqLevel4:
|
||||
case ipac_irqLevel5:
|
||||
case ipac_irqLevel6:
|
||||
case ipac_irqLevel7:
|
||||
ipic->intCtrl[slot][irqNumber] = (cmd & IPIC_INT_LEVEL) |
|
||||
(ipic->intCtrl[slot][irqNumber] & ~IPIC_INT_LEVEL);
|
||||
return OK;
|
||||
|
||||
case ipac_irqGetLevel:
|
||||
return ipic->intCtrl[slot][irqNumber] & IPIC_INT_LEVEL;
|
||||
|
||||
case ipac_irqEnable:
|
||||
ipic->intCtrl[slot][irqNumber] |= IPIC_INT_IEN;
|
||||
return OK;
|
||||
|
||||
case ipac_irqDisable:
|
||||
ipic->intCtrl[slot][irqNumber] &= ~IPIC_INT_IEN;
|
||||
return OK;
|
||||
|
||||
case ipac_irqPoll:
|
||||
return ipic->intCtrl[slot][irqNumber] & IPIC_INT_INT;
|
||||
|
||||
case ipac_irqSetEdge:
|
||||
ipic->intCtrl[slot][irqNumber] |= IPIC_INT_EDGE;
|
||||
return OK;
|
||||
|
||||
case ipac_irqSetLevel:
|
||||
ipic->intCtrl[slot][irqNumber] &= ~IPIC_INT_EDGE;
|
||||
return OK;
|
||||
|
||||
case ipac_irqClear:
|
||||
ipic->intCtrl[slot][irqNumber] |= IPIC_INT_ICLR;
|
||||
return OK;
|
||||
|
||||
default:
|
||||
return S_IPAC_notImplemented;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
/* IPAC Carrier Table */
|
||||
|
||||
ipac_carrier_t ipmv162 = {
|
||||
"Motorola MVME162",
|
||||
SLOTS,
|
||||
initialise,
|
||||
NULL,
|
||||
baseAddr,
|
||||
irqCmd
|
||||
};
|
||||
|
||||
@@ -1,520 +0,0 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Project:
|
||||
Gemini/UKIRT CAN Bus Driver for EPICS
|
||||
|
||||
File:
|
||||
drvIpac.c
|
||||
|
||||
Description:
|
||||
IPAC Driver, provides a standard interface between IPAC Module
|
||||
drivers and the IPAC Carrier drivers.
|
||||
|
||||
Author:
|
||||
Andrew Johnson
|
||||
Created:
|
||||
3 July 1995
|
||||
|
||||
(c) 1995 Royal Greenwich Observatory
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
#ifndef NO_EPICS
|
||||
# include <drvSup.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <vxLib.h>
|
||||
#include "drvIpac.h"
|
||||
|
||||
|
||||
#define IPAC_MAX_CARRIERS 21
|
||||
|
||||
|
||||
/* Private carrier data structures */
|
||||
struct carrierInfo {
|
||||
ipac_carrier_t *driver;
|
||||
void *cPrivate;
|
||||
};
|
||||
|
||||
LOCAL struct {
|
||||
ushort_t number;
|
||||
struct carrierInfo *info[IPAC_MAX_CARRIERS];
|
||||
} carriers = {
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
/* Null carrier stuff */
|
||||
|
||||
LOCAL ipac_carrier_t nullCarrier = {
|
||||
"Null carrier (place holder)",
|
||||
0, /* No slots */
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
LOCAL struct carrierInfo nullInfo = {
|
||||
&nullCarrier,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
#ifndef NO_EPICS
|
||||
|
||||
/* EPICS Driver Support Entry Table */
|
||||
|
||||
struct drvet drvIpac = {
|
||||
3,
|
||||
(DRVSUPFUN) ipacReport,
|
||||
(DRVSUPFUN) ipacInitialise,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Routine:
|
||||
ipacAddCarrier
|
||||
|
||||
Purpose:
|
||||
Used to register a carrier board & carrier driver with the IPAC driver.
|
||||
|
||||
Description:
|
||||
Usually called from the vxWorks (EPICS) startup script. Some types of
|
||||
carrier may need additional initilisation before or after registering,
|
||||
but the card parameter string should be sufficient for most carriers.
|
||||
Note that only the carrier initialise routine is called at this stage.
|
||||
The order in which carriers are registered with this routine specifies
|
||||
the carrier number which they will be allocated, starting from zero.
|
||||
|
||||
Checks that the carrier descriptor table looks sensible, then calls the
|
||||
initialise routine with the given card parameters, and saves the carrier
|
||||
private pointer and carrier table address. The card number allows the
|
||||
same descriptor to be used for all carriers of the same type.
|
||||
|
||||
It may be necessary to remove a carrier temporarily from a system in
|
||||
some circumstances without wanting to have to change the carrier number
|
||||
allocated to higher numbered carriers. To allow this, it is legal to
|
||||
call this routine with a NULL (zero) carrier table address, which
|
||||
switches in the null carrier table instead.
|
||||
|
||||
Returns:
|
||||
0 = OK,
|
||||
S_IPAC_tooMany = Carrier Info Table full,
|
||||
S_IPAC_badTable = Carrier Table invalid.
|
||||
|
||||
Example:
|
||||
ipacAddCarrier(&vipc310, "0x6000");
|
||||
|
||||
*/
|
||||
|
||||
int ipacAddCarrier (
|
||||
ipac_carrier_t *pcarrierTable,
|
||||
char *cardParams
|
||||
) {
|
||||
void *cPrivate;
|
||||
int status;
|
||||
|
||||
if (carriers.number >= IPAC_MAX_CARRIERS) {
|
||||
return S_IPAC_tooMany;
|
||||
}
|
||||
|
||||
if (pcarrierTable == NULL) {
|
||||
carriers.info[carriers.number] = &nullInfo;
|
||||
carriers.number++;
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (pcarrierTable->numberSlots == 0 ||
|
||||
pcarrierTable->initialise == NULL ||
|
||||
pcarrierTable->baseAddr == NULL ||
|
||||
pcarrierTable->irqCmd == NULL) {
|
||||
return S_IPAC_badTable;
|
||||
}
|
||||
|
||||
status = pcarrierTable->initialise(cardParams, &cPrivate);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
|
||||
carriers.info[carriers.number] = malloc(sizeof (struct carrierInfo));
|
||||
carriers.info[carriers.number]->driver = pcarrierTable;
|
||||
carriers.info[carriers.number]->cPrivate = cPrivate;
|
||||
carriers.number++;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Routine:
|
||||
ipmCheck
|
||||
|
||||
Function:
|
||||
Check on presence of an IPAC module at the given carrier & slot number.
|
||||
|
||||
Description:
|
||||
Does a quick check to make sure the carrier and slot numbers are legal,
|
||||
probes the IDprom space to ensure an IPAC is installed, and checks that
|
||||
the IDprom starts with the "IPAC" identifier.
|
||||
|
||||
Returns:
|
||||
0 = OK,
|
||||
S_IPAC_badAddress = Bad carrier or slot number,
|
||||
S_IPAC_noModule = No module installed,
|
||||
S_IPAC_noIpacId = "IPAC" identifier not found
|
||||
|
||||
*/
|
||||
|
||||
int ipmCheck (
|
||||
ushort_t carrier,
|
||||
ushort_t slot
|
||||
) {
|
||||
ipac_idProm_t *id;
|
||||
char dummy;
|
||||
|
||||
if (carrier >= carriers.number ||
|
||||
slot >= carriers.info[carrier]->driver->numberSlots) {
|
||||
return S_IPAC_badAddress;
|
||||
}
|
||||
|
||||
id = (ipac_idProm_t *) ipmBaseAddr(carrier, slot, ipac_addrID);
|
||||
if (id == NULL) {
|
||||
return S_IPAC_badDriver;
|
||||
}
|
||||
|
||||
if (vxMemProbe((void *)&id->asciiI, READ, 1, &dummy)) {
|
||||
return S_IPAC_noModule;
|
||||
}
|
||||
|
||||
if (id->asciiI != 'I' ||
|
||||
id->asciiP != 'P' ||
|
||||
id->asciiA != 'A' ||
|
||||
id->asciiC != 'C') {
|
||||
return S_IPAC_noIpacId; /* Not an IPAC */
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Routine:
|
||||
checkCRC
|
||||
|
||||
Function:
|
||||
Calculate the CRC of the IDprom at the given address.
|
||||
|
||||
Description:
|
||||
Generates an industry standard CRC of the ID Prom data as described
|
||||
in the GreenSpring Industry Pack specification. The CRC byte in the
|
||||
Prom (at address 0x17) is set to zero for the purpose of calculating
|
||||
the CRC.
|
||||
|
||||
Returns:
|
||||
The low 8 bits of the calculated CRC value.
|
||||
|
||||
*/
|
||||
|
||||
LOCAL int checkCRC (
|
||||
uchar_t *data,
|
||||
ushort_t length
|
||||
) {
|
||||
uint_t i, crc = 0xffff;
|
||||
uchar_t mask;
|
||||
|
||||
for (i = 1; i < 2*length; i += 2) {
|
||||
mask = 0x80;
|
||||
while (mask) {
|
||||
if ((data[i] & mask) && (i != 0x17)) {
|
||||
crc ^= 0x8000;
|
||||
}
|
||||
crc += crc;
|
||||
if (crc > 0xffff) {
|
||||
crc = (crc & 0xffff) ^ 0x1021;
|
||||
}
|
||||
mask >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return (~crc) & 0xff;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Routine:
|
||||
ipmValidate
|
||||
|
||||
Function:
|
||||
Validate a particular IPAC module type at the given carrier & slot number.
|
||||
|
||||
Description:
|
||||
Uses ipmCheck to ensure the carrier and slot numbers are legal, probe the
|
||||
IDprom and check that the IDprom looks like an IPAC module. Calculates
|
||||
the CRC for the ID Prom, and compares the manufacturer and model ID values
|
||||
in the Prom to the ones given.
|
||||
|
||||
Returns:
|
||||
0 = OK,
|
||||
S_IPAC_badAddress = Bad carrier or slot number,
|
||||
S_IPAC_noModule = No module installed,
|
||||
S_IPAC_noIpacId = "IPAC" identifier not found
|
||||
S_IPAC_badCRC = CRC Check failed,
|
||||
S_IPAC_badModule = Manufacturer or model IDs wrong
|
||||
|
||||
*/
|
||||
|
||||
int ipmValidate (
|
||||
ushort_t carrier,
|
||||
ushort_t slot,
|
||||
uchar_t manufacturerId,
|
||||
uchar_t modelId
|
||||
) {
|
||||
ipac_idProm_t *id;
|
||||
int status;
|
||||
|
||||
status = ipmCheck(carrier, slot);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
|
||||
id = (ipac_idProm_t *) ipmBaseAddr(carrier, slot, ipac_addrID);
|
||||
if (checkCRC((uchar_t *) id, id->bytesUsed) != id->CRC) {
|
||||
return S_IPAC_badCRC;
|
||||
}
|
||||
|
||||
if (id->manufacturerId != manufacturerId ||
|
||||
id->modelId != modelId) {
|
||||
return S_IPAC_badModule;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Routine:
|
||||
ipmReport
|
||||
|
||||
Function:
|
||||
returns printable string giving status of module at given carrier/slot.
|
||||
|
||||
Description:
|
||||
Generates a report string describing the given IPAC slot. If a module
|
||||
is installed, it includes the manufacturer and model ID numbers. If
|
||||
the report function is supported by the carrier driver this report
|
||||
string is appended.
|
||||
|
||||
Returns:
|
||||
Pointer to static, printable string.
|
||||
|
||||
Sample Output:
|
||||
"C0 S1 : 0xB1/0x01 - M0 L4,5"
|
||||
|
||||
*/
|
||||
|
||||
char *ipmReport (
|
||||
ushort_t carrier,
|
||||
ushort_t slot
|
||||
) {
|
||||
static char report[80];
|
||||
int status;
|
||||
|
||||
sprintf(report, "C%hd S%hd : ", carrier, slot);
|
||||
|
||||
status = ipmCheck(carrier, slot);
|
||||
if (status == S_IPAC_badAddress) {
|
||||
strcat(report, "No such carrier/slot");
|
||||
return report;
|
||||
}
|
||||
|
||||
if (status == S_IPAC_noModule) {
|
||||
strcat(report, "No Module");
|
||||
} else {
|
||||
ipac_idProm_t *id;
|
||||
char module[16];
|
||||
|
||||
id = (ipac_idProm_t *) ipmBaseAddr(carrier, slot, ipac_addrID);
|
||||
sprintf(module, "0x%02hX/0x%02hX", (short) id->manufacturerId,
|
||||
(short) id->modelId);
|
||||
strcat(report, module);
|
||||
}
|
||||
|
||||
if (carriers.info[carrier]->driver->report != NULL) {
|
||||
strcat(report, " - ");
|
||||
strcat(report, carriers.info[carrier]->driver->report(
|
||||
carriers.info[carrier]->cPrivate, slot));
|
||||
}
|
||||
|
||||
return report;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Routine:
|
||||
ipmBaseAddr
|
||||
|
||||
Function:
|
||||
Returns a pointer to the selected IP address space
|
||||
|
||||
Description:
|
||||
Checks its input parameters, then calls the carrier driver. This will
|
||||
return a pointer to the location of the address space indicated by the
|
||||
space parameter. All IP modules must provide an ID prom to indicate
|
||||
the module type (space = ipac_addrID). Most modules need register I/O
|
||||
locations, which are in the I/O space (space = ipac_addrIO). Some
|
||||
types of module also provide memory (space = ipac_addrMem), but if
|
||||
this is not required the carrier may allow it to be disabled, in which
|
||||
case the driver should return a NULL for this address space. Some
|
||||
carriers provide a 32-bit wide I/O space for Dual-slot IP modules;
|
||||
carriers which do not should return NULL for this space.
|
||||
|
||||
Returns:
|
||||
Base CPU address of IP address space, or NULL pointer.
|
||||
|
||||
*/
|
||||
|
||||
void *ipmBaseAddr (
|
||||
ushort_t carrier,
|
||||
ushort_t slot,
|
||||
ipac_addr_t space
|
||||
) {
|
||||
if (carrier >= carriers.number ||
|
||||
slot >= carriers.info[carrier]->driver->numberSlots) {
|
||||
return NULL;
|
||||
}
|
||||
return carriers.info[carrier]->driver->baseAddr(
|
||||
carriers.info[carrier]->cPrivate, slot, space);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Routine:
|
||||
ipmIrqCmd
|
||||
|
||||
Function:
|
||||
Send command to slot interrupt controller.
|
||||
|
||||
Description:
|
||||
Checks input parameters, then passes the interrupt command request to
|
||||
the carrier driver routine. The driver is only required to support
|
||||
the command ipac_irqEnable; for other commands it may return the status
|
||||
code S_IPAC_notImplemented and do nothing.
|
||||
|
||||
Returns:
|
||||
0 = OK,
|
||||
S_IPAC_badAddress = illegal carrier, slot or irqNumber,
|
||||
S_IPAC_notImplemented = Driver does not support that command,
|
||||
other, depending on command.
|
||||
|
||||
*/
|
||||
|
||||
int ipmIrqCmd (
|
||||
ushort_t carrier,
|
||||
ushort_t slot,
|
||||
ushort_t irqNumber,
|
||||
ipac_irqCmd_t cmd
|
||||
) {
|
||||
if (irqNumber > 1 ||
|
||||
carrier >= carriers.number ||
|
||||
slot >= carriers.info[carrier]->driver->numberSlots) {
|
||||
return S_IPAC_badAddress;
|
||||
}
|
||||
|
||||
return carriers.info[carrier]->driver->irqCmd(
|
||||
carriers.info[carrier]->cPrivate, slot, irqNumber, cmd);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Routine:
|
||||
ipacReport
|
||||
|
||||
Function:
|
||||
Report status of all known IPAC carriers
|
||||
|
||||
Description:
|
||||
Prints information on each known carrier board and slot according to the
|
||||
specified interest level. Level 0 lists carriers only, with the number
|
||||
of slots it supports. Level 1 gives each slot, manufacturer & model ID
|
||||
of the installed module (if any), and the carrier driver report for that
|
||||
slot. Level 2 adds the address of each memory space for the slot.
|
||||
|
||||
Returns:
|
||||
OK.
|
||||
|
||||
*/
|
||||
|
||||
int ipacReport (
|
||||
int interest
|
||||
) {
|
||||
ushort_t carrier, slot;
|
||||
|
||||
for (carrier=0; carrier < carriers.number; carrier++) {
|
||||
printf(" IP Carrier %2d: %s, %d slots\n", carrier,
|
||||
carriers.info[carrier]->driver->carrierType,
|
||||
carriers.info[carrier]->driver->numberSlots);
|
||||
|
||||
if (interest > 0) {
|
||||
long memBase, io32Base;
|
||||
|
||||
for (slot=0; slot < carriers.info[carrier]->driver->numberSlots;
|
||||
slot++) {
|
||||
printf(" %s\n", ipmReport(carrier, slot));
|
||||
|
||||
if (interest > 1) {
|
||||
printf(" ID = 0x%lx, I/O = 0x%lx",
|
||||
(long) ipmBaseAddr(carrier, slot, ipac_addrID),
|
||||
(long) ipmBaseAddr(carrier, slot, ipac_addrIO));
|
||||
io32Base = (long) ipmBaseAddr(carrier, slot, ipac_addrIO32);
|
||||
if (io32Base != NULL) {
|
||||
printf(", I/O32 = 0x%lx", io32Base);
|
||||
}
|
||||
memBase = (long) ipmBaseAddr(carrier, slot, ipac_addrMem);
|
||||
if (memBase != NULL) {
|
||||
printf(", Mem = 0x%lx", memBase);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Routine:
|
||||
ipacInitialise
|
||||
|
||||
Function:
|
||||
Initialise the IPAC driver
|
||||
|
||||
Description:
|
||||
Null routine.
|
||||
|
||||
Returns:
|
||||
OK.
|
||||
|
||||
*/
|
||||
|
||||
int ipacInitialise (
|
||||
int after
|
||||
) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Project:
|
||||
Gemini/UKIRT CAN Bus Driver for EPICS
|
||||
|
||||
File:
|
||||
drvIpac.h
|
||||
|
||||
Description:
|
||||
IPAC Driver header file, defines the software interfaces:
|
||||
1. Upwards to the IPAC Module driver
|
||||
2. Downwards to the IPAC Carrier driver
|
||||
|
||||
Author:
|
||||
Andrew Johnson
|
||||
Created:
|
||||
1 July 1995
|
||||
|
||||
(c) 1995 Royal Greenwich Observatory
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
#ifndef INCdrvIpacH
|
||||
#define INCdrvIpacH
|
||||
|
||||
#include <types.h>
|
||||
#include "ipModules.h"
|
||||
|
||||
#ifndef NO_EPICS
|
||||
#include <errMdef.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Error numbers */
|
||||
|
||||
#ifndef OK
|
||||
#define OK 0
|
||||
#endif
|
||||
|
||||
#ifndef M_ipac
|
||||
#define M_ipac (600 << 16)
|
||||
#endif
|
||||
|
||||
#define S_IPAC_badTable (M_ipac| 1) /*IPAC Carrier Table invalid*/
|
||||
#define S_IPAC_tooMany (M_ipac| 2) /*Too many IPAC carriers, table full*/
|
||||
#define S_IPAC_badAddress (M_ipac| 3) /*Bad IPAC carrier or slot number*/
|
||||
#define S_IPAC_badDriver (M_ipac| 4) /*Bad value from IPAC carrier driver*/
|
||||
#define S_IPAC_noModule (M_ipac| 5) /*No IP module installed*/
|
||||
#define S_IPAC_noIpacId (M_ipac| 6) /*IPAC identifier not found*/
|
||||
#define S_IPAC_badCRC (M_ipac| 7) /*IPAC CRC Check failed*/
|
||||
#define S_IPAC_badModule (M_ipac| 8) /*IPAC Manufacturer or model ID wrong*/
|
||||
#define S_IPAC_notImplemented (M_ipac| 9) /*IPAC Driver command not available*/
|
||||
|
||||
|
||||
/* Structure of the IPAC ID Prom, located in the pack ID space. */
|
||||
|
||||
typedef struct {
|
||||
uchar_t pad00;
|
||||
uchar_t asciiI;
|
||||
uchar_t pad02;
|
||||
uchar_t asciiP;
|
||||
uchar_t pad04;
|
||||
uchar_t asciiA;
|
||||
uchar_t pad06;
|
||||
uchar_t asciiC;
|
||||
uchar_t pad08;
|
||||
uchar_t manufacturerId;
|
||||
uchar_t pad0a;
|
||||
uchar_t modelId;
|
||||
uchar_t pad0c;
|
||||
uchar_t revision;
|
||||
uchar_t pad0e;
|
||||
uchar_t reserved;
|
||||
uchar_t pad10;
|
||||
uchar_t driverIdLow;
|
||||
uchar_t pad12;
|
||||
uchar_t driverIdHigh;
|
||||
uchar_t pad14;
|
||||
uchar_t bytesUsed;
|
||||
uchar_t pad16;
|
||||
uchar_t CRC;
|
||||
uchar_t pad18;
|
||||
uchar_t packSpecific[0x3f-0x18];
|
||||
} ipac_idProm_t;
|
||||
|
||||
|
||||
/* These are the types of address space implemented in the IP
|
||||
specification. Some IP modules only use the ID and IO spaces. */
|
||||
|
||||
#define IPAC_ADDR_SPACES 4
|
||||
|
||||
typedef enum {
|
||||
ipac_addrID = 0, /* ID Prom space */
|
||||
ipac_addrIO = 1, /* Registers etc */
|
||||
ipac_addrIO32 = 2, /* Registers for 32-bit dual-slot */
|
||||
ipac_addrMem = 3 /* Memory space */
|
||||
} ipac_addr_t;
|
||||
|
||||
|
||||
/* The following are the possible commands to the carrier driver to
|
||||
handle interrupts from the IP modules. Some carriers will only be
|
||||
able to implement a subset of these commands. Note that irqEnable
|
||||
should call the vxWorks sysBusEnable routine if this is needed to
|
||||
pass the carrier interrupts through to the CPU. */
|
||||
|
||||
typedef enum {
|
||||
ipac_irqLevel0 = 0, /* Disables interrupts */
|
||||
ipac_irqLevel1 = 1, /* Lowest priority */
|
||||
ipac_irqLevel2 = 2,
|
||||
ipac_irqLevel3 = 3,
|
||||
ipac_irqLevel4 = 4,
|
||||
ipac_irqLevel5 = 5,
|
||||
ipac_irqLevel6 = 6, /* Highest priority */
|
||||
ipac_irqLevel7 = 7, /* Non-maskable, don't use */
|
||||
ipac_irqGetLevel, /* Returns level set (or hard-coded) */
|
||||
ipac_irqEnable, /* Required to use interrupts */
|
||||
ipac_irqDisable, /* Not necessarily supported */
|
||||
ipac_irqPoll, /* Returns interrupt state */
|
||||
ipac_irqSetEdge, /* Sets edge-triggered interrupts */
|
||||
ipac_irqSetLevel, /* Sets level-triggered (default) */
|
||||
ipac_irqClear /* Only needed if using edge-triggered */
|
||||
} ipac_irqCmd_t;
|
||||
|
||||
|
||||
/* This is a table which each IPAC carrier driver provides to allow
|
||||
it to be queried by the IPAC driver. One table is required for
|
||||
each type of carrier. The cPrivate pointer is returned by the
|
||||
carrier driver initialise routine, and passed to all of the other
|
||||
routines as a means of identification of the carrier board. */
|
||||
|
||||
typedef struct {
|
||||
char *carrierType;
|
||||
/* String containing carrier board type */
|
||||
ushort_t numberSlots;
|
||||
/* Number of IPAC devices this carrier can hold */
|
||||
int (*initialise)(char *cardParams, void **cPrivate);
|
||||
/* Initialise carrier and return *cPrivate */
|
||||
char *(*report)(void *cPrivate, ushort_t slot);
|
||||
/* Return string with giving status of this slot */
|
||||
void *(*baseAddr)(void *cPrivate, ushort_t slot, ipac_addr_t space);
|
||||
/* Return base addresses for this slot */
|
||||
int (*irqCmd)(void *cPrivate, ushort_t slot,
|
||||
ushort_t irqNumber, ipac_irqCmd_t cmd);
|
||||
/* interrupt manipulation */
|
||||
} ipac_carrier_t;
|
||||
|
||||
|
||||
/* Functions for startup and interactive use */
|
||||
|
||||
extern int ipacAddCarrier(ipac_carrier_t *pcarrier, char *cardParams);
|
||||
extern int ipacReport(int interest);
|
||||
extern int ipacInitialise(int after);
|
||||
|
||||
|
||||
/* Functions for use in IPAC module drivers */
|
||||
|
||||
extern int ipmCheck(ushort_t carrier, ushort_t slot);
|
||||
extern int ipmValidate(ushort_t carrier, ushort_t slot,
|
||||
uchar_t manufacturerId, uchar_t modelId);
|
||||
extern char *ipmReport(ushort_t carrier, ushort_t slot);
|
||||
extern void *ipmBaseAddr(ushort_t carrier, ushort_t slot, ipac_addr_t space);
|
||||
extern int ipmIrqCmd(ushort_t carrier, ushort_t slot,
|
||||
ushort_t irqNumber, ipac_irqCmd_t cmd);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* INCipacH */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,48 +0,0 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Project:
|
||||
Gemini/UKIRT CAN Bus Driver for EPICS
|
||||
|
||||
File:
|
||||
drvTip810.h
|
||||
|
||||
Description:
|
||||
Header file for TEWS TIP810 CAN Bus driver.
|
||||
|
||||
Author:
|
||||
Andrew Johnson
|
||||
Created:
|
||||
20 July 1995
|
||||
|
||||
(c) 1995 Royal Greenwich Observatory
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
#ifndef INCdrvTip810H
|
||||
#define INCdrvTip810H
|
||||
|
||||
#include <types.h>
|
||||
#include "canBus.h"
|
||||
|
||||
|
||||
/* Error Numbers */
|
||||
|
||||
#ifndef M_t810
|
||||
#define M_t810 (810<<16)
|
||||
#endif
|
||||
|
||||
#define S_t810_duplicateDevice (M_t810| 1) /*duplicate t810 device definition*/
|
||||
#define S_t810_badBusRate (M_t810| 2) /*CANbus bit rate not supported*/
|
||||
#define S_t810_badDevice (M_t810| 3) /*device pointer is not for t810*/
|
||||
#define S_t810_transmitterBusy (M_t810| 4) /*transmit buffer unexpectedly busy*/
|
||||
|
||||
|
||||
extern int t810Report(int page);
|
||||
extern int t810Create(char *busName, ushort_t card, ushort_t slot,
|
||||
uint_t busRate);
|
||||
extern int t810Shutdown(int starttype);
|
||||
extern int t810Initialise(void);
|
||||
|
||||
#endif /* INCdrvTip810H */
|
||||
|
||||
@@ -1,262 +0,0 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Project:
|
||||
Gemini/UKIRT CAN Bus Driver for EPICS
|
||||
|
||||
File:
|
||||
drvVipc310.c
|
||||
|
||||
Description:
|
||||
IPAC Carrier Driver for the GreenSpring VIPC310 Dual IndustryPack
|
||||
Carrier VME board, provides the interface between IPAC driver and the
|
||||
hardware. This carrier is 3U high, and thus cannot support 32-bit
|
||||
accesses to dual-slot IP modules.
|
||||
|
||||
Author:
|
||||
Andrew Johnson
|
||||
Created:
|
||||
5 July 1995
|
||||
|
||||
(c) 1995 Royal Greenwich Observatory
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <vme.h>
|
||||
#include <sysLib.h>
|
||||
#include "drvIpac.h"
|
||||
|
||||
|
||||
/* Characteristics of the card */
|
||||
|
||||
#define SLOTS 2
|
||||
#define IO_SPACES 2 /* Address spaces in A16 */
|
||||
#define IPAC_IRQS 2 /* Interrupts per module */
|
||||
|
||||
|
||||
/* Offsets from base address in VME A16 */
|
||||
|
||||
#define REGS_A 0x0000
|
||||
#define PROM_A 0x0080
|
||||
#define REGS_B 0x0100
|
||||
#define PROM_B 0x0180
|
||||
|
||||
|
||||
/* VME Interrupt levels */
|
||||
|
||||
#define IRQ_A0 4
|
||||
#define IRQ_A1 5
|
||||
#define IRQ_B0 2
|
||||
#define IRQ_B1 1
|
||||
|
||||
|
||||
/* Carrier Private structure type, one instance per board */
|
||||
|
||||
typedef void* private_t[IPAC_ADDR_SPACES][SLOTS];
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Routine:
|
||||
initialise
|
||||
|
||||
Purpose:
|
||||
Creates new private table for VIPC310 at addresses given by cardParams
|
||||
|
||||
Description:
|
||||
Checks the parameter string for the address of the card I/O space and
|
||||
optional size of the memory space for the modules. If both the I/O and
|
||||
memory base addresses can be reached from the CPU, a private table is
|
||||
created for this board. The private table is a 2-D array of pointers
|
||||
to the base addresses of the various accessible parts of the IP module.
|
||||
|
||||
Parameters:
|
||||
The parameter string should comprise a hex number (the 0x or 0X at the
|
||||
start is optional) optionally followed by a comma and a decimal integer.
|
||||
The first number is the I/O base address of the card in the VME A16
|
||||
address space (the factory default is 0x6000). If present the second
|
||||
number gives the memory space in Kbytes allocated to each IP module.
|
||||
The memory base address of the VIPC310 card is set using the same jumpers
|
||||
as the I/O base address and is always 256 times the I/O base address,
|
||||
but in the VME A24 address space. The factory default fot the memory
|
||||
base address is thus 0x600000. If the memory size parameter is omitted
|
||||
or set to zero then neither IP module provides any memory space. Legal
|
||||
memory size values are 0, 64, 128, 256, 512, 1024 or 2048. The memory
|
||||
size interacts with the memory base address such that it is possible to
|
||||
set the existance of memory in either slot independently with suitable
|
||||
adjustment of the base address.
|
||||
|
||||
Examples:
|
||||
"0x6000"
|
||||
This indicates that the carrier has its I/O base set to 0x6000, and
|
||||
neither slot uses any memory space.
|
||||
"1000,512"
|
||||
Here the I/O base is set to 0x1000, and there is 512 Kbytes of
|
||||
memory on each module, with the IP module A memory at 0x100000
|
||||
and module B at 0x180000.
|
||||
"0xfe00, 128"
|
||||
The I/O base is at 0xfe00, and hence the carrier memory base is
|
||||
0xfe0000. However because the memory size is set to give each module
|
||||
128 Kbytes of memory space, module A cannot be selected (128 K =
|
||||
0x020000, so the module is decoded at 0xfc0000 but can't be accessed
|
||||
because this is below the memory base).
|
||||
|
||||
Returns:
|
||||
0 = OK,
|
||||
S_IPAC_badAddress = Parameter string error, or address not reachable
|
||||
|
||||
*/
|
||||
|
||||
LOCAL int initialise (
|
||||
char *cardParams,
|
||||
void **pprivate
|
||||
) {
|
||||
int params, status1 = OK, status2 = OK, mSize = 0;
|
||||
long ioBase, mOrig, mBase;
|
||||
ushort_t space, slot;
|
||||
private_t *private;
|
||||
static const int offset[IO_SPACES][SLOTS] = {
|
||||
PROM_A, PROM_B,
|
||||
REGS_A, REGS_B
|
||||
};
|
||||
|
||||
if (cardParams == NULL ||
|
||||
strlen(cardParams) == 0) {
|
||||
ioBase = 0x6000;
|
||||
} else {
|
||||
params = sscanf(cardParams, "%p,%i", (void **) &ioBase, &mSize);
|
||||
if (params < 1 || params > 2 ||
|
||||
ioBase > 0xfe00 || ioBase & 0x01ff ||
|
||||
mSize < 0 || mSize > 2048 || mSize & 63) {
|
||||
return S_IPAC_badAddress;
|
||||
}
|
||||
}
|
||||
|
||||
mBase = ioBase << 8; /* Fixed by VIPC310 card */
|
||||
|
||||
status1 = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,
|
||||
(char *) ioBase, (char **) &ioBase);
|
||||
if (mSize > 0) {
|
||||
status2 = sysBusToLocalAdrs(VME_AM_STD_SUP_DATA,
|
||||
(char *) mBase, (char **) &mBase);
|
||||
}
|
||||
if (status1 || status2) {
|
||||
return S_IPAC_badAddress;
|
||||
}
|
||||
|
||||
mSize = mSize << 10; /* Convert size from K to Bytes */
|
||||
mOrig = mBase & ~(mSize * SLOTS - 1);
|
||||
|
||||
private = malloc(sizeof (private_t));
|
||||
for (space = 0; space < IO_SPACES; space++) {
|
||||
for (slot = 0; slot < SLOTS; slot++) {
|
||||
(*private)[space][slot] = (void *) (ioBase + offset[space][slot]);
|
||||
}
|
||||
}
|
||||
|
||||
(*private)[ipac_addrIO32][0] = NULL;
|
||||
(*private)[ipac_addrIO32][1] = NULL;
|
||||
|
||||
if (mOrig == mBase) {
|
||||
(*private)[ipac_addrMem][0] = (void *) mBase;
|
||||
(*private)[ipac_addrMem][1] = (void *) (mBase + mSize);
|
||||
} else {
|
||||
(*private)[ipac_addrMem][0] = NULL;
|
||||
(*private)[ipac_addrMem][1] = (void *) mBase;
|
||||
}
|
||||
|
||||
*pprivate = private;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Routine:
|
||||
baseAddr
|
||||
|
||||
Purpose:
|
||||
Returns the base address for the requested slot & address space
|
||||
|
||||
Description:
|
||||
Because we did all that hard work in the initialise routine, this
|
||||
routine only has to do a table lookup in the private array.
|
||||
Note that no parameter checking is required - the IPAC driver which
|
||||
calls this routine handles that.
|
||||
|
||||
Returns:
|
||||
The requested address, or NULL if the module has no memory.
|
||||
|
||||
*/
|
||||
|
||||
LOCAL void *baseAddr (
|
||||
void *private,
|
||||
ushort_t slot,
|
||||
ipac_addr_t space
|
||||
) {
|
||||
return (*(private_t *) private)[space][slot];
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Routine:
|
||||
irqCmd
|
||||
|
||||
Purpose:
|
||||
Handles interrupter commands and status requests
|
||||
|
||||
Description:
|
||||
The GreenSpring board is limited to fixed interrupt levels, and has
|
||||
no control over interrupts. The only commands thus supported are
|
||||
a request of the interrupt level associated with a particular slot
|
||||
and interrupt number, or to enable interrupts by making sure the
|
||||
VMEbus interrupter is listening on the necessary level.
|
||||
|
||||
Returns:
|
||||
ipac_irqGetLevel returns the interrupt level (1, 2, 4 or 5),
|
||||
ipac_irqEnable returns 0 = OK,
|
||||
other calls return S_IPAC_notImplemented.
|
||||
|
||||
*/
|
||||
|
||||
LOCAL int irqCmd (
|
||||
void *private,
|
||||
ushort_t slot,
|
||||
ushort_t irqNumber,
|
||||
ipac_irqCmd_t cmd
|
||||
) {
|
||||
static const int irqLevel[SLOTS][IPAC_IRQS] = {
|
||||
IRQ_A0, IRQ_A1,
|
||||
IRQ_B0, IRQ_B1
|
||||
};
|
||||
|
||||
switch (cmd) {
|
||||
case ipac_irqGetLevel:
|
||||
return irqLevel[slot][irqNumber];
|
||||
|
||||
case ipac_irqEnable:
|
||||
sysIntEnable(irqLevel[slot][irqNumber]);
|
||||
return OK;
|
||||
|
||||
default:
|
||||
return S_IPAC_notImplemented;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
/* IPAC Carrier Table */
|
||||
|
||||
ipac_carrier_t vipc310 = {
|
||||
"GreenSpring VIPC310",
|
||||
SLOTS,
|
||||
initialise,
|
||||
NULL,
|
||||
baseAddr,
|
||||
irqCmd
|
||||
};
|
||||
|
||||
@@ -1,275 +0,0 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Project:
|
||||
Gemini/UKIRT CAN Bus Driver for EPICS
|
||||
|
||||
File:
|
||||
drvVipc610.c
|
||||
|
||||
Description:
|
||||
IPAC Carrier Driver for the GreenSpring VIPC610-01 Quad IndustryPack
|
||||
Carrier VME board, provides the interface between IPAC driver and the
|
||||
hardware. This carrier is 6U high, but cannot support 32-bit accesses
|
||||
to dual-slot IP modules. Note the -01 option fixes the IRQ levels to
|
||||
be equivalent to two VIPC310 carriers.
|
||||
|
||||
Author:
|
||||
Andrew Johnson
|
||||
Created:
|
||||
19 July 1995
|
||||
|
||||
(c) 1995 Royal Greenwich Observatory
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <vme.h>
|
||||
#include <sysLib.h>
|
||||
#include "drvIpac.h"
|
||||
|
||||
|
||||
/* Characteristics of the card */
|
||||
|
||||
#define SLOTS 4
|
||||
#define IO_SPACES 2 /* Address spaces in A16 */
|
||||
#define IPAC_IRQS 2 /* Interrupts per module */
|
||||
|
||||
|
||||
/* Offsets from base address in VME A16 */
|
||||
|
||||
#define REGS_A 0x0000
|
||||
#define PROM_A 0x0080
|
||||
#define REGS_B 0x0100
|
||||
#define PROM_B 0x0180
|
||||
#define REGS_C 0x0200
|
||||
#define PROM_C 0x0280
|
||||
#define REGS_D 0x0300
|
||||
#define PROM_D 0x0380
|
||||
|
||||
|
||||
/* VME Interrupt levels for -01 option */
|
||||
|
||||
#define IRQ_A0 4
|
||||
#define IRQ_A1 5
|
||||
#define IRQ_B0 2
|
||||
#define IRQ_B1 1
|
||||
#define IRQ_C0 4
|
||||
#define IRQ_C1 5
|
||||
#define IRQ_D0 2
|
||||
#define IRQ_D1 1
|
||||
|
||||
|
||||
/* Carrier Private structure type, one instance per board */
|
||||
|
||||
typedef void* private_t[IPAC_ADDR_SPACES][SLOTS];
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Routine:
|
||||
initialise
|
||||
|
||||
Purpose:
|
||||
Creates new private table for VIPC610 at addresses given by cardParams
|
||||
|
||||
Description:
|
||||
Checks the parameter string for the address of the card I/O space and
|
||||
optional size of the memory space for the modules. If both the I/O and
|
||||
memory base addresses can be reached from the CPU, a private table is
|
||||
created for this board. The private table is a 2-D array of pointers
|
||||
to the base addresses of the various accessible parts of the IP module.
|
||||
|
||||
Parameters:
|
||||
The parameter string should comprise a hex number (the 0x or 0X at the
|
||||
start is optional) optionally followed by a comma and a decimal integer.
|
||||
The first number is the I/O base address of the card in the VME A16
|
||||
address space (the factory default is 0x6000). If present the second
|
||||
number gives the memory space in Kbytes allocated to each IP module.
|
||||
The memory base address of the VIPC610 card is set using the same jumpers
|
||||
as the I/O base address and is always 256 times the I/O base address,
|
||||
but in the VME A24 address space. The factory default for the memory
|
||||
base address is thus 0x600000. If the memory size parameter is omitted
|
||||
or set to zero then none of the IP modules on the carrier provide any
|
||||
memory space. Legal memory size values are 0, 64?, 128, 256, 512, 1024
|
||||
or 2048. The memory size interacts with the memory base address such
|
||||
that it is possible to exclude memory from the lower slots while still
|
||||
providing access to memory in the later slots by adjusting the base
|
||||
address suitably.
|
||||
|
||||
Examples:
|
||||
"0x6000"
|
||||
This indicates that the carrier board has its I/O base set to
|
||||
0x6000, and none of the slots provide memory space.
|
||||
"1000,128"
|
||||
Here the I/O base is set to 0x1000, and there is 128Kbytes of
|
||||
memory on each module, with the IP module A memory at 0x100000,
|
||||
module B at 0x120000, module C at 0x140000 and D at 0x160000.
|
||||
"7000,1024"
|
||||
The I/O base is at 0x7000, and hence the carrier memory base is
|
||||
0x700000. However because the memory size is set to 1024 Kbytes,
|
||||
modules A, B and C cannot be selected (1024 K = 0x100000, so they
|
||||
are decoded at 0x400000, 0x500000 and 0x600000 but can't be accessed
|
||||
because these are below the base address).
|
||||
|
||||
Returns:
|
||||
0 = OK,
|
||||
S_IPAC_badAddress = Parameter string error, or address not reachable
|
||||
|
||||
*/
|
||||
|
||||
LOCAL int initialise (
|
||||
char *cardParams,
|
||||
void **pprivate
|
||||
) {
|
||||
int params, status1 = OK, status2 = OK, mSize = 0;
|
||||
ulong_t ioBase, mOrig, mBase, addr;
|
||||
ushort_t space, slot;
|
||||
private_t *private;
|
||||
static const int offset[IO_SPACES][SLOTS] = {
|
||||
PROM_A, PROM_B, PROM_C, PROM_D,
|
||||
REGS_A, REGS_B, REGS_C, REGS_D
|
||||
};
|
||||
|
||||
if (cardParams == NULL ||
|
||||
strlen(cardParams) == 0) {
|
||||
ioBase = 0x6000;
|
||||
} else {
|
||||
params = sscanf(cardParams, "%p,%i", (void **) &ioBase, &mSize);
|
||||
if (params < 1 || params > 2 ||
|
||||
ioBase > 0xfc00 || ioBase & 0x01ff ||
|
||||
mSize < 0 || mSize > 2048 || mSize & 63) {
|
||||
return S_IPAC_badAddress;
|
||||
}
|
||||
}
|
||||
|
||||
mBase = ioBase << 8; /* Fixed by the VIPC610 card */
|
||||
ioBase = ioBase & 0xfc00; /* Clear A09 */
|
||||
|
||||
status1 = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,
|
||||
(char *) ioBase, (char **) &ioBase);
|
||||
if (mSize > 0) {
|
||||
status2 = sysBusToLocalAdrs(VME_AM_STD_SUP_DATA,
|
||||
(char *) mBase, (char **) &mBase);
|
||||
}
|
||||
if (status1 || status2) {
|
||||
return S_IPAC_badAddress;
|
||||
}
|
||||
|
||||
mSize = mSize << 10; /* Convert size from K to Bytes */
|
||||
mOrig = mBase & ~(mSize * SLOTS - 1);
|
||||
|
||||
private = malloc(sizeof (private_t));
|
||||
for (space = 0; space < IO_SPACES; space++) {
|
||||
for (slot = 0; slot < SLOTS; slot++) {
|
||||
(*private)[space][slot] = (void *) (ioBase + offset[space][slot]);
|
||||
}
|
||||
}
|
||||
|
||||
for (slot = 0; slot < SLOTS; slot++) {
|
||||
(*private)[ipac_addrIO32][slot] = NULL;
|
||||
addr = mOrig + (mSize * slot);
|
||||
if (addr < mBase) {
|
||||
(*private)[ipac_addrMem][slot] = NULL;
|
||||
} else {
|
||||
(*private)[ipac_addrMem][slot] = (void *) addr;
|
||||
}
|
||||
}
|
||||
|
||||
*pprivate = private;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Routine:
|
||||
baseAddr
|
||||
|
||||
Purpose:
|
||||
Returns the base address for the requested slot & address space
|
||||
|
||||
Description:
|
||||
Because we did all that hard work in the initialise routine, this
|
||||
routine only has to do a table lookup in the private array.
|
||||
Note that no parameter checking is required - the IPAC driver which
|
||||
calls this routine handles that.
|
||||
|
||||
Returns:
|
||||
The requested address, or NULL if the module has no memory.
|
||||
|
||||
*/
|
||||
|
||||
LOCAL void *baseAddr (
|
||||
void *private,
|
||||
ushort_t slot,
|
||||
ipac_addr_t space
|
||||
) {
|
||||
return (*(private_t *) private)[space][slot];
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Routine:
|
||||
irqCmd
|
||||
|
||||
Purpose:
|
||||
Handles interrupter commands and status requests
|
||||
|
||||
Description:
|
||||
The GreenSpring board is limited to fixed interrupt levels, and has
|
||||
no control over interrupts. The only commands thus supported are
|
||||
a request of the interrupt level associated with a particular slot
|
||||
and interrupt number, or to enable interrupts by making sure the
|
||||
VMEbus interrupter is listening on the necessary level.
|
||||
|
||||
Returns:
|
||||
ipac_irqGetLevel returns the interrupt level (1, 2, 4 or 5),
|
||||
ipac_irqEnable returns 0 = OK,
|
||||
other calls return S_IPAC_notImplemented.
|
||||
|
||||
*/
|
||||
|
||||
LOCAL int irqCmd (
|
||||
void *private,
|
||||
ushort_t slot,
|
||||
ushort_t irqNumber,
|
||||
ipac_irqCmd_t cmd
|
||||
) {
|
||||
static const int irqLevel[SLOTS][IPAC_IRQS] = {
|
||||
IRQ_A0, IRQ_A1,
|
||||
IRQ_B0, IRQ_B1,
|
||||
IRQ_C0, IRQ_C1,
|
||||
IRQ_D0, IRQ_D1
|
||||
};
|
||||
|
||||
switch (cmd) {
|
||||
case ipac_irqGetLevel:
|
||||
return irqLevel[slot][irqNumber];
|
||||
|
||||
case ipac_irqEnable:
|
||||
sysIntEnable(irqLevel[slot][irqNumber]);
|
||||
return OK;
|
||||
|
||||
default:
|
||||
return S_IPAC_notImplemented;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
/* IPAC Carrier Table */
|
||||
|
||||
ipac_carrier_t vipc610 = {
|
||||
"GreenSpring VIPC610-01",
|
||||
SLOTS,
|
||||
initialise,
|
||||
NULL,
|
||||
baseAddr,
|
||||
irqCmd
|
||||
};
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
|
||||
#ifndef INCipModulesH
|
||||
#define INCipModulesH
|
||||
|
||||
|
||||
#define IP_MANUFACTURER_GREENSPRING 0xf0
|
||||
|
||||
#define IP_MODEL_GS_PRECISION_ADC 0x15
|
||||
#define IP_MODEL_GS_PRECISION_ADC_N "ADC"
|
||||
|
||||
#define IP_MODEL_GS_QUAD_SERIAL 0x37
|
||||
#define IP_MODEL_GS_QUAD_SERIAL_N "Quad_Serial"
|
||||
|
||||
#define IP_MODEL_GS_OCTAL_SERIAL 0x22
|
||||
#define IP_MODEL_GS_OCTAL_SERIAL_N "Octal_Serial"
|
||||
|
||||
#define IP_MODEL_GS_SERIAL 0x10
|
||||
#define IP_MODEL_GS_SERIAL_N "Serial"
|
||||
|
||||
#define IP_MODEL_GS_QUADRATURE 0x41
|
||||
#define IP_MODEL_GS_QUADRATURE_N "Quadrature"
|
||||
|
||||
#define IP_MODEL_GS_488 0x14
|
||||
#define IP_MODEL_GS_488_N "ip488"
|
||||
|
||||
|
||||
#define IP_MANUFACTURER_TEWS 0xb3
|
||||
|
||||
#define IP_MODEL_TEWS_TIP810 0x01
|
||||
|
||||
|
||||
#endif /* INCipModulesH */
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Project:
|
||||
Gemini/UKIRT CAN Bus Driver for EPICS
|
||||
|
||||
File:
|
||||
ipic.h
|
||||
|
||||
Description:
|
||||
IndustryPack Interface Controller ASIC header file, giving the register
|
||||
layout and programming model for the IPIC chip used on the MVME162.
|
||||
|
||||
Author:
|
||||
Andrew Johnson
|
||||
Created:
|
||||
6 July 1995
|
||||
|
||||
(c) 1995 Royal Greenwich Observatory
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
#ifndef INCipicH
|
||||
#define INCipicH
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Chip Registers */
|
||||
|
||||
#define IPIC_CHIP_ID 0x23
|
||||
#define IPIC_CHIP_REVISION 0x00
|
||||
|
||||
|
||||
/* Interrupt Control Register bits */
|
||||
|
||||
#define IPIC_INT_LEVEL 0x07
|
||||
#define IPIC_INT_ICLR 0x08
|
||||
#define IPIC_INT_IEN 0x10
|
||||
#define IPIC_INT_INT 0x20
|
||||
#define IPIC_INT_EDGE 0x40
|
||||
#define IPIC_INT_PLTY 0x80
|
||||
|
||||
|
||||
/* General Control Registers bits */
|
||||
|
||||
#define IPIC_GEN_MEN 0x01
|
||||
#define IPIC_GEN_WIDTH 0x0c
|
||||
#define IPIC_GEN_WIDTH_8 0x04
|
||||
#define IPIC_GEN_WIDTH_16 0x08
|
||||
#define IPIC_GEN_WIDTH_32 0x00
|
||||
#define IPIC_GEN_RT 0x30
|
||||
#define IPIC_GEN_RT_0 0x00
|
||||
#define IPIC_GEN_RT_2 0x10
|
||||
#define IPIC_GEN_RT_4 0x20
|
||||
#define IPIC_GEN_RT_8 0x30
|
||||
#define IPIC_GEN_ERR 0x80
|
||||
|
||||
|
||||
/* IP Reset register bits */
|
||||
|
||||
#define IPIC_IP_RESET 0x01
|
||||
|
||||
|
||||
/* Chip Structure */
|
||||
|
||||
typedef struct {
|
||||
uchar_t chipId;
|
||||
uchar_t chipRevision;
|
||||
uchar_t reserved1[2];
|
||||
ushort_t memBase[4];
|
||||
uchar_t memSize[4];
|
||||
uchar_t intCtrl[4][2];
|
||||
uchar_t genCtrl[4];
|
||||
uchar_t reserved2[3];
|
||||
uchar_t ipReset;
|
||||
} ipic_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* INCipicH */
|
||||
|
||||
@@ -1,188 +0,0 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Project:
|
||||
Gemini/UKIRT CAN Bus Driver for EPICS
|
||||
|
||||
File:
|
||||
pca82c200.h
|
||||
|
||||
Description:
|
||||
Philips Stand-alone CAN-controller chip header file, giving the register
|
||||
layout and programming model for the chip used on the TIP810 IP module.
|
||||
|
||||
Author:
|
||||
Andrew Johnson
|
||||
Created:
|
||||
19 July 1995
|
||||
|
||||
(c) 1995 Royal Greenwich Observatory
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
#ifndef INCpca82c200H
|
||||
#define INCpca82c200H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/***** Control Segment Bit Patterns *****/
|
||||
|
||||
/* Control Register */
|
||||
|
||||
#define PCA_CR_TM 0x80 /* Test Mode */
|
||||
#define PCA_CR_S 0x40 /* Synch */
|
||||
#define PCA_CR_OIE 0x10 /* Overrun Interrupt Enable */
|
||||
#define PCA_CR_EIE 0x08 /* Error Interrupt Enable */
|
||||
#define PCA_CR_TIE 0x04 /* Transmit Interrupt Enable */
|
||||
#define PCA_CR_RIE 0x02 /* Receive Interrupt Enable */
|
||||
#define PCA_CR_RR 0x01 /* Reset Request */
|
||||
|
||||
|
||||
/* Command Register */
|
||||
|
||||
#define PCA_CMR_GTS 0x10 /* Goto Sleep */
|
||||
#define PCA_CMR_COS 0x08 /* Clear Overrun Status */
|
||||
#define PCA_CMR_RRB 0x04 /* Release Receive Buffer */
|
||||
#define PCA_CMR_AT 0x02 /* Abort Transmission */
|
||||
#define PCA_CMR_TR 0x01 /* Transmission Request */
|
||||
|
||||
|
||||
/* Status Register */
|
||||
|
||||
#define PCA_SR_BS 0x80 /* Bus Status */
|
||||
#define PCA_SR_ES 0x40 /* Error Status */
|
||||
#define PCA_SR_TS 0x20 /* Transmit Status */
|
||||
#define PCA_SR_RS 0x10 /* Receive Status */
|
||||
#define PCA_SR_TCS 0x08 /* Transmission Complete Status */
|
||||
#define PCA_SR_TBS 0x04 /* Transmit Buffer Status */
|
||||
#define PCA_SR_DO 0x02 /* Data Overrun */
|
||||
#define PCA_SR_RBS 0x01 /* Receive Buffer Status */
|
||||
|
||||
|
||||
/* Interrupt Register */
|
||||
|
||||
#define PCA_IR_WUI 0x10 /* Wake-Up Interrupt */
|
||||
#define PCA_IR_OI 0x08 /* Overrun Interrupt */
|
||||
#define PCA_IR_EI 0x04 /* Error Interrupt */
|
||||
#define PCA_IR_TI 0x02 /* Transmit Interrupt */
|
||||
#define PCA_IR_RI 0x01 /* Receive Interrupt */
|
||||
|
||||
|
||||
/* Bus Timing Register 0 */
|
||||
|
||||
#define PCA_BTR0_1M6 0x00 /* 1.6 Mbits/sec, 20 m */
|
||||
#define PCA_BTR0_1M0 0x00 /* 1.0 Mbits/sec, 40 m */
|
||||
#define PCA_BTR0_500K 0x00 /* 500 Kbits/sec, 130 m */
|
||||
#define PCA_BTR0_250K 0x01 /* 250 Kbits/sec, 270 m */
|
||||
#define PCA_BTR0_125K 0x03 /* 125 Kbits/sec, 530 m */
|
||||
#define PCA_BTR0_100K 0x43 /* 100 Kbits/sec, 620 m */
|
||||
#define PCA_BTR0_50K 0x47 /* 50 Kbits/sec, 1.3 km */
|
||||
#define PCA_BTR0_20K 0x53 /* 20 Kbits/sec, 3.3 km */
|
||||
#define PCA_BTR0_10K 0x67 /* 10 Kbits/sec, 6.7 km */
|
||||
#define PCA_BTR0_5K 0x7f /* 5 Kbits/sec, 10 km */
|
||||
|
||||
#define PCA_KVASER_1M0 0x00 /* 1.0 Mbits/sec, 40 m -- Kvaser standard */
|
||||
#define PCA_KVASER_500K 0x01 /* 500 Kbits/sec, 130 m -- Kvaser standard */
|
||||
#define PCA_KVASER_250K 0x03 /* 250 Kbits/sec, 270 m -- Kvaser standard */
|
||||
#define PCA_KVASER_125K 0x07 /* 125 Kbits/sec, 530 m -- Kvaser standard */
|
||||
|
||||
|
||||
/* Bus Timing Register 1 */
|
||||
|
||||
#define PCA_BTR1_1M6 0x11 /* 1.6 Mbits/sec, 20 m */
|
||||
#define PCA_BTR1_1M0 0x14 /* 1.0 Mbits/sec, 40 m */
|
||||
#define PCA_BTR1_500K 0x1c /* 500 Kbits/sec, 130 m */
|
||||
#define PCA_BTR1_250K 0x1c /* 250 Kbits/sec, 270 m */
|
||||
#define PCA_BTR1_125K 0x1c /* 125 Kbits/sec, 530 m */
|
||||
#define PCA_BTR1_100K 0x2f /* 100 Kbits/sec, 620 m */
|
||||
#define PCA_BTR1_50K 0x2f /* 50 Kbits/sec, 1.3 km */
|
||||
#define PCA_BTR1_20K 0x2f /* 20 Kbits/sec, 3.3 km */
|
||||
#define PCA_BTR1_10K 0x2f /* 10 Kbits/sec, 6.7 km */
|
||||
#define PCA_BTR1_5K 0x7f /* 5 Kbits/sec, 10 km */
|
||||
|
||||
#define PCA_BTR1_KVASER 0x23 /* All speeds -- Kvaser standard */
|
||||
|
||||
/* Output Control Register */
|
||||
|
||||
#define PCA_OCR_OCM_NORMAL 0x02
|
||||
#define PCA_OCR_OCM_CLOCK 0x03
|
||||
#define PCA_OCR_OCM_BIPHASE 0x00
|
||||
#define PCA_OCR_OCM_TEST 0x01
|
||||
|
||||
#define PCA_OCR_OCT1_FLOAT 0x00
|
||||
#define PCA_OCR_OCT1_PULLDOWN 0x40
|
||||
#define PCA_OCR_OCT1_PULLUP 0x80
|
||||
#define PCA_OCR_OCT1_PUSHPULL 0xc0
|
||||
|
||||
#define PCA_OCR_OCT0_FLOAT 0x00
|
||||
#define PCA_OCR_OCT0_PULLDOWN 0x08
|
||||
#define PCA_OCR_OCT0_PULLUP 0x10
|
||||
#define PCA_OCR_OCT0_PUSHPULL 0x18
|
||||
|
||||
#define PCA_OCR_OCP1_INVERT 0x20
|
||||
#define PCA_OCR_OCP0_INVERT 0x04
|
||||
|
||||
|
||||
/* Message Buffers */
|
||||
|
||||
#define PCA_MSG_ID0_RSHIFT 3
|
||||
#define PCA_MSG_ID1_LSHIFT 5
|
||||
#define PCA_MSG_ID1_MASK 0xe0
|
||||
#define PCA_MSG_RTR 0x10
|
||||
#define PCA_MSG_DLC_MASK 0x0f
|
||||
|
||||
|
||||
/***** Chip Structure *****/
|
||||
|
||||
/* Message Buffers */
|
||||
|
||||
typedef struct {
|
||||
uchar_t pad0;
|
||||
uchar_t descriptor0;
|
||||
uchar_t pad1;
|
||||
uchar_t descriptor1;
|
||||
ushort_t data[8];
|
||||
} msgBuffer_t;
|
||||
|
||||
|
||||
/* Chip Registers */
|
||||
|
||||
typedef volatile struct {
|
||||
uchar_t pad00;
|
||||
uchar_t control;
|
||||
uchar_t pad01;
|
||||
uchar_t command;
|
||||
uchar_t pad02;
|
||||
uchar_t status;
|
||||
uchar_t pad03;
|
||||
uchar_t interrupt;
|
||||
uchar_t pad04;
|
||||
uchar_t acceptanceCode;
|
||||
uchar_t pad05;
|
||||
uchar_t acceptanceMask;
|
||||
uchar_t pad06;
|
||||
uchar_t busTiming0;
|
||||
uchar_t pad07;
|
||||
uchar_t busTiming1;
|
||||
uchar_t pad08;
|
||||
uchar_t outputControl;
|
||||
uchar_t pad09;
|
||||
uchar_t test;
|
||||
msgBuffer_t txBuffer;
|
||||
msgBuffer_t rxBuffer;
|
||||
uchar_t pad31;
|
||||
uchar_t clockDivider;
|
||||
} pca82c200_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* INCpca82c200H */
|
||||
|
||||
Reference in New Issue
Block a user