local fork (temporary)

Dependents:   VodafoneUSBModem_bleedingedge2

Fork of USBHostWANDongle_bleedingedge by Donatien Garnier

Committer:
donatien
Date:
Tue Jul 31 10:37:16 2012 +0000
Revision:
9:c9e9817c398c
Parent:
3:4394986752db
Child:
10:08bce4cd973a
Child:
12:a712bad7a979
Renamed Endpoint->USBEndpoint because it conflicted with the Socket API! Made some weird symbols mixups happen that made everything explode when the first USB endpoint was allocated.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
donatien 9:c9e9817c398c 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
donatien 9:c9e9817c398c 2 *
donatien 9:c9e9817c398c 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
donatien 9:c9e9817c398c 4 * and associated documentation files (the "Software"), to deal in the Software without
donatien 9:c9e9817c398c 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
donatien 9:c9e9817c398c 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
donatien 9:c9e9817c398c 7 * Software is furnished to do so, subject to the following conditions:
donatien 9:c9e9817c398c 8 *
donatien 9:c9e9817c398c 9 * The above copyright notice and this permission notice shall be included in all copies or
donatien 9:c9e9817c398c 10 * substantial portions of the Software.
donatien 9:c9e9817c398c 11 *
donatien 9:c9e9817c398c 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
donatien 9:c9e9817c398c 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
donatien 9:c9e9817c398c 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
donatien 9:c9e9817c398c 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
donatien 9:c9e9817c398c 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
donatien 9:c9e9817c398c 17 */
donatien 9:c9e9817c398c 18
donatien 9:c9e9817c398c 19 #define __DEBUG__ 4 //Maximum verbosity
donatien 9:c9e9817c398c 20 #ifndef __MODULE__
donatien 9:c9e9817c398c 21 #define __MODULE__ "WANDongleSerialPort.cpp"
donatien 9:c9e9817c398c 22 #endif
donatien 9:c9e9817c398c 23
donatien 9:c9e9817c398c 24 #include "dbg.h"
donatien 9:c9e9817c398c 25 #include <cstdint>
donatien 9:c9e9817c398c 26 #include "rtos.h"
donatien 9:c9e9817c398c 27
donatien 9:c9e9817c398c 28 #include "WANDongleSerialPort.h"
donatien 9:c9e9817c398c 29
donatien 9:c9e9817c398c 30 WANDongleSerialPort::WANDongleSerialPort() : cb_tx_en(false), cb_rx_en(false), listener(NULL)
donatien 9:c9e9817c398c 31 {
donatien 9:c9e9817c398c 32 reset();
donatien 9:c9e9817c398c 33 }
donatien 9:c9e9817c398c 34
donatien 9:c9e9817c398c 35 void WANDongleSerialPort::init(USBHost* pHost)
donatien 9:c9e9817c398c 36 {
donatien 9:c9e9817c398c 37 host = pHost;
donatien 9:c9e9817c398c 38 }
donatien 9:c9e9817c398c 39
donatien 9:c9e9817c398c 40 void WANDongleSerialPort::reset()
donatien 9:c9e9817c398c 41 {
donatien 9:c9e9817c398c 42 bulk_in = NULL;
donatien 9:c9e9817c398c 43 bulk_out = NULL;
donatien 9:c9e9817c398c 44
donatien 9:c9e9817c398c 45 buf_out_len = 0;
donatien 9:c9e9817c398c 46 max_out_size = 0;
donatien 9:c9e9817c398c 47 lock_tx = false;
donatien 9:c9e9817c398c 48 cb_tx_pending = false;
donatien 9:c9e9817c398c 49
donatien 9:c9e9817c398c 50 buf_in_len = 0;
donatien 9:c9e9817c398c 51 buf_in_read_pos = 0;
donatien 9:c9e9817c398c 52 lock_rx = false;
donatien 9:c9e9817c398c 53 cb_rx_pending = false;
donatien 9:c9e9817c398c 54 }
donatien 9:c9e9817c398c 55
donatien 9:c9e9817c398c 56 int WANDongleSerialPort::readPacket()
donatien 9:c9e9817c398c 57 {
donatien 9:c9e9817c398c 58 rx_mtx.lock();
donatien 9:c9e9817c398c 59 if(lock_rx)
donatien 9:c9e9817c398c 60 {
donatien 9:c9e9817c398c 61 ERR("Fail");
donatien 9:c9e9817c398c 62 rx_mtx.unlock();
donatien 9:c9e9817c398c 63 return -1;
donatien 9:c9e9817c398c 64 }
donatien 9:c9e9817c398c 65
donatien 9:c9e9817c398c 66 lock_rx = true; //Receiving
donatien 9:c9e9817c398c 67 rx_mtx.unlock();
donatien 9:c9e9817c398c 68 // DBG("readPacket");
donatien 9:c9e9817c398c 69 //lock_rx.lock();
donatien 9:c9e9817c398c 70 host->lock();
donatien 9:c9e9817c398c 71 USB_TYPE res = host->bulkRead(dev, (USBEndpoint *)bulk_in, buf_in, ((USBEndpoint *)bulk_in)->getSize(), false); //Queue transfer
donatien 9:c9e9817c398c 72 if(res != USB_TYPE_PROCESSING)
donatien 9:c9e9817c398c 73 {
donatien 9:c9e9817c398c 74 host->unlock();
donatien 9:c9e9817c398c 75 //lock_rx.unlock();
donatien 9:c9e9817c398c 76 ERR("host->bulkRead() returned %d", res);
donatien 9:c9e9817c398c 77 Thread::wait(100);
donatien 9:c9e9817c398c 78 return -1;
donatien 9:c9e9817c398c 79 }
donatien 9:c9e9817c398c 80 host->unlock();
donatien 9:c9e9817c398c 81 return 0;
donatien 9:c9e9817c398c 82 }
donatien 9:c9e9817c398c 83
donatien 9:c9e9817c398c 84 int WANDongleSerialPort::writePacket()
donatien 9:c9e9817c398c 85 {
donatien 9:c9e9817c398c 86 tx_mtx.lock();
donatien 9:c9e9817c398c 87 if(lock_tx)
donatien 9:c9e9817c398c 88 {
donatien 9:c9e9817c398c 89 ERR("Fail");
donatien 9:c9e9817c398c 90 tx_mtx.unlock();
donatien 9:c9e9817c398c 91 return -1;
donatien 9:c9e9817c398c 92 }
donatien 9:c9e9817c398c 93
donatien 9:c9e9817c398c 94 lock_tx = true; //Transmitting
donatien 9:c9e9817c398c 95 tx_mtx.unlock();
donatien 9:c9e9817c398c 96 // DBG("writePacket");
donatien 9:c9e9817c398c 97
donatien 9:c9e9817c398c 98 //lock_tx.lock();
donatien 9:c9e9817c398c 99 host->lock();
donatien 9:c9e9817c398c 100 USB_TYPE res = host->bulkWrite(dev, (USBEndpoint *)bulk_out, buf_out, buf_out_len, false); //Queue transfer
donatien 9:c9e9817c398c 101 if(res != USB_TYPE_PROCESSING)
donatien 9:c9e9817c398c 102 {
donatien 9:c9e9817c398c 103 host->unlock();
donatien 9:c9e9817c398c 104 //lock_tx.unlock();
donatien 9:c9e9817c398c 105 ERR("host->bulkWrite() returned %d", res);
donatien 9:c9e9817c398c 106 Thread::wait(100);
donatien 9:c9e9817c398c 107 return -1;
donatien 9:c9e9817c398c 108 }
donatien 9:c9e9817c398c 109 host->unlock();
donatien 9:c9e9817c398c 110 return 0;
donatien 9:c9e9817c398c 111 }
donatien 9:c9e9817c398c 112
donatien 9:c9e9817c398c 113 int WANDongleSerialPort::putc(int c)
donatien 9:c9e9817c398c 114 {
donatien 9:c9e9817c398c 115 tx_mtx.lock();
donatien 9:c9e9817c398c 116 if(!lock_tx)
donatien 9:c9e9817c398c 117 {
donatien 9:c9e9817c398c 118 if(buf_out_len < max_out_size)
donatien 9:c9e9817c398c 119 {
donatien 9:c9e9817c398c 120 buf_out[buf_out_len] = (uint8_t)c;
donatien 9:c9e9817c398c 121 buf_out_len++;
donatien 9:c9e9817c398c 122 }
donatien 9:c9e9817c398c 123 }
donatien 9:c9e9817c398c 124 else
donatien 9:c9e9817c398c 125 {
donatien 9:c9e9817c398c 126 ERR("CAN'T WRITE!");
donatien 9:c9e9817c398c 127 }
donatien 9:c9e9817c398c 128 tx_mtx.unlock();
donatien 9:c9e9817c398c 129 return c;
donatien 9:c9e9817c398c 130 }
donatien 9:c9e9817c398c 131
donatien 9:c9e9817c398c 132 int WANDongleSerialPort::getc()
donatien 9:c9e9817c398c 133 {
donatien 9:c9e9817c398c 134 rx_mtx.lock();
donatien 9:c9e9817c398c 135 int c = 0;
donatien 9:c9e9817c398c 136 if(!lock_rx)
donatien 9:c9e9817c398c 137 {
donatien 9:c9e9817c398c 138 if(buf_in_read_pos < buf_in_len)
donatien 9:c9e9817c398c 139 {
donatien 9:c9e9817c398c 140 c = (int)buf_in[buf_in_read_pos];
donatien 9:c9e9817c398c 141 buf_in_read_pos++;
donatien 9:c9e9817c398c 142 }
donatien 9:c9e9817c398c 143 }
donatien 9:c9e9817c398c 144 else
donatien 9:c9e9817c398c 145 {
donatien 9:c9e9817c398c 146 ERR("CAN'T READ!");
donatien 9:c9e9817c398c 147 }
donatien 9:c9e9817c398c 148 rx_mtx.unlock();
donatien 9:c9e9817c398c 149 return c;
donatien 9:c9e9817c398c 150 }
donatien 9:c9e9817c398c 151
donatien 9:c9e9817c398c 152 int WANDongleSerialPort::readable()
donatien 9:c9e9817c398c 153 {
donatien 9:c9e9817c398c 154 rx_mtx.lock();
donatien 9:c9e9817c398c 155 if (lock_rx)
donatien 9:c9e9817c398c 156 {
donatien 9:c9e9817c398c 157 rx_mtx.unlock();
donatien 9:c9e9817c398c 158 return 0;
donatien 9:c9e9817c398c 159 }
donatien 9:c9e9817c398c 160
donatien 9:c9e9817c398c 161 /* if( !lock_rx.trylock() )
donatien 9:c9e9817c398c 162 {
donatien 9:c9e9817c398c 163 return 0;
donatien 9:c9e9817c398c 164 }*/
donatien 9:c9e9817c398c 165 int res = buf_in_len - buf_in_read_pos;
donatien 9:c9e9817c398c 166 //lock_rx.unlock();
donatien 9:c9e9817c398c 167 rx_mtx.unlock();
donatien 9:c9e9817c398c 168 return res;
donatien 9:c9e9817c398c 169 }
donatien 9:c9e9817c398c 170
donatien 9:c9e9817c398c 171 int WANDongleSerialPort::writeable()
donatien 9:c9e9817c398c 172 {
donatien 9:c9e9817c398c 173 tx_mtx.lock();
donatien 9:c9e9817c398c 174 if (lock_tx)
donatien 9:c9e9817c398c 175 {
donatien 9:c9e9817c398c 176 tx_mtx.unlock();
donatien 9:c9e9817c398c 177 return 0;
donatien 9:c9e9817c398c 178 }
donatien 9:c9e9817c398c 179
donatien 9:c9e9817c398c 180 /*if( !lock_tx.trylock() )
donatien 9:c9e9817c398c 181 {
donatien 9:c9e9817c398c 182 return 0;
donatien 9:c9e9817c398c 183 }*/
donatien 9:c9e9817c398c 184 int res = max_out_size - buf_out_len;
donatien 9:c9e9817c398c 185 tx_mtx.unlock();
donatien 9:c9e9817c398c 186 //lock_tx.unlock();
donatien 9:c9e9817c398c 187 return res;
donatien 9:c9e9817c398c 188 }
donatien 9:c9e9817c398c 189
donatien 9:c9e9817c398c 190 void WANDongleSerialPort::attach(IUSBHostSerialListener* pListener)
donatien 9:c9e9817c398c 191 {
donatien 9:c9e9817c398c 192 if(pListener == NULL)
donatien 9:c9e9817c398c 193 {
donatien 9:c9e9817c398c 194 setupIrq(false, RxIrq);
donatien 9:c9e9817c398c 195 setupIrq(false, TxIrq);
donatien 9:c9e9817c398c 196 }
donatien 9:c9e9817c398c 197 listener = pListener;
donatien 9:c9e9817c398c 198 if(pListener != NULL)
donatien 9:c9e9817c398c 199 {
donatien 9:c9e9817c398c 200 setupIrq(true, RxIrq);
donatien 9:c9e9817c398c 201 setupIrq(true, TxIrq);
donatien 9:c9e9817c398c 202 }
donatien 9:c9e9817c398c 203 }
donatien 9:c9e9817c398c 204
donatien 9:c9e9817c398c 205 void WANDongleSerialPort::setupIrq(bool en, IrqType irq /*= RxIrq*/)
donatien 9:c9e9817c398c 206 {
donatien 9:c9e9817c398c 207 switch(irq)
donatien 9:c9e9817c398c 208 {
donatien 9:c9e9817c398c 209 case RxIrq:
donatien 9:c9e9817c398c 210 rx_mtx.lock();
donatien 9:c9e9817c398c 211 cb_rx_en = en;
donatien 9:c9e9817c398c 212 if(en && cb_rx_pending)
donatien 9:c9e9817c398c 213 {
donatien 9:c9e9817c398c 214 cb_rx_pending = false;
donatien 9:c9e9817c398c 215 rx_mtx.unlock();
donatien 9:c9e9817c398c 216 listener->readable(); //Process the interrupt that was raised
donatien 9:c9e9817c398c 217 }
donatien 9:c9e9817c398c 218 else
donatien 9:c9e9817c398c 219 {
donatien 9:c9e9817c398c 220 rx_mtx.unlock();
donatien 9:c9e9817c398c 221 }
donatien 9:c9e9817c398c 222 break;
donatien 9:c9e9817c398c 223 case TxIrq:
donatien 9:c9e9817c398c 224 tx_mtx.lock();
donatien 9:c9e9817c398c 225 cb_tx_en = en;
donatien 9:c9e9817c398c 226 if(en && cb_tx_pending)
donatien 9:c9e9817c398c 227 {
donatien 9:c9e9817c398c 228 cb_tx_pending = false;
donatien 9:c9e9817c398c 229 tx_mtx.unlock();
donatien 9:c9e9817c398c 230 listener->writeable(); //Process the interrupt that was raised
donatien 9:c9e9817c398c 231 }
donatien 9:c9e9817c398c 232 else
donatien 9:c9e9817c398c 233 {
donatien 9:c9e9817c398c 234 tx_mtx.unlock();
donatien 9:c9e9817c398c 235 }
donatien 9:c9e9817c398c 236 break;
donatien 9:c9e9817c398c 237 }
donatien 9:c9e9817c398c 238 }
donatien 9:c9e9817c398c 239
donatien 9:c9e9817c398c 240
donatien 9:c9e9817c398c 241 void WANDongleSerialPort::connect( USBDeviceConnected* pDev, USBEndpoint* pInEp, USBEndpoint* pOutEp )
donatien 9:c9e9817c398c 242 {
donatien 9:c9e9817c398c 243 dev = pDev;
donatien 9:c9e9817c398c 244 bulk_in = pInEp;
donatien 9:c9e9817c398c 245 bulk_out = pOutEp;
donatien 9:c9e9817c398c 246 max_out_size = bulk_out->getSize();
donatien 9:c9e9817c398c 247 if( max_out_size > WANDONGLE_MAX_OUTEP_SIZE )
donatien 9:c9e9817c398c 248 {
donatien 9:c9e9817c398c 249 max_out_size = WANDONGLE_MAX_OUTEP_SIZE;
donatien 9:c9e9817c398c 250 }
donatien 9:c9e9817c398c 251 bulk_in->attach(this, &WANDongleSerialPort::rxHandler);
donatien 9:c9e9817c398c 252 bulk_out->attach(this, &WANDongleSerialPort::txHandler);
donatien 9:c9e9817c398c 253 readPacket(); //Start receiving data
donatien 9:c9e9817c398c 254 }
donatien 9:c9e9817c398c 255
donatien 9:c9e9817c398c 256 void WANDongleSerialPort::disconnect( )
donatien 9:c9e9817c398c 257 {
donatien 9:c9e9817c398c 258 reset();
donatien 9:c9e9817c398c 259 }
donatien 9:c9e9817c398c 260
donatien 9:c9e9817c398c 261 //Private methods
donatien 9:c9e9817c398c 262
donatien 9:c9e9817c398c 263
donatien 9:c9e9817c398c 264 void WANDongleSerialPort::rxHandler()
donatien 9:c9e9817c398c 265 {
donatien 9:c9e9817c398c 266 if (((USBEndpoint *) bulk_in)->getState() == USB_TYPE_IDLE) //Success
donatien 9:c9e9817c398c 267 {
donatien 9:c9e9817c398c 268 buf_in_read_pos = 0;
donatien 9:c9e9817c398c 269 buf_in_len = ((USBEndpoint *) bulk_in)->getLengthTransferred(); //Update length
donatien 9:c9e9817c398c 270 //lock_rx.unlock();
donatien 9:c9e9817c398c 271 rx_mtx.lock();
donatien 9:c9e9817c398c 272 lock_rx = false; //Transmission complete
donatien 9:c9e9817c398c 273 if(cb_rx_en)
donatien 9:c9e9817c398c 274 {
donatien 9:c9e9817c398c 275 rx_mtx.unlock();
donatien 9:c9e9817c398c 276 listener->readable(); //Call handler from the IRQ context
donatien 9:c9e9817c398c 277 //readPacket() should be called by the handler subsequently once the buffer has been emptied
donatien 9:c9e9817c398c 278 }
donatien 9:c9e9817c398c 279 else
donatien 9:c9e9817c398c 280 {
donatien 9:c9e9817c398c 281 cb_rx_pending = true; //Queue the callback
donatien 9:c9e9817c398c 282 rx_mtx.unlock();
donatien 9:c9e9817c398c 283 }
donatien 9:c9e9817c398c 284
donatien 9:c9e9817c398c 285 }
donatien 9:c9e9817c398c 286 else //Error, try reading again
donatien 9:c9e9817c398c 287 {
donatien 9:c9e9817c398c 288 //lock_rx.unlock();
donatien 9:c9e9817c398c 289 readPacket();
donatien 9:c9e9817c398c 290 }
donatien 9:c9e9817c398c 291 }
donatien 9:c9e9817c398c 292
donatien 9:c9e9817c398c 293 void WANDongleSerialPort::txHandler()
donatien 9:c9e9817c398c 294 {
donatien 9:c9e9817c398c 295 if (((USBEndpoint *) bulk_out)->getState() == USB_TYPE_IDLE) //Success
donatien 9:c9e9817c398c 296 {
donatien 9:c9e9817c398c 297 tx_mtx.lock();
donatien 9:c9e9817c398c 298 buf_out_len = 0; //Reset length
donatien 9:c9e9817c398c 299 lock_tx = false; //Transmission complete
donatien 9:c9e9817c398c 300 //lock_tx.unlock();
donatien 9:c9e9817c398c 301 if(cb_tx_en)
donatien 9:c9e9817c398c 302 {
donatien 9:c9e9817c398c 303 tx_mtx.unlock();
donatien 9:c9e9817c398c 304 listener->writeable(); //Call handler from the IRQ context
donatien 9:c9e9817c398c 305 //writePacket() should be called by the handler subsequently once the buffer has been filled
donatien 9:c9e9817c398c 306 }
donatien 9:c9e9817c398c 307 else
donatien 9:c9e9817c398c 308 {
donatien 9:c9e9817c398c 309 cb_tx_pending = true; //Queue the callback
donatien 9:c9e9817c398c 310 tx_mtx.unlock();
donatien 9:c9e9817c398c 311 }
donatien 9:c9e9817c398c 312 }
donatien 9:c9e9817c398c 313 else //Error, try reading again
donatien 9:c9e9817c398c 314 {
donatien 9:c9e9817c398c 315 //lock_tx.unlock();
donatien 9:c9e9817c398c 316 writePacket();
donatien 9:c9e9817c398c 317 }
donatien 9:c9e9817c398c 318 }