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 gr-peach-opencv-project-sd-card 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 14:47:49 by
1.7.2
