XBee-mbed library http://mbed.org/users/okini3939/notebook/xbee-mbed/
Dependents: device_server_udp led_sender_post XBee_API_ex1 XBee_API_ex2 ... more
Revision 4:f6d73acc1f75, committed 2012-03-13
- Comitter:
- okini3939
- Date:
- Tue Mar 13 09:01:52 2012 +0000
- Parent:
- 3:8573b122fa84
- Child:
- 5:547cfff7adf7
- Commit message:
Changed in this revision
--- a/XBee.cpp Thu Mar 08 17:41:29 2012 +0000 +++ b/XBee.cpp Tue Mar 13 09:01:52 2012 +0000 @@ -67,11 +67,11 @@ _checksum = checksum; } -uint8_t XBeeResponse::getFrameDataLength() { +uint16_t XBeeResponse::getFrameDataLength() { return _frameLength; } -void XBeeResponse::setFrameLength(uint8_t frameLength) { +void XBeeResponse::setFrameLength(uint16_t frameLength) { _frameLength = frameLength; } @@ -158,7 +158,7 @@ return 11; } -uint8_t ZBRxResponse::getDataLength() { +uint16_t ZBRxResponse::getDataLength() { return getPacketLength() - getDataOffset() - 1; } @@ -461,7 +461,7 @@ return (getOption() & 4) == 4; } -uint8_t RxResponse::getDataLength() { +uint16_t RxResponse::getDataLength() { return getPacketLength() - getDataOffset() - 1; } @@ -519,7 +519,7 @@ return getStatus() == AT_OK; } -uint8_t RemoteAtCommandResponse::getValueLength() { +uint16_t RemoteAtCommandResponse::getValueLength() { return getFrameDataLength() - 14; } @@ -605,7 +605,7 @@ return getFrameData()[3]; } -uint8_t AtCommandResponse::getValueLength() { +uint16_t AtCommandResponse::getValueLength() { return getFrameDataLength() - 4; } @@ -632,7 +632,7 @@ } uint16_t XBeeResponse::getPacketLength() { - return ((_msbLength << 8) & 0xff) + (_lsbLength & 0xff); + return ((uint16_t)_msbLength << 8) + _lsbLength; } uint8_t* XBeeResponse::getFrameData() { @@ -664,27 +664,60 @@ void XBee::resetResponse() { _pos = 0; + _epos = 0; _escape = false; + _checksumTotal = 0; _response.reset(); } XBee::XBee(PinName p_tx, PinName p_rx): _xbee(p_tx, p_rx) { _pos = 0; + _epos = 0; _escape = false; _checksumTotal = 0; _nextFrameId = 0; - _cts = NULL; _response.init(); _response.setFrameData(_responseFrameData); } -XBee::XBee(PinName p_tx, PinName p_rx, PinName p_cts): _xbee(p_tx, p_rx) { +XBee::XBee(PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts): _xbee(p_tx, p_rx) { _pos = 0; + _epos = 0; _escape = false; _checksumTotal = 0; _nextFrameId = 0; - _cts = new DigitalIn(p_cts); +#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) + if (p_cts == p12) { // CTS (P0_17) + LPC_UART1->MCR |= (1<<7); // CTSEN + LPC_PINCON->PINSEL1 &= ~(3 << 2); + LPC_PINCON->PINSEL1 |= (1 << 2); // UART CTS + } + if (p_rts == P0_22) { // RTS (P0_22) + LPC_UART1->MCR |= (1<<6); // RTSEN + LPC_PINCON->PINSEL1 &= ~(3 << 12); + LPC_PINCON->PINSEL1 |= (1 << 12); // UART RTS + _xbee.attach(this, &XBee::isr_recv, Serial::RxIrq); + _rts = true; + } else { + _rts = false; + } +#elif defined(TARGET_LPC11U24) + if (p_cts == p21) { // CTS (P0_7) + LPC_UART->MCR = (1<<7); // CTSEN + LPC_IOCON->PIO0_7 &= ~0x07; + LPC_IOCON->PIO0_7 |= 0x01; // UART CTS + } + if (p_rts == p22) { // RTS (P0_17) + LPC_UART->MCR = (1<<6); // RTSEN + LPC_IOCON->PIO0_17 &= ~0x07; + LPC_IOCON->PIO0_17 |= 0x01; // UART RTS + _xbee.attach(this, &XBee::isr_recv, Serial::RxIrq); + _rts = true; + } else { + _rts = false; + } +#endif _response.init(); _response.setFrameData(_responseFrameData); @@ -760,11 +793,30 @@ } } + DBG("(timeout %d %d)\r\n", _pos, _epos); // timed out t.stop(); return false; } +void XBee::isr_recv () { + _rxbuf[_rxaddr_w] = _xbee.getc(); + _rxaddr_w = (_rxaddr_w + 1) % MAX_RXBUF_SIZE; +} + +int XBee::getbuf () { + int r; + __disable_irq(); + r = _rxbuf[_rxaddr_r]; + _rxaddr_r = (_rxaddr_r + 1) % MAX_RXBUF_SIZE; + __enable_irq(); + return r; +} + +int XBee::bufreadable () { + return _rxaddr_w != _rxaddr_r; +} + void XBee::readPacket() { // reset previous response if (_response.isAvailable() || _response.isError()) { @@ -772,20 +824,33 @@ resetResponse(); } - while (_xbee.readable()) { +// while (_xbee.readable()) { + while ((! _rts && _xbee.readable()) || (_rts && bufreadable())) { - b = _xbee.getc(); +// b = _xbee.getc(); + if (_rts) { + b = getbuf(); + } else { + b = _xbee.getc(); + } if (_pos > 0 && b == START_BYTE && ATAP == 2) { // new packet start before previous packeted completed -- discard previous packet and start over + DBG("error: %02x %d %d\r\n", b, _pos, _epos); _response.setErrorCode(UNEXPECTED_START_BYTE); return; } if (_pos > 0 && b == ESCAPE) { if (_xbee.readable()) { - b = _xbee.getc(); +// b = _xbee.getc(); + if (_rts) { + b = getbuf(); + } else { + b = _xbee.getc(); + } b = 0x20 ^ b; + _epos ++; } else { // escape byte. next byte will be _escape = true; @@ -797,6 +862,7 @@ if (_escape == true) { b = 0x20 ^ b; _escape = false; + _epos ++; } // checksum includes all bytes starting with api id @@ -840,10 +906,10 @@ // check if we're at the end of the packet // packet length does not include start, length, or checksum bytes, so add 3 if (_pos == (_response.getPacketLength() + 3)) { +// if (_pos + _epos == (_response.getPacketLength() + 3)) { // verify checksum //std::cout << "read checksum " << static_cast<unsigned int>(b) << " at pos " << static_cast<unsigned int>(_pos) << std::endl; - if ((_checksumTotal & 0xff) == 0xff) { _response.setChecksum(b); _response.setAvailable(true); @@ -851,6 +917,7 @@ _response.setErrorCode(NO_ERROR); } else { // checksum failed + DBG("error: checksum %02x %02x %d %d\r\n", b, _checksumTotal, _pos, _epos); _response.setErrorCode(CHECKSUM_FAILURE); } @@ -860,6 +927,7 @@ // reset state vars _pos = 0; + _epos = 0; _checksumTotal = 0; @@ -909,7 +977,7 @@ //} -PayloadRequest::PayloadRequest(uint8_t apiId, uint8_t frameId, uint8_t *payload, uint8_t payloadLength) : XBeeRequest(apiId, frameId) { +PayloadRequest::PayloadRequest(uint8_t apiId, uint8_t frameId, uint8_t *payload, uint16_t payloadLength) : XBeeRequest(apiId, frameId) { _payloadPtr = payload; _payloadLength = payloadLength; } @@ -922,11 +990,11 @@ _payloadPtr = payload; } -uint8_t PayloadRequest::getPayloadLength() { +uint16_t PayloadRequest::getPayloadLength() { return _payloadLength; } -void PayloadRequest::setPayloadLength(uint8_t payloadLength) { +void PayloadRequest::setPayloadLength(uint16_t payloadLength) { _payloadLength = payloadLength; } @@ -967,21 +1035,21 @@ } -ZBTxRequest::ZBTxRequest(XBeeAddress64 &addr64, uint16_t addr16, uint8_t broadcastRadius, uint8_t option, uint8_t *data, uint8_t dataLength, uint8_t frameId): PayloadRequest(ZB_TX_REQUEST, frameId, data, dataLength) { +ZBTxRequest::ZBTxRequest(XBeeAddress64 &addr64, uint16_t addr16, uint8_t broadcastRadius, uint8_t option, uint8_t *data, uint16_t dataLength, uint8_t frameId): PayloadRequest(ZB_TX_REQUEST, frameId, data, dataLength) { _addr64 = addr64; _addr16 = addr16; _broadcastRadius = broadcastRadius; _option = option; } -ZBTxRequest::ZBTxRequest(XBeeAddress64 &addr64, uint8_t *data, uint8_t dataLength): PayloadRequest(ZB_TX_REQUEST, DEFAULT_FRAME_ID, data, dataLength) { +ZBTxRequest::ZBTxRequest(XBeeAddress64 &addr64, uint8_t *data, uint16_t dataLength): PayloadRequest(ZB_TX_REQUEST, DEFAULT_FRAME_ID, data, dataLength) { _addr64 = addr64; _addr16 = ZB_BROADCAST_ADDRESS; _broadcastRadius = ZB_BROADCAST_RADIUS_MAX_HOPS; _option = ZB_TX_UNICAST; } -uint8_t ZBTxRequest::getFrameData(uint8_t pos) { +uint8_t ZBTxRequest::getFrameData(uint16_t pos) { if (pos == 0) { return (_addr64.getMsb() >> 24) & 0xff; } else if (pos == 1) { @@ -1011,7 +1079,7 @@ } } -uint8_t ZBTxRequest::getFrameDataLength() { +uint16_t ZBTxRequest::getFrameDataLength() { return ZB_TX_API_LENGTH + getPayloadLength(); } @@ -1055,17 +1123,17 @@ } -Tx16Request::Tx16Request(uint16_t addr16, uint8_t option, uint8_t *data, uint8_t dataLength, uint8_t frameId) : PayloadRequest(TX_16_REQUEST, frameId, data, dataLength) { +Tx16Request::Tx16Request(uint16_t addr16, uint8_t option, uint8_t *data, uint16_t dataLength, uint8_t frameId) : PayloadRequest(TX_16_REQUEST, frameId, data, dataLength) { _addr16 = addr16; _option = option; } -Tx16Request::Tx16Request(uint16_t addr16, uint8_t *data, uint8_t dataLength) : PayloadRequest(TX_16_REQUEST, DEFAULT_FRAME_ID, data, dataLength) { +Tx16Request::Tx16Request(uint16_t addr16, uint8_t *data, uint16_t dataLength) : PayloadRequest(TX_16_REQUEST, DEFAULT_FRAME_ID, data, dataLength) { _addr16 = addr16; _option = ACK_OPTION; } -uint8_t Tx16Request::getFrameData(uint8_t pos) { +uint8_t Tx16Request::getFrameData(uint16_t pos) { if (pos == 0) { return (_addr16 >> 8) & 0xff; @@ -1078,7 +1146,7 @@ } } -uint8_t Tx16Request::getFrameDataLength() { +uint16_t Tx16Request::getFrameDataLength() { return TX_16_API_LENGTH + getPayloadLength(); } @@ -1102,17 +1170,17 @@ } -Tx64Request::Tx64Request(XBeeAddress64 &addr64, uint8_t option, uint8_t *data, uint8_t dataLength, uint8_t frameId) : PayloadRequest(TX_64_REQUEST, frameId, data, dataLength) { +Tx64Request::Tx64Request(XBeeAddress64 &addr64, uint8_t option, uint8_t *data, uint16_t dataLength, uint8_t frameId) : PayloadRequest(TX_64_REQUEST, frameId, data, dataLength) { _addr64 = addr64; _option = option; } -Tx64Request::Tx64Request(XBeeAddress64 &addr64, uint8_t *data, uint8_t dataLength) : PayloadRequest(TX_64_REQUEST, DEFAULT_FRAME_ID, data, dataLength) { +Tx64Request::Tx64Request(XBeeAddress64 &addr64, uint8_t *data, uint16_t dataLength) : PayloadRequest(TX_64_REQUEST, DEFAULT_FRAME_ID, data, dataLength) { _addr64 = addr64; _option = ACK_OPTION; } -uint8_t Tx64Request::getFrameData(uint8_t pos) { +uint8_t Tx64Request::getFrameData(uint16_t pos) { if (pos == 0) { return (_addr64.getMsb() >> 24) & 0xff; @@ -1137,7 +1205,7 @@ } } -uint8_t Tx64Request::getFrameDataLength() { +uint16_t Tx64Request::getFrameDataLength() { return TX_64_API_LENGTH + getPayloadLength(); } @@ -1199,7 +1267,7 @@ _commandValueLength = length; } -uint8_t AtCommandRequest::getFrameData(uint8_t pos) { +uint8_t AtCommandRequest::getFrameData(uint16_t pos) { if (pos == 0) { return _command[0]; @@ -1219,7 +1287,7 @@ // XBeeRequest::reset(); //} -uint8_t AtCommandRequest::getFrameDataLength() { +uint16_t AtCommandRequest::getFrameDataLength() { // command is 2 byte + length of value return AT_COMMAND_API_LENGTH + _commandValueLength; } @@ -1286,7 +1354,7 @@ } -uint8_t RemoteAtCommandRequest::getFrameData(uint8_t pos) { +uint8_t RemoteAtCommandRequest::getFrameData(uint16_t pos) { if (pos == 0) { return (_remoteAddress64.getMsb() >> 24) & 0xff; } else if (pos == 1) { @@ -1318,7 +1386,7 @@ } } -uint8_t RemoteAtCommandRequest::getFrameDataLength() { +uint16_t RemoteAtCommandRequest::getFrameDataLength() { return REMOTE_AT_COMMAND_API_LENGTH + getCommandValueLength(); } @@ -1376,12 +1444,9 @@ if (escape && (b == START_BYTE || b == ESCAPE || b == XON || b == XOFF)) { // std::cout << "escaping byte [" << toHexString(b) << "] " << std::endl; - if (_cts) while (_cts->read() != 0); _xbee.putc(ESCAPE); - if (_cts) while (_cts->read() != 0); _xbee.putc(b ^ 0x20); } else { - if (_cts) while (_cts->read() != 0); _xbee.putc(b); } DBG("%02x ", b);
--- a/XBee.h Thu Mar 08 17:41:29 2012 +0000 +++ b/XBee.h Tue Mar 13 09:01:52 2012 +0000 @@ -33,6 +33,7 @@ #define SERIES_1 #define SERIES_2 +#define WIFI // set to ATAP value of XBee. AP=2 is recommended #define ATAP 2 @@ -48,7 +49,9 @@ // if a RX packet exceeds this size, it cannot be parsed! // This value is determined by the largest packet size (100 byte payload + 64-bit address + option byte and rssi byte) of a series 1 radio -#define MAX_FRAME_DATA_SIZE 110 +//#define MAX_FRAME_DATA_SIZE 110 +#define MAX_FRAME_DATA_SIZE 1520 +#define MAX_RXBUF_SIZE 32 #define BROADCAST_ADDRESS 0xffff #define ZB_BROADCAST_ADDRESS 0xfffe @@ -182,7 +185,7 @@ * Returns the length of the frame data: all bytes after the api id, and prior to the checksum * Note up to release 0.1.2, this was incorrectly including the checksum in the length. */ - uint8_t getFrameDataLength(); + uint16_t getFrameDataLength(); void setFrameData(uint8_t* frameDataPtr); /** * Returns the buffer that contains the response. @@ -194,7 +197,7 @@ */ uint8_t* getFrameData(); - void setFrameLength(uint8_t frameLength); + void setFrameLength(uint16_t frameLength); // to support future 65535 byte packets I guess /** * Returns the length of the packet @@ -283,7 +286,7 @@ uint8_t _msbLength; uint8_t _lsbLength; uint8_t _checksum; - uint8_t _frameLength; + uint16_t _frameLength; bool _complete; uint8_t _errorCode; }; @@ -348,7 +351,7 @@ /** * Returns the length of the payload */ - virtual uint8_t getDataLength() = 0; + virtual uint16_t getDataLength() = 0; /** * Returns the position in the frame data where the data begins */ @@ -382,7 +385,7 @@ XBeeAddress64& getRemoteAddress64(); uint16_t getRemoteAddress16(); uint8_t getOption(); - virtual uint8_t getDataLength(); + virtual uint16_t getDataLength(); // frame position where data starts virtual uint8_t getDataOffset(); private: @@ -444,7 +447,7 @@ uint8_t getOption(); bool isAddressBroadcast(); bool isPanBroadcast(); - virtual uint8_t getDataLength(); + virtual uint16_t getDataLength(); virtual uint8_t getDataOffset(); virtual uint8_t getRssiOffset() = 0; }; @@ -558,7 +561,7 @@ /** * Returns the length of the command value array. */ - uint8_t getValueLength(); + uint16_t getValueLength(); /** * Returns true if status equals AT_OK */ @@ -588,7 +591,7 @@ /** * Returns the length of the command value array. */ - uint8_t getValueLength(); + uint16_t getValueLength(); /** * Returns the 16-bit address of the remote radio */ @@ -639,11 +642,11 @@ * The reason for this is the API ID and Frame ID are common to all requests, whereas my definition of * frame data is only the API specific data. */ - virtual uint8_t getFrameData(uint8_t pos) = 0; + virtual uint8_t getFrameData(uint16_t pos) = 0; /** * Returns the size of the api frame (not including frame id or api id or checksum). */ - virtual uint8_t getFrameDataLength() = 0; + virtual uint16_t getFrameDataLength() = 0; //void reset(); protected: void setApiId(uint8_t apiId); @@ -677,7 +680,7 @@ class XBee { public: XBee(PinName p_tx, PinName p_rx); - XBee(PinName p_tx, PinName p_rx, PinName p_cts); + XBee(PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts); // for eclipse dev only // void setSerial(HardwareSerial serial); /** @@ -723,21 +726,27 @@ * Returns a sequential frame id between 1 and 255 */ uint8_t getNextFrameId(); + + void isr_recv (); + int getbuf (); + int bufreadable (); private: void sendByte(uint8_t b, bool escape); void resetResponse(); XBeeResponse _response; bool _escape; // current packet position for response. just a state variable for packet parsing and has no relevance for the response otherwise - uint8_t _pos; + uint16_t _pos, _epos; // last byte read uint8_t b; - uint8_t _checksumTotal; + uint16_t _checksumTotal; uint8_t _nextFrameId; // buffer for incoming RX packets. holds only the api specific frame data, starting after the api id byte and prior to checksum uint8_t _responseFrameData[MAX_FRAME_DATA_SIZE]; Serial _xbee; - DigitalIn *_cts; + char _rxbuf[MAX_RXBUF_SIZE]; + int _rxaddr_w, _rxaddr_r; + bool _rts; }; /** @@ -745,7 +754,7 @@ */ class PayloadRequest : public XBeeRequest { public: - PayloadRequest(uint8_t apiId, uint8_t frameId, uint8_t *payload, uint8_t payloadLength); + PayloadRequest(uint8_t apiId, uint8_t frameId, uint8_t *payload, uint16_t payloadLength); /** * Returns the payload of the packet, if not null */ @@ -757,16 +766,16 @@ /** * Returns the length of the payload array, as specified by the user. */ - uint8_t getPayloadLength(); + uint16_t getPayloadLength(); /** * Sets the length of the payload to include in the request. For example if the payload array * is 50 bytes and you only want the first 10 to be included in the packet, set the length to 10. * Length must be <= to the array length. */ - void setPayloadLength(uint8_t payloadLength); + void setPayloadLength(uint16_t payloadLength); private: uint8_t* _payloadPtr; - uint8_t _payloadLength; + uint16_t _payloadLength; }; #ifdef SERIES_1 @@ -781,11 +790,11 @@ */ class Tx16Request : public PayloadRequest { public: - Tx16Request(uint16_t addr16, uint8_t option, uint8_t *payload, uint8_t payloadLength, uint8_t frameId); + Tx16Request(uint16_t addr16, uint8_t option, uint8_t *payload, uint16_t payloadLength, uint8_t frameId); /** * Creates a Unicast Tx16Request with the ACK option and DEFAULT_FRAME_ID */ - Tx16Request(uint16_t addr16, uint8_t *payload, uint8_t payloadLength); + Tx16Request(uint16_t addr16, uint8_t *payload, uint16_t payloadLength); /** * Creates a default instance of this class. At a minimum you must specify * a payload, payload length and a destination address before sending this request. @@ -795,8 +804,8 @@ void setAddress16(uint16_t addr16); uint8_t getOption(); void setOption(uint8_t option); - virtual uint8_t getFrameData(uint8_t pos); - virtual uint8_t getFrameDataLength(); + virtual uint8_t getFrameData(uint16_t pos); + virtual uint16_t getFrameDataLength(); protected: private: uint16_t _addr16; @@ -813,11 +822,11 @@ */ class Tx64Request : public PayloadRequest { public: - Tx64Request(XBeeAddress64 &addr64, uint8_t option, uint8_t *payload, uint8_t payloadLength, uint8_t frameId); + Tx64Request(XBeeAddress64 &addr64, uint8_t option, uint8_t *payload, uint16_t payloadLength, uint8_t frameId); /** * Creates a unicast Tx64Request with the ACK option and DEFAULT_FRAME_ID */ - Tx64Request(XBeeAddress64 &addr64, uint8_t *payload, uint8_t payloadLength); + Tx64Request(XBeeAddress64 &addr64, uint8_t *payload, uint16_t payloadLength); /** * Creates a default instance of this class. At a minimum you must specify * a payload, payload length and a destination address before sending this request. @@ -828,8 +837,8 @@ // TODO move option to superclass uint8_t getOption(); void setOption(uint8_t option); - virtual uint8_t getFrameData(uint8_t pos); - virtual uint8_t getFrameDataLength(); + virtual uint8_t getFrameData(uint16_t pos); + virtual uint16_t getFrameDataLength(); private: XBeeAddress64 _addr64; uint8_t _option; @@ -857,8 +866,8 @@ /** * Creates a unicast ZBTxRequest with the ACK option and DEFAULT_FRAME_ID */ - ZBTxRequest(XBeeAddress64 &addr64, uint8_t *payload, uint8_t payloadLength); - ZBTxRequest(XBeeAddress64 &addr64, uint16_t addr16, uint8_t broadcastRadius, uint8_t option, uint8_t *payload, uint8_t payloadLength, uint8_t frameId); + ZBTxRequest(XBeeAddress64 &addr64, uint8_t *payload, uint16_t payloadLength); + ZBTxRequest(XBeeAddress64 &addr64, uint16_t addr16, uint8_t broadcastRadius, uint8_t option, uint8_t *payload, uint16_t payloadLength, uint8_t frameId); /** * Creates a default instance of this class. At a minimum you must specify * a payload, payload length and a destination address before sending this request. @@ -874,8 +883,8 @@ void setOption(uint8_t option); protected: // declare virtual functions - virtual uint8_t getFrameData(uint8_t pos); - virtual uint8_t getFrameDataLength(); + virtual uint8_t getFrameData(uint16_t pos); + virtual uint16_t getFrameDataLength(); private: XBeeAddress64 _addr64; uint16_t _addr16; @@ -894,8 +903,8 @@ AtCommandRequest(); AtCommandRequest(uint8_t *command); AtCommandRequest(uint8_t *command, uint8_t *commandValue, uint8_t commandValueLength); - virtual uint8_t getFrameData(uint8_t pos); - virtual uint8_t getFrameDataLength(); + virtual uint8_t getFrameData(uint16_t pos); + virtual uint16_t getFrameDataLength(); uint8_t* getCommand(); void setCommand(uint8_t* command); uint8_t* getCommandValue(); @@ -946,8 +955,8 @@ void setRemoteAddress64(XBeeAddress64 &remoteAddress64); bool getApplyChanges(); void setApplyChanges(bool applyChanges); - virtual uint8_t getFrameData(uint8_t pos); - virtual uint8_t getFrameDataLength(); + virtual uint8_t getFrameData(uint16_t pos); + virtual uint16_t getFrameDataLength(); static XBeeAddress64 broadcastAddress64; // static uint16_t broadcast16Address; private:
--- a/XBeeWiFi.cpp Thu Mar 08 17:41:29 2012 +0000 +++ b/XBeeWiFi.cpp Tue Mar 13 09:01:52 2012 +0000 @@ -19,7 +19,7 @@ #define REVERSE_ENDIAN(x) (uint16_t)(((uint16_t)x >> 8) | ((uint16_t)x << 8)) #ifdef USE_WIFICLASS -XBeeWiFi::XBeeWiFi (PinName p_tx, PinName p_rx, PinName p_cts) : XBee(p_tx, p_rx, p_cts) { +XBeeWiFi::XBeeWiFi (PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts) : XBee(p_tx, p_rx, p_cts, p_rts) { } int XBeeWiFi::setup (int security, const char *ssid, const char *pin) { @@ -86,6 +86,36 @@ return getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId()); } +int XBeeWiFi::baud (int b) { + // RESET + uint8_t cmd[2] = {'B', 'D'}; + char val[4]; + AtCommandRequest atRequest; + int r, len; + + if (b < 0x100) { + val[0] = b; + len = 1; + } else { + val[0] = (b >> 24) & 0xff; + val[1] = (b >> 16) & 0xff; + val[2] = (b >> 8) & 0xff; + val[3] = b & 0xff; + len = 4; + } + atRequest.setCommand(cmd); + atRequest.setCommandValue((uint8_t*)val); + atRequest.setCommandValueLength(len); + atRequest.setFrameId(getNextFrameId()); + send(atRequest); + r = getWiResponse(AT_COMMAND_RESPONSE, atRequest.getFrameId()); + + if (r == 0) { + begin(b); + } + return r; +} + int XBeeWiFi::setAddress () { // DHCP uint8_t cmd[2] = {'M', 'A'}; @@ -281,9 +311,11 @@ return 0; } +// *** Note: wifi is turned off when XBee send the port 53 udp packet. int XBeeWiFi::getHostByName (const char* name, IpAddr &addr) { - char buf[1024]; - int i, r, len; + Timer timeout; + char buf[600]; + int r, len; uint8_t cmd[2] = {'C', '0'}; char val[2]; IPv4TransmitRequest dnsRequest; @@ -294,7 +326,7 @@ addr = IpAddr(127, 0, 0, 1); return 0; } - +/* // bind src port val[0] = (DNS_SRC_PORT >> 8) & 0xff; val[1] = DNS_SRC_PORT & 0xff; @@ -305,7 +337,7 @@ send(atRequest); r = getWiResponse(AT_COMMAND_RESPONSE); DBG("wifi C0: %d\r\n", r); - +*/ // send DNS request len = createDnsRequest(name, buf); dnsRequest.setAddress(_nameserver); @@ -314,18 +346,23 @@ dnsRequest.setProtocol(PROTOCOL_UDP); dnsRequest.setPayload((uint8_t*)buf); dnsRequest.setPayloadLength(len); - for (i = 0; i < DNS_TIMEOUT; i ++) { + + // wait responce + timeout.reset(); + timeout.start(); + while (timeout.read_ms() < DNS_TIMEOUT) { dnsRequest.setFrameId(getNextFrameId()); send(dnsRequest); r = getWiResponse(TX_STATUS_RESPONSE, dnsRequest.getFrameId()); DBG("wifi TX: %d\r\n", r); - if (r == 0) { + if (r >= 0) { // recv DNS request r = getWiResponse(IPv4_RX_FRAME, 0, 3000); DBG("wifi RX: %d\r\n", r); if (r >= 0) { + timeout.stop(); getResponse().getAtCommandResponse(atResponse); return getDnsResponse(atResponse.getValue() + 6, atResponse.getValueLength() - 6, addr); } @@ -333,6 +370,7 @@ break; } } + timeout.stop(); return -1; } @@ -418,7 +456,7 @@ IPv4TransmitRequest::IPv4TransmitRequest() : PayloadRequest(IPv4_TRANSMIT_REQUEST, DEFAULT_FRAME_ID, NULL, 0) { } -IPv4TransmitRequest::IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint16_t srcPort, uint8_t protocol, uint8_t option, uint8_t *data, uint8_t dataLength, uint8_t frameId): PayloadRequest(IPv4_TRANSMIT_REQUEST, frameId, data, dataLength) { +IPv4TransmitRequest::IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint16_t srcPort, uint8_t protocol, uint8_t option, uint8_t *data, uint16_t dataLength, uint8_t frameId): PayloadRequest(IPv4_TRANSMIT_REQUEST, frameId, data, dataLength) { _dstAddr = dstAddr; _dstPort = dstPort; _srcPort = srcPort; @@ -426,7 +464,7 @@ _option = option; } -IPv4TransmitRequest::IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint8_t *data, uint8_t dataLength): PayloadRequest(IPv4_TRANSMIT_REQUEST, DEFAULT_FRAME_ID, data, dataLength) { +IPv4TransmitRequest::IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint8_t *data, uint16_t dataLength): PayloadRequest(IPv4_TRANSMIT_REQUEST, DEFAULT_FRAME_ID, data, dataLength) { _dstAddr = dstAddr; _dstPort = dstPort; _srcPort = 0x270f; @@ -434,7 +472,7 @@ _option = 0; } -uint8_t IPv4TransmitRequest::getFrameData(uint8_t pos) { +uint8_t IPv4TransmitRequest::getFrameData(uint16_t pos) { if (pos == 0) { return _dstAddr[0]; } else if (pos == 1) { @@ -460,7 +498,7 @@ } } -uint8_t IPv4TransmitRequest::getFrameDataLength() { +uint16_t IPv4TransmitRequest::getFrameDataLength() { return IPv4_TRANSMIT_REQUEST_API_LENGTH + getPayloadLength(); } @@ -518,32 +556,35 @@ } +IPV4RxFrame::IPV4RxFrame () { +} + IpAddr& IPV4RxFrame::getSrcAddress() { - _srcAddr = IpAddr(getFrameData()[4], getFrameData()[5], getFrameData()[6], getFrameData()[7]); + _srcAddr = IpAddr(getFrameData()[0], getFrameData()[1], getFrameData()[2], getFrameData()[3]); return _srcAddr; } uint16_t IPV4RxFrame::getDstPort() { - return (getFrameData()[8] << 8) + getFrameData()[9]; + return (getFrameData()[4] << 8) + getFrameData()[5]; } uint16_t IPV4RxFrame::getSrcPort() { - return (getFrameData()[10] << 8) + getFrameData()[11]; + return (getFrameData()[6] << 8) + getFrameData()[7]; } uint8_t IPV4RxFrame::getProtocol() { - return getFrameData()[12]; + return getFrameData()[8]; } uint8_t IPV4RxFrame::getStatus() { - return getFrameData()[13]; + return getFrameData()[9]; } // markers to read data from packet array. this is the index, so the 12th item in the array uint8_t IPV4RxFrame::getDataOffset() { - return 14; + return 10; } -uint8_t IPV4RxFrame::getDataLength() { +uint16_t IPV4RxFrame::getDataLength() { return getPacketLength() - getDataOffset() - 1; }
--- a/XBeeWiFi.h Thu Mar 08 17:41:29 2012 +0000 +++ b/XBeeWiFi.h Tue Mar 13 09:01:52 2012 +0000 @@ -72,8 +72,8 @@ #define DNS_CLASS_IN 1 #define DNS_PORT 53 -#define DNS_SRC_PORT 1234 -#define DNS_TIMEOUT 5 // x 3s +#define DNS_SRC_PORT 10053 +#define DNS_TIMEOUT 15000 // ms struct DNSHeader { uint16_t id; @@ -104,21 +104,26 @@ */ class XBeeWiFi : public XBee { public: - XBeeWiFi (PinName p_tx, PinName p_rx, PinName p_cts); + XBeeWiFi (PinName p_tx, PinName p_rx, PinName p_cts, PinName p_rts); int setup (int security, const char *ssid, const char *pin); int setup (const char *ssid); int reset (); + int baud (int b); int setAddress (); int setAddress (IpAddr &ipaddr, IpAddr &netmask, IpAddr &gateway, IpAddr &nameserver); int getAddress (IpAddr &ipaddr, IpAddr &netmask, IpAddr &gateway, IpAddr &nameserver); int setTimeout (int timeout); int getStatus (); - int getWiResponse (int apiId, int frameid = 0, int timeout = 1500); + int getWiResponse (int apiId, int frameid = 0, int timeout = 3000); #ifdef USE_WIFIDNS int setNameserver (IpAddr &nameserver); int getHostByName (const char* name, IpAddr &addr); #endif + /** + * Call with instance of AtCommandResponse only if getApiId() == AT_COMMAND_RESPONSE + */ +// void getIPV4RxFrame (XBeeResponse &responses); protected: int getWiAddr (IpAddr &ipaddr); @@ -140,8 +145,8 @@ /** * Creates a unicast IPv4TransmitRequest with the DEFAULT_FRAME_ID */ - IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint16_t srcPort, uint8_t protocol, uint8_t option, uint8_t *data, uint8_t dataLength, uint8_t frameId); - IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint8_t *data, uint8_t dataLength); + IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint16_t srcPort, uint8_t protocol, uint8_t option, uint8_t *data, uint16_t dataLength, uint8_t frameId); + IPv4TransmitRequest(IpAddr &dstAddr, uint16_t dstPort, uint8_t *data, uint16_t dataLength); /** * Creates a default instance of this class. At a minimum you must specify * a payload, payload length and a destination address before sending this request. @@ -159,8 +164,8 @@ void setOption(uint8_t option); protected: // declare virtual functions - virtual uint8_t getFrameData(uint8_t pos); - virtual uint8_t getFrameDataLength(); + virtual uint8_t getFrameData(uint16_t pos); + virtual uint16_t getFrameDataLength(); private: IpAddr _dstAddr; uint16_t _dstPort; @@ -190,7 +195,7 @@ uint16_t getSrcPort(); uint8_t getProtocol(); uint8_t getStatus(); - virtual uint8_t getDataLength(); + virtual uint16_t getDataLength(); // frame position where data starts virtual uint8_t getDataOffset(); private: