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