EthernetNetIf Compatibility.
Dependents: XBeeWiFi_SPI_example
Fork of NetServicesSource by
Revision 4:fd826cad83c0, committed 2010-07-09
- Comitter:
- donatien
- Date:
- Fri Jul 09 14:46:47 2010 +0000
- Parent:
- 3:95e0bc00a1bb
- Child:
- 5:dd63a1e02b1b
- Commit message:
Changed in this revision
--- a/dbg/dbg.h Fri Jun 18 10:38:57 2010 +0000 +++ b/dbg/dbg.h Fri Jul 09 14:46:47 2010 +0000 @@ -47,7 +47,7 @@ #undef DBG #undef DBG_END #undef BREAK -#define DBG DebugStream::debug +#define DBG(...) do{ DebugStream::debug("[%s:%s@%d] ", __FILE__, __FUNCTION__, __LINE__); DebugStream::debug(__VA_ARGS__); } while(0); #define DBG_END DebugStream::release #define BREAK() DebugStream::breakPoint(__FILE__, __LINE__) #endif
--- a/drv/at/ATIf.cpp Fri Jun 18 10:38:57 2010 +0000 +++ b/drv/at/ATIf.cpp Fri Jul 09 14:46:47 2010 +0000 @@ -38,10 +38,13 @@ //#define __DEBUG #include "dbg/dbg.h" -ATIf::ATIf() : SerialBuf(SERIAL_BUF_LEN), m_signalsEnable(false), m_isOpen(false), m_pCurrentSignal(NULL), m_signals() +ATIf::ATIf() : SerialBuf(SERIAL_BUF_LEN), m_isOpen(false)//, m_signalsEnable(false), m_isOpen(false), m_pCurrentSignal(NULL), m_signals() { + DBG("New AT If@%p\n", this); + m_readTimeout = READ_TIMEOUT; //default 1s //tmpBuf = NULL; + m_lineMode = false; m_tmpBuf = new char[TMP_BUF_SIZE]; } @@ -129,23 +132,23 @@ m_lineMode = lineMode; } +#if 0 void ATIf::setSignals(bool signalsEnable) { m_signalsEnable=signalsEnable; } +#endif -#ifdef __LINKING_SCRIPT_BUG_SOLVED__ +#if 0 template<class T> void ATIf::attachSignal( const char* sigName, T* pItem, bool (T::*pMethod)(ATIf*, bool, bool*) ) //Attach Signal ("Unsollicited response code" in Telit_AT_Reference_Guide.pdf) to an handler fn { ATSigHandler sig(sigName, (ATSigHandler::CDummy*)pItem, (bool (ATSigHandler::CDummy::*)(ATIf*, bool, bool*))pMethod); m_signals.push_back(sig); } -#else -//defined in ATIf.h directly -//(it's ugly, I know ;)) #endif +#if 0 void ATIf::detachSignal( const char* sigName ) { list<ATSigHandler>::iterator it; @@ -159,10 +162,11 @@ } } } +#endif ATErr ATIf::open(Serial* pSerial) //Deactivate echo, etc { - DBG("\r\nOpening..."); + DBG("Opening...\n"); m_isOpen = true; //Must be set so that the serial port-related fns work //Setup options // pSerial->baud(BAUDRATE); //FIXME @@ -172,14 +176,15 @@ setTimeout(1000); setLineMode(true); //Line Mode - DBG("\r\nTrmt..."); + DBG("Trmt...\n"); // printf("AT+IPR=%d", BAUDRATE); //FIXME + printf("ATZ"); //Reset wait(.100); printf("ATE"); //Deactivate echo wait(.500); flushBuffer(); - DBG("\r\nATE OK."); + DBG("ATZ ATE...\n"); int len = writeLine("ATV1"); ATErr err = AT_OK; @@ -217,7 +222,7 @@ #if NET_USB_SERIAL ATErr ATIf::open(UsbSerial* pUsbSerial) //Deactivate echo, etc { - DBG("\r\nOpening..."); + DBG("Opening...\n"); m_isOpen = true; //Must be set so that the serial port-related fns work //Setup options SerialBuf::attach(pUsbSerial); @@ -234,7 +239,7 @@ wait(.500); flushBuffer(); - DBG("\r\nATE OK."); + DBG("ATZ ATE...\n"); int len = writeLine("ATQ0 V1 S0=0 &C1 &D2 +FCLASS=0");//writeLine("ATQ0 V1 S0=0 &C1 &D2 +FCLASS=0"); ATErr err = AT_OK; @@ -246,7 +251,7 @@ err = checkOK(); if (err) //No ACK from module { - DBG("\r\nOpening port, error %d.", err); + DBG("Opening port, error %d.\n", err); if(err==AT_TIMEOUT) err = AT_NOANSWER; } @@ -259,8 +264,10 @@ return err; } - DBG("\r\nNo error."); + DBG("No error.\n"); + #if 0//FIXME m_signalsEnable = true; + #endif //FIXME: // m_pSerial->attach<ATIf>(this, &ATIf::onSerialInterrupt); @@ -272,7 +279,7 @@ { SerialBuf::detach(); //Detach serial buf m_isOpen = false; - m_signalsEnable = false; + //m_signalsEnable = false; return AT_OK; } @@ -282,11 +289,12 @@ return AT_CLOSED; int len=0; -// char c; + //char c; while(readable()) { - /* c = */ getc(); - // DBG("\r\n[%c] discarded.", c); + //DBG("Readable\n"); + /*c =*/ getc(); + //DBG("\r\n[%c] discarded.", c); // wait(0.01); len++; } @@ -335,6 +343,7 @@ return AT_OK; } +#if 0 bool ATIf::onRead() { if(!m_signalsEnable) @@ -378,6 +387,7 @@ //m_isOpen = u_isOpen; return handled; } +#endif ATErr ATIf::rawOpen(Serial* pSerial, int baudrate) //Simple open function for similar non-conforming protocols { @@ -706,6 +716,7 @@ return len; } +#if 0 bool ATIf::handleSignal() { bool beg = false; @@ -756,5 +767,6 @@ return result; } +#endif #endif
--- a/drv/at/ATIf.h Fri Jun 18 10:38:57 2010 +0000 +++ b/drv/at/ATIf.h Fri Jul 09 14:46:47 2010 +0000 @@ -52,7 +52,8 @@ ATIf(); virtual ~ATIf(); - + +#if 0 template<class T> //void attachSignal( const char* sigName, T* pItem, bool (T::*pMethod)(ATIf*, bool, bool*) ); //Attach Signal ("Unsollicited response code" in Telit_AT_Reference_Guide.pdf) to an handler fn //Linker bug : Must be defined here :( @@ -62,6 +63,7 @@ m_signals.push_back(sig); } void detachSignal( const char* sigName ); +#endif ATErr open(Serial* pSerial); //Deactivate echo, etc #if NET_USB_SERIAL @@ -73,12 +75,12 @@ int scanf(const char* format, ... ); void setTimeout(int timeout); //used by scanf void setLineMode(bool lineMode); //Switch btw line & raw fns - void setSignals(bool signalsEnable); + //void setSignals(bool signalsEnable); ATErr flushBuffer(); //Discard input buffer ATErr flushLine(int timeout); //Discard input buffer until CRLF is encountered protected: - virtual bool onRead(); //Inherited from SerialBuf, return true if data is incomplete + //virtual bool onRead(); //Inherited from SerialBuf, return true if data is incomplete ATErr rawOpen(Serial* pSerial, int baudrate); //Simple open function for similar non-conforming protocols public: @@ -97,11 +99,12 @@ volatile int m_readTimeout; volatile bool m_lineMode; - bool m_signalsEnable; + //bool m_signalsEnable; bool m_isOpen; char* m_tmpBuf; - + +#if 0 class ATSigHandler { class CDummy; @@ -120,6 +123,7 @@ bool handleSignal(); //Returns true if signal has been handled list<ATSigHandler> m_signals; +#endif };
--- a/drv/gprs/GPRSModem.cpp Fri Jun 18 10:38:57 2010 +0000 +++ b/drv/gprs/GPRSModem.cpp Fri Jul 09 14:46:47 2010 +0000 @@ -34,7 +34,7 @@ GPRSModem::GPRSModem() : ATIf() { - + DBG("New GPRSModem@%p\n", this); } GPRSModem::~GPRSModem() @@ -260,7 +260,7 @@ if(len != 0) //Likely +CME ERROR was returned or NO CARRIER return GPRS_MODEM; - ATIf::setSignals(false); + //ATIf::setSignals(false); DBG("\r\nConnected.\r\n");
--- a/drv/serial/buf/SerialBuf.cpp Fri Jun 18 10:38:57 2010 +0000 +++ b/drv/serial/buf/SerialBuf.cpp Fri Jul 09 14:46:47 2010 +0000 @@ -36,255 +36,200 @@ #define m_pStream( a ) (m_pSerial->a) #endif -SerialBuf::SerialBuf(int len) : m_trmt(false), m_pSerial(NULL), m_intCanReadData(true), m_readMode(false) //Buffer length +//Circular buf + +SerialCircularBuf::SerialCircularBuf(int len) : m_readMode(false) +{ + m_buf = new char[len]; + m_len = len; + m_pReadStart = m_pRead = m_buf; + m_pWrite = m_buf; +} + +SerialCircularBuf::~SerialCircularBuf() +{ + if(m_buf) + delete[] m_buf; +} + +int SerialCircularBuf::room() //Return room available in buf +{ + //return m_len - len() - 1; //-1 is to avoid loop + if ( m_pReadStart > m_pWrite ) + return ( m_pReadStart - m_pWrite - 1 ); + else + return m_len - ( m_pWrite - m_pReadStart ) - 1; +} + +int SerialCircularBuf::len() //Return chars length in buf +{ + if ( m_pWrite >= m_pRead ) + return ( m_pWrite - m_pRead ); + else + return m_len - ( m_pRead - m_pWrite ); // = ( ( m_buf + m_len) - m_pRead ) + ( m_pWrite - m_buf ) +} + +void SerialCircularBuf::write(char c) +{ +#if 0 + if(!room()) + return; +#endif + //WARN: Must call room() before + *m_pWrite = c; + m_pWrite++; + if(m_pWrite>=m_buf+m_len) + m_pWrite=m_buf; +} +char SerialCircularBuf::read() +{ +#if 0 + if(!len()) + return 0; +#endif + //WARN: Must call len() before + char c = *m_pRead; + m_pRead++; + + if(m_pRead>=m_buf+m_len) + m_pRead=m_buf; + + if(!m_readMode) //If readmode=false, trash this char + m_pReadStart=m_pRead; + + return c; +} + +void SerialCircularBuf::setReadMode(bool readMode) //If true, keeps chars in buf when read, false by default +{ + if(m_readMode == true && readMode == false) + { + //Trash bytes that have been read + flushRead(); + } + m_readMode = readMode; +} + +void SerialCircularBuf::flushRead() //Delete chars that have been read & return chars len (only useful with readMode = true) +{ + m_pReadStart = m_pRead; +} + +void SerialCircularBuf::resetRead() //Go back to initial read position & return chars len (only useful with readMode = true) +{ + m_pRead = m_pReadStart; +} + +//SerialBuf + +SerialBuf::SerialBuf(int len) : m_rxBuf(len), m_txBuf(len), m_pSerial(NULL) //Buffer length #if NET_USB_SERIAL , m_pUsbSerial(NULL) #endif { - m_buf = new char[len]; - m_bufLen=len; - m_pRead=m_buf; - m_pReadStart=m_buf; - m_pReadByInt=m_buf; - m_pWrite=m_buf; + DBG("New Serial buf@%p\n", this); } SerialBuf::~SerialBuf() { - delete[] m_buf; + } void SerialBuf::attach(Serial* pSerial) { + DBG("Serial buf@%p in attach\n", this); m_pSerial = pSerial; - m_pSerial->attach<SerialBuf>(this, &SerialBuf::onSerialInterrupt); -// onSerialInterrupt(); //Flush hw buffer into current buf + m_pSerial->attach<SerialBuf>(this, &SerialBuf::onRxInterrupt, Serial::RxIrq); + m_pSerial->attach<SerialBuf>(this, &SerialBuf::onTxInterrupt, Serial::TxIrq); + onRxInterrupt(); //Read data +} + +void SerialBuf::detach() +{ + if(m_pSerial) + { + m_pSerial->attach<SerialBuf>(NULL, NULL, Serial::RxIrq); + m_pSerial->attach<SerialBuf>(NULL, NULL, Serial::TxIrq); + m_pSerial = NULL; + } + #if NET_USB_SERIAL + else if(m_pUsbSerial) + { + m_pUsbSerial->attach<SerialBuf>(NULL, NULL, UsbSerial::RxIrq); + m_pUsbSerial->attach<SerialBuf>(NULL, NULL, UsbSerial::TxIrq); + m_pUsbSerial = NULL; + } + #endif } #if NET_USB_SERIAL void SerialBuf::attach(UsbSerial* pUsbSerial) { m_pUsbSerial = pUsbSerial; - //m_pUsbSerial->attach<SerialBuf>(this, &SerialBuf::onSerialInterrupt); - m_usbTick.attach_us<SerialBuf>(this, &SerialBuf::onSerialInterrupt, 10000); + m_pUsbSerial->attach<SerialBuf>(this, &SerialBuf::onRxInterrupt, UsbSerial::RxIrq); + m_pUsbSerial->attach<SerialBuf>(this, &SerialBuf::onTxInterrupt, UsbSerial::TxIrq); + onRxInterrupt(); //Read data } #endif -void SerialBuf::detach() -{ - if(m_pSerial) - { - m_pSerial->attach(0); - m_pSerial = NULL; - } - #if NET_USB_SERIAL - else if(m_pUsbSerial) - { - m_usbTick.detach(); - m_pUsbSerial = NULL; - } - #endif -} - - -void SerialBuf::onSerialInterrupt() //Callback from m_pSerial -{ - //DBG("\r\n[INT]"); - // Timer tmr; - // tmr.start(); -// static volatile bool incompleteData = true; -// static volatile char* pLastIntReadPos = m_buf; - if(!(m_pStream(readable()))) - { - return; - } - int len=0; - do - { - if(room()>0) - { - len++; -#ifdef __DEBUGVERBOSE - char c = m_pStream(getc()); - DBG("\r\n[%c]",c); - put(c); -#else - put(m_pStream(getc())); -#endif - } - else - { - DBG("\r\nWARN: SerialBuf Overrun"); - m_pStream(getc()); - } - } while(m_pStream(readable())); - // DBG("\r\n[/INT]=*%d*\r\n w len=*%d*",tmr.read_us(),len); - - if( m_intCanReadData ) - { - volatile bool u_readMode = m_readMode; //Save User context on interrupt - volatile bool handled = onRead(); - if(handled) - { - m_pReadByInt = m_pRead; - if(m_pRead==m_pReadStart) - { - //Data has been processed - } - else - { - m_pRead = m_pReadStart; - m_intCanReadData = false; - //Data has to be processed in user space - } - } - setReadMode( u_readMode ); - } - - -#if 0 - if( incompleteData || ( pLastIntReadPos != m_pRead ) ) - { - bool u_readMode = m_readMode; //Save User context on interrupt - incompleteData = onRead(); - if(!incompleteData) - m_pRead = m_pReadStart; - pLastIntReadPos = m_pRead; - - } -#endif - -} - char SerialBuf::getc() { -// DBG("\r\n\[GETC]"); -#if 0 - if(m_trmt) //Was transmitting - { - DBG("\r\n<\r\n"); - m_trmt=false; - } -#endif - char c; - c = get(); - DBG("%c", c); -// DBG("\r\n[/GETC]"); + while(!readable()); + char c = m_rxBuf.read(); return c; } void SerialBuf::putc(char c) { -#if 0 - if(!m_trmt) //Was receiving - { - DBG("\r\n>\r\n"); - m_trmt=true; - } -#endif -// m_pSerial->writeable(); -// while(!m_pSerial->writeable() /*|| m_pSerial->readable()*/) -// { -// wait_us(100); -// DBG("\r\nWait...\r\n"); -// } -/* - NVIC_DisableIRQ(UART1_IRQn); - NVIC_DisableIRQ(UART2_IRQn); - NVIC_DisableIRQ(UART3_IRQn); - */ -// onSerialInterrupt(); - m_pStream(putc(c)); -/* NVIC_EnableIRQ(UART1_IRQn); - NVIC_EnableIRQ(UART2_IRQn); - NVIC_EnableIRQ(UART3_IRQn); - */ - DBG("%c", c); + while(!writeable()); + m_txBuf.write(c); + onTxInterrupt(); } -/* Buffer Stuff */ - bool SerialBuf::readable() { -// onSerialInterrupt(); //Flush hw buffer into current buf - // DBG("\r\nLen=%d",len()); - return (len()>0); + if( !m_rxBuf.len() ) //Fill buf if possible + onRxInterrupt(); + return (bool)m_rxBuf.len(); } bool SerialBuf::writeable() { - return m_pStream(writeable()); + if( !m_rxBuf.room() ) //Free buf is possible + onTxInterrupt(); + return (bool)m_txBuf.room(); } void SerialBuf::setReadMode(bool readMode) //If true, keeps chars in buf when read, false by default { - if(m_readMode == true && readMode == false) - { - //Trash bytes that have been read - flushRead(); - } - m_readMode=readMode; + m_rxBuf.setReadMode(readMode); } -void SerialBuf::flushRead() //Delete chars that have been read (only useful with readMode = true) +void SerialBuf::flushRead() //Delete chars that have been read & return chars len (only useful with readMode = true) { - m_pReadStart = m_pRead; + m_rxBuf.flushRead(); } -void SerialBuf::resetRead() //Go back to initial read position (only useful with readMode = true) +void SerialBuf::resetRead() //Go back to initial read position & return chars len (only useful with readMode = true) { - m_pRead = m_pReadStart; -} - -bool SerialBuf::onRead() -{ - return false; - //Nothing here + m_rxBuf.resetRead(); } -char SerialBuf::get() //Get a char from buf +void SerialBuf::onRxInterrupt() //Callback from m_pSerial { - //WARN: Must call len() before - char c = *m_pRead; - m_pRead++; - - if(m_pRead>=m_buf+m_bufLen) - m_pRead=m_buf; - - if(!m_readMode) //If readmode=false, trash this char - m_pReadStart=m_pRead; - - if(m_pRead==m_pReadByInt) //Next message can be processed by interrupt - m_intCanReadData = true; -/* else if(m_intCanReadData) //Increment this address - m_pReadByInt=m_pRead;*/ - return c; + while( m_rxBuf.room() && m_pStream(readable()) ) + { + m_rxBuf.write(m_pStream(getc())); + } } -void SerialBuf::put(char c) //Put a char in buf +void SerialBuf::onTxInterrupt() //Callback from m_pSerial { - //WARN: Must call room() before - *m_pWrite = c; - m_pWrite++; - if(m_pWrite>=m_buf+m_bufLen) - m_pWrite=m_buf; + while( m_txBuf.len() && m_pStream(writeable()) ) + { + m_pStream(putc(m_txBuf.read())); + } } -int SerialBuf::room() //Return room available in buf -{ - //return m_bufLen - len() - 1; //-1 is to avoid loop - if ( m_pReadStart > m_pWrite ) - return ( m_pReadStart - m_pWrite - 1 ); - else - return m_bufLen - ( m_pWrite - m_pReadStart ) - 1; -} - -int SerialBuf::len() //Return chars length in buf -{ - if ( m_pWrite >= m_pRead ) - return ( m_pWrite - m_pRead ); - else - return m_bufLen - ( m_pRead - m_pWrite ); // = ( ( m_buf + m_bufLen) - m_pRead ) + ( m_pWrite - m_buf ) -} #endif
--- a/drv/serial/buf/SerialBuf.h Fri Jun 18 10:38:57 2010 +0000 +++ b/drv/serial/buf/SerialBuf.h Fri Jul 09 14:46:47 2010 +0000 @@ -30,11 +30,37 @@ #include "drv/serial/usb/UsbSerial.h" #endif +class SerialCircularBuf +{ +public: + SerialCircularBuf(int len); + ~SerialCircularBuf(); + + int room(); + int len(); + + void write(char c); + char read(); + + void setReadMode(bool readMode); //If true, keeps chars in buf when read, false by default + void flushRead(); //Delete chars that have been read & return chars len (only useful with readMode = true) + void resetRead(); //Go back to initial read position & return chars len (only useful with readMode = true) + +private: + char* m_buf; + int m_len; + + volatile char* m_pReadStart; + volatile char* m_pRead; + volatile char* m_pWrite; + volatile bool m_readMode; +}; + class SerialBuf { public: SerialBuf(int len); //Buffer length - ~SerialBuf(); + virtual ~SerialBuf(); void attach(Serial* pSerial); void detach(); @@ -52,36 +78,20 @@ void setReadMode(bool readMode); //If true, keeps chars in buf when read, false by default void flushRead(); //Delete chars that have been read & return chars len (only useful with readMode = true) void resetRead(); //Go back to initial read position & return chars len (only useful with readMode = true) -protected: - virtual bool onRead();// = 0; //Called when new bytes are received : WARN: executed in an interrupt context >> only fast & non-blocking code (eg no printf;)) - //return true if handled, false otherwise + private: - void onSerialInterrupt(); //Callback from m_pSerial + void onRxInterrupt(); //Callback from m_pSerial + void onTxInterrupt(); //Callback from m_pSerial + + SerialCircularBuf m_rxBuf; + SerialCircularBuf m_txBuf; - volatile bool m_trmt; //For debugging (Was transmitting?) - Serial* m_pSerial; //Not owned - - char get(); //Get a char from buf - void put(char c); //Put a char in buf - int room(); //Return room available in buf - int len(); //Return chars len in buf - - char* m_buf; - int m_bufLen; - volatile char* m_pReadStart; - volatile char* m_pRead; - volatile char* m_pReadByInt; //Chars read during interrupt - volatile bool m_intCanReadData; - - volatile char* m_pWrite; - volatile bool m_readMode; - #if NET_USB_SERIAL //USB Serial Impl UsbSerial* m_pUsbSerial; //Not owned - Ticker m_usbTick; + //Ticker m_usbTick; #endif };
--- a/drv/serial/lwip/sio.cpp Fri Jun 18 10:38:57 2010 +0000 +++ b/drv/serial/lwip/sio.cpp Fri Jul 09 14:46:47 2010 +0000 @@ -37,12 +37,15 @@ #include "netCfg.h" #if NET_PPP - -#define MAX_SERIAL_PORTS 8 +//#define MAX_SERIAL_PORTS 8 #include "lwip/sio.h" #include "mbed.h" -#include "sioMgr.h" +//#include "sioMgr.h" +#include "drv/serial/buf/SerialBuf.h" + +//#define __DEBUG +#include "dbg/dbg.h" //extern "C" { @@ -54,6 +57,7 @@ */ sio_fd_t sio_open(u8_t devnum) { +#if 0 SerialBuf* pIf = SioMgr::getIf(devnum); if(pIf == NULL) return NULL; @@ -61,7 +65,9 @@ //Got a SerialBuf* object //WARN: It HAS to be initialised (instanciated + attached to a Serial obj) - return (sio_fd_t*) pIf; + return (sio_fd_t) pIf; + #endif + return NULL; } /** @@ -171,7 +177,7 @@ SerialBuf* pIf = (SerialBuf*) fd; while(len) { - //while(!pIf->writeable()); + while(!pIf->writeable()); pIf->putc(*data); data++; len--;
--- a/drv/serial/lwip/sioMgr.cpp Fri Jun 18 10:38:57 2010 +0000 +++ b/drv/serial/lwip/sioMgr.cpp Fri Jul 09 14:46:47 2010 +0000 @@ -20,6 +20,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#if 0 //Dep #include "sioMgr.h" @@ -45,3 +46,4 @@ return m_pSerialBufList[item-1]; } +#endif
--- a/drv/serial/lwip/sioMgr.h Fri Jun 18 10:38:57 2010 +0000 +++ b/drv/serial/lwip/sioMgr.h Fri Jul 09 14:46:47 2010 +0000 @@ -20,7 +20,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - +#if 0 //Dep #ifndef SIOMGR_H #define SIOMGR_H @@ -47,3 +47,4 @@ }; #endif +#endif
--- a/drv/serial/usb/UsbSerial.cpp Fri Jun 18 10:38:57 2010 +0000 +++ b/drv/serial/usb/UsbSerial.cpp Fri Jul 09 14:46:47 2010 +0000 @@ -21,9 +21,12 @@ THE SOFTWARE. */ +#include "rpc.h" + #include "UsbSerial.h" -#include "usbserialif.h" -#include "rpc.h" + +//#define __DEBUG +#include "dbg/dbg.h" #include "netCfg.h" #if NET_USB_SERIAL @@ -31,9 +34,11 @@ namespace mbed { #define BUF_LEN 64 -#define FLUSH_TMOUT 10000 //US +#define FLUSH_TMOUT 100000 //US -UsbSerial::UsbSerial(int usbDev, int usbIf, const char *name /*= NULL*/) : Stream(name), m_txTimeout() { +UsbSerial::UsbSerial(UsbDevice* pDevice, int epIn, int epOut, const char* name /*= NULL*/) : Stream(name), m_epIn(pDevice, epIn, true, USB_BULK, BUF_LEN), m_epOut(pDevice, epOut, false, USB_BULK, BUF_LEN), +m_pInCbItem(NULL), m_pInCbMeth(NULL), m_pOutCbItem(NULL), m_pOutCbMeth(NULL) +{ m_inBufEven = new char[BUF_LEN]; m_inBufOdd = new char[BUF_LEN]; m_pInBufPos = m_inBufUsr = m_inBufEven; @@ -46,7 +51,14 @@ m_inBufLen = m_outBufLen = 0; -// startRx(); + DBG("Starting RX'ing on in ep\n"); + + m_timeout = false; + + m_epIn.setOnCompletion(this, &UsbSerial::onEpInTransfer); + m_epOut.setOnCompletion(this, &UsbSerial::onEpOutTransfer); + + startRx(); } UsbSerial::~UsbSerial() @@ -65,57 +77,157 @@ // } +#if 0 //For doc only +template <class T> +void attach(T* pCbItem, void (T::*pCbMeth)()) +{ + m_pCbItem = (CDummy*) pCbItem; + m_pCbMeth = (void (CDummy::*)()) pCbMeth; +} +#endif + int UsbSerial::_getc() { + NVIC_DisableIRQ(US_TICKER_TIMER_IRQn); + NVIC_DisableIRQ(USB_IRQn); char c; c = *m_pInBufPos; m_pInBufPos++; + NVIC_EnableIRQ(USB_IRQn); + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); return c; } int UsbSerial::_putc(int c) { - m_txTimeout.detach(); //Do not want to be interrupted, accessing shared data here... - *m_pOutBufPos = (char) c; - m_pOutBufPos++; - if( (m_pOutBufPos - m_outBufUsr) == BUF_LEN) //Must flush + NVIC_DisableIRQ(US_TICKER_TIMER_IRQn); + NVIC_DisableIRQ(USB_IRQn); + if( (m_pOutBufPos - m_outBufUsr) < BUF_LEN ) { + *m_pOutBufPos = (char) c; + m_pOutBufPos++; + } + else + { + DBG("NO WAY!!!\n"); + } + #if 1 + if( (m_pOutBufPos - m_outBufUsr) >= BUF_LEN ) //Must flush + { + if(m_timeout) + m_txTimeout.detach(); startTx(); } else { - m_txTimeout.attach_us(this, &UsbSerial::startTx, FLUSH_TMOUT); + /*if(m_timeout) + m_txTimeout.detach(); + m_timeout = true; + m_txTimeout.attach_us(this, &UsbSerial::startTx, FLUSH_TMOUT);*/ + if(!m_timeout) + { + m_timeout = true; + m_txTimeout.attach_us(this, &UsbSerial::startTx, FLUSH_TMOUT); + } } + #endif + //startTx(); + NVIC_EnableIRQ(USB_IRQn); + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); return c; } int UsbSerial::readable() { + NVIC_DisableIRQ(US_TICKER_TIMER_IRQn); + NVIC_DisableIRQ(USB_IRQn); + int res; if( (m_pInBufPos - m_inBufUsr) < m_inBufLen ) { - // printf("\r\nREADABLE\r\n"); - return true; + //DBG("\r\nREADABLE\r\n"); + res = true; } else { - // printf("\r\nNOT READABLE\r\n"); + //DBG("\r\nNOT READABLE\r\n"); startRx(); //Try to swap packets & start another transmission - return ((m_pInBufPos - m_inBufUsr) < m_inBufLen )?true:false; + res = ((m_pInBufPos - m_inBufUsr) < m_inBufLen )?true:false; } + NVIC_EnableIRQ(USB_IRQn); + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); + return (bool)res; } int UsbSerial::writeable() { - // printf("\r\nWRITEABLE???\r\n"); - return (bool)( (m_pOutBufPos - m_outBufUsr) < BUF_LEN); + NVIC_DisableIRQ(US_TICKER_TIMER_IRQn); + NVIC_DisableIRQ(USB_IRQn); + // DBG("\r\nWRITEABLE???\r\n"); + int res = (bool)( (m_pOutBufPos - m_outBufUsr) < BUF_LEN); + NVIC_EnableIRQ(USB_IRQn); + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); + return res; +} + +void UsbSerial::onReadable() +{ + if(m_pInCbItem && m_pInCbMeth) + (m_pInCbItem->*m_pInCbMeth)(); } +void UsbSerial::onWriteable() +{ + if(m_pOutCbItem && m_pOutCbMeth) + (m_pOutCbItem->*m_pOutCbMeth)(); +} + +void UsbSerial::onEpInTransfer() +{ + int len = m_epIn.status(); + DBG("RX transfer completed w len=%d\n",len); + startRx(); + if(len > 0) + onReadable(); +} + +void UsbSerial::onEpOutTransfer() +{ + int len = m_epOut.status(); + DBG("TX transfer completed w len=%d\n",len); + if(m_timeout) + m_txTimeout.detach(); + startTx(); + if(len > 0) + onWriteable(); +} void UsbSerial::startTx() { - if( SerialTransmitted() < 0 ) + + DBG("Transfer>\n"); + + m_timeout = false; + +// m_txTimeout.detach(); + + if(!(m_pOutBufPos - m_outBufUsr)) { - //Wait & retry - m_txTimeout.attach_us(this, &UsbSerial::startTx, FLUSH_TMOUT); + DBG("?!?!?\n"); return; } + if( m_epOut.status() == USBERR_PROCESSING ) + { + //Wait & retry + //m_timeout = true; + //m_txTimeout.attach_us(this, &UsbSerial::startTx, FLUSH_TMOUT); + DBG("Ep is busy...\n"); + return; + } + + if( m_epOut.status() < 0 ) + { + DBG("Tx trying again...\n"); + m_epOut.transfer((volatile uint8_t*)m_outBufTrmt, m_outBufLen); + return; + } + m_outBufLen = m_pOutBufPos - m_outBufUsr; //Swap buffers @@ -123,7 +235,7 @@ m_outBufUsr = m_outBufTrmt; m_outBufTrmt = swapBuf; - SerialTx((volatile USB_INT08U*)m_outBufTrmt, m_outBufLen); + m_epOut.transfer((volatile uint8_t*)m_outBufTrmt, m_outBufLen); m_pOutBufPos = m_outBufUsr; @@ -136,10 +248,16 @@ //User buf is not empty, cannot swap now... return; } - int len = SerialReceived(); + int len = m_epIn.status(); + if( len == USBERR_PROCESSING ) + { + //Previous transmission not completed + return; + } if( len < 0 ) { - //Previous transmission not completed + DBG("Rx trying again...\n"); + m_epIn.transfer((volatile uint8_t*)m_inBufTrmt, BUF_LEN); //Start another transmission return; } @@ -149,19 +267,16 @@ volatile char* swapBuf = m_inBufUsr; m_inBufUsr = m_inBufTrmt; m_inBufTrmt = swapBuf; - - SerialRx((volatile USB_INT08U*)m_inBufTrmt, BUF_LEN); //Start another transmission + m_pInBufPos = m_inBufUsr; - m_pInBufPos = m_inBufUsr; - + DBG("Starting new transfer\n"); + m_epIn.transfer((volatile uint8_t*)m_inBufTrmt, BUF_LEN); //Start another transmission + } - - +#ifdef MBED_RPC const struct rpc_method *UsbSerial::get_rpc_methods() { static const rpc_method methods[] = { - { "baud", rpc_method_caller<UsbSerial, int, &UsbSerial::baud> }, - { "format", rpc_method_caller<UsbSerial, int, int, int, &UsbSerial::format> }, { "readable", rpc_method_caller<int, UsbSerial, &UsbSerial::readable> }, { "writeable", rpc_method_caller<int, UsbSerial, &UsbSerial::writeable> }, RPC_METHOD_SUPER(Stream) @@ -171,12 +286,13 @@ struct rpc_class *UsbSerial::get_rpc_class() { static const rpc_function funcs[] = { - { "new", rpc_function_caller<const char*, int, int, const char*, Base::construct<UsbSerial,int,int,const char*> > }, + /*{ "new", rpc_function_caller<const char*, UsbDevice*, int, int, const char*, Base::construct<UsbSerial,UsbDevice*,int,int,const char*> > },*/ //RPC is buggy RPC_METHOD_END }; static rpc_class c = { "UsbSerial", funcs, NULL }; return &c; } +#endif } // namespace mbed
--- a/drv/serial/usb/UsbSerial.h Fri Jun 18 10:38:57 2010 +0000 +++ b/drv/serial/usb/UsbSerial.h Fri Jul 09 14:46:47 2010 +0000 @@ -29,17 +29,19 @@ #include "Stream.h" #include "mbed.h" +#include "drv/usb/UsbDevice.h" +#include "drv/usb/UsbEndpoint.h" + namespace mbed { class UsbSerial : public Stream { public: - UsbSerial(int usbDev, int usbIf, const char *name = NULL); + UsbSerial(UsbDevice* pDevice, int epIn, int epOut, const char* name = NULL); virtual ~UsbSerial(); //Apart from the ctor/dtor, exactly the same protos as Serial - void baud(int baudrate); enum Parity { @@ -49,9 +51,29 @@ Forced1 = 3, Forced0 = 4 }; + + enum IrqType { + RxIrq = 0 + , TxIrq + }; void format(int bits, int parity, int stop); - + + class CDummy; + template <class T> + void attach(T* pCbItem, void (T::*pCbMeth)(), IrqType type = RxIrq) + { + if(type == RxIrq) + { + m_pInCbItem = (CDummy*) pCbItem; + m_pInCbMeth = (void (CDummy::*)()) pCbMeth; + } + else + { + m_pOutCbItem = (CDummy*) pCbItem; + m_pOutCbMeth = (void (CDummy::*)()) pCbMeth; + } + } #if 0 // Inhereted from Stream, for documentation only @@ -107,20 +129,38 @@ */ int writeable(); +#ifdef MBED_RPC virtual const struct rpc_method *get_rpc_methods(); static struct rpc_class *get_rpc_class(); +#endif protected: virtual int _getc(); virtual int _putc(int c); + void onReadable(); + void onWriteable(); + + void onEpInTransfer(); + void onEpOutTransfer(); + private: + UsbEndpoint m_epIn; + UsbEndpoint m_epOut; + + CDummy* m_pInCbItem; + void (CDummy::*m_pInCbMeth)(); + + CDummy* m_pOutCbItem; + void (CDummy::*m_pOutCbMeth)(); + void startTx(); void startRx(); Timeout m_txTimeout; + volatile bool m_timeout; volatile char* m_inBufEven; volatile char* m_inBufOdd;
--- a/drv/serial/usb/usbserialif.cpp Fri Jun 18 10:38:57 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,278 +0,0 @@ - -/* -Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -/* - USB-Serial device driver - Donatien Garnier 2010 -*/ - -#include "usbserialif.h" -#include "drv/usb/UsbEndpoint.h" - -#include "netCfg.h" -#if NET_USB_SERIAL - -UsbEndpoint* pEpIn; -UsbEndpoint* pEpOut; - -#define DONGLE_STATE_UNKNOWN 0 -#define DONGLE_STATE_CDFS 1 -#define DONGLE_STATE_SERIAL 2 - -USB_INT08U dongleState; - -USB_INT32S SerialInit() -{ - dongleState = DONGLE_STATE_UNKNOWN; - Host_Init(); // Initialize the host controller - USB_INT32S rc = Host_EnumDev(); // Enumerate the device connected - if (rc != OK) - { - fprintf(stderr, "Could not enumerate device: %d\n", rc); - return rc; - } - return OK; -} - -bool SerialHasToSwitch() -{ - return (dongleState == DONGLE_STATE_CDFS); -} - -uint16_t m_vid; -uint16_t m_pid; - -USB_INT32S SerialSendMagic() -{ - bool scsi = false; - //Size 31 - const unsigned char magicHuawei[] = { 0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78, 0, 0, 0, 0, 0, 0, 0, 0x11, 0x6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - const unsigned char magicVoda[] = { 0x55, 0x53, 0x42, 0x43, 0x78, 0x56, 0x34, 0x12, 0x01, 0, 0, 0, 0x80, 0, 0x06, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - char* magic; - USB_INT32S rc; - if((m_vid == 0x12d1) && (m_pid == 0x1446)) - { - PRINT_Log("\r\nHuawei magic packet sent.\r\n"); - magic = (char*) magicHuawei; - scsi = true; - } - else if((m_vid == 0x12d1) && (m_pid == 0x1003)) - { - PRINT_Log("\r\nHuawei magic control packet sent.\r\n"); - rc = Host_CtrlSend( 0 /*USB_TYPE_STANDARD | USB_RECIP_DEVICE*/, 0x03 /*USB_REQ_SET_FEATURE*/, 00000001, 0, 0, NULL); - } - else if(m_vid == 0x0af0) - { - PRINT_Log("\r\nVoda magic packet sent.\r\n"); - magic = (char*) magicVoda; - scsi = true; - } - else - { - return -1; - } - - if(scsi) - { - rc = pEpOut->transfer((volatile USB_INT08U*)magic, 31); - while(rc == PROCESSING) - { - rc = pEpOut->status(); - } - } - - delete pEpOut; - pEpOut = NULL; - return rc; -} - -USB_INT32S SerialCheckVidPid() -{ - volatile USB_INT08U *desc_ptr; - desc_ptr = TDBuffer; - - ser_int_found = 0; - - m_vid = *((USB_INT16U*)&desc_ptr[8]); - m_pid = *((USB_INT16U*)&desc_ptr[10]); - - if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_DEVICE) { - PRINT_Log("\r\nLen = %02x\r\n",desc_ptr[0]); - PRINT_Log("\r\nDesc code %02x\r\n",desc_ptr[1]); - return (ERR_BAD_CONFIGURATION); - } - - if( m_vid == 0x12d1 &&//Huawei : Change - m_pid == 0x1446 ) - { - PRINT_Log("\r\nHuawei device found in CDFS mode\r\n"); - dongleState = DONGLE_STATE_CDFS; - } - else if( m_vid == 0x12d1 &&//Huawei : Change - m_pid == 0x1001 ) - { - PRINT_Log("\r\nHuawei device found in Serial mode\r\n"); - dongleState = DONGLE_STATE_SERIAL; - } - else if( m_vid == 0x0af0 &&//Voda?Qualcomm? : Change - m_pid == 0x7501 ) - { - PRINT_Log("\r\nVodafone K3760 found, checking mode...\r\n"); - dongleState = DONGLE_STATE_UNKNOWN; - } - else if( m_vid == 0x12d1 &&//Voda?Qualcomm? : Change - m_pid == 0x1003 ) - { - PRINT_Log("\r\nHuawei device found, checking mode...\r\n"); - dongleState = DONGLE_STATE_UNKNOWN; - } - else - { - PRINT_Log("\r\nDevice %04x : %04x found.\r\n",m_vid,m_pid); - } - return OK; -} - -USB_INT32S SerialParseConfig() -{ - volatile USB_INT08U *desc_ptr; - - desc_ptr = TDBuffer; - - if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_CONFIGURATION) { - return (ERR_BAD_CONFIGURATION); - } - desc_ptr += desc_ptr[0]; - - int epOut = 0; - int epIn = 0; - - pEpOut = NULL; - pEpIn = NULL; - while (desc_ptr != TDBuffer + ReadLE16U(&TDBuffer[2])) { - - switch (desc_ptr[1]) { - case USB_DESCRIPTOR_TYPE_INTERFACE: - PRINT_Log("\r\nIf %02x:%02x:%02x.\r\n",desc_ptr[5],desc_ptr[6],desc_ptr[7]); - if (desc_ptr[5] == 0xFF && - desc_ptr[6] == 0xFF && - desc_ptr[7] == 0xFF ) { - dongleState = DONGLE_STATE_SERIAL; - } - else - if (desc_ptr[5] == 0xFF && - desc_ptr[6] == 0xFF && - desc_ptr[7] == 0xFF ) { - dongleState = DONGLE_STATE_CDFS; - } - desc_ptr += desc_ptr[0]; /* Move to next descriptor start */ - break; - - case USB_DESCRIPTOR_TYPE_ENDPOINT: /* If it is an endpoint descriptor */ - PRINT_Log("\r\nEp %02x of size %d.\r\n", desc_ptr[2], (ReadLE16U(&desc_ptr[4]) )); - if ( SerialHasToSwitch() ) - { - if( (dongleState == DONGLE_STATE_CDFS) && (pEpOut == NULL) /*desc_ptr[2] == 1*/) //EP 1 - { - pEpOut = new UsbEndpoint((desc_ptr[2] & 0x7F), false, ReadLE16U(&desc_ptr[4])); - } - /* Move to next descriptor start */ - } - desc_ptr += desc_ptr[0]; - break; - - default: /* If the descriptor is neither interface nor endpoint */ - desc_ptr += desc_ptr[0]; /* Move to next descriptor start */ - break; - } - } - if (dongleState == DONGLE_STATE_SERIAL) { - PRINT_Log("Virtual Serial Port device %04x:%04x connected, vid=%d, pid=%d\n", m_vid, m_pid); - if(m_vid==0x0af0) //Voda - { - pEpOut = new UsbEndpoint((0x0a & 0x7F), false, 64); - pEpIn = new UsbEndpoint((0x8b & 0x7F), true, 64); - PRINT_Log("Voda K3760\r\n"); - } - else //if ( ( m_vid == 0x12d1 ) && ( m_pid == 0x1003 ) ) - /*{*/ - if ( ( m_vid == 0x12d1 ) && ( m_pid == 0x1003 ) ) - { - pEpOut = new UsbEndpoint((0x02 & 0x7F), false, 64); - pEpIn = new UsbEndpoint((0x82 & 0x7F), true, 64); - PRINT_Log("Huawei E220\r\n"); - } - else /*if ( m_vid == 0x12d1 && - m_pid == 0x1001 )*/ - { - pEpOut = new UsbEndpoint((0x01 & 0x7F), false, 64); - pEpIn = new UsbEndpoint((0x82 & 0x7F), true, 64); - PRINT_Log("Huawei E1550\r\n"); - } - - PRINT_Log("Virtual Serial Port device %04x:%04x connected\n", m_vid, m_pid); - return (OK); - } - else if (dongleState == DONGLE_STATE_CDFS) { - PRINT_Log("CDFS dongle connected, reset\n"); - return (OK); - } else { - PRINT_Log("Not a Virtual Serial Port device\n"); - return (ERR_NO_MS_INTERFACE); - } -} - - -USB_INT32S SerialRx( volatile USB_INT08U* buf, USB_INT32U len ) -{ - USB_INT32S rc; - rc = pEpIn->transfer(buf, len); - return rc; -} - -USB_INT32S SerialReceived() -{ - return pEpIn->status(); -} - -USB_INT32S SerialTx( volatile USB_INT08U* buf, USB_INT32U len ) -{ - USB_INT32S rc; - rc = pEpOut->transfer(buf, len); - // PRINT_Log("\r\nOut rc = %d\r\n",len); - return rc; -} - -USB_INT32S SerialTransmitted() -{ - USB_INT32S rc = pEpOut->status(); -/* if(rc>=0) - { - PRINT_Log("\r\nTransmitted %d\r\n",rc); - }*/ - return rc; -} - -USB_INT32S SerialReg(USB_INT16U vid, USB_INT16U pid) {return 0;} - -#endif
--- a/drv/serial/usb/usbserialif.h Fri Jun 18 10:38:57 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ - -/* -Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -/* - USB-Serial device driver - Donatien Garnier 2010 -*/ - -#ifndef USBSERIALIF_H -#define USBSERIALIF_H - -/* -************************************************************************************************************** -* INCLUDE HEADER FILES -************************************************************************************************************** -*/ - -#include "drv/usb/USBHostLite/usbhost_inc.h" - -/* -************************************************************************************************************** -* FUNCTION PROTOTYPES -************************************************************************************************************** -*/ - -USB_INT32S SerialRx( volatile USB_INT08U* buf, USB_INT32U len ); -USB_INT32S SerialReceived(); - -USB_INT32S SerialTx( volatile USB_INT08U* buf, USB_INT32U len ); -USB_INT32S SerialTransmitted(); - -USB_INT32S SerialCheckVidPid(); -USB_INT32S SerialParseConfig(); - -USB_INT32S SerialInit(); - - -bool SerialHasToSwitch(); -USB_INT32S SerialSendMagic(); - -USB_INT32S SerialReg(USB_INT16U vid, USB_INT16U pid); - -#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drv/umtsstick/UMTSStick.cpp Fri Jul 09 14:46:47 2010 +0000 @@ -0,0 +1,323 @@ + +/* +Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "netCfg.h" +#if NET_UMTS + +#include "UMTSStick.h" + +#define __DEBUG +#include "dbg/dbg.h" + +UMTSStick::UMTSStick() : m_host(), m_pDev(NULL) +{ + +} + +UMTSStick::~UMTSStick() +{ + +} + + +UMTSStickErr UMTSStick::getSerial(UsbSerial** ppUsbSerial) +{ + m_host.init(); + + UMTSStickErr rc; + + rc = waitForDevice(); + if(rc) + return rc; + + //Device is now enumerated, read table + + uint16_t vid = m_pDev->getVid(); + uint16_t pid = m_pDev->getPid(); + + DBG("Configuration set: vid:%04x pid:%04x\n", vid, pid); + + bool handled = false; + bool cdfs = false; + const UMTSSwitchingInfo* pInfo; + for(int i = 0; i < UMTS_SWITCHING_COUNT; i++) + { + pInfo = &UMTSwitchingTable[i]; + if( !checkDeviceState(pInfo, &cdfs) ) + { + handled = true; + break; + } + + } //for(int i = 0; i < UMTS_SWITCHING_COUNT; i++) + + if(!handled) + { + DBG("Don't know this device!\n"); + return UMTSERR_NOTIMPLEMENTED; + } + + //Check if the device is in CDFS mode, in this case switch + if(cdfs) + { + DBG("Switching the device by sending a magic packet\n"); + + rc = switchMode(pInfo); + if(rc) + return rc; + + DBG("Now wait for device to reconnect\n"); + + m_host.releaseDevice(m_pDev); + + //Wait for device to reconnect + wait(3); + rc = waitForDevice(); + if(rc) + return rc; + } + + rc = findSerial(ppUsbSerial); + if(rc) + return rc; + + return UMTSERR_OK; +} + +UMTSStickErr UMTSStick::waitForDevice() +{ + bool ready = false; + while(!ready) + { + while(!m_host.devicesCount()) + {} + wait(1); + if(m_host.devicesCount()) + ready = true; + } + + m_pDev = m_host.getDevice(0); + + while(!m_pDev->enumerated()) + { + m_host.poll(); + if(!m_host.devicesCount()) + return UMTSERR_DISCONNECTED; + } + + wait(3); + + return UMTSERR_OK; +} + +UMTSStickErr UMTSStick::checkDeviceState(const UMTSSwitchingInfo* pInfo, bool* pCdfs) +{ + uint16_t vid = m_pDev->getVid(); + uint16_t pid = m_pDev->getPid(); + bool handled = false; + if( (vid == pInfo->cdfsVid) && (pid == pInfo->cdfsPid) ) + { + DBG("Match on dongles list\n"); + if( !pInfo->targetClass ) //No specific interface to check, vid/pid couple is specific to CDFS mode + { + DBG("Found device in CDFS mode\n"); + handled = true; + *pCdfs = true; + } + else //if( !pInfo->targetClass ) + { + //Has to check if there is an interface of class targetClass + byte* desc = NULL; + int c = 0; + + while( !m_pDev->getInterfaceDescriptor(1, c++, &desc) ) + { + if( desc[5] == pInfo->targetClass ) + { + DBG("Found device in Serial mode\n"); + handled = true; + *pCdfs = false; + break; + } + } + + if(!handled) + { + //All interfaces were tried, so we are in CDFS mode + DBG("Found device in CDFS mode\n"); + handled = true; + *pCdfs = true; + } + } //if( !pInfo->targetClass ) + } //if( (vid == pInfo->cdfsVid) && (pid == pInfo->cdfsPid) ) + else + { + //Try every vid/pid couple of the serial list + for( int i = 0; i < 16 ; i++) + { + if(!pInfo->serialPidList[i]) + break; + if( (pInfo->serialVid == vid) && (pInfo->serialPidList[i] == pid) ) + { + DBG("Found device in Serial mode\n"); + handled = true; + *pCdfs = false; + break; + } + } + } //if( (vid == pInfo->cdfsVid) && (pid == pInfo->cdfsPid) ) + + if(!handled) + return UMTSERR_NOTFOUND; + + return UMTSERR_OK; +} + +UMTSStickErr UMTSStick::switchMode(const UMTSSwitchingInfo* pInfo) +{ + if(!pInfo->huaweiPacket) //Send SCSI packet on first bulk ep + { + //Find first bulk ep + byte* desc = NULL; + int c = 0; + + UsbEndpoint *pEpOut = NULL; + + while( !m_pDev->getInterfaceDescriptor(1, c++, &desc) ) + { + byte* p = desc; + int epNum = 0; + p = p + p[0]; //Move to next descriptor (which should be an ep descriptor) + while (epNum < desc[4]) //Eps count in this if + { + if (p[1] != USB_DESCRIPTOR_TYPE_ENDPOINT) + break; + + if( (p[3] == 0x02) && !(p[2] & 0x80) ) //Bulk endpoint, out + { + DBG("Found bulk ep %02x\n", p[2]); + pEpOut = new UsbEndpoint( m_pDev, p[2], false, USB_BULK, *((uint16_t*)&p[4]) ); + break; + } + + p = p + p[0]; //Move to next ep desc + epNum++; + } + if(pEpOut) + break; + } + + if(!pEpOut) + return UMTSERR_NOTFOUND; + + //Send SCSI packet + + DBG("Sending SCSI Packet to switch\n"); + byte ramCdfsBuf[31]; + memcpy(ramCdfsBuf, pInfo->cdfsPacket, 31); + pEpOut->transfer((volatile byte*)ramCdfsBuf, 31); + while(pEpOut->status() == USBERR_PROCESSING); + int ret = pEpOut->status(); + if((ret < 0) && (ret !=USBERR_DISCONNECTED)) //Packet was not transfered + { + DBG("Usb error %d\n", ret); + delete pEpOut; + return UMTSERR_USBERR; + } + + delete pEpOut; + } + else + { + UsbErr usbErr; + //Send the Huawei-specific control packet + usbErr = m_pDev->controlSend(0, 0x03, 1, 0, NULL, 0); + if(usbErr && (usbErr != USBERR_DISCONNECTED)) + return UMTSERR_USBERR; + } + + DBG("The stick should be switching in serial mode now\n"); + + return UMTSERR_OK; +} + +UMTSStickErr UMTSStick::findSerial(UsbSerial** ppUsbSerial) +{ + byte* desc = NULL; + int c = 0; + + int epOut = 0; + int epIn = 0; + + while( !m_pDev->getInterfaceDescriptor(1, c++, &desc) ) + { + byte* p = desc; + int epNum = 0; + + DBG("Interface of type %02x\n", desc[5]); + + if(desc[5] != 0xFF) //Not a serial-like if + continue; + + p = p + p[0]; //Move to next descriptor (which should be an ep descriptor) + while (epNum < desc[4]) //Eps count in this if + { + if (p[1] == USB_DESCRIPTOR_TYPE_ENDPOINT) + { + if( (p[3] == 0x02) && !(p[2] & 0x80) && !epOut ) //Bulk endpoint, out + { + DBG("Found bulk out ep %02x of payload size %04x\n", p[2], *((uint16_t*)&p[4])); + epOut = p[2] & 0x7F; + } + + if( (p[3] == 0x02) && (p[2] & 0x80) && !epIn ) //Bulk endpoint, in + { + DBG("Found bulk in ep %02x of payload size %04x\n", p[2], *((uint16_t*)&p[4])); + epIn = p[2] & 0x7F; + } + + if(epOut && epIn) + break; + } + + p = p + p[0]; //Move to next ep desc + epNum++; + } + + if(epOut && epIn) + break; + } + + if(!epOut || !epIn) + return UMTSERR_NOTFOUND; + + DBG("Endpoints found, create serial object\n"); + + *ppUsbSerial = new UsbSerial(m_pDev, epIn, epOut); + + DBG("UsbSerial object created\n"); + + return UMTSERR_OK; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drv/umtsstick/UMTSStick.h Fri Jul 09 14:46:47 2010 +0000 @@ -0,0 +1,82 @@ + +/* +Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef UMTS_STICK_H +#define UMTS_STICK_H + +#include "mbed.h" + +#include "drv/usb/UsbHostMgr.h" +#include "drv/usb/UsbDevice.h" +#include "drv/usb/UsbEndpoint.h" + +#include "drv/serial/usb/UsbSerial.h" + +#define UMTS_SWITCHING_COUNT 2 + +typedef unsigned char byte; + +struct UMTSSwitchingInfo +{ + uint16_t cdfsVid; + uint16_t cdfsPid; + uint16_t serialVid; + uint16_t serialPidList[16]; + byte targetClass; + bool huaweiPacket; + byte cdfsPacket[31]; +}; + +extern const UMTSSwitchingInfo UMTSwitchingTable[UMTS_SWITCHING_COUNT]; + +enum UMTSStickErr +{ + __UMTSERR_MIN = -0xFFFF, + UMTSERR_NOTFOUND, + UMTSERR_NOTIMPLEMENTED, + UMTSERR_USBERR, + UMTSERR_DISCONNECTED, + UMTSERR_OK = 0 +}; + +class UMTSStick +{ +public: + UMTSStick(); + ~UMTSStick(); + + UMTSStickErr getSerial(UsbSerial** ppUsbSerial); + +private: + UMTSStickErr waitForDevice(); + UMTSStickErr checkDeviceState(const UMTSSwitchingInfo* pInfo, bool* pCdfs); + + UMTSStickErr switchMode(const UMTSSwitchingInfo* pInfo); + UMTSStickErr findSerial(UsbSerial** ppUsbSerial); + + + UsbHostMgr m_host; + UsbDevice* m_pDev; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drv/umtsstick/UMTSStickData.cpp Fri Jul 09 14:46:47 2010 +0000 @@ -0,0 +1,24 @@ +#include "UMTSStick.h" + +const UMTSSwitchingInfo UMTSwitchingTable[UMTS_SWITCHING_COUNT] = { + +/* +struct UMTSSwitchingInfo +{ + uint16_t cdfsVid; + uint16_t cdfsPid; + uint16_t serialVid; + uint16_t serialPidList[16]; + byte targetClass; + bool huaweiPacket; + byte cdfsPacket[31]; +}; +*/ + +//Huawei E220, E230, E270, E870 +{ 0x12d1, 0x1003, 0, {0}, 0xFF, true, {0} }, + +//Huawei E1550, E270+ +{ 0x12d1, 0x1446, 0x12d1, {0x1001, 0x1406, 0x140c, 0x14ac/*, 0x1003*/}, 0, false, { 0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78, 0, 0, 0, 0, 0, 0, 0, 0x11, 0x06, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } + +};
--- a/drv/usb/USBHostLite/usbhost_cpu.h Fri Jun 18 10:38:57 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ - -/* -Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -/* -************************************************************************************************************** -* NXP USB Host Stack -* -* (c) Copyright 2008, NXP SemiConductors -* (c) Copyright 2008, OnChip Technologies LLC -* All Rights Reserved -* -* www.nxp.com -* www.onchiptech.com -* -* File : usbhost_cpu.h -* Programmer(s) : Ravikanth.P -* Version : -* -************************************************************************************************************** -*/ - -#ifndef USBHOST_CPU_H -#define USBHOST_CPU_H - -/* -************************************************************************************************************** -* TYPE DEFINITIONS OF DATA TYPES -************************************************************************************************************** -*/ - -typedef unsigned int USB_INT32U; -typedef signed int USB_INT32S; -typedef unsigned short USB_INT16U; -typedef signed short USB_INT16S; -typedef unsigned char USB_INT08U; -typedef signed char USB_INT08S; - -#endif
--- a/drv/usb/USBHostLite/usbhost_err.h Fri Jun 18 10:38:57 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ - -/* -Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -/* -************************************************************************************************************** -* NXP USB Host Stack -* -* (c) Copyright 2008, NXP SemiConductors -* (c) Copyright 2008, OnChip Technologies LLC -* All Rights Reserved -* -* www.nxp.com -* www.onchiptech.com -* -* File : usbhost_err.h -* Programmer(s) : Ravikanth.P -* Version : -* -************************************************************************************************************** -*/ - -#ifndef USBHOST_ERR_H -#define USBHOST_ERR_H - - -/* -************************************************************************************************************** -* GENERAL DEFINITIONS -************************************************************************************************************** -*/ - -#define OK 0 -#define MATCH_FOUND 0 - -/* -************************************************************************************************************** -* HOST CONTROLLER SPECIFIC ERROR CODES -************************************************************************************************************** -*/ - -#define ERR_TD_FAIL -1 - -/* -************************************************************************************************************** -* MASS STORAGE SPECIFIC ERROR CODES -************************************************************************************************************** -*/ - -#define ERR_MS_CMD_FAILED -10 -#define ERR_BAD_CONFIGURATION -11 -#define ERR_NO_MS_INTERFACE -12 - -/* -************************************************************************************************************** -* FAT SPECIFIC ERROR CODES -************************************************************************************************************** -*/ - -#define MATCH_NOT_FOUND -20 -#define ERR_FAT_NOT_SUPPORTED -21 -#define ERR_OPEN_LIMIT_REACHED -22 -#define ERR_INVALID_BOOT_SIG -23 -#define ERR_INVALID_BOOT_SEC -24 -#define ERR_ROOT_DIR_FULL -25 - -#define PROCESSING -101 -#endif
--- a/drv/usb/USBHostLite/usbhost_inc.h Fri Jun 18 10:38:57 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ - -/* -Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -/* -************************************************************************************************************** -* NXP USB Host Stack -* -* (c) Copyright 2008, NXP SemiConductors -* (c) Copyright 2008, OnChip Technologies LLC -* All Rights Reserved -* -* www.nxp.com -* www.onchiptech.com -* -* File : usbhost_inc.h -* Programmer(s) : Ravikanth.P -* Version : -* -************************************************************************************************************** -*/ - -#ifndef USBHOST_INC_H -#define USBHOST_INC_H - -/* -************************************************************************************************************** -* INCLUDE HEADER FILES -************************************************************************************************************** -*/ - -#include "usbhost_cpu.h" -#include "usbhost_err.h" -#include "usbhost_lpc17xx.h" -#include "drv/serial/usb/usbserialif.h" -#include "mbed.h" - - -#ifdef TARGET_LPC2368 -#error "There is no USB host on the LPC2368!" -#endif - -#endif
--- a/drv/usb/USBHostLite/usbhost_lpc17xx.c Fri Jun 18 10:38:57 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,923 +0,0 @@ - -/* -Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -/* -************************************************************************************************************** -* NXP USB Host Stack -* -* (c) Copyright 2008, NXP SemiConductors -* (c) Copyright 2008, OnChip Technologies LLC -* All Rights Reserved -* -* www.nxp.com -* www.onchiptech.com -* -* File : usbhost_lpc17xx.c -* Programmer(s) : Ravikanth.P -* Version : -* -************************************************************************************************************** -*/ - -/* -************************************************************************************************************** -* INCLUDE HEADER FILES -************************************************************************************************************** -*/ - -#include "netCfg.h" -#if NET_USB - -#ifdef __cplusplus -extern "C" { -#endif - -#include "usbhost_lpc17xx.h" -//#include "UsbEndpoint.h" - -/* -************************************************************************************************************** -* GLOBAL VARIABLES -************************************************************************************************************** -*/ -int gUSBConnected; - -volatile USB_INT32U HOST_RhscIntr = 0; /* Root Hub Status Change interrupt */ -volatile USB_INT32U HOST_WdhIntr = 0; /* Semaphore to wait until the TD is submitted */ -volatile USB_INT08U HOST_TDControlStatus = 0; -volatile HCED *EDCtrl; /* Control endpoint descriptor structure */ -//volatile HCED *EDBulkHead; -//volatile HCED *EDBulkIn; /* BulkIn endpoint descriptor structure */ -//volatile HCED *EDBulkOut; /* BulkOut endpoint descriptor structure */ -volatile HCTD *TDHead; /* Head transfer descriptor structure */ -volatile HCTD *TDTail; /* Tail transfer descriptor structure */ -volatile HCCA *Hcca; /* Host Controller Communications Area structure */ - USB_INT16U *TDBufNonVol; /* Identical to TDBuffer just to reduce compiler warnings */ -volatile USB_INT08U *TDBuffer; /* Current Buffer Pointer of transfer descriptor */ - -// USB host structures -// AHB SRAM block 1 -#define HOSTBASEADDR 0x2007C000 -// reserve memory for the linker -static USB_INT08U HostBuf[0x300] __attribute((section("AHBSRAM1"),aligned))/* __attribute__((at(HOSTBASEADDR)))*/; -/* -************************************************************************************************************** -* DELAY IN MILLI SECONDS -* -* Description: This function provides a delay in milli seconds -* -* Arguments : delay The delay required -* -* Returns : None -* -************************************************************************************************************** -*/ - -void Host_DelayMS (USB_INT32U delay) -{ - volatile USB_INT32U i; - - - for (i = 0; i < delay; i++) { - Host_DelayUS(1000); - } -} - -/* -************************************************************************************************************** -* DELAY IN MICRO SECONDS -* -* Description: This function provides a delay in micro seconds -* -* Arguments : delay The delay required -* -* Returns : None -* -************************************************************************************************************** -*/ - -void Host_DelayUS (USB_INT32U delay) -{ - volatile USB_INT32U i; - - for (i = 0; i < (4 * delay); i++) { /* This logic was tested. It gives app. 1 micro sec delay */ - ; - } - -} - -// bits of the USB/OTG clock control register -#define HOST_CLK_EN (1<<0) -#define DEV_CLK_EN (1<<1) -#define PORTSEL_CLK_EN (1<<3) -#define AHB_CLK_EN (1<<4) - -// bits of the USB/OTG clock status register -#define HOST_CLK_ON (1<<0) -#define DEV_CLK_ON (1<<1) -#define PORTSEL_CLK_ON (1<<3) -#define AHB_CLK_ON (1<<4) - -// we need host clock, OTG/portsel clock and AHB clock -#define CLOCK_MASK (HOST_CLK_EN | PORTSEL_CLK_EN | AHB_CLK_EN) - -/* -************************************************************************************************************** -* INITIALIZE THE HOST CONTROLLER -* -* Description: This function initializes lpc17xx host controller -* -* Arguments : None -* -* Returns : -* -************************************************************************************************************** -*/ -void Host_Init (void) -{ - PRINT_Log("In Host_Init\n"); - NVIC_DisableIRQ(USB_IRQn); /* Disable the USB interrupt source */ - - // turn on power for USB - LPC_SC->PCONP |= (1UL<<31); - // Enable USB host clock, port selection and AHB clock - LPC_USB->USBClkCtrl |= CLOCK_MASK; - // Wait for clocks to become available - while ((LPC_USB->USBClkSt & CLOCK_MASK) != CLOCK_MASK) - ; - - // it seems the bits[0:1] mean the following - // 0: U1=device, U2=host - // 1: U1=host, U2=host - // 2: reserved - // 3: U1=host, U2=device - // NB: this register is only available if OTG clock (aka "port select") is enabled!! - // since we don't care about port 2, set just bit 0 to 1 (U1=host) - LPC_USB->OTGStCtrl |= 1; - - // now that we've configured the ports, we can turn off the portsel clock - LPC_USB->USBClkCtrl &= ~PORTSEL_CLK_EN; - - // power pins are not connected on mbed, so we can skip them - /* P1[18] = USB_UP_LED, 01 */ - /* P1[19] = /USB_PPWR, 10 */ - /* P1[22] = USB_PWRD, 10 */ - /* P1[27] = /USB_OVRCR, 10 */ - /*LPC_PINCON->PINSEL3 &= ~((3<<4) | (3<<6) | (3<<12) | (3<<22)); - LPC_PINCON->PINSEL3 |= ((1<<4)|(2<<6) | (2<<12) | (2<<22)); // 0x00802080 - */ - - // configure USB D+/D- pins - /* P0[29] = USB_D+, 01 */ - /* P0[30] = USB_D-, 01 */ - LPC_PINCON->PINSEL1 &= ~((3<<26) | (3<<28)); - LPC_PINCON->PINSEL1 |= ((1<<26)|(1<<28)); // 0x14000000 - - PRINT_Log("Initializing Host Stack\n"); - - Hcca = (volatile HCCA *)(HostBuf+0x000); - TDHead = (volatile HCTD *)(HostBuf+0x100); - TDTail = (volatile HCTD *)(HostBuf+0x110); - EDCtrl = (volatile HCED *)(HostBuf+0x120); - //Space for Bulk Eps -// EDBulkHead = (volatile HCED *)(HostBuf+0x130); -// EDBulkIn = (volatile HCED *)(HostBuf+0x130); -// EDBulkOut = (volatile HCED *)(HostBuf+0x140); -// TDBuffer = (volatile USB_INT08U *)(HostBuf+0x150); - TDBuffer = (volatile USB_INT08U *)(HostBuf+0x130); - -// printf("\r\n--EDBulkHead = %p--\r\n", EDBulkHead); - printf("\r\n--TDBuffer = %p--\r\n", TDBuffer); - - /* Initialize all the TDs, EDs and HCCA to 0 */ - Host_EDInit(EDCtrl); -// Host_EDInit(EDBulkIn); -// Host_EDInit(EDBulkOut); - /* Host_TDInit(TDHead); - Host_TDInit(TDTail);*/ - Host_HCCAInit(Hcca); - - Host_DelayMS(50); /* Wait 50 ms before apply reset */ - LPC_USB->HcControl = 0; /* HARDWARE RESET */ - LPC_USB->HcControlHeadED = 0; /* Initialize Control list head to Zero */ - LPC_USB->HcBulkHeadED = 0; /* Initialize Bulk list head to Zero */ - - /* SOFTWARE RESET */ - LPC_USB->HcCommandStatus = OR_CMD_STATUS_HCR; - LPC_USB->HcFmInterval = DEFAULT_FMINTERVAL; /* Write Fm Interval and Largest Data Packet Counter */ - - /* Put HC in operational state */ - LPC_USB->HcControl = (LPC_USB->HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER; - LPC_USB->HcRhStatus = OR_RH_STATUS_LPSC; /* Set Global Power */ - - LPC_USB->HcHCCA = (USB_INT32U)Hcca; - LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus; /* Clear Interrrupt Status */ - - - LPC_USB->HcInterruptEnable = OR_INTR_ENABLE_MIE | - OR_INTR_ENABLE_WDH | - OR_INTR_ENABLE_RHSC; - - NVIC_SetPriority(USB_IRQn, 0); /* highest priority */ - /* Enable the USB Interrupt */ - NVIC_EnableIRQ(USB_IRQn); - PRINT_Log("Host Initialized\n"); -} - -/* -************************************************************************************************************** -* INTERRUPT SERVICE ROUTINE -* -* Description: This function services the interrupt caused by host controller -* -* Arguments : None -* -* Returns : None -* -************************************************************************************************************** -*/ - -void USB_IRQHandler (void) __irq -{ - USB_INT32U int_status; - USB_INT32U ie_status; - - int_status = LPC_USB->HcInterruptStatus; /* Read Interrupt Status */ - ie_status = LPC_USB->HcInterruptEnable; /* Read Interrupt enable status */ - - if (!(int_status & ie_status)) { - return; - } else { - - int_status = int_status & ie_status; - if (int_status & OR_INTR_STATUS_RHSC) { /* Root hub status change interrupt */ - if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CSC) { - if (LPC_USB->HcRhStatus & OR_RH_STATUS_DRWE) { - /* - * When DRWE is on, Connect Status Change - * means a remote wakeup event. - */ - HOST_RhscIntr = 1;// JUST SOMETHING FOR A BREAKPOINT - } - else { - /* - * When DRWE is off, Connect Status Change - * is NOT a remote wakeup event - */ - if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) { - if (!gUSBConnected) { - HOST_TDControlStatus = 0; - HOST_WdhIntr = 0; - HOST_RhscIntr = 1; - gUSBConnected = 1; - } - else - PRINT_Log("Spurious status change (connected)?\n"); - } else { - if (gUSBConnected) { - LPC_USB->HcInterruptEnable = 0; // why do we get multiple disc. rupts??? - HOST_RhscIntr = 0; - gUSBConnected = 0; - } - else - PRINT_Log("Spurious status change (disconnected)?\n"); - } - } - LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC; - } - if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRSC) { - LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; - } - } - if (int_status & OR_INTR_STATUS_WDH) { /* Writeback Done Head interrupt */ - HOST_WdhIntr = 1; - HOST_TDControlStatus = (TDHead->Control >> 28) & 0xf; - //UsbEndpoint Cb : TODO - //UsbEndpoint::completed(); - } - LPC_USB->HcInterruptStatus = int_status; /* Clear interrupt status register */ - } - return; -} - -/* -************************************************************************************************************** -* PROCESS TRANSFER DESCRIPTOR -* -* Description: This function processes the transfer descriptor -* -* Arguments : ed Endpoint descriptor that contains this transfer descriptor -* token SETUP, IN, OUT -* buffer Current Buffer Pointer of the transfer descriptor -* buffer_len Length of the buffer -* -* Returns : OK if TD submission is successful -* ERROR if TD submission fails -* -************************************************************************************************************** -*/ - -volatile USB_INT32U h; - -USB_INT32S Host_TDresult(volatile HCED *ed, - volatile USB_INT32U token) -{ - if(HOST_WdhIntr) - HOST_WdhIntr = 0; - else - __WFI(); - - if(ed->HeadTd == h) - { - return PROCESSING; - } - - if (!HOST_TDControlStatus) { - return (OK); - } else { - return (ERR_TD_FAIL); - } -} - -USB_INT32S Host_ProcessTD (volatile HCED *ed, - volatile USB_INT32U token, - volatile USB_INT08U *buffer, - USB_INT32U buffer_len, - bool block /* = true */ ) -{ - volatile USB_INT32U td_toggle; - - - if (ed == EDCtrl) { - if (token == TD_SETUP) { - td_toggle = TD_TOGGLE_0; - } else { - td_toggle = TD_TOGGLE_1; - } - } else { - td_toggle = 0; - } - TDHead->Control = (TD_ROUNDING | - token | - TD_DELAY_INT(0) | - td_toggle | - TD_CC); - TDTail->Control = 0; - TDHead->CurrBufPtr = (USB_INT32U) buffer; - TDTail->CurrBufPtr = 0; - TDHead->Next = (USB_INT32U) TDTail; - TDTail->Next = 0; - TDHead->BufEnd = (USB_INT32U)(buffer + (buffer_len - 1)); - TDTail->BufEnd = 0; - - h = ed->HeadTd = (USB_INT32U)TDHead | ((ed->HeadTd) & 0x00000002); - ed->TailTd = (USB_INT32U)TDTail; - ed->Next = 0; - - if (ed == EDCtrl) { - LPC_USB->HcControlHeadED = (USB_INT32U)ed; - LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_CLF; - LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_CLE; - } else { - LPC_USB->HcBulkHeadED = (USB_INT32U)ed; - LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_BLF; - LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_BLE; - } - - if(block) - { - while(ed->HeadTd == h) - { - Host_WDHWait(); - } - } - else - { - return PROCESSING; - } - -// if (!(TDHead->Control & 0xF0000000)) { - if (!HOST_TDControlStatus) { - return (OK); - } else { - return (ERR_TD_FAIL); - } -} - -/* -************************************************************************************************************** -* ENUMERATE THE DEVICE -* -* Description: This function is used to enumerate the device connected -* -* Arguments : None -* -* Returns : None -* -************************************************************************************************************** -*/ - -USB_INT32S Host_EnumDev (void) -{ - USB_INT32S rc; - - PRINT_Log("\r\nConnect a device\r\n"); - while (!HOST_RhscIntr) - __WFI(); - Host_DelayMS(100); /* USB 2.0 spec says atleast 50ms delay beore port reset */ - LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS; // Initiate port reset - while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS) - __WFI(); // Wait for port reset to complete... - LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; // ...and clear port reset signal - Host_DelayMS(200); /* Wait for 100 MS after port reset */ - - EDCtrl->Control = 8 << 16; /* Put max pkt size = 8 */ - /* Read first 8 bytes of device desc */ - rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, TDBuffer, 8); - if (rc != OK) { - PRINT_Err(rc); - return (rc); - } - EDCtrl->Control = TDBuffer[7] << 16; /* Get max pkt size of endpoint 0 */ - rc = HOST_SET_ADDRESS(1); /* Set the device address to 1 */ - if (rc != OK) { - PRINT_Err(rc); - return (rc); - } - Host_DelayMS(2); - EDCtrl->Control = (EDCtrl->Control) | 1; /* Modify control pipe with address 1 */ - - /**/ - - rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, TDBuffer, 17); //Read full device descriptor - if (rc != OK) { - PRINT_Err(rc); - return (rc); - } - - rc = SerialCheckVidPid(); - if (rc != OK) { - PRINT_Err(rc); - return (rc); - } - /**/ - /* Get the configuration descriptor */ - rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, TDBuffer, 9); - if (rc != OK) { - PRINT_Err(rc); - return (rc); - } - /* Get the first configuration data */ - rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, TDBuffer, ReadLE16U(&TDBuffer[2])); - if (rc != OK) { - PRINT_Err(rc); - return (rc); - } - #ifdef MS - rc = MS_ParseConfiguration(); /* Parse the configuration */ - if (rc != OK) { - PRINT_Err(rc); - return (rc); - } - #endif - PRINT_Log("\r\nParsing cfg\r\n"); - rc = SerialParseConfig(); /* Parse the configuration */ - if (rc != OK) { - PRINT_Err(rc); - return (rc); - } - - rc = USBH_SET_CONFIGURATION(1); /* Select device configuration 1 */ - if (rc != OK) { - PRINT_Err(rc); - } - Host_DelayMS(100); /* Some devices may require this delay */ - return (rc); -} - -/* -************************************************************************************************************** -* RECEIVE THE CONTROL INFORMATION -* -* Description: This function is used to receive the control information -* -* Arguments : bm_request_type -* b_request -* w_value -* w_index -* w_length -* buffer -* -* Returns : OK if Success -* ERROR if Failed -* -************************************************************************************************************** -*/ - -USB_INT32S Host_CtrlRecv ( USB_INT08U bm_request_type, - USB_INT08U b_request, - USB_INT16U w_value, - USB_INT16U w_index, - USB_INT16U w_length, - volatile USB_INT08U *buffer) -{ - USB_INT32S rc; - - - Host_FillSetup(bm_request_type, b_request, w_value, w_index, w_length); - rc = Host_ProcessTD(EDCtrl, TD_SETUP, TDBuffer, 8); - if (rc == OK) { - if (w_length) { - rc = Host_ProcessTD(EDCtrl, TD_IN, TDBuffer, w_length); - } - if (rc == OK) { - rc = Host_ProcessTD(EDCtrl, TD_OUT, NULL, 0); - } - } - return (rc); -} - -/* -************************************************************************************************************** -* SEND THE CONTROL INFORMATION -* -* Description: This function is used to send the control information -* -* Arguments : None -* -* Returns : OK if Success -* ERR_INVALID_BOOTSIG if Failed -* -************************************************************************************************************** -*/ - -USB_INT32S Host_CtrlSend ( USB_INT08U bm_request_type, - USB_INT08U b_request, - USB_INT16U w_value, - USB_INT16U w_index, - USB_INT16U w_length, - volatile USB_INT08U *buffer) -{ - USB_INT32S rc; - - - Host_FillSetup(bm_request_type, b_request, w_value, w_index, w_length); - - rc = Host_ProcessTD(EDCtrl, TD_SETUP, TDBuffer, 8); - if (rc == OK) { - if (w_length) { - rc = Host_ProcessTD(EDCtrl, TD_OUT, TDBuffer, w_length); - } - if (rc == OK) { - rc = Host_ProcessTD(EDCtrl, TD_IN, NULL, 0); - } - } - return (rc); -} - -/* -************************************************************************************************************** -* FILL SETUP PACKET -* -* Description: This function is used to fill the setup packet -* -* Arguments : None -* -* Returns : OK if Success -* ERR_INVALID_BOOTSIG if Failed -* -************************************************************************************************************** -*/ - -void Host_FillSetup (USB_INT08U bm_request_type, - USB_INT08U b_request, - USB_INT16U w_value, - USB_INT16U w_index, - USB_INT16U w_length) -{ - int i; - for (i=0;i<w_length;i++) - TDBuffer[i] = 0; - - TDBuffer[0] = bm_request_type; - TDBuffer[1] = b_request; - WriteLE16U(&TDBuffer[2], w_value); - WriteLE16U(&TDBuffer[4], w_index); - WriteLE16U(&TDBuffer[6], w_length); -} - - - -/* -************************************************************************************************************** -* INITIALIZE THE TRANSFER DESCRIPTOR -* -* Description: This function initializes transfer descriptor -* -* Arguments : Pointer to TD structure -* -* Returns : None -* -************************************************************************************************************** -*/ - -void Host_TDInit (volatile HCTD *td) -{ - - td->Control = 0; - td->CurrBufPtr = 0; - td->Next = 0; - td->BufEnd = 0; -} - -/* -************************************************************************************************************** -* INITIALIZE THE ENDPOINT DESCRIPTOR -* -* Description: This function initializes endpoint descriptor -* -* Arguments : Pointer to ED strcuture -* -* Returns : None -* -************************************************************************************************************** -*/ - -void Host_EDInit (volatile HCED *ed) -{ - - ed->Control = 0; - ed->TailTd = 0; - ed->HeadTd = 0; - ed->Next = 0; -} - -/* -************************************************************************************************************** -* INITIALIZE HOST CONTROLLER COMMUNICATIONS AREA -* -* Description: This function initializes host controller communications area -* -* Arguments : Pointer to HCCA -* -* Returns : -* -************************************************************************************************************** -*/ - -void Host_HCCAInit (volatile HCCA *hcca) -{ - USB_INT32U i; - - - for (i = 0; i < 32; i++) { - - hcca->IntTable[i] = 0; - hcca->FrameNumber = 0; - hcca->DoneHead = 0; - } - -} - -/* -************************************************************************************************************** -* WAIT FOR WDH INTERRUPT -* -* Description: This function is infinite loop which breaks when ever a WDH interrupt rises -* -* Arguments : None -* -* Returns : None -* -************************************************************************************************************** -*/ - -void Host_WDHWait (void) -{ - while (!HOST_WdhIntr) - __WFI(); - - HOST_WdhIntr = 0; -} - -/* -************************************************************************************************************** -* READ LE 32U -* -* Description: This function is used to read an unsigned integer from a character buffer in the platform -* containing little endian processor -* -* Arguments : pmem Pointer to the character buffer -* -* Returns : val Unsigned integer -* -************************************************************************************************************** -*/ - -USB_INT32U ReadLE32U (volatile USB_INT08U *pmem) -{ - USB_INT32U val = *(USB_INT32U*)pmem; -#ifdef __BIG_ENDIAN - return __REV(val); -#else - return val; -#endif -} - -/* -************************************************************************************************************** -* WRITE LE 32U -* -* Description: This function is used to write an unsigned integer into a charecter buffer in the platform -* containing little endian processor. -* -* Arguments : pmem Pointer to the charecter buffer -* val Integer value to be placed in the charecter buffer -* -* Returns : None -* -************************************************************************************************************** -*/ - -void WriteLE32U (volatile USB_INT08U *pmem, - USB_INT32U val) -{ -#ifdef __BIG_ENDIAN - *(USB_INT32U*)pmem = __REV(val); -#else - *(USB_INT32U*)pmem = val; -#endif -} - -/* -************************************************************************************************************** -* READ LE 16U -* -* Description: This function is used to read an unsigned short integer from a charecter buffer in the platform -* containing little endian processor -* -* Arguments : pmem Pointer to the charecter buffer -* -* Returns : val Unsigned short integer -* -************************************************************************************************************** -*/ - -USB_INT16U ReadLE16U (volatile USB_INT08U *pmem) -{ - USB_INT16U val = *(USB_INT16U*)pmem; -#ifdef __BIG_ENDIAN - return __REV16(val); -#else - return val; -#endif -} - -/* -************************************************************************************************************** -* WRITE LE 16U -* -* Description: This function is used to write an unsigned short integer into a charecter buffer in the -* platform containing little endian processor -* -* Arguments : pmem Pointer to the charecter buffer -* val Value to be placed in the charecter buffer -* -* Returns : None -* -************************************************************************************************************** -*/ - -void WriteLE16U (volatile USB_INT08U *pmem, - USB_INT16U val) -{ -#ifdef __BIG_ENDIAN - *(USB_INT16U*)pmem = (__REV16(val) & 0xFFFF); -#else - *(USB_INT16U*)pmem = val; -#endif -} - -/* -************************************************************************************************************** -* READ BE 32U -* -* Description: This function is used to read an unsigned integer from a charecter buffer in the platform -* containing big endian processor -* -* Arguments : pmem Pointer to the charecter buffer -* -* Returns : val Unsigned integer -* -************************************************************************************************************** -*/ - -USB_INT32U ReadBE32U (volatile USB_INT08U *pmem) -{ - USB_INT32U val = *(USB_INT32U*)pmem; -#ifdef __BIG_ENDIAN - return val; -#else - return __REV(val); -#endif -} - -/* -************************************************************************************************************** -* WRITE BE 32U -* -* Description: This function is used to write an unsigned integer into a charecter buffer in the platform -* containing big endian processor -* -* Arguments : pmem Pointer to the charecter buffer -* val Value to be placed in the charecter buffer -* -* Returns : None -* -************************************************************************************************************** -*/ - -void WriteBE32U (volatile USB_INT08U *pmem, - USB_INT32U val) -{ -#ifdef __BIG_ENDIAN - *(USB_INT32U*)pmem = val; -#else - *(USB_INT32U*)pmem = __REV(val); -#endif -} - -/* -************************************************************************************************************** -* READ BE 16U -* -* Description: This function is used to read an unsigned short integer from a charecter buffer in the platform -* containing big endian processor -* -* Arguments : pmem Pointer to the charecter buffer -* -* Returns : val Unsigned short integer -* -************************************************************************************************************** -*/ - -USB_INT16U ReadBE16U (volatile USB_INT08U *pmem) -{ - USB_INT16U val = *(USB_INT16U*)pmem; -#ifdef __BIG_ENDIAN - return val; -#else - return __REV16(val); -#endif -} - -/* -************************************************************************************************************** -* WRITE BE 16U -* -* Description: This function is used to write an unsigned short integer into the charecter buffer in the -* platform containing big endian processor -* -* Arguments : pmem Pointer to the charecter buffer -* val Value to be placed in the charecter buffer -* -* Returns : None -* -************************************************************************************************************** -*/ - -void WriteBE16U (volatile USB_INT08U *pmem, - USB_INT16U val) -{ -#ifdef __BIG_ENDIAN - *(USB_INT16U*)pmem = val; -#else - *(USB_INT16U*)pmem = (__REV16(val) & 0xFFFF); -#endif -} - -#ifdef __cplusplus -} -#endif - -#endif
--- a/drv/usb/USBHostLite/usbhost_lpc17xx.h Fri Jun 18 10:38:57 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,292 +0,0 @@ - -/* -Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -/* -************************************************************************************************************** -* NXP USB Host Stack -* -* (c) Copyright 2008, NXP SemiConductors -* (c) Copyright 2008, OnChip Technologies LLC -* All Rights Reserved -* -* www.nxp.com -* www.onchiptech.com -* -* File : usbhost_lpc17xx.h -* Programmer(s) : Ravikanth.P -* Version : -* -************************************************************************************************************** -*/ - -#ifndef USBHOST_LPC17xx_H -#define USBHOST_LPC17xx_H - -/* -************************************************************************************************************** -* INCLUDE HEADER FILES -************************************************************************************************************** -*/ - -#include "usbhost_inc.h" - -/* -************************************************************************************************************** -* PRINT CONFIGURATION -************************************************************************************************************** -*/ - -#define PRINT_ENABLE 1 - -#if PRINT_ENABLE -#define PRINT_Log(...) printf(__VA_ARGS__) -#define PRINT_Err(rc) printf("ERROR: In %s at Line %u - rc = %d\n", __FUNCTION__, __LINE__, rc) - -#else -#define PRINT_Log(...) do {} while(0) -#define PRINT_Err(rc) do {} while(0) - -#endif - -/* -************************************************************************************************************** -* GENERAL DEFINITIONS -************************************************************************************************************** -*/ - -#define DESC_LENGTH(x) x[0] -#define DESC_TYPE(x) x[1] - - -#define HOST_GET_DESCRIPTOR(descType, descIndex, data, length) \ - Host_CtrlRecv(USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR, \ - (descType << 8)|(descIndex), 0, length, data) - -#define HOST_SET_ADDRESS(new_addr) \ - Host_CtrlSend(USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE, SET_ADDRESS, \ - new_addr, 0, 0, NULL) - -#define USBH_SET_CONFIGURATION(configNum) \ - Host_CtrlSend(USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE, SET_CONFIGURATION, \ - configNum, 0, 0, NULL) - -#define USBH_SET_INTERFACE(ifNum, altNum) \ - Host_CtrlSend(USB_HOST_TO_DEVICE | USB_RECIPIENT_INTERFACE, SET_INTERFACE, \ - altNum, ifNum, 0, NULL) - -/* -************************************************************************************************************** -* OHCI OPERATIONAL REGISTER FIELD DEFINITIONS -************************************************************************************************************** -*/ - - /* ------------------ HcControl Register --------------------- */ -#define OR_CONTROL_CLE 0x00000010 -#define OR_CONTROL_BLE 0x00000020 -#define OR_CONTROL_HCFS 0x000000C0 -#define OR_CONTROL_HC_OPER 0x00000080 - /* ----------------- HcCommandStatus Register ----------------- */ -#define OR_CMD_STATUS_HCR 0x00000001 -#define OR_CMD_STATUS_CLF 0x00000002 -#define OR_CMD_STATUS_BLF 0x00000004 - /* --------------- HcInterruptStatus Register ----------------- */ -#define OR_INTR_STATUS_WDH 0x00000002 -#define OR_INTR_STATUS_RHSC 0x00000040 - /* --------------- HcInterruptEnable Register ----------------- */ -#define OR_INTR_ENABLE_WDH 0x00000002 -#define OR_INTR_ENABLE_RHSC 0x00000040 -#define OR_INTR_ENABLE_MIE 0x80000000 - /* ---------------- HcRhDescriptorA Register ------------------ */ -#define OR_RH_STATUS_LPSC 0x00010000 -#define OR_RH_STATUS_DRWE 0x00008000 - /* -------------- HcRhPortStatus[1:NDP] Register -------------- */ -#define OR_RH_PORT_CCS 0x00000001 -#define OR_RH_PORT_PRS 0x00000010 -#define OR_RH_PORT_CSC 0x00010000 -#define OR_RH_PORT_PRSC 0x00100000 - - -/* -************************************************************************************************************** -* FRAME INTERVAL -************************************************************************************************************** -*/ - -#define FI 0x2EDF /* 12000 bits per frame (-1) */ -#define DEFAULT_FMINTERVAL ((((6 * (FI - 210)) / 7) << 16) | FI) - -/* -************************************************************************************************************** -* ENDPOINT DESCRIPTOR CONTROL FIELDS -************************************************************************************************************** -*/ - -#define ED_SKIP (USB_INT32U) (0x00001000) /* Skip this ep in queue */ - -/* -************************************************************************************************************** -* TRANSFER DESCRIPTOR CONTROL FIELDS -************************************************************************************************************** -*/ - -#define TD_ROUNDING (USB_INT32U) (0x00040000) /* Buffer Rounding */ -#define TD_SETUP (USB_INT32U)(0) /* Direction of Setup Packet */ -#define TD_IN (USB_INT32U)(0x00100000) /* Direction In */ -#define TD_OUT (USB_INT32U)(0x00080000) /* Direction Out */ -#define TD_DELAY_INT(x) (USB_INT32U)((x) << 21) /* Delay Interrupt */ -#define TD_TOGGLE_0 (USB_INT32U)(0x02000000) /* Toggle 0 */ -#define TD_TOGGLE_1 (USB_INT32U)(0x03000000) /* Toggle 1 */ -#define TD_CC (USB_INT32U)(0xF0000000) /* Completion Code */ - -/* -************************************************************************************************************** -* USB STANDARD REQUEST DEFINITIONS -************************************************************************************************************** -*/ - -#define USB_DESCRIPTOR_TYPE_DEVICE 1 -#define USB_DESCRIPTOR_TYPE_CONFIGURATION 2 -#define USB_DESCRIPTOR_TYPE_INTERFACE 4 -#define USB_DESCRIPTOR_TYPE_ENDPOINT 5 - /* ----------- Control RequestType Fields ----------- */ -#define USB_DEVICE_TO_HOST 0x80 -#define USB_HOST_TO_DEVICE 0x00 -#define USB_REQUEST_TYPE_CLASS 0x20 -#define USB_RECIPIENT_DEVICE 0x00 -#define USB_RECIPIENT_INTERFACE 0x01 - /* -------------- USB Standard Requests -------------- */ -#define SET_ADDRESS 5 -#define GET_DESCRIPTOR 6 -#define SET_CONFIGURATION 9 -#define SET_INTERFACE 11 - -/* -************************************************************************************************************** -* TYPE DEFINITIONS -************************************************************************************************************** -*/ - -typedef struct hcEd { /* ----------- HostController EndPoint Descriptor ------------- */ - volatile USB_INT32U Control; /* Endpoint descriptor control */ - volatile USB_INT32U TailTd; /* Physical address of tail in Transfer descriptor list */ - volatile USB_INT32U HeadTd; /* Physcial address of head in Transfer descriptor list */ - volatile USB_INT32U Next; /* Physical address of next Endpoint descriptor */ -} HCED; - -typedef struct hcTd { /* ------------ HostController Transfer Descriptor ------------ */ - volatile USB_INT32U Control; /* Transfer descriptor control */ - volatile USB_INT32U CurrBufPtr; /* Physical address of current buffer pointer */ - volatile USB_INT32U Next; /* Physical pointer to next Transfer Descriptor */ - volatile USB_INT32U BufEnd; /* Physical address of end of buffer */ -} HCTD; - -typedef struct hcca { /* ----------- Host Controller Communication Area ------------ */ - volatile USB_INT32U IntTable[32]; /* Interrupt Table */ - volatile USB_INT32U FrameNumber; /* Frame Number */ - volatile USB_INT32U DoneHead; /* Done Head */ - volatile USB_INT08U Reserved[116]; /* Reserved for future use */ - volatile USB_INT08U Unknown[4]; /* Unused */ -} HCCA; - -/* -************************************************************************************************************** -* EXTERN DECLARATIONS -************************************************************************************************************** -*/ -#if 0 -extern volatile HCED *EDBulkIn; /* BulkIn endpoint descriptor structure */ -extern volatile HCED *EDBulkOut; /* BulkOut endpoint descriptor structure */ -extern volatile HCED *EDBulkHead; -extern volatile HCTD *TDHead; /* Head transfer descriptor structure */ -extern volatile HCTD *TDTail; /* Tail transfer descriptor structure */ -#endif -extern volatile USB_INT08U *TDBuffer; /* Current Buffer Pointer of transfer descriptor */ - -/* -************************************************************************************************************** -* FUNCTION PROTOTYPES -************************************************************************************************************** -*/ - -void Host_Init (void); - -extern "C" void USB_IRQHandler(void) __irq; - -USB_INT32S Host_EnumDev (void); - -USB_INT32S Host_TDresult(volatile HCED *ed, - volatile USB_INT32U token); - -USB_INT32S Host_ProcessTD(volatile HCED *ed, - volatile USB_INT32U token, - volatile USB_INT08U *buffer, - USB_INT32U buffer_len, - bool block = true); - - -void Host_DelayUS ( USB_INT32U delay); -void Host_DelayMS ( USB_INT32U delay); - - -void Host_TDInit (volatile HCTD *td); -void Host_EDInit (volatile HCED *ed); -void Host_HCCAInit (volatile HCCA *hcca); - -USB_INT32S Host_CtrlRecv ( USB_INT08U bm_request_type, - USB_INT08U b_request, - USB_INT16U w_value, - USB_INT16U w_index, - USB_INT16U w_length, - volatile USB_INT08U *buffer); - -USB_INT32S Host_CtrlSend ( USB_INT08U bm_request_type, - USB_INT08U b_request, - USB_INT16U w_value, - USB_INT16U w_index, - USB_INT16U w_length, - volatile USB_INT08U *buffer); - -void Host_FillSetup( USB_INT08U bm_request_type, - USB_INT08U b_request, - USB_INT16U w_value, - USB_INT16U w_index, - USB_INT16U w_length); - - -void Host_WDHWait (void); - - -USB_INT32U ReadLE32U (volatile USB_INT08U *pmem); -void WriteLE32U (volatile USB_INT08U *pmem, - USB_INT32U val); -USB_INT16U ReadLE16U (volatile USB_INT08U *pmem); -void WriteLE16U (volatile USB_INT08U *pmem, - USB_INT16U val); -USB_INT32U ReadBE32U (volatile USB_INT08U *pmem); -void WriteBE32U (volatile USB_INT08U *pmem, - USB_INT32U val); -USB_INT16U ReadBE16U (volatile USB_INT08U *pmem); -void WriteBE16U (volatile USB_INT08U *pmem, - USB_INT16U val); - -#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drv/usb/UsbDevice.cpp Fri Jul 09 14:46:47 2010 +0000 @@ -0,0 +1,291 @@ + +/* +Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "UsbDevice.h" + +#include "netCfg.h" +#if NET_USB + +//#define __DEBUG +#include "dbg/dbg.h" + +UsbDevice::UsbDevice( UsbHostMgr* pMgr, int hub, int port, int addr ) : m_pControlEp(NULL), /*m_controlEp( this, 0x00, false, USB_CONTROL, 8 ),*/ +m_pMgr(pMgr), m_connected(false), m_enumerated(false), m_hub(hub), m_port(port), m_addr(addr), m_refs(0), +m_vid(0), m_pid(0) +{ + +} + +UsbDevice::~UsbDevice() +{ + if(m_pControlEp) + delete m_pControlEp; +} + +UsbErr UsbDevice::enumerate() +{ + // USB_INT32S rc; + + UsbErr rc; + + DBG("Starting enumeration (m_pMgr = %p)\n", m_pMgr); + +#if 1 + m_pMgr->resetPort(m_hub, m_port); +#else + wait_ms(100); /* USB 2.0 spec says atleast 50ms delay beore port reset */ + LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS; // Initiate port reset + while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS) + __WFI(); // Wait for port reset to complete... + LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; // ...and clear port reset signal + wait_ms(200); /* Wait for 100 MS after port reset */ +#endif + + DBG("Port reset\n"); + + wait_ms(200); + + m_pControlEp = new UsbEndpoint( this, 0x00, false, USB_CONTROL, 8, 0 ); + + //EDCtrl->Control = 8 << 16;/* Put max pkt size = 8 */ + /* Read first 8 bytes of device desc */ + rc = controlReceive(USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR, (USB_DESCRIPTOR_TYPE_DEVICE << 8)|(0), 0, m_controlDataBuf, 8); + if (rc) + { + DBG("RC=%d",rc); + return (rc); + } + + DBG("Got descriptor, max ep size is %d\n", m_controlDataBuf[7]); + + m_pControlEp->updateSize(m_controlDataBuf[7]); /* Get max pkt size of endpoint 0 */ + rc = controlSend(USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE, SET_ADDRESS, m_addr, 0, NULL, 0); /* Set the device address to m_addr */ + if (rc) + { + // PRINT_Err(rc); + return (rc); + } + wait_ms(2); + //EDCtrl->Control = (EDCtrl->Control) | 1; /* Modify control pipe with address 1 */ + + //Update address + m_pControlEp->updateAddr(m_addr); + DBG("Ep addr is now %d", m_addr); + /**/ + + //rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, TDBuffer, 17); //Read full device descriptor + rc = controlReceive(USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR, (USB_DESCRIPTOR_TYPE_DEVICE << 8)|(0), 0, m_controlDataBuf, 17); + if (rc) + { + //PRINT_Err(rc); + return (rc); + } + /* + rc = SerialCheckVidPid(); + if (rc != OK) { + PRINT_Err(rc); + return (rc); + } + */ + /**/ + + m_vid = *((uint16_t*)&m_controlDataBuf[8]); + m_pid = *((uint16_t*)&m_controlDataBuf[10]); + + DBG("VID: %02x, PID: %02x\n", m_vid, m_pid); + /* Get the configuration descriptor */ + //rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, TDBuffer, 9); + rc = controlReceive(USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR, (USB_DESCRIPTOR_TYPE_CONFIGURATION << 8)|(0), 0, m_controlDataBuf, 9); + if (rc) + { + //PRINT_Err(rc); + return (rc); + } + /* Get the first configuration data */ + //rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, TDBuffer, *((uint16_t*)&TDBuffer[2])); + rc = controlReceive(USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR, (USB_DESCRIPTOR_TYPE_CONFIGURATION << 8)|(0), 0, m_controlDataBuf, *((uint16_t*)&m_controlDataBuf[2])); + if (rc) + { + //PRINT_Err(rc); + return (rc); + } + + DBG("Desc len is %d\n", *((uint16_t*)&m_controlDataBuf[2])); + + DBG("Set configuration\n"); + + //rc = USBH_SET_CONFIGURATION(1);/* Select device configuration 1 */ + rc = controlSend(USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE, SET_CONFIGURATION, 1, 0, NULL, 0); + if (rc) + { + // PRINT_Err(rc); + return rc; + } + wait_ms(100);/* Some devices may require this delay */ + + m_enumerated = true; + return USBERR_OK; +} + +bool UsbDevice::connected() +{ + return m_connected; +} + +bool UsbDevice::enumerated() +{ + return m_enumerated; +} + +int UsbDevice::getPid() +{ + return m_pid; +} + +int UsbDevice::getVid() +{ + return m_vid; +} + +UsbErr UsbDevice::getConfigurationDescriptor(int config, uint8_t** pBuf) +{ + //For now olny one config + *pBuf = m_controlDataBuf; + return USBERR_OK; +} + +UsbErr UsbDevice::getInterfaceDescriptor(int config, int item, uint8_t** pBuf) +{ + byte* desc_ptr = m_controlDataBuf; + +/* if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_CONFIGURATION) + { + return USBERR_BADCONFIG; + }*/ + + if(item>=m_controlDataBuf[4])//Interfaces count + return USBERR_NOTFOUND; + + desc_ptr += desc_ptr[0]; + + *pBuf = NULL; + + while (desc_ptr < m_controlDataBuf + *((uint16_t*)&m_controlDataBuf[2])) + { + + switch (desc_ptr[1]) { + case USB_DESCRIPTOR_TYPE_INTERFACE: + if(desc_ptr[2] == item) + { + *pBuf = desc_ptr; + return USBERR_OK; + } + desc_ptr += desc_ptr[0]; // Move to next descriptor start + break; + } + + } + + if(*pBuf == NULL) + return USBERR_NOTFOUND; + + return USBERR_OK; +} + + +UsbErr UsbDevice::setConfiguration(int config) +{ + return USBERR_OK; +} + +UsbErr UsbDevice::controlSend(byte requestType, byte request, word value, word index, const byte* buf, int len) +{ + UsbErr rc; + fillControlBuf(requestType, request, value, index, len); + m_pControlEp->setNextToken(TD_SETUP); + rc = m_pControlEp->transfer(m_controlBuf, 8); + while(m_pControlEp->status() == USBERR_PROCESSING); + rc = (UsbErr) MIN(0, m_pControlEp->status()); + if(rc) + return rc; + if(len) + { + m_pControlEp->setNextToken(TD_OUT); + rc = m_pControlEp->transfer((byte*)buf, len); + while(m_pControlEp->status() == USBERR_PROCESSING); + rc = (UsbErr) MIN(0, m_pControlEp->status()); + if(rc) + return rc; + } + m_pControlEp->setNextToken(TD_IN); + rc = m_pControlEp->transfer(NULL, 0); + while(m_pControlEp->status() == USBERR_PROCESSING); + rc = (UsbErr) MIN(0, m_pControlEp->status()); + if(rc) + return rc; + return USBERR_OK; +} + +UsbErr UsbDevice::controlReceive(byte requestType, byte request, word value, word index, const byte* buf, int len) +{ + UsbErr rc; + fillControlBuf(requestType, request, value, index, len); + m_pControlEp->setNextToken(TD_SETUP); + rc = m_pControlEp->transfer(m_controlBuf, 8); + while(m_pControlEp->status() == USBERR_PROCESSING); + rc = (UsbErr) MIN(0, m_pControlEp->status()); + if(rc) + return rc; + if(len) + { + m_pControlEp->setNextToken(TD_IN); + rc = m_pControlEp->transfer( (byte*) buf, len); + while(m_pControlEp->status() == USBERR_PROCESSING); + rc = (UsbErr) MIN(0, m_pControlEp->status()); + if(rc) + return rc; + } + m_pControlEp->setNextToken(TD_OUT); + rc = m_pControlEp->transfer(NULL, 0); + while(m_pControlEp->status() == USBERR_PROCESSING); + rc = (UsbErr) MIN(0, m_pControlEp->status()); + if(rc) + return rc; + return USBERR_OK; +} + +void UsbDevice::fillControlBuf(byte requestType, byte request, word value, word index, int len) +{ +#ifdef __BIG_ENDIAN + #error "Must implement BE to LE conv here" +#endif + m_controlBuf[0] = requestType; + m_controlBuf[1] = request; + //We are in LE so it's fine + *((word*)&m_controlBuf[2]) = value; + *((word*)&m_controlBuf[4]) = index; + *((word*)&m_controlBuf[6]) = (word) len; +} + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drv/usb/UsbDevice.h Fri Jul 09 14:46:47 2010 +0000 @@ -0,0 +1,87 @@ + +/* +Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef USB_DEVICE_H +#define USB_DEVICE_H + +#include "mbed.h" +#include "UsbInc.h" +#include "UsbEndpoint.h" +#include "UsbHostMgr.h" + +class UsbHostMgr; +class UsbEndpoint; + +class UsbDevice +{ +protected: + UsbDevice( UsbHostMgr* pMgr, int hub, int port, int addr ); + ~UsbDevice(); + + UsbErr enumerate(); + +public: + bool connected(); + bool enumerated(); + + int getPid(); + int getVid(); + + UsbErr getConfigurationDescriptor(int config, uint8_t** pBuf); + + UsbErr getInterfaceDescriptor(int config, int item, uint8_t** pBuf); + + UsbErr setConfiguration(int config); + + + UsbErr controlSend(byte requestType, byte request, word value, word index, const byte* buf, int len); + UsbErr controlReceive(byte requestType, byte request, word value, word index, const byte* buf, int len); + +protected: + void fillControlBuf(byte requestType, byte request, word value, word index, int len); +private: + friend class UsbEndpoint; + friend class UsbHostMgr; + + UsbEndpoint* m_pControlEp; + + UsbHostMgr* m_pMgr; + + bool m_connected; + bool m_enumerated; + + int m_hub; + int m_port; + int m_addr; + + int m_refs; + + uint16_t m_vid; + uint16_t m_pid; + + byte m_controlBuf[8];//8 + byte m_controlDataBuf[/*128*/256]; + +}; + +#endif
--- a/drv/usb/UsbEndpoint.cpp Fri Jun 18 10:38:57 2010 +0000 +++ b/drv/usb/UsbEndpoint.cpp Fri Jul 09 14:46:47 2010 +0000 @@ -23,272 +23,369 @@ #include "UsbEndpoint.h" +#include "UsbDevice.h" + +#include "usb_mem.h" + #include "netCfg.h" #if NET_USB -EdPool::EdPool(int size) : m_pos(0) -{ - m_pool = new uint8_t[2*size*0x10]; - printf("\r\n--HCED* m_pool= %p of size %d--\r\n", m_pool, 2*size*0x10); -} - -EdPool::~EdPool() -{ - printf("\r\n--~EdPool()--\r\n"); - delete[] m_pool; -} +//#define __DEBUG +#include "dbg/dbg.h" -HCED* EdPool::get() -{ - printf("\r\n--HCED* &m_pool[m_pos]= %p--\r\n", &m_pool[m_pos]); - while( ( ((uint32_t)&m_pool[m_pos]) & 0xF ) != 0 ) - { - m_pos++; - } - HCED* pEd = (HCED*) &m_pool[m_pos]; - m_pos += sizeof(HCED); - printf("\r\n--HCED* pEd = %p--\r\n", pEd); - return pEd; -} - -TdPool::TdPool(int size) : m_pos(0) -{ - m_pool = new uint8_t[2*size*0x10]; - printf("\r\n--HCTD* m_pool= %p of size %d--\r\n", m_pool, 2*size*0x10); -} - -TdPool::~TdPool() -{ - printf("\r\n--~EdPool()--\r\n"); - delete[] m_pool; -} - -HCTD* TdPool::get() +UsbEndpoint::UsbEndpoint( UsbDevice* pDevice, uint8_t ep, bool dir, UsbEndpointType type, uint16_t size, int addr /*= -1*/ ) : m_pDevice(pDevice), m_result(true), m_status((int)USBERR_OK), m_len(0), m_pBufStartPtr(NULL), +m_pCbItem(NULL), m_pCbMeth(NULL), m_pNextEp(NULL) { - printf("\r\n--HCTD* &m_pool[m_pos]= %p--\r\n", &m_pool[m_pos]); - while( ( ((uint32_t)&m_pool[m_pos]) & 0xF ) != 0 ) + //Insert into Eps list + //FIXME: Assert that no USB interrupt is triggered meanwhile + if(m_pHeadEp) { - m_pos++; - } - HCTD* pTd = (HCTD*) &m_pool[m_pos]; - m_pos += sizeof(HCTD); - printf("\r\n--HCTD* pTd = %p--\r\n", pTd); - return pTd; -} -//uint8_t TdPool::pool[16*0x10]={0};//Ok for 2 Eps (2*(2Tds/Ep*2Eps)) -//int TdPool::pos = 0; + m_pNextEp = m_pHeadEp; + m_pHeadEp = this; + } + else + { + m_pNextEp = NULL; + m_pHeadEp = this; + } -extern volatile HCED* EDBulkHead; -//volatile HCED* UsbEndpoint::m_pNextEd = NULL; - -UsbEndpoint::UsbEndpoint( /* UsbDevice*, */ uint8_t ep, bool dir, uint16_t size ) : m_edPool(1), m_tdPool(2), m_done(true), m_len(0), m_pBufStartPtr(NULL) -{ - #if 1 + m_pEd = (volatile HCED*)usb_get_ed(); - m_pEd = m_edPool.get(); - - #else - if(m_pNextEd == NULL) - { - m_pNextEd = EDBulkHead; - //printf("\r\n--m_pEd = %p < EDBulkHead = %p --\r\n", m_pEd, EDBulkHead); - } + m_pTdHead = (volatile HCTD*)usb_get_td(); + m_pTdTail = (volatile HCTD*)usb_get_td(); - printf("\r\n--Ep Inst--\r\n"); - m_pEd = /*new HCED(); // */m_pNextEd; - - //printf("\r\n--m_pNextEd = %p--\r\n", m_pNextEd); - m_pNextEd += 1; //TODO: Avail mem check - //printf("\r\n--m_pNextEd = %p--\r\n", m_pNextEd); - #endif - - m_pTdHead = m_tdPool.get();//new HCTD(); - m_pTdTail = m_tdPool.get();//new HCTD(); - - printf("\r\n--m_pEd = %p--\r\n", m_pEd); + //printf("\r\n--m_pEd = %p--\r\n", m_pEd); //Init Ed & Td - printf("\r\n--Ep Init--\r\n"); - Host_EDInit(m_pEd); - printf("\r\n--Td Init--\r\n"); - Host_TDInit(m_pTdHead); - Host_TDInit(m_pTdTail); + //printf("\r\n--Ep Init--\r\n"); + memset((void*)m_pEd, 0, sizeof(HCED)); + //printf("\r\n--Td Init--\r\n"); + + memset((void*)m_pTdHead, 0, sizeof(HCTD)); + memset((void*)m_pTdTail, 0, sizeof(HCTD)); + + if(addr == -1) + addr = pDevice->m_addr; //Setup Ed - printf("\r\n--Ep Setup--\r\n"); - m_pEd->Control = 1 | /* USB address */ //FIXME: Device Id + //printf("\r\n--Ep Setup--\r\n"); + m_pEd->Control = addr | /* USB address */ ((ep & 0x7F) << 7) | /* Endpoint address */ - ((dir?2:1) << 11) | /* direction : Out = 1, 2 = In */ + (type!=USB_CONTROL?((dir?2:1) << 11):0) | /* direction : Out = 1, 2 = In */ (size << 16); /* MaxPkt Size */ m_dir = dir; + m_setup = false; + m_type = type; - m_pEd->TailTd = m_pEd->HeadTd = (USB_INT32U) m_pTdTail; //Empty TD list + m_pEd->TailTd = m_pEd->HeadTd = (uint32_t) m_pTdTail; //Empty TD list + + DBG("Before link\n"); - printf("\r\n--Ep Reg--\r\n"); - //Append Ed to bulk Ep list - #if 1 - volatile HCED* prevEd = (volatile HCED*) LPC_USB->HcBulkHeadED; - m_pEd->Next = (USB_INT32U) prevEd; - LPC_USB->HcBulkHeadED = (USB_INT32U) m_pEd; - #else - if( LPC_USB->HcBulkHeadED == 0 ) + //printf("\r\n--Ep Reg--\r\n"); + //Append Ed to Ed list + volatile HCED* prevEd; + switch( m_type ) { - LPC_USB->HcBulkHeadED = (USB_INT32U)m_pEd; - printf("\r\n--Bulk head--\r\n"); + case USB_CONTROL: + prevEd = (volatile HCED*) LPC_USB->HcControlHeadED; + break; + case USB_BULK: + default: + prevEd = (volatile HCED*) LPC_USB->HcBulkHeadED; + break; + } + + DBG("prevEd is %p\n", prevEd); + + if(prevEd) + { + DBG("prevEd set\n") + + while(prevEd->Next) + { + DBG("prevEd->Next = %08x\n", prevEd->Next); + prevEd = (volatile HCED*) prevEd->Next; + } + prevEd->Next = (uint32_t) m_pEd; + } else { - volatile HCED* prevEd = (volatile HCED*) LPC_USB->HcBulkHeadED; - while(prevEd->Next) + switch( m_type ) { - prevEd = (volatile HCED*) prevEd->Next; + case USB_CONTROL: + LPC_USB->HcControlHeadED = (uint32_t) m_pEd; + break; + case USB_BULK: + default: + LPC_USB->HcBulkHeadED = (uint32_t) m_pEd; + break; } - printf("\r\n--Appended to ep list (prevEd = %p)--\r\n", prevEd); - prevEd->Next = (USB_INT32U) m_pEd; } - #endif - /* - printf("\r\n--Writing config reg--\r\n"); - LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_BLF; - LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_BLE; - */ + + DBG("Ep init\n"); } UsbEndpoint::~UsbEndpoint() { + //Remove from Eps list + //FIXME: Assert that no USB interrupt is triggered meanwhile + if(m_pHeadEp != this) + { + UsbEndpoint* prevEp = m_pHeadEp; + while(prevEp->m_pNextEp != this) + prevEp = prevEp->m_pNextEp; + prevEp->m_pNextEp = m_pNextEp; + } + else + { + m_pHeadEp = m_pNextEp; + } + m_pEd->Control |= ED_SKIP; //Skip this Ep in queue //Remove from queue - if( LPC_USB->HcBulkHeadED == (USB_INT32U) m_pEd ) + volatile HCED* prevEd; + switch( m_type ) { + case USB_CONTROL: + prevEd = (volatile HCED*) LPC_USB->HcControlHeadED; + break; + case USB_BULK: + default: + prevEd = (volatile HCED*) LPC_USB->HcBulkHeadED; + break; + } + if( m_pEd == prevEd ) + { + switch( m_type ) + { + case USB_CONTROL: + LPC_USB->HcControlHeadED = m_pEd->Next; + break; + case USB_BULK: + default: + LPC_USB->HcBulkHeadED = m_pEd->Next; + break; + } LPC_USB->HcBulkHeadED = m_pEd->Next; } else { - volatile HCED* prevEd = (volatile HCED*) LPC_USB->HcBulkHeadED; - while( prevEd->Next != (USB_INT32U) m_pEd ) + while( prevEd->Next != (uint32_t) m_pEd ) { prevEd = (volatile HCED*) prevEd->Next; } prevEd->Next = m_pEd->Next; } - if( LPC_USB->HcBulkCurrentED == (USB_INT32U) m_pEd ) - { - LPC_USB->HcBulkCurrentED = 0; - } - + // + usb_free_ed((volatile byte*)m_pEd); - #if 0 //NO WAY! Owned by pool!!! - delete m_pEd; - delete m_pTdHead; - delete m_pTdTail; - #endif + usb_free_td((volatile byte*)m_pTdHead); + usb_free_td((volatile byte*)m_pTdTail); +} + +void UsbEndpoint::setNextToken(uint32_t token) //Only for control Eps +{ + switch(token) + { + case TD_SETUP: + m_dir = false; + m_setup = true; + break; + case TD_IN: + m_dir = true; + m_setup = false; + break; + case TD_OUT: + m_dir = false; + m_setup = false; + break; + } } -RC UsbEndpoint::transfer(volatile uint8_t* buf, uint32_t len) +UsbErr UsbEndpoint::transfer(volatile uint8_t* buf, uint32_t len) { - if(!m_done) - return ERR_TD_FAIL; - volatile USB_INT32U token = (m_dir?TD_IN:TD_OUT); - //printf("\r\n--m_pEd->HeadTd = %16x, m_pTdHead = %16x, m_pEd->TailTd = %16x, m_pTdTail = %16x--\r\n",m_pEd->HeadTd,(USB_INT32U)m_pTdHead,m_pEd->TailTd,(USB_INT32U)m_pTdTail); + if(!m_result) + return USBERR_BUSY; //The previous trasnfer is not completed + //FIXME: We should be able to queue the next transfer, still needs to be implemented + + if( !m_pDevice->connected() ) + return USBERR_DISCONNECTED; + + m_result = false; + + volatile uint32_t token = (m_setup?TD_SETUP:(m_dir?TD_IN:TD_OUT)); + + volatile uint32_t td_toggle; + if (m_type == USB_CONTROL) + { + if (m_setup) + { + td_toggle = TD_TOGGLE_0; + } + else + { + td_toggle = TD_TOGGLE_1; + } + } + else + { + td_toggle = 0; + } //Swap Tds - //printf("\r\n--Swap Tds--\r\n"); - volatile HCTD* pTdSwap; - pTdSwap = m_pTdTail; - m_pTdTail = m_pTdHead; - m_pTdHead = pTdSwap; - - - // printf("\r\n--m_pEd->HeadTd = %16x, m_pTdHead = %16x, m_pEd->TailTd = %16x, m_pTdTail = %16x--\r\n",m_pEd->HeadTd,(USB_INT32U)m_pTdHead,m_pEd->TailTd,(USB_INT32U)m_pTdTail); - - // printf("\r\n--Tds setup--\r\n"); - m_pTdHead->Control = (TD_ROUNDING | - token | - // TD_DELAY_INT(0) | - TD_DELAY_INT(7) | - TD_CC); - m_pTdTail->Control = 0; - m_pTdHead->CurrBufPtr = (USB_INT32U) buf; - m_pBufStartPtr = buf; - m_pTdTail->CurrBufPtr = 0; - m_pTdHead->Next = (USB_INT32U) m_pTdTail; - m_pTdTail->Next = 0; - m_pTdHead->BufEnd = (USB_INT32U)(buf + (len - 1)); - m_pTdTail->BufEnd = 0; - -// printf("\r\n--Ed setup--\r\n"); -// m_pEd->HeadTd = (USB_INT32U)m_pTdHead | ((m_pEd->HeadTd) & 0x00000002); - m_pEd->HeadTd = (USB_INT32U)m_pTdHead | ((m_pEd->HeadTd) & 0x00000002); //Carry bit - m_pEd->TailTd = (USB_INT32U)m_pTdTail; -/* - printf("\r\n--Swap Tds--\r\n"); volatile HCTD* pTdSwap; pTdSwap = m_pTdTail; m_pTdTail = m_pTdHead; m_pTdHead = pTdSwap; - */ -// ed->Next = 0; + + m_pTdHead->Control = (TD_ROUNDING | + token | + TD_DELAY_INT(0) |//7 + td_toggle | + TD_CC); - //printf("\r\n--m_pEd->HeadTd = %16x, m_pTdHead = %16x, m_pEd->TailTd = %16x, m_pTdTail = %16x--\r\n",m_pEd->HeadTd,(USB_INT32U)m_pTdHead,m_pEd->TailTd,(USB_INT32U)m_pTdTail); + m_pTdTail->Control = 0; + m_pTdHead->CurrBufPtr = (uint32_t) buf; + m_pBufStartPtr = buf; + m_pTdTail->CurrBufPtr = 0; + m_pTdHead->Next = (uint32_t) m_pTdTail; + m_pTdTail->Next = 0; + m_pTdHead->BufEnd = (uint32_t)(buf + (len - 1)); + m_pTdTail->BufEnd = 0; - // printf("\r\n--Writing config reg--\r\n"); - LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_BLF; - LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_BLE; + m_pEd->HeadTd = (uint32_t)m_pTdHead | ((m_pEd->HeadTd) & 0x00000002); //Carry bit + m_pEd->TailTd = (uint32_t)m_pTdTail; - // printf("\r\n--Processing queue--\r\n"); - // __WFI(); - m_done = false; + //DBG("m_pEd->HeadTd = %08x\n", m_pEd->HeadTd); + + if(m_type == USB_CONTROL) + { + LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_CLF; + LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_CLE; //Enable control list + } + else //USB_BULK + { + LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_BLF; + LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_BLE; //Enable bulk list + } + + //m_done = false; m_len = len; - return PROCESSING; + + return USBERR_PROCESSING; } -RC UsbEndpoint::status() +int UsbEndpoint::status() { - if( m_done ) + if( !m_pDevice->connected() ) { - return OK; + if(!m_result) + onCompletion(); + m_result = true; + return (int)USBERR_DISCONNECTED; } - //volatile HCTD* pTd = (volatile HCTD*) m_pEd->HeadTd; - //printf("\r\nm_pTdHead->CurrBufPtr = %16x", m_pTdHead->CurrBufPtr); - //printf("\r\n--m_pEd->HeadTd = %16x, m_pTdHead = %16x, m_pEd->TailTd = %16x, m_pTdTail = %16x--\r\n",m_pEd->HeadTd,(USB_INT32U)m_pTdHead,m_pEd->TailTd,(USB_INT32U)m_pTdTail); - //if( pTd->CurrBufPtr == 0 /*m_pEd->HeadTd != (USB_INT32U)m_pTdHead*//*m_pEd->HeadTd == (USB_INT32U)m_pTdTail*/) //Empty queue - else if( (m_pEd->HeadTd & ~0xF) == (USB_INT32U) m_pTdTail ) + else if( !m_result ) + { + return (int)USBERR_PROCESSING; + } + /*else if( m_done ) + { + return (int)USBERR_OK; + }*/ + else { - //Done - //printf("\r\n--m_pEd->HeadTd = %16x, m_pTdHead = %16x, m_pEd->TailTd = %16x, m_pTdTail = %16x--\r\n",m_pEd->HeadTd,(USB_INT32U)m_pTdHead,m_pEd->TailTd,(USB_INT32U)m_pTdTail); - int len; - if(m_pTdHead->CurrBufPtr) - len = m_pTdHead->CurrBufPtr - (USB_INT32U)m_pBufStartPtr; //Does not work properly, packet might have been discarded - else - len = m_len; -// printf("\r\nDone w/ len = %d (m_pTdHead->CurrBufPtr=%16x)\r\n", len, m_pTdHead->CurrBufPtr); - if(len == 0) //Packet transfered completely - len = m_len; - //Host_TDInit(m_pTdTail); - //m_pEd->TailTd = m_pEd->HeadTd = (USB_INT32U) m_pTdTail; //Empty TD list - - // printf("\r\n--Writing config reg--\r\n"); - //LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_BLF; - //LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_BLE; - - m_done = true; - return len; - //return OK; + return m_status; + } +} + +void UsbEndpoint::updateAddr(int addr) +{ + DBG("m_pEd->Control = %08x\n", m_pEd->Control); + m_pEd->Control &= ~0x7F; + m_pEd->Control |= addr; + DBG("m_pEd->Control = %08x\n", m_pEd->Control); +} + +void UsbEndpoint::updateSize(uint16_t size) +{ + DBG("m_pEd->Control = %08x\n", m_pEd->Control); + m_pEd->Control &= ~0x3FF0000; + m_pEd->Control |= (size << 16); + DBG("m_pEd->Control = %08x\n", m_pEd->Control); +} + +#if 0 //For doc only +template <class T> +void UsbEndpoint::setOnCompletion( T* pCbItem, void (T::*pCbMeth)() ) +{ + m_pCbItem = (CDummy*) pCbItem; + m_pCbMeth = (void (CDummy::*)()) pCbMeth; +} +#endif + +void UsbEndpoint::onCompletion() +{ + DBG("Transfer completed\n"); + if( m_pTdHead->Control >> 28 ) + { + DBG("\r\nTD Failed with condition code %01x\r\n", m_pTdHead->Control >> 28 ); + m_status = (int)USBERR_TDFAIL; } else if( m_pEd->HeadTd & 0x1 ) { - printf("\r\nHALTED!!\r\n"); - return ERR_TD_FAIL; + m_pEd->HeadTd = m_pEd->HeadTd & ~0x1; + DBG("\r\nHALTED!!\r\n"); + m_status = (int)USBERR_HALTED; + } + else if( (m_pEd->HeadTd & ~0xF) == (uint32_t) m_pTdTail ) + { + //Done + int len; + DBG("m_pTdHead->CurrBufPtr = %08x, m_pBufStartPtr=%08x\n", m_pTdHead->CurrBufPtr, (uint32_t) m_pBufStartPtr); + if(m_pTdHead->CurrBufPtr) + len = m_pTdHead->CurrBufPtr - (uint32_t) m_pBufStartPtr; + else + len = m_len; + /*if(len == 0) //Packet transfered completely + len = m_len;*/ + //m_done = true; + DBG("Transfered %d bytes\n", len); + m_status = len; } else - { - // wait(1); - return PROCESSING; + { + DBG("\r\nUnknown error...\r\n"); + m_status = (int)USBERR_ERROR; } + m_result = true; + if(m_pCbItem && m_pCbMeth) + (m_pCbItem->*m_pCbMeth)(); } +void UsbEndpoint::sOnCompletion(uint32_t pTd) +{ + if(!m_pHeadEp) + return; + do + { + DBG("sOnCompletion (pTd = %08x)\n", pTd); + UsbEndpoint* pEp = m_pHeadEp; + do + { + if((uint32_t)pEp->m_pTdHead == pTd) + { + pEp->onCompletion(); + break; + } + } while(pEp = pEp->m_pNextEp); + } while( pTd = (uint32_t)( ((HCTD*)pTd)->Next ) ); //Go around the Done queue +} + +UsbEndpoint* UsbEndpoint::m_pHeadEp = NULL; + #endif
--- a/drv/usb/UsbEndpoint.h Fri Jun 18 10:38:57 2010 +0000 +++ b/drv/usb/UsbEndpoint.h Fri Jul 09 14:46:47 2010 +0000 @@ -25,55 +25,63 @@ #define USB_ENDPOINT_H #include "mbed.h" -#include "USBHostLite/usbhost_inc.h" +#include "UsbInc.h" -typedef int32_t RC; +class UsbDevice; -class EdPool +enum UsbEndpointType { -public: - EdPool(int size); - ~EdPool(); - HCED* get(); -private: - uint8_t* m_pool; - int m_pos; - -}; - -class TdPool -{ -public: - TdPool(int size); - ~TdPool(); - HCTD* get(); -private: - uint8_t* m_pool; - int m_pos; - + USB_CONTROL, + USB_BULK +// USB_INT, +// USB_ISO }; class UsbEndpoint { public: - UsbEndpoint( /* UsbDevice*, */ uint8_t ep, bool dir, uint16_t size ); + UsbEndpoint( UsbDevice* pDevice, uint8_t ep, bool dir, UsbEndpointType type, uint16_t size, int addr = -1 ); ~UsbEndpoint(); - RC transfer(volatile uint8_t* buf, uint32_t len); + void setNextToken(uint32_t token); //Only for control Eps + + UsbErr transfer(volatile uint8_t* buf, uint32_t len); + + int status(); //return UsbErr or transfered len + + void updateAddr(int addr); + void updateSize(uint16_t size); - RC status(); - + //void setOnCompletion( void(*pCb)completed() ); + class CDummy; + template <class T> + void setOnCompletion( T* pCbItem, void (T::*pCbMeth)() ) + { + m_pCbItem = (CDummy*) pCbItem; + m_pCbMeth = (void (CDummy::*)()) pCbMeth; + } + //static void completed(){} +protected: + void onCompletion(); +public: + static void sOnCompletion(uint32_t pTd); + private: - EdPool m_edPool; - TdPool m_tdPool; + friend class UsbDevice; + + UsbDevice* m_pDevice; bool m_dir; + bool m_setup; + UsbEndpointType m_type; - bool m_done; + //bool m_done; + volatile bool m_result; + volatile int m_status; - uint32_t m_len; + volatile uint32_t m_len; volatile uint8_t* m_pBufStartPtr; @@ -83,6 +91,13 @@ //static volatile HCED* m_pNextEd; + CDummy* m_pCbItem; + void (CDummy::*m_pCbMeth)(); + + + static UsbEndpoint* m_pHeadEp; + UsbEndpoint* m_pNextEp; + }; #endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drv/usb/UsbHostMgr.cpp Fri Jul 09 14:46:47 2010 +0000 @@ -0,0 +1,358 @@ + +/* +Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "UsbHostMgr.h" + +#include "usb_mem.h" + +#include "string.h" //For memcpy, memmove, memset + +#include "netCfg.h" +#if NET_USB + +//#define __DEBUG +#include "dbg/dbg.h" + +// bits of the USB/OTG clock control register +#define HOST_CLK_EN (1<<0) +#define DEV_CLK_EN (1<<1) +#define PORTSEL_CLK_EN (1<<3) +#define AHB_CLK_EN (1<<4) + +// bits of the USB/OTG clock status register +#define HOST_CLK_ON (1<<0) +#define DEV_CLK_ON (1<<1) +#define PORTSEL_CLK_ON (1<<3) +#define AHB_CLK_ON (1<<4) + +// we need host clock, OTG/portsel clock and AHB clock +#define CLOCK_MASK (HOST_CLK_EN | PORTSEL_CLK_EN | AHB_CLK_EN) + +static UsbHostMgr* pMgr = NULL; + +extern "C" void sUsbIrqhandler(void) __irq +{ + DBG("\n+Int\n"); + if(pMgr) + pMgr->UsbIrqhandler(); + DBG("\n-Int\n"); + return; +} + +UsbHostMgr::UsbHostMgr() : m_lpDevices() +{ + if(!pMgr) + pMgr = this; + usb_mem_init(); + memset(m_lpDevices, NULL, sizeof(UsbDevice*) * USB_HOSTMGR_MAX_DEVS); + m_pHcca = (HCCA*) usb_get_hcca(); + memset((void*)m_pHcca, 0, 0x100); + DBG("Host manager at %p\n", this); +} + +UsbHostMgr::~UsbHostMgr() +{ + if(pMgr == this) + pMgr = NULL; +} + +UsbErr UsbHostMgr::init() //Initialize host +{ + NVIC_DisableIRQ(USB_IRQn); /* Disable the USB interrupt source */ + + LPC_SC->PCONP &= ~(1UL<<31); //Cut power + wait(1); + + + // turn on power for USB + LPC_SC->PCONP |= (1UL<<31); + // Enable USB host clock, port selection and AHB clock + LPC_USB->USBClkCtrl |= CLOCK_MASK; + // Wait for clocks to become available + while ((LPC_USB->USBClkSt & CLOCK_MASK) != CLOCK_MASK) + ; + + // it seems the bits[0:1] mean the following + // 0: U1=device, U2=host + // 1: U1=host, U2=host + // 2: reserved + // 3: U1=host, U2=device + // NB: this register is only available if OTG clock (aka "port select") is enabled!! + // since we don't care about port 2, set just bit 0 to 1 (U1=host) + LPC_USB->OTGStCtrl |= 1; + + // now that we've configured the ports, we can turn off the portsel clock + LPC_USB->USBClkCtrl &= ~PORTSEL_CLK_EN; + + // power pins are not connected on mbed, so we can skip them + /* P1[18] = USB_UP_LED, 01 */ + /* P1[19] = /USB_PPWR, 10 */ + /* P1[22] = USB_PWRD, 10 */ + /* P1[27] = /USB_OVRCR, 10 */ + /*LPC_PINCON->PINSEL3 &= ~((3<<4) | (3<<6) | (3<<12) | (3<<22)); + LPC_PINCON->PINSEL3 |= ((1<<4)|(2<<6) | (2<<12) | (2<<22)); // 0x00802080 + */ + + // configure USB D+/D- pins + /* P0[29] = USB_D+, 01 */ + /* P0[30] = USB_D-, 01 */ + LPC_PINCON->PINSEL1 &= ~((3<<26) | (3<<28)); + LPC_PINCON->PINSEL1 |= ((1<<26)|(1<<28)); // 0x14000000 + + DBG("Initializing Host Stack\n"); + + wait_ms(100); /* Wait 50 ms before apply reset */ + LPC_USB->HcControl = 0; /* HARDWARE RESET */ + LPC_USB->HcControlHeadED = 0; /* Initialize Control list head to Zero */ + LPC_USB->HcBulkHeadED = 0; /* Initialize Bulk list head to Zero */ + + /* SOFTWARE RESET */ + LPC_USB->HcCommandStatus = OR_CMD_STATUS_HCR; + LPC_USB->HcFmInterval = DEFAULT_FMINTERVAL; /* Write Fm Interval and Largest Data Packet Counter */ + + /* Put HC in operational state */ + LPC_USB->HcControl = (LPC_USB->HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER; + LPC_USB->HcRhStatus = OR_RH_STATUS_LPSC; /* Set Global Power */ + + LPC_USB->HcHCCA = (uint32_t)(m_pHcca); + LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus; /* Clear Interrrupt Status */ + + + LPC_USB->HcInterruptEnable = OR_INTR_ENABLE_MIE | + OR_INTR_ENABLE_WDH | + OR_INTR_ENABLE_RHSC; + + NVIC_SetPriority(USB_IRQn, 0); /* highest priority */ + /* Enable the USB Interrupt */ + NVIC_SetVector(USB_IRQn, (uint32_t)(sUsbIrqhandler)); + LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC; + LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; + + /* Check for any connected devices */ + if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) //Root device connected + { + //Device connected + wait(1); + DBG("Device connected (%08x)\n", LPC_USB->HcRhPortStatus1); + onUsbDeviceConnected(0, 1); //Hub 0 (root hub), Port 1 (count starts at 1) + } + + DBG("Enabling IRQ\n"); + NVIC_EnableIRQ(USB_IRQn); + DBG("End of host stack initialization\n"); + return USBERR_OK; +} + +void UsbHostMgr::poll() //Enumerate connected devices, etc +{ + for(int i = 0; i < devicesCount(); i++) + { + if( (m_lpDevices[i]->m_connected) + && !(m_lpDevices[i]->m_enumerated) ) + { + m_lpDevices[i]->enumerate(); + return; + } + } +} + +int UsbHostMgr::devicesCount() +{ + int i; + for(i = 0; i < USB_HOSTMGR_MAX_DEVS; i++) + { + if (m_lpDevices[i] == NULL) + break; + } + return i; +} + +UsbDevice* UsbHostMgr::getDevice(int item) +{ + UsbDevice* pDev = m_lpDevices[item]; + if(!pDev) + return NULL; + + pDev->m_refs++; + return pDev; +} + +void UsbHostMgr::releaseDevice(UsbDevice* pDev) +{ + pDev->m_refs--; + if(pDev->m_refs > 0) + return; + //If refs count = 0, delete + //Find & remove from list + int i; + for(i = 0; i < USB_HOSTMGR_MAX_DEVS; i++) + { + if (m_lpDevices[i] == pDev) + break; + } + if(i!=USB_HOSTMGR_MAX_DEVS) + memmove(&m_lpDevices[i], &m_lpDevices[i+1], sizeof(UsbDevice*) * (USB_HOSTMGR_MAX_DEVS - (i + 1))); //Safer than memcpy because of overlapping mem + m_lpDevices[USB_HOSTMGR_MAX_DEVS - 1] = NULL; + delete pDev; +} + +void UsbHostMgr::UsbIrqhandler() +{ + uint32_t int_status; + uint32_t ie_status; + + int_status = LPC_USB->HcInterruptStatus; /* Read Interrupt Status */ + ie_status = LPC_USB->HcInterruptEnable; /* Read Interrupt enable status */ + + if (!(int_status & ie_status)) + { + return; + } + else + { + int_status = int_status & ie_status; + if (int_status & OR_INTR_STATUS_RHSC) /* Root hub status change interrupt */ + { + DBG("LPC_USB->HcRhPortStatus1 = %08x\n", LPC_USB->HcRhPortStatus1); + if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CSC) + { + if (LPC_USB->HcRhStatus & OR_RH_STATUS_DRWE) + { + /* + * When DRWE is on, Connect Status Change + * means a remote wakeup event. + */ + //HOST_RhscIntr = 1;// JUST SOMETHING FOR A BREAKPOINT + } + else + { + /* + * When DRWE is off, Connect Status Change + * is NOT a remote wakeup event + */ + if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) //Root device connected + { + //Device connected + DBG("Device connected (%08x)\n", LPC_USB->HcRhPortStatus1); + onUsbDeviceConnected(0, 1); //Hub 0 (root hub), Port 1 (count starts at 1) + } + else //Root device disconnected + { + //Device disconnected + DBG("Device disconnected\n"); + onUsbDeviceDisconnected(0, 1); + } + //TODO: HUBS + } + LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC; + } + if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRSC) + { + LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; + } + } + if (int_status & OR_INTR_STATUS_WDH) /* Writeback Done Head interrupt */ + { + //UsbEndpoint::sOnCompletion((LPC_USB->HccaDoneHead) & 0xFE); + if(m_pHcca->DoneHead) + { + UsbEndpoint::sOnCompletion(m_pHcca->DoneHead); + m_pHcca->DoneHead = 0; + LPC_USB->HcInterruptStatus = OR_INTR_STATUS_WDH; + if(m_pHcca->DoneHead) + DBG("??????????????????????????????\n\n\n"); + } + else + { + //Probably an error + int_status = LPC_USB->HcInterruptStatus; + DBG("HcInterruptStatus = %08x\n", int_status); + if (int_status & OR_INTR_STATUS_UE) //Unrecoverable error, disconnect devices and resume + { + onUsbDeviceDisconnected(0, 1); + LPC_USB->HcInterruptStatus = OR_INTR_STATUS_UE; + LPC_USB->HcCommandStatus = 0x01; //Host Controller Reset + } + } + } + LPC_USB->HcInterruptStatus = int_status; /* Clear interrupt status register */ + } + return; +} + +void UsbHostMgr::onUsbDeviceConnected(int hub, int port) +{ + int item = devicesCount(); + if( item == USB_HOSTMGR_MAX_DEVS ) + return; //List full... + //Find a free address (not optimized, but not really important) + int i; + int addr = 1; + for(i = 0; i < item; i++) + { + addr = MAX( addr, m_lpDevices[i]->m_addr + 1 ); + } + m_lpDevices[item] = new UsbDevice( this, hub, port, addr ); + m_lpDevices[item]->m_connected = true; +} + +void UsbHostMgr::onUsbDeviceDisconnected(int hub, int port) +{ + for(int i = 0; i < devicesCount(); i++) + { + if( (m_lpDevices[i]->m_hub == hub) + && (m_lpDevices[i]->m_port == port) ) + { + m_lpDevices[i]->m_connected = false; + if(!m_lpDevices[i]->m_enumerated) + { + delete m_lpDevices[i]; + m_lpDevices[i] = NULL; + } + return; + } + } +} + +void UsbHostMgr::resetPort(int hub, int port) +{ + DBG("Resetting hub %d, port %d\n", hub, port); + if(hub == 0) //Root hub + { + wait_ms(100); /* USB 2.0 spec says at least 50ms delay before port reset */ + LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS; // Initiate port reset + DBG("Before loop\n"); + while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS) + ; + LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; // ...and clear port reset signal + DBG("After loop\n"); + wait_ms(200); /* Wait for 100 MS after port reset */ + } + else + { + //TODO: Hubs + } + DBG("Port reset OK\n"); +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drv/usb/UsbHostMgr.h Fri Jul 09 14:46:47 2010 +0000 @@ -0,0 +1,67 @@ +/* +Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +//Assigns addresses to connected devices... + +#ifndef USB_HOSTMGR_H +#define USB_HOSTMGR_H + +#include "mbed.h" +#include "UsbInc.h" +#include "UsbDevice.h" + +#define USB_HOSTMGR_MAX_DEVS 1 //1 device max for now... will be more when hubs are supported + +class UsbDevice; + +class UsbHostMgr //[0-1] inst +{ +public: + UsbHostMgr(); + ~UsbHostMgr(); + + UsbErr init(); //Initialize host + + void poll(); //Enumerate connected devices, etc + + int devicesCount(); + + UsbDevice* getDevice(int item); + void releaseDevice(UsbDevice* pDev); + + + void UsbIrqhandler(); + +protected: + void onUsbDeviceConnected(int hub, int port); + void onUsbDeviceDisconnected(int hub, int port); + + friend class UsbDevice; + void resetPort(int hub, int port); + +private: +/* __align(8)*/ volatile HCCA* m_pHcca; + + UsbDevice* m_lpDevices[USB_HOSTMGR_MAX_DEVS]; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drv/usb/UsbInc.h Fri Jul 09 14:46:47 2010 +0000 @@ -0,0 +1,193 @@ + +/* +Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef USB_INC_H +#define USB_INC_H + +#include "mbed.h" + +#define MIN(a,b) ((a)<(b)?(a):(b)) +#define MAX(a,b) ((a)>(b)?(a):(b)) + +//typedef int32_t RC; + +typedef uint8_t byte; +typedef uint16_t word; + +enum UsbErr +{ + __USBERR_MIN = -0xFFFF, + USBERR_DISCONNECTED, + USBERR_NOTFOUND, + USBERR_BADCONFIG, + USBERR_PROCESSING, + USBERR_HALTED, //Transfer on an ep is stalled + USBERR_BUSY, + USBERR_TDFAIL, + USBERR_ERROR, + USBERR_OK = 0 +}; + + +/* From NXP's USBHostLite stack's usbhost_lpc17xx.h */ +/* Only the types names have been changed to avoid unecessary typedefs */ + + +/* +************************************************************************************************************** +* NXP USB Host Stack +* +* (c) Copyright 2008, NXP SemiConductors +* (c) Copyright 2008, OnChip Technologies LLC +* All Rights Reserved +* +* www.nxp.com +* www.onchiptech.com +* +* File : usbhost_lpc17xx.h +* Programmer(s) : Ravikanth.P +* Version : +* +************************************************************************************************************** +*/ + + + +/* +************************************************************************************************************** +* OHCI OPERATIONAL REGISTER FIELD DEFINITIONS +************************************************************************************************************** +*/ + + /* ------------------ HcControl Register --------------------- */ +#define OR_CONTROL_CLE 0x00000010 +#define OR_CONTROL_BLE 0x00000020 +#define OR_CONTROL_HCFS 0x000000C0 +#define OR_CONTROL_HC_OPER 0x00000080 + /* ----------------- HcCommandStatus Register ----------------- */ +#define OR_CMD_STATUS_HCR 0x00000001 +#define OR_CMD_STATUS_CLF 0x00000002 +#define OR_CMD_STATUS_BLF 0x00000004 + /* --------------- HcInterruptStatus Register ----------------- */ +#define OR_INTR_STATUS_WDH 0x00000002 +#define OR_INTR_STATUS_RHSC 0x00000040 +#define OR_INTR_STATUS_UE 0x00000010 + /* --------------- HcInterruptEnable Register ----------------- */ +#define OR_INTR_ENABLE_WDH 0x00000002 +#define OR_INTR_ENABLE_RHSC 0x00000040 +#define OR_INTR_ENABLE_MIE 0x80000000 + /* ---------------- HcRhDescriptorA Register ------------------ */ +#define OR_RH_STATUS_LPSC 0x00010000 +#define OR_RH_STATUS_DRWE 0x00008000 + /* -------------- HcRhPortStatus[1:NDP] Register -------------- */ +#define OR_RH_PORT_CCS 0x00000001 +#define OR_RH_PORT_PRS 0x00000010 +#define OR_RH_PORT_CSC 0x00010000 +#define OR_RH_PORT_PRSC 0x00100000 + + +/* +************************************************************************************************************** +* FRAME INTERVAL +************************************************************************************************************** +*/ + +#define FI 0x2EDF /* 12000 bits per frame (-1) */ +#define DEFAULT_FMINTERVAL ((((6 * (FI - 210)) / 7) << 16) | FI) + +/* +************************************************************************************************************** +* ENDPOINT DESCRIPTOR CONTROL FIELDS +************************************************************************************************************** +*/ + +#define ED_SKIP (uint32_t) (0x00001000) /* Skip this ep in queue */ + +/* +************************************************************************************************************** +* TRANSFER DESCRIPTOR CONTROL FIELDS +************************************************************************************************************** +*/ + +#define TD_ROUNDING (uint32_t) (0x00040000) /* Buffer Rounding */ +#define TD_SETUP (uint32_t)(0) /* Direction of Setup Packet */ +#define TD_IN (uint32_t)(0x00100000) /* Direction In */ +#define TD_OUT (uint32_t)(0x00080000) /* Direction Out */ +#define TD_DELAY_INT(x) (uint32_t)((x) << 21) /* Delay Interrupt */ +#define TD_TOGGLE_0 (uint32_t)(0x02000000) /* Toggle 0 */ +#define TD_TOGGLE_1 (uint32_t)(0x03000000) /* Toggle 1 */ +#define TD_CC (uint32_t)(0xF0000000) /* Completion Code */ + +/* +************************************************************************************************************** +* USB STANDARD REQUEST DEFINITIONS +************************************************************************************************************** +*/ + +#define USB_DESCRIPTOR_TYPE_DEVICE 1 +#define USB_DESCRIPTOR_TYPE_CONFIGURATION 2 +#define USB_DESCRIPTOR_TYPE_INTERFACE 4 +#define USB_DESCRIPTOR_TYPE_ENDPOINT 5 + /* ----------- Control RequestType Fields ----------- */ +#define USB_DEVICE_TO_HOST 0x80 +#define USB_HOST_TO_DEVICE 0x00 +#define USB_REQUEST_TYPE_CLASS 0x20 +#define USB_RECIPIENT_DEVICE 0x00 +#define USB_RECIPIENT_INTERFACE 0x01 + /* -------------- USB Standard Requests -------------- */ +#define SET_ADDRESS 5 +#define GET_DESCRIPTOR 6 +#define SET_CONFIGURATION 9 +#define SET_INTERFACE 11 + +/* +************************************************************************************************************** +* TYPE DEFINITIONS +************************************************************************************************************** +*/ + +typedef struct hcEd { /* ----------- HostController EndPoint Descriptor ------------- */ + volatile uint32_t Control; /* Endpoint descriptor control */ + volatile uint32_t TailTd; /* Physical address of tail in Transfer descriptor list */ + volatile uint32_t HeadTd; /* Physcial address of head in Transfer descriptor list */ + volatile uint32_t Next; /* Physical address of next Endpoint descriptor */ +} HCED; + +typedef struct hcTd { /* ------------ HostController Transfer Descriptor ------------ */ + volatile uint32_t Control; /* Transfer descriptor control */ + volatile uint32_t CurrBufPtr; /* Physical address of current buffer pointer */ + volatile uint32_t Next; /* Physical pointer to next Transfer Descriptor */ + volatile uint32_t BufEnd; /* Physical address of end of buffer */ +} HCTD; + +typedef struct hcca { /* ----------- Host Controller Communication Area ------------ */ + volatile uint32_t IntTable[32]; /* Interrupt Table */ + volatile uint32_t FrameNumber; /* Frame Number */ + volatile uint32_t DoneHead; /* Done Head */ + volatile uint8_t Reserved[116]; /* Reserved for future use */ + volatile uint8_t Unknown[4]; /* Unused */ +} HCCA; + + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drv/usb/usb_mem.c Fri Jul 09 14:46:47 2010 +0000 @@ -0,0 +1,108 @@ + +/* +Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "usb_mem.h" + +#include "string.h" //For memcpy, memmove, memset + +#include "netCfg.h" +#if NET_USB + +#define EDS_COUNT 4 +#define TDS_COUNT 8 + +#define HCCA_SIZE 0x100 +#define ED_SIZE 0x10 +#define TD_SIZE 0x10 + +#define TOTAL_SIZE (HCCA_SIZE + (EDS_COUNT*ED_SIZE) + (TDS_COUNT*TD_SIZE)) + + +static volatile byte usb_buf[TOTAL_SIZE] __attribute((section("AHBSRAM1"),aligned)) __attribute__((at(0x20080000))); //256 bytes aligned! + +static volatile byte* usb_hcca; //256 bytes aligned! + +static volatile byte* usb_edBuf; //4 bytes aligned! +static volatile byte* usb_tdBuf; //4 bytes aligned! + +static byte usb_edBufAlloc[EDS_COUNT]; +static byte usb_tdBufAlloc[TDS_COUNT]; + +void usb_mem_init() +{ + usb_hcca = usb_buf; + usb_edBuf = usb_buf + HCCA_SIZE; + usb_tdBuf = usb_buf + HCCA_SIZE + (EDS_COUNT*ED_SIZE); + memset(usb_edBufAlloc, 0, EDS_COUNT); + memset(usb_tdBufAlloc, 0, TDS_COUNT); +} + +volatile byte* usb_get_hcca() +{ + return usb_hcca; +} + +volatile byte* usb_get_ed() +{ + int i; + for(i = 0; i < EDS_COUNT; i++) + { + if( !usb_edBufAlloc[i] ) + { + usb_edBufAlloc[i] = 1; + return usb_edBuf + i*ED_SIZE; + } + } + return NULL; //Could not alloc ED +} + +volatile byte* usb_get_td() +{ + int i; + for(i = 0; i < TDS_COUNT; i++) + { + if( !usb_tdBufAlloc[i] ) + { + usb_tdBufAlloc[i] = 1; + return usb_tdBuf + i*TD_SIZE; + } + } + return NULL; //Could not alloc TD +} + +void usb_free_ed(volatile byte* ed) +{ + int i; + i = (ed - usb_edBuf) / ED_SIZE; + usb_edBufAlloc[i] = 0; +} + +void usb_free_td(volatile byte* td) +{ + int i; + i = (td - usb_tdBuf) / TD_SIZE; + usb_tdBufAlloc[i] = 0; +} + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drv/usb/usb_mem.h Fri Jul 09 14:46:47 2010 +0000 @@ -0,0 +1,48 @@ +/* +Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef USB_MEM_H +#define USB_MEM_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned char byte; + +void usb_mem_init(); + +volatile byte* usb_get_hcca(); + +volatile byte* usb_get_ed(); + +volatile byte* usb_get_td(); + +void usb_free_ed(volatile byte* ed); + +void usb_free_td(volatile byte* td); + +#ifdef __cplusplus +} +#endif + +#endif
--- a/if/eth/EthernetNetIf.cpp Fri Jun 18 10:38:57 2010 +0000 +++ b/if/eth/EthernetNetIf.cpp Fri Jul 09 14:46:47 2010 +0000 @@ -79,7 +79,7 @@ m_pNetIf->hwaddr_len = ETHARP_HWADDR_LEN; //6 eth_address((char *)m_pNetIf->hwaddr); - DBG("\r\nHW Addr is : %02x:%02x:%02x:%02x:%02x:%02x.\r\n", + DBG("HW Addr is : %02x:%02x:%02x:%02x:%02x:%02x.\n", m_pNetIf->hwaddr[0], m_pNetIf->hwaddr[1], m_pNetIf->hwaddr[2], m_pNetIf->hwaddr[3], m_pNetIf->hwaddr[4], m_pNetIf->hwaddr[5]); @@ -92,7 +92,7 @@ if(m_useDhcp) { dhcp_start(m_pNetIf); - DBG("\r\nDHCP Started, waiting for IP...\r\n"); + DBG("DHCP Started, waiting for IP...\n"); } else { @@ -131,7 +131,7 @@ m_ip = IpAddr(&(m_pNetIf->ip_addr)); - DBG("\r\nConnected, IP : %d.%d.%d.%d\r\n", m_ip[0], m_ip[1], m_ip[2], m_ip[3]); + DBG("Connected, IP : %d.%d.%d.%d\n", m_ip[0], m_ip[1], m_ip[2], m_ip[3]); return ETH_OK; }
--- a/if/ppp/PPPNetIf.cpp Fri Jun 18 10:38:57 2010 +0000 +++ b/if/ppp/PPPNetIf.cpp Fri Jul 09 14:46:47 2010 +0000 @@ -33,7 +33,7 @@ #include "netCfg.h" #if NET_PPP -#define PPP_TIMEOUT 60000 +#define PPP_TIMEOUT 30000//60000 #define BUF_SIZE 128 @@ -88,10 +88,14 @@ DBG("\r\nPPPNetIf: Set Auth.\r\n"); - m_pIf->flushBuffer(); //Flush buffer before passing serial port to PPP - + //wait(1.); + + //m_pIf->flushBuffer(); //Flush buffer before passing serial port to PPP + m_status = PPP_CONNECTING; + DBG("m_pIf = %p\n", m_pIf); int res = pppOverSerialOpen((void*)m_pIf, sPppCallback, (void*)this); + DBG("\r\nPPP connected\r\n"); if(res<0) { disconnect(); @@ -119,6 +123,7 @@ if( m_status == PPP_DISCONNECTED ) { + disconnect(); return PPP_PROTOCOL; } @@ -140,7 +145,7 @@ m_pIf->flushBuffer(); m_pIf->printf("+++"); - wait(.1); + wait(.5); m_pIf->flushBuffer(); GPRSErr gprsErr; @@ -194,7 +199,6 @@ //Link Callback void PPPNetIf::pppCallback(int errCode, void *arg) { - //DBG("\r\nPPPNetIf: Callback errCode = %d.\r\n", errCode); switch ( errCode ) { //No error @@ -203,6 +207,7 @@ break; default: //Disconnected + DBG("\r\nPPPNetIf: Callback errCode = %d.\r\n", errCode); m_status = PPP_DISCONNECTED; break; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/if/umtsstick/UMTSStickNetIf.cpp Fri Jul 09 14:46:47 2010 +0000 @@ -0,0 +1,92 @@ + +/* +Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "netCfg.h" +#if NET_UMTS + +#include "UMTSStickNetIf.h" + +#define __DEBUG +#include "dbg/dbg.h" + +UMTSStickNetIf::UMTSStickNetIf() : PPPNetIf(NULL), m_umtsStick(), m_pUsbSerial(NULL) +{ + PPPNetIf::m_pIf = new GPRSModem(); +} + +UMTSStickNetIf::~UMTSStickNetIf() +{ + delete PPPNetIf::m_pIf; + if(m_pUsbSerial) + delete m_pUsbSerial; +} + +UMTSStickErr UMTSStickNetIf::setup() //UMTSStickErr is from /drv/umtsstick/UMTSStick.h +{ + return m_umtsStick.getSerial(&m_pUsbSerial); +} + +PPPErr UMTSStickNetIf::connect(const char* apn /*= NULL*/, const char* userId /*= NULL*/, const char* password /*= NULL*/) //Connect using GPRS +{ + if(!m_pUsbSerial) + return PPP_MODEM; + + ATErr atErr; + for(int i=0; i<3; i++) + { + atErr = m_pIf->open(m_pUsbSerial); //3 tries + if(!atErr) + break; + wait(4); + } + + if(atErr) + return PPP_MODEM; + + PPPErr pppErr; + for(int i=0; i<3; i++) + { + pppErr = PPPNetIf::GPRSConnect(apn, userId, password); + if(!pppErr) + break; + wait(4); + } + if(pppErr) + return pppErr; + + return PPP_OK; +} + +PPPErr UMTSStickNetIf::disconnect() +{ + PPPErr pppErr = PPPNetIf::disconnect(); + if(pppErr) + return pppErr; + + m_pIf->close(); + + return PPP_OK; +} + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/if/umtsstick/UMTSStickNetIf.h Fri Jul 09 14:46:47 2010 +0000 @@ -0,0 +1,51 @@ + +/* +Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef UMTSSTICKNETIF_H +#define UMTSSTICKNETIF_H + +#include "mbed.h" + +#include "if/net/net.h" +#include "if/ppp/PPPNetIf.h" + +#include "drv/umtsstick/UMTSStick.h" + +class UMTSStickNetIf : protected PPPNetIf +{ +public: + UMTSStickNetIf(); + virtual ~UMTSStickNetIf(); + + UMTSStickErr setup(); //UMTSStickErr is from /drv/umtsstick/UMTSStick.h + PPPErr connect(const char* apn = NULL, const char* userId = NULL, const char* password = NULL); //Connect using GPRS + PPPErr disconnect(); + +private: + UMTSStick m_umtsStick; + UsbSerial* m_pUsbSerial; + +}; + +#endif +
--- a/lwip/core/def.c Fri Jun 18 10:38:57 2010 +0000 +++ b/lwip/core/def.c Fri Jul 09 14:46:47 2010 +0000 @@ -61,7 +61,7 @@ * @return n in network byte order */ u16_t -htons(u16_t n) +lwip_htons(u16_t n) { return ((n & 0xff) << 8) | ((n & 0xff00) >> 8); } @@ -73,7 +73,7 @@ * @return n in host byte order */ u16_t -ntohs(u16_t n) +lwip_ntohs(u16_t n) { return htons(n); } @@ -85,7 +85,7 @@ * @return n in network byte order */ u32_t -htonl(u32_t n) +lwip_htonl(u32_t n) { return ((n & 0xff) << 24) | ((n & 0xff00) << 8) | @@ -100,7 +100,7 @@ * @return n in host byte order */ u32_t -ntohl(u32_t n) +lwip_ntohl(u32_t n) { return htonl(n); }
--- a/lwip/include/lwip/def.h Fri Jun 18 10:38:57 2010 +0000 +++ b/lwip/include/lwip/def.h Fri Jul 09 14:46:47 2010 +0000 @@ -39,7 +39,6 @@ #ifdef __cplusplus extern "C" { #endif - #define LWIP_MAX(x , y) (((x) > (y)) ? (x) : (y)) #define LWIP_MIN(x , y) (((x) < (y)) ? (x) : (y)) @@ -47,6 +46,24 @@ #define NULL ((void *)0) #endif +/** Get the absolute difference between 2 u32_t values (correcting overflows) + * 'a' is expected to be 'higher' (without overflow) than 'b'. */ +#define LWIP_U32_DIFF(a, b) (((a) >= (b)) ? ((a) - (b)) : (((a) + ((b) ^ 0xFFFFFFFF) + 1))) + +/* Endianess-optimized shifting of two u8_t to create one u16_t */ +#if BYTE_ORDER == LITTLE_ENDIAN +#define LWIP_MAKE_U16(a, b) ((a << 8) | b) +#else +#define LWIP_MAKE_U16(a, b) ((b << 8) | a) +#endif + +#ifndef LWIP_PLATFORM_BYTESWAP +#define LWIP_PLATFORM_BYTESWAP 0 +#endif + +#ifndef LWIP_PREFIX_BYTEORDER_FUNCS +/* workaround for naming collisions on some platforms */ + #ifdef htons #undef htons #endif /* htons */ @@ -60,38 +77,46 @@ #undef ntohl #endif /* ntohl */ -#ifndef LWIP_PLATFORM_BYTESWAP -#define LWIP_PLATFORM_BYTESWAP 0 -#endif +#define htons(x) lwip_htons(x) +#define ntohs(x) lwip_ntohs(x) +#define htonl(x) lwip_htonl(x) +#define ntohl(x) lwip_ntohl(x) +#endif /* LWIP_PREFIX_BYTEORDER_FUNCS */ #if BYTE_ORDER == BIG_ENDIAN -#define htons(x) (x) -#define ntohs(x) (x) -#define htonl(x) (x) -#define ntohl(x) (x) +#define lwip_htons(x) (x) +#define lwip_ntohs(x) (x) +#define lwip_htonl(x) (x) +#define lwip_ntohl(x) (x) +#define PP_HTONS(x) (x) +#define PP_NTOHS(x) (x) +#define PP_HTONL(x) (x) +#define PP_NTOHL(x) (x) #else /* BYTE_ORDER != BIG_ENDIAN */ -#ifdef LWIP_PREFIX_BYTEORDER_FUNCS -/* workaround for naming collisions on some platforms */ -#define htons lwip_htons -#define ntohs lwip_ntohs -#define htonl lwip_htonl -#define ntohl lwip_ntohl -#endif /* LWIP_PREFIX_BYTEORDER_FUNCS */ #if LWIP_PLATFORM_BYTESWAP -#define htons(x) LWIP_PLATFORM_HTONS(x) -#define ntohs(x) LWIP_PLATFORM_HTONS(x) -#define htonl(x) LWIP_PLATFORM_HTONL(x) -#define ntohl(x) LWIP_PLATFORM_HTONL(x) +#define lwip_htons(x) LWIP_PLATFORM_HTONS(x) +#define lwip_ntohs(x) LWIP_PLATFORM_HTONS(x) +#define lwip_htonl(x) LWIP_PLATFORM_HTONL(x) +#define lwip_ntohl(x) LWIP_PLATFORM_HTONL(x) #else /* LWIP_PLATFORM_BYTESWAP */ -u16_t htons(u16_t x); -u16_t ntohs(u16_t x); -u32_t htonl(u32_t x); -u32_t ntohl(u32_t x); +u16_t lwip_htons(u16_t x); +u16_t lwip_ntohs(u16_t x); +u32_t lwip_htonl(u32_t x); +u32_t lwip_ntohl(u32_t x); #endif /* LWIP_PLATFORM_BYTESWAP */ -#endif /* BYTE_ORDER == BIG_ENDIAN */ +/* These macros should be calculated by the preprocessor and are used + with compile-time constants only (so that there is no little-endian + overhead at runtime). */ +#define PP_HTONS(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)) +#define PP_NTOHS(x) PP_HTONS(x) +#define PP_HTONL(x) ((((x) & 0xff) << 24) | \ + (((x) & 0xff00) << 8) | \ + (((x) & 0xff0000UL) >> 8) | \ + (((x) & 0xff000000UL) >> 24)) +#define PP_NTOHL(x) PP_HTONL(x) -#define PP_HTONS htons +#endif /* BYTE_ORDER == BIG_ENDIAN */ #ifdef __cplusplus }
--- a/lwip/lwipopts.h Fri Jun 18 10:38:57 2010 +0000 +++ b/lwip/lwipopts.h Fri Jul 09 14:46:47 2010 +0000 @@ -56,10 +56,10 @@ #define SIO_FIFO_DEBUG LWIP_DBG_OFF #define TCPDUMP_DEBUG LWIP_DBG_OFF -#define PPP_DEBUG LWIP_DBG_OFF -#define MEM_DEBUG LWIP_DBG_ON -#define MEMP_DEBUG LWIP_DBG_ON -#define PBUF_DEBUG LWIP_DBG_ON +#define PPP_DEBUG LWIP_DBG_ON +#define MEM_DEBUG LWIP_DBG_OFF +#define MEMP_DEBUG LWIP_DBG_OFF +#define PBUF_DEBUG LWIP_DBG_OFF #define API_LIB_DEBUG LWIP_DBG_OFF #define API_MSG_DEBUG LWIP_DBG_OFF #define TCPIP_DEBUG LWIP_DBG_OFF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lwip/lwipopts_light.h Fri Jul 09 14:46:47 2010 +0000 @@ -0,0 +1,454 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels <adam@sics.se> + * + */ +#ifndef __LWIPOPTS_H__ +#define __LWIPOPTS_H__ + +#include "netCfg.h" +#if NET_LWIP_STACK + +//#include "arch/sys_arch.h" + +/* <sys/time.h> is included in cc.h! */ +#define LWIP_TIMEVAL_PRIVATE 0 + +//#define __LWIP_DEBUG +#include "dbg/dbg.h" + +#ifdef __LWIP_DEBUG + +#define LWIP_DEBUG 1 + +#define LWIP_DBG_MIN_LEVEL 0 +//#define LWIP_COMPAT_SOCKETS 1 +#define TAPIF_DEBUG LWIP_DBG_OFF +#define TUNIF_DEBUG LWIP_DBG_OFF +#define UNIXIF_DEBUG LWIP_DBG_OFF +#define DELIF_DEBUG LWIP_DBG_OFF +#define SIO_FIFO_DEBUG LWIP_DBG_OFF +#define TCPDUMP_DEBUG LWIP_DBG_OFF + +#define PPP_DEBUG LWIP_DBG_OFF +#define MEM_DEBUG LWIP_DBG_ON +#define MEMP_DEBUG LWIP_DBG_ON +#define PBUF_DEBUG LWIP_DBG_ON +#define API_LIB_DEBUG LWIP_DBG_OFF +#define API_MSG_DEBUG LWIP_DBG_OFF +#define TCPIP_DEBUG LWIP_DBG_OFF +#define NETIF_DEBUG LWIP_DBG_OFF +#define SOCKETS_DEBUG LWIP_DBG_OFF +#define DEMO_DEBUG LWIP_DBG_OFF +#define IP_DEBUG LWIP_DBG_OFF +#define IP_REASS_DEBUG LWIP_DBG_OFF +#define RAW_DEBUG LWIP_DBG_OFF +#define ICMP_DEBUG LWIP_DBG_OFF +#define UDP_DEBUG LWIP_DBG_OFF +#define TCP_DEBUG LWIP_DBG_OFF +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#define TCP_WND_DEBUG LWIP_DBG_OFF +#define TCP_FR_DEBUG LWIP_DBG_OFF +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#define TCP_RST_DEBUG LWIP_DBG_OFF +#define ETHARP_DEBUG LWIP_DBG_OFF +#define DNS_DEBUG LWIP_DBG_OFF + +#endif + +/* +extern unsigned char debug_flags; +#define LWIP_DBG_TYPES_ON debug_flags +*/ +#define NO_SYS 1 +#define LWIP_SOCKET (NO_SYS==0) +#define LWIP_NETCONN (NO_SYS==0) + + +#define IP_FRAG_USES_STATIC_BUF 0 + + + +/* ---------- Memory options ---------- */ +/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which + lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2 + byte alignment -> define MEM_ALIGNMENT to 2. */ +/* MSVC port: intel processors don't need 4-byte alignment, + but are faster that way! */ +#define MEM_ALIGNMENT 4 + +/* MEM_SIZE: the size of the heap memory. If the application will send +a lot of data that needs to be copied, this should be set high. */ +//#define MEM_SIZE 10240 + +#if TARGET_LPC1768 + + +#define MEM_SIZE 2000 + +/// + +#define MEM_POSITION __attribute((section("AHBSRAM0"))) + +/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application + sends a lot of data out of ROM (or other static memory), this + should be set high. */ +#define MEMP_NUM_PBUF 8 +/* MEMP_NUM_RAW_PCB: the number of UDP protocol control blocks. One + per active RAW "connection". */ +//#define MEMP_NUM_RAW_PCB 3 +/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One + per active UDP "connection". */ +#define MEMP_NUM_UDP_PCB 2 +/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP + connections. */ +#define MEMP_NUM_TCP_PCB 2 +/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP + connections. */ +#define MEMP_NUM_TCP_PCB_LISTEN 2//4 +/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP + segments. */ +#define MEMP_NUM_TCP_SEG 8 +/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active + timeouts. */ +#define MEMP_NUM_SYS_TIMEOUT 12 + +/* The following four are used only with the sequential API and can be + set to 0 if the application only will use the raw API. */ +/* MEMP_NUM_NETBUF: the number of struct netbufs. */ +#define MEMP_NUM_NETBUF 0 +/* MEMP_NUM_NETCONN: the number of struct netconns. */ +#define MEMP_NUM_NETCONN 0 +/* MEMP_NUM_TCPIP_MSG_*: the number of struct tcpip_msg, which is used + for sequential API communication and incoming packets. Used in + src/api/tcpip.c. */ +#define MEMP_NUM_TCPIP_MSG_API 0 +#define MEMP_NUM_TCPIP_MSG_INPKT 0 + +/* ---------- Pbuf options ---------- */ +/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */ +#define PBUF_POOL_SIZE 16//100 + +/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */ +#define PBUF_POOL_BUFSIZE 128 + +/* PBUF_LINK_HLEN: the number of bytes that should be allocated for a + link level header. */ +//#define PBUF_LINK_HLEN 16 + +/** SYS_LIGHTWEIGHT_PROT + * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection + * for certain critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#define SYS_LIGHTWEIGHT_PROT 0 //No sys here + +/* ---------- TCP options ---------- */ +#define LWIP_TCP 1 +#define TCP_TTL 255 + +/* Controls if TCP should queue segments that arrive out of + order. Define to 0 if your device is low on memory. */ +#define TCP_QUEUE_OOSEQ 0 + +/* TCP Maximum segment size. */ +//#define TCP_MSS 1024 +#define TCP_MSS 0x276//536//0x276 + +/* TCP sender buffer space (bytes). */ +#define TCP_SND_BUF 1024 + +/* TCP sender buffer space (pbufs). This must be at least = 2 * + TCP_SND_BUF/TCP_MSS for things to work. */ +#define TCP_SND_QUEUELEN (2 * TCP_SND_BUF/TCP_MSS) + +/* TCP writable space (bytes). This must be less than or equal + to TCP_SND_BUF. It is the amount of space which must be + available in the tcp snd_buf for select to return writable */ +#define TCP_SNDLOWAT (TCP_SND_BUF/2) + +/* TCP receive window. */ +#define TCP_WND 1024 //8096 + +/* Maximum number of retransmissions of data segments. */ +//#define TCP_MAXRTX 12 + +/* Maximum number of retransmissions of SYN segments. */ +//#define TCP_SYNMAXRTX 4 + +#elif TARGET_LPC2368 + +#define MEM_POSITION __attribute((section("AHBSRAM1"))) + +/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application + sends a lot of data out of ROM (or other static memory), this + should be set high. */ +#define MEMP_NUM_PBUF 8 +/* MEMP_NUM_RAW_PCB: the number of UDP protocol control blocks. One + per active RAW "connection". */ +//#define MEMP_NUM_RAW_PCB 3 +/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One + per active UDP "connection". */ +#define MEMP_NUM_UDP_PCB 2 +/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP + connections. */ +#define MEMP_NUM_TCP_PCB 2 +/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP + connections. */ +#define MEMP_NUM_TCP_PCB_LISTEN 2//4 +/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP + segments. */ +#define MEMP_NUM_TCP_SEG 8 +/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active + timeouts. */ +#define MEMP_NUM_SYS_TIMEOUT 12 + +/* The following four are used only with the sequential API and can be + set to 0 if the application only will use the raw API. */ +/* MEMP_NUM_NETBUF: the number of struct netbufs. */ +#define MEMP_NUM_NETBUF 0 +/* MEMP_NUM_NETCONN: the number of struct netconns. */ +#define MEMP_NUM_NETCONN 0 +/* MEMP_NUM_TCPIP_MSG_*: the number of struct tcpip_msg, which is used + for sequential API communication and incoming packets. Used in + src/api/tcpip.c. */ +#define MEMP_NUM_TCPIP_MSG_API 0 +#define MEMP_NUM_TCPIP_MSG_INPKT 0 + +/* ---------- Pbuf options ---------- */ +/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */ +#define PBUF_POOL_SIZE 8//16//100 + +/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */ +//#define PBUF_POOL_BUFSIZE 128 + +/* PBUF_LINK_HLEN: the number of bytes that should be allocated for a + link level header. */ +//#define PBUF_LINK_HLEN 16 + +/** SYS_LIGHTWEIGHT_PROT + * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection + * for certain critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#define SYS_LIGHTWEIGHT_PROT 0 //No sys here + +/* ---------- TCP options ---------- */ +#define LWIP_TCP 1 +#define TCP_TTL 255 + +/* Controls if TCP should queue segments that arrive out of + order. Define to 0 if your device is low on memory. */ +#define TCP_QUEUE_OOSEQ 0 + +/* TCP Maximum segment size. */ +//#define TCP_MSS 1024 +#define TCP_MSS 512//0x276//536//0x276 + +/* TCP sender buffer space (bytes). */ +#define TCP_SND_BUF 1024//2048 + +/* TCP sender buffer space (pbufs). This must be at least = 2 * + TCP_SND_BUF/TCP_MSS for things to work. */ +#define TCP_SND_QUEUELEN (4 * TCP_SND_BUF/TCP_MSS)//(4 * TCP_SND_BUF/TCP_MSS) + +/* TCP writable space (bytes). This must be less than or equal + to TCP_SND_BUF. It is the amount of space which must be + available in the tcp snd_buf for select to return writable */ +#define TCP_SNDLOWAT (TCP_SND_BUF/2) + +/* TCP receive window. */ +#define TCP_WND 512 //8096 + +/* Maximum number of retransmissions of data segments. */ +//#define TCP_MAXRTX 12 + +/* Maximum number of retransmissions of SYN segments. */ +//#define TCP_SYNMAXRTX 4 + +#endif + +/* ---------- ARP options ---------- */ +#define LWIP_ARP (NET_ETH | NET_ZG2100) +#define ARP_TABLE_SIZE 2//4//10 +#define ARP_QUEUEING 0//1 +#define ETHARP_TRUST_IP_MAC 1 + +/* ---------- IP options ---------- */ +/* Define IP_FORWARD to 1 if you wish to have the ability to forward + IP packets across network interfaces. If you are going to run lwIP + on a device with only one network interface, define this to 0. */ +#define IP_FORWARD 0 + + +/* IP reassembly and segmentation.These are orthogonal even + * if they both deal with IP fragments */ + /* +#define IP_REASSEMBLY 1 +#define IP_REASS_MAX_PBUFS 10 +#define MEMP_NUM_REASSDATA 10 +#define IP_FRAG 1 +*/ +/* ---------- ICMP options ---------- */ +#define ICMP_TTL 255 + +/* ---------- DHCP options ---------- */ +/* Define LWIP_DHCP to 1 if you want DHCP configuration of + interfaces. */ +#define LWIP_DHCP (NET_ETH | NET_ZG2100) + +/* 1 if you want to do an ARP check on the offered address + (recommended if using DHCP). */ +#define DHCP_DOES_ARP_CHECK (LWIP_DHCP) + +/* ---------- AUTOIP options ------- */ +#define LWIP_AUTOIP 0 + +/* ---------- SNMP options ---------- */ +/** @todo SNMP is experimental for now + @note UDP must be available for SNMP transport */ +#ifndef LWIP_SNMP +#define LWIP_SNMP 0 +#endif + + +#ifndef SNMP_PRIVATE_MIB +#define SNMP_PRIVATE_MIB 0 +#endif + + +/* ---------- UDP options ---------- */ +#define LWIP_UDP 1 +#define UDP_TTL 255 + +/* ---------- DNS options ---------- */ +#define LWIP_DNS 1 + +/* ---------- RAW options ---------- */ +#define LWIP_RAW 0 +#define RAW_TTL 255 + +/* ---------- Statistics options ---------- */ +/* individual STATS options can be turned off by defining them to 0 + * (e.g #define TCP_STATS 0). All of them are turned off if LWIP_STATS + * is 0 + * */ + +#define LWIP_STATS 0 + +/* ---------- PPP options ---------- */ + +#define PPP_SUPPORT NET_PPP /* Set > 0 for PPP */ + +#if PPP_SUPPORT > 0 + +#define NUM_PPP 1 /* Max PPP sessions. */ + + +/* Select modules to enable. Ideally these would be set in the makefile but + * we're limited by the command line length so you need to modify the settings + * in this file. + */ +#define PAP_SUPPORT 1 /* Set > 0 for PAP. */ +#define CHAP_SUPPORT 1 /* Set > 0 for CHAP. */ +#define MSCHAP_SUPPORT 0 /* Set > 0 for MSCHAP (NOT FUNCTIONAL!) */ +#define CBCP_SUPPORT 0 /* Set > 0 for CBCP (NOT FUNCTIONAL!) */ +#define CCP_SUPPORT 0 /* Set > 0 for CCP (NOT FUNCTIONAL!) */ +#define VJ_SUPPORT 1 /* Set > 0 for VJ header compression. */ +#define MD5_SUPPORT 1 /* Set > 0 for MD5 (see also CHAP) */ + + +/* + * Timeouts. + */ +#define FSM_DEFTIMEOUT 6 /* Timeout time in seconds */ +#define FSM_DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */ +#define FSM_DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */ +#define FSM_DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */ + +#define UPAP_DEFTIMEOUT 6 /* Timeout (seconds) for retransmitting req */ +#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ + +#define CHAP_DEFTIMEOUT 6 /* Timeout time in seconds */ +#define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */ + + +/* Interval in seconds between keepalive echo requests, 0 to disable. */ +#if 1 +#define LCP_ECHOINTERVAL 0 +#else + +#define LCP_ECHOINTERVAL 10 +#endif + + +/* Number of unanswered echo requests before failure. */ +#define LCP_MAXECHOFAILS 3 + +/* Max Xmit idle time (in jiffies) before resend flag char. */ +#define PPP_MAXIDLEFLAG 0//Send it every time//100 + +/* + * Packet sizes + * + * Note - lcp shouldn't be allowed to negotiate stuff outside these + * limits. See lcp.h in the pppd directory. + * (XXX - these constants should simply be shared by lcp.c instead + * of living in lcp.h) + */ +#define PPP_MTU 1500 /* Default MTU (size of Info field) */ +#if 0 +#define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN) +#else + +#define PPP_MAXMTU 1500 /* Largest MTU we allow */ +#endif + +#define PPP_MINMTU 64 +#define PPP_MRU 1500 /* default MRU = max length of info field */ +#define PPP_MAXMRU 1500 /* Largest MRU we allow */ +#define PPP_DEFMRU 296 /* Try for this */ +#define PPP_MINMRU 128 /* No MRUs below this */ + + +#define MAXNAMELEN 64 /* max length of hostname or name for auth */ +#define MAXSECRETLEN 64 /* max length of password or secret */ + +#endif /* PPP_SUPPORT > 0 */ + +//C++ Compat +#define try vTry + +#endif + + +#endif /* __LWIPOPTS_H__ */
--- a/lwip/netif/ppp/auth.c Fri Jun 18 10:38:57 2010 +0000 +++ b/lwip/netif/ppp/auth.c Fri Jul 09 14:46:47 2010 +0000 @@ -634,20 +634,14 @@ if (passwd_from_file) { BZERO(ppp_settings.passwd, MAXSECRETLEN); } - /* - * XXX Warning: the unit number indicates the interface which is - * not necessarily the PPP connection. It works here as long - * as we are only supporting PPP interfaces. - */ - /* @todo: Remove pppIOCtl, it is not used anywhere else. - Instead, directly set errCode. */ - pppIOCtl(unit, PPPCTLS_ERRCODE, &errCode); /* * We've failed to authenticate ourselves to our peer. * He'll probably take the link down, and there's not much * we can do except wait for that. */ + pppIOCtl(unit, PPPCTLS_ERRCODE, &errCode); + lcp_close(unit, "Failed to authenticate ourselves to peer"); } /*
--- a/lwip/netif/ppp/chpms.c Fri Jun 18 10:38:57 2010 +0000 +++ b/lwip/netif/ppp/chpms.c Fri Jul 09 14:46:47 2010 +0000 @@ -325,7 +325,7 @@ MDupdate(&md4Context, unicodePassword, secret_len * 2 * 8); /* Unicode is 2 bytes/char, *8 for bit count */ if (low_byte_first == -1) { - low_byte_first = (htons((unsigned short int)1) != 1); + low_byte_first = (PP_HTONS((unsigned short int)1) != 1); } if (low_byte_first == 0) { /* @todo: arg type - u_long* or u_int* ? */
--- a/lwip/netif/ppp/fsm.c Fri Jun 18 10:38:57 2010 +0000 +++ b/lwip/netif/ppp/fsm.c Fri Jul 09 14:46:47 2010 +0000 @@ -122,7 +122,7 @@ { #if PPP_DEBUG int oldState = f->state; - + LWIP_UNUSED_ARG(oldState); #endif
--- a/lwip/netif/ppp/ipcp.c Fri Jun 18 10:38:57 2010 +0000 +++ b/lwip/netif/ppp/ipcp.c Fri Jul 09 14:46:47 2010 +0000 @@ -1233,7 +1233,7 @@ if (!ho->neg_addr) { ho->hisaddr = wo->hisaddr; } -#ifdef __PPP_STRICT_IMPL__ //Kludge for bad 3g providers PPP impl +#ifdef __PPP_STRICT_IMPL__ //DG : Kludge for bad 3g providers PPP impl if (ho->hisaddr == 0) { IPCPDEBUG(LOG_ERR, ("Could not determine remote IP address\n")); ipcp_close(f->unit, "Could not determine remote IP address");
--- a/lwip/netif/ppp/lcp.c Fri Jun 18 10:38:57 2010 +0000 +++ b/lwip/netif/ppp/lcp.c Fri Jul 09 14:46:47 2010 +0000 @@ -107,7 +107,7 @@ static u32_t lcp_echo_timer_running = 0; /* TRUE if a timer is running */ /* @todo: do we really need such a large buffer? The typical 1500 bytes seem too much. */ -static u_char nak_buffer[PPP_MRU] MEM_POSITION; /* where we construct a nak packet */ +static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */ /* * Callbacks for fsm code. (CI = Configuration Information) @@ -2010,7 +2010,7 @@ * Detect the failure of the peer at this point. */ if (lcp_echo_fails != 0) { - if (lcp_echos_pending++ >= lcp_echo_fails) { + if (lcp_echos_pending >= lcp_echo_fails) { LcpLinkFailure(f); lcp_echos_pending = 0; } @@ -2024,6 +2024,7 @@ pktp = pkt; PUTLONG(lcp_magic, pktp); fsm_sdata(f, ECHOREQ, (u_char)(lcp_echo_number++ & 0xFF), pkt, (int)(pktp - pkt)); + ++lcp_echos_pending; } }
--- a/lwip/netif/ppp/md5.c Fri Jun 18 10:38:57 2010 +0000 +++ b/lwip/netif/ppp/md5.c Fri Jul 09 14:46:47 2010 +0000 @@ -138,8 +138,8 @@ unsigned int i, ii; #if 0 - PPPDEBUGLOG_INFO, ("MD5Update: %u:%.*H\n", inLen, MIN(inLen, 20) * 2, inBuf); - PPPDEBUGLOG_INFO, ("MD5Update: %u:%s\n", inLen, inBuf); + PPPDEBUG(LOG_INFO, ("MD5Update: %u:%.*H\n", inLen, LWIP_MIN(inLen, 20) * 2, inBuf)); + PPPDEBUG(LOG_INFO, ("MD5Update: %u:%s\n", inLen, inBuf)); #endif /* compute number of bytes mod 64 */
--- a/lwip/netif/ppp/ppp.c Fri Jun 18 10:38:57 2010 +0000 +++ b/lwip/netif/ppp/ppp.c Fri Jul 09 14:46:47 2010 +0000 @@ -249,7 +249,7 @@ /******************************/ u_long subnetMask; -static PPPControl pppControl[NUM_PPP] MEM_POSITION; /* The PPP interface control blocks. */ +static PPPControl pppControl[NUM_PPP]; /* The PPP interface control blocks. */ /* * PPP Data Link Layer "protocol" table. @@ -279,7 +279,7 @@ * Buffers for outgoing packets. This must be accessed only from the appropriate * PPP task so that it doesn't need to be protected to avoid collisions. */ -u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN] MEM_POSITION; +u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN]; /*****************************/ @@ -439,7 +439,7 @@ magicInit(); - subnetMask = htonl(0xffffff00); + subnetMask = PP_HTONL(0xffffff00); for (i = 0; i < NUM_PPP; i++) { /* Initialize each protocol to the standard option set. */ @@ -447,10 +447,6 @@ (*protp->init)(i); } } - -#if PPPOE_SUPPORT - pppoe_init(); -#endif /* PPPOE_SUPPORT */ } void @@ -706,12 +702,12 @@ nPut(PPPControl *pc, struct pbuf *nb) { struct pbuf *b; - int c = 0; + int c; for(b = nb; b != NULL; b = b->next) { if((c = sio_write(pc->fd, (u8_t*)b->payload, b->len)) != b->len) { PPPDEBUG(LOG_WARNING, - ("PPP nPut: incomplete sio_write(fd:%d, len:%d, c: 0x%"X8_F") c = %d\n", (size_t)pc->fd, b->len, c, c)); + ("PPP nPut: incomplete sio_write(fd:%"SZT_F", len:%d, c: 0x%"X8_F") c = %d\n", (size_t)pc->fd, b->len, c, c)); LINK_STATS_INC(link.err); pc->lastXMit = 0; /* prepend PPP_FLAG to next packet */ snmp_inc_ifoutdiscards(&pc->netif); @@ -766,7 +762,7 @@ #if PPPOE_SUPPORT static err_t -pppnetifOutputOverEthernet(int pd, struct pbuf *p) +pppifOutputOverEthernet(int pd, struct pbuf *p) { PPPControl *pc = &pppControl[pd]; struct pbuf *pb; @@ -810,7 +806,7 @@ /* Send a packet on the given connection. */ static err_t -pppnetifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) +pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) { int pd = (int)(size_t)netif->state; PPPControl *pc = &pppControl[pd]; @@ -827,7 +823,7 @@ /* We let any protocol value go through - it can't hurt us * and the peer will just drop it if it's not accepting it. */ if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) { - PPPDEBUG(LOG_WARNING, ("pppnetifOutput[%d]: bad parms prot=%d pb=%p\n", + PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad parms prot=%d pb=%p\n", pd, PPP_IP, pb)); LINK_STATS_INC(link.opterr); LINK_STATS_INC(link.drop); @@ -837,7 +833,7 @@ /* Check that the link is up. */ if (lcp_phase[pd] == PHASE_DEAD) { - PPPDEBUG(LOG_ERR, ("pppnetifOutput[%d]: link not up\n", pd)); + PPPDEBUG(LOG_ERR, ("pppifOutput[%d]: link not up\n", pd)); LINK_STATS_INC(link.rterr); LINK_STATS_INC(link.drop); snmp_inc_ifoutdiscards(netif); @@ -846,7 +842,7 @@ #if PPPOE_SUPPORT if(pc->ethif) { - return pppnetifOutputOverEthernet(pd, pb); + return pppifOutputOverEthernet(pd, pb); } #endif /* PPPOE_SUPPORT */ @@ -854,7 +850,7 @@ /* Grab an output buffer. */ headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); if (headMB == NULL) { - PPPDEBUG(LOG_WARNING, ("pppnetifOutput[%d]: first alloc fail\n", pd)); + PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: first alloc fail\n", pd)); LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.drop); snmp_inc_ifoutdiscards(netif); @@ -879,7 +875,7 @@ protocol = PPP_VJC_UNCOMP; break; default: - PPPDEBUG(LOG_WARNING, ("pppnetifOutput[%d]: bad IP packet\n", pd)); + PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad IP packet\n", pd)); LINK_STATS_INC(link.proterr); LINK_STATS_INC(link.drop); snmp_inc_ifoutdiscards(netif); @@ -940,7 +936,7 @@ /* If we failed to complete the packet, throw it away. */ if (!tailMB) { PPPDEBUG(LOG_WARNING, - ("pppnetifOutput[%d]: Alloc err - dropping proto=%d\n", + ("pppifOutput[%d]: Alloc err - dropping proto=%d\n", pd, protocol)); pbuf_free(headMB); LINK_STATS_INC(link.memerr); @@ -950,7 +946,7 @@ } /* Send it. */ - PPPDEBUG(LOG_INFO, ("pppnetifOutput[%d]: proto=0x%"X16_F"\n", pd, protocol)); + PPPDEBUG(LOG_INFO, ("pppifOutput[%d]: proto=0x%"X16_F"\n", pd, protocol)); nPut(pc, headMB); #endif /* PPPOS_SUPPORT */ @@ -1320,14 +1316,14 @@ } /* - * pppnetifNetifInit - netif init callback + * pppifNetifInit - netif init callback */ static err_t -pppnetifNetifInit(struct netif *netif) +pppifNetifInit(struct netif *netif) { netif->name[0] = 'p'; netif->name[1] = 'p'; - netif->output = pppnetifOutput; + netif->output = pppifOutput; netif->mtu = pppMTU((int)(size_t)netif->state); netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP; #if LWIP_NETIF_HOSTNAME @@ -1353,7 +1349,7 @@ } else { netif_remove(&pc->netif); if (netif_add(&pc->netif, &pc->addrs.our_ipaddr, &pc->addrs.netmask, - &pc->addrs.his_ipaddr, (void *)(size_t)pd, pppnetifNetifInit, ip_input)) { + &pc->addrs.his_ipaddr, (void *)(size_t)pd, pppifNetifInit, ip_input)) { netif_set_up(&pc->netif); pc->if_up = 1; pc->errCode = PPPERR_NONE; @@ -1583,7 +1579,7 @@ return p; /* live dangerously */ } - for(b = p, pl = (u_char*) q->payload; b != NULL; b = b->next) { + for(b = p, pl = (u_char*)q->payload; b != NULL; b = b->next) { MEMCPY(pl, b->payload, b->len); pl += b->len; } @@ -1669,8 +1665,8 @@ PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ uncompressed\n", pd)); #else /* PPPOS_SUPPORT && VJ_SUPPORT */ /* No handler for this protocol so drop the packet. */ - PPPDEBUG((LOG_INFO, - "pppInput[%d]: drop VJ UnComp in %d:.*H\n", + PPPDEBUG(LOG_INFO, + ("pppInput[%d]: drop VJ UnComp in %d:.*H\n", pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload)); #endif /* PPPOS_SUPPORT && VJ_SUPPORT */ break; @@ -1710,7 +1706,7 @@ protocol = htons(protocol); SMEMCPY(nb->payload, &protocol, sizeof(protocol)); #endif /* BYTE_ORDER == LITTLE_ENDIAN */ - lcp_sprotrej(pd, (u_char*) nb->payload, nb->len); + lcp_sprotrej(pd, (u_char*)nb->payload, nb->len); } break; } @@ -1893,9 +1889,9 @@ } #if 0 else { - PPPDEBUG((LOG_WARNING, - "pppInProc[%d]: Invalid control <%d>\n", pcrx->pd, curChar)); - pcrx->inState = PDSTART; + PPPDEBUG(LOG_WARNING, + ("pppInProc[%d]: Invalid control <%d>\n", pcrx->pd, curChar)); + pcrx->inState = PDSTART; } #endif case PDPROTOCOL1: /* Process protocol field 1. */ @@ -1935,7 +1931,7 @@ break; } if (pcrx->inHead == NULL) { - struct pppInputHeader *pih = (struct pppInputHeader*) nextNBuf->payload; + struct pppInputHeader *pih = (struct pppInputHeader *)nextNBuf->payload; pih->unit = pcrx->pd; pih->proto = pcrx->inProtocol;
--- a/lwip/netif/ppp/ppp_oe.c Fri Jun 18 10:38:57 2010 +0000 +++ b/lwip/netif/ppp/ppp_oe.c Fri Jul 09 14:46:47 2010 +0000 @@ -72,98 +72,17 @@ #if PPPOE_SUPPORT /* don't build if not configured for use in lwipopts.h */ +#include "netif/ppp_oe.h" + #include "ppp.h" #include "pppdebug.h" #include "lwip/timers.h" - -#include "netif/ppp_oe.h" +#include "lwip/memp.h" #include <string.h> #include <stdio.h> -/** @todo Replace this part with a simple list like other lwIP lists */ -#ifndef _SYS_QUEUE_H_ -#define _SYS_QUEUE_H_ - -/* - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may only be traversed in the forward direction. - * - * For details on the use of these macros, see the queue(3) manual page. - */ - -/* - * List declarations. - */ -#define LIST_HEAD(name, type) \ -struct name { \ - struct type *lh_first; /* first element */ \ -} - -#define LIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define LIST_ENTRY(type) \ -struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ -} - -/* - * List functions. - */ - -#define LIST_EMPTY(head) ((head)->lh_first == NULL) - -#define LIST_FIRST(head) ((head)->lh_first) - -#define LIST_FOREACH(var, head, field) \ - for ((var) = LIST_FIRST((head)); \ - (var); \ - (var) = LIST_NEXT((var), field)) - -#define LIST_INIT(head) do { \ - LIST_FIRST((head)) = NULL; \ -} while (0) - -#define LIST_INSERT_AFTER(listelm, elm, field) do { \ - if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL) \ - LIST_NEXT((listelm), field)->field.le_prev = \ - &LIST_NEXT((elm), field); \ - LIST_NEXT((listelm), field) = (elm); \ - (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ -} while (0) - -#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.le_prev = (listelm)->field.le_prev; \ - LIST_NEXT((elm), field) = (listelm); \ - *(listelm)->field.le_prev = (elm); \ - (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ -} while (0) - -#define LIST_INSERT_HEAD(head, elm, field) do { \ - if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ - LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field); \ - LIST_FIRST((head)) = (elm); \ - (elm)->field.le_prev = &LIST_FIRST((head)); \ -} while (0) - -#define LIST_NEXT(elm, field) ((elm)->field.le_next) - -#define LIST_REMOVE(elm, field) do { \ - if (LIST_NEXT((elm), field) != NULL) \ - LIST_NEXT((elm), field)->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = LIST_NEXT((elm), field); \ -} while (0) - -#endif /* !_SYS_QUEUE_H_ */ - /* Add a 16 bit unsigned value to a buffer pointed to by PTR */ #define PPPOE_ADD_16(PTR, VAL) \ @@ -188,27 +107,11 @@ #define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ #endif -struct pppoe_softc { - LIST_ENTRY(pppoe_softc) sc_list; - struct netif *sc_ethif; /* ethernet interface we are using */ - int sc_pd; /* ppp unit number */ - void (*sc_linkStatusCB)(int pd, int up); - - int sc_state; /* discovery phase or session connected */ - struct eth_addr sc_dest; /* hardware address of concentrator */ - u16_t sc_session; /* PPPoE session id */ +#ifndef PPPOE_ERRORSTRING_LEN +#define PPPOE_ERRORSTRING_LEN 64 +#endif +static char pppoe_error_tmp[PPPOE_ERRORSTRING_LEN]; - char *sc_service_name; /* if != NULL: requested name of service */ - char *sc_concentrator_name; /* if != NULL: requested concentrator id */ - u8_t *sc_ac_cookie; /* content of AC cookie we must echo back */ - size_t sc_ac_cookie_len; /* length of cookie data */ -#ifdef PPPOE_SERVER - u8_t *sc_hunique; /* content of host unique we must echo back */ - size_t sc_hunique_len; /* length of host unique */ -#endif - int sc_padi_retried; /* number of PADI retries already done */ - int sc_padr_retried; /* number of PADR retries already done */ -}; /* input routines */ static void pppoe_dispatch_disc_pkt(struct netif *, struct pbuf *); @@ -234,21 +137,16 @@ static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct netif *); static struct pppoe_softc * pppoe_find_softc_by_hunique(u8_t *, size_t, struct netif *); -static LIST_HEAD(pppoe_softc_head, pppoe_softc) pppoe_softc_list; - -void -pppoe_init(void) -{ - LIST_INIT(&pppoe_softc_list); -} +/** linked list of created pppoe interfaces */ +static struct pppoe_softc *pppoe_softc_list; err_t pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), struct pppoe_softc **scptr) { struct pppoe_softc *sc; - sc = mem_malloc(sizeof(struct pppoe_softc)); - if(!sc) { + sc = (struct pppoe_softc *)memp_malloc(MEMP_PPPOE_IF); + if (sc == NULL) { *scptr = NULL; return ERR_MEM; } @@ -261,7 +159,9 @@ sc->sc_linkStatusCB = linkStatusCB; sc->sc_ethif = ethif; - LIST_INSERT_HEAD(&pppoe_softc_list, sc, sc_list); + /* put the new interface at the head of the list */ + sc->next = pppoe_softc_list; + pppoe_softc_list = sc; *scptr = sc; @@ -271,9 +171,9 @@ err_t pppoe_destroy(struct netif *ifp) { - struct pppoe_softc * sc; + struct pppoe_softc *sc, *prev = NULL; - LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { + for (sc = pppoe_softc_list; sc != NULL; prev = sc, sc = sc->next) { if (sc->sc_ethif == ifp) { break; } @@ -284,18 +184,23 @@ } sys_untimeout(pppoe_timeout, sc); - LIST_REMOVE(sc, sc_list); + if (prev == NULL) { + /* remove sc from the head of the list */ + pppoe_softc_list = sc->next; + } else { + /* remove sc from the list */ + prev->next = sc->next; + } +#ifdef PPPOE_TODO if (sc->sc_concentrator_name) { mem_free(sc->sc_concentrator_name); } if (sc->sc_service_name) { mem_free(sc->sc_service_name); } - if (sc->sc_ac_cookie) { - mem_free(sc->sc_ac_cookie); - } - mem_free(sc); +#endif /* PPPOE_TODO */ + memp_free(MEMP_PPPOE_IF, sc); return ERR_OK; } @@ -315,7 +220,7 @@ return NULL; } - LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { + for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) { if (sc->sc_state == PPPOE_STATE_SESSION && sc->sc_session == session) { if (sc->sc_ethif == rcvif) { @@ -335,7 +240,7 @@ { struct pppoe_softc *sc, *t; - if (LIST_EMPTY(&pppoe_softc_list)) { + if (pppoe_softc_list == NULL) { return NULL; } @@ -344,7 +249,7 @@ } MEMCPY(&t, token, len); - LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { + for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) { if (sc == t) { break; } @@ -384,7 +289,6 @@ struct pppoe_softc *sc; const char *err_msg; char devname[6]; - char *error; u8_t *ac_cookie; u16_t ac_cookie_len; #ifdef PPPOE_SERVER @@ -487,17 +391,11 @@ break; } if (err_msg) { - error = NULL; if (errortag && len) { - error = mem_malloc(len+1); - if (error) { - strncpy(error, (char*)pb->payload + off + sizeof(pt), len); - error[len-1] = '\0'; - } - } - if (error) { - printf("%s: %s: %s\n", devname, err_msg, error); - mem_free(error); + u16_t error_len = LWIP_MIN(len, sizeof(pppoe_error_tmp)-1); + strncpy(pppoe_error_tmp, (char*)pb->payload + off + sizeof(pt), error_len); + pppoe_error_tmp[error_len-1] = '\0'; + printf("%s: %s: %s\n", devname, err_msg, pppoe_error_tmp); } else { printf("%s: %s\n", devname, err_msg); } @@ -594,7 +492,7 @@ case PPPOE_CODE_PADO: if (sc == NULL) { /* be quiet if there is not a single pppoe instance */ - if (!LIST_EMPTY(&pppoe_softc_list)) { + if (pppoe_softc_list != NULL) { printf("pppoe: received PADO but could not find request for it\n"); } goto done; @@ -604,13 +502,6 @@ goto done; } if (ac_cookie) { - if (sc->sc_ac_cookie) { - mem_free(sc->sc_ac_cookie); - } - sc->sc_ac_cookie = mem_malloc(ac_cookie_len); - if (sc->sc_ac_cookie == NULL) { - goto done; - } sc->sc_ac_cookie_len = ac_cookie_len; MEMCPY(sc->sc_ac_cookie, ac_cookie, ac_cookie_len); } @@ -659,7 +550,7 @@ pppoe_disc_input(struct netif *netif, struct pbuf *p) { /* avoid error messages if there is not a single pppoe instance */ - if (!LIST_EMPTY(&pppoe_softc_list)) { + if (pppoe_softc_list != NULL) { pppoe_dispatch_disc_pkt(netif, p); } else { pbuf_free(p); @@ -778,7 +669,10 @@ { struct pbuf *pb; u8_t *p; - int len, l1 = 0, l2 = 0; /* XXX: gcc */ + int len; +#ifdef PPPOE_TODO + int l1 = 0, l2 = 0; /* XXX: gcc */ +#endif /* PPPOE_TODO */ if (sc->sc_state >PPPOE_STATE_PADI_SENT) { PPPDEBUG(LOG_ERR, ("ERROR: pppoe_send_padi in state %d", sc->sc_state)); @@ -786,6 +680,7 @@ /* calculate length of frame (excluding ethernet header + pppoe header) */ len = 2 + 2 + 2 + 2 + sizeof sc; /* service name tag is required, host unique is send too */ +#ifdef PPPOE_TODO if (sc->sc_service_name != NULL) { l1 = (int)strlen(sc->sc_service_name); len += l1; @@ -794,6 +689,7 @@ l2 = (int)strlen(sc->sc_concentrator_name); len += 2 + 2 + l2; } +#endif /* PPPOE_TODO */ LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff", sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff); @@ -808,19 +704,24 @@ /* fill in pkt */ PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, (u16_t)len); PPPOE_ADD_16(p, PPPOE_TAG_SNAME); +#ifdef PPPOE_TODO if (sc->sc_service_name != NULL) { PPPOE_ADD_16(p, l1); MEMCPY(p, sc->sc_service_name, l1); p += l1; - } else { + } else +#endif /* PPPOE_TODO */ + { PPPOE_ADD_16(p, 0); } +#ifdef PPPOE_TODO if (sc->sc_concentrator_name != NULL) { PPPOE_ADD_16(p, PPPOE_TAG_ACNAME); PPPOE_ADD_16(p, l2); MEMCPY(p, sc->sc_concentrator_name, l2); p += l2; } +#endif /* PPPOE_TODO */ PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); PPPOE_ADD_16(p, sizeof(sc)); MEMCPY(p, &sc, sizeof sc); @@ -954,10 +855,6 @@ /* cleanup softc */ sc->sc_state = PPPOE_STATE_INITIAL; MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); - if (sc->sc_ac_cookie) { - mem_free(sc->sc_ac_cookie); - sc->sc_ac_cookie = NULL; - } sc->sc_ac_cookie_len = 0; #ifdef PPPOE_SERVER if (sc->sc_hunique) { @@ -993,17 +890,22 @@ { struct pbuf *pb; u8_t *p; - size_t len, l1 = 0; /* XXX: gcc */ + size_t len; +#ifdef PPPOE_TODO + size_t l1 = 0; /* XXX: gcc */ +#endif /* PPPOE_TODO */ if (sc->sc_state != PPPOE_STATE_PADR_SENT) { return ERR_CONN; } len = 2 + 2 + 2 + 2 + sizeof(sc); /* service name, host unique */ +#ifdef PPPOE_TODO if (sc->sc_service_name != NULL) { /* service name tag maybe empty */ l1 = strlen(sc->sc_service_name); len += l1; } +#endif /* PPPOE_TODO */ if (sc->sc_ac_cookie_len > 0) { len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */ } @@ -1017,11 +919,14 @@ p = (u8_t*)pb->payload + sizeof (struct eth_hdr); PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len); PPPOE_ADD_16(p, PPPOE_TAG_SNAME); +#ifdef PPPOE_TODO if (sc->sc_service_name != NULL) { PPPOE_ADD_16(p, l1); MEMCPY(p, sc->sc_service_name, l1); p += l1; - } else { + } else +#endif /* PPPOE_TODO */ + { PPPOE_ADD_16(p, 0); } if (sc->sc_ac_cookie_len > 0) { @@ -1053,7 +958,7 @@ LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); ethhdr = (struct eth_hdr *)pb->payload; - ethhdr->type = htons(ETHTYPE_PPPOEDISC); + ethhdr->type = PP_HTONS(ETHTYPE_PPPOEDISC); MEMCPY(ethhdr->dest.addr, dest, sizeof(ethhdr->dest.addr)); MEMCPY(ethhdr->src.addr, ((struct eth_addr *)outgoing_if->hwaddr)->addr, sizeof(ethhdr->src.addr)); @@ -1219,10 +1124,6 @@ /* clean up softc */ MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); - if (sc->sc_ac_cookie) { - mem_free(sc->sc_ac_cookie); - sc->sc_ac_cookie = NULL; - } sc->sc_ac_cookie_len = 0; sc->sc_session = 0; }
--- a/lwip/netif/ppp/vj.c Fri Jun 18 10:38:57 2010 +0000 +++ b/lwip/netif/ppp/vj.c Fri Jul 09 14:46:47 2010 +0000 @@ -160,7 +160,7 @@ * `compressible' (i.e., ACK isn't set or some other control bit is * set). */ - if ((IPH_OFFSET(ip) & htons(0x3fff)) || pb->tot_len < 40) { + if ((IPH_OFFSET(ip) & PP_HTONS(0x3fff)) || pb->tot_len < 40) { return (TYPE_IP); } th = (struct tcp_hdr *)&((long *)ip)[hlen]; @@ -608,7 +608,7 @@ goto bad; } - bufptr = (u8_t*) n0->payload; + bufptr = (u8_t*)n0->payload; for(q = np; q != NULL; q = q->next) { MEMCPY(q->payload, bufptr, q->len); bufptr += q->len;
--- a/netCfg.h Fri Jun 18 10:38:57 2010 +0000 +++ b/netCfg.h Fri Jul 09 14:46:47 2010 +0000 @@ -4,9 +4,10 @@ #define NET_PPP 1 #define NET_ZG2100 0 #define NET_ETH 1 -#define NET_USB_SERIAL 0 +#define NET_USB_SERIAL 1 #define NET_TELIT 1 #define NET_CFG_H 1 +#define NET_UMTS 1 #define NET_USB 1 #define NET_LWIP_STACK 1 #endif
--- a/services/mysql/MySQLClient.cpp Fri Jun 18 10:38:57 2010 +0000 +++ b/services/mysql/MySQLClient.cpp Fri Jul 09 14:46:47 2010 +0000 @@ -25,7 +25,7 @@ #include "sha1.h" //For 4.1+ passwords #include "mycrypt.h" //For 4.0- passwords -#define __DEBUG +//#define __DEBUG #include "dbg/dbg.h" #define MYSQL_TIMEOUT_MS 15000