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:
Fri Aug 02 08:04:58 2013 +0000
Revision:
0:34c829fbc7a8
Child:
1:759afa79ebe8
First version. Untested;

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 0:34c829fbc7a8 81 return true;
daniele 0:34c829fbc7a8 82 }
daniele 0:34c829fbc7a8 83
daniele 0:34c829fbc7a8 84 bool USBCDC_ECM::send(uint8_t * buffer, uint32_t size) {
daniele 0:34c829fbc7a8 85 return USBDevice::write(EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE);
daniele 0:34c829fbc7a8 86 }
daniele 0:34c829fbc7a8 87
daniele 0:34c829fbc7a8 88 bool USBCDC_ECM::readEP(uint8_t * buffer, uint32_t * size) {
daniele 0:34c829fbc7a8 89 if (!USBDevice::readEP(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
daniele 0:34c829fbc7a8 90 return false;
daniele 0:34c829fbc7a8 91 if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
daniele 0:34c829fbc7a8 92 return false;
daniele 0:34c829fbc7a8 93 return true;
daniele 0:34c829fbc7a8 94 }
daniele 0:34c829fbc7a8 95
daniele 0:34c829fbc7a8 96 bool USBCDC_ECM::readEP_NB(uint8_t * buffer, uint32_t * size) {
daniele 0:34c829fbc7a8 97 if (!USBDevice::readEP_NB(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
daniele 0:34c829fbc7a8 98 return false;
daniele 0:34c829fbc7a8 99 if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
daniele 0:34c829fbc7a8 100 return false;
daniele 0:34c829fbc7a8 101 return true;
daniele 0:34c829fbc7a8 102 }
daniele 0:34c829fbc7a8 103
daniele 0:34c829fbc7a8 104
daniele 0:34c829fbc7a8 105 uint8_t * USBCDC_ECM::deviceDesc() {
daniele 0:34c829fbc7a8 106 static uint8_t deviceDescriptor[] = {
daniele 0:34c829fbc7a8 107 18, // bLength
daniele 0:34c829fbc7a8 108 1, // bDescriptorType
daniele 0:34c829fbc7a8 109 0x10, 0x01, // bcdUSB
daniele 0:34c829fbc7a8 110 2, // bDeviceClass
daniele 0:34c829fbc7a8 111 0, // bDeviceSubClass
daniele 0:34c829fbc7a8 112 0, // bDeviceProtocol
daniele 0:34c829fbc7a8 113 MAX_PACKET_SIZE_EP0, // bMaxPacketSize0
daniele 0:34c829fbc7a8 114 LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor
daniele 0:34c829fbc7a8 115 LSB(PRODUCT_ID), MSB(PRODUCT_ID),// idProduct
daniele 0:34c829fbc7a8 116 0x00, 0x01, // bcdDevice
daniele 0:34c829fbc7a8 117 1, // iManufacturer
daniele 0:34c829fbc7a8 118 2, // iProduct
daniele 0:34c829fbc7a8 119 3, // iSerialNumber
daniele 0:34c829fbc7a8 120 4, // iMacAddress
daniele 0:34c829fbc7a8 121 1 // bNumConfigurations
daniele 0:34c829fbc7a8 122 };
daniele 0:34c829fbc7a8 123 return deviceDescriptor;
daniele 0:34c829fbc7a8 124 }
daniele 0:34c829fbc7a8 125
daniele 0:34c829fbc7a8 126 uint8_t * USBCDC_ECM::stringIinterfaceDesc() {
daniele 0:34c829fbc7a8 127 static uint8_t stringIinterfaceDescriptor[] = {
daniele 0:34c829fbc7a8 128 0x08,
daniele 0:34c829fbc7a8 129 STRING_DESCRIPTOR,
daniele 0:34c829fbc7a8 130 'C',0,'D',0,'C',0,
daniele 0:34c829fbc7a8 131 };
daniele 0:34c829fbc7a8 132 return stringIinterfaceDescriptor;
daniele 0:34c829fbc7a8 133 }
daniele 0:34c829fbc7a8 134
daniele 0:34c829fbc7a8 135 uint8_t * USBCDC_ECM::stringIproductDesc() {
daniele 0:34c829fbc7a8 136 static uint8_t stringIproductDescriptor[] = {
daniele 0:34c829fbc7a8 137 36,
daniele 0:34c829fbc7a8 138 STRING_DESCRIPTOR,
daniele 0:34c829fbc7a8 139 '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 140 };
daniele 0:34c829fbc7a8 141 return stringIproductDescriptor;
daniele 0:34c829fbc7a8 142 }
daniele 0:34c829fbc7a8 143
daniele 0:34c829fbc7a8 144 uint8_t * USBCDC_ECM::stringIserialDesc() {
daniele 0:34c829fbc7a8 145 static uint8_t stringIserialDescriptor[] = {
daniele 0:34c829fbc7a8 146 26,
daniele 0:34c829fbc7a8 147 STRING_DESCRIPTOR,
daniele 0:34c829fbc7a8 148 '0',0,'0',0,
daniele 0:34c829fbc7a8 149 '5', 0,'a',0,
daniele 0:34c829fbc7a8 150 'f',0,'3',0,
daniele 0:34c829fbc7a8 151 '4',0,'1',0,
daniele 0:34c829fbc7a8 152 'b',0,'4',0,
daniele 0:34c829fbc7a8 153 'c',0,'7',0
daniele 0:34c829fbc7a8 154 };
daniele 0:34c829fbc7a8 155 return stringIserialDescriptor;
daniele 0:34c829fbc7a8 156 }
daniele 0:34c829fbc7a8 157
daniele 0:34c829fbc7a8 158 uint8_t * USBCDC_ECM::stringIConfigurationDesc() {
daniele 0:34c829fbc7a8 159 static uint8_t stringImacAddr[] = {
daniele 0:34c829fbc7a8 160 26,
daniele 0:34c829fbc7a8 161 STRING_DESCRIPTOR,
daniele 0:34c829fbc7a8 162 '0',0,'0',0,
daniele 0:34c829fbc7a8 163 '5', 0,'a',0,
daniele 0:34c829fbc7a8 164 'f',0,'3',0,
daniele 0:34c829fbc7a8 165 '4',0,'1',0,
daniele 0:34c829fbc7a8 166 'b',0,'4',0,
daniele 0:34c829fbc7a8 167 'c',0,'7',0
daniele 0:34c829fbc7a8 168 };
daniele 0:34c829fbc7a8 169 return stringImacAddr;
daniele 0:34c829fbc7a8 170 }
daniele 0:34c829fbc7a8 171
daniele 0:34c829fbc7a8 172 #define CONFIG1_DESC_SIZE (9+9+5+5+13+7+9+7+7)
daniele 0:34c829fbc7a8 173
daniele 0:34c829fbc7a8 174 uint8_t * USBCDC_ECM::configurationDesc() {
daniele 0:34c829fbc7a8 175 static uint8_t configDescriptor[] = {
daniele 0:34c829fbc7a8 176 // configuration descriptor
daniele 0:34c829fbc7a8 177 9, // bLength
daniele 0:34c829fbc7a8 178 2, // bDescriptorType
daniele 0:34c829fbc7a8 179 LSB(CONFIG1_DESC_SIZE), // wTotalLength
daniele 0:34c829fbc7a8 180 MSB(CONFIG1_DESC_SIZE),
daniele 0:34c829fbc7a8 181 2, // bNumInterfaces
daniele 0:34c829fbc7a8 182 1, // bConfigurationValue
daniele 0:34c829fbc7a8 183 0, // iConfiguration
daniele 0:34c829fbc7a8 184 0xc0, // bmAttributes
daniele 0:34c829fbc7a8 185 50, // bMaxPower
daniele 0:34c829fbc7a8 186
daniele 0:34c829fbc7a8 187 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
daniele 0:34c829fbc7a8 188 9, // bLength
daniele 0:34c829fbc7a8 189 4, // bDescriptorType
daniele 0:34c829fbc7a8 190 0, // bInterfaceNumber
daniele 0:34c829fbc7a8 191 0, // bAlternateSetting
daniele 0:34c829fbc7a8 192 1, // bNumEndpoints
daniele 0:34c829fbc7a8 193 0x02, // bInterfaceClass
daniele 0:34c829fbc7a8 194 0x06, // bInterfaceSubClass
daniele 0:34c829fbc7a8 195 0x00, // bInterfaceProtocol
daniele 0:34c829fbc7a8 196 0, // iInterface
daniele 0:34c829fbc7a8 197
daniele 0:34c829fbc7a8 198 // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26
daniele 0:34c829fbc7a8 199 5, // bFunctionLength
daniele 0:34c829fbc7a8 200 0x24, // bDescriptorType
daniele 0:34c829fbc7a8 201 0x00, // bDescriptorSubtype
daniele 0:34c829fbc7a8 202 0x20, 0x01, // bcdCDC
daniele 0:34c829fbc7a8 203
daniele 0:34c829fbc7a8 204 // CDC Union
daniele 0:34c829fbc7a8 205 5, // bFunctionLength
daniele 0:34c829fbc7a8 206 0x24, // bDescriptorType
daniele 0:34c829fbc7a8 207 0x06, // bDescriptorSubType
daniele 0:34c829fbc7a8 208 0, // bControlInterface
daniele 0:34c829fbc7a8 209 1, // bSubordinateInterface0
daniele 0:34c829fbc7a8 210
daniele 0:34c829fbc7a8 211
daniele 0:34c829fbc7a8 212
daniele 0:34c829fbc7a8 213 // CDC/ECM Functional Descriptor
daniele 0:34c829fbc7a8 214 13, // bFunctionLenght
daniele 0:34c829fbc7a8 215 0x24, // bDescriptorType
daniele 0:34c829fbc7a8 216 0x0F, // bDescriptorSubtype
daniele 0:34c829fbc7a8 217 4, // iMacAddress
daniele 0:34c829fbc7a8 218 0, 0, 0, 0, // bmEthernetStatistics
daniele 0:34c829fbc7a8 219
daniele 0:34c829fbc7a8 220 0x05, 0xEA, // wMaxSegmentSize
daniele 0:34c829fbc7a8 221
daniele 0:34c829fbc7a8 222
daniele 0:34c829fbc7a8 223 0, 0, // wNumberMCFilters
daniele 0:34c829fbc7a8 224
daniele 0:34c829fbc7a8 225 0, // bNumberPowerFilters
daniele 0:34c829fbc7a8 226
daniele 0:34c829fbc7a8 227 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
daniele 0:34c829fbc7a8 228 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
daniele 0:34c829fbc7a8 229 ENDPOINT_DESCRIPTOR, // bDescriptorType
daniele 0:34c829fbc7a8 230 PHY_TO_DESC(EPINT_IN), // bEndpointAddress
daniele 0:34c829fbc7a8 231 0x03 , // bmAttributes (0x03=intr)
daniele 0:34c829fbc7a8 232 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
daniele 0:34c829fbc7a8 233 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
daniele 0:34c829fbc7a8 234 16,
daniele 0:34c829fbc7a8 235
daniele 0:34c829fbc7a8 236 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
daniele 0:34c829fbc7a8 237 9, // bLength
daniele 0:34c829fbc7a8 238 4, // bDescriptorType
daniele 0:34c829fbc7a8 239 1, // bInterfaceNumber
daniele 0:34c829fbc7a8 240 0, // bAlternateSetting
daniele 0:34c829fbc7a8 241 2, // bNumEndpoints
daniele 0:34c829fbc7a8 242 0x0A, // bInterfaceClass
daniele 0:34c829fbc7a8 243 0x00, // bInterfaceSubClass
daniele 0:34c829fbc7a8 244 0x00, // bInterfaceProtocol
daniele 0:34c829fbc7a8 245 0, // iInterface
daniele 0:34c829fbc7a8 246
daniele 0:34c829fbc7a8 247 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
daniele 0:34c829fbc7a8 248 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
daniele 0:34c829fbc7a8 249 ENDPOINT_DESCRIPTOR, // bDescriptorType
daniele 0:34c829fbc7a8 250 PHY_TO_DESC(EPBULK_IN), // bEndpointAddress
daniele 0:34c829fbc7a8 251 E_BULK, // bmAttributes (0x02=bulk)
daniele 0:34c829fbc7a8 252 LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
daniele 0:34c829fbc7a8 253 MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
daniele 0:34c829fbc7a8 254 0, // bInterval
daniele 0:34c829fbc7a8 255
daniele 0:34c829fbc7a8 256 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
daniele 0:34c829fbc7a8 257 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
daniele 0:34c829fbc7a8 258 ENDPOINT_DESCRIPTOR, // bDescriptorType
daniele 0:34c829fbc7a8 259 PHY_TO_DESC(EPBULK_OUT), // bEndpointAddress
daniele 0:34c829fbc7a8 260 E_BULK, // bmAttributes (0x02=bulk)
daniele 0:34c829fbc7a8 261 LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
daniele 0:34c829fbc7a8 262 MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
daniele 0:34c829fbc7a8 263 0 // bInterval
daniele 0:34c829fbc7a8 264 };
daniele 0:34c829fbc7a8 265 return configDescriptor;
daniele 0:34c829fbc7a8 266 }