Support Isochronous transfer additionally

Dependents:   USBHostC270_example_GR-PEACH USBHostDac_example USBHostDac_Audio_in_out

Fork of USBHost_custom by Renesas

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 
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 #if(1) /* Isochronous */
00131     inline uint8_t * getConfDescrCurPtr() {
00132         return &data[indexCnfdDescr];
00133     };
00134 
00135     inline uint16_t getConfDescrRestLen() {
00136         return lenCnfdDescr - indexCnfdDescr;
00137     };
00138 #endif
00139 
00140     /**
00141     * reset a specific device
00142     *
00143     * @param dev device which will be resetted
00144     */
00145     USB_TYPE resetDevice(USBDeviceConnected * dev);
00146 
00147     /**
00148     * Get a device
00149     *
00150     * @param index index of the device which will be returned
00151     *
00152     * @returns pointer on the "index" device
00153     */
00154     USBDeviceConnected * getDevice(uint8_t index);
00155 
00156     /*
00157     * If there is a HID device connected, the host stores the length of the report descriptor.
00158     * This avoid to the driver to re-ask the configuration descriptor to request the report descriptor
00159     *
00160     * @returns length of the report descriptor
00161     */
00162     inline uint16_t getLengthReportDescr() {
00163         return lenReportDescr;
00164     };
00165 
00166     /**
00167      *  register a driver into the host associated with a callback function called when the device is disconnected
00168      *
00169      *  @param dev device
00170      *  @param intf interface number
00171      *  @param tptr pointer to the object to call the member function on
00172      *  @param mptr pointer to the member function to be called
00173      */
00174     template<typename T>
00175     inline void registerDriver(USBDeviceConnected * dev, uint8_t intf, T* tptr, void (T::*mptr)(void)) {
00176         int index = findDevice(dev);
00177         if ((index != -1) && (mptr != NULL) && (tptr != NULL)) {
00178             USB_DBG("register driver for dev: %p on intf: %d", dev, intf);
00179             deviceAttachedDriver[index][intf] = true;
00180             dev->onDisconnect(intf, tptr, mptr);
00181         }
00182     }
00183 
00184     /**
00185      * register a driver into the host associated with a callback function called when the device is disconnected
00186      *
00187      * @param dev device
00188      * @param intf interface number
00189      * @param fn callback called when the specified device has been disconnected
00190      */
00191     inline void registerDriver(USBDeviceConnected * dev, uint8_t intf, void (*fn)(void)) {
00192         int index = findDevice(dev);
00193         if ((index != -1) && (fn != NULL)) {
00194             USB_DBG("register driver for dev: %p on intf: %d", dev, intf);
00195             deviceAttachedDriver[index][intf] = true;
00196             dev->onDisconnect(intf, fn);
00197         }
00198     }
00199 
00200     /**
00201      * Instantiate to protect USB thread from accessing shared objects (USBConnectedDevices and Interfaces)
00202      */
00203     class Lock
00204     {
00205     public:
00206       Lock(USBHost* pHost);
00207       ~Lock();
00208     private:
00209       USBHost* m_pHost;
00210     };
00211 
00212     friend class USBHostHub;
00213 
00214 protected:
00215 
00216     /**
00217     * Virtual method called when a transfer has been completed
00218     *
00219     * @param addr list of the TDs which have been completed
00220     */
00221     virtual void transferCompleted(volatile uint32_t addr);
00222 
00223     /**
00224     * Virtual method called when a device has been connected
00225     *
00226     * @param hub hub number of the device
00227     * @param port port number of the device
00228     * @param lowSpeed 1 if low speed, 0 otherwise
00229     * @param hub_parent reference on the parent hub
00230     */
00231     virtual void deviceConnected(int hub, int port, bool lowSpeed, USBHostHub * hub_parent = NULL);
00232 
00233     /**
00234     * Virtuel method called when a device has been disconnected
00235     *
00236     * @param hub hub number of the device
00237     * @param port port number of the device
00238     * @param addr list of the TDs which have been completed to dequeue freed TDs
00239     */
00240     virtual void deviceDisconnected(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr);
00241 
00242 
00243 private:
00244     // singleton class -> constructor is private
00245     USBHost();
00246     static USBHost * instHost;
00247     uint16_t  lenReportDescr;
00248 #if(1) /* Isochronous */
00249     uint16_t  lenCnfdDescr;
00250     uint16_t  indexCnfdDescr;
00251 #endif
00252 
00253     // endpoints
00254     void unqueueEndpoint(USBEndpoint * ep) ;
00255     USBEndpoint  endpoints[MAX_ENDPOINT];
00256     USBEndpoint* volatile  control;
00257 
00258     USBEndpoint* volatile  headControlEndpoint;
00259     USBEndpoint* volatile  headBulkEndpoint;
00260     USBEndpoint* volatile  headInterruptEndpoint;
00261 
00262     USBEndpoint* volatile  tailControlEndpoint;
00263     USBEndpoint* volatile  tailBulkEndpoint;
00264     USBEndpoint* volatile  tailInterruptEndpoint;
00265 
00266     bool controlEndpointAllocated;
00267 
00268     // devices connected
00269     USBDeviceConnected devices[MAX_DEVICE_CONNECTED];
00270     bool  deviceInUse[MAX_DEVICE_CONNECTED];
00271     bool  deviceAttachedDriver[MAX_DEVICE_CONNECTED][MAX_INTF];
00272     bool  deviceReset[MAX_DEVICE_CONNECTED];
00273     bool  deviceInited[MAX_DEVICE_CONNECTED];
00274 
00275 #if MAX_HUB_NB
00276     USBHostHub hubs[MAX_HUB_NB];
00277     bool hub_in_use[MAX_HUB_NB];
00278 #endif
00279 
00280     // to store a setup packet
00281     uint8_t  setupPacket[8];
00282 
00283     typedef struct {
00284         uint8_t event_id;
00285         void * td_addr;
00286         uint8_t hub;
00287         uint8_t port;
00288         uint8_t lowSpeed;
00289         uint8_t td_state;
00290         void * hub_parent;
00291     } message_t;
00292 
00293     Thread usbThread;
00294     void usb_process();
00295     static void usb_process_static(void const * arg);
00296     Mail<message_t, 10> mail_usb_event;
00297     Mutex usb_mutex;
00298     Mutex td_mutex;
00299 
00300     // buffer for conf descriptor
00301 #if(1) /* Isochronous */
00302     uint8_t data[1024];
00303 #else
00304     uint8_t data[415];
00305 #endif
00306 
00307     /**
00308     * Add a transfer on the TD linked list associated to an ED
00309     *
00310     * @param ed the transfer is associated to this ed
00311     * @param buf pointer on a buffer where will be read/write data to send or receive
00312     * @param len transfer length
00313     *
00314     * @return status of the transfer
00315     */
00316     USB_TYPE addTransfer(USBEndpoint * ed, uint8_t * buf, uint32_t len) ;
00317 
00318     /**
00319     * Link the USBEndpoint to the linked list and attach an USBEndpoint this USBEndpoint to a device
00320     *
00321     * @param dev pointer on a USBDeviceConnected object
00322     * @param ep pointer on the USBEndpoint which will be added
00323     *
00324     * return true if successful
00325     */
00326     bool addEndpoint(USBDeviceConnected * dev, uint8_t intf_nb, USBEndpoint * ep) ;
00327 
00328     /**
00329     * Create an USBEndpoint descriptor. Warning: the USBEndpoint is not linked.
00330     *
00331     * @param type USBEndpoint type (CONTROL_ENDPOINT, BULK_ENDPOINT, INTERRUPT_ENDPOINT)
00332     * @param dir USBEndpoint direction (no meaning for CONTROL_ENDPOINT)
00333     * @param size USBEndpoint max packet size
00334     * @param addr USBEndpoint address
00335     *
00336     * @returns pointer on the USBEndpoint created
00337     */
00338     USBEndpoint * newEndpoint(ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint32_t size, uint8_t addr) ;
00339 
00340     /**
00341     * Request the device descriptor
00342     *
00343     * @param dev request the device descriptor on this device
00344     * @param buf buffer to store the device descriptor
00345     * @param max_len_buf maximum size of buf
00346     * @param len_dev_descr pointer to store the length of the packet transferred
00347     */
00348     USB_TYPE getDeviceDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_dev_descr = NULL);
00349 
00350     /**
00351     * Request the configuration descriptor
00352     *
00353     * @param dev request the configuration descriptor on this device
00354     * @param buf buffer to store the configuration descriptor
00355     * @param max_len_buf maximum size of buf
00356     * @param len_conf_descr pointer to store the length of the packet transferred
00357     */
00358     USB_TYPE getConfigurationDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_conf_descr = NULL);
00359 
00360     /**
00361     * Set the address of a specific device
00362     *
00363     * @param dev device to set the address
00364     * @param address address
00365     */
00366     USB_TYPE setAddress(USBDeviceConnected * dev, uint8_t address);
00367 
00368     /**
00369     * Set the configuration of a device
00370     *
00371     * @param dev device on which the specified configuration will be activated
00372     * @param conf configuration number to activate (usually 1)
00373     */
00374     USB_TYPE setConfiguration(USBDeviceConnected * dev, uint8_t conf);
00375 
00376     /**
00377     * Free a specific device
00378     *
00379     * @param dev device to be freed
00380     */
00381     void freeDevice(USBDeviceConnected * dev);
00382 
00383     USB_TYPE controlTransfer(   USBDeviceConnected * dev,
00384                                 uint8_t requestType,
00385                                 uint8_t request,
00386                                 uint32_t value,
00387                                 uint32_t index,
00388                                 uint8_t * buf,
00389                                 uint32_t len,
00390                                 bool write);
00391 
00392     USB_TYPE generalTransfer(   USBDeviceConnected * dev,
00393                                 USBEndpoint * ep,
00394                                 uint8_t * buf,
00395                                 uint32_t len,
00396                                 bool blocking,
00397                                 ENDPOINT_TYPE type,
00398                                 bool write) ;
00399 
00400     void fillControlBuf(uint8_t requestType, uint8_t request, uint16_t value, uint16_t index, int len) ;
00401     void parseConfDescr(USBDeviceConnected * dev, uint8_t * conf_descr, uint32_t len, IUSBEnumerator* pEnumerator) ;
00402     int findDevice(USBDeviceConnected * dev) ;
00403     int findDevice(uint8_t hub, uint8_t port, USBHostHub * hub_parent = NULL) ;
00404     uint8_t numberDriverAttached(USBDeviceConnected * dev);
00405 
00406     /////////////////////////
00407     /// FOR DEBUG
00408     /////////////////////////
00409     void printList(ENDPOINT_TYPE type);
00410 
00411 };
00412 
00413 #endif