Fork of Smoothie to port to mbed non-LPC targets.
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