API for communicating with XBee devices.

Dependencies:   CircularBuffer FixedLengthList

Dependents:   XBeeApiTest XBeeApiSimpleATCmdsExample XBeeApiBroadcastExample XBeeApiBroadcastExampleRTOS ... more

Overview

XBeeApi is intended to be a library for providing a high-level API interface to the XBee - for example getChannel() and setChannel(2) methods rather than needing to send( "ATCH" ) and send( "ATCH 2" ) - and then de-code the responses.

See the notebook page here for a description of how the API works & some details on the various classes.

Features:

  • Support for transmission & reception of data packets
  • Support for reading & changing settings
  • Support for "Remote AT" interface to access settings & I/O channels on remote XBees
  • XBeeApi should work if you're using mbed-rtos, though it is not currently threadsafe. Take a look at the XBeeApiBroadcastExampleRTOS example if you're including mbed-rtos.

Example Programs

There are also example programs available:

Transmit

Import programXBeeApiSimpleBroadcastExample

Simple example of how to use XBeeApi - set up the XBee, configure P2P networking then transmit a frame.

Import programXBeeApiBroadcastExample

Example for XBeeAPI; a little more involved than XBeeApiSimpleBroadcastExample with report on failure to set up the XBee and on the transmit status of the message.

Import programXBeeApiBroadcastExampleRTOS

Example of using the XBeeApi library to broadcast a message, based on XBeeApiBroadcastExample. This example shows how to use the library when using mbed-rtos. Before compiling you must open "XbeeApi\Config\XBeeApiCfg.hpp" and change the '#if 0' to '#if 1' on the line above the comment reading "Use RTOS features to make XBeeApi threadsafe"

Settings/Status

Import programXBeeApiSimpleATCmdsExample

Simple example of using XBeeApi to send AT-style commands to the XBee

Import programXBeeApiRemoteATCmdsExample

Example of using the XBeeApi library to send AT commands to remote XBee devices in order to read/write settings

Receive

Import programXBeeApiSimpleReceiveExample

Simple example of using XBeeApi to receive data packets via wireless

Import programXBeeApiReceiveCallbackExample

Example of using the XBeeApi library to receive a message via a callback method

Import programXBeeApiReceiveCallbackExampleRTOS

Example of using the XBeeApi library to receive a message via a callback method. This example shows how to use the library when using mbed-rtos. See the comment at the top of main.cpp

Remote I/O

Import programXBeeApiRemoteIOExample

Example of using the XBeeApi library to read inputs on a remote XBee

If you have 2 mbed connected XBees available then you can use XBeeApiSimpleReceiveExample and XBeeApiSimpleBroadcastExample as a pair.

Note that this is still a work in progress! XBeeApiTodoList tracks some of the functionality still to be added.

Committer:
johnb
Date:
Mon Jan 27 21:08:06 2014 +0000
Revision:
3:c3d96b94041a
Documentation & misc changes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
johnb 3:c3d96b94041a 1 /**
johnb 3:c3d96b94041a 2
johnb 3:c3d96b94041a 3 Copyright 2014 John Bailey
johnb 3:c3d96b94041a 4
johnb 3:c3d96b94041a 5 Licensed under the Apache License, Version 2.0 (the "License");
johnb 3:c3d96b94041a 6 you may not use this file except in compliance with the License.
johnb 3:c3d96b94041a 7 You may obtain a copy of the License at
johnb 3:c3d96b94041a 8
johnb 3:c3d96b94041a 9 http://www.apache.org/licenses/LICENSE-2.0
johnb 3:c3d96b94041a 10
johnb 3:c3d96b94041a 11 Unless required by applicable law or agreed to in writing, software
johnb 3:c3d96b94041a 12 distributed under the License is distributed on an "AS IS" BASIS,
johnb 3:c3d96b94041a 13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
johnb 3:c3d96b94041a 14 See the License for the specific language governing permissions and
johnb 3:c3d96b94041a 15 limitations under the License.
johnb 3:c3d96b94041a 16
johnb 3:c3d96b94041a 17 */
johnb 3:c3d96b94041a 18
johnb 3:c3d96b94041a 19 #include "XBeeDevice.hpp"
johnb 3:c3d96b94041a 20
johnb 3:c3d96b94041a 21 /** Enum of bytes with a special meaning when communicating with the XBee in API
johnb 3:c3d96b94041a 22 mode. In escaped mode, these are the bytes that need to be escaped */
johnb 3:c3d96b94041a 23 typedef enum
johnb 3:c3d96b94041a 24 {
johnb 3:c3d96b94041a 25 XBEE_SB_XON = 0x11,
johnb 3:c3d96b94041a 26 XBEE_SB_XOFF = 0x13,
johnb 3:c3d96b94041a 27 XBEE_SB_FRAME_DELIMITER = 0x7E,
johnb 3:c3d96b94041a 28 XBEE_SB_ESCAPE = 0x7D
johnb 3:c3d96b94041a 29 } XBeeSerialSpecialBytes_e;
johnb 3:c3d96b94041a 30
johnb 3:c3d96b94041a 31 XBeeDevice::XBeeDevice( PinName p_tx, PinName p_rx, PinName p_rts, PinName p_cts ): m_if( p_tx, p_rx )
johnb 3:c3d96b94041a 32 {
johnb 3:c3d96b94041a 33 m_escape = true;
johnb 3:c3d96b94041a 34 m_inAtCmdMode = false;
johnb 3:c3d96b94041a 35 m_rxMsgLastWasEsc = false;
johnb 3:c3d96b94041a 36
johnb 3:c3d96b94041a 37 /* Can only do flow control on devices which support it */
johnb 3:c3d96b94041a 38 #if defined ( DEVICE_SERIAL_FC )
johnb 3:c3d96b94041a 39 /* TODO: need rts and cts both set? */
johnb 3:c3d96b94041a 40 m_if.set_flow_control( mbed::SerialBase::Flow.RTSCTS, p_rts, p_cts );
johnb 3:c3d96b94041a 41 #endif
johnb 3:c3d96b94041a 42
johnb 3:c3d96b94041a 43 /* Attach RX call-back to the serial interface */
johnb 3:c3d96b94041a 44 m_if.attach( this, &XBeeDevice::if_rx, Serial::RxIrq);
johnb 3:c3d96b94041a 45 }
johnb 3:c3d96b94041a 46
johnb 3:c3d96b94041a 47 XBeeDevice::~XBeeDevice( void )
johnb 3:c3d96b94041a 48 {
johnb 3:c3d96b94041a 49
johnb 3:c3d96b94041a 50 /* Iterate all of the decoders and un-register them */
johnb 3:c3d96b94041a 51 for( FixedLengthList<XBeeApiFrameDecoder*, XBEEAPI_CONFIG_DECODER_LIST_SIZE>::iterator it = m_decoders.begin() ;
johnb 3:c3d96b94041a 52 it != m_decoders.end();
johnb 3:c3d96b94041a 53 it++ ) {
johnb 3:c3d96b94041a 54 (*it)->unregisterCallback();
johnb 3:c3d96b94041a 55 }
johnb 3:c3d96b94041a 56 }
johnb 3:c3d96b94041a 57
johnb 3:c3d96b94041a 58 void XBeeDevice::if_rx( void )
johnb 3:c3d96b94041a 59 {
johnb 3:c3d96b94041a 60 /* Keep going while there are bytes to be read */
johnb 3:c3d96b94041a 61 while(m_if.readable()) {
johnb 3:c3d96b94041a 62
johnb 3:c3d96b94041a 63 uint8_t c = m_if.getc();
johnb 3:c3d96b94041a 64
johnb 3:c3d96b94041a 65 /* Sanity check that if we're starting from an empty buffer the byte that we're
johnb 3:c3d96b94041a 66 receiving is a frame delimiter */
johnb 3:c3d96b94041a 67 if(( m_inAtCmdMode ) ||
johnb 3:c3d96b94041a 68 (( c == XBEE_SB_FRAME_DELIMITER ) ||
johnb 3:c3d96b94041a 69 ( m_rxBuff.getSize() )))
johnb 3:c3d96b94041a 70 {
johnb 3:c3d96b94041a 71 /* If it's an escape character we want to de-code the escape, so flag
johnb 3:c3d96b94041a 72 that we have a pending escape but don't modify the rx buffer */
johnb 3:c3d96b94041a 73 if( m_escape &&
johnb 3:c3d96b94041a 74 ( c == XBEE_SB_ESCAPE ))
johnb 3:c3d96b94041a 75 {
johnb 3:c3d96b94041a 76 m_rxMsgLastWasEsc = true;
johnb 3:c3d96b94041a 77 }
johnb 3:c3d96b94041a 78 else
johnb 3:c3d96b94041a 79 {
johnb 3:c3d96b94041a 80 if( m_rxMsgLastWasEsc ) {
johnb 3:c3d96b94041a 81 c = c ^ 0x20;
johnb 3:c3d96b94041a 82 m_rxMsgLastWasEsc = false;
johnb 3:c3d96b94041a 83 }
johnb 3:c3d96b94041a 84 m_rxBuff.write( &c, 1 );
johnb 3:c3d96b94041a 85 }
johnb 3:c3d96b94041a 86 } else {
johnb 3:c3d96b94041a 87 /* TODO */
johnb 3:c3d96b94041a 88 }
johnb 3:c3d96b94041a 89 }
johnb 3:c3d96b94041a 90
johnb 3:c3d96b94041a 91 if( m_inAtCmdMode )
johnb 3:c3d96b94041a 92 {
johnb 3:c3d96b94041a 93 m_rxMsgLastWasEsc = false;
johnb 3:c3d96b94041a 94 }
johnb 3:c3d96b94041a 95
johnb 3:c3d96b94041a 96 checkRxDecode();
johnb 3:c3d96b94041a 97 }
johnb 3:c3d96b94041a 98
johnb 3:c3d96b94041a 99 #define INITIAL_PEEK_LEN (3U)
johnb 3:c3d96b94041a 100
johnb 3:c3d96b94041a 101 void XBeeDevice::checkRxDecode( void )
johnb 3:c3d96b94041a 102 {
johnb 3:c3d96b94041a 103 /* Get an initial portion of data from the read buffer so that the message length can be determined */
johnb 3:c3d96b94041a 104 uint8_t buff[INITIAL_PEEK_LEN];
johnb 3:c3d96b94041a 105 uint16_t len = m_rxBuff.peek( buff, INITIAL_PEEK_LEN );
johnb 3:c3d96b94041a 106
johnb 3:c3d96b94041a 107 if((len >= INITIAL_PEEK_LEN ) &&
johnb 3:c3d96b94041a 108 (buff[ XBEE_CMD_POSN_HEADER ] == XBEE_SB_FRAME_DELIMITER ))
johnb 3:c3d96b94041a 109 {
johnb 3:c3d96b94041a 110 /* Try and get enough data to cover the whole message */
johnb 3:c3d96b94041a 111 /* TODO: Magic number */
johnb 3:c3d96b94041a 112 const uint16_t cmdLen = MSG_LEN_IN_BUFFER( buff ) + 4;
johnb 3:c3d96b94041a 113 uint8_t cmdBuff[cmdLen];
johnb 3:c3d96b94041a 114 uint16_t len = m_rxBuff.peek( cmdBuff, cmdLen );
johnb 3:c3d96b94041a 115
johnb 3:c3d96b94041a 116 if( len >= cmdLen )
johnb 3:c3d96b94041a 117 {
johnb 3:c3d96b94041a 118 /* TODO: Verify checksum */
johnb 3:c3d96b94041a 119
johnb 3:c3d96b94041a 120 /* Iterate all of the decoders */
johnb 3:c3d96b94041a 121 for( FixedLengthList<XBeeApiFrameDecoder*, XBEEAPI_CONFIG_DECODER_LIST_SIZE>::iterator it = m_decoders.begin() ;
johnb 3:c3d96b94041a 122 it != m_decoders.end();
johnb 3:c3d96b94041a 123 it++ ) {
johnb 3:c3d96b94041a 124
johnb 3:c3d96b94041a 125 /* Does the decoder handle the API ID in the message */
johnb 3:c3d96b94041a 126 if( (*it)->getCmdType() == cmdBuff[ XBEE_CMD_POSN_API_ID ] )
johnb 3:c3d96b94041a 127 {
johnb 3:c3d96b94041a 128 bool processed = (*it)->decodeCallback( cmdBuff, cmdLen );
johnb 3:c3d96b94041a 129 if( processed )
johnb 3:c3d96b94041a 130 {
johnb 3:c3d96b94041a 131 break;
johnb 3:c3d96b94041a 132 }
johnb 3:c3d96b94041a 133 break;
johnb 3:c3d96b94041a 134 }
johnb 3:c3d96b94041a 135 }
johnb 3:c3d96b94041a 136 /* Remove the data from the receive buffer - either it was decoded (all well and good)
johnb 3:c3d96b94041a 137 or it wasn't, in which case we need to get rid of it to prevent it from jamming
johnb 3:c3d96b94041a 138 up the message queue */
johnb 3:c3d96b94041a 139 m_rxBuff.chomp( cmdLen );
johnb 3:c3d96b94041a 140 }
johnb 3:c3d96b94041a 141 }
johnb 3:c3d96b94041a 142 }
johnb 3:c3d96b94041a 143
johnb 3:c3d96b94041a 144 bool XBeeDevice::registerDecoder( XBeeApiFrameDecoder* const p_decoder )
johnb 3:c3d96b94041a 145 {
johnb 3:c3d96b94041a 146 bool ret_val = false;
johnb 3:c3d96b94041a 147 if( p_decoder != NULL )
johnb 3:c3d96b94041a 148 {
johnb 3:c3d96b94041a 149 if( !m_decoders.inList( p_decoder ) ) {
johnb 3:c3d96b94041a 150 m_decoders.push( p_decoder );
johnb 3:c3d96b94041a 151 p_decoder->registerCallback( this );
johnb 3:c3d96b94041a 152 ret_val = true;
johnb 3:c3d96b94041a 153 }
johnb 3:c3d96b94041a 154 }
johnb 3:c3d96b94041a 155 return ret_val;
johnb 3:c3d96b94041a 156 }
johnb 3:c3d96b94041a 157
johnb 3:c3d96b94041a 158 bool XBeeDevice::unregisterDecoder( XBeeApiFrameDecoder* const p_decoder )
johnb 3:c3d96b94041a 159 {
johnb 3:c3d96b94041a 160 bool ret_val = false;
johnb 3:c3d96b94041a 161 if( p_decoder != NULL )
johnb 3:c3d96b94041a 162 {
johnb 3:c3d96b94041a 163 /* Iterate all of the decoders */
johnb 3:c3d96b94041a 164 for( FixedLengthList<XBeeApiFrameDecoder*, XBEEAPI_CONFIG_DECODER_LIST_SIZE>::iterator it = m_decoders.begin() ;
johnb 3:c3d96b94041a 165 it != m_decoders.end();
johnb 3:c3d96b94041a 166 it++ ) {
johnb 3:c3d96b94041a 167 if( *it == p_decoder ) {
johnb 3:c3d96b94041a 168 p_decoder->unregisterCallback();
johnb 3:c3d96b94041a 169 /* TODO: Actually remove the item from m_decoders! */
johnb 3:c3d96b94041a 170 ret_val = true;
johnb 3:c3d96b94041a 171 }
johnb 3:c3d96b94041a 172 }
johnb 3:c3d96b94041a 173 }
johnb 3:c3d96b94041a 174 return ret_val;
johnb 3:c3d96b94041a 175 }
johnb 3:c3d96b94041a 176
johnb 3:c3d96b94041a 177 void XBeeDevice::SendFrame( const XBeeApiFrame* const p_cmd )
johnb 3:c3d96b94041a 178 {
johnb 3:c3d96b94041a 179 uint8_t sum = 0U;
johnb 3:c3d96b94041a 180 uint16_t len;
johnb 3:c3d96b94041a 181 uint16_t i;
johnb 3:c3d96b94041a 182 const uint8_t* cmdData;
johnb 3:c3d96b94041a 183
johnb 3:c3d96b94041a 184 #if defined XBEEAPI_CONFIG_USING_RTOS
johnb 3:c3d96b94041a 185 m_ifMutex.lock();
johnb 3:c3d96b94041a 186 #endif
johnb 3:c3d96b94041a 187
johnb 3:c3d96b94041a 188 xbeeWrite( XBEE_SB_FRAME_DELIMITER, false );
johnb 3:c3d96b94041a 189
johnb 3:c3d96b94041a 190 len = p_cmd->getCmdLen();
johnb 3:c3d96b94041a 191 xbeeWrite((uint8_t)(len >> 8U));
johnb 3:c3d96b94041a 192 xbeeWrite((uint8_t)(len & 0xFF));
johnb 3:c3d96b94041a 193
johnb 3:c3d96b94041a 194 sum += xbeeWrite((uint8_t)p_cmd->getCmdId());
johnb 3:c3d96b94041a 195
johnb 3:c3d96b94041a 196 cmdData = p_cmd->getDataPtr();
johnb 3:c3d96b94041a 197
johnb 3:c3d96b94041a 198 for( i = 0;
johnb 3:c3d96b94041a 199 i < (len-1);
johnb 3:c3d96b94041a 200 i++ )
johnb 3:c3d96b94041a 201 {
johnb 3:c3d96b94041a 202 sum += xbeeWrite(cmdData[i]);
johnb 3:c3d96b94041a 203 }
johnb 3:c3d96b94041a 204
johnb 3:c3d96b94041a 205 /* Checksum is 0xFF - summation of bytes (excluding delimiter and length) */
johnb 3:c3d96b94041a 206 xbeeWrite( (uint8_t)0xFFU - sum );
johnb 3:c3d96b94041a 207
johnb 3:c3d96b94041a 208 fflush( m_if );
johnb 3:c3d96b94041a 209
johnb 3:c3d96b94041a 210 #if defined XBEEAPI_CONFIG_USING_RTOS
johnb 3:c3d96b94041a 211 m_ifMutex.unlock();
johnb 3:c3d96b94041a 212 #endif
johnb 3:c3d96b94041a 213 }
johnb 3:c3d96b94041a 214
johnb 3:c3d96b94041a 215 uint8_t XBeeDevice::xbeeWrite( uint8_t p_byte, bool p_doEscape )
johnb 3:c3d96b94041a 216 {
johnb 3:c3d96b94041a 217 uint8_t c_sum = 0;
johnb 3:c3d96b94041a 218
johnb 3:c3d96b94041a 219 if (p_doEscape && m_escape &&
johnb 3:c3d96b94041a 220 ((p_byte == XBEE_SB_FRAME_DELIMITER ) ||
johnb 3:c3d96b94041a 221 (p_byte == XBEE_SB_ESCAPE ) ||
johnb 3:c3d96b94041a 222 (p_byte == XBEE_SB_XON ) ||
johnb 3:c3d96b94041a 223 (p_byte == XBEE_SB_XOFF)))
johnb 3:c3d96b94041a 224 {
johnb 3:c3d96b94041a 225 #if 0
johnb 3:c3d96b94041a 226 m_if.printf("%02x ",XBEE_SB_ESCAPE);
johnb 3:c3d96b94041a 227 m_if.printf("%02x ",p_byte ^ 0x20);
johnb 3:c3d96b94041a 228 #else
johnb 3:c3d96b94041a 229 m_if.putc(XBEE_SB_ESCAPE);
johnb 3:c3d96b94041a 230 m_if.putc(p_byte ^ 0x20);
johnb 3:c3d96b94041a 231 #endif
johnb 3:c3d96b94041a 232 c_sum += XBEE_SB_ESCAPE;
johnb 3:c3d96b94041a 233 c_sum += p_byte ^ 0x20;
johnb 3:c3d96b94041a 234 } else {
johnb 3:c3d96b94041a 235 #if 0
johnb 3:c3d96b94041a 236 m_if.printf("%02x ",p_byte);
johnb 3:c3d96b94041a 237 #else
johnb 3:c3d96b94041a 238 m_if.putc(p_byte);
johnb 3:c3d96b94041a 239 #endif
johnb 3:c3d96b94041a 240 c_sum += p_byte;
johnb 3:c3d96b94041a 241 }
johnb 3:c3d96b94041a 242 return c_sum;
johnb 3:c3d96b94041a 243 }
johnb 3:c3d96b94041a 244
johnb 3:c3d96b94041a 245 #define IS_OK( _b ) (( _b[ 0 ] == 'O' ) && ( _b[ 1 ] == 'K' ) && ( _b[ 2 ] == '\r' ))
johnb 3:c3d96b94041a 246 #define OK_LEN (3U)
johnb 3:c3d96b94041a 247
johnb 3:c3d96b94041a 248 XBeeDevice::XBeeDeviceReturn_t XBeeDevice::SendFrame( const char* const p_dat, size_t p_len, int p_wait_ms )
johnb 3:c3d96b94041a 249 {
johnb 3:c3d96b94041a 250 XBeeDeviceReturn_t ret_val;
johnb 3:c3d96b94041a 251
johnb 3:c3d96b94041a 252 if( m_inAtCmdMode )
johnb 3:c3d96b94041a 253 {
johnb 3:c3d96b94041a 254 #if defined XBEEAPI_CONFIG_USING_RTOS
johnb 3:c3d96b94041a 255 m_ifMutex.lock();
johnb 3:c3d96b94041a 256 #endif
johnb 3:c3d96b94041a 257 for( size_t i = 0;
johnb 3:c3d96b94041a 258 i < p_len;
johnb 3:c3d96b94041a 259 i++ ) {
johnb 3:c3d96b94041a 260 m_if.putc(p_dat[i]);
johnb 3:c3d96b94041a 261 }
johnb 3:c3d96b94041a 262
johnb 3:c3d96b94041a 263 fflush( m_if );
johnb 3:c3d96b94041a 264
johnb 3:c3d96b94041a 265 wait_ms( p_wait_ms );
johnb 3:c3d96b94041a 266
johnb 3:c3d96b94041a 267 /* Check the response for the OK indicator */
johnb 3:c3d96b94041a 268 if( m_rxBuff.getSize() == OK_LEN )
johnb 3:c3d96b94041a 269 {
johnb 3:c3d96b94041a 270 uint8_t ok_buff[OK_LEN];
johnb 3:c3d96b94041a 271 m_rxBuff.read( ok_buff, OK_LEN );
johnb 3:c3d96b94041a 272
johnb 3:c3d96b94041a 273 if( IS_OK( ok_buff ))
johnb 3:c3d96b94041a 274 {
johnb 3:c3d96b94041a 275 ret_val = XBEEDEVICE_OK;
johnb 3:c3d96b94041a 276 }
johnb 3:c3d96b94041a 277 else
johnb 3:c3d96b94041a 278 {
johnb 3:c3d96b94041a 279 ret_val = XBEEDEVICE_UNEXPECTED_DATA;
johnb 3:c3d96b94041a 280 }
johnb 3:c3d96b94041a 281 }
johnb 3:c3d96b94041a 282 else
johnb 3:c3d96b94041a 283 {
johnb 3:c3d96b94041a 284 ret_val = XBEEDEVICE_UNEXPECTED_LENGTH;
johnb 3:c3d96b94041a 285 }
johnb 3:c3d96b94041a 286 #if defined XBEEAPI_CONFIG_USING_RTOS
johnb 3:c3d96b94041a 287 m_ifMutex.unlock();
johnb 3:c3d96b94041a 288 #endif
johnb 3:c3d96b94041a 289 }
johnb 3:c3d96b94041a 290 else
johnb 3:c3d96b94041a 291 {
johnb 3:c3d96b94041a 292 ret_val = XBEEDEVICE_WRONG_MODE;
johnb 3:c3d96b94041a 293 }
johnb 3:c3d96b94041a 294 return ret_val;
johnb 3:c3d96b94041a 295 }
johnb 3:c3d96b94041a 296
johnb 3:c3d96b94041a 297 XBeeDevice::XBeeDeviceReturn_t XBeeDevice::setUpApi( void )
johnb 3:c3d96b94041a 298 {
johnb 3:c3d96b94041a 299 XBeeDeviceReturn_t ret_val;
johnb 3:c3d96b94041a 300
johnb 3:c3d96b94041a 301 /* TODO: 10ms should be changed to be the guard period */
johnb 3:c3d96b94041a 302 wait_ms( 10 );
johnb 3:c3d96b94041a 303
johnb 3:c3d96b94041a 304 m_inAtCmdMode = true;
johnb 3:c3d96b94041a 305
johnb 3:c3d96b94041a 306 /* Request to enter command mode */
johnb 3:c3d96b94041a 307 /* TODO: Magic number */
johnb 3:c3d96b94041a 308 ret_val = SendFrame("+++", 3, 5000);
johnb 3:c3d96b94041a 309
johnb 3:c3d96b94041a 310 /* Everything OK with last request? */
johnb 3:c3d96b94041a 311 if( ret_val == XBEEDEVICE_OK )
johnb 3:c3d96b94041a 312 {
johnb 3:c3d96b94041a 313 /* API mode 2 please! */
johnb 3:c3d96b94041a 314 ret_val = SendFrame("ATAP 2\r",7);
johnb 3:c3d96b94041a 315 }
johnb 3:c3d96b94041a 316
johnb 3:c3d96b94041a 317 /* Everything OK with last request? */
johnb 3:c3d96b94041a 318 if( ret_val == XBEEDEVICE_OK )
johnb 3:c3d96b94041a 319 {
johnb 3:c3d96b94041a 320 /* Exit command mode, back to API mode */
johnb 3:c3d96b94041a 321 /* TODO: Magic number */
johnb 3:c3d96b94041a 322 ret_val = SendFrame("ATCN\r",5);
johnb 3:c3d96b94041a 323 }
johnb 3:c3d96b94041a 324
johnb 3:c3d96b94041a 325 m_inAtCmdMode = false;
johnb 3:c3d96b94041a 326
johnb 3:c3d96b94041a 327 return ret_val;
johnb 3:c3d96b94041a 328 }
johnb 3:c3d96b94041a 329
johnb 3:c3d96b94041a 330 #if defined XBEEAPI_CONFIG_ENABLE_DEVELOPER
johnb 3:c3d96b94041a 331
johnb 3:c3d96b94041a 332 void XBeeDevice::dumpRxBuffer( Stream* p_buf, const bool p_hexView )
johnb 3:c3d96b94041a 333 {
johnb 3:c3d96b94041a 334 uint8_t c;
johnb 3:c3d96b94041a 335 while( m_rxBuff.getSize() ) {
johnb 3:c3d96b94041a 336 if( m_rxBuff.read( &c, 1 ) ) {
johnb 3:c3d96b94041a 337 if( p_hexView ) {
johnb 3:c3d96b94041a 338 uint8_t a = '-';
johnb 3:c3d96b94041a 339 if(( c>=32 ) && (c<=126)) {
johnb 3:c3d96b94041a 340 a = c;
johnb 3:c3d96b94041a 341 }
johnb 3:c3d96b94041a 342 p_buf->printf("0x%02x (%c) ",c,a);
johnb 3:c3d96b94041a 343 } else {
johnb 3:c3d96b94041a 344 p_buf->printf("%c",c);
johnb 3:c3d96b94041a 345 if( c == '\r' ) {
johnb 3:c3d96b94041a 346 p_buf->printf("\n");
johnb 3:c3d96b94041a 347 }
johnb 3:c3d96b94041a 348 }
johnb 3:c3d96b94041a 349 }
johnb 3:c3d96b94041a 350 }
johnb 3:c3d96b94041a 351 }
johnb 3:c3d96b94041a 352
johnb 3:c3d96b94041a 353 #endif