CDC/ECM driver for mbed, based on USBDevice by mbed-official. Uses PicoTCP to access Ethernet USB device. License: GPLv2

Dependents:   USBEthernet_TEST

Fork of USB_Ethernet by Daniele Lacamera

Committer:
daniele
Date:
Sat Aug 03 08:51:00 2013 +0000
Revision:
1:759afa79ebe8
Parent:
0:34c829fbc7a8
Child:
2:540f6e142d59
Work in progress: CDC-ECM support (GPL2);

Who changed what in which revision?

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