summaryrefslogtreecommitdiff
path: root/doc/common-usbproto.xml
blob: 3b8b8948348512b01b2c5bf84b34588d437d1e30 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
<section>
<title>USB Protocol</title>
<para>
The USB protocol is completely non-standard.  Since OpenPICC is a very
special-purpose device, it's obvious that no standard USB protocol will be
applicable.  However, our vendor-specific protocol is completely open and
documented to allow for development of interoperable applications.
</para>

<section>
<Title>USB Endpoints</title>
<para>
Since the SAM7 hardware only provides four USB endpoints, we have to use them
according to their endpoint type, rather than to their function within the
protocol. We have to overload and (de)multiplex within one endpoint quite a
bit.
</para>
<para>
EP0 - Control Endpoint
EP1 - Bulk Out endpoint (host -> device)
EP2 - Bulik In endpoint (device -> host)
EP3 - Interrupt In endpoint (device -> host)
</para>
<para>
The control endpoint behaves according to the USB specification.  It only
takes care of usb configuration and management.  No application data is
transferred over it.
</para>
</section> <!-- USB Endpoints -->

<section>
<title>USB packets, transfers</title>
<para>
In order to understand this devices' USB prootocol, some basics about any
communication with USB endpoints need to be known.
</para>
<para>
USB endpoints exchange a stream of data by means of USB transfers.  Every
transfer is conveyed as multiple transaction.  Every transaction transports
multiple USB packets.  The Endpoint buffer size of the SAM7 usb device
controller is 64bytes for EP1, EP2 and EP3.  Therefore, a single packet can be
up to 64 bytes in size. As soon as a packet smaller than the endpoint size
(64byte) is received, the end of that particular USB transfer is detected.
If the transfer size is an integral size of the endpoint size, a zero-length-packet (ZLP) is sent to explicitly signal the end of the transfer.
</para>
<para>
The buffer management inside the SAM7 firmware can deal with USB transfers of
up to 2048 bytes in size.  To optimize memory efficiency, all buffers are
statically pre-allocated, and the majority of USB buffers is only 64bytes in
size.  This way, the memory consumption for small transfers (such as register read/write transfers) can be kept low.
</para>
<para>
Large transfers (&gt; 64 bytes, but &let; 2024 bytes) should be used only
when they are absolutely required.
</para>
</section> <!-- USB packets, transfers -->

<section>
<title>Host software interaction with USB Endpoints</title>
<para>
Any host software operating the USB device should take into consideration
that memory is a scarce resource on the SAM7, especially for
applications with relatively high speed compared to the USB 1.1 full speed bandwith), such as higher-bitrate 847kHz ISO14443 communication.
</para>
<para>
Therefore it is important to serve device requests on the BULK IN and
INTERRUPT IN endpoints as soon as possible.  In most cases, the application
will simply keep those two pipes open all the time, by re-submitting an USB
request block as soon as the previous one at that endpiont has completed.
</para>
<para>
The BULK OUT endpoint will obviously only be filled with requests from the
host software when there are any such requests.
</para>
<para>
On the highest level of the protocol, there are three different classes of device requests:
</para>
<para>
1. uni-directional without high-level acknowledgement, such as a register
write without explicit request for a response.  This means that the host
software will only send a single BULK OUT transfer.  This transfer is
acknowledged inherently by the USB protocol, and the host software can be sure
that the transfer was correctly received by the device.  
</para>
<para>
2. bi-directional with a single response, such as a register read. This means
that the host sends a single BULK OUT transfer, to which the device replies
with a single BULK IN transfer.
</para>
<para>
3. bi-directional with multiple responses.  This means that even though the
host only sends a single BULK OUT transfer, there will be multiple BULK IN
transfers in response.
</para>
</section> <!-- Host software interaction -->

<section>
<title>The usb transfer header</title>
<para>
Application data transferred over EP1, EP2 and EP3 is prefixed with a
four-byte header, 'struct openpcd_hdr'.
</para>
<para>
The first byte is the command byte.  The high nibble of the command byte
specifies the command class, whereas the the low nibble selects the particular
command within a given class.
</para>
<para>
The second byte specifies flags.  There are currently two flags:
</para>
<para>
The RESPOND flag signifies that the sender of this transfer explicitly
requests a response back from the other side.
</para>
<para>
The ERROR flag signifies that this transfer indicates some error
</para>
<para>
The MULTIPLE flag signifies that this is part of a response that consists of
multiple transfers.
</para>
<para>
The LAST flag signifies that the current transfer is the last transfer
of a multiple-transfer response.
</para>
<para>
The third byte is called 'register' for historical purpose.  It should
actually rather be called address or index.  Its significance differs
according to the actual command that is being performed.
</para>
<para>
The fourth byte is called 'val' for 'value'. Again, its purpose is command
specific.  In case of e.g. a register write, it is the value to be written
into the register.
</para>
</section> <!-- USB Transfer Header -->

<section>
<title>The individual USB protocol commands</title>

<section>
<title>Generic USB commands: CMD_CLS_GENERIC</title>

<section>
<title>CMD_GET_VERSION</title>
<para>
This command is used to obtain the version number of the USB device. This
might be used to differentiate different hardware revisions by the host software.
</para>
<para>
The response to this command contains the version number in the
variable-length 'data' section of the transfer.
</para>
</section>

<section>
<title>CMD_SET_LED</title>
<para>
Using this command, the host software can control the LED's present in the
OpenPICC.  The LED can be specified in the 'reg' section of the header.
Currently there are two LED's, LED 1 (green) and LED 2 (red).  The 'val'
header field controls whether the LED should be switched on (1) or off (0).
</para>
</section>

<section>
<title>CMD_GET_SERIAL</title>
<para>
This command is used to obtain the serial number of the OpenPICC device.
The serial number is returned in the 'data' section of the response transfer.
</para>
</section>

</section> <!-- Generic USB commands -->

<section>
<title>USB Testing commands</title>
<section>
<title>CMD_USBTEST_IN</title>
<para>
</para>
</section>
<section>
<title>CMD_USBTEST_OUT</title>
<para>
</para>
</section>
</section> <!-- USB testing commands -->


personal git repositories of Harald Welte. Your mileage may vary