USB composite device example program, drag-and-drop flash writer.

Dependencies:   SWD USBDevice mbed BaseDAP

Revision:
1:ea8e179320d7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/USBMSD2/USBMSD2.cpp	Sat Sep 28 03:21:14 2013 +0000
@@ -0,0 +1,330 @@
+/* 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 "USBMSD2.h"
+#include "USB_MSD.h"
+#include "USB_CDC.h"
+#include "USB_HID.h"
+#include "mydebug.h"
+
+#define DEFAULT_CONFIGURATION (1)
+
+USBMSD2::USBMSD2(uint16_t vendor_id, uint16_t product_id, uint16_t product_release) 
+    : USBDevice(vendor_id, product_id, product_release)
+{
+    _msd = new USB_MSD(this, this);
+    _cdc = new USB_CDC(this);
+    _hid = new USB_HID(this);
+}
+
+USBMSD2::~USBMSD2() {
+    _msd->disconnect();
+    USBDevice::disconnect();
+}
+
+void USBMSD2::putc(int c)
+{
+    _cdc->putc(c);
+}
+
+int USBMSD2::getc()
+{
+    return _cdc->getc();
+}
+
+int USBMSD2::readable()
+{
+    return _cdc->readable();
+}
+    
+int USBMSD2::writeable()
+{
+    return _cdc->writeable();
+}
+
+bool USBMSD2::readNB(HID_REPORT* report)
+{
+    return _hid->readNB(report);
+}
+
+bool USBMSD2::send(HID_REPORT* report)
+{
+    return _hid->send(report);
+}
+
+bool USBMSD2::connect()
+{
+    if (_msd->connect()) {
+        USBDevice::connect();
+        return true;
+    }
+    return false;
+}
+
+// Called in ISR context to process a class specific request
+bool USBMSD2::USBCallback_request(void) {
+    CONTROL_TRANSFER* transfer = getTransferPtr();
+    if (_msd->Request_callback(transfer)) {
+        return true;
+    }
+    if (_cdc->Request_callback(transfer)) {
+        return true;
+    }
+    // Find the HID descriptor, after the configuration descriptor
+    uint8_t* hidDescriptor = findDescriptor(HID_DESCRIPTOR);
+    if (_hid->Request_callback(transfer, hidDescriptor)) {
+        return true;
+    }
+    return false;
+}
+
+/* virtual */ void USBMSD2::USBCallback_requestCompleted(uint8_t* buf, uint32_t length)
+{
+    CONTROL_TRANSFER* transfer = getTransferPtr();
+    if (_cdc->RequestCompleted_callback(transfer, buf, length)) {
+        return;
+    }    
+}
+
+// Called in ISR context
+// Set configuration. Return false if the
+// configuration is not supported.
+bool USBMSD2::USBCallback_setConfiguration(uint8_t configuration) {
+    if (configuration != DEFAULT_CONFIGURATION) {
+        return false;
+    }
+
+    // Configure endpoints > 0
+    addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
+    addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+    
+    addEndpoint(CDC_EPINT_IN, MAX_PACKET_SIZE_EPINT);
+    addEndpoint(CDC_EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
+    addEndpoint(CDC_EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+
+    addEndpoint(HID_EPINT_IN, MAX_PACKET_SIZE_EPINT);
+    addEndpoint(HID_EPINT_OUT, MAX_PACKET_SIZE_EPINT);
+
+    //activate readings
+    readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+
+    readStart(CDC_EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
+
+    readStart(HID_EPINT_OUT, MAX_PACKET_SIZE_EPINT);
+
+    return true;
+}
+
+/* virtual */ bool USBMSD2::EP2_OUT_callback() { return _msd->EPBULK_OUT_callback(); }
+/* virtual */ bool USBMSD2::EP2_IN_callback()  { return _msd->EPBULK_IN_callback();  }
+/* virtual */ bool USBMSD2::EP5_OUT_callback() { return _cdc->EPBULK_OUT_callback(); }
+
+uint8_t * USBMSD2::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 * USBMSD2::stringIinterfaceDesc() {
+    static uint8_t stringIinterfaceDescriptor[] = {
+        0x08,               //bLength
+        STRING_DESCRIPTOR,  //bDescriptorType 0x03
+        'H',0,'I',0,'D',0,  //bString iInterface - HID
+    };
+    return stringIinterfaceDescriptor;
+}
+
+uint8_t * USBMSD2::stringIproductDesc() {
+    static uint8_t stringIproductDescriptor[] = {
+        32,                                                       //bLength
+        STRING_DESCRIPTOR,                                        //bDescriptorType 0x03
+        'K',0,'L',0,'2',0,'5',0,'Z',0,' ',0,'C',0,'M',0,'S',0,'I',0,'S',0,'-',0,'D',0,'A',0,'P',0 // KL25Z CMSIS-DAP
+    };
+    return stringIproductDescriptor;
+}
+
+uint8_t * USBMSD2::configurationDesc() {
+    static uint8_t configDescriptor[] = {
+        // Configuration 1
+        9,      // bLength
+        2,      // bDescriptorType
+        LSB(122), // wTotalLength
+        MSB(122),
+        4,      // bNumInterfaces
+        1,      // bConfigurationValue: 0x01 is used to select this configuration
+        0x00,   // iConfiguration: no string to describe this configuration
+        0x80,   // bmAttributes
+        250,    // bMaxPower, device power consumption is 100 mA
+
+        // Interface 0, Alternate Setting 0, MSC Class
+        INTERFACE_DESCRIPTOR_LENGTH, // bLength
+        INTERFACE_DESCRIPTOR,        // bDescriptorType
+        0,      // bInterfaceNumber
+        0,      // bAlternateSetting
+        2,      // bNumEndpoints
+        0x08,   // bInterfaceClass
+        0x06,   // bInterfaceSubClass
+        0x50,   // bInterfaceProtocol
+        0x04,   // iInterface
+
+        // 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
+        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(EPBULK_OUT),    // bEndpointAddress
+        E_BULK,                     // bmAttributes (0x02=bulk)
+        LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
+        0,                          // bInterval
+
+        // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
+        INTERFACE_DESCRIPTOR_LENGTH, // bLength
+        INTERFACE_DESCRIPTOR,        // bDescriptorType
+        1,                      // 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
+        2,                      // 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
+        1,                      // bMasterInterface
+        2,                      // bSlaveInterface0
+
+        // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
+        ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
+        ENDPOINT_DESCRIPTOR,            // bDescriptorType
+        PHY_TO_DESC(CDC_EPINT_IN),      // bEndpointAddress
+        E_INTERRUPT,                    // bmAttributes (0x03=intr)
+        LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
+        2,                              // bInterval
+
+        // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
+        INTERFACE_DESCRIPTOR_LENGTH, // bLength
+        INTERFACE_DESCRIPTOR,        // bDescriptorType
+        2,                          // 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(CDC_EPBULK_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(CDC_EPBULK_OUT),// bEndpointAddress
+        E_BULK,                     // bmAttributes (0x02=bulk)
+        LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
+        0,                          // bInterval
+
+        INTERFACE_DESCRIPTOR_LENGTH,    // bLength
+        INTERFACE_DESCRIPTOR,           // bDescriptorType
+        3,                              // bInterfaceNumber
+        0,                              // bAlternateSetting
+        2,                              // bNumEndpoints
+        HID_CLASS,                      // bInterfaceClass
+        HID_SUBCLASS_NONE,              // bInterfaceSubClass
+        HID_PROTOCOL_NONE,              // bInterfaceProtocol
+        0,                              // iInterface
+
+        HID_DESCRIPTOR_LENGTH,          // bLength
+        HID_DESCRIPTOR,                 // bDescriptorType
+        LSB(HID_VERSION_1_11),          // bcdHID (LSB)
+        MSB(HID_VERSION_1_11),          // bcdHID (MSB)
+        0x00,                           // bCountryCode
+        1,                              // bNumDescriptors
+        REPORT_DESCRIPTOR,              // bDescriptorType
+        LSB(_hid->reportDescLength()),  // wDescriptorLength (LSB)
+        MSB(_hid->reportDescLength()),  // wDescriptorLength (MSB)
+
+        ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
+        ENDPOINT_DESCRIPTOR,            // bDescriptorType
+        PHY_TO_DESC(HID_EPINT_IN),      // bEndpointAddress
+        E_INTERRUPT,                    // bmAttributes
+        LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
+        1,                              // bInterval (milliseconds)
+
+        ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
+        ENDPOINT_DESCRIPTOR,            // bDescriptorType
+        PHY_TO_DESC(HID_EPINT_OUT),     // bEndpointAddress
+        E_INTERRUPT,                    // bmAttributes
+        LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
+        MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
+        1,                              // bInterval (milliseconds)
+    };
+    return configDescriptor;
+}