Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of XBee by
Diff: XBee.cpp
- Revision:
- 4:f6d73acc1f75
- Parent:
- 3:8573b122fa84
- Child:
- 6:dc1f35defd71
--- 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);