Support Isochronous transfer additionally
Dependents: USBHostC270_example_GR-PEACH USBHostDac_example USBHostDac_Audio_in_out
Fork of USBHost_custom 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 } 00034 00035 void USBHostSerial::disconnect(void) 00036 { 00037 ports_found = 0; 00038 dev = NULL; 00039 } 00040 00041 bool USBHostSerial::connect() { 00042 00043 if (dev) { 00044 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { 00045 USBDeviceConnected* d = host->getDevice(i); 00046 if (dev == d) 00047 return true; 00048 } 00049 disconnect(); 00050 } 00051 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { 00052 USBDeviceConnected* d = host->getDevice(i); 00053 if (d != NULL) { 00054 00055 USB_DBG("Trying to connect serial device \r\n"); 00056 if(host->enumerate(d, this)) 00057 break; 00058 00059 USBEndpoint* bulk_in = d->getEndpoint(port_intf, BULK_ENDPOINT, IN); 00060 USBEndpoint* bulk_out = d->getEndpoint(port_intf, BULK_ENDPOINT, OUT); 00061 if (bulk_in && bulk_out) 00062 { 00063 USBHostSerialPort::connect(host,d,port_intf,bulk_in, bulk_out); 00064 dev = d; 00065 } 00066 } 00067 } 00068 return dev != NULL; 00069 } 00070 00071 /*virtual*/ void USBHostSerial::setVidPid(uint16_t vid, uint16_t pid) 00072 { 00073 // we don't check VID/PID for MSD driver 00074 } 00075 00076 /*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 00077 { 00078 if (!ports_found && 00079 CHECK_INTERFACE(intf_class, intf_subclass, intf_protocol)) { 00080 port_intf = intf_nb; 00081 ports_found = true; 00082 return true; 00083 } 00084 return false; 00085 } 00086 00087 /*virtual*/ bool USBHostSerial::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used 00088 { 00089 if (ports_found && (intf_nb == port_intf)) { 00090 if (type == BULK_ENDPOINT) 00091 return true; 00092 } 00093 return false; 00094 } 00095 00096 #else // (USBHOST_SERIAL > 1) 00097 00098 //------------------------------------------------------------------------------ 00099 00100 USBHostMultiSerial::USBHostMultiSerial() 00101 { 00102 host = USBHost::getHostInst(); 00103 dev = NULL; 00104 memset(ports, NULL, sizeof(ports)); 00105 ports_found = 0; 00106 } 00107 00108 USBHostMultiSerial::~USBHostMultiSerial() 00109 { 00110 disconnect(); 00111 } 00112 00113 void USBHostMultiSerial::disconnect(void) 00114 { 00115 for (int port = 0; port < USBHOST_SERIAL; port ++) 00116 { 00117 if (ports[port]) 00118 { 00119 delete ports[port]; 00120 ports[port] = NULL; 00121 } 00122 } 00123 ports_found = 0; 00124 dev = NULL; 00125 } 00126 00127 bool USBHostMultiSerial::connect() { 00128 00129 if (dev) 00130 { 00131 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) 00132 { 00133 USBDeviceConnected* d = host->getDevice(i); 00134 if (dev == d) 00135 return true; 00136 } 00137 disconnect(); 00138 } 00139 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) 00140 { 00141 USBDeviceConnected* d = host->getDevice(i); 00142 if (d != NULL) { 00143 00144 USB_DBG("Trying to connect serial device \r\n"); 00145 if(host->enumerate(d, this)) 00146 break; 00147 00148 for (int port = 0; port < ports_found; port ++) 00149 { 00150 USBEndpoint* bulk_in = d->getEndpoint(port_intf[port], BULK_ENDPOINT, IN); 00151 USBEndpoint* bulk_out = d->getEndpoint(port_intf[port], BULK_ENDPOINT, OUT); 00152 if (bulk_in && bulk_out) 00153 { 00154 ports[port] = new USBHostSerialPort(); 00155 if (ports[port]) 00156 { 00157 ports[port]->connect(host,d,port_intf[port],bulk_in, bulk_out); 00158 dev = d; 00159 } 00160 } 00161 } 00162 } 00163 } 00164 return dev != NULL; 00165 } 00166 00167 /*virtual*/ void USBHostMultiSerial::setVidPid(uint16_t vid, uint16_t pid) 00168 { 00169 // we don't check VID/PID for MSD driver 00170 } 00171 00172 /*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 00173 { 00174 if ((ports_found < USBHOST_SERIAL) && 00175 CHECK_INTERFACE(intf_class, intf_subclass, intf_protocol)) { 00176 port_intf[ports_found++] = intf_nb; 00177 return true; 00178 } 00179 return false; 00180 } 00181 00182 /*virtual*/ bool USBHostMultiSerial::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used 00183 { 00184 if ((ports_found > 0) && (intf_nb == port_intf[ports_found-1])) { 00185 if (type == BULK_ENDPOINT) 00186 return true; 00187 } 00188 return false; 00189 } 00190 00191 #endif 00192 00193 //------------------------------------------------------------------------------ 00194 00195 #define SET_LINE_CODING 0x20 00196 00197 USBHostSerialPort::USBHostSerialPort() 00198 { 00199 p_circ_buf = new CircBufferHostSerial<uint8_t, (1024 * 32)>; 00200 init(); 00201 } 00202 00203 USBHostSerialPort::~USBHostSerialPort() { 00204 delete p_circ_buf; 00205 } 00206 00207 void USBHostSerialPort::init(void) 00208 { 00209 dev_connected = false; 00210 host = NULL; 00211 dev = NULL; 00212 serial_intf = 0; 00213 size_bulk_in = 0; 00214 size_bulk_out = 0; 00215 bulk_in = NULL; 00216 bulk_out = NULL; 00217 line_coding.baudrate = 9600; 00218 line_coding.data_bits = 8; 00219 line_coding.parity = None; 00220 line_coding.stop_bits = 1; 00221 p_circ_buf->flush(); 00222 } 00223 00224 void USBHostSerialPort::connect(USBHost* _host, USBDeviceConnected * _dev, 00225 uint8_t _serial_intf, USBEndpoint* _bulk_in, USBEndpoint* _bulk_out) 00226 { 00227 host = _host; 00228 dev = _dev; 00229 serial_intf = _serial_intf; 00230 bulk_in = _bulk_in; 00231 bulk_out = _bulk_out; 00232 00233 USB_INFO("New Serial device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, serial_intf); 00234 dev->setName("Serial", serial_intf); 00235 host->registerDriver(dev, serial_intf, this, &USBHostSerialPort::init); 00236 baud(9600); 00237 size_bulk_in = bulk_in->getSize(); 00238 size_bulk_out = bulk_out->getSize(); 00239 bulk_in->attach(this, &USBHostSerialPort::rxHandler); 00240 bulk_out->attach(this, &USBHostSerialPort::txHandler); 00241 host->bulkRead(dev, bulk_in, buf, size_bulk_in, false); 00242 dev_connected = true; 00243 } 00244 00245 bool USBHostSerialPort::connected() { 00246 return dev_connected; 00247 } 00248 00249 void USBHostSerialPort::rxHandler() { 00250 if (bulk_in) { 00251 int len = bulk_in->getLengthTransferred(); 00252 if (bulk_in->getState() == USB_TYPE_IDLE) { 00253 for (int i = 0; i < len; i++) { 00254 while (p_circ_buf->isFull()) { 00255 Thread::wait(1); 00256 } 00257 p_circ_buf->queue(buf[i]); 00258 } 00259 rx.call(); 00260 host->bulkRead(dev, bulk_in, buf, size_bulk_in, false); 00261 } 00262 } 00263 } 00264 00265 void USBHostSerialPort::txHandler() { 00266 if (bulk_out) { 00267 if (bulk_out->getState() == USB_TYPE_IDLE) { 00268 tx.call(); 00269 } 00270 } 00271 } 00272 00273 int USBHostSerialPort::_putc(int c) { 00274 if (bulk_out) { 00275 if (host->bulkWrite(dev, bulk_out, (uint8_t *)&c, 1) == USB_TYPE_OK) { 00276 return 1; 00277 } 00278 } 00279 return -1; 00280 } 00281 00282 void USBHostSerialPort::baud(int baudrate) { 00283 line_coding.baudrate = baudrate; 00284 format(line_coding.data_bits, (Parity)line_coding.parity, line_coding.stop_bits); 00285 } 00286 00287 void USBHostSerialPort::format(int bits, Parity parity, int stop_bits) { 00288 line_coding.data_bits = bits; 00289 line_coding.parity = parity; 00290 line_coding.stop_bits = (stop_bits == 1) ? 0 : 2; 00291 00292 // set line coding 00293 host->controlWrite( dev, 00294 USB_RECIPIENT_INTERFACE | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS, 00295 SET_LINE_CODING, 00296 0, serial_intf, (uint8_t *)&line_coding, 7); 00297 } 00298 00299 int USBHostSerialPort::_getc() { 00300 uint8_t c = 0; 00301 if (bulk_in == NULL) { 00302 init(); 00303 return -1; 00304 } 00305 while (p_circ_buf->isEmpty()) { 00306 if (dev_connected == false) { 00307 return -1; 00308 } 00309 Thread::wait(1); 00310 } 00311 p_circ_buf->dequeue(&c); 00312 return c; 00313 } 00314 00315 int USBHostSerialPort::writeBuf(const char* b, int s) { 00316 int i; 00317 int c = 0; 00318 if (bulk_out) { 00319 while (s > 0) { 00320 if (dev_connected == false) { 00321 break; 00322 } 00323 i = (s < size_bulk_out) ? s : size_bulk_out; 00324 if (host->bulkWrite(dev, bulk_out, (uint8_t *)(b+c), i) == USB_TYPE_OK) { 00325 c += i; 00326 s -= i; 00327 } 00328 } 00329 } 00330 return c; 00331 } 00332 00333 int USBHostSerialPort::readBuf(char* b, int s, int timeout) { 00334 int i = 0; 00335 00336 if (bulk_in) { 00337 for (i = 0; i < s; i++) { 00338 while ((p_circ_buf->isEmpty()) && (dev_connected)) { 00339 if (timeout == 0) { 00340 break; 00341 } else { 00342 if (timeout > 0) { 00343 timeout--; 00344 } 00345 Thread::wait(1); 00346 } 00347 } 00348 if (!p_circ_buf->dequeue((uint8_t *)&b[i])) { 00349 break; 00350 } 00351 } 00352 } 00353 return i; 00354 } 00355 00356 uint32_t USBHostSerialPort::available() { 00357 return p_circ_buf->available(); 00358 } 00359 00360 #endif 00361 00362
Generated on Tue Jul 12 2022 18:09:26 by 1.7.2