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.
Fork of USBDevice by
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 bool USBCDC::USBCallback_request(void) { 00042 /* Called in ISR context */ 00043 00044 bool success = false; 00045 CONTROL_TRANSFER * transfer = getTransferPtr(); 00046 00047 /* Process class-specific requests */ 00048 00049 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) { 00050 switch (transfer->setup.bRequest) { 00051 case CDC_GET_LINE_CODING: 00052 transfer->remaining = 7; 00053 transfer->ptr = cdc_line_coding; 00054 transfer->direction = DEVICE_TO_HOST; 00055 success = true; 00056 break; 00057 case CDC_SET_LINE_CODING: 00058 transfer->remaining = 7; 00059 transfer->notify = true; 00060 success = true; 00061 break; 00062 case CDC_SET_CONTROL_LINE_STATE: 00063 if (transfer->setup.wValue & CLS_DTR) { 00064 terminal_connected = true; 00065 } else { 00066 terminal_connected = false; 00067 } 00068 success = true; 00069 break; 00070 default: 00071 break; 00072 } 00073 } 00074 00075 return success; 00076 } 00077 00078 void USBCDC::USBCallback_requestCompleted(uint8_t *buf, uint32_t length) { 00079 // Request of setting line coding has 7 bytes 00080 if (length != 7) { 00081 return; 00082 } 00083 00084 CONTROL_TRANSFER * transfer = getTransferPtr(); 00085 00086 /* Process class-specific requests */ 00087 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) { 00088 if (transfer->setup.bRequest == CDC_SET_LINE_CODING) { 00089 if (memcmp(cdc_line_coding, buf, 7)) { 00090 memcpy(cdc_line_coding, buf, 7); 00091 00092 int baud = buf[0] + (buf[1] << 8) 00093 + (buf[2] << 16) + (buf[3] << 24); 00094 int stop = buf[4]; 00095 int bits = buf[6]; 00096 int parity = buf[5]; 00097 00098 lineCodingChanged(baud, bits, parity, stop); 00099 } 00100 } 00101 } 00102 } 00103 00104 // Called in ISR context 00105 // Set configuration. Return false if the 00106 // configuration is not supported. 00107 bool USBCDC::USBCallback_setConfiguration(uint8_t configuration) { 00108 if (configuration != DEFAULT_CONFIGURATION) { 00109 return false; 00110 } 00111 00112 // Configure endpoints > 0 00113 addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT); 00114 addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK); 00115 addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); 00116 00117 // We activate the endpoint to be able to recceive data 00118 readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); 00119 return true; 00120 } 00121 00122 bool USBCDC::send(uint8_t * buffer, uint32_t size) { 00123 return USBDevice::write(EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE); 00124 } 00125 00126 bool USBCDC::readEP(uint8_t * buffer, uint32_t * size) { 00127 if (!USBDevice::readEP(EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE)) 00128 return false; 00129 if (!readStart(EPBULK_OUT, MAX_CDC_REPORT_SIZE)) 00130 return false; 00131 return true; 00132 } 00133 00134 bool USBCDC::readEP_NB(uint8_t * buffer, uint32_t * size) { 00135 if (!USBDevice::readEP_NB(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 00143 uint8_t * USBCDC::deviceDesc() { 00144 static uint8_t deviceDescriptor[] = { 00145 18, // bLength 00146 1, // bDescriptorType 00147 0x10, 0x01, // bcdUSB 00148 2, // bDeviceClass 00149 0, // bDeviceSubClass 00150 0, // bDeviceProtocol 00151 MAX_PACKET_SIZE_EP0, // bMaxPacketSize0 00152 (uint8_t)(LSB(VENDOR_ID)), (uint8_t)(MSB(VENDOR_ID)), // idVendor 00153 (uint8_t)(LSB(PRODUCT_ID)), (uint8_t)(MSB(PRODUCT_ID)),// idProduct 00154 0x00, 0x01, // bcdDevice 00155 1, // iManufacturer 00156 2, // iProduct 00157 3, // iSerialNumber 00158 1 // bNumConfigurations 00159 }; 00160 return deviceDescriptor; 00161 } 00162 00163 uint8_t * USBCDC::stringIinterfaceDesc() { 00164 static uint8_t stringIinterfaceDescriptor[] = { 00165 0x08, 00166 STRING_DESCRIPTOR, 00167 'C',0,'D',0,'C',0, 00168 }; 00169 return stringIinterfaceDescriptor; 00170 } 00171 00172 uint8_t * USBCDC::stringIproductDesc() { 00173 static uint8_t stringIproductDescriptor[] = { 00174 0x16, 00175 STRING_DESCRIPTOR, 00176 'C',0,'D',0,'C',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 00177 }; 00178 return stringIproductDescriptor; 00179 } 00180 00181 00182 #define CONFIG1_DESC_SIZE (9+8+9+5+5+4+5+7+9+7+7) 00183 00184 uint8_t * USBCDC::configurationDesc() { 00185 static uint8_t configDescriptor[] = { 00186 // configuration descriptor 00187 9, // bLength 00188 2, // bDescriptorType 00189 LSB(CONFIG1_DESC_SIZE), // wTotalLength 00190 MSB(CONFIG1_DESC_SIZE), 00191 2, // bNumInterfaces 00192 1, // bConfigurationValue 00193 0, // iConfiguration 00194 0x80, // bmAttributes 00195 50, // bMaxPower 00196 00197 // IAD to associate the two CDC interfaces 00198 0x08, // bLength 00199 0x0b, // bDescriptorType 00200 0x00, // bFirstInterface 00201 0x02, // bInterfaceCount 00202 0x02, // bFunctionClass 00203 0x02, // bFunctionSubClass 00204 0, // bFunctionProtocol 00205 0, // iFunction 00206 00207 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 00208 9, // bLength 00209 4, // bDescriptorType 00210 0, // bInterfaceNumber 00211 0, // bAlternateSetting 00212 1, // bNumEndpoints 00213 0x02, // bInterfaceClass 00214 0x02, // bInterfaceSubClass 00215 0x01, // bInterfaceProtocol 00216 0, // iInterface 00217 00218 // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26 00219 5, // bFunctionLength 00220 0x24, // bDescriptorType 00221 0x00, // bDescriptorSubtype 00222 0x10, 0x01, // bcdCDC 00223 00224 // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27 00225 5, // bFunctionLength 00226 0x24, // bDescriptorType 00227 0x01, // bDescriptorSubtype 00228 0x03, // bmCapabilities 00229 1, // bDataInterface 00230 00231 // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28 00232 4, // bFunctionLength 00233 0x24, // bDescriptorType 00234 0x02, // bDescriptorSubtype 00235 0x06, // bmCapabilities 00236 00237 // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33 00238 5, // bFunctionLength 00239 0x24, // bDescriptorType 00240 0x06, // bDescriptorSubtype 00241 0, // bMasterInterface 00242 1, // bSlaveInterface0 00243 00244 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 00245 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00246 ENDPOINT_DESCRIPTOR, // bDescriptorType 00247 PHY_TO_DESC(EPINT_IN), // bEndpointAddress 00248 E_INTERRUPT, // bmAttributes (0x03=intr) 00249 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) 00250 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) 00251 16, // bInterval 00252 00253 00254 00255 00256 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 00257 9, // bLength 00258 4, // bDescriptorType 00259 1, // bInterfaceNumber 00260 0, // bAlternateSetting 00261 2, // bNumEndpoints 00262 0x0A, // bInterfaceClass 00263 0x00, // bInterfaceSubClass 00264 0x00, // bInterfaceProtocol 00265 0, // iInterface 00266 00267 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 00268 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00269 ENDPOINT_DESCRIPTOR, // bDescriptorType 00270 PHY_TO_DESC(EPBULK_IN), // bEndpointAddress 00271 E_BULK, // bmAttributes (0x02=bulk) 00272 LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB) 00273 MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB) 00274 0, // bInterval 00275 00276 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 00277 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00278 ENDPOINT_DESCRIPTOR, // bDescriptorType 00279 PHY_TO_DESC(EPBULK_OUT), // bEndpointAddress 00280 E_BULK, // bmAttributes (0x02=bulk) 00281 LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB) 00282 MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB) 00283 0 // bInterval 00284 }; 00285 return configDescriptor; 00286 }
Generated on Tue Jul 12 2022 14:14:02 by
