XBee-mbed library Forked from http://mbed.org/users/okini3939/notebook/xbee-mbed/
Fork of XBee by
Diff: XBee.cpp
- Revision:
- 4:f6d73acc1f75
- Parent:
- 3:8573b122fa84
- Child:
- 6:6f84e2840408
--- 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);