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 Smoothie 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 <cstdint> 00020 #include <cstdio> 00021 #include <cstring> 00022 00023 #include "USBCDC.h" 00024 00025 // static uint8_t cdc_line_coding[7]= {0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08}; 00026 00027 #define iprintf(...) do { } while (0) 00028 00029 // #define DEFAULT_CONFIGURATION (1) 00030 00031 // #define CDC_SET_LINE_CODING 0x20 00032 // #define CDC_GET_LINE_CODING 0x21 00033 // #define CDC_SET_CONTROL_LINE_STATE 0x22 00034 00035 // #define MAX_CDC_REPORT_SIZE MAX_PACKET_SIZE_EPBULK 00036 00037 USBCDC::USBCDC(USB *u) { 00038 usb = u; 00039 00040 CDC_iad = { 00041 DL_INTERFACE_ASSOCIATION, 00042 DT_INTERFACE_ASSOCIATION, 00043 0, // bFirstInterface - filled out later 00044 2, // bInterfaceCount - contiguous interfaces associated with this function 00045 UC_COMM, // bFunctionClass 00046 USB_CDC_SUBCLASS_ACM, // bFunctionSubClass 00047 USB_CDC_PROTOCOL_ITU_V250, // bFunctionProtocol 00048 0, // iFunction 00049 }; 00050 CDC_if = { 00051 DL_INTERFACE, // bLength 00052 DT_INTERFACE, // bDescType 00053 0, // bInterfaceNumber: filled out during addInterface() 00054 0, // bAlternateSetting 00055 1, // bNumEndpoints 00056 UC_COMM, // bInterfaceClass 00057 USB_CDC_SUBCLASS_ACM, // bInterfaceSubClass 00058 USB_CDC_PROTOCOL_ITU_V250, // bInterfaceProtocol 00059 0, // iInterface 00060 0, 0, 0, // dummy padding 00061 this, // callback 00062 }; 00063 CDC_intep = { 00064 DL_ENDPOINT, // bLength 00065 DT_ENDPOINT, // bDescType 00066 EP_DIR_IN, // bEndpointAddress: we provide direction, address is filled in by addEndpoint() 00067 EA_INTERRUPT, // bmAttributes 00068 8, // wMaxPacketSize 00069 16, // bInterval 00070 0, // dummy padding 00071 this, // endpoint callback 00072 }; 00073 CDC_header = { 00074 USB_CDC_LENGTH_HEADER, // bLength 00075 DT_CDC_DESCRIPTOR, // bDescType 00076 USB_CDC_SUBTYPE_HEADER, // bDescSubType 00077 0x0110, // bcdCDC 00078 }; 00079 CDC_callmgmt = { 00080 USB_CDC_LENGTH_CALLMGMT, // bLength 00081 DT_CDC_DESCRIPTOR, // bDescType 00082 USB_CDC_SUBTYPE_CALL_MANAGEMENT, // bDescSubType 00083 USB_CDC_CALLMGMT_CAP_CALLMGMT | USB_CDC_CALLMGMT_CAP_DATAINTF, // bmCapabilities 00084 0, // bDataInterface: filled in later 00085 }; 00086 CDC_acm = { 00087 USB_CDC_LENGTH_ACM, // bLength 00088 DT_CDC_DESCRIPTOR, // bDescType 00089 USB_CDC_SUBTYPE_ACM, // bDescSubType 00090 USB_CDC_ACM_CAP_LINE | USB_CDC_ACM_CAP_BRK, // bmCapabilities 00091 }; 00092 CDC_union = { 00093 USB_CDC_LENGTH_UNION, // bLength 00094 DT_CDC_DESCRIPTOR, // bDescType 00095 USB_CDC_SUBTYPE_UNION, // bDescSubType 00096 0, // bMasterInterface 00097 0, // bSlaveInterface0 00098 }; 00099 CDC_slaveif = { 00100 DL_INTERFACE, // bLength 00101 DT_INTERFACE, // bDescType 00102 0, // bInterfaceNumber: filled out during addInterface() 00103 0, // bAlternateSetting 00104 2, // bNumEndpoints 00105 UC_CDC_DATA, // bInterfaceClass 00106 0, // bInterfaceSubClass 00107 0, // bInterfaceProtocol 00108 0, // iInterface 00109 0, 0, 0, // dummy padding 00110 this, // callback 00111 }; 00112 CDC_BulkIn = { 00113 DL_ENDPOINT, // bLength 00114 DT_ENDPOINT, // bDescType 00115 EP_DIR_IN, // bEndpointAddress: we provide direction, address is filled in by addEndpoint() 00116 EA_BULK, // bmAttributes 00117 MAX_PACKET_SIZE_EPBULK, // wMaxPacketSize 00118 1, // bInterval 00119 0, // dummy padding 00120 this, // endpoint callback 00121 }; 00122 CDC_BulkOut = { 00123 DL_ENDPOINT, // bLength 00124 DT_ENDPOINT, // bDescType 00125 EP_DIR_OUT, // bEndpointAddress: we provide direction, address is filled in by addEndpoint() 00126 EA_BULK, // bmAttributes 00127 MAX_PACKET_SIZE_EPBULK, // wMaxPacketSize 00128 1, // bInterval 00129 0, // dummy padding 00130 this, // endpoint callback 00131 }; 00132 00133 usbdesc_string_l(16) s = usbstring("Smoothie Serial"); 00134 memcpy(&CDC_string, &s, sizeof(CDC_string)); 00135 00136 usb->addDescriptor(&CDC_iad); 00137 uint8_t IfAddr = 00138 usb->addInterface(&CDC_if); 00139 usb->addDescriptor(&CDC_header); 00140 usb->addDescriptor(&CDC_callmgmt); 00141 usb->addDescriptor(&CDC_acm); 00142 usb->addDescriptor(&CDC_union); 00143 usb->addEndpoint(&CDC_intep); 00144 uint8_t slaveIfAddr = 00145 usb->addInterface(&CDC_slaveif); 00146 usb->addEndpoint(&CDC_BulkOut); 00147 usb->addEndpoint(&CDC_BulkIn); 00148 00149 CDC_if.iInterface = usb->addString(&CDC_string); 00150 00151 CDC_iad.bFirstInterface = IfAddr; 00152 CDC_iad.iFunction = CDC_if.iInterface; 00153 CDC_union.bMasterInterface = IfAddr; 00154 CDC_union.bSlaveInterface0 = slaveIfAddr; 00155 CDC_callmgmt.bDataInterface = slaveIfAddr; 00156 00157 cdc_line_coding.dwDTERate = 9600; 00158 cdc_line_coding.bCharFormat = 0; 00159 cdc_line_coding.bParityType = 0; 00160 cdc_line_coding.bDataBits = 8; 00161 } 00162 00163 /* Called in ISR context */ 00164 bool USBCDC::USBEvent_Request(CONTROL_TRANSFER &transfer) { 00165 00166 /* Process class-specific requests */ 00167 00168 if (transfer.setup.bmRequestType.Type == CLASS_TYPE) { 00169 switch (transfer.setup.bRequest) { 00170 case CDC_GET_LINE_CODING: 00171 // iprintf("[CDC]:GET_LINE_ENCODING\n"); 00172 transfer.remaining = 7; 00173 transfer.ptr = (uint8_t *) &cdc_line_coding; 00174 transfer.direction = DEVICE_TO_HOST; 00175 return true; 00176 case CDC_SET_LINE_CODING: 00177 // iprintf("[CDC]:SET_LINE_ENCODING\n"); 00178 transfer.remaining = 7; 00179 transfer.ptr = (uint8_t *) &cdc_line_coding; 00180 transfer.notify = true; 00181 transfer.direction = HOST_TO_DEVICE; 00182 return true; 00183 case CDC_SET_CONTROL_LINE_STATE: 00184 iprintf("[CDC]:SET_CONTROL_LINE_STATE 0x%02X\n", transfer.setup.wValue); 00185 if (transfer.setup.wValue & CDC_CLS_DTR) 00186 on_attach(); 00187 else 00188 on_detach(); 00189 return true; 00190 default: 00191 break; 00192 } 00193 } 00194 00195 return false; 00196 } 00197 00198 bool USBCDC::USBEvent_RequestComplete(CONTROL_TRANSFER &transfer, uint8_t* buffer, uint32_t length) 00199 { 00200 if (transfer.setup.bmRequestType.Type == CLASS_TYPE) 00201 { 00202 switch (transfer.setup.bRequest) 00203 { 00204 case CDC_SET_LINE_CODING: 00205 { 00206 iprintf("Got Line Coding:"); 00207 iprintf(" BAUD: %lu ", cdc_line_coding.dwDTERate); 00208 iprintf(" STOP: "); 00209 if (cdc_line_coding.bCharFormat == 0) iprintf("1"); 00210 else if (cdc_line_coding.bCharFormat == 1) iprintf("1.5"); 00211 else if (cdc_line_coding.bCharFormat == 2) iprintf("2"); 00212 else iprintf("?"); 00213 iprintf(" PARITY: %d", cdc_line_coding.bParityType); 00214 iprintf(" DATABITS: %d", cdc_line_coding.bDataBits); 00215 00216 iprintf("\n"); 00217 return true; 00218 } 00219 } 00220 } 00221 return false; 00222 } 00223 00224 bool USBCDC::send(uint8_t * buffer, uint32_t size) { 00225 return usb->writeNB(CDC_BulkIn.bEndpointAddress, buffer, size, CDC_BulkIn.wMaxPacketSize); 00226 } 00227 00228 bool USBCDC::readEP(uint8_t * buffer, uint32_t * size) { 00229 // iprintf("USBCDC:readEP 0x%02X\n", CDC_BulkOut.bEndpointAddress); 00230 if (!usb->readEP(CDC_BulkOut.bEndpointAddress, buffer, size, CDC_BulkOut.wMaxPacketSize)) 00231 { 00232 // iprintf("readEP failed\n"); 00233 return false; 00234 } 00235 // iprintf("readEP ok\n"); 00236 if (!usb->readStart(CDC_BulkOut.bEndpointAddress, CDC_BulkOut.wMaxPacketSize)) 00237 { 00238 // iprintf("readStart failed\n"); 00239 return false; 00240 } 00241 // iprintf("readStart ok\n"); 00242 return true; 00243 } 00244 00245 bool USBCDC::readEP_NB(uint8_t * buffer, uint32_t * size) { 00246 if (!usb->readEP_NB(CDC_BulkOut.bEndpointAddress, buffer, size, CDC_BulkOut.wMaxPacketSize)) 00247 return false; 00248 if (!usb->readStart(CDC_BulkOut.bEndpointAddress, CDC_BulkOut.wMaxPacketSize)) 00249 return false; 00250 return true; 00251 } 00252 00253 void USBCDC::on_attach(void) {} 00254 00255 void USBCDC::on_detach(void) {}
Generated on Tue Jul 12 2022 20:09:03 by
1.7.2
