[docs] Add usb_proto.md.
Change-Id: I92261bf9921ae790c94eaa01ba429e6dd124221c
diff --git a/docs/usb_proto.md b/docs/usb_proto.md
new file mode 100644
index 0000000..48bf1a2
--- /dev/null
+++ b/docs/usb_proto.md
@@ -0,0 +1,119 @@
+# Zedmon USB Protocol
+
+## Device and Vendor ID
+
+Zedmon devices all share the same device and vendor ID:
+
+**Vendor ID** 0x18d1 (Google, Inc.)
+
+**Device ID**: 0xaf00
+
+## Interfaces and Endpoints
+
+Zedmon exposes two USB interfaces. One is a CDC Serial interface that can
+be used to communicate with the lk console. The other is a pair of bulk
+endpoints which speak the protocol documented here. This interface is specified
+as:
+
+**Class**: 0xff
+**Subclass**: 0xff
+**Protocol**: 0x00
+
+Future versions may use other protocol numbers.
+
+## Packet Structure
+
+Zedmon packets are encapsulated in USB packets. The only common header is a
+1 byte `packet type` field. Packet length and error detection is handled by USB.
+Some packets only contain the 1 byte `packet type` header and no payload.
+If a single report does not fit in a USB packet, the behavior is undefined.
+
+### Packet Types
+
+The valid packet types are:
+
+ID | Dir | Description
+-----|------|---------------------
+0x00 | H->T | Query Report Format
+0x10 | H->T | Enable Reporting
+0x11 | H->T | Disable Reporting
+0x80 | T->H | Report Format
+0x81 | T->H | Report
+
+### Packet Field and Value Types
+
+The following data types are using in packets. Types with n/a IDs are not
+valid types for report data.
+
+ID | Type | Description
+-----|---------|---------------
+0x00 | uint8 | Unsigned 8 Bit Integer
+0x01 | uint16 | Unsigned 16 Bit Little-Endian Integer
+0x03 | uint32 | Unsigned 32 Bit Little-Endian Integer
+0x04 | uint64 | Unsigned 64 Bit Little-Endian Integer
+0x10 | float32 | 32 Bit Little-Endian IEEE-745 Floating Point
+n/a | string | Null-Terminated ASCII Encoded String.
+
+### Units
+
+The following units are used in report format packets:
+
+ID | Description
+-----|---------------
+0x00 | Amperes
+0x01 | Volts
+
+## Packets
+
+### 0x00 - Query Report Format
+
+Requests the target send a `Report Format` packet. If the target responds
+with a `Report Format` packet with the `Value Index` of 0xff, this indicates that
+there is no value at that index. To enumerate the values, the host should
+start by requesting `Value Index` 0 and continue to request the next
+`Value Index` until receiving a packet with the index of 0xff.
+
+**Payload**:
+
+Byte(s) | Format | Description
+--------|---------|------------
+ 0 | uint8 | Packet Type
+ 1 | uint8 | Value Index
+
+### 0x10 - Enable Reporting
+
+Requests the target start sending `Report` packets.
+
+**Payload**: None
+
+### 0x11 - Disable Reporting
+
+Requests the target stop sending `Report` packets.
+
+**Payload**: None
+
+### 0x80 - Report Format
+
+**Payload**:
+
+Byte(s) | Format | Description
+--------|---------|------------
+ 0 | uint8 | Packet Type
+ 1 | uint8 | Value Index
+ 2 | uint8 | Value Type
+ 3 | uint8 | Unit
+ 4..7 | float32 | Scale
+ 8..63 | string | Name
+
+### 0x81 - Report
+
+**Payload**: One or more data reports of the following format. The length of
+each report is determined by the `Report Format` query responses. No partial
+reports will be included in a `Report` packet.
+
+Field | Format | Description
+----------|----------|------------------------------------------------------
+timestamp | uint64 | Timestamp, in microseconds, in the local clock domain.
+value 0 | variable | Value of the 0th field described by the `Report Format` packets.
+ ... | ... | ...
+value n | variable | Value of the nth field described by the `Report Format` packets.