Daniel Beer

# 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
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
bmAttributes            3
Transfer Type            Interrupt
Synch Type               None
Usage Type               Data
wMaxPacketSize     0x0040  1x 64 bytes
bInterval             255
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bmAttributes            2
Transfer Type            Bulk
Synch Type               None
Usage Type               Data
wMaxPacketSize     0x0040  1x 64 bytes
bInterval             255
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
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
bmAttributes            3
Transfer Type            Interrupt
Synch Type               None
Usage Type               Data
wMaxPacketSize     0x0040  1x 64 bytes
bInterval               1
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
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.

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 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).

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).