John Bailey / XBeeApi

Dependencies:   CircularBuffer FixedLengthList

Dependents:   XBeeApiTest XBeeApiSimpleATCmdsExample XBeeApiBroadcastExample XBeeApiBroadcastExampleRTOS ... more

Committer:
johnb
Date:
Tue Feb 04 23:52:50 2014 +0000
Revision:
16:8095c43a2a6e
Parent:
10:0d084d0253a7
Child:
29:c6d037cceb02
Flesh out XBeeApiTXFrame and add XBeeApiTxFrameEx

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