John Bailey / XBeeApi

Dependencies:   CircularBuffer FixedLengthList

Dependents:   XBeeApiTest XBeeApiSimpleATCmdsExample XBeeApiBroadcastExample XBeeApiBroadcastExampleRTOS ... more

Committer:
johnb
Date:
Thu Feb 06 21:25:17 2014 +0000
Revision:
29:c6d037cceb02
Parent:
16:8095c43a2a6e
Child:
33:eccf4725930c
Infrastructure for supporting different XBee models; Change XBeeApiCmdAt constructor to allown an XBeeDevice to be passed

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