USBHost library. NOTE: This library is only officially supported on the LPC1768 platform. For more information, please see the handbook page.
Dependencies: FATFileSystem mbed-rtos
Dependents: BTstack WallbotWii SD to Flash Data Transfer USBHost-MSD_HelloWorld ... more
WANDongleSerialPort.cpp
00001 /* Copyright (c) 2010-2012 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 "USBHostConf.h" 00020 00021 #ifdef USBHOST_3GMODULE 00022 00023 #define __DEBUG__ 0 00024 #ifndef __MODULE__ 00025 #define __MODULE__ "WANDongleSerialPort.cpp" 00026 #endif 00027 00028 #include "dbg.h" 00029 #include <stdint.h> 00030 #include "rtos.h" 00031 00032 #include "WANDongleSerialPort.h" 00033 00034 WANDongleSerialPort::WANDongleSerialPort() : cb_tx_en(false), cb_rx_en(false), listener(NULL) 00035 { 00036 reset(); 00037 } 00038 00039 void WANDongleSerialPort::init(USBHost* pHost) 00040 { 00041 host = pHost; 00042 } 00043 00044 void WANDongleSerialPort::reset() 00045 { 00046 tx_mtx.lock(); 00047 rx_mtx.lock(); 00048 00049 bulk_in = NULL; 00050 bulk_out = NULL; 00051 00052 buf_out_len = 0; 00053 max_out_size = 0; 00054 lock_tx = false; 00055 cb_tx_pending = false; 00056 00057 buf_in_len = 0; 00058 buf_in_read_pos = 0; 00059 lock_rx = false; 00060 cb_rx_pending = false; 00061 00062 tx_mtx.unlock(); 00063 rx_mtx.unlock(); 00064 } 00065 00066 int WANDongleSerialPort::readPacket() 00067 { 00068 USB_DBG("Read packet on %p", this); 00069 rx_mtx.lock(); 00070 if(lock_rx) 00071 { 00072 USB_ERR("Fail"); 00073 rx_mtx.unlock(); 00074 return -1; 00075 } 00076 00077 if( bulk_in == NULL ) 00078 { 00079 USB_WARN("Port is disconnected"); 00080 rx_mtx.unlock(); 00081 return -1; 00082 } 00083 00084 lock_rx = true; //Receiving 00085 rx_mtx.unlock(); 00086 // USB_DBG("readPacket"); 00087 //lock_rx.lock(); 00088 USB_TYPE res = host->bulkRead(dev, (USBEndpoint *)bulk_in, buf_in, ((USBEndpoint *)bulk_in)->getSize(), false); //Queue transfer 00089 if(res != USB_TYPE_PROCESSING) 00090 { 00091 //lock_rx.unlock(); 00092 USB_ERR("host->bulkRead() returned %d", res); 00093 Thread::wait(100); 00094 return -1; 00095 } 00096 return 0; 00097 } 00098 00099 int WANDongleSerialPort::writePacket() 00100 { 00101 tx_mtx.lock(); 00102 if(lock_tx) 00103 { 00104 USB_ERR("Fail"); 00105 tx_mtx.unlock(); 00106 return -1; 00107 } 00108 00109 if( bulk_out == NULL ) 00110 { 00111 USB_WARN("Port is disconnected"); 00112 tx_mtx.unlock(); 00113 return -1; 00114 } 00115 00116 lock_tx = true; //Transmitting 00117 tx_mtx.unlock(); 00118 // USB_DBG("writePacket"); 00119 00120 //lock_tx.lock(); 00121 USB_TYPE res = host->bulkWrite(dev, (USBEndpoint *)bulk_out, buf_out, buf_out_len, false); //Queue transfer 00122 if(res != USB_TYPE_PROCESSING) 00123 { 00124 //lock_tx.unlock(); 00125 USB_ERR("host->bulkWrite() returned %d", res); 00126 Thread::wait(100); 00127 return -1; 00128 } 00129 return 0; 00130 } 00131 00132 int WANDongleSerialPort::putc(int c) 00133 { 00134 tx_mtx.lock(); 00135 if(!lock_tx) 00136 { 00137 if(buf_out_len < max_out_size) 00138 { 00139 buf_out[buf_out_len] = (uint8_t)c; 00140 buf_out_len++; 00141 } 00142 } 00143 else 00144 { 00145 USB_ERR("CAN'T WRITE!"); 00146 } 00147 tx_mtx.unlock(); 00148 return c; 00149 } 00150 00151 int WANDongleSerialPort::getc() 00152 { 00153 rx_mtx.lock(); 00154 int c = 0; 00155 if(!lock_rx) 00156 { 00157 if(buf_in_read_pos < buf_in_len) 00158 { 00159 c = (int)buf_in[buf_in_read_pos]; 00160 buf_in_read_pos++; 00161 } 00162 } 00163 else 00164 { 00165 USB_ERR("CAN'T READ!"); 00166 } 00167 rx_mtx.unlock(); 00168 return c; 00169 } 00170 00171 int WANDongleSerialPort::readable() 00172 { 00173 rx_mtx.lock(); 00174 if (lock_rx) 00175 { 00176 rx_mtx.unlock(); 00177 return 0; 00178 } 00179 00180 /* if( !lock_rx.trylock() ) 00181 { 00182 return 0; 00183 }*/ 00184 int res = buf_in_len - buf_in_read_pos; 00185 //lock_rx.unlock(); 00186 rx_mtx.unlock(); 00187 return res; 00188 } 00189 00190 int WANDongleSerialPort::writeable() 00191 { 00192 tx_mtx.lock(); 00193 if (lock_tx) 00194 { 00195 tx_mtx.unlock(); 00196 return 0; 00197 } 00198 00199 /*if( !lock_tx.trylock() ) 00200 { 00201 return 0; 00202 }*/ 00203 int res = max_out_size - buf_out_len; 00204 tx_mtx.unlock(); 00205 //lock_tx.unlock(); 00206 return res; 00207 } 00208 00209 void WANDongleSerialPort::attach(IUSBHostSerialListener* pListener) 00210 { 00211 if(pListener == NULL) 00212 { 00213 setupIrq(false, RxIrq); 00214 setupIrq(false, TxIrq); 00215 } 00216 listener = pListener; 00217 if(pListener != NULL) 00218 { 00219 setupIrq(true, RxIrq); 00220 setupIrq(true, TxIrq); 00221 } 00222 } 00223 00224 void WANDongleSerialPort::setupIrq(bool en, IrqType irq /*= RxIrq*/) 00225 { 00226 switch(irq) 00227 { 00228 case RxIrq: 00229 rx_mtx.lock(); 00230 cb_rx_en = en; 00231 if(en && cb_rx_pending) 00232 { 00233 cb_rx_pending = false; 00234 rx_mtx.unlock(); 00235 listener->readable(); //Process the interrupt that was raised 00236 } 00237 else 00238 { 00239 rx_mtx.unlock(); 00240 } 00241 break; 00242 case TxIrq: 00243 tx_mtx.lock(); 00244 cb_tx_en = en; 00245 if(en && cb_tx_pending) 00246 { 00247 cb_tx_pending = false; 00248 tx_mtx.unlock(); 00249 listener->writeable(); //Process the interrupt that was raised 00250 } 00251 else 00252 { 00253 tx_mtx.unlock(); 00254 } 00255 break; 00256 } 00257 } 00258 00259 00260 void WANDongleSerialPort::connect( USBDeviceConnected* pDev, USBEndpoint* pInEp, USBEndpoint* pOutEp ) 00261 { 00262 dev = pDev; 00263 bulk_in = pInEp; 00264 bulk_out = pOutEp; 00265 max_out_size = bulk_out->getSize(); 00266 if( max_out_size > WANDONGLE_MAX_OUTEP_SIZE ) 00267 { 00268 max_out_size = WANDONGLE_MAX_OUTEP_SIZE; 00269 } 00270 bulk_in->attach(this, &WANDongleSerialPort::rxHandler); 00271 bulk_out->attach(this, &WANDongleSerialPort::txHandler); 00272 readPacket(); //Start receiving data 00273 } 00274 00275 void WANDongleSerialPort::disconnect( ) 00276 { 00277 reset(); 00278 } 00279 00280 //Private methods 00281 00282 00283 void WANDongleSerialPort::rxHandler() 00284 { 00285 if (((USBEndpoint *) bulk_in)->getState() == USB_TYPE_IDLE) //Success 00286 { 00287 buf_in_read_pos = 0; 00288 buf_in_len = ((USBEndpoint *) bulk_in)->getLengthTransferred(); //Update length 00289 //lock_rx.unlock(); 00290 rx_mtx.lock(); 00291 lock_rx = false; //Transmission complete 00292 if(cb_rx_en) 00293 { 00294 rx_mtx.unlock(); 00295 listener->readable(); //Call handler from the IRQ context 00296 //readPacket() should be called by the handler subsequently once the buffer has been emptied 00297 } 00298 else 00299 { 00300 cb_rx_pending = true; //Queue the callback 00301 rx_mtx.unlock(); 00302 } 00303 00304 } 00305 else //Error, try reading again 00306 { 00307 //lock_rx.unlock(); 00308 USB_DBG("Trying again"); 00309 readPacket(); 00310 } 00311 } 00312 00313 void WANDongleSerialPort::txHandler() 00314 { 00315 if (((USBEndpoint *) bulk_out)->getState() == USB_TYPE_IDLE) //Success 00316 { 00317 tx_mtx.lock(); 00318 buf_out_len = 0; //Reset length 00319 lock_tx = false; //Transmission complete 00320 //lock_tx.unlock(); 00321 if(cb_tx_en) 00322 { 00323 tx_mtx.unlock(); 00324 listener->writeable(); //Call handler from the IRQ context 00325 //writePacket() should be called by the handler subsequently once the buffer has been filled 00326 } 00327 else 00328 { 00329 cb_tx_pending = true; //Queue the callback 00330 tx_mtx.unlock(); 00331 } 00332 } 00333 else //Error, try reading again 00334 { 00335 //lock_tx.unlock(); 00336 writePacket(); 00337 } 00338 } 00339 00340 #endif /* USBHOST_3GMODULE */
Generated on Tue Jul 12 2022 13:32:26 by 1.7.2