]> git.gir.st - tmk_keyboard.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/USBHost/USBHost/USBHost.h
Merge commit '1fe4406f374291ab2e86e95a97341fd9c475fcb8'
[tmk_keyboard.git] / tmk_core / tool / mbed / mbed-sdk / libraries / USBHost / USBHost / USBHost.h
1 /* mbed USBHost Library
2 * Copyright (c) 2006-2013 ARM Limited
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef USBHOST_H
18 #define USBHOST_H
19
20 #include "USBHALHost.h"
21 #include "USBDeviceConnected.h"
22 #include "IUSBEnumerator.h"
23 #include "USBHostConf.h"
24 #include "rtos.h"
25 #include "dbg.h"
26 #include "USBHostHub.h"
27
28 /**
29 * USBHost class
30 * This class is a singleton. All drivers have a reference on the static USBHost instance
31 */
32 class USBHost : public USBHALHost {
33 public:
34 /**
35 * Static method to create or retrieve the single USBHost instance
36 */
37 static USBHost * getHostInst();
38
39 /**
40 * Control read: setup stage, data stage and status stage
41 *
42 * @param dev the control read will be done for this device
43 * @param requestType request type
44 * @param request request
45 * @param value value
46 * @param index index
47 * @param buf pointer on a buffer where will be store the data received
48 * @param len length of the transfer
49 *
50 * @returns status of the control read
51 */
52 USB_TYPE controlRead(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len);
53
54 /**
55 * Control write: setup stage, data stage and status stage
56 *
57 * @param dev the control write will be done for this device
58 * @param requestType request type
59 * @param request request
60 * @param value value
61 * @param index index
62 * @param buf pointer on a buffer which will be written
63 * @param len length of the transfer
64 *
65 * @returns status of the control write
66 */
67 USB_TYPE controlWrite(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len);
68
69 /**
70 * Bulk read
71 *
72 * @param dev the bulk transfer will be done for this device
73 * @param ep USBEndpoint which will be used to read a packet
74 * @param buf pointer on a buffer where will be store the data received
75 * @param len length of the transfer
76 * @param blocking if true, the read is blocking (wait for completion)
77 *
78 * @returns status of the bulk read
79 */
80 USB_TYPE bulkRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true);
81
82 /**
83 * Bulk write
84 *
85 * @param dev the bulk transfer will be done for this device
86 * @param ep USBEndpoint which will be used to write a packet
87 * @param buf pointer on a buffer which will be written
88 * @param len length of the transfer
89 * @param blocking if true, the write is blocking (wait for completion)
90 *
91 * @returns status of the bulk write
92 */
93 USB_TYPE bulkWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true);
94
95 /**
96 * Interrupt read
97 *
98 * @param dev the bulk transfer will be done for this device
99 * @param ep USBEndpoint which will be used to write a packet
100 * @param buf pointer on a buffer which will be written
101 * @param len length of the transfer
102 * @param blocking if true, the read is blocking (wait for completion)
103 *
104 * @returns status of the interrupt read
105 */
106 USB_TYPE interruptRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true);
107
108 /**
109 * Interrupt write
110 *
111 * @param dev the bulk transfer will be done for this device
112 * @param ep USBEndpoint which will be used to write a packet
113 * @param buf pointer on a buffer which will be written
114 * @param len length of the transfer
115 * @param blocking if true, the write is blocking (wait for completion)
116 *
117 * @returns status of the interrupt write
118 */
119 USB_TYPE interruptWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true);
120
121 /**
122 * Enumerate a device.
123 *
124 * @param dev device which will be enumerated
125 *
126 * @returns status of the enumeration
127 */
128 USB_TYPE enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerator);
129
130 /**
131 * reset a specific device
132 *
133 * @param dev device which will be resetted
134 */
135 USB_TYPE resetDevice(USBDeviceConnected * dev);
136
137 /**
138 * Get a device
139 *
140 * @param index index of the device which will be returned
141 *
142 * @returns pointer on the "index" device
143 */
144 USBDeviceConnected * getDevice(uint8_t index);
145
146 /*
147 * If there is a HID device connected, the host stores the length of the report descriptor.
148 * This avoid to the driver to re-ask the configuration descriptor to request the report descriptor
149 *
150 * @returns length of the report descriptor
151 */
152 inline uint16_t getLengthReportDescr() {
153 return lenReportDescr;
154 };
155
156 /**
157 * register a driver into the host associated with a callback function called when the device is disconnected
158 *
159 * @param dev device
160 * @param intf interface number
161 * @param tptr pointer to the object to call the member function on
162 * @param mptr pointer to the member function to be called
163 */
164 template<typename T>
165 inline void registerDriver(USBDeviceConnected * dev, uint8_t intf, T* tptr, void (T::*mptr)(void)) {
166 int index = findDevice(dev);
167 if ((index != -1) && (mptr != NULL) && (tptr != NULL)) {
168 USB_DBG("register driver for dev: %p on intf: %d", dev, intf);
169 deviceAttachedDriver[index][intf] = true;
170 dev->onDisconnect(intf, tptr, mptr);
171 }
172 }
173
174 /**
175 * register a driver into the host associated with a callback function called when the device is disconnected
176 *
177 * @param dev device
178 * @param intf interface number
179 * @param fn callback called when the specified device has been disconnected
180 */
181 inline void registerDriver(USBDeviceConnected * dev, uint8_t intf, void (*fn)(void)) {
182 int index = findDevice(dev);
183 if ((index != -1) && (fn != NULL)) {
184 USB_DBG("register driver for dev: %p on intf: %d", dev, intf);
185 deviceAttachedDriver[index][intf] = true;
186 dev->onDisconnect(intf, fn);
187 }
188 }
189
190 /**
191 * Instantiate to protect USB thread from accessing shared objects (USBConnectedDevices and Interfaces)
192 */
193 class Lock
194 {
195 public:
196 Lock(USBHost* pHost);
197 ~Lock();
198 private:
199 USBHost* m_pHost;
200 };
201
202 friend class USBHostHub;
203
204 protected:
205
206 /**
207 * Virtual method called when a transfer has been completed
208 *
209 * @param addr list of the TDs which have been completed
210 */
211 virtual void transferCompleted(volatile uint32_t addr);
212
213 /**
214 * Virtual method called when a device has been connected
215 *
216 * @param hub hub number of the device
217 * @param port port number of the device
218 * @param lowSpeed 1 if low speed, 0 otherwise
219 * @param hub_parent reference on the parent hub
220 */
221 virtual void deviceConnected(int hub, int port, bool lowSpeed, USBHostHub * hub_parent = NULL);
222
223 /**
224 * Virtuel method called when a device has been disconnected
225 *
226 * @param hub hub number of the device
227 * @param port port number of the device
228 * @param addr list of the TDs which have been completed to dequeue freed TDs
229 */
230 virtual void deviceDisconnected(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr);
231
232
233 private:
234 // singleton class -> constructor is private
235 USBHost();
236 static USBHost * instHost;
237 uint16_t lenReportDescr;
238
239 // endpoints
240 void unqueueEndpoint(USBEndpoint * ep) ;
241 USBEndpoint endpoints[MAX_ENDPOINT];
242 USBEndpoint* volatile control;
243
244 USBEndpoint* volatile headControlEndpoint;
245 USBEndpoint* volatile headBulkEndpoint;
246 USBEndpoint* volatile headInterruptEndpoint;
247
248 USBEndpoint* volatile tailControlEndpoint;
249 USBEndpoint* volatile tailBulkEndpoint;
250 USBEndpoint* volatile tailInterruptEndpoint;
251
252 bool controlEndpointAllocated;
253
254 // devices connected
255 USBDeviceConnected devices[MAX_DEVICE_CONNECTED];
256 bool deviceInUse[MAX_DEVICE_CONNECTED];
257 bool deviceAttachedDriver[MAX_DEVICE_CONNECTED][MAX_INTF];
258 bool deviceReset[MAX_DEVICE_CONNECTED];
259 bool deviceInited[MAX_DEVICE_CONNECTED];
260
261 #if MAX_HUB_NB
262 USBHostHub hubs[MAX_HUB_NB];
263 bool hub_in_use[MAX_HUB_NB];
264 #endif
265
266 // to store a setup packet
267 uint8_t setupPacket[8];
268
269 typedef struct {
270 uint8_t event_id;
271 void * td_addr;
272 uint8_t hub;
273 uint8_t port;
274 uint8_t lowSpeed;
275 uint8_t td_state;
276 void * hub_parent;
277 } message_t;
278
279 Thread usbThread;
280 void usb_process();
281 static void usb_process_static(void const * arg);
282 Mail<message_t, 10> mail_usb_event;
283 Mutex usb_mutex;
284 Mutex td_mutex;
285
286 // buffer for conf descriptor
287 uint8_t data[415];
288
289 /**
290 * Add a transfer on the TD linked list associated to an ED
291 *
292 * @param ed the transfer is associated to this ed
293 * @param buf pointer on a buffer where will be read/write data to send or receive
294 * @param len transfer length
295 *
296 * @return status of the transfer
297 */
298 USB_TYPE addTransfer(USBEndpoint * ed, uint8_t * buf, uint32_t len) ;
299
300 /**
301 * Link the USBEndpoint to the linked list and attach an USBEndpoint this USBEndpoint to a device
302 *
303 * @param dev pointer on a USBDeviceConnected object
304 * @param ep pointer on the USBEndpoint which will be added
305 *
306 * return true if successful
307 */
308 bool addEndpoint(USBDeviceConnected * dev, uint8_t intf_nb, USBEndpoint * ep) ;
309
310 /**
311 * Create an USBEndpoint descriptor. Warning: the USBEndpoint is not linked.
312 *
313 * @param type USBEndpoint type (CONTROL_ENDPOINT, BULK_ENDPOINT, INTERRUPT_ENDPOINT)
314 * @param dir USBEndpoint direction (no meaning for CONTROL_ENDPOINT)
315 * @param size USBEndpoint max packet size
316 * @param addr USBEndpoint address
317 *
318 * @returns pointer on the USBEndpoint created
319 */
320 USBEndpoint * newEndpoint(ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint32_t size, uint8_t addr) ;
321
322 /**
323 * Request the device descriptor
324 *
325 * @param dev request the device descriptor on this device
326 * @param buf buffer to store the device descriptor
327 * @param max_len_buf maximum size of buf
328 * @param len_dev_descr pointer to store the length of the packet transferred
329 */
330 USB_TYPE getDeviceDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_dev_descr = NULL);
331
332 /**
333 * Request the configuration descriptor
334 *
335 * @param dev request the configuration descriptor on this device
336 * @param buf buffer to store the configuration descriptor
337 * @param max_len_buf maximum size of buf
338 * @param len_conf_descr pointer to store the length of the packet transferred
339 */
340 USB_TYPE getConfigurationDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_conf_descr = NULL);
341
342 /**
343 * Set the address of a specific device
344 *
345 * @param dev device to set the address
346 * @param address address
347 */
348 USB_TYPE setAddress(USBDeviceConnected * dev, uint8_t address);
349
350 /**
351 * Set the configuration of a device
352 *
353 * @param dev device on which the specified configuration will be activated
354 * @param conf configuration number to activate (usually 1)
355 */
356 USB_TYPE setConfiguration(USBDeviceConnected * dev, uint8_t conf);
357
358 /**
359 * Free a specific device
360 *
361 * @param dev device to be freed
362 */
363 void freeDevice(USBDeviceConnected * dev);
364
365 USB_TYPE controlTransfer( USBDeviceConnected * dev,
366 uint8_t requestType,
367 uint8_t request,
368 uint32_t value,
369 uint32_t index,
370 uint8_t * buf,
371 uint32_t len,
372 bool write);
373
374 USB_TYPE generalTransfer( USBDeviceConnected * dev,
375 USBEndpoint * ep,
376 uint8_t * buf,
377 uint32_t len,
378 bool blocking,
379 ENDPOINT_TYPE type,
380 bool write) ;
381
382 void fillControlBuf(uint8_t requestType, uint8_t request, uint16_t value, uint16_t index, int len) ;
383 void parseConfDescr(USBDeviceConnected * dev, uint8_t * conf_descr, uint32_t len, IUSBEnumerator* pEnumerator) ;
384 int findDevice(USBDeviceConnected * dev) ;
385 int findDevice(uint8_t hub, uint8_t port, USBHostHub * hub_parent = NULL) ;
386 uint8_t numberDriverAttached(USBDeviceConnected * dev);
387
388 /////////////////////////
389 /// FOR DEBUG
390 /////////////////////////
391 void printList(ENDPOINT_TYPE type);
392
393 };
394
395 #endif
Imprint / Impressum