USB CDC (serial) and USB MSC (strage) Composite Device. http://mbed.org/users/okini3939/notebook/USB_Device/

Dependencies:   ChaNFSSD mbed ChaNFS

Committer:
okini3939
Date:
Fri Dec 23 16:37:58 2011 +0000
Revision:
2:5db90410bb90
Parent:
0:9b1d17d54055

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okini3939 0:9b1d17d54055 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
okini3939 0:9b1d17d54055 2 *
okini3939 0:9b1d17d54055 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
okini3939 0:9b1d17d54055 4 * and associated documentation files (the "Software"), to deal in the Software without
okini3939 0:9b1d17d54055 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
okini3939 0:9b1d17d54055 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
okini3939 0:9b1d17d54055 7 * Software is furnished to do so, subject to the following conditions:
okini3939 0:9b1d17d54055 8 *
okini3939 0:9b1d17d54055 9 * The above copyright notice and this permission notice shall be included in all copies or
okini3939 0:9b1d17d54055 10 * substantial portions of the Software.
okini3939 0:9b1d17d54055 11 *
okini3939 0:9b1d17d54055 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
okini3939 0:9b1d17d54055 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
okini3939 0:9b1d17d54055 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
okini3939 0:9b1d17d54055 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
okini3939 0:9b1d17d54055 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
okini3939 0:9b1d17d54055 17 */
okini3939 0:9b1d17d54055 18
okini3939 0:9b1d17d54055 19 #include "stdint.h"
okini3939 0:9b1d17d54055 20 #include "USBCDC.h"
okini3939 0:9b1d17d54055 21 #include "USBBusInterface.h"
okini3939 0:9b1d17d54055 22
okini3939 0:9b1d17d54055 23 static uint8_t cdc_line_coding[7]= {0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08};
okini3939 0:9b1d17d54055 24
okini3939 0:9b1d17d54055 25 #define DEFAULT_CONFIGURATION (1)
okini3939 0:9b1d17d54055 26
okini3939 0:9b1d17d54055 27 #define CDC_SET_LINE_CODING 0x20
okini3939 0:9b1d17d54055 28 #define CDC_GET_LINE_CODING 0x21
okini3939 0:9b1d17d54055 29 #define CDC_SET_CONTROL_LINE_STATE 0x22
okini3939 0:9b1d17d54055 30
okini3939 0:9b1d17d54055 31 #define MAX_CDC_REPORT_SIZE MAX_PACKET_SIZE_EPBULK
okini3939 0:9b1d17d54055 32
okini3939 0:9b1d17d54055 33 USBCDC::USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) {
okini3939 0:9b1d17d54055 34 USBDevice::connect();
okini3939 0:9b1d17d54055 35 }
okini3939 0:9b1d17d54055 36
okini3939 0:9b1d17d54055 37 bool USBCDC::USBCallback_request(void) {
okini3939 0:9b1d17d54055 38 /* Called in ISR context */
okini3939 0:9b1d17d54055 39
okini3939 0:9b1d17d54055 40 bool success = false;
okini3939 0:9b1d17d54055 41 CONTROL_TRANSFER * transfer = getTransferPtr();
okini3939 0:9b1d17d54055 42
okini3939 0:9b1d17d54055 43 /* Process class-specific requests */
okini3939 0:9b1d17d54055 44
okini3939 0:9b1d17d54055 45 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
okini3939 0:9b1d17d54055 46 switch (transfer->setup.bRequest) {
okini3939 0:9b1d17d54055 47 case CDC_GET_LINE_CODING:
okini3939 0:9b1d17d54055 48 transfer->remaining = 7;
okini3939 0:9b1d17d54055 49 transfer->ptr = cdc_line_coding;
okini3939 0:9b1d17d54055 50 transfer->direction = DEVICE_TO_HOST;
okini3939 0:9b1d17d54055 51 success = true;
okini3939 0:9b1d17d54055 52 break;
okini3939 0:9b1d17d54055 53 case CDC_SET_LINE_CODING:
okini3939 0:9b1d17d54055 54 transfer->remaining = 7;
okini3939 0:9b1d17d54055 55 success = true;
okini3939 0:9b1d17d54055 56 break;
okini3939 0:9b1d17d54055 57 case CDC_SET_CONTROL_LINE_STATE:
okini3939 0:9b1d17d54055 58 success = true;
okini3939 0:9b1d17d54055 59 break;
okini3939 0:9b1d17d54055 60 default:
okini3939 0:9b1d17d54055 61 break;
okini3939 0:9b1d17d54055 62 }
okini3939 0:9b1d17d54055 63 }
okini3939 0:9b1d17d54055 64
okini3939 0:9b1d17d54055 65 return success;
okini3939 0:9b1d17d54055 66 }
okini3939 0:9b1d17d54055 67
okini3939 0:9b1d17d54055 68
okini3939 0:9b1d17d54055 69 // Called in ISR context
okini3939 0:9b1d17d54055 70 // Set configuration. Return false if the
okini3939 0:9b1d17d54055 71 // configuration is not supported.
okini3939 0:9b1d17d54055 72 bool USBCDC::USBCallback_setConfiguration(uint8_t configuration) {
okini3939 0:9b1d17d54055 73 if (configuration != DEFAULT_CONFIGURATION) {
okini3939 0:9b1d17d54055 74 return false;
okini3939 0:9b1d17d54055 75 }
okini3939 0:9b1d17d54055 76
okini3939 0:9b1d17d54055 77 // Configure endpoints > 0
okini3939 0:9b1d17d54055 78 addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
okini3939 0:9b1d17d54055 79 addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
okini3939 0:9b1d17d54055 80 addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
okini3939 0:9b1d17d54055 81
okini3939 0:9b1d17d54055 82 // We activate the endpoint to be able to recceive data
okini3939 0:9b1d17d54055 83 readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
okini3939 0:9b1d17d54055 84 return true;
okini3939 0:9b1d17d54055 85 }
okini3939 0:9b1d17d54055 86
okini3939 0:9b1d17d54055 87 bool USBCDC::send(uint8_t * buffer, uint16_t size) {
okini3939 0:9b1d17d54055 88 return USBDevice::write(EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE);
okini3939 0:9b1d17d54055 89 }
okini3939 0:9b1d17d54055 90
okini3939 0:9b1d17d54055 91 bool USBCDC::readEP(uint8_t * buffer, uint16_t * size) {
okini3939 0:9b1d17d54055 92 if (!USBDevice::readEP(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
okini3939 0:9b1d17d54055 93 return false;
okini3939 0:9b1d17d54055 94 if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
okini3939 0:9b1d17d54055 95 return false;
okini3939 0:9b1d17d54055 96 return true;
okini3939 0:9b1d17d54055 97 }
okini3939 0:9b1d17d54055 98
okini3939 0:9b1d17d54055 99 bool USBCDC::readEP_NB(uint8_t * buffer, uint16_t * size) {
okini3939 0:9b1d17d54055 100 if (!USBDevice::readEP_NB(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
okini3939 0:9b1d17d54055 101 return false;
okini3939 0:9b1d17d54055 102 if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
okini3939 0:9b1d17d54055 103 return false;
okini3939 0:9b1d17d54055 104 return true;
okini3939 0:9b1d17d54055 105 }
okini3939 0:9b1d17d54055 106
okini3939 0:9b1d17d54055 107
okini3939 0:9b1d17d54055 108 uint8_t * USBCDC::deviceDesc() {
okini3939 0:9b1d17d54055 109 static uint8_t deviceDescriptor[] = {
okini3939 0:9b1d17d54055 110 18, // bLength
okini3939 0:9b1d17d54055 111 1, // bDescriptorType
okini3939 0:9b1d17d54055 112 0x10, 0x01, // bcdUSB
okini3939 0:9b1d17d54055 113 2, // bDeviceClass
okini3939 0:9b1d17d54055 114 0, // bDeviceSubClass
okini3939 0:9b1d17d54055 115 0, // bDeviceProtocol
okini3939 0:9b1d17d54055 116 MAX_PACKET_SIZE_EP0, // bMaxPacketSize0
okini3939 0:9b1d17d54055 117 LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor
okini3939 0:9b1d17d54055 118 LSB(PRODUCT_ID), MSB(PRODUCT_ID),// idProduct
okini3939 0:9b1d17d54055 119 0x00, 0x01, // bcdDevice
okini3939 0:9b1d17d54055 120 1, // iManufacturer
okini3939 0:9b1d17d54055 121 2, // iProduct
okini3939 0:9b1d17d54055 122 3, // iSerialNumber
okini3939 0:9b1d17d54055 123 1 // bNumConfigurations
okini3939 0:9b1d17d54055 124 };
okini3939 0:9b1d17d54055 125 return deviceDescriptor;
okini3939 0:9b1d17d54055 126 }
okini3939 0:9b1d17d54055 127
okini3939 0:9b1d17d54055 128 uint8_t * USBCDC::stringIinterfaceDesc() {
okini3939 0:9b1d17d54055 129 static uint8_t stringIinterfaceDescriptor[] = {
okini3939 0:9b1d17d54055 130 0x08,
okini3939 0:9b1d17d54055 131 STRING_DESCRIPTOR,
okini3939 0:9b1d17d54055 132 'C',0,'D',0,'C',0,
okini3939 0:9b1d17d54055 133 };
okini3939 0:9b1d17d54055 134 return stringIinterfaceDescriptor;
okini3939 0:9b1d17d54055 135 }
okini3939 0:9b1d17d54055 136
okini3939 0:9b1d17d54055 137 uint8_t * USBCDC::stringIproductDesc() {
okini3939 0:9b1d17d54055 138 static uint8_t stringIproductDescriptor[] = {
okini3939 0:9b1d17d54055 139 0x16,
okini3939 0:9b1d17d54055 140 STRING_DESCRIPTOR,
okini3939 0:9b1d17d54055 141 'C',0,'D',0,'C',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0
okini3939 0:9b1d17d54055 142 };
okini3939 0:9b1d17d54055 143 return stringIproductDescriptor;
okini3939 0:9b1d17d54055 144 }
okini3939 0:9b1d17d54055 145
okini3939 0:9b1d17d54055 146
okini3939 0:9b1d17d54055 147 #define CONFIG1_DESC_SIZE (9+9+5+5+4+5+7+9+7+7)
okini3939 0:9b1d17d54055 148
okini3939 0:9b1d17d54055 149 uint8_t * USBCDC::configurationDesc() {
okini3939 0:9b1d17d54055 150 static uint8_t configDescriptor[] = {
okini3939 0:9b1d17d54055 151 9, // bLength;
okini3939 0:9b1d17d54055 152 2, // bDescriptorType;
okini3939 0:9b1d17d54055 153 LSB(CONFIG1_DESC_SIZE), // wTotalLength
okini3939 0:9b1d17d54055 154 MSB(CONFIG1_DESC_SIZE),
okini3939 0:9b1d17d54055 155 2, // bNumInterfaces
okini3939 0:9b1d17d54055 156 1, // bConfigurationValue
okini3939 0:9b1d17d54055 157 0, // iConfiguration
okini3939 0:9b1d17d54055 158 0x80, // bmAttributes
okini3939 0:9b1d17d54055 159 50, // bMaxPower
okini3939 0:9b1d17d54055 160
okini3939 0:9b1d17d54055 161 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
okini3939 0:9b1d17d54055 162 9, // bLength
okini3939 0:9b1d17d54055 163 4, // bDescriptorType
okini3939 0:9b1d17d54055 164 0, // bInterfaceNumber
okini3939 0:9b1d17d54055 165 0, // bAlternateSetting
okini3939 0:9b1d17d54055 166 1, // bNumEndpoints
okini3939 0:9b1d17d54055 167 0x02, // bInterfaceClass
okini3939 0:9b1d17d54055 168 0x02, // bInterfaceSubClass
okini3939 0:9b1d17d54055 169 0x01, // bInterfaceProtocol
okini3939 0:9b1d17d54055 170 0, // iInterface
okini3939 0:9b1d17d54055 171
okini3939 0:9b1d17d54055 172 // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26
okini3939 0:9b1d17d54055 173 5, // bFunctionLength
okini3939 0:9b1d17d54055 174 0x24, // bDescriptorType
okini3939 0:9b1d17d54055 175 0x00, // bDescriptorSubtype
okini3939 0:9b1d17d54055 176 0x10, 0x01, // bcdCDC
okini3939 0:9b1d17d54055 177
okini3939 0:9b1d17d54055 178 // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27
okini3939 0:9b1d17d54055 179 5, // bFunctionLength
okini3939 0:9b1d17d54055 180 0x24, // bDescriptorType
okini3939 0:9b1d17d54055 181 0x01, // bDescriptorSubtype
okini3939 0:9b1d17d54055 182 0x03, // bmCapabilities
okini3939 0:9b1d17d54055 183 1, // bDataInterface
okini3939 0:9b1d17d54055 184
okini3939 0:9b1d17d54055 185 // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28
okini3939 0:9b1d17d54055 186 4, // bFunctionLength
okini3939 0:9b1d17d54055 187 0x24, // bDescriptorType
okini3939 0:9b1d17d54055 188 0x02, // bDescriptorSubtype
okini3939 0:9b1d17d54055 189 0x06, // bmCapabilities
okini3939 0:9b1d17d54055 190
okini3939 0:9b1d17d54055 191 // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33
okini3939 0:9b1d17d54055 192 5, // bFunctionLength
okini3939 0:9b1d17d54055 193 0x24, // bDescriptorType
okini3939 0:9b1d17d54055 194 0x06, // bDescriptorSubtype
okini3939 0:9b1d17d54055 195 0, // bMasterInterface
okini3939 0:9b1d17d54055 196 1, // bSlaveInterface0
okini3939 0:9b1d17d54055 197
okini3939 0:9b1d17d54055 198 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
okini3939 0:9b1d17d54055 199 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
okini3939 0:9b1d17d54055 200 ENDPOINT_DESCRIPTOR, // bDescriptorType
okini3939 0:9b1d17d54055 201 PHY_TO_DESC(EPINT_IN), // bEndpointAddress
okini3939 0:9b1d17d54055 202 E_INTERRUPT, // bmAttributes (0x03=intr)
okini3939 0:9b1d17d54055 203 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
okini3939 0:9b1d17d54055 204 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
okini3939 0:9b1d17d54055 205 16, // bInterval
okini3939 0:9b1d17d54055 206
okini3939 0:9b1d17d54055 207
okini3939 0:9b1d17d54055 208
okini3939 0:9b1d17d54055 209
okini3939 0:9b1d17d54055 210 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
okini3939 0:9b1d17d54055 211 9, // bLength
okini3939 0:9b1d17d54055 212 4, // bDescriptorType
okini3939 0:9b1d17d54055 213 1, // bInterfaceNumber
okini3939 0:9b1d17d54055 214 0, // bAlternateSetting
okini3939 0:9b1d17d54055 215 2, // bNumEndpoints
okini3939 0:9b1d17d54055 216 0x0A, // bInterfaceClass
okini3939 0:9b1d17d54055 217 0x00, // bInterfaceSubClass
okini3939 0:9b1d17d54055 218 0x00, // bInterfaceProtocol
okini3939 0:9b1d17d54055 219 0, // iInterface
okini3939 0:9b1d17d54055 220
okini3939 0:9b1d17d54055 221 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
okini3939 0:9b1d17d54055 222 7, // bLength
okini3939 0:9b1d17d54055 223 5, // bDescriptorType
okini3939 0:9b1d17d54055 224 PHY_TO_DESC(EPBULK_IN), // bEndpointAddress
okini3939 0:9b1d17d54055 225 0x02, // bmAttributes (0x02=bulk)
okini3939 0:9b1d17d54055 226 LSB(MAX_PACKET_SIZE_EPBULK), // wMaxPacketSize (LSB)
okini3939 0:9b1d17d54055 227 MSB(MAX_PACKET_SIZE_EPBULK), // wMaxPacketSize (MSB)
okini3939 0:9b1d17d54055 228 0, // bInterval
okini3939 0:9b1d17d54055 229
okini3939 0:9b1d17d54055 230 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
okini3939 0:9b1d17d54055 231 7, // bLength
okini3939 0:9b1d17d54055 232 5, // bDescriptorType
okini3939 0:9b1d17d54055 233 PHY_TO_DESC(EPBULK_OUT),// bEndpointAddress
okini3939 0:9b1d17d54055 234 0x02, // bmAttributes (0x02=bulk)
okini3939 0:9b1d17d54055 235 LSB(MAX_PACKET_SIZE_EPBULK), // wMaxPacketSize (LSB)
okini3939 0:9b1d17d54055 236 MSB(MAX_PACKET_SIZE_EPBULK), // wMaxPacketSize (MSB)
okini3939 0:9b1d17d54055 237 0 // bInterval
okini3939 0:9b1d17d54055 238 };
okini3939 0:9b1d17d54055 239 return configDescriptor;
okini3939 0:9b1d17d54055 240 }