Nicholas Herriot / VodafoneK3770Lib
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBHost.h Source File

USBHost.h

00001 /* Copyright (c) 2010-2011 mbed.org, MIT License
00002 *
00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00004 * and associated documentation files (the "Software"), to deal in the Software without
00005 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
00006 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
00007 * Software is furnished to do so, subject to the following conditions:
00008 *
00009 * The above copyright notice and this permission notice shall be included in all copies or
00010 * substantial portions of the Software.
00011 *
00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00017 */
00018 
00019 #ifndef USBHOST_H
00020 #define USBHOST_H
00021 
00022 #include "USBHALHost.h"
00023 #include "USBDeviceConnected.h"
00024 #include "Endpoint.h"
00025 
00026 #define MAX_DEVICE_NB 1
00027 
00028 // singleton class
00029 class USBHost : public USBHALHost {
00030 public:
00031     /*
00032     * Static method to create or retrieve the single USBHost instance
00033     */
00034     static USBHost * getHostInst();
00035     
00036     USB_TYPE getDeviceDescriptor(USBDeviceConnected * dev, uint8_t * buf) ;
00037     USB_TYPE getConfigurationDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint8_t * len_conf_descr = NULL) ;
00038     USB_TYPE setConfiguration(USBDeviceConnected * dev, uint8_t conf) ;
00039     USB_TYPE getStringDescriptor(USBDeviceConnected * dev, uint8_t index, uint8_t * buf) ;
00040     USB_TYPE getReportDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint8_t len) ;
00041 
00042     /*
00043     * Control read: setup stage, data stage and status stage
00044     *
00045     * @param dev the control read will be done for this device
00046     * @param requestType request type
00047     * @param request request
00048     * @param value value
00049     * @param index index
00050     * @param buf pointer on a buffer where will be store the data received
00051     * @param len length of the transfer
00052     *
00053     * @returns status of the control read
00054     */
00055     USB_TYPE controlRead(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len) ;
00056 
00057     /*
00058     * Control write: setup stage, data stage and status stage
00059     *
00060     * @param dev the control write will be done for this device
00061     * @param requestType request type
00062     * @param request request
00063     * @param value value
00064     * @param index index
00065     * @param buf pointer on a buffer which will be written
00066     * @param len length of the transfer
00067     *
00068     * @returns status of the control write
00069     */
00070     USB_TYPE controlWrite(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len) ;
00071 
00072 
00073     /*
00074     * Bulk read
00075     *
00076     * @param dev the bulk transfer will be done for this device
00077     * @param ep endpoint which will be used to read a packet
00078     * @param buf pointer on a buffer where will be store the data received
00079     * @param len length of the transfer
00080     * @param blocking if true, the read is blocking (wait for completion)
00081     *
00082     * @returns status of the bulk read
00083     */
00084     USB_TYPE bulkRead(USBDeviceConnected * dev, Endpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true) ;
00085 
00086     /*
00087     * Bulk write
00088     *
00089     * @param dev the bulk transfer will be done for this device
00090     * @param ep endpoint which will be used to write a packet
00091     * @param buf pointer on a buffer which will be written
00092     * @param len length of the transfer
00093     * @param blocking if true, the write is blocking (wait for completion)
00094     *
00095     * @returns status of the bulk write
00096     */
00097     USB_TYPE bulkWrite(USBDeviceConnected * dev, Endpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true) ;
00098 
00099     /*
00100     * Interrupt read
00101     *
00102     * @param dev the bulk transfer will be done for this device
00103     * @param ep endpoint which will be used to write a packet
00104     * @param buf pointer on a buffer which will be written
00105     * @param len length of the transfer
00106     * @param blocking if true, the read is blocking (wait for completion)
00107     *
00108     * @returns status of the interrupt read
00109     */
00110     USB_TYPE interruptRead(USBDeviceConnected * dev, Endpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true) ;
00111 
00112     /*
00113     * Interrupt write
00114     *
00115     * @param dev the bulk transfer will be done for this device
00116     * @param ep endpoint which will be used to write a packet
00117     * @param buf pointer on a buffer which will be written
00118     * @param len length of the transfer
00119     * @param blocking if true, the write is blocking (wait for completion)
00120     *
00121     * @returns status of the interrupt write
00122     */
00123     USB_TYPE interruptWrite(USBDeviceConnected * dev, Endpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true) ;
00124 
00125     /*
00126     * Enumerate a device. This method is responsible for:
00127     *   - set the address of the device
00128     *   - fill a USBDeviceConnected object:
00129     *       - add interfaces, endpoints, ...
00130     *   - set a configuration
00131     *
00132     * @param dev device which will be enumerated
00133     *
00134     * @returns status of the enumeration
00135     */
00136     USB_TYPE enumerate(USBDeviceConnected * dev) ;
00137 
00138     /*
00139     * Get a device
00140     *
00141     * @param index index of the device which will be returned
00142     *
00143     * @returns pointer on the "index" device
00144     */
00145     USBDeviceConnected * getDevice(uint8_t index) ;
00146 
00147     /*
00148     * reset port and hub of a specific device
00149     *
00150     * @param pointer on the device hich will be reseted
00151     */
00152     void resetDevice(USBDeviceConnected * dev) ;
00153 
00154     /*
00155     * If there is a HID device connected, the host stores the length of the report descriptor.
00156     * This avoid to the driver to re-ask the configuration descriptor to request the report descriptor
00157     *
00158     * @returns length of the report descriptor
00159     */
00160     uint16_t getLengthReportDescr()  {
00161         return lenReportDescr;
00162     };
00163 
00164     /**
00165      *  register a driver into the host associated with a callback function called when the device is disconnected
00166      *
00167      *  @param dev device
00168      *  @param tptr pointer to the object to call the member function on
00169      *  @param mptr pointer to the member function to be called
00170      */
00171     template<typename T>
00172     void registerDriver(USBDeviceConnected * dev, uint8_t intf, T* tptr, void (T::*mptr)(void))  {
00173         int index = findDevice(dev);
00174         if ((index != -1) && (mptr != NULL) && (tptr != NULL)) {
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 fn callback called when the specified device has been disconnected
00184      */
00185     void registerDriver(USBDeviceConnected * dev, uint8_t intf, void (*fn)(void))  {
00186         int index = findDevice(dev);
00187         if ((index != -1) && (fn != NULL)) {
00188             dev->onDisconnect(intf, fn);
00189         }
00190     }
00191 
00192 
00193 protected:
00194 
00195     /*
00196     * Virtual method called when a device has been connected
00197     *
00198     * @param hub hub number of the device
00199     * @param port port number of the device
00200     * @param lowSpeed 1 if low speed, 0 otherwise
00201     */
00202     virtual void deviceConnected(int hub, int port, bool lowSpeed) ;
00203 
00204     /*
00205     * Virtuel method called when a device has been disconnected
00206     *
00207     * @param hub hub number of the device
00208     * @param port port number of the device
00209     * @param addr list of the TDs which have been completed to dequeue freed TDs
00210     */
00211     virtual void deviceDisconnected(int hub, int port, volatile uint32_t addr) ;
00212 
00213     /*
00214     * Virtual method called when a transfer has been completed
00215     *
00216     * @param addr list of the TDs which have been completed
00217     */
00218     virtual void transferCompleted(volatile uint32_t addr) ;
00219 
00220 
00221 private:
00222     // singleton class -> constructor is private
00223     USBHost();
00224 
00225     static USBHost * instHost;
00226 
00227     uint8_t  nb_devices;
00228     uint16_t  lenReportDescr;
00229 
00230     void fillControlBuf(uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, int len) ;
00231     void parseConfDescr(USBDeviceConnected * dev, uint8_t * conf_descr, uint32_t len) ;
00232     void freeDevice(USBDeviceConnected * dev) ;
00233     int findDevice(USBDeviceConnected * dev) ;
00234 
00235 
00236     // endpoints
00237     void unqueueEndpoint(Endpoint * ep) ;
00238     Endpoint  endpoints[MAX_ENDPOINT];
00239     Endpoint* volatile  control;
00240 
00241     Endpoint* volatile  headControlEndpoint;
00242     Endpoint* volatile  headBulkEndpoint;
00243     Endpoint* volatile  headInterruptEndpoint;
00244 
00245     Endpoint* volatile  tailControlEndpoint;
00246     Endpoint* volatile  tailBulkEndpoint;
00247     Endpoint* volatile  tailInterruptEndpoint;
00248 
00249     bool controlEndpointAllocated;
00250 
00251 
00252     // devices connected
00253     USBDeviceConnected  devices[MAX_DEVICE_NB];
00254     volatile bool  deviceInUse[MAX_DEVICE_NB];
00255     volatile bool  deviceReset[MAX_DEVICE_NB];
00256     
00257     /*
00258     * Add a transfer on the TD linked list associated to an ED
00259     *
00260     * @param ed the transfer is associated to this ed
00261     * @param buf pointer on a buffer where will be read/write data to send or receive
00262     * @param len transfer length
00263     *
00264     * @return status of the transfer
00265     */
00266     USB_TYPE addTransfer(Endpoint * ed, uint8_t * buf, uint32_t len) ;
00267     
00268     /*
00269     * Link the endpoint to the linked list and attach an endpoint this endpoint to a device
00270     *
00271     * @param dev pointer on a USBDeviceConnected object
00272     * @param ep pointer on the Endpoint which will be added
00273     *
00274     * return true if successful
00275     */
00276     bool addEndpoint(USBDeviceConnected * dev, uint8_t intf_nb, Endpoint * ep) ;
00277 
00278     /*
00279     * Create an endpoint descriptor. Warning: the endpoint is not linked.
00280     *
00281     * @param type endpoint type (CONTROL_ENDPOINT, BULK_ENDPOINT, INTERRUPT_ENDPOINT)
00282     * @param dir endpoint direction (no meaning for CONTROL_ENDPOINT)
00283     * @param size endpoint max packet size
00284     * @param addr endpoint address
00285     *
00286     * @returns pointer on the Endpoint created
00287     */
00288     Endpoint * newEndpoint(ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint32_t size, uint8_t addr) ;
00289 
00290 
00291     // to store a setup packet
00292     uint8_t  setupPacket[8];
00293 
00294 
00295     /////////////////////////
00296     /// FOR DEBUG
00297     /////////////////////////
00298     void printBulk();
00299     void printInt();
00300 
00301 };
00302 
00303 #endif