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 13:16:14 2013 +0000
Revision:
2:540f6e142d59
Parent:
1:759afa79ebe8
Moved to single package

Who changed what in which revision?

UserRevisionLine numberNew contents of line
daniele 2:540f6e142d59 1 /*********************************************************************
daniele 2:540f6e142d59 2 PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
daniele 2:540f6e142d59 3 See LICENSE and COPYING for usage.
daniele 2:540f6e142d59 4 Do not redistribute without a written permission by the Copyright
daniele 2:540f6e142d59 5 holders.
daniele 0:34c829fbc7a8 6
daniele 2:540f6e142d59 7 Authors: Daniele Lacamera, Julien Duraj
daniele 2:540f6e142d59 8 *********************************************************************/
daniele 0:34c829fbc7a8 9 #include "stdint.h"
daniele 0:34c829fbc7a8 10 #include "USBCDC_ECM.h"
daniele 0:34c829fbc7a8 11 #define DEFAULT_CONFIGURATION (1)
daniele 0:34c829fbc7a8 12 #define MAX_CDC_REPORT_SIZE MAX_PACKET_SIZE_EPBULK
daniele 0:34c829fbc7a8 13
daniele 0:34c829fbc7a8 14 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 15 terminal_connected = false;
daniele 0:34c829fbc7a8 16 USBDevice::connect();
daniele 0:34c829fbc7a8 17 }
daniele 0:34c829fbc7a8 18
daniele 0:34c829fbc7a8 19 bool USBCDC_ECM::USBCallback_request(void) {
daniele 0:34c829fbc7a8 20 /* Called in ISR context */
daniele 0:34c829fbc7a8 21
daniele 0:34c829fbc7a8 22 bool success = false;
daniele 0:34c829fbc7a8 23 CONTROL_TRANSFER * transfer = getTransferPtr();
daniele 0:34c829fbc7a8 24
daniele 0:34c829fbc7a8 25 if (transfer->setup.bmRequestType.Type == STANDARD_TYPE) {
daniele 0:34c829fbc7a8 26 printf("In USBCallback_request: GENERIC Request: %02x\n", transfer->setup.bRequest);
daniele 0:34c829fbc7a8 27 } else if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
daniele 0:34c829fbc7a8 28 printf("In USBCallback_request: CLASS specific Request: %02x\n", transfer->setup.bRequest);
daniele 0:34c829fbc7a8 29 switch (transfer->setup.bRequest) {
daniele 0:34c829fbc7a8 30 default:
daniele 0:34c829fbc7a8 31 break;
daniele 0:34c829fbc7a8 32 }
daniele 0:34c829fbc7a8 33 }
daniele 0:34c829fbc7a8 34
daniele 0:34c829fbc7a8 35 return success;
daniele 0:34c829fbc7a8 36 }
daniele 0:34c829fbc7a8 37
daniele 0:34c829fbc7a8 38 bool USBCDC_ECM::USBCallback_setInterface(uint16_t interface, uint8_t alternate)
daniele 0:34c829fbc7a8 39 {
daniele 0:34c829fbc7a8 40 printf("Host selected interface %d, alternate %d\n", interface, alternate);
daniele 0:34c829fbc7a8 41 return true;
daniele 0:34c829fbc7a8 42 }
daniele 0:34c829fbc7a8 43
daniele 0:34c829fbc7a8 44
daniele 0:34c829fbc7a8 45 // Called in ISR context
daniele 0:34c829fbc7a8 46 // Set configuration. Return false if the
daniele 0:34c829fbc7a8 47 // configuration is not supported.
daniele 0:34c829fbc7a8 48 bool USBCDC_ECM::USBCallback_setConfiguration(uint8_t configuration) {
daniele 0:34c829fbc7a8 49 printf("In USBCallback_SetConfiguration: %02x\n", configuration);
daniele 0:34c829fbc7a8 50 if (configuration != DEFAULT_CONFIGURATION) {
daniele 0:34c829fbc7a8 51 printf("Set config: failed\n");
daniele 0:34c829fbc7a8 52 return false;
daniele 0:34c829fbc7a8 53 }
daniele 0:34c829fbc7a8 54
daniele 0:34c829fbc7a8 55 // Configure endpoints > 0
daniele 0:34c829fbc7a8 56 addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
daniele 0:34c829fbc7a8 57 addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
daniele 0:34c829fbc7a8 58 addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
daniele 0:34c829fbc7a8 59
daniele 0:34c829fbc7a8 60 // We activate the endpoint to be able to recceive data
daniele 0:34c829fbc7a8 61 readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
daniele 0:34c829fbc7a8 62 printf("Set config: OK!\n");
daniele 1:759afa79ebe8 63
daniele 0:34c829fbc7a8 64 return true;
daniele 0:34c829fbc7a8 65 }
daniele 0:34c829fbc7a8 66
daniele 0:34c829fbc7a8 67 bool USBCDC_ECM::send(uint8_t * buffer, uint32_t size) {
daniele 1:759afa79ebe8 68 if (!configured())
daniele 1:759afa79ebe8 69 return false;
daniele 0:34c829fbc7a8 70 return USBDevice::write(EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE);
daniele 0:34c829fbc7a8 71 }
daniele 0:34c829fbc7a8 72
daniele 0:34c829fbc7a8 73 bool USBCDC_ECM::readEP(uint8_t * buffer, uint32_t * size) {
daniele 1:759afa79ebe8 74 if (!configured())
daniele 1:759afa79ebe8 75 return false;
daniele 0:34c829fbc7a8 76 if (!USBDevice::readEP(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
daniele 0:34c829fbc7a8 77 return false;
daniele 0:34c829fbc7a8 78 if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
daniele 0:34c829fbc7a8 79 return false;
daniele 0:34c829fbc7a8 80 return true;
daniele 0:34c829fbc7a8 81 }
daniele 0:34c829fbc7a8 82
daniele 0:34c829fbc7a8 83 bool USBCDC_ECM::readEP_NB(uint8_t * buffer, uint32_t * size) {
daniele 1:759afa79ebe8 84 if (!configured())
daniele 1:759afa79ebe8 85 return false;
daniele 0:34c829fbc7a8 86 if (!USBDevice::readEP_NB(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE))
daniele 0:34c829fbc7a8 87 return false;
daniele 0:34c829fbc7a8 88 if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE))
daniele 0:34c829fbc7a8 89 return false;
daniele 0:34c829fbc7a8 90 return true;
daniele 0:34c829fbc7a8 91 }
daniele 0:34c829fbc7a8 92
daniele 0:34c829fbc7a8 93
daniele 0:34c829fbc7a8 94 uint8_t * USBCDC_ECM::deviceDesc() {
daniele 0:34c829fbc7a8 95 static uint8_t deviceDescriptor[] = {
daniele 0:34c829fbc7a8 96 18, // bLength
daniele 0:34c829fbc7a8 97 1, // bDescriptorType
daniele 0:34c829fbc7a8 98 0x10, 0x01, // bcdUSB
daniele 0:34c829fbc7a8 99 2, // bDeviceClass
daniele 0:34c829fbc7a8 100 0, // bDeviceSubClass
daniele 0:34c829fbc7a8 101 0, // bDeviceProtocol
daniele 0:34c829fbc7a8 102 MAX_PACKET_SIZE_EP0, // bMaxPacketSize0
daniele 0:34c829fbc7a8 103 LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor
daniele 0:34c829fbc7a8 104 LSB(PRODUCT_ID), MSB(PRODUCT_ID),// idProduct
daniele 0:34c829fbc7a8 105 0x00, 0x01, // bcdDevice
daniele 0:34c829fbc7a8 106 1, // iManufacturer
daniele 0:34c829fbc7a8 107 2, // iProduct
daniele 0:34c829fbc7a8 108 3, // iSerialNumber
daniele 0:34c829fbc7a8 109 4, // iMacAddress
daniele 0:34c829fbc7a8 110 1 // bNumConfigurations
daniele 0:34c829fbc7a8 111 };
daniele 0:34c829fbc7a8 112 return deviceDescriptor;
daniele 0:34c829fbc7a8 113 }
daniele 0:34c829fbc7a8 114
daniele 0:34c829fbc7a8 115 uint8_t * USBCDC_ECM::stringIinterfaceDesc() {
daniele 0:34c829fbc7a8 116 static uint8_t stringIinterfaceDescriptor[] = {
daniele 0:34c829fbc7a8 117 0x08,
daniele 0:34c829fbc7a8 118 STRING_DESCRIPTOR,
daniele 0:34c829fbc7a8 119 'C',0,'D',0,'C',0,
daniele 0:34c829fbc7a8 120 };
daniele 0:34c829fbc7a8 121 return stringIinterfaceDescriptor;
daniele 0:34c829fbc7a8 122 }
daniele 0:34c829fbc7a8 123
daniele 0:34c829fbc7a8 124 uint8_t * USBCDC_ECM::stringIproductDesc() {
daniele 0:34c829fbc7a8 125 static uint8_t stringIproductDescriptor[] = {
daniele 0:34c829fbc7a8 126 36,
daniele 0:34c829fbc7a8 127 STRING_DESCRIPTOR,
daniele 0:34c829fbc7a8 128 '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 129 };
daniele 0:34c829fbc7a8 130 return stringIproductDescriptor;
daniele 0:34c829fbc7a8 131 }
daniele 0:34c829fbc7a8 132
daniele 0:34c829fbc7a8 133 uint8_t * USBCDC_ECM::stringIserialDesc() {
daniele 0:34c829fbc7a8 134 static uint8_t stringIserialDescriptor[] = {
daniele 0:34c829fbc7a8 135 26,
daniele 0:34c829fbc7a8 136 STRING_DESCRIPTOR,
daniele 0:34c829fbc7a8 137 '0',0,'0',0,
daniele 0:34c829fbc7a8 138 '5', 0,'a',0,
daniele 0:34c829fbc7a8 139 'f',0,'3',0,
daniele 0:34c829fbc7a8 140 '4',0,'1',0,
daniele 0:34c829fbc7a8 141 'b',0,'4',0,
daniele 0:34c829fbc7a8 142 'c',0,'7',0
daniele 0:34c829fbc7a8 143 };
daniele 0:34c829fbc7a8 144 return stringIserialDescriptor;
daniele 0:34c829fbc7a8 145 }
daniele 0:34c829fbc7a8 146
daniele 0:34c829fbc7a8 147 uint8_t * USBCDC_ECM::stringIConfigurationDesc() {
daniele 0:34c829fbc7a8 148 static uint8_t stringImacAddr[] = {
daniele 0:34c829fbc7a8 149 26,
daniele 0:34c829fbc7a8 150 STRING_DESCRIPTOR,
daniele 0:34c829fbc7a8 151 '0',0,'0',0,
daniele 0:34c829fbc7a8 152 '5', 0,'a',0,
daniele 0:34c829fbc7a8 153 'f',0,'3',0,
daniele 0:34c829fbc7a8 154 '4',0,'1',0,
daniele 0:34c829fbc7a8 155 'b',0,'4',0,
daniele 0:34c829fbc7a8 156 'c',0,'7',0
daniele 0:34c829fbc7a8 157 };
daniele 0:34c829fbc7a8 158 return stringImacAddr;
daniele 0:34c829fbc7a8 159 }
daniele 0:34c829fbc7a8 160
daniele 0:34c829fbc7a8 161 #define CONFIG1_DESC_SIZE (9+9+5+5+13+7+9+7+7)
daniele 0:34c829fbc7a8 162
daniele 0:34c829fbc7a8 163 uint8_t * USBCDC_ECM::configurationDesc() {
daniele 0:34c829fbc7a8 164 static uint8_t configDescriptor[] = {
daniele 0:34c829fbc7a8 165 // configuration descriptor
daniele 0:34c829fbc7a8 166 9, // bLength
daniele 0:34c829fbc7a8 167 2, // bDescriptorType
daniele 0:34c829fbc7a8 168 LSB(CONFIG1_DESC_SIZE), // wTotalLength
daniele 0:34c829fbc7a8 169 MSB(CONFIG1_DESC_SIZE),
daniele 0:34c829fbc7a8 170 2, // bNumInterfaces
daniele 0:34c829fbc7a8 171 1, // bConfigurationValue
daniele 0:34c829fbc7a8 172 0, // iConfiguration
daniele 0:34c829fbc7a8 173 0xc0, // bmAttributes
daniele 0:34c829fbc7a8 174 50, // bMaxPower
daniele 0:34c829fbc7a8 175
daniele 0:34c829fbc7a8 176 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
daniele 0:34c829fbc7a8 177 9, // bLength
daniele 0:34c829fbc7a8 178 4, // bDescriptorType
daniele 0:34c829fbc7a8 179 0, // bInterfaceNumber
daniele 0:34c829fbc7a8 180 0, // bAlternateSetting
daniele 0:34c829fbc7a8 181 1, // bNumEndpoints
daniele 0:34c829fbc7a8 182 0x02, // bInterfaceClass
daniele 0:34c829fbc7a8 183 0x06, // bInterfaceSubClass
daniele 0:34c829fbc7a8 184 0x00, // bInterfaceProtocol
daniele 0:34c829fbc7a8 185 0, // iInterface
daniele 0:34c829fbc7a8 186
daniele 0:34c829fbc7a8 187 // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26
daniele 0:34c829fbc7a8 188 5, // bFunctionLength
daniele 0:34c829fbc7a8 189 0x24, // bDescriptorType
daniele 0:34c829fbc7a8 190 0x00, // bDescriptorSubtype
daniele 0:34c829fbc7a8 191 0x20, 0x01, // bcdCDC
daniele 0:34c829fbc7a8 192
daniele 0:34c829fbc7a8 193 // CDC Union
daniele 0:34c829fbc7a8 194 5, // bFunctionLength
daniele 0:34c829fbc7a8 195 0x24, // bDescriptorType
daniele 0:34c829fbc7a8 196 0x06, // bDescriptorSubType
daniele 0:34c829fbc7a8 197 0, // bControlInterface
daniele 0:34c829fbc7a8 198 1, // bSubordinateInterface0
daniele 0:34c829fbc7a8 199
daniele 0:34c829fbc7a8 200
daniele 0:34c829fbc7a8 201
daniele 0:34c829fbc7a8 202 // CDC/ECM Functional Descriptor
daniele 0:34c829fbc7a8 203 13, // bFunctionLenght
daniele 0:34c829fbc7a8 204 0x24, // bDescriptorType
daniele 0:34c829fbc7a8 205 0x0F, // bDescriptorSubtype
daniele 0:34c829fbc7a8 206 4, // iMacAddress
daniele 0:34c829fbc7a8 207 0, 0, 0, 0, // bmEthernetStatistics
daniele 0:34c829fbc7a8 208
daniele 0:34c829fbc7a8 209 0x05, 0xEA, // wMaxSegmentSize
daniele 0:34c829fbc7a8 210
daniele 0:34c829fbc7a8 211
daniele 0:34c829fbc7a8 212 0, 0, // wNumberMCFilters
daniele 0:34c829fbc7a8 213
daniele 0:34c829fbc7a8 214 0, // bNumberPowerFilters
daniele 0:34c829fbc7a8 215
daniele 0:34c829fbc7a8 216 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
daniele 0:34c829fbc7a8 217 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
daniele 0:34c829fbc7a8 218 ENDPOINT_DESCRIPTOR, // bDescriptorType
daniele 0:34c829fbc7a8 219 PHY_TO_DESC(EPINT_IN), // bEndpointAddress
daniele 0:34c829fbc7a8 220 0x03 , // bmAttributes (0x03=intr)
daniele 0:34c829fbc7a8 221 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
daniele 0:34c829fbc7a8 222 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
daniele 0:34c829fbc7a8 223 16,
daniele 0:34c829fbc7a8 224
daniele 0:34c829fbc7a8 225 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
daniele 0:34c829fbc7a8 226 9, // bLength
daniele 0:34c829fbc7a8 227 4, // bDescriptorType
daniele 0:34c829fbc7a8 228 1, // bInterfaceNumber
daniele 0:34c829fbc7a8 229 0, // bAlternateSetting
daniele 0:34c829fbc7a8 230 2, // bNumEndpoints
daniele 0:34c829fbc7a8 231 0x0A, // bInterfaceClass
daniele 0:34c829fbc7a8 232 0x00, // bInterfaceSubClass
daniele 0:34c829fbc7a8 233 0x00, // bInterfaceProtocol
daniele 0:34c829fbc7a8 234 0, // iInterface
daniele 0:34c829fbc7a8 235
daniele 0:34c829fbc7a8 236 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
daniele 0:34c829fbc7a8 237 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
daniele 0:34c829fbc7a8 238 ENDPOINT_DESCRIPTOR, // bDescriptorType
daniele 0:34c829fbc7a8 239 PHY_TO_DESC(EPBULK_IN), // bEndpointAddress
daniele 0:34c829fbc7a8 240 E_BULK, // bmAttributes (0x02=bulk)
daniele 0:34c829fbc7a8 241 LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
daniele 0:34c829fbc7a8 242 MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
daniele 0:34c829fbc7a8 243 0, // bInterval
daniele 0:34c829fbc7a8 244
daniele 0:34c829fbc7a8 245 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
daniele 0:34c829fbc7a8 246 ENDPOINT_DESCRIPTOR_LENGTH, // bLength
daniele 0:34c829fbc7a8 247 ENDPOINT_DESCRIPTOR, // bDescriptorType
daniele 0:34c829fbc7a8 248 PHY_TO_DESC(EPBULK_OUT), // bEndpointAddress
daniele 0:34c829fbc7a8 249 E_BULK, // bmAttributes (0x02=bulk)
daniele 0:34c829fbc7a8 250 LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB)
daniele 0:34c829fbc7a8 251 MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB)
daniele 0:34c829fbc7a8 252 0 // bInterval
daniele 0:34c829fbc7a8 253 };
daniele 0:34c829fbc7a8 254 return configDescriptor;
daniele 0:34c829fbc7a8 255 }