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