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