EPICS Support for the Xycom-9660 IP Carrier Board and 3 IP Modules

Version 1.0
Andy Foster, Observatory Sciences Limited, Cambridge, UK
  1. Introduction
  2. Definitions, Acronyms and Abbreviations
  3. Xycom-9660 Carrier Board
  4. Xycom-2440 Digital Input Module
  5. Xycom-2445 Digital Output Module
  6. Xycom-5320 Analog Input Module
  7. Where to find the software

1. Introduction

The Gemini Multi-Conjugate Adaptive Optics System project has decided to adopt Xycom as its manufacturer of choice to supply an IPAC carrier board and various IPAC modules. The motivation for using IPAC is to be able to provide cost effective functionality in one VME slot. There are a range of IPAC modules that provide functionality such as digital I/O and analog I/O. Since the carrier board is capable of hosting 4 modules and occupies one VME slot, we can tailor this slot to provide the desired mixture of digital and analog I/O.

The Xycom IPAC carrier board and its various modules did not have software support already available from the EPICS community. As part of the MCAO project, we have developed this support and the details of its use are documented here. In particular, we have developed EPICS support for the carrier board and 3 modules. These modules are:


2. Definitions, Acronyms and Abbreviations


3. Xycom-9660 Carrier Board

3.1 Hardware

The Xycom-9660 is a non-intelligent, 6U high, VME board. It provides an interface to the VME backplane for up to 4 IPAC modules. Data access is through the front panel. All data and register access to the IP modules are available as offsets from the base address of the carrier board. The front panel contains 4 LED's that indicate successful access to each of the on-board IPAC modules, this is very helpful in debugging problems. The carrier board supports two interrupt requests per IPAC module. It effectively maps these interrupts to one of the seven available interrupt request lines on the VME backplane.

3.1.1 Jumper Settings

There is one bank of jumpers on this board that allows the base address of the board to be configured. The carrier board is shipped with a default factory setting of 0x0000. The carrier board interfaces with the VMEbus as a 1K byte block of address locations in the VMEbus short I/O address space.

3.2 Software

The way in which a driver for an IPAC carrier board is implemented within EPICS follows a very well defined methodology. Essentially, there is a generic IPAC driver already available for EPICS and each new carrier board needs to provide certain functions to interface to this generic driver. The generic driver is called "drvIpac" and was developed by Andrew Johnson (see his description at drvIpac). We have followed this approach in implementing the EPICS support for this carrier board. Essentially, four interface functions have been written:

This function is called from "ipacAddCarrier" which itself is called from within the vxWorks/EPICS startup script. The purpose of this function is to probe the VME memory space to make sure that communication with the board is possible and to initialise the board by setting the appropriate registers as required.

This function returns the base address, given a slot number on the carrier board and an address space. Note that many IPAC modules use two address spaces, this is because the IPAC module itself can have memory onboard. Typically the I/O base address of the module is in A16 space whilst any onboard memory is mapped into A24 space. We do not have to worry about this with the modules we have chosen for MCAO because none of them contain any onboard memory.

This function sets up interrupt control handling. Typically, it will enable the VME interrupt address level being used. We use level 6 for handling interrupts. This is the highest priority non-maskable interrupt level permitted by the VME specification.

This function returns information about the status of the module in each slot of the carrier board. It is called from "ipacReport", which is usually called from the vxWorks shell.

For the user of the Xycom-9660 carrier board software, the details of the four functions above are immaterial. The most important public function that the user will need to understand is "ipacAddCarrier" which is part of the generic IPAC driver.

int ipacAddCarrier(ipac_carrier_t *pcarrier, char *cardParams);

This routine should be called from the vxWorks/EPICS start-up script. It registers a particular carrier board with the generic IPAC driver. It must be called once for each carrier board in the system. The order is which carriers are registered with this routine defines the carrier number they will be allocated, starting from zero for the first board registered.

The first argument to the routine is a pointer to the carrier descriptor table. In the case of the Xycom-9660 board, this will always be &xy9660.

For the Xycom-9660 board, the second argument will be the base address of the carrier board, e.g. "0x0400". This base address must agree with that selected via the hardware jumpers on the carrier board itself.

When called, the function checks that the carrier descriptor table looks sensible, calls the "initialise" routine (as described above), then saves the carrier private pointer and carrier table address in an internal array. The card number allows the same descriptor table to be used for all carriers of the same type i.e. all Xycom-9660 carrier boards use the same descriptor table.

Note that the driver can be used without EPICS by compiling the code with the flag "-D NO_EPICS".


4. The Xycom-2440 Digital Input Module

4.1 Hardware

The Xycom-2440 Digital Input Module allows for the monitoring of 32 optically-isolated inputs. It is a high-speed board for which zero wait states are required. Access times for all data transfer cycles are described in terms of "wait" states. Zero wait states implies that all cycles complete in 250ns. There are three different models of this particular board allowing a selection of input ranges from +/-4 to +/-60 volts. The board we have chosen for MCAO operates in the +/-4 to +/-18 volt range.

The board is capable of generating an interrupt for a change in each input channel. Whether the interrupt is generated for a low-to-high or a high-to-low transition is software programmable through an event register. Since this register occupies 1 byte and there are 32 inputs, the resolution for controlling the interrupts is 4 channels (nibble) per bit of the event register. Note that we can detect both types of transition for a single input channel but to do this requires bi-wiring of the channels with a wire jumper at the termination panel.

For each set of 8 input channels (defined as a port), we can configure the debounce time through software. The debounce time is the amount of time that must elapse before a transition to a new state is confirmed to have taken place.

4.1.1 Jumper Settings

There are no jumper settings for this module.

4.2 Software

Two software modules have been written for this card, "drvXy2440.c" and "devXy2440.c". These correspond to the vxWorks/EPICS device driver and EPICS device support respectively. The device driver can be compiled for use with vxWorks only by compiling with the "-D NO_EPICS" directive.

This module can be configured through software to run in two different modes: standard mode and enhanced mode. The difference between the modes is that interrupts are only generated in enhanced mode and debounce is only configurable in enhanced mode.

4.2.1 The vxWorks Interface

The vxWorks interface is provided by a set of four functions. We describe their use below.


int xy2440Report( int interest );

This function is typically run from the vxWorks shell although it could easily be called from a user function. It prints out information about the state of all Xycom-2440 cards in the system. The parameter interest determines the amount of information given. There are three supported choices of this parameter: 0, 1 and 2. The two outputs for interest levels 0 and 1 are shown below. Using an interest level of 2 returns both sets of information.

68k->xy2440Report 0

68k->xy2440Report 1


int xy2440Initialise( void );

This function is responsible for connecting the interrupt service routine to the interrupt vector and for enabling the appropriate VME interrupt line (level 6 is used). In standard mode, this routine effectively does nothing. However, it is good practice to always call this routine from your vxWorks start-up script. It must be called after xy2440Create, which is described in detail in the next section. Note the routine will only return an error if the connection between ISR and interrupt vector cannot be made.


int xy2440Create( char *name, ushort_t card, ushort_t slot, 
                  char *modeName, char *intHandlerName, char *usrFunc, short vector, 
                  short event, short debounce );

This function is responsible for creating the software entity that will control a particular Xycom-2440 module in the system. It must always be called from the vxWorks start-up script. It will configure the registers in memory according to the parameters specified as inputs to this function. We now describe in detail, the meaning of each parameter.

char *name

This is a unique name for this particular module in the system. Any ASCII string beginning with a letter is acceptable. Examples are "bi1", "Digital1". Further use of this parameter is made in the EPICS interface.

ushort_t card

The number of the carrier board in which this module is located.\240 Remember that carrier boards are assigned values beginning at zero and incrementing with each call to "ipacAddCarrier".

ushort_t slot

The number of the slot on the carrier board in which this module is located. The Xycom-9660 carrier board actually labels its slots A, B, C & D. These map to 0, 1, 2 & 3 when specifying this parameter.

char *modeName

This defines the mode in which we want to run the module. There are two possible values: STANDARD or ENHANCED. As stated earlier, interrupts and debounce control are only available in enhanced mode.

char *intHandlerName

This defines the type of interrupts we are configuring for this module. There are two possibilities: COS or LEVEL. COS is an abbreviation for change-of-state and refers to interrupts being generated for both low-to-high and high-to-low transitions on the same channel. Note that to use change-of-state operation, the user must physically connect input bits 0 & 4, 1 & 5, 2 & 6 and 3 & 7 of each port, at the termination panel. This obviously reduces the number of inputs for the card from 32 to 16. LEVEL specifies that interrupts will only be generated on one particular transition (low-to-high or high-to-low) for each bit. In this mode, all 32 bits are available for use. The choice of this parameter will decide which of the two ISR's, supplied with the driver, will be called when an interrupt occurs.

char *usrFunc

This is the name of a user function that, if specified, will be called from the COS or LEVEL interrupt service routine. The user's routine will be passed the name of the board generating the interrupt and the interrupting port and bit numbers according to the following prototype:

usrFunc( char *name, int port, int bit )

If the user does specify a routine, it must be loaded in the vxWorks startup script prior to xy2440Create being called. If the user does not want to specify a routine, then 0x0 should be entered here.

short vector

This is the interrupt vector number to be used. The valid range is 0-255, however, vector numbers below 64 are reserved on the MVME167 board for system components.

short event

This byte defines which transitions of the input channels will cause an interrupt. Each bit of event controls 4 input channels according to the following list:

short debounce

This byte controls the debounce time for each output port. Two bits of debounce per port are required to select one of 4 possible time ranges as follows:


long xy2440Read( char *name, short port, short bit, int readFlag,
                 unsigned short *pval, int debug );

This function is responsible for reading a single input channel or a group of input channels. We now describe in detail, the meaning of each parameter.

char *name

The unique name which identifies this particular module in the system.

short port

The number of the port we want to read from. Ports are numbered from 0 to 3.

short bit

The number of the bit, within the port, we wish to read. Bits are numbered from 0 to 7.

int readFlag

This parameter defines the amount of data to read. There are 4 possibilities, defined as an enumerated type in drvXy2440.h. These are:

unsigned short *pval

This is the location of the returned data.

int debug

This is flag which controls debug statements within this function. A value of 0 suppresses debug statements, a value of 1 forces debug statements to be printed out.


4.2.2 The vxWorks Startup Script

Lines similar to the following must be placed in the vxWorks startup script:

Note that a separate call to xy2440Create is necessary for each Xycom-2440 module in the system. Only one call to xy2440Initialise is necessary as this initializes all the modules.


4.2.3 The EPICS Interface

The EPICS interface is defined by the device support that has been written to support this module. Within the EPICS software architecture, the device support layer links EPICS records to the device driver layer. Device support has been written for the BI, MBBI and MBBIDIRECT EPICS records. Within an EPICS input record, the communication link to the hardware is configured through two fields, the DTYP field and the INP link. For the Xycom-2440 module, these fields should be specified as follows:

Here, name, is the unique name of this module within the system. This should always be the same as that specified as the first parameter in the call to xy2440Create.

<p> is the port number we wish to read from.

<b> is the bit number we wish to read from.

For the MBBI and MBBIDIRECT records, it is essential to configure the NOBT field. This is the number of bits you wish to read. An MBBI record is capable of reading up to and including 4 bits, an MBBIDIRECT record is capable of reading up to and including 16 bits. The read will begin at the position indicated by the P and B parameters in the INP link specification.

It is worth pointing out two important differences between the EPICS support for the Xycom-2440 module and EPICS support for the Xycom-240 digital I/O board which is distributed as part of EPICS base:


4.2.4 The EPICS Startup Script

A single line, for each Xycom-2440 module, similar to the following should be placed in the startup script:

The explicit call to xy2440Initialise, as shown in the vxWorks startup script, is unnecessary as this will be called automatically when EPICS initializes via the execution of iocCore.


5. Xycom-2445 Digital Output Module

5.1 Hardware

The Xycom-2445 module allows control of up to 32 optically isolated outputs. This is achieved via 32 bipolar SSR's. It is a high-speed board for which zero wait states are required. Access times for all data transfer cycles are described in terms of "wait" states. Zero wait states implies that all cycles complete in 250ns. This module is loop-back compatible with the Xycom-2440 module. The output channels are split into 4 ports of 8 channels. Each group of 8 channels can be connected to common for low side switching. In this configuration, the module is TTL compatible. For safety reasons, when the module is powered-up or a system reset occurs, the SSR's will be disabled and the outputs are turned off.

5.1.1 Jumper Settings

There are no jumper settings for this module.

5.2 Software

Two software modules have been written for this card, "drvXy2445.c" and "devXy2445.c". These correspond to the vxWorks/EPICS device driver and EPICS device support respectively. The device driver can be compiled for use with vxWorks only by compiling with the "-D NO_EPICS" directive.

5.2.1 The vxWorks Interface

The vxWorks interface is provided by a set of five functions. We describe their use below.


int xy2445Report( int interest );

This function is typically run from the vxWorks shell although it could easily be called from a user function. It prints out information about the state of all Xycom-2445 cards in the system. The parameter interest determines the amount of information given. There are three supported choices of this parameter: 0, 1 and 2. The two outputs for interest levels 0 and 1 are shown below. Using an interest level of 2 returns both sets of information.

68k->xy2445Report 0

68k->xy2445Report 1


int xy2445Initialise( void );

This is a null function that does not perform any duties. It is included so that the driver is compliant with the EPICS interface.


int xy2445Create( char *name, ushort_t card, ushort_t slot );

This function is responsible for creating the software entity that will control a particular Xycom-2445 module in the system. It must always be called from the vxWorks start-up script. It will configure the registers in memory according to the parameters specified as inputs to this function. We now describe in detail, the meaning of each parameter.

char *name

This is a unique name for this particular module in the system. Any ASCII string beginning with a letter is acceptable. Examples are "bo1", "Digital1". Further use of this parameter is made in the EPICS interface.

ushort_t card

The number of the carrier board in which this module is located.\240 Remember that carrier boards are assigned values beginning at zero and incrementing with each call to "ipacAddCarrier".

ushort_t slot

The number of the slot on the carrier board in which this module is located. The Xycom-9660 carrier board actually labels its slots A, B, C & D. These map to 0, 1, 2 & 3 when specifying this parameter.


long xy2445Read( char *name, short port, short bit, int readFlag,
                 unsigned short *pval, int debug );

This function is responsible for reading a single output channel or a group of output channels. We now describe in detail, the meaning of each parameter.

char *name

The unique name which identifies this particular module in the system.

short port

The number of the port we want to read from. Ports are numbered from 0 to 3.

short bit

The number of the bit, within the port, we wish to read. Bits are numbered from 0 to 7.

int readFlag

This parameter defines the amount of data to read. There are 4 possibilities, defined as an enumerated type in drvXy2445.h. These are:

unsigned short *pval

This is the location of the returned data.

int debug

This is flag which controls debug statements within this function. A value of 0 suppresses debug statements, a value of 1 forces debug statements to be printed out.


long xy2445Write( char *name, short port, short bit, int writeFlag,
                 long value, int debug );

This function is responsible for writing to a single output channel or a group of output channels. We now describe in detail, the meaning of each parameter.

char *name

The unique name which identifies this particular module in the system.

short port

The number of the port we want to write to. Ports are numbered from 0 to 3.

short bit

The number of the bit, within the port, we wish to write to. Bits are numbered from 0 to 7.

int writeFlag

This parameter defines the amount of data to write. There are 4 possibilities, defined as an enumerated type in drvXy2445.h. These are:

long value

The value to be written.

int debug

This is flag which controls debug statements within this function. A value of 0 suppresses debug statements, a value of 1 forces debug statements to be printed out.


5.2.2 The vxWorks Startup Script

A line similar to the following must be placed in the vxWorks startup script:

Note that a separate call to xy2445Create is necessary for each Xycom-2445 module in the system.


5.2.3 The EPICS Interface

The EPICS interface is defined by the device support that has been written to support this module. Within the EPICS software architecture, the device support layer links EPICS records to the device driver layer. Device support has been written for the BO, MBBO and MBBODIRECT EPICS records. Within an EPICS output record, the communication link to the hardware is configured through two fields, the DTYP field and the OUT link. For the Xycom-2445 module, these fields should be specified as follows:

Here, name, is the unique name of this module within the system. This should always be the same as that specified as the first parameter in the call to xy2445Create.

<p> is the port number we wish to write to.

<b> is the bit number we wish to write to.

For the MBBO and MBBODIRECT records, it is essential to configure the NOBT field. This is the number of bits you wish to write. An MBBO record is capable of writing up to and including 4 bits, an MBBODIRECT record is capable of writing up to and including 16 bits. The write will begin at the position indicated by the P and B parameters in the OUT link specification.


5.2.4 The EPICS Startup Script

The EPICS startup script entry is identical to the vxWorks startup script entry above.


6. Xycom-5320 Analog Input Module

6.1 Hardware

The Xycom-5320 module allows monitoring of up to 20 differential or 40 single-ended channels. Each analog value is converted to a 12-bit digital value using a successive approximation ADC with an 8.5\265s conversion time. The board is capable of a maximum system throughput of 100,000 samples per second using the pipe-lined mode of operation. In this mode, the board is configured to read the next channel while the current channel is being converted.

Input acquisition can be triggered via software or by an external hardware input for synchronization to external events. One nice feature of the board is that it contains four voltage sources and an analog ground reference to enable automatic calibration. The gain of each channel is separately configurable through software. Valid values for the gain are 1, 2, 4 or 8.

6.1.1 Jumper Settings

This module contains two banks of jumpers. One bank enables the input voltage range to be selected, the other bank enables an external or internal power supply to be used. One of three input voltage ranges can be chosen: -5 to +5 V, -10 to +10 V or 0 to +10 V. For the power, if the internal supply is chosen, then the +/- 12 V back-plane source is used via the P1 connector. If the external supply is chosen the user must supply a +/- 15 V power source via the P2 connector. Note that the input voltage ranges: -10 to +10 V and 0 to +10 V can only be achieved by using an external power source, otherwise the digitized values will be clipped.

6.2 Software

Two software modules have been written for this card, "drvXy5320.c" and "devXy5320.c". These correspond to the vxWorks/EPICS device driver and EPICS device support respectively. The device driver can be compiled for use with vxWorks only by compiling with the "-D NO_EPICS" directive.

6.2.1 The vxWorks Interface

The vxWorks interface is provided by a set of five functions. We describe their use below.


int xy5320Report( int interest );

This function is typically run from the vxWorks shell although it could easily be called from a user function. It prints out information about the state of all Xycom-5320 cards in the system. The parameter interest is not actually used by the function, so the same information will be obtained for all values of interest. An example of the output from this function is given below.

68k->xy5320Report

So, for each channel configured at boot time, the following information is given:


int xy5320Initialise( void );

This function is responsible for starting two tasks. One of these tasks calibrates all the xy5320 modules in the system every twenty minutes. The other task reads all the configured input channels, on all the xy5320 modules, into memory at 20 Hz. It then calculates the corrected digitized value by using the calibration data. This function must be called from the vxWorks startup script after the call to xy5320Create.


int xy5320Create( char *name, ushort_t card, ushort_t slot, 
                  char *voltRangeName, char *modeName, int numSamples,
                  char *filename );

This function is responsible for creating the software entity that will control a particular Xycom-5320 module in the system. It must be called once from the vxWorks start-up script for each Xycom-5320 module. It will configure the registers in memory according to the parameters specified as inputs to this function. We now describe in detail, the meaning of each parameter.

char *name

This is a unique name for this particular module in the system. Any ASCII string beginning with a letter is acceptable. Examples are "ai1", "Analog1". Further use of this parameter is made in the EPICS interface.

ushort_t card

The number of the carrier board in which this module is located. Remember that carrier boards are assigned values beginning at zero and incrementing with each call to "ipacAddCarrier".

ushort_t slot

The number of the slot on the carrier board in which this module is located. The Xycom-9660 carrier board actually labels its slots A, B, C & D. These map to 0, 1, 2 & 3 when specifying this parameter.

char *voltRangeName

This is a string representing the voltage range over which the board will operate. There are three valid choices: "-5TO5", "-10TO10" or "0TO10". Please note that the board jumpers need changing as well, when a new voltage range is selected.

char *modeName

This is a string representing the type of inputs we are dealing with. There are two valid choices: "DIF" or "SE". These correspond to Differential and Single-ended respectively.

int numSamples

This is the number of times every input channel is read before an average value for each channel is calculated. Note that increasing the size of this parameter can have drastic effects on the CPU usage. Typically, a value of 16 reduces the noise and results in a smooth output.

char *filename

This is the name of a file that contains the numbers of the configured channels and their respective gains. The full pathname to the file should be specified if the file is not located in the local directory. The file itself has a very simple format. There should be two columns separated by at least one space. The first column contains channel numbers, the second column contains the gain settings. Remember there are 4 valid gain settings, these are: 1, 2, 4 & 8. Example contents of this file would be:

This configures the module so that only 4 channels will read. Channel 0 will have a gain of 1, channel 6 will have a gain of 2, channel 12 will have a gain of 4 and channel 18 will have a gain of 8.

The information specified in this file is very important as it essentially controls which channels will be read and what gain will be applied until the next time the system is rebooted. Note that it is possible to specify the same channel any number of times, each with a different gain setting if desired.


long xy5320ReadChannel( char *name, int channel, 
                        unsigned long ftvl, void *prval );

This function is responsible for reading a single input channel. We now describe in detail, the meaning of each parameter.

char *name

The unique name which identifies this particular module in the system.

char *channel

The number of the channel we wish to read from.

unsigned long ftvl

The data type we wish to read. There are 2 possibilities, defined as an enumerated type in drvXy5320.h. These are:

void *prval

This is the location of the returned data. Note that sufficient space must be passed into this routine for the data to be copied into.


long xy5320ReadArray( char *name, int startIndex, int numChan,
                      unsigned long ftvl, void *prval );

This function is responsible for reading an array of input channels. We now describe in detail, the meaning of each parameter.

char *name

The unique name which identifies this particular module in the system.

int startIndex

The index of the start channel within the file named in the call to xy5320Create. The index begins at 0 for the first channel in the file.

int numChan

The number of channel values to be read.

unsigned long ftvl

The data type we wish to read. There are 2 possibilities, defined as an enumerated type in drvXy5320.h. These are:

void *prval

This is the location of the returned data. Note that sufficient space must be passed into this routine for the data to be copied into.


6.2.2 The vxWorks Startup Script

Two lines similar to the following must be placed in the vxWorks startup script:

Note that a separate call to xy5320Create is necessary for each Xycom-5320 module in the system. Only one call to xy5320Initialise is necessary as this initializes all the modules.


6.2.3 The EPICS Interface

The EPICS interface is defined by the device support that has been written to support this module. Within the EPICS software architecture, the device support layer links EPICS records to the device driver layer. Device support has been written for the AI and the Waveform EPICS records. Within an EPICS input record, the communication link to the hardware is configured through two fields, the DTYP field and the INP link. For the Xycom-5320 module, these fields should be specified as follows:

Here, name, is the unique name of this module within the system. This should always be the same as that specified as the first parameter in the call to xy5320Create.

In the next two paragraphs, filename, refers to the file named in the call to xy5320Create. For the AI record, <c> is the channel number we wish to read from. This must have previously been configured through filename. For the Waveform record, <c> is no longer the channel number. It is the index of the channel in filename at which we want the array to begin.

The FTVL field within the Waveform record allows the user to specify the type of data within the array. This device support uses the setting of this field to decide whether to return the corrected digitized values (FTVL=LONG) or the analog values (FTVL=DOUBLE). The Waveform record contains a field, NELM that usually specifies the number of channels to be read. It is slightly different for this device support. NELM must be set to twice the number of channels you wish to read plus 1. That is:

The reason is as follows. We want to return not only the analog values of the channels but the channel numbers themselves and the number of elements read. The format of the returned array is as follows:

The reason for returning all of these values in a single array is to circumvent the problem of atomic Channel Access "gets". If these data were split between 2 or 3 different record fields, then it would always be possible to obtain a dataset that is inconsistent. By using an array, we do not have this problem.

Note that the output from the Waveform record can be connected to an input of a genSub record and the values of the array can be manipulated with ease.


6.2.4 The EPICS Startup Script

A single line, for each Xycom-5320 module, similar to the following should be placed in the startup script:

The explicit call to xy5320Initialise, as shown in the vxWorks startup script, is unnecessary as this will be called automatically when EPICS initializes via the execution of iocCore.


7. Where to find the software

The software is available for download from the link given in the table below:

Version EPICS Release Filename
1.0 R3.13.x xycomIpac-1.0.tar.gz

When expanded, the gzipped tar file contains a simple three level directory structure. The top-level directory will be called xycomIpac, under which will be found src. Under src there are 4 directories: xy2440, xy2445, xy5320 and xy9660. The driver, device support and DBD files for each module can be found in the appropriate directory. To build these into your application:


Andy Foster <ajf@observatorysciences.co.uk>