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:
Andrew Johnson
1999-12-09 19:57:07 +00:00
parent 7110b36b77
commit 06b4e4b151
12 changed files with 0 additions and 3113 deletions

View File

@@ -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)

View File

@@ -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 */

View File

@@ -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
};

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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 */

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */