USB composite device example program, drag-and-drop flash writer.
Dependencies: SWD USBDevice mbed BaseDAP
Diff: tests/USBMSD2/USBMSD2.cpp
- Revision:
- 1:ea8e179320d7
diff -r 2385683c867a -r ea8e179320d7 tests/USBMSD2/USBMSD2.cpp --- /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; +}