USB Composite support

Dependents:   mbed_cdc_hid_composite

Fork of USBDevice by mbed official

Files at this revision

API Documentation at this revision

Comitter:
steeven
Date:
Sun May 31 15:36:50 2015 +0000
Parent:
54:461d954eee6b
Commit message:
Make USBDevice support Composite

Changed in this revision

USBDevice/USBComposite.cpp Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBComposite.h Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBDevice.cpp Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBDevice.h Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBHAL.h Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBHAL_LPC17.cpp Show annotated file Show diff for this revision Revisions of this file
USBDevice/USBInterface.h Show annotated file Show diff for this revision Revisions of this file
USBSerial/USBCDC.cpp Show annotated file Show diff for this revision Revisions of this file
USBSerial/USBCDC.h Show annotated file Show diff for this revision Revisions of this file
USBSerial/USBSerial.cpp Show annotated file Show diff for this revision Revisions of this file
USBSerial/USBSerial.h Show annotated file Show diff for this revision Revisions of this file
readme.txt Show annotated file Show diff for this revision Revisions of this file
diff -r 461d954eee6b -r 7c559fcb1d17 USBDevice/USBComposite.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBComposite.cpp	Sun May 31 15:36:50 2015 +0000
@@ -0,0 +1,214 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "stdint.h"
+#include "USBComposite.h"
+
+#define DEFAULT_CONFIGURATION (1)
+
+USBComposite::USBComposite(bool connect_blocking, uint16_t vendor_id, uint16_t product_id , uint16_t product_release):
+    USBDevice(vendor_id, product_id, product_release) {
+//    USBDevice::connect(connect_blocking);
+}
+
+bool USBComposite::USBCallback_request(void) {
+    /* Called in ISR context */
+    uint8_t i;
+
+    for (i = 0; i < sizeof(_intfs)/sizeof(_intfs[0]); ++i) {
+        if (_intfs[i] != NULL && _intfs[i]->USBCallback_request() == true) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+void USBComposite::USBCallback_requestCompleted(uint8_t *buf, uint32_t length) {
+    /* Called in ISR context */
+    uint8_t i;
+
+    for (i = 0; i < sizeof(_intfs)/sizeof(_intfs[0]); ++i) {
+        if (_intfs[i] != NULL) {
+            _intfs[i]->USBCallback_requestCompleted(buf, length);
+        }
+    }
+}
+
+// Called in ISR context
+// Set configuration. Return false if the
+// configuration is not supported.
+bool USBComposite::USBCallback_setConfiguration(uint8_t configuration) {
+    if (configuration != DEFAULT_CONFIGURATION) {
+        return false;
+    }
+
+//    // Configure endpoints > 0
+//    _usb->addEndpoint(_ep_int_in, MAX_PACKET_SIZE_EPINT);
+//    _usb->addEndpoint(_ep_bulk_in, MAX_PACKET_SIZE_EPBULK);
+//    _usb->addEndpoint(_ep_bulk_out, MAX_PACKET_SIZE_EPBULK);
+//
+//    // We activate the endpoint to be able to recceive data
+//    _usb->readStart(_ep_bulk_out, MAX_PACKET_SIZE_EPBULK);
+    return true;
+}
+
+uint8_t * USBComposite::deviceDesc() {
+    static uint8_t deviceDescriptor[] = {
+        18,                   // bLength
+        1,                    // bDescriptorType
+        0x10, 0x01,           // bcdUSB
+        2,                    // bDeviceClass
+        0,                    // bDeviceSubClass
+        0,                    // bDeviceProtocol
+        MAX_PACKET_SIZE_EP0,  // bMaxPacketSize0
+        (uint8_t)(LSB(VENDOR_ID)), (uint8_t)(MSB(VENDOR_ID)),  // idVendor
+        (uint8_t)(LSB(PRODUCT_ID)), (uint8_t)(MSB(PRODUCT_ID)),// idProduct
+        0x00, 0x01,           // bcdDevice
+        1,                    // iManufacturer
+        2,                    // iProduct
+        3,                    // iSerialNumber
+        1                     // bNumConfigurations
+    };
+    return deviceDescriptor;
+}
+
+uint8_t * USBComposite::stringIinterfaceDesc() {
+    static uint8_t stringIinterfaceDescriptor[] = {
+        0x08,
+        STRING_DESCRIPTOR,
+        'C',0,'D',0,'C',0,
+    };
+    return stringIinterfaceDescriptor;
+}
+
+uint8_t * USBComposite::stringIproductDesc() {
+    static uint8_t stringIproductDescriptor[] = {
+        0x16,
+        STRING_DESCRIPTOR,
+        'C',0,'D',0,'C',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0
+    };
+    return stringIproductDescriptor;
+}
+
+
+#define CONFIG1_DESC_SIZE (9+8+9+5+5+4+5+7+9+7+7)
+
+uint8_t * USBComposite::configurationDesc() {
+    static uint8_t configDescriptor[] = {
+        // configuration descriptor
+        9,                      // bLength
+        2,                      // bDescriptorType
+        LSB(CONFIG1_DESC_SIZE), // wTotalLength
+        MSB(CONFIG1_DESC_SIZE),
+        2,                      // bNumInterfaces
+        1,                      // bConfigurationValue
+        0,                      // iConfiguration
+        0x80,                   // bmAttributes
+        50,                     // bMaxPower
+
+        // IAD to associate the two CDC interfaces
+        0x08,                   // bLength
+        0x0b,                   // bDescriptorType
+        0x00,                   // bFirstInterface
+        0x02,                   // bInterfaceCount
+        0x02,                   // bFunctionClass
+        0x02,                   // bFunctionSubClass
+        0,                      // bFunctionProtocol
+        0,                      // iFunction
+
+        // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
+        9,                      // bLength
+        4,                      // bDescriptorType
+        0,                      // bInterfaceNumber
+        0,                      // bAlternateSetting
+        1,                      // bNumEndpoints
+        0x02,                   // bInterfaceClass
+        0x02,                   // bInterfaceSubClass
+        0x01,                   // bInterfaceProtocol
+        0,                      // iInterface
+
+        // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26
+        5,                      // bFunctionLength
+        0x24,                   // bDescriptorType
+        0x00,                   // bDescriptorSubtype
+        0x10, 0x01,             // bcdCDC
+
+        // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27
+        5,                      // bFunctionLength
+        0x24,                   // bDescriptorType
+        0x01,                   // bDescriptorSubtype
+        0x03,                   // bmCapabilities
+        1,                      // bDataInterface
+
+        // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28
+        4,                      // bFunctionLength
+        0x24,                   // bDescriptorType
+        0x02,                   // bDescriptorSubtype
+        0x06,                   // bmCapabilities
+
+        // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33
+        5,                      // bFunctionLength
+        0x24,                   // bDescriptorType
+        0x06,                   // bDescriptorSubtype
+        0,                      // bMasterInterface
+        1,                      // bSlaveInterface0
+
+        // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
+        ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
+        ENDPOINT_DESCRIPTOR,            // bDescriptorType
+//        PHY_TO_DESC(_ep_int_in),          // bEndpointAddress
+        E_INTERRUPT,                    // bmAttributes (0x03=intr)
+        LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
+        16,                             // bInterval
+
+
+
+
+        // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
+        9,                          // bLength
+        4,                          // bDescriptorType
+        1,                          // bInterfaceNumber
+        0,                          // bAlternateSetting
+        2,                          // bNumEndpoints
+        0x0A,                       // bInterfaceClass
+        0x00,                       // bInterfaceSubClass
+        0x00,                       // bInterfaceProtocol
+        0,                          // iInterface
+
+        // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
+        ENDPOINT_DESCRIPTOR_LENGTH, // bLength
+        ENDPOINT_DESCRIPTOR,        // bDescriptorType
+//        PHY_TO_DESC(_ep_bulk_in),     // bEndpointAddress
+        E_BULK,                     // bmAttributes (0x02=bulk)
+        LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
+        0,                          // bInterval
+
+        // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
+        ENDPOINT_DESCRIPTOR_LENGTH, // bLength
+        ENDPOINT_DESCRIPTOR,        // bDescriptorType
+//        PHY_TO_DESC(_ep_bulk_out),    // bEndpointAddress
+        E_BULK,                     // bmAttributes (0x02=bulk)
+        LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
+        0                           // bInterval
+    };
+    return configDescriptor;
+}
diff -r 461d954eee6b -r 7c559fcb1d17 USBDevice/USBComposite.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBComposite.h	Sun May 31 15:36:50 2015 +0000
@@ -0,0 +1,93 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef USBCOMPOSITE_H
+#define USBCOMPOSITE_H
+
+/* These headers are included for child class. */
+#include "USBEndpoints.h"
+#include "USBDescriptor.h"
+#include "USBDevice_Types.h"
+
+#include "USBDevice.h"
+
+class USBComposite: public USBDevice{
+public:
+
+    /*
+    * Constructor
+    *
+    * @param vendor_id Your vendor_id
+    * @param product_id Your product_id
+    * @param product_release Your preoduct_release
+    * @param connect_blocking define if the connection must be blocked if USB not plugged in
+    */
+    USBComposite(bool connect_blocking = true, uint16_t vendor_id = 0x1f00, uint16_t product_id = 0x2012, uint16_t product_release = 0x0001);
+
+    virtual bool bind(USBComposite *intf) {
+        uint8_t i;
+        for (i = 0; i < sizeof(_intfs)/sizeof(_intfs[0]); ++i) {
+            if (_intfs[i] == NULL){
+                _intfs[i] = intf;
+                return true;
+            }
+        }
+        return false;
+    }
+
+protected:
+
+    /*
+    * Get device descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
+    *
+    * @returns pointer to the device descriptor
+    */
+    virtual uint8_t * deviceDesc();
+
+    /*
+    * Get string product descriptor
+    *
+    * @returns pointer to the string product descriptor
+    */
+    virtual uint8_t * stringIproductDesc();
+
+    /*
+    * Get string interface descriptor
+    *
+    * @returns pointer to the string interface descriptor
+    */
+    virtual uint8_t * stringIinterfaceDesc();
+
+    /*
+    * Get configuration descriptor
+    *
+    * @returns pointer to the configuration descriptor
+    */
+    virtual uint8_t * configurationDesc();
+
+
+protected:
+    virtual bool USBCallback_request();
+    virtual void USBCallback_requestCompleted(uint8_t *buf, uint32_t length);
+    virtual bool USBCallback_setConfiguration(uint8_t configuration);
+    volatile bool terminal_connected;
+
+    USBComposite* _intfs[4];
+};
+
+#endif
diff -r 461d954eee6b -r 7c559fcb1d17 USBDevice/USBDevice.cpp
--- a/USBDevice/USBDevice.cpp	Fri May 22 08:45:47 2015 +0100
+++ b/USBDevice/USBDevice.cpp	Sun May 31 15:36:50 2015 +0000
@@ -987,6 +987,8 @@
 }
 
 uint8_t * USBDevice::stringIinterfaceDesc() {
+    if (_intf)
+        return _intf->stringIinterfaceDesc();
     static uint8_t stringIinterfaceDescriptor[] = {
         0x08,               /*bLength*/
         STRING_DESCRIPTOR,  /*bDescriptorType 0x03*/
@@ -996,6 +998,8 @@
 }
 
 uint8_t * USBDevice::stringIproductDesc() {
+    if (_intf)
+        return _intf->stringIproductDesc();
     static uint8_t stringIproductDescriptor[] = {
         0x16,                                                       /*bLength*/
         STRING_DESCRIPTOR,                                          /*bDescriptorType 0x03*/
diff -r 461d954eee6b -r 7c559fcb1d17 USBDevice/USBDevice.h
--- a/USBDevice/USBDevice.h	Fri May 22 08:45:47 2015 +0100
+++ b/USBDevice/USBDevice.h	Sun May 31 15:36:50 2015 +0000
@@ -22,11 +22,13 @@
 #include "mbed.h"
 #include "USBDevice_Types.h"
 #include "USBHAL.h"
+#include "USBInterface.h"
+
 
 class USBDevice: public USBHAL
 {
 public:
-    USBDevice(uint16_t vendor_id, uint16_t product_id, uint16_t product_release);
+    USBDevice(uint16_t vendor_id = 0x1f00, uint16_t product_id = 0x2012, uint16_t product_release = 0x0001);
 
     /*
     * Check if the device is configured
@@ -126,6 +128,7 @@
     */
     virtual void USBCallback_busReset(void) {};
 
+
     /*
     * Called by USBDevice on Endpoint0 request. Warning: Called in ISR context
     * This is used to handle extensions to standard requests
@@ -133,7 +136,12 @@
     *
     * @returns true if class handles this request
     */
-    virtual bool USBCallback_request() { return false; };
+    virtual bool USBCallback_request() {
+        if (_intf)
+            return _intf->USBCallback_request();
+        else
+            return false;
+    };
 
     /*
     * Called by USBDevice on Endpoint0 request completion
@@ -145,7 +153,10 @@
     * @param buf buffer received on endpoint 0
     * @param length length of this buffer
     */
-    virtual void USBCallback_requestCompleted(uint8_t * buf, uint32_t length) {};
+    virtual void USBCallback_requestCompleted(uint8_t * buf, uint32_t length) {
+        if (_intf)
+            _intf->USBCallback_requestCompleted(buf, length);
+    };
 
     /*
     * Called by USBDevice layer. Set configuration of the device.
@@ -153,7 +164,11 @@
     *
     * @param configuration Number of the configuration
     */
-    virtual bool USBCallback_setConfiguration(uint8_t configuration) { return false; };
+    virtual bool USBCallback_setConfiguration(uint8_t configuration) {
+        if (_intf)
+            return _intf->USBCallback_setConfiguration(configuration);
+        return false;
+    };
 
     /*
      * Called by USBDevice layer. Set interface/alternate of the device.
@@ -176,7 +191,11 @@
     *
     * @returns pointer to the configuration descriptor
     */
-    virtual uint8_t * configurationDesc(){return NULL;};
+    virtual uint8_t * configurationDesc(){
+        if (_intf)
+            return _intf->configurationDesc();
+        return NULL;
+    };
 
     /*
     * Get string lang id descriptor
@@ -227,7 +246,16 @@
     */
     virtual uint16_t reportDescLength() { return 0; };
 
+    CONTROL_TRANSFER * getTransferPtr(void);
 
+    virtual bool bind(USBInterface *intf) {
+        _intf = intf;
+        return true;
+    }
+
+    uint16_t VENDOR_ID;
+    uint16_t PRODUCT_ID;
+    uint16_t PRODUCT_RELEASE;
 
 protected:
     virtual void busReset(void);
@@ -237,11 +265,7 @@
     virtual void connectStateChanged(unsigned int connected);
     virtual void suspendStateChanged(unsigned int suspended);
     uint8_t * findDescriptor(uint8_t descriptorType);
-    CONTROL_TRANSFER * getTransferPtr(void);
 
-    uint16_t VENDOR_ID;
-    uint16_t PRODUCT_ID;
-    uint16_t PRODUCT_RELEASE;
 
 private:
     bool addRateFeedbackEndpoint(uint8_t endpoint, uint32_t maxPacket);
@@ -265,6 +289,8 @@
 
     uint16_t currentInterface;
     uint8_t currentAlternate;
+
+    USBInterface *_intf;
 };
 
 
diff -r 461d954eee6b -r 7c559fcb1d17 USBDevice/USBHAL.h
--- a/USBDevice/USBHAL.h	Fri May 22 08:45:47 2015 +0100
+++ b/USBDevice/USBHAL.h	Sun May 31 15:36:50 2015 +0000
@@ -108,14 +108,24 @@
     static void _usbisr(void);
     static USBHAL * instance;
 
+
 #if defined(TARGET_LPC11UXX) || defined(TARGET_LPC11U6X) || defined(TARGET_LPC1347) || defined(TARGET_LPC1549)
         bool (USBHAL::*epCallback[10 - 2])(void);
 #elif defined(TARGET_STM32F4)
         bool (USBHAL::*epCallback[8 - 2])(void);
 #else
-        bool (USBHAL::*epCallback[32 - 2])(void);
+        void *epCallbackObj[32 - 2];
+        bool (*epCallback[32 - 2])(void *);
 #endif
 
+public:
+    void set_ep_callback(uint8_t ep, void * obj, bool (*ptr)(void *)) {
+        if ((obj != NULL) && (ptr != NULL)) {
+            epCallback[ep] = ptr;
+            epCallbackObj[ep] = obj;
+        }
+    }
+
 
 };
 #endif
diff -r 461d954eee6b -r 7c559fcb1d17 USBDevice/USBHAL_LPC17.cpp
--- a/USBDevice/USBHAL_LPC17.cpp	Fri May 22 08:45:47 2015 +0100
+++ b/USBDevice/USBHAL_LPC17.cpp	Sun May 31 15:36:50 2015 +0000
@@ -329,6 +329,9 @@
     NVIC_DisableIRQ(USB_IRQn);
 
     // fill in callback array
+    memset(epCallback, 0, sizeof(epCallback) * sizeof(void *));
+    memset(epCallbackObj, 0, sizeof(epCallbackObj) * sizeof(void *));
+    /*
     epCallback[0] = &USBHAL::EP1_OUT_callback;
     epCallback[1] = &USBHAL::EP1_IN_callback;
     epCallback[2] = &USBHAL::EP2_OUT_callback;
@@ -359,6 +362,7 @@
     epCallback[27] = &USBHAL::EP14_IN_callback;
     epCallback[28] = &USBHAL::EP15_OUT_callback;
     epCallback[29] = &USBHAL::EP15_IN_callback;
+    */
 
     // Enable power to USB device controller
     LPC_SC->PCONP |= PCUSB;
@@ -612,8 +616,11 @@
                 selectEndpointClearInterrupt(num);
                 epComplete |= EP(num);
                 LPC_USB->USBDevIntClr = EP_SLOW;
-                if ((instance->*(epCallback[num - 2]))()) {
-                    epComplete &= ~EP(num);
+
+                if (instance->epCallback[num - 2] != NULL){
+                    if (instance->epCallback[num - 2](instance->epCallbackObj[num - 2])) {
+                        epComplete &= ~EP(num);
+                    }
                 }
             }
         }
diff -r 461d954eee6b -r 7c559fcb1d17 USBDevice/USBInterface.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/USBInterface.h	Sun May 31 15:36:50 2015 +0000
@@ -0,0 +1,84 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef USINTERFACE_H
+#define USINTERFACE_H
+
+#include "mbed.h"
+#include "USBDevice_Types.h"
+//#include "USBHAL.h"
+
+class USBInterface {
+public:
+    USBInterface(){}
+    virtual ~USBInterface(){};
+//  virtual int *endpoints();
+
+    /*
+    * Called by USBDevice on Endpoint0 request. Warning: Called in ISR context
+    * This is used to handle extensions to standard requests
+    * and class specific requests
+    *
+    * @returns true if class handles this request
+    */
+    virtual bool USBCallback_request() { return false; };
+
+    /*
+    * Called by USBDevice on Endpoint0 request completion
+    * if the 'notify' flag has been set to true. Warning: Called in ISR context
+    *
+    * In this case it is used to indicate that a HID report has
+    * been received from the host on endpoint 0
+    *
+    * @param buf buffer received on endpoint 0
+    * @param length length of this buffer
+    */
+    virtual void USBCallback_requestCompleted(uint8_t * buf, uint32_t length) {};
+
+    /*
+    * Get string interface descriptor
+    *
+    * @returns pointer to the string interface descriptor
+    */
+    virtual uint8_t * stringIinterfaceDesc() { return (uint8_t *)NULL; }
+
+    /*
+    * Get string product descriptor
+    *
+    * @returns pointer to the string product descriptor
+    */
+    virtual uint8_t * stringIproductDesc()  { return (uint8_t *)NULL; }
+
+    /*
+    * Get configuration descriptor
+    *
+    * @returns pointer to the configuration descriptor
+    */
+    virtual uint8_t * configurationDesc()  { return (uint8_t *)NULL; }
+
+    /*
+    * Called by USBDevice layer. Set configuration of the device.
+    * For instance, you can add all endpoints that you need on this function.
+    *
+    * @param configuration Number of the configuration
+    */
+    virtual bool USBCallback_setConfiguration(uint8_t configuration) { return false; };
+
+};
+
+#endif
diff -r 461d954eee6b -r 7c559fcb1d17 USBSerial/USBCDC.cpp
--- a/USBSerial/USBCDC.cpp	Fri May 22 08:45:47 2015 +0100
+++ b/USBSerial/USBCDC.cpp	Sun May 31 15:36:50 2015 +0000
@@ -33,16 +33,19 @@
 
 #define MAX_CDC_REPORT_SIZE MAX_PACKET_SIZE_EPBULK
 
-USBCDC::USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect_blocking): USBDevice(vendor_id, product_id, product_release) {
+USBCDC::USBCDC(USBDevice *usb, uint8_t ep_int_in, uint8_t ep_bulk_in, uint8_t ep_bulk_out, bool connect_blocking):
+        _usb(usb),
+        _ep_int_in(ep_int_in), _ep_bulk_in(ep_bulk_in), _ep_bulk_out(ep_bulk_out) {
     terminal_connected = false;
-    USBDevice::connect(connect_blocking);
+    _usb->bind(this);
+    _usb->connect(connect_blocking);
 }
 
 bool USBCDC::USBCallback_request(void) {
     /* Called in ISR context */
 
     bool success = false;
-    CONTROL_TRANSFER * transfer = getTransferPtr();
+    CONTROL_TRANSFER * transfer = _usb->getTransferPtr();
 
     /* Process class-specific requests */
 
@@ -81,7 +84,7 @@
         return;
     }
 
-    CONTROL_TRANSFER * transfer = getTransferPtr();
+    CONTROL_TRANSFER * transfer = _usb->getTransferPtr();
 
     /* Process class-specific requests */
     if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
@@ -110,31 +113,31 @@
     }
 
     // Configure endpoints > 0
-    addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
-    addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
-    addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+    _usb->addEndpoint(_ep_int_in, MAX_PACKET_SIZE_EPINT);
+    _usb->addEndpoint(_ep_bulk_in, MAX_PACKET_SIZE_EPBULK);
+    _usb->addEndpoint(_ep_bulk_out, MAX_PACKET_SIZE_EPBULK);
 
     // We activate the endpoint to be able to recceive data
-    readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+    _usb->readStart(_ep_bulk_out, MAX_PACKET_SIZE_EPBULK);
     return true;
 }
 
 bool USBCDC::send(uint8_t * buffer, uint32_t size) {
-    return USBDevice::write(EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE);
+    return _usb->write(_ep_bulk_in, buffer, size, MAX_CDC_REPORT_SIZE);
 }
 
 bool USBCDC::readEP(uint8_t * buffer, uint32_t * size) {
-    if (!USBDevice::readEP(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
+    if (!_usb->readEP(_ep_bulk_out, buffer, size, MAX_CDC_REPORT_SIZE))
         return false;
-    if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
+    if (!_usb->readStart(_ep_bulk_out, MAX_CDC_REPORT_SIZE))
         return false;
     return true;
 }
 
 bool USBCDC::readEP_NB(uint8_t * buffer, uint32_t * size) {
-    if (!USBDevice::readEP_NB(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
+    if (!_usb->readEP_NB(_ep_bulk_out, buffer, size, MAX_CDC_REPORT_SIZE))
         return false;
-    if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
+    if (!_usb->readStart(_ep_bulk_out, MAX_CDC_REPORT_SIZE))
         return false;
     return true;
 }
@@ -149,8 +152,8 @@
         0,                    // bDeviceSubClass
         0,                    // bDeviceProtocol
         MAX_PACKET_SIZE_EP0,  // bMaxPacketSize0
-        (uint8_t)(LSB(VENDOR_ID)), (uint8_t)(MSB(VENDOR_ID)),  // idVendor
-        (uint8_t)(LSB(PRODUCT_ID)), (uint8_t)(MSB(PRODUCT_ID)),// idProduct
+        (uint8_t)(LSB(_usb->VENDOR_ID)), (uint8_t)(MSB(_usb->VENDOR_ID)),  // idVendor
+        (uint8_t)(LSB(_usb->PRODUCT_ID)), (uint8_t)(MSB(_usb->PRODUCT_ID)),// idProduct
         0x00, 0x01,           // bcdDevice
         1,                    // iManufacturer
         2,                    // iProduct
@@ -244,7 +247,7 @@
         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
         ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
         ENDPOINT_DESCRIPTOR,            // bDescriptorType
-        PHY_TO_DESC(EPINT_IN),          // bEndpointAddress
+        PHY_TO_DESC(_ep_int_in),          // bEndpointAddress
         E_INTERRUPT,                    // bmAttributes (0x03=intr)
         LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
         MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
@@ -267,7 +270,7 @@
         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
         ENDPOINT_DESCRIPTOR_LENGTH, // bLength
         ENDPOINT_DESCRIPTOR,        // bDescriptorType
-        PHY_TO_DESC(EPBULK_IN),     // bEndpointAddress
+        PHY_TO_DESC(_ep_bulk_in),     // bEndpointAddress
         E_BULK,                     // bmAttributes (0x02=bulk)
         LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
         MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
@@ -276,7 +279,7 @@
         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
         ENDPOINT_DESCRIPTOR_LENGTH, // bLength
         ENDPOINT_DESCRIPTOR,        // bDescriptorType
-        PHY_TO_DESC(EPBULK_OUT),    // bEndpointAddress
+        PHY_TO_DESC(_ep_bulk_out),    // bEndpointAddress
         E_BULK,                     // bmAttributes (0x02=bulk)
         LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
         MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
diff -r 461d954eee6b -r 7c559fcb1d17 USBSerial/USBCDC.h
--- a/USBSerial/USBCDC.h	Fri May 22 08:45:47 2015 +0100
+++ b/USBSerial/USBCDC.h	Sun May 31 15:36:50 2015 +0000
@@ -26,7 +26,7 @@
 
 #include "USBDevice.h"
 
-class USBCDC: public USBDevice {
+class USBCDC: public USBInterface {
 public:
 
     /*
@@ -37,7 +37,7 @@
     * @param product_release Your preoduct_release
     * @param connect_blocking define if the connection must be blocked if USB not plugged in
     */
-    USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect_blocking);
+    USBCDC(USBDevice *usb, uint8_t ep_int_in, uint8_t ep_bulk_in, uint8_t ep_bulk_out, bool connect_blocking);
 
 protected:
 
@@ -118,6 +118,15 @@
     virtual bool USBCallback_setConfiguration(uint8_t configuration);
     volatile bool terminal_connected;
 
+    USBDevice *_usb;
+
+    uint8_t _ep_int_in; //EPINT_IN
+    uint8_t _ep_bulk_in; //EPBULK_IN
+    uint8_t _ep_bulk_out; //EPBULK_OUT
+
+
 };
 
+
+
 #endif
diff -r 461d954eee6b -r 7c559fcb1d17 USBSerial/USBSerial.cpp
--- a/USBSerial/USBSerial.cpp	Fri May 22 08:45:47 2015 +0100
+++ b/USBSerial/USBSerial.cpp	Sun May 31 15:36:50 2015 +0000
@@ -16,6 +16,7 @@
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
+
 #include "stdint.h"
 #include "USBSerial.h"
 
@@ -33,7 +34,6 @@
     return c;
 }
 
-
 bool USBSerial::writeBlock(uint8_t * buf, uint16_t size) {
     if(size > MAX_PACKET_SIZE_EPBULK) {
         return false;
@@ -46,18 +46,19 @@
 
 
 
-bool USBSerial::EPBULK_OUT_callback() {
+bool USBSerial::EP_OUT_callback(void *_self) {
+    USBSerial *self = (USBSerial *)_self;
     uint8_t c[65];
     uint32_t size = 0;
 
     //we read the packet received and put it on the circular buffer
-    readEP(c, &size);
+    self->readEP(c, &size);
     for (uint32_t i = 0; i < size; i++) {
-        buf.queue(c[i]);
+        self->buf.queue(c[i]);
     }
 
     //call a potential handler
-    rx.call();
+    self->rx.call();
 
     return true;
 }
diff -r 461d954eee6b -r 7c559fcb1d17 USBSerial/USBSerial.h
--- a/USBSerial/USBSerial.h	Fri May 22 08:45:47 2015 +0100
+++ b/USBSerial/USBSerial.h	Sun May 31 15:36:50 2015 +0000
@@ -56,8 +56,11 @@
     * @param connect_blocking define if the connection must be blocked if USB not plugged in
     *
     */
-    USBSerial(uint16_t vendor_id = 0x1f00, uint16_t product_id = 0x2012, uint16_t product_release = 0x0001, bool connect_blocking = true): USBCDC(vendor_id, product_id, product_release, connect_blocking){
+
+    USBSerial(USBDevice *usb = new USBDevice(), bool connect_blocking = true, uint8_t ep_int_in = EPINT_IN, uint8_t ep_bulk_in = EPBULK_IN, uint8_t ep_bulk_out = EPBULK_OUT):
+        USBCDC(usb, ep_int_in, ep_bulk_in, ep_bulk_out, connect_blocking) {
         settingsChangedCallback = 0;
+        usb->set_ep_callback(ep_bulk_out, this, &USBSerial::EP_OUT_callback);
     };
 
 
@@ -145,13 +148,15 @@
     }
 
 protected:
-    virtual bool EPBULK_OUT_callback();
+    static bool EP_OUT_callback(void *self);
+
     virtual void lineCodingChanged(int baud, int bits, int parity, int stop){
         if (settingsChangedCallback) {
             settingsChangedCallback(baud, bits, parity, stop);
         }
     }
 
+
 private:
     FunctionPointer rx;
     CircBuffer<uint8_t,128> buf;
diff -r 461d954eee6b -r 7c559fcb1d17 readme.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/readme.txt	Sun May 31 15:36:50 2015 +0000
@@ -0,0 +1,22 @@
+UsbDeviceComposite
+
+!!! only tested CDC on LPC1768
+TODO: 
+    0. need to associate max packet length with endpoint
+    1. Rework HID
+    2. test Composite
+    3. rework device...
+    4. rework all HAL drivers
+
+Why not direct extend to USBDevice?
+    USBDevice has to be shared to multiple interfaces of a composite device 
+Why not multi-extend?
+    Some time need to implement 2 CDC or HIDs, can't extend twoice
+
+Composite Sample:
+    UsbComposite usb;
+    USBHID hid(&usb);
+    USBSerial ser(&usb);
+
+Single interface Sample:
+    USBHID hid;