PHS module SMA-01 library. see: https://developer.mbed.org/users/phsfan/notebook/abitusbmodem/
Dependencies: Socket lwip-sys lwip
Dependents: AbitUSBModem_HTTPTest AbitUSBModem_MQTTTest AbitUSBModem_WebsocketTest AbitUSBModem_SMSTest
Fork of VodafoneUSBModem by
USBSerialStream.cpp
00001 /* USBSerialStream.cpp */ 00002 /* Copyright (C) 2012 mbed.org, MIT License 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00005 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00006 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00007 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00008 * furnished to do so, subject to the following conditions: 00009 * 00010 * The above copyright notice and this permission notice shall be included in all copies or 00011 * substantial portions of the Software. 00012 * 00013 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00014 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00015 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00016 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00017 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00018 */ 00019 00020 00021 00022 #define __DEBUG__ 0 00023 #ifndef __MODULE__ 00024 #define __MODULE__ "USBSerialStream.cpp" 00025 #endif 00026 00027 #include "core/fwk.h" 00028 00029 #include <cstring> 00030 00031 #include "USBSerialStream.h" 00032 00033 USBSerialStream::USBSerialStream(IUSBHostSerial& serial) : m_serial(serial), m_serialTxFifoEmpty(true), 00034 m_availableSphre(1), m_spaceSphre(1), m_inBuf() 00035 { 00036 m_availableSphre.wait(); 00037 m_spaceSphre.wait(); 00038 //Attach interrupts 00039 m_serial.attach(this); 00040 } 00041 00042 /*virtual*/ USBSerialStream::~USBSerialStream() 00043 { 00044 m_serial.attach(NULL); 00045 } 00046 00047 //0 for non-blocking (returns immediately), -1 for infinite blocking 00048 /*virtual*/ int USBSerialStream::read(uint8_t* buf, size_t* pLength, size_t maxLength, uint32_t timeout/*=osWaitForever*/) 00049 { 00050 DBG("Trying to read at most %d chars", maxLength); 00051 int ret = waitAvailable(timeout); 00052 if(ret) 00053 { 00054 WARN("Error %d while waiting for incoming data", ret); 00055 return ret; 00056 } 00057 int a = available(); //Prevent macro issues 00058 int readLen = MIN( a, maxLength ); 00059 *pLength = readLen; 00060 00061 00062 setupReadableISR(false); 00063 while(readLen--) 00064 { 00065 m_inBuf.dequeue(buf); 00066 buf++; 00067 } 00068 setupReadableISR(true); 00069 00070 return OK; 00071 } 00072 00073 /*virtual*/ size_t USBSerialStream::available() 00074 { 00075 setupReadableISR(false); //m_inBuf.available() is not reentrant 00076 size_t len = m_inBuf.available(); 00077 setupReadableISR(true); 00078 return len; 00079 } 00080 00081 /*virtual*/ int USBSerialStream::waitAvailable(uint32_t timeout/*=osWaitForever*/) //Wait for data to be available 00082 { 00083 int ret; 00084 if(available()) //Is data already available? 00085 { 00086 while( m_availableSphre.wait(0) > 0 ); //Clear the queue as data is available 00087 return OK; 00088 } 00089 00090 DBG("Waiting for data availability %d ms (-1 is infinite)", timeout); 00091 ret = m_availableSphre.wait(timeout); //Wait for data to arrive or for abort 00092 if(ret <= 0) 00093 { 00094 DBG("Timeout"); 00095 return NET_TIMEOUT; 00096 } 00097 if(!m_inBuf.available()) //Even if abort has been called, return that data is available 00098 { 00099 DBG("Aborted"); 00100 return NET_INTERRUPTED; 00101 } 00102 DBG("Finished waiting"); 00103 while( m_availableSphre.wait(0) > 0 ); //Clear the queue as data is available 00104 return OK; 00105 } 00106 00107 /*virtual*/ int USBSerialStream::abortRead() //Abort current reading (or waiting) operation 00108 { 00109 if( /*!available()*/true ) //If there is data pending, no need to abort 00110 { 00111 m_availableSphre.release(); //Force exiting the waiting state 00112 } 00113 else 00114 { 00115 DBG("Serial is readable"); ; 00116 } 00117 return OK; 00118 } 00119 00120 void USBSerialStream::setupReadableISR(bool en) 00121 { 00122 m_serial.setupIrq(en, IUSBHostSerial::RxIrq); 00123 } 00124 00125 void USBSerialStream::readable() //Callback from m_serial when new data is available 00126 { 00127 while(m_serial.readable()) 00128 { 00129 m_inBuf.queue(m_serial.getc()); 00130 } 00131 m_serial.readPacket(); //Start read of next packet 00132 m_availableSphre.release(); //Force exiting the waiting state 00133 } 00134 00135 00136 00137 //0 for non-blocking (returns immediately), -1 for infinite blocking 00138 /*virtual*/ int USBSerialStream::write(uint8_t* buf, size_t length, uint32_t timeout/*=-1*/) 00139 { 00140 DBG("Trying to write %d chars", length); 00141 do 00142 { 00143 int ret = waitSpace(timeout); 00144 if(ret) 00145 { 00146 WARN("Error %d while waiting for space", ret); 00147 return ret; 00148 } 00149 int s = space(); //Prevent macro issues 00150 int writeLen = MIN( s, length ); 00151 DBG("Writing %d chars", writeLen); 00152 setupWriteableISR(false); 00153 while(writeLen) 00154 { 00155 m_outBuf.queue(*buf); 00156 buf++; 00157 length--; 00158 writeLen--; 00159 } 00160 //If m_serial tx fifo is empty we need to start the packet write 00161 if( m_outBuf.available() && m_serialTxFifoEmpty ) 00162 { 00163 writeable(); 00164 } 00165 setupWriteableISR(true); 00166 } while(length); 00167 DBG("Write successful"); 00168 return OK; 00169 } 00170 00171 /*virtual*/ size_t USBSerialStream::space() 00172 { 00173 setupWriteableISR(false); //m_outBuf.available() is not reentrant 00174 size_t len = CIRCBUF_SIZE - m_outBuf.available(); 00175 setupWriteableISR(true); 00176 return len; 00177 } 00178 00179 /*virtual*/ int USBSerialStream::waitSpace(uint32_t timeout/*=-1*/) //Wait for space to be available 00180 { 00181 int ret; 00182 if(space()) //Is still space already left? 00183 { 00184 while( m_spaceSphre.wait(0) > 0); //Clear the queue as space is available 00185 return OK; 00186 } 00187 00188 DBG("Waiting for data space %d ms (-1 is infinite)", timeout); 00189 ret = m_spaceSphre.wait(timeout); //Wait for space to be made or for abort 00190 if(ret <= 0) 00191 { 00192 DBG("Timeout"); 00193 return NET_TIMEOUT; 00194 } 00195 if(!space()) //Even if abort has been called, return that space is available 00196 { 00197 DBG("Aborted"); 00198 return NET_INTERRUPTED; 00199 } 00200 while( m_spaceSphre.wait(0) > 0); //Clear the queue as space is available 00201 return OK; 00202 } 00203 00204 /*virtual*/ int USBSerialStream::abortWrite() //Abort current writing (or waiting) operation 00205 { 00206 if( !space() ) //If there is space left, no need to abort 00207 { 00208 m_spaceSphre.release(); //Force exiting the waiting state 00209 } 00210 return OK; 00211 } 00212 00213 void USBSerialStream::setupWriteableISR(bool en) 00214 { 00215 m_serial.setupIrq(en, IUSBHostSerial::TxIrq); 00216 } 00217 00218 void USBSerialStream::writeable() //Callback from m_serial when new space is available 00219 { 00220 if(m_outBuf.isEmpty()) 00221 { 00222 m_serialTxFifoEmpty = true; 00223 } 00224 else 00225 { 00226 m_serialTxFifoEmpty = false; 00227 while(m_serial.writeable() && !m_outBuf.isEmpty()) 00228 { 00229 uint8_t c; 00230 m_outBuf.dequeue(&c); 00231 m_serial.putc((char)c); 00232 } 00233 m_serial.writePacket(); //Start packet write 00234 } 00235 if(!m_outBuf.isFull()) 00236 { 00237 m_spaceSphre.release(); //Force exiting the waiting state 00238 } 00239 }
Generated on Wed Jul 13 2022 01:40:22 by 1.7.2