USBHost library. NOTE: This library is only officially supported on the LPC1768 platform. For more information, please see the handbook page.

Dependencies:   FATFileSystem mbed-rtos

Dependents:   BTstack WallbotWii SD to Flash Data Transfer USBHost-MSD_HelloWorld ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBHost.h Source File

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