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