jAER project on SourceForge

net.sf.jaer.hardwareinterface.usb.silabs
Class SiLabsC8051F320_USBIO_ServoController

java.lang.Object
  extended by net.sf.jaer.hardwareinterface.usb.silabs.SiLabsC8051F320_USBIO_ServoController
All Implemented Interfaces:
de.thesycon.usbio.PnPNotifyInterface, de.thesycon.usbio.UsbIoErrorCodes, HardwareInterface, ServoInterface
Direct Known Subclasses:
WowWeeAliveHardwareInterface, WowWeeRSHardwareInterface

public class SiLabsC8051F320_USBIO_ServoController
extends java.lang.Object
implements de.thesycon.usbio.UsbIoErrorCodes, de.thesycon.usbio.PnPNotifyInterface, ServoInterface

The USB servo controller board is controlled by this class. Use this class by making new SiLabsC8051F320_USBIO_ServoController's from the ServoInterfaceFactory.

Servo motor controller using USBIO driver access to SiLabsC8051F320 device. To prevent blocking on the thread controlling the servo, this class starts a consumer thread that communicates with the USB interface. The producer (the user) communicates with the consumer thread using an ArrayBlockingQueue. Therefore servo commands never produce hardware exceptions; these are caught in the consumer thread by closing the device, which should be reopened on the next command.

This class goes with the USB servo board shown below, which also shows the pinout of the board and the use of the jumpers.

Author:
tobi

Nested Class Summary
 class SiLabsC8051F320_USBIO_ServoController.ServoCommand
          encapsulates the servo command bytes that are sent.
 
Field Summary
protected  de.thesycon.usbio.structs.USB_DEVICE_DESCRIPTOR deviceDescriptor
          the USBIO device descriptor
static int ENDPOINT_OUT_LENGTH
          length of endpoint, ideally this value should be obtained from the pipe bound to the endpoint but we know what it is for this device.
protected  int gDevList
          the devlist handle for USBIO
static java.lang.String GUID
          driver guid (Globally unique ID, for this USB driver instance
protected  de.thesycon.usbio.UsbIo gUsbIo
          the UsbIo interface to the device.
protected  int interfaceNumber
          the device number, out of all potential compatible devices that could be opened
static int NUM_SERVOS
          The board can control this many servos
protected  int numberOfStringDescriptors
           
static short PID
          The product ID
static int SERVO_QUEUE_LENGTH
          number of servo commands that can be queued up.
protected  de.thesycon.usbio.structs.USB_STRING_DESCRIPTOR stringDescriptor1
          the first USB string descriptor (Vendor name) (if available)
protected  de.thesycon.usbio.structs.USB_STRING_DESCRIPTOR stringDescriptor2
          the second USB string descriptor (Product name) (if available)
protected  de.thesycon.usbio.structs.USB_STRING_DESCRIPTOR stringDescriptor3
          the third USB string descriptor (Serial number) (if available)
static short VID
          The vendor ID
 
Fields inherited from interface de.thesycon.usbio.UsbIoErrorCodes
USBIO_ERR_ADDITIONAL_EVENT_SIGNALLED, USBIO_ERR_ALREADY_BOUND, USBIO_ERR_ALREADY_CONFIGURED, USBIO_ERR_BABBLE_DETECTED, USBIO_ERR_BAD_START_FRAME, USBIO_ERR_BTSTUFF, USBIO_ERR_BUFFER_OVERRUN, USBIO_ERR_BUFFER_UNDERRUN, USBIO_ERR_BULK_RESTRICTION, USBIO_ERR_CANCELED, USBIO_ERR_CONTROL_NOT_SUPPORTED, USBIO_ERR_CONTROL_RESTRICTION, USBIO_ERR_CRC, USBIO_ERR_DATA_BUFFER_ERROR, USBIO_ERR_DATA_OVERRUN, USBIO_ERR_DATA_TOGGLE_MISMATCH, USBIO_ERR_DATA_UNDERRUN, USBIO_ERR_DEMO_EXPIRED, USBIO_ERR_DEV_NOT_RESPONDING, USBIO_ERR_DEVICE_GONE, USBIO_ERR_DEVICE_NOT_FOUND, USBIO_ERR_DEVICE_NOT_OPEN, USBIO_ERR_DEVICE_NOT_PRESENT, USBIO_ERR_ENDPOINT_HALTED, USBIO_ERR_EP0_RESTRICTION, USBIO_ERR_ERROR_BUSY, USBIO_ERR_ERROR_SHORT_TRANSFER, USBIO_ERR_FAILED, USBIO_ERR_FIFO, USBIO_ERR_FRAME_CONTROL_NOT_OWNED, USBIO_ERR_FRAME_CONTROL_OWNED, USBIO_ERR_INSUFFICIENT_RESOURCES, USBIO_ERR_INTERFACE_NOT_FOUND, USBIO_ERR_INTERNAL_HC_ERROR, USBIO_ERR_INTERRUPT_RESTRICTION, USBIO_ERR_INVALID_CONFIGURATION_DESCRIPTOR, USBIO_ERR_INVALID_DEVICE_STATE, USBIO_ERR_INVALID_DIRECTION, USBIO_ERR_INVALID_FUNCTION_PARAM, USBIO_ERR_INVALID_INBUFFER, USBIO_ERR_INVALID_IOCTL, USBIO_ERR_INVALID_ISO_PACKET, USBIO_ERR_INVALID_OUTBUFFER, USBIO_ERR_INVALID_PARAM, USBIO_ERR_INVALID_PARAMETER, USBIO_ERR_INVALID_PIPE_FLAGS, USBIO_ERR_INVALID_PIPE_HANDLE, USBIO_ERR_INVALID_POWER_STATE, USBIO_ERR_INVALID_RECIPIENT, USBIO_ERR_INVALID_TYPE, USBIO_ERR_INVALID_URB_FUNCTION, USBIO_ERR_ISO_NA_LATE_USBPORT, USBIO_ERR_ISO_NOT_ACCESSED_BY_HW, USBIO_ERR_ISO_NOT_ACCESSED_LATE, USBIO_ERR_ISO_RESTRICTION, USBIO_ERR_ISO_TD_ERROR, USBIO_ERR_ISOCH_REQUEST_FAILED, USBIO_ERR_LOAD_SETUP_API_FAILED, USBIO_ERR_NO_BANDWIDTH, USBIO_ERR_NO_MEMORY, USBIO_ERR_NO_SUCH_DEVICE_INSTANCE, USBIO_ERR_NOT_ACCESSED, USBIO_ERR_NOT_BOUND, USBIO_ERR_NOT_CONFIGURED, USBIO_ERR_NOT_SUPPORTED, USBIO_ERR_OPEN_PIPES, USBIO_ERR_OUT_OF_ADDRESS_SPACE, USBIO_ERR_OUT_OF_MEMORY, USBIO_ERR_PENDING_REQUESTS, USBIO_ERR_PID_CHECK_FAILURE, USBIO_ERR_PIPE_NOT_FOUND, USBIO_ERR_PIPE_RESTRICTION, USBIO_ERR_PIPE_SIZE_RESTRICTION, USBIO_ERR_POOL_EMPTY, USBIO_ERR_POWER_DOWN, USBIO_ERR_REQUEST_FAILED, USBIO_ERR_RESERVED1, USBIO_ERR_RESERVED2, USBIO_ERR_SET_CONFIG_FAILED, USBIO_ERR_SET_CONFIGURATION_FAILED, USBIO_ERR_STALL_PID, USBIO_ERR_STATUS_NOT_MAPPED, USBIO_ERR_SUCCESS, USBIO_ERR_TIMEOUT, USBIO_ERR_TOO_MUCH_ISO_PACKETS, USBIO_ERR_UNEXPECTED_PID, USBIO_ERR_USBD_BUFFER_TOO_SMALL, USBIO_ERR_USBD_INTERFACE_NOT_FOUND, USBIO_ERR_USBD_TIMEOUT, USBIO_ERR_VERSION_MISMATCH, USBIO_ERR_VID_RESTRICTION, USBIO_ERR_XACT_ERROR
 
Constructor Summary
SiLabsC8051F320_USBIO_ServoController()
          Creates a new instance of SiLabsC8051F320_USBIO_ServoController using device 0 - the first device in the list.
SiLabsC8051F320_USBIO_ServoController(int devNumber)
          Creates a new instance of USBAEMonitor.
 
Method Summary
protected  void checkServoCommandThread()
           
 void close()
          Closes the device.
 void disableAllServos()
          disables all servos
 void disableServo(int servo)
          sends a servo value to disable the servo
 short getDID()
           
 float getLastServoValue(int servo)
          Returns last servo value sent (0 before sending a value)
 float[] getLastServoValues()
          Returns last servo values sent.These are in order of PCA outputs on the SiLabs chip, which are opposite the labeling on the board.
 int getNumberOfStringDescriptors()
          returns number of string descriptors
 int getNumServos()
           
 short getPID()
           
 byte getServo(int servo)
          corrects for mislabling of servo board compared with pca output port on SiLabs, i.e.
 java.lang.String[] getStringDescriptors()
          return the string USB descriptors for the device
 java.lang.String getTypeName()
          get text name of interface, e.g.
 short getVID()
           
 int[] getVIDPID()
          return the USB VID/PID of the interface
protected  boolean hasStringIdentifier()
          checks if device has a string identifier that is a non-empty string
 boolean isOpen()
          reports if interface is open().
static void main(java.lang.String[] args)
          Tests by making the testing GUI.
 void onAdd()
           
 void onRemove()
           
 void open()
          This method does the hard work of opening the device, downloading the firmware, making sure everything is OK.
 void setAllServoValues(float[] values)
          sets all servos to values in one transfer
 void setPort2(int portValue)
          sends a command to set the port 2 output (on the side of the original board) to portValue.
 float setServoPWMFrequencyHz(float freq)
          Attempts to set the PWM frequency.
 void setServoValue(int servo, float value)
          sets servo position.
protected  void submitCommand(SiLabsC8051F320_USBIO_ServoController.ServoCommand cmd)
          Submits the command to the writer thread queue that sends them to the device
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

GUID

public static final java.lang.String GUID
driver guid (Globally unique ID, for this USB driver instance

See Also:
Constant Field Values

VID

public static final short VID
The vendor ID

See Also:
Constant Field Values

PID

public static final short PID
The product ID

See Also:
Constant Field Values

ENDPOINT_OUT_LENGTH

public static final int ENDPOINT_OUT_LENGTH
length of endpoint, ideally this value should be obtained from the pipe bound to the endpoint but we know what it is for this device. It is set to 16 bytes to minimize transmission time. At 12 Mbps, 16 bytes+header (13 bytes)=140 bits requires about 30 us to transmit.

See Also:
Constant Field Values

NUM_SERVOS

public static int NUM_SERVOS
The board can control this many servos


SERVO_QUEUE_LENGTH

public static final int SERVO_QUEUE_LENGTH
number of servo commands that can be queued up. It is set to a small number so that comands do not pile up. If the queue is full when a command is given, then the old commands are discarded so that the latest command is next to be processed. Note that this policy can have drawbacks - if commands are sent to different servos successively, then new commands can wipe out commands to older commands to set other servos to some position.

See Also:
Constant Field Values

interfaceNumber

protected int interfaceNumber
the device number, out of all potential compatible devices that could be opened


stringDescriptor1

protected de.thesycon.usbio.structs.USB_STRING_DESCRIPTOR stringDescriptor1
the first USB string descriptor (Vendor name) (if available)


stringDescriptor2

protected de.thesycon.usbio.structs.USB_STRING_DESCRIPTOR stringDescriptor2
the second USB string descriptor (Product name) (if available)


stringDescriptor3

protected de.thesycon.usbio.structs.USB_STRING_DESCRIPTOR stringDescriptor3
the third USB string descriptor (Serial number) (if available)


numberOfStringDescriptors

protected int numberOfStringDescriptors

deviceDescriptor

protected de.thesycon.usbio.structs.USB_DEVICE_DESCRIPTOR deviceDescriptor
the USBIO device descriptor


gUsbIo

protected de.thesycon.usbio.UsbIo gUsbIo
the UsbIo interface to the device. This is assigned on construction by the factory which uses it to open the device. here is used for all USBIO access to the device


gDevList

protected int gDevList
the devlist handle for USBIO

Constructor Detail

SiLabsC8051F320_USBIO_ServoController

public SiLabsC8051F320_USBIO_ServoController()
Creates a new instance of SiLabsC8051F320_USBIO_ServoController using device 0 - the first device in the list.


SiLabsC8051F320_USBIO_ServoController

public SiLabsC8051F320_USBIO_ServoController(int devNumber)
Creates a new instance of USBAEMonitor. Note that it is possible to construct several instances and use each of them to open and read from the same device.

Parameters:
devNumber - the desired device number, in range returned by CypressFX2Factory.getNumInterfacesAvailable
Method Detail

onAdd

public void onAdd()
Specified by:
onAdd in interface de.thesycon.usbio.PnPNotifyInterface

onRemove

public void onRemove()
Specified by:
onRemove in interface de.thesycon.usbio.PnPNotifyInterface

close

public void close()
Closes the device. Never throws an exception.

Specified by:
close in interface HardwareInterface

getNumberOfStringDescriptors

public int getNumberOfStringDescriptors()
returns number of string descriptors

Returns:
number of string descriptors: 2 for TmpDiff128, 3 for MonitorSequencer

hasStringIdentifier

protected boolean hasStringIdentifier()
checks if device has a string identifier that is a non-empty string

Returns:
false if not, true if there is one

open

public void open()
          throws HardwareInterfaceException
This method does the hard work of opening the device, downloading the firmware, making sure everything is OK. This method is synchronized to prevent multiple threads from trying to open at the same time, e.g. a GUI thread and the main thread. Opening the device after it has already been opened has no effect.

Specified by:
open in interface HardwareInterface
Throws:
HardwareInterfaceException - if there is a problem. Diagnostics are printed to stderr.
See Also:
close()

getStringDescriptors

public java.lang.String[] getStringDescriptors()
return the string USB descriptors for the device

Returns:
String[] of length 2 of USB descriptor strings.

getVIDPID

public int[] getVIDPID()
return the USB VID/PID of the interface

Returns:
int[] of length 2 containing the Vendor ID (VID) and Product ID (PID) of the device. First element is VID, second element is PID.

getVID

public short getVID()

getPID

public short getPID()

getDID

public short getDID()
Returns:
bcdDevice (the binary coded decimel device version

isOpen

public boolean isOpen()
reports if interface is open().

Specified by:
isOpen in interface HardwareInterface
Returns:
true if already open

getNumServos

public int getNumServos()
Specified by:
getNumServos in interface ServoInterface
Returns:
number of servos supported by this interface

getTypeName

public java.lang.String getTypeName()
Description copied from interface: HardwareInterface
get text name of interface, e.g. "CypressFX2" or "SiLabsC8051F320"

Specified by:
getTypeName in interface HardwareInterface

submitCommand

protected void submitCommand(SiLabsC8051F320_USBIO_ServoController.ServoCommand cmd)
Submits the command to the writer thread queue that sends them to the device

Parameters:
cmd - the command, which consists of bytes sent to the device.

getLastServoValues

public float[] getLastServoValues()
Returns last servo values sent.These are in order of PCA outputs on the SiLabs chip, which are opposite the labeling on the board.

Specified by:
getLastServoValues in interface ServoInterface

getLastServoValue

public float getLastServoValue(int servo)
Returns last servo value sent (0 before sending a value)

Specified by:
getLastServoValue in interface ServoInterface

checkServoCommandThread

protected void checkServoCommandThread()

setServoPWMFrequencyHz

public float setServoPWMFrequencyHz(float freq)
Attempts to set the PWM frequency. Most analog hobby servos accept from 50-100Hz and digital hobby servos can accept up to 250Hz, although this information is usually not specified in the product information. The SiLabsUSB board can drive servos at 180, 90, 60 or 45 Hz. The frequency is based on the overflow time for a 16 bit counter that is clocked by overflow of an automatically reloaded counter/timer that is clocked by the system clock of 12 MHz. With a timer reload of 1 (requiring 2 cycles to overflow), the 16 bit counter is clocked at 6 MHz, leading to a frequency of 91 Hz.

The default frequency is 91Hz.

Parameters:
freq - the desired frequency in Hz. The actual value is returned.
Returns:
the actual value or 0 if there is an error.

getServo

public byte getServo(int servo)
corrects for mislabling of servo board compared with pca output port on SiLabs, i.e. S0 on board is actually PCA3 output and S3 is PCA0.

Parameters:
servo - is the labeled output port
Returns:
the index into the array that is passed to setAllServoValues to set all the servos simultaneously

setServoValue

public void setServoValue(int servo,
                          float value)
sets servo position. The float value is translated to a value that is written to the device thar results in s pulse width that varies from 0.9 ms to 2.1 ms.

Specified by:
setServoValue in interface ServoInterface
Parameters:
servo - the servo motor, 0 based
value - the value from 0 to 1. Values out of these bounds are clipped. Special value -1f turns off the servos.
See Also:
ServoInterface.setAllServoValues(float[])

disableAllServos

public void disableAllServos()
Description copied from interface: ServoInterface
disables all servos

Specified by:
disableAllServos in interface ServoInterface

disableServo

public void disableServo(int servo)
sends a servo value to disable the servo

Specified by:
disableServo in interface ServoInterface
Parameters:
servo - the servo number, 0 based

setAllServoValues

public void setAllServoValues(float[] values)
sets all servos to values in one transfer

Specified by:
setAllServoValues in interface ServoInterface
Parameters:
values - array of value, must have length of number of servos. Order of values is order given by getServo(i), where i is the labeled output on the servo board.
See Also:
ServoInterface.getNumServos()

setPort2

public void setPort2(int portValue)
sends a command to set the port 2 output (on the side of the original board) to portValue. This port is presently set to open-drain mode on all bits.

Specified by:
setPort2 in interface ServoInterface
Parameters:
portValue - the bits to set

main

public static void main(java.lang.String[] args)
Tests by making the testing GUI.

Parameters:
args - the command line arguments

jAER project on SourceForge