1 /* Copyright (c) 2010-2012 mbed.org, MIT License
3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
4 * and associated documentation files (the "Software"), to deal in the Software without
5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
7 * Software is furnished to do so, subject to the following conditions:
9 * The above copyright notice and this permission notice shall be included in all copies or
10 * substantial portions of the Software.
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 #include "USBHostConf.h"
21 #ifdef USBHOST_3GMODULE
25 #define __MODULE__ "WANDongleSerialPort.cpp"
32 #include "WANDongleSerialPort.h"
34 WANDongleSerialPort::WANDongleSerialPort() : cb_tx_en(false), cb_rx_en(false), listener(NULL)
39 void WANDongleSerialPort::init(USBHost* pHost)
44 void WANDongleSerialPort::reset()
55 cb_tx_pending = false;
60 cb_rx_pending = false;
66 int WANDongleSerialPort::readPacket()
68 USB_DBG("Read packet on %p", this);
79 USB_WARN("Port is disconnected");
84 lock_rx = true; //Receiving
86 // USB_DBG("readPacket");
88 USB_TYPE res = host->bulkRead(dev, (USBEndpoint *)bulk_in, buf_in, ((USBEndpoint *)bulk_in)->getSize(), false); //Queue transfer
89 if(res != USB_TYPE_PROCESSING)
92 USB_ERR("host->bulkRead() returned %d", res);
99 int WANDongleSerialPort::writePacket()
109 if( bulk_out == NULL )
111 USB_WARN("Port is disconnected");
116 lock_tx = true; //Transmitting
118 // USB_DBG("writePacket");
121 USB_TYPE res = host->bulkWrite(dev, (USBEndpoint *)bulk_out, buf_out, buf_out_len, false); //Queue transfer
122 if(res != USB_TYPE_PROCESSING)
125 USB_ERR("host->bulkWrite() returned %d", res);
132 int WANDongleSerialPort::putc(int c)
137 if(buf_out_len < max_out_size)
139 buf_out[buf_out_len] = (uint8_t)c;
145 USB_ERR("CAN'T WRITE!");
151 int WANDongleSerialPort::getc()
157 if(buf_in_read_pos < buf_in_len)
159 c = (int)buf_in[buf_in_read_pos];
165 USB_ERR("CAN'T READ!");
171 int WANDongleSerialPort::readable()
180 /* if( !lock_rx.trylock() )
184 int res = buf_in_len - buf_in_read_pos;
190 int WANDongleSerialPort::writeable()
199 /*if( !lock_tx.trylock() )
203 int res = max_out_size - buf_out_len;
209 void WANDongleSerialPort::attach(IUSBHostSerialListener* pListener)
211 if(pListener == NULL)
213 setupIrq(false, RxIrq);
214 setupIrq(false, TxIrq);
216 listener = pListener;
217 if(pListener != NULL)
219 setupIrq(true, RxIrq);
220 setupIrq(true, TxIrq);
224 void WANDongleSerialPort::setupIrq(bool en, IrqType irq /*= RxIrq*/)
231 if(en && cb_rx_pending)
233 cb_rx_pending = false;
235 listener->readable(); //Process the interrupt that was raised
245 if(en && cb_tx_pending)
247 cb_tx_pending = false;
249 listener->writeable(); //Process the interrupt that was raised
260 void WANDongleSerialPort::connect( USBDeviceConnected* pDev, USBEndpoint* pInEp, USBEndpoint* pOutEp )
265 max_out_size = bulk_out->getSize();
266 if( max_out_size > WANDONGLE_MAX_OUTEP_SIZE )
268 max_out_size = WANDONGLE_MAX_OUTEP_SIZE;
270 bulk_in->attach(this, &WANDongleSerialPort::rxHandler);
271 bulk_out->attach(this, &WANDongleSerialPort::txHandler);
272 readPacket(); //Start receiving data
275 void WANDongleSerialPort::disconnect( )
283 void WANDongleSerialPort::rxHandler()
285 if (((USBEndpoint *) bulk_in)->getState() == USB_TYPE_IDLE) //Success
288 buf_in_len = ((USBEndpoint *) bulk_in)->getLengthTransferred(); //Update length
291 lock_rx = false; //Transmission complete
295 listener->readable(); //Call handler from the IRQ context
296 //readPacket() should be called by the handler subsequently once the buffer has been emptied
300 cb_rx_pending = true; //Queue the callback
305 else //Error, try reading again
308 USB_DBG("Trying again");
313 void WANDongleSerialPort::txHandler()
315 if (((USBEndpoint *) bulk_out)->getState() == USB_TYPE_IDLE) //Success
318 buf_out_len = 0; //Reset length
319 lock_tx = false; //Transmission complete
324 listener->writeable(); //Call handler from the IRQ context
325 //writePacket() should be called by the handler subsequently once the buffer has been filled
329 cb_tx_pending = true; //Queue the callback
333 else //Error, try reading again
340 #endif /* USBHOST_3GMODULE */