John Bailey / XBeeApi

Dependencies:   CircularBuffer FixedLengthList

Dependents:   XBeeApiTest XBeeApiSimpleATCmdsExample XBeeApiBroadcastExample XBeeApiBroadcastExampleRTOS ... more

Committer:
johnb
Date:
Tue Mar 25 18:38:42 2014 +0000
Revision:
33:eccf4725930c
Parent:
29:c6d037cceb02
Child:
40:b96e8cad93d3
New constructor to allow Serial object to be passed rather than instantiated by the XBeeDevice

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