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::send_NB(uint8_t * buffer, uint32_t size) { 00131 return USBDevice::writeNB(EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE); 00132 } 00133 00134 bool USBCDC::readEP(uint8_t * buffer, uint32_t * size) { 00135 if (!USBDevice::readEP(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE)) 00136 return false; 00137 if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE)) 00138 return false; 00139 return true; 00140 } 00141 00142 bool USBCDC::readEP_NB(uint8_t * buffer, uint32_t * size) { 00143 if (!USBDevice::readEP_NB(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE)) 00144 return false; 00145 if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE)) 00146 return false; 00147 return true; 00148 } 00149 00150 00151 const uint8_t * USBCDC::deviceDesc() { 00152 uint8_t deviceDescriptorTemp[] = { 00153 18, // bLength 00154 1, // bDescriptorType 00155 0x10, 0x01, // bcdUSB 00156 2, // bDeviceClass 00157 0, // bDeviceSubClass 00158 0, // bDeviceProtocol 00159 MAX_PACKET_SIZE_EP0, // bMaxPacketSize0 00160 (uint8_t)(LSB(VENDOR_ID)), (uint8_t)(MSB(VENDOR_ID)), // idVendor 00161 (uint8_t)(LSB(PRODUCT_ID)), (uint8_t)(MSB(PRODUCT_ID)),// idProduct 00162 0x00, 0x01, // bcdDevice 00163 1, // iManufacturer 00164 2, // iProduct 00165 3, // iSerialNumber 00166 1 // bNumConfigurations 00167 }; 00168 MBED_ASSERT(sizeof(deviceDescriptorTemp) == sizeof(deviceDescriptor)); 00169 memcpy(deviceDescriptor, deviceDescriptorTemp, sizeof(deviceDescriptor)); 00170 return deviceDescriptor; 00171 } 00172 00173 const uint8_t * USBCDC::stringIinterfaceDesc() { 00174 static const uint8_t stringIinterfaceDescriptor[] = { 00175 0x08, 00176 STRING_DESCRIPTOR, 00177 'C',0,'D',0,'C',0, 00178 }; 00179 return stringIinterfaceDescriptor; 00180 } 00181 00182 const uint8_t * USBCDC::stringIproductDesc() { 00183 static const uint8_t stringIproductDescriptor[] = { 00184 0x16, 00185 STRING_DESCRIPTOR, 00186 'C',0,'D',0,'C',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 00187 }; 00188 return stringIproductDescriptor; 00189 } 00190 00191 00192 #define CONFIG1_DESC_SIZE (9+8+9+5+5+4+5+7+9+7+7) 00193 00194 const uint8_t * USBCDC::configurationDesc() { 00195 static const uint8_t configDescriptor[] = { 00196 // configuration descriptor 00197 9, // bLength 00198 2, // bDescriptorType 00199 LSB(CONFIG1_DESC_SIZE), // wTotalLength 00200 MSB(CONFIG1_DESC_SIZE), 00201 2, // bNumInterfaces 00202 1, // bConfigurationValue 00203 0, // iConfiguration 00204 0x80, // bmAttributes 00205 50, // bMaxPower 00206 00207 // IAD to associate the two CDC interfaces 00208 0x08, // bLength 00209 0x0b, // bDescriptorType 00210 0x00, // bFirstInterface 00211 0x02, // bInterfaceCount 00212 0x02, // bFunctionClass 00213 0x02, // bFunctionSubClass 00214 0, // bFunctionProtocol 00215 0, // iFunction 00216 00217 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 00218 9, // bLength 00219 4, // bDescriptorType 00220 0, // bInterfaceNumber 00221 0, // bAlternateSetting 00222 1, // bNumEndpoints 00223 0x02, // bInterfaceClass 00224 0x02, // bInterfaceSubClass 00225 0x01, // bInterfaceProtocol 00226 0, // iInterface 00227 00228 // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26 00229 5, // bFunctionLength 00230 0x24, // bDescriptorType 00231 0x00, // bDescriptorSubtype 00232 0x10, 0x01, // bcdCDC 00233 00234 // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27 00235 5, // bFunctionLength 00236 0x24, // bDescriptorType 00237 0x01, // bDescriptorSubtype 00238 0x03, // bmCapabilities 00239 1, // bDataInterface 00240 00241 // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28 00242 4, // bFunctionLength 00243 0x24, // bDescriptorType 00244 0x02, // bDescriptorSubtype 00245 0x06, // bmCapabilities 00246 00247 // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33 00248 5, // bFunctionLength 00249 0x24, // bDescriptorType 00250 0x06, // bDescriptorSubtype 00251 0, // bMasterInterface 00252 1, // bSlaveInterface0 00253 00254 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 00255 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00256 ENDPOINT_DESCRIPTOR, // bDescriptorType 00257 PHY_TO_DESC(EPINT_IN), // bEndpointAddress 00258 E_INTERRUPT, // bmAttributes (0x03=intr) 00259 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) 00260 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) 00261 16, // bInterval 00262 00263 00264 00265 00266 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 00267 9, // bLength 00268 4, // bDescriptorType 00269 1, // bInterfaceNumber 00270 0, // bAlternateSetting 00271 2, // bNumEndpoints 00272 0x0A, // bInterfaceClass 00273 0x00, // bInterfaceSubClass 00274 0x00, // bInterfaceProtocol 00275 0, // iInterface 00276 00277 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 00278 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00279 ENDPOINT_DESCRIPTOR, // bDescriptorType 00280 PHY_TO_DESC(EPBULK_IN), // bEndpointAddress 00281 E_BULK, // bmAttributes (0x02=bulk) 00282 LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB) 00283 MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB) 00284 0, // bInterval 00285 00286 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 00287 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00288 ENDPOINT_DESCRIPTOR, // bDescriptorType 00289 PHY_TO_DESC(EPBULK_OUT), // bEndpointAddress 00290 E_BULK, // bmAttributes (0x02=bulk) 00291 LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB) 00292 MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB) 00293 0 // bInterval 00294 }; 00295 return configDescriptor; 00296 }
Generated on Tue Jul 12 2022 12:46:10 by
