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