Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
USBCDC.cpp
00001 /* Copyright (c) 2010-2011 mbed.org, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without 00005 * restriction, including without limitation the rights to use, copy, modify, merge, publish, 00006 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 00007 * Software is furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 00019 #include "stdint.h" 00020 #include "USBCDC.h" 00021 00022 static uint8_t cdc_line_coding[7]= {0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08}; 00023 00024 #define DEFAULT_CONFIGURATION (1) 00025 00026 #define CDC_SET_LINE_CODING 0x20 00027 #define CDC_GET_LINE_CODING 0x21 00028 #define CDC_SET_CONTROL_LINE_STATE 0x22 00029 00030 // Control Line State bits 00031 #define CLS_DTR (1 << 0) 00032 #define CLS_RTS (1 << 1) 00033 00034 #define MAX_CDC_REPORT_SIZE MAX_PACKET_SIZE_EPBULK 00035 00036 USBCDC::USBCDC(uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect_blocking): USBDevice(vendor_id, product_id, product_release) { 00037 terminal_connected = false; 00038 USBDevice::connect(connect_blocking); 00039 } 00040 00041 void USBCDC::USBCallback_busReset(void) { 00042 terminal_connected = false; 00043 }; 00044 00045 bool USBCDC::USBCallback_request(void) { 00046 /* Called in ISR context */ 00047 00048 bool success = false; 00049 CONTROL_TRANSFER * transfer = getTransferPtr(); 00050 00051 /* Process class-specific requests */ 00052 00053 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) { 00054 switch (transfer->setup.bRequest) { 00055 case CDC_GET_LINE_CODING: 00056 transfer->remaining = 7; 00057 transfer->ptr = cdc_line_coding; 00058 transfer->direction = DEVICE_TO_HOST; 00059 success = true; 00060 break; 00061 case CDC_SET_LINE_CODING: 00062 transfer->remaining = 7; 00063 transfer->notify = true; 00064 success = true; 00065 break; 00066 case CDC_SET_CONTROL_LINE_STATE: 00067 if (transfer->setup.wValue & CLS_DTR) { 00068 terminal_connected = true; 00069 } else { 00070 terminal_connected = false; 00071 } 00072 success = true; 00073 break; 00074 default: 00075 break; 00076 } 00077 } 00078 00079 return success; 00080 } 00081 00082 void USBCDC::USBCallback_requestCompleted(uint8_t *buf, uint32_t length) { 00083 // Request of setting line coding has 7 bytes 00084 if (length != 7) { 00085 return; 00086 } 00087 00088 CONTROL_TRANSFER * transfer = getTransferPtr(); 00089 00090 /* Process class-specific requests */ 00091 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) { 00092 if (transfer->setup.bRequest == CDC_SET_LINE_CODING) { 00093 if (memcmp(cdc_line_coding, buf, 7)) { 00094 memcpy(cdc_line_coding, buf, 7); 00095 00096 int baud = buf[0] + (buf[1] << 8) 00097 + (buf[2] << 16) + (buf[3] << 24); 00098 int stop = buf[4]; 00099 int bits = buf[6]; 00100 int parity = buf[5]; 00101 00102 lineCodingChanged(baud, bits, parity, stop); 00103 } 00104 } 00105 } 00106 } 00107 00108 // Called in ISR context 00109 // Set configuration. Return false if the 00110 // configuration is not supported. 00111 bool USBCDC::USBCallback_setConfiguration(uint8_t configuration) { 00112 if (configuration != DEFAULT_CONFIGURATION) { 00113 return false; 00114 } 00115 00116 // Configure endpoints > 0 00117 addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT); 00118 addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK); 00119 addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); 00120 00121 // We activate the endpoint to be able to recceive data 00122 readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); 00123 return true; 00124 } 00125 00126 bool USBCDC::send(uint8_t * buffer, uint32_t size) { 00127 return USBDevice::write(EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE); 00128 } 00129 00130 bool USBCDC::readEP(uint8_t * buffer, uint32_t * size) { 00131 if (!USBDevice::readEP(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE)) 00132 return false; 00133 if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE)) 00134 return false; 00135 return true; 00136 } 00137 00138 bool USBCDC::readEP_NB(uint8_t * buffer, uint32_t * size) { 00139 if (!USBDevice::readEP_NB(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE)) 00140 return false; 00141 if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE)) 00142 return false; 00143 return true; 00144 } 00145 00146 00147 const uint8_t * USBCDC::deviceDesc() { 00148 uint8_t deviceDescriptorTemp[] = { 00149 18, // bLength 00150 1, // bDescriptorType 00151 0x10, 0x01, // bcdUSB 00152 2, // bDeviceClass 00153 0, // bDeviceSubClass 00154 0, // bDeviceProtocol 00155 MAX_PACKET_SIZE_EP0, // bMaxPacketSize0 00156 (uint8_t)(LSB(VENDOR_ID)), (uint8_t)(MSB(VENDOR_ID)), // idVendor 00157 (uint8_t)(LSB(PRODUCT_ID)), (uint8_t)(MSB(PRODUCT_ID)),// idProduct 00158 0x00, 0x01, // bcdDevice 00159 1, // iManufacturer 00160 2, // iProduct 00161 3, // iSerialNumber 00162 1 // bNumConfigurations 00163 }; 00164 MBED_ASSERT(sizeof(deviceDescriptorTemp) == sizeof(deviceDescriptor)); 00165 memcpy(deviceDescriptor, deviceDescriptorTemp, sizeof(deviceDescriptor)); 00166 return deviceDescriptor; 00167 } 00168 00169 const uint8_t * USBCDC::stringIinterfaceDesc() { 00170 static const uint8_t stringIinterfaceDescriptor[] = { 00171 0x08, 00172 STRING_DESCRIPTOR, 00173 'C',0,'D',0,'C',0, 00174 }; 00175 return stringIinterfaceDescriptor; 00176 } 00177 00178 const uint8_t * USBCDC::stringIproductDesc() { 00179 static const uint8_t stringIproductDescriptor[] = { 00180 0x16, 00181 STRING_DESCRIPTOR, 00182 'C',0,'D',0,'C',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 00183 }; 00184 return stringIproductDescriptor; 00185 } 00186 00187 00188 #define CONFIG1_DESC_SIZE (9+8+9+5+5+4+5+7+9+7+7) 00189 00190 const uint8_t * USBCDC::configurationDesc() { 00191 static const uint8_t configDescriptor[] = { 00192 // configuration descriptor 00193 9, // bLength 00194 2, // bDescriptorType 00195 LSB(CONFIG1_DESC_SIZE), // wTotalLength 00196 MSB(CONFIG1_DESC_SIZE), 00197 2, // bNumInterfaces 00198 1, // bConfigurationValue 00199 0, // iConfiguration 00200 0x80, // bmAttributes 00201 50, // bMaxPower 00202 00203 // IAD to associate the two CDC interfaces 00204 0x08, // bLength 00205 0x0b, // bDescriptorType 00206 0x00, // bFirstInterface 00207 0x02, // bInterfaceCount 00208 0x02, // bFunctionClass 00209 0x02, // bFunctionSubClass 00210 0, // bFunctionProtocol 00211 0, // iFunction 00212 00213 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 00214 9, // bLength 00215 4, // bDescriptorType 00216 0, // bInterfaceNumber 00217 0, // bAlternateSetting 00218 1, // bNumEndpoints 00219 0x02, // bInterfaceClass 00220 0x02, // bInterfaceSubClass 00221 0x01, // bInterfaceProtocol 00222 0, // iInterface 00223 00224 // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26 00225 5, // bFunctionLength 00226 0x24, // bDescriptorType 00227 0x00, // bDescriptorSubtype 00228 0x10, 0x01, // bcdCDC 00229 00230 // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27 00231 5, // bFunctionLength 00232 0x24, // bDescriptorType 00233 0x01, // bDescriptorSubtype 00234 0x03, // bmCapabilities 00235 1, // bDataInterface 00236 00237 // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28 00238 4, // bFunctionLength 00239 0x24, // bDescriptorType 00240 0x02, // bDescriptorSubtype 00241 0x06, // bmCapabilities 00242 00243 // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33 00244 5, // bFunctionLength 00245 0x24, // bDescriptorType 00246 0x06, // bDescriptorSubtype 00247 0, // bMasterInterface 00248 1, // bSlaveInterface0 00249 00250 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 00251 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00252 ENDPOINT_DESCRIPTOR, // bDescriptorType 00253 PHY_TO_DESC(EPINT_IN), // bEndpointAddress 00254 E_INTERRUPT, // bmAttributes (0x03=intr) 00255 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) 00256 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) 00257 16, // bInterval 00258 00259 00260 00261 00262 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 00263 9, // bLength 00264 4, // bDescriptorType 00265 1, // bInterfaceNumber 00266 0, // bAlternateSetting 00267 2, // bNumEndpoints 00268 0x0A, // bInterfaceClass 00269 0x00, // bInterfaceSubClass 00270 0x00, // bInterfaceProtocol 00271 0, // iInterface 00272 00273 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 00274 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00275 ENDPOINT_DESCRIPTOR, // bDescriptorType 00276 PHY_TO_DESC(EPBULK_IN), // bEndpointAddress 00277 E_BULK, // bmAttributes (0x02=bulk) 00278 LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB) 00279 MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB) 00280 0, // bInterval 00281 00282 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 00283 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00284 ENDPOINT_DESCRIPTOR, // bDescriptorType 00285 PHY_TO_DESC(EPBULK_OUT), // bEndpointAddress 00286 E_BULK, // bmAttributes (0x02=bulk) 00287 LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB) 00288 MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB) 00289 0 // bInterval 00290 }; 00291 return configDescriptor; 00292 }
Generated on Tue Jul 12 2022 12:22:27 by
