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