1 /* mbed USBHost Library
2 * Copyright (c) 2006-2013 ARM Limited
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include "USBHALHost.h"
21 #include "USBDeviceConnected.h"
22 #include "IUSBEnumerator.h"
23 #include "USBHostConf.h"
26 #include "USBHostHub.h"
30 * This class is a singleton. All drivers have a reference on the static USBHost instance
32 class USBHost
: public USBHALHost
{
35 * Static method to create or retrieve the single USBHost instance
37 static USBHost
* getHostInst();
40 * Control read: setup stage, data stage and status stage
42 * @param dev the control read will be done for this device
43 * @param requestType request type
44 * @param request request
47 * @param buf pointer on a buffer where will be store the data received
48 * @param len length of the transfer
50 * @returns status of the control read
52 USB_TYPE
controlRead(USBDeviceConnected
* dev
, uint8_t requestType
, uint8_t request
, uint32_t value
, uint32_t index
, uint8_t * buf
, uint32_t len
);
55 * Control write: setup stage, data stage and status stage
57 * @param dev the control write will be done for this device
58 * @param requestType request type
59 * @param request request
62 * @param buf pointer on a buffer which will be written
63 * @param len length of the transfer
65 * @returns status of the control write
67 USB_TYPE
controlWrite(USBDeviceConnected
* dev
, uint8_t requestType
, uint8_t request
, uint32_t value
, uint32_t index
, uint8_t * buf
, uint32_t len
);
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)
78 * @returns status of the bulk read
80 USB_TYPE
bulkRead(USBDeviceConnected
* dev
, USBEndpoint
* ep
, uint8_t * buf
, uint32_t len
, bool blocking
= true);
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)
91 * @returns status of the bulk write
93 USB_TYPE
bulkWrite(USBDeviceConnected
* dev
, USBEndpoint
* ep
, uint8_t * buf
, uint32_t len
, bool blocking
= true);
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)
104 * @returns status of the interrupt read
106 USB_TYPE
interruptRead(USBDeviceConnected
* dev
, USBEndpoint
* ep
, uint8_t * buf
, uint32_t len
, bool blocking
= true);
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)
117 * @returns status of the interrupt write
119 USB_TYPE
interruptWrite(USBDeviceConnected
* dev
, USBEndpoint
* ep
, uint8_t * buf
, uint32_t len
, bool blocking
= true);
122 * Enumerate a device.
124 * @param dev device which will be enumerated
126 * @returns status of the enumeration
128 USB_TYPE
enumerate(USBDeviceConnected
* dev
, IUSBEnumerator
* pEnumerator
);
131 * reset a specific device
133 * @param dev device which will be resetted
135 USB_TYPE
resetDevice(USBDeviceConnected
* dev
);
140 * @param index index of the device which will be returned
142 * @returns pointer on the "index" device
144 USBDeviceConnected
* getDevice(uint8_t index
);
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
150 * @returns length of the report descriptor
152 inline uint16_t getLengthReportDescr() {
153 return lenReportDescr
;
157 * register a driver into the host associated with a callback function called when the device is disconnected
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
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
);
175 * register a driver into the host associated with a callback function called when the device is disconnected
178 * @param intf interface number
179 * @param fn callback called when the specified device has been disconnected
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
);
191 * Instantiate to protect USB thread from accessing shared objects (USBConnectedDevices and Interfaces)
196 Lock(USBHost
* pHost
);
202 friend class USBHostHub
;
207 * Virtual method called when a transfer has been completed
209 * @param addr list of the TDs which have been completed
211 virtual void transferCompleted(volatile uint32_t addr
);
214 * Virtual method called when a device has been connected
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
221 virtual void deviceConnected(int hub
, int port
, bool lowSpeed
, USBHostHub
* hub_parent
= NULL
);
224 * Virtuel method called when a device has been disconnected
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
230 virtual void deviceDisconnected(int hub
, int port
, USBHostHub
* hub_parent
, volatile uint32_t addr
);
234 // singleton class -> constructor is private
236 static USBHost
* instHost
;
237 uint16_t lenReportDescr
;
240 void unqueueEndpoint(USBEndpoint
* ep
) ;
241 USBEndpoint endpoints
[MAX_ENDPOINT
];
242 USBEndpoint
* volatile control
;
244 USBEndpoint
* volatile headControlEndpoint
;
245 USBEndpoint
* volatile headBulkEndpoint
;
246 USBEndpoint
* volatile headInterruptEndpoint
;
248 USBEndpoint
* volatile tailControlEndpoint
;
249 USBEndpoint
* volatile tailBulkEndpoint
;
250 USBEndpoint
* volatile tailInterruptEndpoint
;
252 bool controlEndpointAllocated
;
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
];
262 USBHostHub hubs
[MAX_HUB_NB
];
263 bool hub_in_use
[MAX_HUB_NB
];
266 // to store a setup packet
267 uint8_t setupPacket
[8];
281 static void usb_process_static(void const * arg
);
282 Mail
<message_t
, 10> mail_usb_event
;
286 // buffer for conf descriptor
290 * Add a transfer on the TD linked list associated to an ED
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
296 * @return status of the transfer
298 USB_TYPE
addTransfer(USBEndpoint
* ed
, uint8_t * buf
, uint32_t len
) ;
301 * Link the USBEndpoint to the linked list and attach an USBEndpoint this USBEndpoint to a device
303 * @param dev pointer on a USBDeviceConnected object
304 * @param ep pointer on the USBEndpoint which will be added
306 * return true if successful
308 bool addEndpoint(USBDeviceConnected
* dev
, uint8_t intf_nb
, USBEndpoint
* ep
) ;
311 * Create an USBEndpoint descriptor. Warning: the USBEndpoint is not linked.
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
318 * @returns pointer on the USBEndpoint created
320 USBEndpoint
* newEndpoint(ENDPOINT_TYPE type
, ENDPOINT_DIRECTION dir
, uint32_t size
, uint8_t addr
) ;
323 * Request the device descriptor
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
330 USB_TYPE
getDeviceDescriptor(USBDeviceConnected
* dev
, uint8_t * buf
, uint16_t max_len_buf
, uint16_t * len_dev_descr
= NULL
);
333 * Request the configuration descriptor
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
340 USB_TYPE
getConfigurationDescriptor(USBDeviceConnected
* dev
, uint8_t * buf
, uint16_t max_len_buf
, uint16_t * len_conf_descr
= NULL
);
343 * Set the address of a specific device
345 * @param dev device to set the address
346 * @param address address
348 USB_TYPE
setAddress(USBDeviceConnected
* dev
, uint8_t address
);
351 * Set the configuration of a device
353 * @param dev device on which the specified configuration will be activated
354 * @param conf configuration number to activate (usually 1)
356 USB_TYPE
setConfiguration(USBDeviceConnected
* dev
, uint8_t conf
);
359 * Free a specific device
361 * @param dev device to be freed
363 void freeDevice(USBDeviceConnected
* dev
);
365 USB_TYPE
controlTransfer( USBDeviceConnected
* dev
,
374 USB_TYPE
generalTransfer( USBDeviceConnected
* dev
,
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
);
388 /////////////////////////
390 /////////////////////////
391 void printList(ENDPOINT_TYPE type
);