#include <config.h>
#include <CVMEInterface.h>
#include <string>
static void Open(CVMEInterface::AddressMode mode, unsigned short crate=0);
static void Close(void* pCrateHandle);
static void* Map(void* pCrateHandle, unsigned long nBase, unsigned long nBytes);
static void Unmap(void* pCrateHandle, void* pBase, unsigned long nBytes);
static int Read(void* pCrateHandle, unsigned long offset, void* pBuffer, unsigned long nBytes);
static int Write(void* pCrateHandle, unsigned long nOffset, void* pBuffer, unsigned long nBytes);
static void Lock();
static void Unlock();
CVMEInterface provides generic low level
access to VME busses. Programming against either
CVMEinterface or
CVMEModule (see the reference pages for
the device supprot software), ensures that your code is portable
across all VME interfaces supported by the NSCL DAQ system.
This portability comes at the potential price of performance.
This reference section also describes classes for each supported VME interface. If you require access to some special features of an interface, you can sacrifice portability by programming against them as well.
To compile software that uses this class you will need to ensure that the compiler can locate the CVMEInterface.h header as follows:
-I$DAQROOT/include
To link software that uses this class you will need to link in both the VmeAPI library and the Exception library, as well as potentially other device support libraries that depend on your interface. For the SBS PCI/VME interface board, the addtional information required on the link line is shown below:
-L$DAQROOT/lib -lVmeApi -lException -lbtp -lpthread
Opens a handle to access a VME crate. This handle should be used as the
pCrateHandle in other functions in this class.
mode represents the address modifier to be used
by default when accessing the crate through this handle. See
"Types and Public Data" below for more information about the address modifier.
crate is the number of the VME crate to be opened.
if omitted, the crate parameter defaults to 0 which is
suitable for software running in single crate systems. If, however you are
producing software that is supposed to provide general support for a device,
you should not default this parameter.
The handle is returned to the caller as an opaque pointer (void*). If the open is unsuccessful, the function throws a string exception with a value that reports why the open failed.
Closes a handle that was previously opened via
CVMEInterface::Open.
pCrateHandle is the opaque handle to the crate
returned by the
CVMEInterface::Open
call.
Note that it is possible, but not gauranteed that a call to
Close will not unmap any address space
mappings. Therefore, to be totally portable, you should Unmap
all address blocks
created on this crate first, and only then Close the crate,
Failure is reported by throwing a string exception that describes
Creates a mapped segment into the VME address space. A mapped segment
may not be supported by all vme interface boards. If the vme interface
you are using supports VME mapping, the header <config.h
will define HAVE_VME_MAPPING. A mapped segment
uses the mmap(2) system call to map a chunk of VME address
space into your process virtual address space.
As usual pCrateHandle is the handle gotten from the
CVMEInterface::Open
call. The VME address space in the map is specified by nBase
the starting VME addresss of the map and nBytes the size
of the address block in bytes. On success, a pointer to the process virtual
address space corresponding to that block of VME space is returned. On failure,
a string exception is thrown.
Destroys a mapping created by
CVMEInterface::Map.
Once this is called, dereferencing the block of address pointed to by
the pointer returned from CVMEInterface::Map
will almost certainly result in a segmentation fault.
pCrateHandle is the handle to the VME crate
from CVMEInterface::Open.
pBase is the pointer gotten back from
CVMEInterface::Map.
Finally, nBytes is the size of the address
block requested in the original call to
CVMEInterface::Map.
Peforms a read from from the VME crate. The size of the transfer depends
on the byte count nBytes. A value of 1 or 2 transfers
a single byte or short. 3 will transfer a short and a byte but with an undefined
order and therefore should be avoided. Values that are multiples of 4 will
transfer longwords.
The base address of the transfer is given by
offset, and data are transferred to the
memory pointed to by pBuffer.
pCrateHandle as usual is the handle to the crate
gotten from the CVMEInterface::Open
call.
The function resturns the number of bytes actually transferred. Note that the SBS DMA engine has sufficient pipelining that it will overestimate the number of bytes transferred if the transfer is interrupted by a bus error. The function signals errors by throwing a string exception.
Same as CVMEInterface::Read
however data are transferred from the pBuffer to the
VME bus.
These function manage access to the VME crate. Calling Lock
should be called prior to accessing the VME crate and Unlock
when done for a while. The behavior of these functions ensures that only one
process in a computer system can have a successful Lock.
Subsequent attempts to Lock the bus will cause the
caller to block until the owner calls Unlock.
Note that at least one interface (VM-USB) opens and closes the device
during Lock/Unlock calls. This
means that portable programming requires that you hold the lock for the VME
bus prior to performaing any operations on it.
The address modifier is used by the VME bus to qualify addresses presented
to it into address spaces. The VME bus supports several, potentially
distinct, address spaces (distinct means that address x in one address space
may not reference the same thing as address x in another address space).
The following is the supported part of the definition of
CVMEInterface::AddressMode, which is used
to specify address modifiers.
typedef enum { // Addressing modes:
A16,
A24,
A32,
GEO,
MCST,
CBLT
} AddressMode;
For various An address modifiers, n refers to the number of significant address bits for each space. GEO is the address modifier used by e.g. the CAEN V785 and compatible modules to specify geographical addressing. MCST multicast addressing and CBLT chained block transfer.
It is up to the implementation of the class to ensure that where appropriate, block (MBLT) transfesr are performed.
The public member data const char* m_szDriverName
is a null terminated array of characters that gives the name of the device.
All these member functions throw exceptions of type std::string. The contents of the string thrown are a descriptive error message.
The example below opens the A32 address space in vme crate 0. Creates a memory map of longwords starting at location 0x100000 extending for 0x100 bytes does some stuff and then undoes all that.
...
try {
void *pCrate = CVMEInterface::Open(CVMEInterface::A32, 0);
void* *Vme = CVMEInterface::Map(pCrate, 0x100000, 0x100);
uint32_t* pModule = static_cast<uint32_t>(Vme);
// Do stuff dereferencing pModule.
CVMEInterface::Lock(); //Surround each burst of VME activity
...
CVMEInterface::Unlock(); // with Lock/Unlock calls.
...
// Clean up our mess.
CVMEInterface::Unmap(pCrate, Vme, 0x100);
CVMEInterface::Close(pCrate);
}
catch (std::string errorMessage) {
std::cerr << " Caught a string exception: "
<< errorMessage << std::endl;
}
...