XXUSBUtil

Name

XXUSBUtil -- Utility methods for JTEC/Wiener XXUSB controllers

Synopsis


g++ yourstuff -L$DAQLIB -Wl-rpath=$DAQLIB -llibUSB1 \
   `pkg-config libusb-1.0 --libs` `pkg-config libusb-1.0 --cflags`         
      

#include <XXUSBUtil.h>
namespace XXUSBUtil {
    
    
    typedef std::pair<std::string, USBDevice*> XXUSBDevice;
    typedef std::vector<XXUSBDevice> XXUSBDevices;
    
    XXUSBDevices enumerateVMUSB(USB& context);
    XXUSBDevices enumerateCCUSB(USB& context);
    XXUSBDevices enumerateVendorAndProduct(
        USB& context, uint16_t vendor, uint16_t product
    );
    
    int transaction(
        USBDevice* pDevice,
        void* writePacket, size_t writeSize,
        void* readPacket,  size_t readMax, int msTimeout = 0
    );
    void writeActionRegister(USBDevice* pDevice, uint16_t data);

    void executeList(               // VMUSB
        USBDevice* pDevice, const std::vector<uint32_t>& list,
        void* pReturnedData, size_t maxRead, size_t& bytesRead,
        int msTimeout = 0
    );
    
    void executeList(               // CCUSB
        USBDevice* pDevice, const std::vector<uint16_t>& list,
        void* pReturnedData, size_t maxRead, size_t& bytesRead,
        int msTimeout = 0
    );

    uint8_t readEndpoint();
    uint8_t writeEndpoint();
    uint16_t vendorId();
    uint16_t VMUSBProductId();
    uint16_t CCUSBProductId();
    
    // A few operations are somewhat device dependent:
    
    namespace VMUSB {
        void loadList(
            USBDevice* pDevice, uint8_t listNum,
            const std::vector<uint32_t>& list, size_t offset
        );
                
    }
    namespace CCUSB {
        void loadList(
            USBDevice* pDevice, const std::vector<uint16_t>& list,
            bool scaler=false
        );
    }
}

      

DESCRIPTION

Since the VMUSB and CCUSB controllers have similarities at the gross level, it's possible to factor opertions common to them into a stet of unbound functions. The XXUSBUtil package does exactly that; putting data types and functions into the XXUSBUtil namespace.

This manpage documents these functions and data types.

FUNCTIONS AND METHODS

Note that all functions and methods are defined inide the XXUSBUtil namespace so e.g. the function documented as enumerateVMUSB is actually nameed XXUSBUtil::enumerateVMUSB.

XXUSBDevices enumerateVMUSB(USB& context);

Produces a list of VMUSB devices. See DATA TYPES for information about the XXUSBDevices data type. Note that all devices objects returned are dynamically allocated and have not claimed an interface. Unused devices must be deleted. See the first example.

context is the USB context within which to locate the devices. Note that in the XXUSBReadout programs, the controller objects have methods to return a singleton instance pointer to a USB object.

XXUSBDevices enumerateCCUSB(USB& context);

Same as enumerateVMUSB but the CCUSB contollers are enumerated.

XXUSBDevices enumerateVendorAndProduct(USB& context, uint16_t vendor, uint16_t product);

This method enumerates devices that match an arbitraty vendor and product id. Once more context is the USB context.

int transaction(USBDevice* pDevice, void* writePacket, size_t writeSize, void* readPacket, size_t readMax, int msTimeout = 0);

Many operations on the XXUSB controllers are writes followed by reads. For example, immediate operation execution consists of sending a list of operations to the controller, followed by reading back the data the operations in the list generated.

This operation performs these transactions. pDevice, as a USB device on which the transaction is performed. This is normally gotten via one of the enumerate operations above.

writePacket contains a pointer to the data to write. The number of bytes of write data are writeSize.

readPacket points to a buffer into which the data read back from the device is stored. It provides readMax bytes of storage. The actual number of bytes read is stored in bytesRead. msTimeout is the maximum number of milliseconds the function blocks for the read. Note that the default value, 0, means there is no timeout.

The return value is the number of bytes read if greater than zero. The value LIBUSB_ERROR_TIMEOUT reports a timeout, and you must then refer to bytesRead to determine if a retry is approprate. Any actual errors are signalled by throwing a USBException object.

void writeActionRegister(USBDevice* pDevice, uint16_t data);

Both the CCUSB and VMUSB have one write only register, called the action register. All other registers are accessible via immediate list operations. This register is only accessible via this function. pDevice points to the USBDevice object that specifies which device we're writing.

data specifies the data to write to the action register. Note that the bits in the action register may have different meanings between the CC and VM USB controllers. Refer to their manuals.

void executeList(USBDevice* pDevice, const std::vector<uint32_t>& list, void* pReturnedData, size_t maxRead, size_t& bytesRead, int msTimeout = 0);

Executes an immediate list of VME operations for a VMUSB. VMUSB list elements are uint32_t's. pDevice, as usual is the device on which the list is to be executed.

The list is defined by list which provides the list operations and the size of the list. pReturnedData is a pointer to a buffer into which data read by the list will be read. maxRead is the number of bytes available in pReturnedData. bytesRead will be written with the number of bytes actually read from the VME bus by the list. msTimeout is the maximum number of milliseconds to block the read in the transaction this operation implies. Note that the default, 0 implies no timeout.

USBExceptions are used to signal all errors.

void executeList(USBDevice* pDevice, const std::vector<uint16_t>& list, void* pReturnedData, size_t maxRead, size_t& bytesRead, int msTimeout = 0);

Same as previously, but the list is composed of uint16_t elements as the lists for a CCUSB are. Note that this will work perfectly fine on a VMUSB as long as the list is properly formatted.

See the prior overload of executeList for a description of its parameters.

uint8_t readEndpoint();

Returns the endpoint number from which data should be read from an XXUSB controller.

uint8_t writeEndpoint();

Returns the endpoint number to which data should be writen for an XXUSB controller.

uint16_t vendorId();

Returns the vendor id assigned to Wiener for usb devices. This number was assigned by the USB-IF organization.

uint16_t VMUSBProductId();

Returns the product id assigned by Wiener/JTEC for the VMUSB USB VME controller.

uint16_t CCUSBProductId();

Returns the product ID assigned by Wiener/JTEC for the CCUSB USB CAMAC controller.

LOADING LISTS.

The VMUSB and CCUSB operate in data taking by triggering a list of operations on an appropriate trigger. These lists read data which are then blocked and buffered for maximum throughput. The mechanisms for loading a list for later execution, are different between the CCUSB and VMUSB. The CCUSB supports only two lists, an event list and a scaler list and has dedicaed memory for the two. The trigger for the event list is specified by writing appropriate bits in registers in the CCUSB (refer to the CCUSB manual). The VMUSB, supports 8 lists, numbered 0-7 inclusive. Each list can have an independent trigger, however the capability for periodic triggering makes list 1 especially useful as a scaler read list.

A pair of nested namespaces, support loadList methods for the two conrollers. While the parameter signatures for the two loadList functions are, in theory, sufficient to distinguish them to the compiler, putting them in specific namespaces makes unambiguously clear which method should be used when loading lists for specific ontroller.

void XXUSBUtil::VMUSB::loadList(USBDevice* pDevice, uint8_t listNum, const std::vector<uint32_t>& list, size_t offset);

Loads a list of operations into a VMUSB stack for triggered execution in data taking mode. pDevice is the device object connected to the VMUSB. listNum is the number of the list to load [0-7]. list is the list of operations. The CVMUSBReadoutList can be used to create this list.

offset is a value that indicates where in list memory the list should be loaded. The offset to use depends on the sizes of the lists prior to the given list. Each list requires (list.size() + 2)*sizeof(uint32_t)/sizeof(uint16_t)) 'words' of stack space. That is the number of 16bit words required for the list and a two long word header inserted by the firmware.

void XXUSBUtil::CCUSB::loadList(USBDevice* pDevice, const std::vector<uint16_t>& list, bool scaler = false);

Loads a CCUSB readout list. pDevice is the device that's open on the device. list is the list to load and scaler is a flag that, if true, indicates that the list should be loaded as a scaler list.

DATA TYPES

The XXUSBUtil namespace exports two data types:

XXUSBDevice

This type is an std::pair<std::string, USBDevice*>. The first element of the pair is the serial number of a USB device and the second elemet a pointer to a dynamically allocated USBDevice that's open on that device.

VMUSBDevices

Just a vector of XXUSBDevice. This type is returned from the enumertion methods.

EXAMPLES

Enumerating and selecting a VMUSB by serial number. Note that the process is the same for a CCUSB, thought enumerateCCUSB must be used below instead of enumerateVMUSB.


#include <XXUSBUtil.h>
#include <USBDevice.h>
#include <string>

USBDevice*
findVMUSB(const std::stringamp; serial, USB* pContext)
{
   auto devices = XXUSBUtil::enumerateVMUSB(*pContext);
   USBDevice* pResult
   for (int i=0; i < devices.size(); i++) {
      if (serial == devices[i].first) {
        pResult = devices[i].second;
      } else {
         delete devices[i].second;
      }
   }
   if (!pResult) {
      throw std::string("No matching VMUSB in findVMUSB");
   }
   return pResult;
}
         

In the context of the CCUSB program, here's how to load a CCUSB list into a CCUSB controller.


#include <CCUSBReaoutList.h>
#include <XXUSBUtil.h>
#include <USBDevice.h>

/// code fragment to load a CCUSB event readout list:

USB              usb;
CCCUSBReadoutList eventList;
USBDevice* pCCUSB = findDevice(usb);

//... do stuff needed to stuff the eventList
/...

XXUSBUtil::CCUSB::loadList(pDevice, eventList.get(), false);

....