test public

Dependencies:   HttpServer_snapshot_mbed-os

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