local fork

Dependencies:   Socket USBHostWANDongle_bleedingedge lwip-sys lwip

Dependents:   Encrypted

Fork of VodafoneUSBModem_bleedingedge by Donatien Garnier

Committer:
ashleymills
Date:
Tue Mar 05 14:54:15 2013 +0000
Revision:
79:897a0de9d668
Parent:
60:6f42a974eea6
Child:
85:eb249c45395e
Added MU509 support

Who changed what in which revision?

UserRevisionLine numberNew contents of line
donatien 0:3b2f052c333b 1 /* USBSerialStream.cpp */
donatien 22:06fb2a93a1f6 2 /* Copyright (C) 2012 mbed.org, MIT License
donatien 22:06fb2a93a1f6 3 *
donatien 22:06fb2a93a1f6 4 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
donatien 22:06fb2a93a1f6 5 * and associated documentation files (the "Software"), to deal in the Software without restriction,
donatien 22:06fb2a93a1f6 6 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
donatien 22:06fb2a93a1f6 7 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
donatien 22:06fb2a93a1f6 8 * furnished to do so, subject to the following conditions:
donatien 22:06fb2a93a1f6 9 *
donatien 22:06fb2a93a1f6 10 * The above copyright notice and this permission notice shall be included in all copies or
donatien 22:06fb2a93a1f6 11 * substantial portions of the Software.
donatien 22:06fb2a93a1f6 12 *
donatien 22:06fb2a93a1f6 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
donatien 22:06fb2a93a1f6 14 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
donatien 22:06fb2a93a1f6 15 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
donatien 22:06fb2a93a1f6 16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
donatien 22:06fb2a93a1f6 17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
donatien 22:06fb2a93a1f6 18 */
donatien 0:3b2f052c333b 19
ashleymills 79:897a0de9d668 20
ashleymills 79:897a0de9d668 21
donatien 59:0bcb8c5216d4 22 #define __DEBUG__ 0
donatien 0:3b2f052c333b 23 #ifndef __MODULE__
donatien 0:3b2f052c333b 24 #define __MODULE__ "USBSerialStream.cpp"
donatien 0:3b2f052c333b 25 #endif
donatien 0:3b2f052c333b 26
donatien 0:3b2f052c333b 27 #include "core/fwk.h"
donatien 0:3b2f052c333b 28
donatien 60:6f42a974eea6 29 #include <cstring>
donatien 0:3b2f052c333b 30
donatien 0:3b2f052c333b 31 #include "USBSerialStream.h"
donatien 0:3b2f052c333b 32
ashleymills 79:897a0de9d668 33 // XXX ashley's debug
ashleymills 79:897a0de9d668 34 void printBuffer(uint8_t* buf, int len, bool readIn) {
ashleymills 79:897a0de9d668 35
ashleymills 79:897a0de9d668 36 if(len<0) {
ashleymills 79:897a0de9d668 37 return;
ashleymills 79:897a0de9d668 38 }
ashleymills 79:897a0de9d668 39
ashleymills 79:897a0de9d668 40 if(readIn) {
ashleymills 79:897a0de9d668 41 printf("Read(%d): '",len);
ashleymills 79:897a0de9d668 42 } else {
ashleymills 79:897a0de9d668 43 printf("Writing(%d): '",len);
ashleymills 79:897a0de9d668 44 }
ashleymills 79:897a0de9d668 45 for(int i=0; i<len; i++) {
ashleymills 79:897a0de9d668 46 if(buf[i]==0x0a) {
ashleymills 79:897a0de9d668 47 putchar('N');
ashleymills 79:897a0de9d668 48 } else if(buf[i]==0x0d) {
ashleymills 79:897a0de9d668 49 putchar('R');
ashleymills 79:897a0de9d668 50 } else {
ashleymills 79:897a0de9d668 51 putchar(buf[i]);
ashleymills 79:897a0de9d668 52 }
ashleymills 79:897a0de9d668 53 }
ashleymills 79:897a0de9d668 54 printf("'\r\n");
ashleymills 79:897a0de9d668 55 }
donatien 0:3b2f052c333b 56
donatien 0:3b2f052c333b 57 USBSerialStream::USBSerialStream(IUSBHostSerial& serial) : m_serial(serial), m_serialTxFifoEmpty(true),
donatien 0:3b2f052c333b 58 m_availableSphre(1), m_spaceSphre(1), m_inBuf()
donatien 0:3b2f052c333b 59 {
donatien 0:3b2f052c333b 60 m_availableSphre.wait();
donatien 0:3b2f052c333b 61 m_spaceSphre.wait();
donatien 0:3b2f052c333b 62 //Attach interrupts
donatien 0:3b2f052c333b 63 m_serial.attach(this);
donatien 0:3b2f052c333b 64 }
donatien 0:3b2f052c333b 65
donatien 0:3b2f052c333b 66 /*virtual*/ USBSerialStream::~USBSerialStream()
donatien 0:3b2f052c333b 67 {
donatien 0:3b2f052c333b 68 m_serial.attach(NULL);
donatien 0:3b2f052c333b 69 }
donatien 0:3b2f052c333b 70
donatien 0:3b2f052c333b 71 //0 for non-blocking (returns immediately), -1 for infinite blocking
donatien 0:3b2f052c333b 72 /*virtual*/ int USBSerialStream::read(uint8_t* buf, size_t* pLength, size_t maxLength, uint32_t timeout/*=osWaitForever*/)
donatien 0:3b2f052c333b 73 {
ashleymills 79:897a0de9d668 74 uint8_t *bufPointerCopy = buf;
donatien 0:3b2f052c333b 75 DBG("Trying to read at most %d chars", maxLength);
donatien 0:3b2f052c333b 76 int ret = waitAvailable(timeout);
donatien 0:3b2f052c333b 77 if(ret)
donatien 0:3b2f052c333b 78 {
donatien 0:3b2f052c333b 79 WARN("Error %d while waiting for incoming data", ret);
donatien 0:3b2f052c333b 80 return ret;
donatien 0:3b2f052c333b 81 }
donatien 10:21a6f09d5631 82 int a = available(); //Prevent macro issues
donatien 10:21a6f09d5631 83 int readLen = MIN( a, maxLength );
donatien 0:3b2f052c333b 84 *pLength = readLen;
ashleymills 79:897a0de9d668 85
ashleymills 79:897a0de9d668 86
donatien 0:3b2f052c333b 87 setupReadableISR(false);
donatien 0:3b2f052c333b 88 while(readLen--)
donatien 0:3b2f052c333b 89 {
donatien 0:3b2f052c333b 90 m_inBuf.dequeue(buf);
donatien 0:3b2f052c333b 91 buf++;
donatien 0:3b2f052c333b 92 }
donatien 0:3b2f052c333b 93 setupReadableISR(true);
ashleymills 79:897a0de9d668 94 //printBuffer(bufPointerCopy,*pLength,true); // XXX
ashleymills 79:897a0de9d668 95
donatien 0:3b2f052c333b 96 return OK;
donatien 0:3b2f052c333b 97 }
donatien 0:3b2f052c333b 98
donatien 0:3b2f052c333b 99 /*virtual*/ size_t USBSerialStream::available()
donatien 0:3b2f052c333b 100 {
donatien 0:3b2f052c333b 101 setupReadableISR(false); //m_inBuf.available() is not reentrant
donatien 0:3b2f052c333b 102 size_t len = m_inBuf.available();
donatien 0:3b2f052c333b 103 setupReadableISR(true);
donatien 0:3b2f052c333b 104 return len;
donatien 0:3b2f052c333b 105 }
donatien 0:3b2f052c333b 106
donatien 0:3b2f052c333b 107 /*virtual*/ int USBSerialStream::waitAvailable(uint32_t timeout/*=osWaitForever*/) //Wait for data to be available
donatien 0:3b2f052c333b 108 {
donatien 0:3b2f052c333b 109 int ret;
donatien 0:3b2f052c333b 110 if(available()) //Is data already available?
donatien 0:3b2f052c333b 111 {
donatien 10:21a6f09d5631 112 while( m_availableSphre.wait(0) > 0 ); //Clear the queue as data is available
donatien 0:3b2f052c333b 113 return OK;
donatien 0:3b2f052c333b 114 }
donatien 0:3b2f052c333b 115
donatien 0:3b2f052c333b 116 DBG("Waiting for data availability %d ms (-1 is infinite)", timeout);
donatien 0:3b2f052c333b 117 ret = m_availableSphre.wait(timeout); //Wait for data to arrive or for abort
donatien 0:3b2f052c333b 118 if(ret <= 0)
donatien 0:3b2f052c333b 119 {
donatien 0:3b2f052c333b 120 DBG("Timeout");
donatien 0:3b2f052c333b 121 return NET_TIMEOUT;
donatien 0:3b2f052c333b 122 }
donatien 0:3b2f052c333b 123 if(!m_inBuf.available()) //Even if abort has been called, return that data is available
donatien 0:3b2f052c333b 124 {
donatien 0:3b2f052c333b 125 DBG("Aborted");
donatien 0:3b2f052c333b 126 return NET_INTERRUPTED;
donatien 0:3b2f052c333b 127 }
donatien 0:3b2f052c333b 128 DBG("Finished waiting");
donatien 10:21a6f09d5631 129 while( m_availableSphre.wait(0) > 0 ); //Clear the queue as data is available
donatien 0:3b2f052c333b 130 return OK;
donatien 0:3b2f052c333b 131 }
donatien 0:3b2f052c333b 132
donatien 0:3b2f052c333b 133 /*virtual*/ int USBSerialStream::abortRead() //Abort current reading (or waiting) operation
donatien 0:3b2f052c333b 134 {
donatien 0:3b2f052c333b 135 if( /*!available()*/true ) //If there is data pending, no need to abort
donatien 0:3b2f052c333b 136 {
donatien 0:3b2f052c333b 137 m_availableSphre.release(); //Force exiting the waiting state
donatien 0:3b2f052c333b 138 }
donatien 0:3b2f052c333b 139 else
donatien 0:3b2f052c333b 140 {
donatien 0:3b2f052c333b 141 DBG("Serial is readable"); ;
donatien 0:3b2f052c333b 142 }
donatien 0:3b2f052c333b 143 return OK;
donatien 0:3b2f052c333b 144 }
donatien 0:3b2f052c333b 145
donatien 0:3b2f052c333b 146 void USBSerialStream::setupReadableISR(bool en)
donatien 0:3b2f052c333b 147 {
donatien 0:3b2f052c333b 148 m_serial.setupIrq(en, IUSBHostSerial::RxIrq);
donatien 0:3b2f052c333b 149 }
donatien 0:3b2f052c333b 150
donatien 0:3b2f052c333b 151 void USBSerialStream::readable() //Callback from m_serial when new data is available
donatien 0:3b2f052c333b 152 {
donatien 0:3b2f052c333b 153 while(m_serial.readable())
donatien 0:3b2f052c333b 154 {
donatien 0:3b2f052c333b 155 m_inBuf.queue(m_serial.getc());
donatien 0:3b2f052c333b 156 }
donatien 0:3b2f052c333b 157 m_serial.readPacket(); //Start read of next packet
donatien 0:3b2f052c333b 158 m_availableSphre.release(); //Force exiting the waiting state
donatien 0:3b2f052c333b 159 }
donatien 0:3b2f052c333b 160
ashleymills 79:897a0de9d668 161
ashleymills 79:897a0de9d668 162
donatien 0:3b2f052c333b 163 //0 for non-blocking (returns immediately), -1 for infinite blocking
donatien 0:3b2f052c333b 164 /*virtual*/ int USBSerialStream::write(uint8_t* buf, size_t length, uint32_t timeout/*=-1*/)
donatien 0:3b2f052c333b 165 {
ashleymills 79:897a0de9d668 166 //printBuffer(buf,length,false); // XXX
donatien 0:3b2f052c333b 167 DBG("Trying to write %d chars", length);
donatien 0:3b2f052c333b 168 do
donatien 0:3b2f052c333b 169 {
donatien 0:3b2f052c333b 170 int ret = waitSpace(timeout);
donatien 0:3b2f052c333b 171 if(ret)
donatien 0:3b2f052c333b 172 {
donatien 10:21a6f09d5631 173 WARN("Error %d while waiting for space", ret);
donatien 0:3b2f052c333b 174 return ret;
donatien 0:3b2f052c333b 175 }
donatien 10:21a6f09d5631 176 int s = space(); //Prevent macro issues
donatien 10:21a6f09d5631 177 int writeLen = MIN( s, length );
donatien 10:21a6f09d5631 178 DBG("Writing %d chars", writeLen);
donatien 0:3b2f052c333b 179 setupWriteableISR(false);
donatien 0:3b2f052c333b 180 while(writeLen)
donatien 0:3b2f052c333b 181 {
donatien 0:3b2f052c333b 182 m_outBuf.queue(*buf);
donatien 0:3b2f052c333b 183 buf++;
donatien 0:3b2f052c333b 184 length--;
donatien 0:3b2f052c333b 185 writeLen--;
donatien 0:3b2f052c333b 186 }
donatien 10:21a6f09d5631 187 //If m_serial tx fifo is empty we need to start the packet write
donatien 10:21a6f09d5631 188 if( m_outBuf.available() && m_serialTxFifoEmpty )
donatien 10:21a6f09d5631 189 {
donatien 10:21a6f09d5631 190 writeable();
donatien 10:21a6f09d5631 191 }
donatien 0:3b2f052c333b 192 setupWriteableISR(true);
donatien 0:3b2f052c333b 193 } while(length);
donatien 0:3b2f052c333b 194 DBG("Write successful");
donatien 0:3b2f052c333b 195 return OK;
donatien 0:3b2f052c333b 196 }
donatien 0:3b2f052c333b 197
donatien 0:3b2f052c333b 198 /*virtual*/ size_t USBSerialStream::space()
donatien 0:3b2f052c333b 199 {
donatien 0:3b2f052c333b 200 setupWriteableISR(false); //m_outBuf.available() is not reentrant
donatien 0:3b2f052c333b 201 size_t len = CIRCBUF_SIZE - m_outBuf.available();
donatien 0:3b2f052c333b 202 setupWriteableISR(true);
donatien 0:3b2f052c333b 203 return len;
donatien 0:3b2f052c333b 204 }
donatien 0:3b2f052c333b 205
donatien 0:3b2f052c333b 206 /*virtual*/ int USBSerialStream::waitSpace(uint32_t timeout/*=-1*/) //Wait for space to be available
donatien 0:3b2f052c333b 207 {
donatien 0:3b2f052c333b 208 int ret;
donatien 0:3b2f052c333b 209 if(space()) //Is still space already left?
donatien 0:3b2f052c333b 210 {
donatien 10:21a6f09d5631 211 while( m_spaceSphre.wait(0) > 0); //Clear the queue as space is available
donatien 0:3b2f052c333b 212 return OK;
donatien 0:3b2f052c333b 213 }
donatien 0:3b2f052c333b 214
donatien 0:3b2f052c333b 215 DBG("Waiting for data space %d ms (-1 is infinite)", timeout);
donatien 0:3b2f052c333b 216 ret = m_spaceSphre.wait(timeout); //Wait for space to be made or for abort
donatien 0:3b2f052c333b 217 if(ret <= 0)
donatien 0:3b2f052c333b 218 {
donatien 0:3b2f052c333b 219 DBG("Timeout");
donatien 0:3b2f052c333b 220 return NET_TIMEOUT;
donatien 0:3b2f052c333b 221 }
donatien 0:3b2f052c333b 222 if(!space()) //Even if abort has been called, return that space is available
donatien 0:3b2f052c333b 223 {
donatien 0:3b2f052c333b 224 DBG("Aborted");
donatien 0:3b2f052c333b 225 return NET_INTERRUPTED;
donatien 0:3b2f052c333b 226 }
donatien 10:21a6f09d5631 227 while( m_spaceSphre.wait(0) > 0); //Clear the queue as space is available
donatien 0:3b2f052c333b 228 return OK;
donatien 0:3b2f052c333b 229 }
donatien 0:3b2f052c333b 230
donatien 0:3b2f052c333b 231 /*virtual*/ int USBSerialStream::abortWrite() //Abort current writing (or waiting) operation
donatien 0:3b2f052c333b 232 {
donatien 0:3b2f052c333b 233 if( !space() ) //If there is space left, no need to abort
donatien 0:3b2f052c333b 234 {
donatien 0:3b2f052c333b 235 m_spaceSphre.release(); //Force exiting the waiting state
donatien 0:3b2f052c333b 236 }
donatien 0:3b2f052c333b 237 return OK;
donatien 0:3b2f052c333b 238 }
donatien 0:3b2f052c333b 239
donatien 0:3b2f052c333b 240 void USBSerialStream::setupWriteableISR(bool en)
donatien 0:3b2f052c333b 241 {
donatien 0:3b2f052c333b 242 m_serial.setupIrq(en, IUSBHostSerial::TxIrq);
donatien 0:3b2f052c333b 243 }
donatien 0:3b2f052c333b 244
donatien 0:3b2f052c333b 245 void USBSerialStream::writeable() //Callback from m_serial when new space is available
donatien 0:3b2f052c333b 246 {
donatien 0:3b2f052c333b 247 if(m_outBuf.isEmpty())
donatien 0:3b2f052c333b 248 {
donatien 0:3b2f052c333b 249 m_serialTxFifoEmpty = true;
donatien 0:3b2f052c333b 250 }
donatien 0:3b2f052c333b 251 else
donatien 0:3b2f052c333b 252 {
donatien 0:3b2f052c333b 253 m_serialTxFifoEmpty = false;
donatien 0:3b2f052c333b 254 while(m_serial.writeable() && !m_outBuf.isEmpty())
donatien 0:3b2f052c333b 255 {
donatien 0:3b2f052c333b 256 uint8_t c;
donatien 0:3b2f052c333b 257 m_outBuf.dequeue(&c);
donatien 0:3b2f052c333b 258 m_serial.putc((char)c);
donatien 0:3b2f052c333b 259 }
donatien 0:3b2f052c333b 260 m_serial.writePacket(); //Start packet write
donatien 0:3b2f052c333b 261 }
donatien 10:21a6f09d5631 262 if(!m_outBuf.isFull())
donatien 10:21a6f09d5631 263 {
donatien 10:21a6f09d5631 264 m_spaceSphre.release(); //Force exiting the waiting state
donatien 10:21a6f09d5631 265 }
donatien 0:3b2f052c333b 266 }