Konstantin Kochin / USBDevice

Dependents:   STM32F103C8T6_USBSerial_Demo lightweight-weather-station

Fork of USBDevice by mbed official

Committer:
Konstantin Kochin
Date:
Fri Aug 04 10:58:23 2017 +0300
Revision:
72:f9f7fd5440e1
Parent:
70:2c525a50f1b6
Bug fixing

- added missed "include" to "USBDevice_Types.h"
- temporary fix of the lazy initialization of the description table
(method deviceDesc). The fix simply invokes method deviceDesc in the
constructor, because if the method is invoked at first time during
interrupt, it causes os error.

Who changed what in which revision?

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