Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
USBHost.h
00001 /* mbed USBHost Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef USBHOST_H 00018 #define USBHOST_H 00019 00020 #include "USBHALHost.h" 00021 #include "USBDeviceConnected.h" 00022 #include "IUSBEnumerator.h" 00023 #include "USBHostConf.h" 00024 #include "rtos.h" 00025 #include "dbg.h" 00026 #include "USBHostHub.h" 00027 00028 /** 00029 * USBHost class 00030 * This class is a singleton. All drivers have a reference on the static USBHost instance 00031 */ 00032 class USBHost : public USBHALHost { 00033 public: 00034 /** 00035 * Static method to create or retrieve the single USBHost instance 00036 */ 00037 static USBHost * getHostInst(); 00038 00039 /** 00040 * Control read: setup stage, data stage and status stage 00041 * 00042 * @param dev the control read will be done for this device 00043 * @param requestType request type 00044 * @param request request 00045 * @param value value 00046 * @param index index 00047 * @param buf pointer on a buffer where will be store the data received 00048 * @param len length of the transfer 00049 * 00050 * @returns status of the control read 00051 */ 00052 USB_TYPE controlRead(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len); 00053 00054 /** 00055 * Control write: setup stage, data stage and status stage 00056 * 00057 * @param dev the control write will be done for this device 00058 * @param requestType request type 00059 * @param request request 00060 * @param value value 00061 * @param index index 00062 * @param buf pointer on a buffer which will be written 00063 * @param len length of the transfer 00064 * 00065 * @returns status of the control write 00066 */ 00067 USB_TYPE controlWrite(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len); 00068 00069 /** 00070 * Bulk read 00071 * 00072 * @param dev the bulk transfer will be done for this device 00073 * @param ep USBEndpoint which will be used to read a packet 00074 * @param buf pointer on a buffer where will be store the data received 00075 * @param len length of the transfer 00076 * @param blocking if true, the read is blocking (wait for completion) 00077 * 00078 * @returns status of the bulk read 00079 */ 00080 USB_TYPE bulkRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true); 00081 00082 /** 00083 * Bulk write 00084 * 00085 * @param dev the bulk transfer will be done for this device 00086 * @param ep USBEndpoint which will be used to write a packet 00087 * @param buf pointer on a buffer which will be written 00088 * @param len length of the transfer 00089 * @param blocking if true, the write is blocking (wait for completion) 00090 * 00091 * @returns status of the bulk write 00092 */ 00093 USB_TYPE bulkWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true); 00094 00095 /** 00096 * Interrupt read 00097 * 00098 * @param dev the bulk transfer will be done for this device 00099 * @param ep USBEndpoint which will be used to write a packet 00100 * @param buf pointer on a buffer which will be written 00101 * @param len length of the transfer 00102 * @param blocking if true, the read is blocking (wait for completion) 00103 * 00104 * @returns status of the interrupt read 00105 */ 00106 USB_TYPE interruptRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true); 00107 00108 /** 00109 * Interrupt write 00110 * 00111 * @param dev the bulk transfer will be done for this device 00112 * @param ep USBEndpoint which will be used to write a packet 00113 * @param buf pointer on a buffer which will be written 00114 * @param len length of the transfer 00115 * @param blocking if true, the write is blocking (wait for completion) 00116 * 00117 * @returns status of the interrupt write 00118 */ 00119 USB_TYPE interruptWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true); 00120 00121 /** 00122 * Enumerate a device. 00123 * 00124 * @param dev device which will be enumerated 00125 * 00126 * @returns status of the enumeration 00127 */ 00128 USB_TYPE enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerator); 00129 00130 /** 00131 * reset a specific device 00132 * 00133 * @param dev device which will be resetted 00134 */ 00135 USB_TYPE resetDevice(USBDeviceConnected * dev); 00136 00137 /** 00138 * Get a device 00139 * 00140 * @param index index of the device which will be returned 00141 * 00142 * @returns pointer on the "index" device 00143 */ 00144 USBDeviceConnected * getDevice(uint8_t index); 00145 00146 /* 00147 * If there is a HID device connected, the host stores the length of the report descriptor. 00148 * This avoid to the driver to re-ask the configuration descriptor to request the report descriptor 00149 * 00150 * @returns length of the report descriptor 00151 */ 00152 inline uint16_t getLengthReportDescr() { 00153 return lenReportDescr; 00154 }; 00155 00156 /** 00157 * register a driver into the host associated with a callback function called when the device is disconnected 00158 * 00159 * @param dev device 00160 * @param intf interface number 00161 * @param tptr pointer to the object to call the member function on 00162 * @param mptr pointer to the member function to be called 00163 */ 00164 template<typename T> 00165 inline void registerDriver(USBDeviceConnected * dev, uint8_t intf, T* tptr, void (T::*mptr)(void)) { 00166 int index = findDevice(dev); 00167 if ((index != -1) && (mptr != NULL) && (tptr != NULL)) { 00168 USB_DBG("register driver for dev: %p on intf: %d", dev, intf); 00169 deviceAttachedDriver[index][intf] = true; 00170 dev->onDisconnect(intf, tptr, mptr); 00171 } 00172 } 00173 00174 /** 00175 * register a driver into the host associated with a callback function called when the device is disconnected 00176 * 00177 * @param dev device 00178 * @param intf interface number 00179 * @param fn callback called when the specified device has been disconnected 00180 */ 00181 inline void registerDriver(USBDeviceConnected * dev, uint8_t intf, void (*fn)(void)) { 00182 int index = findDevice(dev); 00183 if ((index != -1) && (fn != NULL)) { 00184 USB_DBG("register driver for dev: %p on intf: %d", dev, intf); 00185 deviceAttachedDriver[index][intf] = true; 00186 dev->onDisconnect(intf, fn); 00187 } 00188 } 00189 00190 /** 00191 * Instantiate to protect USB thread from accessing shared objects (USBConnectedDevices and Interfaces) 00192 */ 00193 class Lock 00194 { 00195 public: 00196 Lock(USBHost* pHost); 00197 ~Lock(); 00198 private: 00199 USBHost* m_pHost; 00200 }; 00201 00202 friend class USBHostHub; 00203 00204 protected: 00205 00206 /** 00207 * Virtual method called when a transfer has been completed 00208 * 00209 * @param addr list of the TDs which have been completed 00210 */ 00211 virtual void transferCompleted(volatile uint32_t addr); 00212 00213 /** 00214 * Virtual method called when a device has been connected 00215 * 00216 * @param hub hub number of the device 00217 * @param port port number of the device 00218 * @param lowSpeed 1 if low speed, 0 otherwise 00219 * @param hub_parent reference on the parent hub 00220 */ 00221 virtual void deviceConnected(int hub, int port, bool lowSpeed, USBHostHub * hub_parent = NULL); 00222 00223 /** 00224 * Virtuel method called when a device has been disconnected 00225 * 00226 * @param hub hub number of the device 00227 * @param port port number of the device 00228 * @param addr list of the TDs which have been completed to dequeue freed TDs 00229 */ 00230 virtual void deviceDisconnected(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr); 00231 00232 00233 private: 00234 // singleton class -> constructor is private 00235 USBHost(); 00236 static USBHost * instHost; 00237 uint16_t lenReportDescr; 00238 00239 // endpoints 00240 void unqueueEndpoint(USBEndpoint * ep) ; 00241 USBEndpoint endpoints[MAX_ENDPOINT]; 00242 USBEndpoint* volatile control; 00243 00244 USBEndpoint* volatile headControlEndpoint; 00245 USBEndpoint* volatile headBulkEndpoint; 00246 USBEndpoint* volatile headInterruptEndpoint; 00247 00248 USBEndpoint* volatile tailControlEndpoint; 00249 USBEndpoint* volatile tailBulkEndpoint; 00250 USBEndpoint* volatile tailInterruptEndpoint; 00251 00252 bool controlEndpointAllocated; 00253 00254 // devices connected 00255 USBDeviceConnected devices[MAX_DEVICE_CONNECTED]; 00256 bool deviceInUse[MAX_DEVICE_CONNECTED]; 00257 bool deviceAttachedDriver[MAX_DEVICE_CONNECTED][MAX_INTF]; 00258 bool deviceReset[MAX_DEVICE_CONNECTED]; 00259 bool deviceInited[MAX_DEVICE_CONNECTED]; 00260 00261 #if MAX_HUB_NB 00262 USBHostHub hubs[MAX_HUB_NB]; 00263 bool hub_in_use[MAX_HUB_NB]; 00264 #endif 00265 00266 // to store a setup packet 00267 uint8_t setupPacket[8]; 00268 00269 typedef struct { 00270 uint8_t event_id; 00271 void * td_addr; 00272 uint8_t hub; 00273 uint8_t port; 00274 uint8_t lowSpeed; 00275 uint8_t td_state; 00276 void * hub_parent; 00277 } message_t; 00278 00279 Thread usbThread; 00280 void usb_process(); 00281 Mail<message_t, 10> mail_usb_event; 00282 Mutex usb_mutex; 00283 Mutex td_mutex; 00284 00285 // buffer for conf descriptor 00286 uint8_t data[415]; 00287 00288 /** 00289 * Add a transfer on the TD linked list associated to an ED 00290 * 00291 * @param ed the transfer is associated to this ed 00292 * @param buf pointer on a buffer where will be read/write data to send or receive 00293 * @param len transfer length 00294 * 00295 * @return status of the transfer 00296 */ 00297 USB_TYPE addTransfer(USBEndpoint * ed, uint8_t * buf, uint32_t len) ; 00298 00299 /** 00300 * Link the USBEndpoint to the linked list and attach an USBEndpoint this USBEndpoint to a device 00301 * 00302 * @param dev pointer on a USBDeviceConnected object 00303 * @param ep pointer on the USBEndpoint which will be added 00304 * 00305 * return true if successful 00306 */ 00307 bool addEndpoint(USBDeviceConnected * dev, uint8_t intf_nb, USBEndpoint * ep) ; 00308 00309 /** 00310 * Create an USBEndpoint descriptor. Warning: the USBEndpoint is not linked. 00311 * 00312 * @param type USBEndpoint type (CONTROL_ENDPOINT, BULK_ENDPOINT, INTERRUPT_ENDPOINT) 00313 * @param dir USBEndpoint direction (no meaning for CONTROL_ENDPOINT) 00314 * @param size USBEndpoint max packet size 00315 * @param addr USBEndpoint address 00316 * 00317 * @returns pointer on the USBEndpoint created 00318 */ 00319 USBEndpoint * newEndpoint(ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint32_t size, uint8_t addr) ; 00320 00321 /** 00322 * Request the device descriptor 00323 * 00324 * @param dev request the device descriptor on this device 00325 * @param buf buffer to store the device descriptor 00326 * @param max_len_buf maximum size of buf 00327 * @param len_dev_descr pointer to store the length of the packet transferred 00328 */ 00329 USB_TYPE getDeviceDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_dev_descr = NULL); 00330 00331 /** 00332 * Request the configuration descriptor 00333 * 00334 * @param dev request the configuration descriptor on this device 00335 * @param buf buffer to store the configuration descriptor 00336 * @param max_len_buf maximum size of buf 00337 * @param len_conf_descr pointer to store the length of the packet transferred 00338 */ 00339 USB_TYPE getConfigurationDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_conf_descr = NULL); 00340 00341 /** 00342 * Set the address of a specific device 00343 * 00344 * @param dev device to set the address 00345 * @param address address 00346 */ 00347 USB_TYPE setAddress(USBDeviceConnected * dev, uint8_t address); 00348 00349 /** 00350 * Set the configuration of a device 00351 * 00352 * @param dev device on which the specified configuration will be activated 00353 * @param conf configuration number to activate (usually 1) 00354 */ 00355 USB_TYPE setConfiguration(USBDeviceConnected * dev, uint8_t conf); 00356 00357 /** 00358 * Free a specific device 00359 * 00360 * @param dev device to be freed 00361 */ 00362 void freeDevice(USBDeviceConnected * dev); 00363 00364 USB_TYPE controlTransfer( USBDeviceConnected * dev, 00365 uint8_t requestType, 00366 uint8_t request, 00367 uint32_t value, 00368 uint32_t index, 00369 uint8_t * buf, 00370 uint32_t len, 00371 bool write); 00372 00373 USB_TYPE generalTransfer( USBDeviceConnected * dev, 00374 USBEndpoint * ep, 00375 uint8_t * buf, 00376 uint32_t len, 00377 bool blocking, 00378 ENDPOINT_TYPE type, 00379 bool write) ; 00380 00381 void fillControlBuf(uint8_t requestType, uint8_t request, uint16_t value, uint16_t index, int len) ; 00382 void parseConfDescr(USBDeviceConnected * dev, uint8_t * conf_descr, uint32_t len, IUSBEnumerator* pEnumerator) ; 00383 int findDevice(USBDeviceConnected * dev) ; 00384 int findDevice(uint8_t hub, uint8_t port, USBHostHub * hub_parent = NULL) ; 00385 uint8_t numberDriverAttached(USBDeviceConnected * dev); 00386 00387 ///////////////////////// 00388 /// FOR DEBUG 00389 ///////////////////////// 00390 void printList(ENDPOINT_TYPE type); 00391 00392 }; 00393 00394 #endif
Generated on Tue Jul 12 2022 17:34:59 by
