MCA Data Server Reference

COUNTER

Introduction

USB driver

Counter Device

Data structures

Overview

Module Constants

ARM Data structures

Version

Status

Controls

Calibration

Two-channel Logger

Time histogram

API

Overview

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.

counter_device.py defines the 'mca' class. An object of that class holds all information necessary to operate an Counter. Note that with the exception of its usb_handle, all information is considered transient and the class object is stateless. For each attached Counter one mca object is created, and the bpi_usb.findall() function returns a dictionary of all attached Counter 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 Counters. For a device to be recognized as a Counter it must have a USB vendor id of 0x1FA4 and a product ID of 0x100 (PMT-Counter) or 0x200 (SiPM-Counter).

Unless they require a customized driver, all Counters have the same serial number ("sipmCTR0001", or "pmtCTR0001") as seen by the operating system when it enumerates the devices on the USB bus. This prevents Windows from having to install a new driver copy for every new Counter.

Device driver functions
NameDescription
scan_allScan for attached Counter units, but do not try to claim the devices and open them for communication. Use to count Counter units or check if devices have been plugged in or unplugged.
find_allScan for attached Counter units, claim the interface and open for USB communication. It returns a dictionary of mca objects, one object per attached Counter
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 Counter 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 counter_device.mca.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 mca.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 counter_device.mca.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 mca.read_data function. Data are read in chunks of 256 bytes or less.