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 USBHost by
USBHostSerial.cpp
00001 /* mbed USBHost Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "USBHostSerial.h" 00018 00019 #if USBHOST_SERIAL 00020 00021 #include "dbg.h" 00022 00023 #define CHECK_INTERFACE(cls,subcls,proto) \ 00024 (((cls == 0xFF) && (subcls == 0xFF) && (proto == 0xFF)) /* QUALCOM CDC */ || \ 00025 ((cls == SERIAL_CLASS) && (subcls == 0x00) && (proto == 0x00)) /* STANDARD CDC */ ) 00026 00027 #if (USBHOST_SERIAL <= 1) 00028 00029 USBHostSerial::USBHostSerial() 00030 { 00031 host = USBHost::getHostInst(); 00032 ports_found = 0; 00033 dev_connected = false; 00034 } 00035 00036 bool USBHostSerial::connected() 00037 { 00038 return dev_connected; 00039 } 00040 00041 void USBHostSerial::disconnect(void) 00042 { 00043 ports_found = 0; 00044 dev = NULL; 00045 } 00046 00047 bool USBHostSerial::connect() { 00048 00049 if (dev) 00050 { 00051 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) 00052 { 00053 USBDeviceConnected* d = host->getDevice(i); 00054 if (dev == d) 00055 return true; 00056 } 00057 disconnect(); 00058 } 00059 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) 00060 { 00061 USBDeviceConnected* d = host->getDevice(i); 00062 if (d != NULL) { 00063 00064 USB_DBG("Trying to connect serial device \r\n"); 00065 if(host->enumerate(d, this)) 00066 break; 00067 00068 USBEndpoint* bulk_in = d->getEndpoint(port_intf, BULK_ENDPOINT, IN); 00069 USBEndpoint* bulk_out = d->getEndpoint(port_intf, BULK_ENDPOINT, OUT); 00070 if (bulk_in && bulk_out) 00071 { 00072 USBHostSerialPort::connect(host,d,port_intf,bulk_in, bulk_out); 00073 dev = d; 00074 } 00075 } 00076 } 00077 return dev != NULL; 00078 } 00079 00080 /*virtual*/ void USBHostSerial::setVidPid(uint16_t vid, uint16_t pid) 00081 { 00082 // we don't check VID/PID for MSD driver 00083 } 00084 00085 /*virtual*/ bool USBHostSerial::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed 00086 { 00087 if (!ports_found && 00088 CHECK_INTERFACE(intf_class, intf_subclass, intf_protocol)) { 00089 port_intf = intf_nb; 00090 ports_found = true; 00091 return true; 00092 } 00093 return false; 00094 } 00095 00096 /*virtual*/ bool USBHostSerial::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used 00097 { 00098 if (ports_found && (intf_nb == port_intf)) { 00099 if (type == BULK_ENDPOINT) 00100 return true; 00101 } 00102 return false; 00103 } 00104 00105 #else // (USBHOST_SERIAL > 1) 00106 00107 //------------------------------------------------------------------------------ 00108 00109 USBHostMultiSerial::USBHostMultiSerial() 00110 { 00111 host = USBHost::getHostInst(); 00112 dev = NULL; 00113 memset(ports, NULL, sizeof(ports)); 00114 ports_found = 0; 00115 dev_connected = false; 00116 } 00117 00118 USBHostMultiSerial::~USBHostMultiSerial() 00119 { 00120 disconnect(); 00121 } 00122 00123 bool USBHostMultiSerial::connected() 00124 { 00125 return dev_connected; 00126 } 00127 00128 void USBHostMultiSerial::disconnect(void) 00129 { 00130 for (int port = 0; port < USBHOST_SERIAL; port ++) 00131 { 00132 if (ports[port]) 00133 { 00134 delete ports[port]; 00135 ports[port] = NULL; 00136 } 00137 } 00138 ports_found = 0; 00139 dev = NULL; 00140 } 00141 00142 bool USBHostMultiSerial::connect() { 00143 00144 if (dev) 00145 { 00146 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) 00147 { 00148 USBDeviceConnected* d = host->getDevice(i); 00149 if (dev == d) 00150 return true; 00151 } 00152 disconnect(); 00153 } 00154 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) 00155 { 00156 USBDeviceConnected* d = host->getDevice(i); 00157 if (d != NULL) { 00158 00159 USB_DBG("Trying to connect serial device \r\n"); 00160 if(host->enumerate(d, this)) 00161 break; 00162 00163 for (int port = 0; port < ports_found; port ++) 00164 { 00165 USBEndpoint* bulk_in = d->getEndpoint(port_intf[port], BULK_ENDPOINT, IN); 00166 USBEndpoint* bulk_out = d->getEndpoint(port_intf[port], BULK_ENDPOINT, OUT); 00167 if (bulk_in && bulk_out) 00168 { 00169 ports[port] = new USBHostSerialPort(); 00170 if (ports[port]) 00171 { 00172 ports[port]->connect(host,d,port_intf[port],bulk_in, bulk_out); 00173 dev = d; 00174 } 00175 } 00176 } 00177 } 00178 } 00179 return dev != NULL; 00180 } 00181 00182 /*virtual*/ void USBHostMultiSerial::setVidPid(uint16_t vid, uint16_t pid) 00183 { 00184 // we don't check VID/PID for MSD driver 00185 } 00186 00187 /*virtual*/ bool USBHostMultiSerial::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed 00188 { 00189 if ((ports_found < USBHOST_SERIAL) && 00190 CHECK_INTERFACE(intf_class, intf_subclass, intf_protocol)) { 00191 port_intf[ports_found++] = intf_nb; 00192 return true; 00193 } 00194 return false; 00195 } 00196 00197 /*virtual*/ bool USBHostMultiSerial::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used 00198 { 00199 if ((ports_found > 0) && (intf_nb == port_intf[ports_found-1])) { 00200 if (type == BULK_ENDPOINT) 00201 return true; 00202 } 00203 return false; 00204 } 00205 00206 #endif 00207 00208 //------------------------------------------------------------------------------ 00209 00210 #define SET_LINE_CODING 0x20 00211 00212 USBHostSerialPort::USBHostSerialPort(): circ_buf() 00213 { 00214 init(); 00215 } 00216 00217 void USBHostSerialPort::init(void) 00218 { 00219 host = NULL; 00220 dev = NULL; 00221 serial_intf = NULL; 00222 size_bulk_in = 0; 00223 size_bulk_out = 0; 00224 bulk_in = NULL; 00225 bulk_out = NULL; 00226 line_coding.baudrate = 9600; 00227 line_coding.data_bits = 8; 00228 line_coding.parity = None; 00229 line_coding.stop_bits = 1; 00230 circ_buf.flush(); 00231 } 00232 00233 void USBHostSerialPort::connect(USBHost* _host, USBDeviceConnected * _dev, 00234 uint8_t _serial_intf, USBEndpoint* _bulk_in, USBEndpoint* _bulk_out) 00235 { 00236 host = _host; 00237 dev = _dev; 00238 serial_intf = _serial_intf; 00239 bulk_in = _bulk_in; 00240 bulk_out = _bulk_out; 00241 00242 USB_INFO("New Serial device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, serial_intf); 00243 dev->setName("Serial", serial_intf); 00244 host->registerDriver(dev, serial_intf, this, &USBHostSerialPort::init); 00245 //baud(9600); 00246 size_bulk_in = bulk_in->getSize(); 00247 size_bulk_out = bulk_out->getSize(); 00248 bulk_in->attach(this, &USBHostSerialPort::rxHandler); 00249 bulk_out->attach(this, &USBHostSerialPort::txHandler); 00250 host->bulkRead(dev, bulk_in, buf, size_bulk_in, false); 00251 } 00252 00253 void USBHostSerialPort::rxHandler() { 00254 if (bulk_in) { 00255 int len = bulk_in->getLengthTransferred(); 00256 if (bulk_in->getState() == USB_TYPE_IDLE) { 00257 for (int i = 0; i < len; i++) { 00258 circ_buf.queue(buf[i]); 00259 } 00260 rx.call(); 00261 host->bulkRead(dev, bulk_in, buf, size_bulk_in, false); 00262 } 00263 } 00264 } 00265 00266 void USBHostSerialPort::txHandler() { 00267 if (bulk_out) { 00268 if (bulk_out->getState() == USB_TYPE_IDLE) { 00269 tx.call(); 00270 } 00271 } 00272 } 00273 00274 int USBHostSerialPort::_putc(int c) { 00275 if (bulk_out) { 00276 if (host->bulkWrite(dev, bulk_out, (uint8_t *)&c, 1) == USB_TYPE_OK) { 00277 return 1; 00278 } 00279 } 00280 return -1; 00281 } 00282 00283 void USBHostSerialPort::baud(int baudrate) { 00284 line_coding.baudrate = baudrate; 00285 format(line_coding.data_bits, (Parity)line_coding.parity, line_coding.stop_bits); 00286 } 00287 00288 void USBHostSerialPort::format(int bits, Parity parity, int stop_bits) { 00289 line_coding.data_bits = bits; 00290 line_coding.parity = parity; 00291 line_coding.stop_bits = (stop_bits == 1) ? 0 : 2; 00292 00293 // set line coding 00294 host->controlWrite( dev, 00295 USB_RECIPIENT_INTERFACE | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS, 00296 SET_LINE_CODING, 00297 0, serial_intf, (uint8_t *)&line_coding, 7); 00298 } 00299 00300 int USBHostSerialPort::_getc() { 00301 uint8_t c = 0; 00302 if (bulk_in == NULL) { 00303 init(); 00304 return -1; 00305 } 00306 while (circ_buf.isEmpty()); 00307 circ_buf.dequeue(&c); 00308 return c; 00309 } 00310 00311 int USBHostSerialPort::writeBuf(const char* b, int s) 00312 { 00313 int c = 0; 00314 if (bulk_out) 00315 { 00316 while (c < s) 00317 { 00318 int i = (s < size_bulk_out) ? s : size_bulk_out; 00319 if (host->bulkWrite(dev, bulk_out, (uint8_t *)(b+c), i) == USB_TYPE_OK) 00320 c += i; 00321 } 00322 } 00323 return s; 00324 } 00325 00326 int USBHostSerialPort::readBuf(char* b, int s) 00327 { 00328 int i = 0; 00329 if (bulk_in) 00330 { 00331 for (i = 0; i < s; ) 00332 b[i++] = getc(); 00333 } 00334 return i; 00335 } 00336 00337 uint8_t USBHostSerialPort::available() { 00338 return circ_buf.available(); 00339 } 00340 00341 00342 00343 #endif
Generated on Wed Jul 13 2022 05:47:50 by
1.7.2
