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

Dependencies:   SWD USBDevice mbed BaseDAP

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBMSD2.cpp Source File

USBMSD2.cpp

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 #include "stdint.h"
00020 #include "USBMSD2.h"
00021 #include "USB_MSD.h"
00022 #include "USB_CDC.h"
00023 #include "USB_HID.h"
00024 #include "mydebug.h"
00025 
00026 #define DEFAULT_CONFIGURATION (1)
00027 
00028 USBMSD2::USBMSD2(uint16_t vendor_id, uint16_t product_id, uint16_t product_release) 
00029     : USBDevice(vendor_id, product_id, product_release)
00030 {
00031     _msd = new USB_MSD(this, this);
00032     _cdc = new USB_CDC(this);
00033     _hid = new USB_HID(this);
00034 }
00035 
00036 USBMSD2::~USBMSD2() {
00037     _msd->disconnect();
00038     USBDevice::disconnect();
00039 }
00040 
00041 void USBMSD2::putc(int c)
00042 {
00043     _cdc->putc(c);
00044 }
00045 
00046 int USBMSD2::getc()
00047 {
00048     return _cdc->getc();
00049 }
00050 
00051 int USBMSD2::readable()
00052 {
00053     return _cdc->readable();
00054 }
00055     
00056 int USBMSD2::writeable()
00057 {
00058     return _cdc->writeable();
00059 }
00060 
00061 bool USBMSD2::readNB(HID_REPORT* report)
00062 {
00063     return _hid->readNB(report);
00064 }
00065 
00066 bool USBMSD2::send(HID_REPORT* report)
00067 {
00068     return _hid->send(report);
00069 }
00070 
00071 bool USBMSD2::connect()
00072 {
00073     if (_msd->connect()) {
00074         USBDevice::connect();
00075         return true;
00076     }
00077     return false;
00078 }
00079 
00080 // Called in ISR context to process a class specific request
00081 bool USBMSD2::USBCallback_request(void) {
00082     CONTROL_TRANSFER* transfer = getTransferPtr();
00083     if (_msd->Request_callback(transfer)) {
00084         return true;
00085     }
00086     if (_cdc->Request_callback(transfer)) {
00087         return true;
00088     }
00089     // Find the HID descriptor, after the configuration descriptor
00090     uint8_t* hidDescriptor = findDescriptor(HID_DESCRIPTOR);
00091     if (_hid->Request_callback(transfer, hidDescriptor)) {
00092         return true;
00093     }
00094     return false;
00095 }
00096 
00097 /* virtual */ void USBMSD2::USBCallback_requestCompleted(uint8_t* buf, uint32_t length)
00098 {
00099     CONTROL_TRANSFER* transfer = getTransferPtr();
00100     if (_cdc->RequestCompleted_callback(transfer, buf, length)) {
00101         return;
00102     }    
00103 }
00104 
00105 // Called in ISR context
00106 // Set configuration. Return false if the
00107 // configuration is not supported.
00108 bool USBMSD2::USBCallback_setConfiguration(uint8_t configuration) {
00109     if (configuration != DEFAULT_CONFIGURATION) {
00110         return false;
00111     }
00112 
00113     // Configure endpoints > 0
00114     addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
00115     addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
00116     
00117     addEndpoint(CDC_EPINT_IN, MAX_PACKET_SIZE_EPINT);
00118     addEndpoint(CDC_EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
00119     addEndpoint(CDC_EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
00120 
00121     addEndpoint(HID_EPINT_IN, MAX_PACKET_SIZE_EPINT);
00122     addEndpoint(HID_EPINT_OUT, MAX_PACKET_SIZE_EPINT);
00123 
00124     //activate readings
00125     readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
00126 
00127     readStart(CDC_EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
00128 
00129     readStart(HID_EPINT_OUT, MAX_PACKET_SIZE_EPINT);
00130 
00131     return true;
00132 }
00133 
00134 /* virtual */ bool USBMSD2::EP2_OUT_callback() { return _msd->EPBULK_OUT_callback(); }
00135 /* virtual */ bool USBMSD2::EP2_IN_callback()  { return _msd->EPBULK_IN_callback();  }
00136 /* virtual */ bool USBMSD2::EP5_OUT_callback() { return _cdc->EPBULK_OUT_callback(); }
00137 
00138 uint8_t * USBMSD2::deviceDesc() {
00139     static uint8_t deviceDescriptor[] = {
00140         18,                   // bLength
00141         1,                    // bDescriptorType
00142         0x10, 0x01,           // bcdUSB
00143         2,                    // bDeviceClass
00144         0,                    // bDeviceSubClass
00145         0,                    // bDeviceProtocol
00146         MAX_PACKET_SIZE_EP0,  // bMaxPacketSize0
00147         (uint8_t)(LSB(VENDOR_ID)), (uint8_t)(MSB(VENDOR_ID)),  // idVendor
00148         (uint8_t)(LSB(PRODUCT_ID)), (uint8_t)(MSB(PRODUCT_ID)),// idProduct
00149         0x00, 0x01,           // bcdDevice
00150         1,                    // iManufacturer
00151         2,                    // iProduct
00152         3,                    // iSerialNumber
00153         1                     // bNumConfigurations
00154     };
00155     return deviceDescriptor;
00156 }
00157 
00158 uint8_t * USBMSD2::stringIinterfaceDesc() {
00159     static uint8_t stringIinterfaceDescriptor[] = {
00160         0x08,               //bLength
00161         STRING_DESCRIPTOR,  //bDescriptorType 0x03
00162         'H',0,'I',0,'D',0,  //bString iInterface - HID
00163     };
00164     return stringIinterfaceDescriptor;
00165 }
00166 
00167 uint8_t * USBMSD2::stringIproductDesc() {
00168     static uint8_t stringIproductDescriptor[] = {
00169         32,                                                       //bLength
00170         STRING_DESCRIPTOR,                                        //bDescriptorType 0x03
00171         '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
00172     };
00173     return stringIproductDescriptor;
00174 }
00175 
00176 uint8_t * USBMSD2::configurationDesc() {
00177     static uint8_t configDescriptor[] = {
00178         // Configuration 1
00179         9,      // bLength
00180         2,      // bDescriptorType
00181         LSB(122), // wTotalLength
00182         MSB(122),
00183         4,      // bNumInterfaces
00184         1,      // bConfigurationValue: 0x01 is used to select this configuration
00185         0x00,   // iConfiguration: no string to describe this configuration
00186         0x80,   // bmAttributes
00187         250,    // bMaxPower, device power consumption is 100 mA
00188 
00189         // Interface 0, Alternate Setting 0, MSC Class
00190         INTERFACE_DESCRIPTOR_LENGTH, // bLength
00191         INTERFACE_DESCRIPTOR,        // bDescriptorType
00192         0,      // bInterfaceNumber
00193         0,      // bAlternateSetting
00194         2,      // bNumEndpoints
00195         0x08,   // bInterfaceClass
00196         0x06,   // bInterfaceSubClass
00197         0x50,   // bInterfaceProtocol
00198         0x04,   // iInterface
00199 
00200         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
00201         ENDPOINT_DESCRIPTOR_LENGTH, // bLength
00202         ENDPOINT_DESCRIPTOR,        // bDescriptorType
00203         PHY_TO_DESC(EPBULK_IN),     // bEndpointAddress
00204         E_BULK,                     // bmAttributes (0x02=bulk)
00205         LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
00206         MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
00207         0,                          // bInterval
00208 
00209         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
00210         ENDPOINT_DESCRIPTOR_LENGTH, // bLength
00211         ENDPOINT_DESCRIPTOR,        // bDescriptorType
00212         PHY_TO_DESC(EPBULK_OUT),    // bEndpointAddress
00213         E_BULK,                     // bmAttributes (0x02=bulk)
00214         LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
00215         MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
00216         0,                          // bInterval
00217 
00218         // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
00219         INTERFACE_DESCRIPTOR_LENGTH, // bLength
00220         INTERFACE_DESCRIPTOR,        // bDescriptorType
00221         1,                      // bInterfaceNumber
00222         0,                      // bAlternateSetting
00223         1,                      // bNumEndpoints
00224         0x02,                   // bInterfaceClass
00225         0x02,                   // bInterfaceSubClass
00226         0x01,                   // bInterfaceProtocol
00227         0,                      // iInterface
00228 
00229         // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26
00230         5,                      // bFunctionLength
00231         0x24,                   // bDescriptorType
00232         0x00,                   // bDescriptorSubtype
00233         0x10, 0x01,             // bcdCDC
00234 
00235         // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27
00236         5,                      // bFunctionLength
00237         0x24,                   // bDescriptorType
00238         0x01,                   // bDescriptorSubtype
00239         0x03,                   // bmCapabilities
00240         2,                      // bDataInterface
00241 
00242         // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28
00243         4,                      // bFunctionLength
00244         0x24,                   // bDescriptorType
00245         0x02,                   // bDescriptorSubtype
00246         0x06,                   // bmCapabilities
00247 
00248         // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33
00249         5,                      // bFunctionLength
00250         0x24,                   // bDescriptorType
00251         0x06,                   // bDescriptorSubtype
00252         1,                      // bMasterInterface
00253         2,                      // bSlaveInterface0
00254 
00255         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
00256         ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
00257         ENDPOINT_DESCRIPTOR,            // bDescriptorType
00258         PHY_TO_DESC(CDC_EPINT_IN),      // bEndpointAddress
00259         E_INTERRUPT,                    // bmAttributes (0x03=intr)
00260         LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
00261         MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
00262         2,                              // bInterval
00263 
00264         // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
00265         INTERFACE_DESCRIPTOR_LENGTH, // bLength
00266         INTERFACE_DESCRIPTOR,        // bDescriptorType
00267         2,                          // bInterfaceNumber
00268         0,                          // bAlternateSetting
00269         2,                          // bNumEndpoints
00270         0x0A,                       // bInterfaceClass
00271         0x00,                       // bInterfaceSubClass
00272         0x00,                       // bInterfaceProtocol
00273         0,                          // iInterface
00274 
00275         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
00276         ENDPOINT_DESCRIPTOR_LENGTH, // bLength
00277         ENDPOINT_DESCRIPTOR,        // bDescriptorType
00278         PHY_TO_DESC(CDC_EPBULK_IN), // bEndpointAddress
00279         E_BULK,                     // bmAttributes (0x02=bulk)
00280         LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
00281         MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
00282         0,                          // bInterval
00283 
00284         // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
00285         ENDPOINT_DESCRIPTOR_LENGTH, // bLength
00286         ENDPOINT_DESCRIPTOR,        // bDescriptorType
00287         PHY_TO_DESC(CDC_EPBULK_OUT),// bEndpointAddress
00288         E_BULK,                     // bmAttributes (0x02=bulk)
00289         LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
00290         MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
00291         0,                          // bInterval
00292 
00293         INTERFACE_DESCRIPTOR_LENGTH,    // bLength
00294         INTERFACE_DESCRIPTOR,           // bDescriptorType
00295         3,                              // bInterfaceNumber
00296         0,                              // bAlternateSetting
00297         2,                              // bNumEndpoints
00298         HID_CLASS,                      // bInterfaceClass
00299         HID_SUBCLASS_NONE,              // bInterfaceSubClass
00300         HID_PROTOCOL_NONE,              // bInterfaceProtocol
00301         0,                              // iInterface
00302 
00303         HID_DESCRIPTOR_LENGTH,          // bLength
00304         HID_DESCRIPTOR,                 // bDescriptorType
00305         LSB(HID_VERSION_1_11),          // bcdHID (LSB)
00306         MSB(HID_VERSION_1_11),          // bcdHID (MSB)
00307         0x00,                           // bCountryCode
00308         1,                              // bNumDescriptors
00309         REPORT_DESCRIPTOR,              // bDescriptorType
00310         LSB(_hid->reportDescLength()),  // wDescriptorLength (LSB)
00311         MSB(_hid->reportDescLength()),  // wDescriptorLength (MSB)
00312 
00313         ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
00314         ENDPOINT_DESCRIPTOR,            // bDescriptorType
00315         PHY_TO_DESC(HID_EPINT_IN),      // bEndpointAddress
00316         E_INTERRUPT,                    // bmAttributes
00317         LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
00318         MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
00319         1,                              // bInterval (milliseconds)
00320 
00321         ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
00322         ENDPOINT_DESCRIPTOR,            // bDescriptorType
00323         PHY_TO_DESC(HID_EPINT_OUT),     // bEndpointAddress
00324         E_INTERRUPT,                    // bmAttributes
00325         LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
00326         MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
00327         1,                              // bInterval (milliseconds)
00328     };
00329     return configDescriptor;
00330 }