MCA Data Server Reference

wxMCA Package

Introduction

Server interface

API layer

Driver layer

C-types to libusb0.1

Class constants

Supported Devices

Counter

MCA-1K

MCA-3K

eMorpho

Neutron-3K

USB interface / device driver

USB interface

The USB interface implemented in the ARM M0+ MCU is a peripheral device and has the required control endpoint plus command IN and OUT endpoints (0x81, 0x1) plus data IN and OUT endpoints (0x82, 0x2). Here, IN and OUT are as seen by the host; hence, IN refers to the host reading data from the device.

Device driver

The device driver uses libusb0.1 as the user space usb-driver. Note that only one application can claim a device. In the discussion below, MCA generically refers to Counters, MCA-1000, MCA-3000 and Neutron-3000 devices. More device may be added in the future.

mca_device.py defines the 'mca' class. An object of that class holds all information necessary to operate an MCA. Note that with the exception of its usb_handle, all information is considered transient and the class object is stateless. For each attached MCA one mca object is created, and the bpi_usb.findall() function returns a dictionary of all attached MCA mca objects.

The keys in this dictionary are the unique 32-character long serial numbers of the SAM L21 ARM M0+ processor. These serial numbers are built-in by the manufacturer and cannot be changed or erased. The device driver reads the ARM Version registers to retrieve the unique serial number of the device.

The device driver supports any number of attached MCA units. For a device to be recognized as an MCA it must have a USB vendor id of 0x1FA4 and a recognized product ID. The table below shows currently supported devices.

Unless they require a customized driver, all MCA of the same type have the same serial number (eg "armMorpho001", or "sipmMorpho001") as seen by the operating system as it enumerates the devices on the USB bus. This prevents Windows from having to install a new driver copy for every new MCA.

USB PID vs MCA device
PIDMCA DeviceComment
0x200SiPM CounterWith ARM M0+, no FPGA
0x101PMT-1000With ARM M0+, no FPGA
0x201SiPM-1000With ARM M0+, no FPGA
0x103PMT-3000With ARM M0+ and FPGA
0x203SiPM-3000With ARM M0+ and FPGA
0x104PMT-Neutron-3000With ARM M0+ and FPGA
Table of USB PID used for each supported device.
Device driver functions
NameDescription
scan_allScan for attached MCA, but do not try to claim the devices and open them for communication. Use to count MCA units or check if devices have been plugged in or unplugged.
find_allScan for attached MCA units, claim the interface and open for USB communication. It returns a dictionary of mca objects, one object per attached MCA
close_allClose USB communication for all attached devices.
read_dataRead data from the DATA_IN endpoint. It can read data from their ARM MCU or the FPGA.
write_dataWrite data to COMMAND_EP or DATA_EP. It can send data to the ARM MCU or the FPGA.
Table of device driver functions.

Data I/O

The MCA USB communication uses the concept of a data port. The host first writes instructions to the command endpoint and then issues a usb bulk read to retrieve the data. The software inside the ARM MCU will populate the data_in buffer with the requested data. If the host requires more than 256 byte, the bpi_usb.read_data function will use multiple bulk-reads to satisfy the request.

The read and write functions are both completely agnostic of the data. Data are byte arrays and the two functions look do not look inside or try to interpret the data. Both take an mca object as their only argument.

Function bpi_device.write_data(mca)
ArgumentsTypeDescription
mca.bytes_outByte arrayarray.array('B')
mca.num_bytesIntegerNumber of bytes to send; Maximum is to 216-1=65535 bytes.
mca.write_epIntegerEndpoint; either mca.COMMAND_OUT_EP or mca.DATA_OUT_EP
mca.usb_write_timeoutIntegerUSB write timeout in milli-seconds.
Returns
NoneIntegerNone, or possibly an error code for debugging purposes only.
The bpi_device.write_data function. It writes to the command_out or the data_out endpoint. Data are written in chunks of 256 bytes or less.
Function bpi_device.read_data(mca)
ArgumentsTypeDescription
mca.bytes_inByte arrayarray.array('B'); Buffer to receive the data read from the device.
mca.num_bytesIntegerNumber of bytes to read; Maximum is to 216-1=65535 bytes.
mca.read_epIntegerEndpoint; either mca.COMMAND_IN_EP or mca.DATA_IN_EP, where mca.COMMAND_IN_EP is used for debugging only.
mca.usb_read_timeoutIntegerUSB read timeout in milli-seconds.
num_bytesIntegerNumber of bytes to read (up to 216-1=65535).
Returns
NoneIntegerNone, or possibly an error code for debugging purposes only.
The bpi_usb.read_data function. Data are read in chunks of 256 bytes or less.