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 uint8_t * USBCDC::deviceDesc() { 00148 static uint8_t deviceDescriptor[] = { 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 return deviceDescriptor; 00165 } 00166 00167 uint8_t * USBCDC::stringIinterfaceDesc() { 00168 static uint8_t stringIinterfaceDescriptor[] = { 00169 0x08, 00170 STRING_DESCRIPTOR, 00171 'C',0,'D',0,'C',0, 00172 }; 00173 return stringIinterfaceDescriptor; 00174 } 00175 00176 uint8_t * USBCDC::stringIproductDesc() { 00177 static uint8_t stringIproductDescriptor[] = { 00178 0x16, 00179 STRING_DESCRIPTOR, 00180 'C',0,'D',0,'C',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 00181 }; 00182 return stringIproductDescriptor; 00183 } 00184 00185 00186 #define CONFIG1_DESC_SIZE (9+8+9+5+5+4+5+7+9+7+7) 00187 00188 uint8_t * USBCDC::configurationDesc() { 00189 static uint8_t configDescriptor[] = { 00190 // configuration descriptor 00191 9, // bLength 00192 2, // bDescriptorType 00193 LSB(CONFIG1_DESC_SIZE), // wTotalLength 00194 MSB(CONFIG1_DESC_SIZE), 00195 2, // bNumInterfaces 00196 1, // bConfigurationValue 00197 0, // iConfiguration 00198 0x80, // bmAttributes 00199 50, // bMaxPower 00200 00201 // IAD to associate the two CDC interfaces 00202 0x08, // bLength 00203 0x0b, // bDescriptorType 00204 0x00, // bFirstInterface 00205 0x02, // bInterfaceCount 00206 0x02, // bFunctionClass 00207 0x02, // bFunctionSubClass 00208 0, // bFunctionProtocol 00209 0, // iFunction 00210 00211 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 00212 9, // bLength 00213 4, // bDescriptorType 00214 0, // bInterfaceNumber 00215 0, // bAlternateSetting 00216 1, // bNumEndpoints 00217 0x02, // bInterfaceClass 00218 0x02, // bInterfaceSubClass 00219 0x01, // bInterfaceProtocol 00220 0, // iInterface 00221 00222 // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26 00223 5, // bFunctionLength 00224 0x24, // bDescriptorType 00225 0x00, // bDescriptorSubtype 00226 0x10, 0x01, // bcdCDC 00227 00228 // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27 00229 5, // bFunctionLength 00230 0x24, // bDescriptorType 00231 0x01, // bDescriptorSubtype 00232 0x03, // bmCapabilities 00233 1, // bDataInterface 00234 00235 // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28 00236 4, // bFunctionLength 00237 0x24, // bDescriptorType 00238 0x02, // bDescriptorSubtype 00239 0x06, // bmCapabilities 00240 00241 // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33 00242 5, // bFunctionLength 00243 0x24, // bDescriptorType 00244 0x06, // bDescriptorSubtype 00245 0, // bMasterInterface 00246 1, // bSlaveInterface0 00247 00248 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 00249 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00250 ENDPOINT_DESCRIPTOR, // bDescriptorType 00251 PHY_TO_DESC(EPINT_IN), // bEndpointAddress 00252 E_INTERRUPT, // bmAttributes (0x03=intr) 00253 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) 00254 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) 00255 16, // bInterval 00256 00257 00258 00259 00260 // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 00261 9, // bLength 00262 4, // bDescriptorType 00263 1, // bInterfaceNumber 00264 0, // bAlternateSetting 00265 2, // bNumEndpoints 00266 0x0A, // bInterfaceClass 00267 0x00, // bInterfaceSubClass 00268 0x00, // bInterfaceProtocol 00269 0, // iInterface 00270 00271 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 00272 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00273 ENDPOINT_DESCRIPTOR, // bDescriptorType 00274 PHY_TO_DESC(EPBULK_IN), // bEndpointAddress 00275 E_BULK, // bmAttributes (0x02=bulk) 00276 LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB) 00277 MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB) 00278 0, // bInterval 00279 00280 // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 00281 ENDPOINT_DESCRIPTOR_LENGTH, // bLength 00282 ENDPOINT_DESCRIPTOR, // bDescriptorType 00283 PHY_TO_DESC(EPBULK_OUT), // bEndpointAddress 00284 E_BULK, // bmAttributes (0x02=bulk) 00285 LSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (LSB) 00286 MSB(MAX_PACKET_SIZE_EPBULK),// wMaxPacketSize (MSB) 00287 0 // bInterval 00288 }; 00289 return configDescriptor; 00290 }
Generated on Thu Jul 14 2022 14:36:24 by
