test public

Dependencies:   HttpServer_snapshot_mbed-os

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers WANDongleSerialPort.cpp Source File

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 */