]> git.donarmstrong.com Git - qmk_firmware.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/USBHost/USBHost/USBHost.h
allow overriding of TARGET
[qmk_firmware.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