#include <SBSBit3API.h.h>
#include <string>
static void SetDMABlockTransfer(void* pHandle, bool enable);
static void SetDMAPauseMode(void* pHandle, bool enable);
static void SetMaxTransferWidth(void* pHandle, bt_width_t width);
static void SetDMAAddressModifier(void* pHandle, int Modifier);
static void SetMMAPAddressModifier(void* pHandle, int Modifier);
static void SetSwapMode(void* pHandle, bt_swap_t SwapMode);
static void SetDMAThreshold(void* pHandle, int nTransfers);
static void SetDMAPollCeiling(void* pHandle, int nTransfers);
static void SetTraceMask(void* pHandle, int nMask);
static int GetLocalCardPartNumber(void* pHandle);
static int GetRemoteCardPartNumber(void* pHandle);
static unsigned int GetLocalMemorySize(void* pHandle);
static bool IsDMABlockTransfer(void* pHandle);
static bool IsDMAPauseMode(void* pHandle);
static bt_width_t GetMaxTransferWidth(void* pHandle);
static int GetDMAAddressModifier(void* pHandle);
static int GetMMAPAddressModifier(void* pHandle);
static int GetSwapMode(void* pHandle);
static int GetDMAThreshold(void* pHandle);
static int GetDMAPollCeiling(void* pHandle);
static int GetTraceMask(void* pHandle);
static void ResetVme(void* pHandle);
static bt_error_t CheckErrors(void* pHandle);
static bt_error_t ClearErrors(void* pHandle);
The CSBSBit3VmeInterface provides
static member functions that allow you to tune the way an
SBS Bit 3 PCI/VME interface card works. These functions are
simply a thin wrapper around similarly named bt_xxxx
and btp_xxxx functions in the SBS support library.
If you have any doubts about this documentation, refer to the SBS
documentation for their library.
The headers for this must be located by the compiler at compile time via e.g.:
-I$DAQROOT/include
Furthermore, the linker must incorporate the appropriate set of libraries
via e.g.:
-I$DAQROOT/lib -lVmeAPI -lException -lbtp -lpthread
In all the function definitions discussed in this section,
pHandle is a VME crate handle that was
returned from CVMEInterface::Open.
All functions throw std::string exceptions in the event of error.
The value of the string is a descriptive error message that can be output to
e.g. stderr.
Enables or disbales DMA block transfer mode according to the value of
enable. When enabled, and a transfer is larger
than the DMA threshold, DMA is done using VME Block transfers. The
hardware automatically modifies your address modifier appropriately as well.
Block transfer mode for the VME bus is a performance enhancement supported by most boards. With block transfers, an address cycle only occurs at the beginning of a transfer, with an increment of the appropriate width to be understood betwen transfers. Note that the VME bus specification requires that block transfers not cross 256byte boundaries. Larger block transfers are tranparently composed of several smaller, compliant block transfers.
Enables or disables DMA pause mode. DMA pause mode, when enabled, periodically releases the VME bus in the middle of DMA transfers. This can lower the latency of bus arbitration in a multimaster VME system.
Sets the maximum transfer width on the bus according to width.
Values for width can be 1, 2 or 4 for byte, short and longwords respectively.
This can be used prior to a DMA transfer to ensure that a block transfer to or from
a module that e.g. does not support D32 transfers is done in the appropriate width.
Sets the value used for subsequent DMA transfers on this handle. The modifier that must be supplied is the actual binary value of the AM bits gated on the VME bus. See Appendix C for a table of VME address modifiers.
Sets the value used for the address modifier for subsequent memory
mapping operations (e.g.
CVMEInterface::Map
calls). This can be used to allow a single device handle to
create memory maps in several address spaces.
Allows you to set the hardware byte swapping mode performed by the interface. Normally the default swapping mode (BT_SWAP_DEFAULT) is suitable for use with Intel (little endian) systems. Other byte swap modes are provided however other modes are allowed as shown by the definition of bt_swap_t below:
typedef enum BT_SWAP_BITS_VALUE {
BT_SWAP_NONE = 0, /* No swapping */
BT_SWAP_BSNBD, /* Byte swap, non byte data */
BT_SWAP_WS, /* Word swap */
BT_SWAP_WS_BSNBD, /* Word swap and byte swap, non btye data */
BT_SWAP_BSBD, /* Byte swap, btye data */
BT_SWAP_BSBD_BSNBD, /* Btye swap, byte data and byte swap, non byte data */
BT_SWAP_BSBD_WS, /* Byte swap, byte data and word swap */
BT_SWAP_BSBD_WS_BSNBD, /* All possible swapping */
BT_SWAP_DEFAULT, /* Driver default swapping */
BT_MAX_SWAP
} bt_swap_t;
Sets the DMA transfer threshold. If a
CVMEInterface::Read or
CVMEInterface::Write
are performed with a size of more than nTransfers bytes,
the DMA engine is used to accomplish the transfer rather than program control.
This is provided because the overhead of starting/stopping a DMA transfer is
significant and, therefore, for small transfer counts, it is quicker
to do program controlled transfers in the device drivers than to do a DMA
transfer. Note that the efficiency of DMA transfers is also affected by
whether or not the DMA engine is allowed to run block mode transfers.
Program controlled transfers are always done without enabling block mode.
Sets the DMA Polling ceiling to nTransfers.
The DMA poll ceiling determines when the device driver switches from
using polling to wait for DMA to complete to using interrupts.
This is a balancing act between interrupt latency and system responsiveness.
While the device driver is polling the computer will literally not be able to do
anything else. Waiting for completion by interrupt requires more device driver
overhead, but allows the computer to do other things during the wait.
Clearly for very small transfer counts, by the time the driver has set up the interrupt completion, the transfer may have completed. For very large transfer counts, polling will make the responsiveness of the system to other events quite jerky.
Sets the conditions under which the driver will trace what it is doing to the system log files. This is intended for device driver debugging. Keep you code off this. If you're debugging patches to the device driver you will have figured out how to use this function. Over-use of tracing can have heavy performance implications.
Reads the part number of the PCI part of the bus bridge.
Reads the part number of the VME part of the bus bridge.
Some models of the VME side of the bus bridge can have on-board memory. The idea is that a secondary VME master could place data in this memory which could then be transferred out by the host without creating VME bus contention. This function returns the number of bytes of memory in the VME side of the bridge (could be 0).
Returns true if DMA has been enabled to use VME block transfers.
Returns true if DMA Pause mode was enabled
Returns the maximum number of bytes wide that can be transferred in one Bus operation.
Returns the DMA address modifier. If you are going to use a DMA transfer with a different address modifier than the default for your handle, you can use this to get the default modifier, change it, perform your DMA and then restore the default modifier.
Returns the address modifier used to do memory mapping.
returns the swap mode for the device. This will actually be a value that can be cast to bt_swap_t
Returns the threshold at which DMA is used rather than programmed I/O for read/write operations.
Returns the transfer count above which the driver will use interrupts to wait for DMA completion rather than driver polling.
Returns the set of bits that describe what the driver is tracing.
Resets the VME crate.
Checks the PCI/VME bridge for asynchronous errors.
Resets the adapter error status.
Byte swapping is controlled/reported using bt_swap_t which is defined as shown below:
typedef enum BT_SWAP_BITS_VALUE {
BT_SWAP_NONE = 0, /* No swapping */
BT_SWAP_BSNBD, /* Byte swap, non byte data */
BT_SWAP_WS, /* Word swap */
BT_SWAP_WS_BSNBD, /* Word swap and byte swap, non btye data */
BT_SWAP_BSBD, /* Byte swap, btye data */
BT_SWAP_BSBD_BSNBD, /* Btye swap, byte data and byte swap, non byte data */
BT_SWAP_BSBD_WS, /* Byte swap, byte data and word swap */
BT_SWAP_BSBD_WS_BSNBD, /* All possible swapping */
BT_SWAP_DEFAULT, /* Driver default swapping */
BT_MAX_SWAP
} bt_swap_t;
Error codes include:
typedef enum {
BT_SUCCESS = 0, /* Everything is just swell */
POSIX_EQUIV(BT_EIO, EIO), /* Input or output error */
POSIX_EQUIV(BT_ENXIO, ENXIO), /* Non-existent device */
POSIX_EQUIV(BT_ENOMEM, ENOMEM), /* Out of memory or other resource */
POSIX_EQUIV(BT_EINVAL, EINVAL), /* Invalid parameter */
POSIX_EQUIV(BT_EACCESS, EACCES), /* Access failed: permission denied */
POSIX_EQUIV(BT_EDESC, EBADF), /* Invalid descriptor */
POSIX_EQUIV(BT_ENOSUP, ENOSYS), /* Option not supported on this */
/* particular implementation. */
POSIX_EQUIV(BT_EABORT, EINTR), /* Interrupted a system call */
#define BT_EINTR BT_EABORT /* Obsolete form */
POSIX_EQUIV(BT_ESYSMAX, BT_ESTART), /* past last POSIX defined error */
BT_EFAIL, /* Something went wrong. Generic error. */
BT_ENORD, /* Device does not support reads */
BT_ENOWR, /* Device does not support writes */
BT_ESTATUS, /* Status register error value */
BT_ENOPWR, /* Power is off or cable is disconnected */
BT_EPWRCYC, /* Power was cycled */
BT_EBUSY, /* Timer expired before a resource became available. */
BT_ELCARD, /* Local card failed diagnostics */
BT_ECABLE, /* Interconnection cable failed diagnostics */
BT_ERCARD, /* Remote card failed diagnostics */
BT_EPAIR, /* The pair of adapter cards failed diagnostics */
BT_EEXCEPT, /* OS exception error */
BT_EEVT_NOT_REGISTERED, /* enviorment not registered */
BT_ENOT_FOUND, /* Attempt to acquire or remove an unknown event */
BT_ENOT_LOCKED, /* attempt to unlock a unlocked unit */
BT_ENOT_TRANSMITTER, /* Remote access requested on a unit that is not a transmitter */
BT_EPCI_CONFIG, /* Error reading or writting PCI configuration registers */
BT_ELOCAL, /* Attempt to perform TAS or CAS on local device */
BT_EUNKNOWN_REMID, /* Remote adaptor not supported */
BT_ENO_UNIT, /* Unit does not exist */
BT_ENO_MMAP, /* Logical device does not support bt_mmap() */
BT_EHANDLE, /* Attempt to get unique signal handle failed */
BT_MAX_ERR /* Last Error number */
} bt_error_t;
Note that POSIX_EQUIV makes the left status
equal to the right status.
The software indicates errors by throwing std::string exceptions. The value of these exception objects is explanatory error text suitable for display on e.g. std::cerr.