Emulation of LocalFileSystem with virtual COM.

Dependencies:   USBDevice

Dependents:   KL46Z-lpc81isp lpcterm2

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