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:
Wed Jan 29 20:19:59 2014 +0000
Revision:
5:b40a6fd3a334
Child:
6:3cb62daace78
Documentation update

Who changed what in which revision?

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