10.01.2014 Views

CAMAC++

CAMAC++

CAMAC++

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

04 July 2000<br />

<strong>CAMAC++</strong><br />

Steve Wotton


1 Introduction<br />

This document describes a primitive C++ CAMAC library for systems which utilise the CES CBD8211 CAMAC<br />

branch driver. No attempt has been made to preserve the familiar calling sequences of standard CAMAC libraries.<br />

The motivation for providing this library is to ease the integration of CAMAC systems into modern data acquisition<br />

environments where portability between different operating systems and different hardware environments may be<br />

important. The library is incomplete and under development.<br />

The library has so far been used on the following systems:<br />

• HP742 VME SBC running HPUX<br />

• PC running Windows NT using the National Instruments PCI-to-VME interface.<br />

• SBCs running OS9<br />

• CES RIO running LynxOs<br />

The g++ v2.7.2 compiler has been used except on WNT where Borland C++ v5 was used. It should be<br />

straightforward to modify the library for use in other similar systems. The main requirement is that the host system<br />

should support transparent addressing of the VMEbus. On virtual memory systems (like the HP) this is done by<br />

mapping the physical address space of the CBD into the user's virtual address space. On non-virtual addressing<br />

systems (eg OS-9) the corresponding address mapping function would simply return the "physical" address of the<br />

module. All this architecture dependent stuff is hidden in a vme class for easy portability.<br />

2 About the CAMAC branch driver<br />

The CBD can drive a single CAMAC branch containing up to 7 crates. The physical VME base address of the CBD<br />

depends on the branch number selected with the front panel switch. The base address is then given by the expression<br />

(0x800000 | (N


3.1.1 Member functions<br />

Member function Operation Returns<br />

cbranch(vme *VME, const char brname[], const char config[]) Constructor(1) -<br />

cbranch(vme *VME, CAMACD *address, unsigned brnumber,<br />

Constructor(2) -<br />

const char config[])<br />

3.1.2 Description of arguments<br />

Name<br />

Notes<br />

VME Pointer to VME++ object<br />

brname Name of branch as identified in VME++ configuration file<br />

config Configuration file name or environment variable name<br />

address Physical base address of CBD<br />

brnumber Physical branch number<br />

The following example configuration file describes a system having two camac crates on branch 0 with two<br />

CAMAC modules in each crate:<br />

branch: 0 0x800000<br />

crate: 1 crate1<br />

module: 16 tdc lrs2228<br />

module: 21 scalar1 lrs2551<br />

crate: 2 crate2<br />

module: 7 scalar2 lrs2551<br />

module: 8 scalar3 lrs2551<br />

Each line has one of the following forms:<br />

branch: number CBD_addr<br />

crate: number name<br />

module: slot_number name type<br />

The "name" parameters are arbitrary and are used to locate the named object in the internal lists. The "number"<br />

parameters must be consistent with the hardware configuration. The module "type" parameter is used to determine<br />

which concrete class of module to instantiate.<br />

Refer to the example program for more details.<br />

The alternative form of the constructor cbranch(vme,addr,i,file) allows the creation of a branch to which<br />

crates and modules may be added later by explicit calls to ccrate and cmodule constructors in the user program.<br />

Note that the name of an existing file is still required as this is identified with a semaphore created by the library.<br />

However, in this case, the file may be empty - the branch number and physical address of the CAMAC branch driver<br />

are passed explicitly as constructor arguments.<br />

3.2 The class ccrate<br />

This class represents a CAMAC crate and implements the functions used for crate initialisation and control:<br />

Member function Operation Returns<br />

ccrate(cbranch *branch, int id, char *name ) Constructor -<br />

void reset(void) Crate reset (CCCZ) -<br />

void clear(void) Crate clear (CCCC) -<br />

int clrInhibit(void) Clear inhibit (CCCI) Inhibit state<br />

int setInhibit(void) Set inhibit (CCCI) Inhibit state<br />

int testInhibit(void) Test inhibit (CTCI) Inhibit state<br />

int clrDemand(void)<br />

Clear demand (CCCD) Demand state<br />

int setDemand(void) Set demand (CCCD) Demand state<br />

int testDemand(void) Test demand (CTCD) Demand state<br />

3.3 The class cmodule<br />

This class is an abstraction of a CAMAC module and is used to define the interface functions which all derived<br />

classes must provide. Currently the following functions must exist: read, test, clear, execute. See camac.h for<br />

implementation details.<br />

3


CAMAC defines a set of function codes which perform more or less standard operations on all CAMAC modules<br />

(although not all functions are implemented on all modules). The following is a suggested convention for the<br />

cmodule member function names corresponding to the CAMAC function codes F0-31:<br />

CAMAC read member function CAMAC control member function CAMAC write member function<br />

F0 read F8 testLam F16 write<br />

F1 read2 F9 clear F17 write2<br />

F2 readClear F10 clearLam F18 setSelective<br />

F3 readComplement F11 clear2 F19 setSelective2<br />

F4 - F12 - F20 -<br />

F5 - F13 - F21 clearSelective<br />

F6 - F14 - F22 -<br />

F7 - F15 - F23 clearSelective2<br />

- - F24 disable - -<br />

- - F25 execute - -<br />

- - F26 enable - -<br />

- - F27 test - -<br />

- - F28-F31 - - -<br />

CAMAC Q, X and timeout responses are placed into cmodule::errno which should be checked after every<br />

CAMAC operation which may affect these flags. If 0, no error occurred otherwise bit 0 set indicates CAMAC<br />

timeout, bit 1 set indicates no X response and bit 2 set indicates no Q response.<br />

4 Locating modules<br />

The class library constructors build internal data structures which are lists of which crates belong to a branch and<br />

which modules belong to a crate. Modules may be located by name, the module and crate names being defined in<br />

the branch configuration file. The example program illustrates how to locate the module called "scalar" in the crate<br />

named "crate2". Note the type cast to the actual type of the located module. This expression should be used as a<br />

model for locating other modules.<br />

5 Extending the library<br />

Every CAMAC module in a system is represented by a concrete class derived from class cmodule. Adding support<br />

for new modules means deriving a new class from cmodule which must implement at least the read, test,<br />

clear and execute member functions (although they may be dummy). The simple classes lrs2228 (a D16<br />

module) and lrs2551 (a D24 module) in camac.h serve as simple examples. One should not forget to set<br />

cmodule::errors depending on the CAMAC response.<br />

6 Error handling<br />

For maximum portability C++ exception handling has not been used in this library. Instead, each class contains a<br />

public data member, errors, which behaves as a trace buffer into which arbitrary text can be placed for later<br />

display. This strategy has the advantage of allowing constructors (which cannot return values) to report errors in the<br />

same way as other member functions and also allows messages to be reported from deeply nested function calls and<br />

still allow the error to be precisely located. The trace buffer continues to accumulate error messages until flushed to<br />

cout or cerr using the


8 Multitasking<br />

The hardware must be protected against concurrent access which may arise in a multitasking environment where<br />

more than one process may try to access a CAMAC branch. One possibility would be to confine all CAMAC<br />

operations within a single process. Another possibility would be to protect all CAMAC operations with a<br />

semaphore. In order to avoid incurring any unnecessary software penalties the responsibility of protecting the<br />

CAMAC operations has been left to the user. The example program illustrates the use of the branch semaphore. This<br />

approach has the disadvantage that users can cheat by not protecting CAMAC access with the semaphore either<br />

deliberately or inadvertently (e.g. by using an alternative CAMAC library with different or no protection<br />

mechanism). Note that the semaphore is used in the library to protect the branch initialisation.<br />

Another potential problem in a multi-tasking environment is that of initialisation. Typically the hardware<br />

initialisation should be done only once. Since an initialisation function is called from the class constructors and only<br />

the first use of a constructor by any process in the system should perform initialisation, a second semaphore is used<br />

by the library to guarantee this behaviour. The initialisation routines can always be called from the users program at<br />

any time in order to reinitialise part or all of the CAMAC branch. Again, it is possible to cheat the concurrent access<br />

protection scheme.<br />

8.1 Interrupts<br />

Interrupt handling (generated in response to LAMs) is not implemented. On the HP this would require the<br />

implementation of a device driver. On OS9 a device driver already exists but needs to be integrated with this library.<br />

The Nat. Inst. PCI-VME interface has user-callable software to install interrupt handlers so implementation of LAM<br />

interrupt handlers should be easy here. The main problem is to make the library behave the same on all platforms<br />

given the constraints of using the already existing software.<br />

8.2 C-binding<br />

These functions are implemented as jacket routines to the C++ API. The CBRANCHID and CMODULEID type<br />

arguments are actually pointers to the underlying C++ objects and should never be directly manipulated by a C-<br />

coded application. They serve as context arguments used by the library. Since these are jacket routines, this code is<br />

hardware independent and is split off into a separate file, ccamac.cpp<br />

Function Operation Returns<br />

int opencbranch(CBRANCHID *cid, VMEID vid,<br />

const char *file)<br />

Setup CAMAC branch using<br />

configuration file<br />

error<br />

code<br />

int closecbranch(CBRANCHID cid)<br />

Close CAMAC branch<br />

error<br />

code<br />

int getcbranch(CBRANCHID cid)<br />

Get exclusive access to (lock) branch error<br />

code<br />

int releasecbranch(CBRANCHID cid)<br />

Release lock on branch<br />

error<br />

code<br />

int getcmodule(CBRANCHID cid, CMODULEID *mid,<br />

error<br />

Get pointer to named module<br />

const char *crate, const char *module)<br />

code<br />

int cfnr(CMODULEID mid, int A, int *D, int fn) Perform read operation<br />

QXT<br />

int cfnw(CMODULEID mid, int A, int D, int fn) Perform write operation<br />

QXT<br />

int cfnc(CMODULEID mid, int fn) Perform control operation QXT<br />

Where the return code is indicated as QXT this means a bitmask indicating the status of the CAMAC Q, X and T<br />

response in the least significant 3 bits or some other error code in higher order bits.<br />

In addition to these routines it is also necessary to initialise the VME interface using the openvme() and<br />

closevme() from the VME library as in the example program.<br />

9 Built in support for CAMAC modules<br />

Support for a number of specific common CAMAC modules is included in the library. The following modules are<br />

known in addition to generic 16bit and 24bit data modules:<br />

Module Description<br />

LRS2228 TDC<br />

LRS2229 TDC<br />

5


LRS2249 ADC<br />

LRS2551 Scaler, 12ch.<br />

LRS4416 Discriminator<br />

LRS4418 Programmable delay, 16ch<br />

LRS4516 Programmable Logic Unit<br />

LRS4432 Scaler, 32ch.<br />

or2027 Output register, 16ch.<br />

LRS2341 Input register, 16ch.<br />

c85 CAEN Programmable logic unit<br />

10 Example C++ program<br />

11 Example C program<br />

6

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!