CDC/ECM driver for mbed, based on USBDevice by mbed-official. Uses PicoTCP to access Ethernet USB device. License: GPLv2
Fork of USB_Ethernet by
USBCDC_ECM.cpp@2:540f6e142d59, 2013-08-03 (annotated)
- 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?
User | Revision | Line number | New 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 | } |