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.
Dependents: KL46Z-lpc81isp lpcterm2
USB_CDC.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 "USB_CDC.h" 00020 00021 #if (DEBUG2 > 3) 00022 #define CDC_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");} while(0); 00023 #define CDC_DBG_HEX(A,B) while(0); 00024 #else 00025 #define CDC_DBG(...) while(0) 00026 #define CDC_DBG_HEX(A,B) while(0) 00027 #endif 00028 00029 static uint8_t cdc_line_coding[7]= {0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08}; 00030 00031 #define CDC_SET_LINE_CODING 0x20 00032 #define CDC_GET_LINE_CODING 0x21 00033 #define CDC_SET_CONTROL_LINE_STATE 0x22 00034 #define CDC_SEND_BREAK 0x23 00035 00036 #define MAX_CDC_REPORT_SIZE MAX_PACKET_SIZE_EPBULK 00037 00038 USB_CDC::USB_CDC(USBDevice* device) : _device(device), _rx_buf(128) 00039 ,settingsChangedCallback(NULL),controlLineStateChangedCallback(NULL),sendBreakCallback(NULL) 00040 { 00041 CDC_DBG("device=%p", device); 00042 00043 terminal_connected = false; 00044 //USBDevice::connect(); 00045 } 00046 00047 void USB_CDC::putc(int c) 00048 { 00049 if (terminal_connected) { 00050 uint8_t buf[1]; 00051 buf[0] = c; 00052 _device->write(CDC_EPBULK_IN, buf, sizeof(buf), MAX_CDC_REPORT_SIZE); 00053 } 00054 } 00055 00056 int USB_CDC::getc() 00057 { 00058 uint8_t c = 0; 00059 while (_rx_buf.isEmpty()); 00060 _rx_buf.dequeue(&c); 00061 return c; 00062 } 00063 00064 int USB_CDC::readable() 00065 { 00066 return _rx_buf.available() > 0 ? 1 : 0; 00067 } 00068 00069 int USB_CDC::writeable() 00070 { 00071 return 1; 00072 } 00073 00074 bool USB_CDC::send(uint8_t * buffer, uint32_t size) { 00075 return _device->write(CDC_EPBULK_IN, buffer, size, MAX_CDC_REPORT_SIZE); 00076 } 00077 00078 bool USB_CDC::readEP(uint8_t * buffer, uint32_t * size) { 00079 if (!_device->readEP(CDC_EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE)) 00080 return false; 00081 if (!_device->readStart(CDC_EPBULK_OUT, MAX_CDC_REPORT_SIZE)) 00082 return false; 00083 return true; 00084 } 00085 00086 bool USB_CDC::readEP_NB(uint8_t * buffer, uint32_t * size) { 00087 if (!_device->readEP_NB(CDC_EPBULK_OUT, buffer, size, MAX_CDC_REPORT_SIZE)) 00088 return false; 00089 if (!_device->readStart(CDC_EPBULK_OUT, MAX_CDC_REPORT_SIZE)) 00090 return false; 00091 return true; 00092 } 00093 00094 bool USB_CDC::Request_callback(CONTROL_TRANSFER* transfer) 00095 { 00096 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) { 00097 switch (transfer->setup.bRequest) { 00098 case CDC_SET_LINE_CODING: // 0x20 00099 transfer->remaining = 7; 00100 transfer->notify = true; 00101 terminal_connected = true; 00102 return true; 00103 00104 case CDC_GET_LINE_CODING: // x021 00105 transfer->remaining = 7; 00106 transfer->ptr = cdc_line_coding; 00107 transfer->direction = DEVICE_TO_HOST; 00108 return true; 00109 00110 case CDC_SET_CONTROL_LINE_STATE: // 0x22 00111 controlLineStateChanged((transfer->setup.wValue>>1) & 1, (transfer->setup.wValue) & 1); 00112 terminal_connected = false; 00113 return true; 00114 00115 case CDC_SEND_BREAK: // 0x23 00116 sendBreak(transfer->setup.wValue); 00117 return true; 00118 } 00119 } 00120 return false; 00121 } 00122 00123 bool USB_CDC::RequestCompleted_callback(CONTROL_TRANSFER* transfer, uint8_t* buf, int length) 00124 { 00125 CDC_DBG("transer=%p", transfer); 00126 if (transfer->setup.bmRequestType.Type == CLASS_TYPE) { 00127 if (transfer->setup.bRequest == CDC_SET_LINE_CODING) { 00128 if (memcmp(cdc_line_coding, buf, 7)) { 00129 memcpy(cdc_line_coding, buf, 7); 00130 00131 int baud = buf[0] + (buf[1] << 8) 00132 + (buf[2] << 16) + (buf[3] << 24); 00133 int stop = (buf[4] == 0) ? 1 : 2; 00134 int bits = buf[6]; 00135 int parity = buf[5]; 00136 lineCodingChanged(baud, bits, parity, stop); 00137 return true; 00138 } 00139 } 00140 } 00141 CDC_DBG_HEX((uint8_t*)transfer, sizeof(CONTROL_TRANSFER)); 00142 return false; 00143 } 00144 00145 bool USB_CDC::EPBULK_OUT_callback() // virtual COM to target 00146 { 00147 uint8_t buf[MAX_CDC_REPORT_SIZE]; 00148 uint32_t size = 0; 00149 //we read the packet received and put it on the circular buffer 00150 _device->readEP(CDC_EPBULK_OUT, buf, &size, MAX_CDC_REPORT_SIZE); 00151 CDC_DBG("size=%d", size); 00152 for(int i = 0; i < size; i++) { 00153 _rx_buf.queue(buf[i]); 00154 } 00155 00156 // We reactivate the endpoint to receive next characters 00157 _device->readStart(CDC_EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); 00158 return true; 00159 } 00160 00161 void USB_CDC::lineCodingChanged(int baud, int bits, int parity, int stop) 00162 { 00163 CDC_DBG("baud=%d,bits=%d,parity=%d,stop=%d", baud,bits, parity, stop); 00164 if (settingsChangedCallback) { 00165 settingsChangedCallback(baud, bits, parity, stop); 00166 } 00167 } 00168 00169 void USB_CDC::controlLineStateChanged(int rts, int dtr) 00170 { 00171 CDC_DBG("rts=%d,dtr=%d", rts, dtr); 00172 if (controlLineStateChangedCallback) { 00173 controlLineStateChangedCallback(rts, dtr); 00174 } 00175 } 00176 00177 void USB_CDC::sendBreak(uint16_t duration) 00178 { 00179 CDC_DBG("duration=%u", duration) 00180 if (sendBreakCallback) { 00181 sendBreakCallback(duration); 00182 } 00183 } 00184
Generated on Tue Jul 12 2022 19:39:32 by
1.7.2