USB protocol
This device has a product:vendor code of 0451:f432 and provides two USB interfaces. One is a CDC-ACM class device (this is the interface to the application UART). This interface is supported by Linux 2.6.31.1, and appears as /dev/ttyACMxx.
The other interface is the debug interface. It presents itself as an HID class interface and has two interrupt endpoints (0x01 for output, 0x81 for input). This interface is highlighted in the output from lsusb below:
Bus 004 Device 002: ID 0451:f432 Texas Instruments, Inc.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x0451 Texas Instruments, Inc.
idProduct 0xf432
bcdDevice 1.00
iManufacturer 1 Texas Instruments
iProduct 2 Texas Instruments MSP-FET430UIF
iSerial 3 47FF598CDECA3743
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 85
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 1 AT-commands (v.25ter)
iInterface 5 MSP430 Application UART
CDC Header:
bcdCDC 1.10
CDC Call Management:
bmCapabilities 0x00
bDataInterface 0
CDC ACM:
bmCapabilities 0x02
line coding and serial state
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 255
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x03 EP 3 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 255
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 255
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 4 MSP430 Debug-Interface
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.01
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 694
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Device Status: 0x0000
(Bus Powered)
There are (at a more abstract level than USB bus transfers) three types of packets that are used to communicate with the device:
- Buffer fills
- These packets are used to send a data payload to the device (for example, a block of data to be written to flash, or a set of register values).
- Command packets
- These are used to instruct the device to perform some action.
- Reply packets
- A reply packet is sent from the device in response to a command packet (no reply is sent in response to a buffer fill).
The format of each of these three types of packet are described in detail in the following sections.
Both command packets and reply packets include a checksum. For details of the checksum calculation, see the source code.
Note that certain padding rules must be observed for transfers to the device. They are, as far as I can tell:
Transfers whose length is larger than 48 must be padded to a multiple of 64 bytes.
Transfers whose length is not larger than 48, but larger than 16, must be padded to a multiple of 16 bytes, plus 1.
Failure to pad transfers in this way seems to result in the device crashing, after which it must be replugged.
The first byte of all USB transfers is the length of the transfer, minus 1.
USB interface: Buffer fills
These transfers are sent to endpoint 0x01 on the device to put data into an internal buffer. The size of this buffer is unknown, but appears to be not much larger than 256 bytes. This buffer can be filled by multiple USB transfers, each of which contain part of the data block.
An example of this type of packet is shown and described below:
PipeHandle = 80e56994 [endpoint 0x00000001]
00000000: 20 83 3b 00 0f 00 00 00 00 00 00 00 00 00 33 0f
00000010: 1f 0f ff ff 05 00 00 00 00 02 00 01 00 01 00 d7
00000020: 60
Byte 0x00: The length of this transfer, minus 1.
Byte 0x01: Always 0x83, to indicate a buffer fill.
Bytes 0x02-0x03: Destination offset in buffer, little endian (0x003b).
Byte 0x04: Data length (N = 0x0f).
Bytes 0x05-0x13: Data bytes (always N bytes starting at 0x05).
Bytes 0x14-0x20: Garbage to satisfy padding rules.
USB interface: Command packets
Command packets are sent to endpoint 0x01 on the device to instruct it to perform some action, or to retrieve information. An example command packet is shown and described below:
PipeHandle = 80e56994 [endpoint 0x00000001]
00000000: 0c 7e 12 02 01 00 01 00 00 00 4f fc 7e
Byte 0x00: The length of this transfer, minus 1.
Byte 0x01: Command delimeter (always 0x7e).
Bytes 0x02-0x09: Command payload.
Bytes 0x0a-0x0b: Checksum (0xfc4f) calculated over command payload.
Byte 0x0c: Command delimeter (always 0x7e).
Command payloads are variable length (but are usually multiples of 4 bytes). Since they are delimeted by 0x7e bytes either side, certain quoting rules must be used for some payloads:
- 0x7d must be replaced with 0x7d 0x5d.
- 0x7e must be replaced with 0x7d 0x5e.
The first byte of a command payload indicate the command type (which is matched in the reply). For more details, consult the source code for MSPDebug (in fet.c).
USB interface: Reply packets
The device transfers replies from endpoint 0x81. All USB transfers from the device are of exactly 64 bytes, but reply packets may be of almost any size. Thus, reply packets are split into fragments and received over multiple transfers (possibly with padding).
It is in principle possible for a single transfer to contain fragments of multiple reply packets. However, I’ve never seen this from the eZ430-RF2500. In MSPDebug, the transfers are reassembled into a continuous byte stream from which packets are then extracted.
An example of a reply sent via multiple transfers from the device is shown below:
PipeHandle = 80e56974 [endpoint 0x00000081]
00000000: 3f 3e 4a 00 08 03 00 00 40 00 00 00 00 80 00 00
00000010: 00 06 00 00 00 00 00 00 00 00 00 00 ff ff 00 00
00000020: ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00
00000030: ff ff 00 00 ff ff 00 00 ff ff 00 00 0e 02 00 00
Byte 0x00: Number of bytes in this transfer, minus 1 (always 0x3f).
Byte 0x01: Number of valid data bytes.
Bytes 0x02-0x3f: Packet data.
PipeHandle = 80e56974 [endpoint 0x00000081]
00000000: 3f 0e 2a 02 00 00 c1 ff 00 00 08 00 00 00 9e d8
00000010: ff ff ff bf ff ff 7f ef 7d db ff ff ff df ff a7
00000020: fd 7f ef bd ff bf f7 ff bf 9f f9 ff fb ff bf ff
00000030: bf ff be ff ff ef fd 7b df ff ff ff ff ff f7 ff
Byte 0x00: Number of bytes in this transfer, minus 1 (always 0x3f).
Byte 0x01: Number of valid data bytes.
Bytes 0x02-0x0f: Packet data.
Bytes 0x10-0x3f: Garbage to satisfy padding rules.
After unpacking an concatenating the valid data in each transfer, packets can be extracted from the resulting stream. An example showing the packet extracted from the above data is shown below:
00000000: 4a 00 08 03 00 00 40 00 00 00 00 80 00 00 00 06
00000010: 00 00 00 00 00 00 00 00 00 00 ff ff 00 00 ff ff
00000020: 00 00 ff ff 00 00 ff ff 00 00 ff ff 00 00 ff ff
00000030: 00 00 ff ff 00 00 ff ff 00 00 0e 02 00 00 2a 02
00000040: 00 00 c1 ff 00 00 08 00 00 00 9e d8
Bytes 0x00-0x01: Payload length, including checksum (0x004a).
Bytes 0x02-0x49: Packet payload.
Bytes 0x4a-0x4b: Checksum calculated over payload (0xd89e).
Note that the first byte of the payload matches the first byte of the command that prompted the reply. In this example, the reply is in response to a “get context” command (0x08).