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