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 Feb 03 23:37:29 2014 +0000
Revision:
14:edec6cd78ffb
Parent:
13:302e7c1ea0b3
Child:
24:2cd1094c4fd7
Fix problems with blocking API

Who changed what in which revision?

UserRevisionLine numberNew contents of line
johnb 8:1b48b619d7f6 1 /**
johnb 8:1b48b619d7f6 2
johnb 8:1b48b619d7f6 3 Copyright 2014 John Bailey
johnb 13:302e7c1ea0b3 4
johnb 8:1b48b619d7f6 5 Licensed under the Apache License, Version 2.0 (the "License");
johnb 8:1b48b619d7f6 6 you may not use this file except in compliance with the License.
johnb 8:1b48b619d7f6 7 You may obtain a copy of the License at
johnb 8:1b48b619d7f6 8
johnb 8:1b48b619d7f6 9 http://www.apache.org/licenses/LICENSE-2.0
johnb 8:1b48b619d7f6 10
johnb 8:1b48b619d7f6 11 Unless required by applicable law or agreed to in writing, software
johnb 8:1b48b619d7f6 12 distributed under the License is distributed on an "AS IS" BASIS,
johnb 8:1b48b619d7f6 13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
johnb 8:1b48b619d7f6 14 See the License for the specific language governing permissions and
johnb 8:1b48b619d7f6 15 limitations under the License.
johnb 8:1b48b619d7f6 16
johnb 8:1b48b619d7f6 17 */
johnb 8:1b48b619d7f6 18
johnb 8:1b48b619d7f6 19 #include "XBeeApiCmdAt.hpp"
johnb 8:1b48b619d7f6 20
johnb 8:1b48b619d7f6 21 /* Set of Frame ID codes for the various commands (see XBEE_CMD_POSN_FRAME_ID) */
johnb 8:1b48b619d7f6 22
johnb 13:302e7c1ea0b3 23 #define CMD_RESPONSE_GET_VR '1'
johnb 13:302e7c1ea0b3 24 #define CMD_RESPONSE_GET_HV '2'
johnb 13:302e7c1ea0b3 25 #define CMD_RESPONSE_GET_CH '3'
johnb 13:302e7c1ea0b3 26 #define CMD_RESPONSE_SET_CH '4'
johnb 13:302e7c1ea0b3 27 #define CMD_RESPONSE_SET_CE '5'
johnb 13:302e7c1ea0b3 28 #define CMD_RESPONSE_GET_CE '6'
johnb 13:302e7c1ea0b3 29 #define CMD_RESPONSE_SET_EDA '7'
johnb 13:302e7c1ea0b3 30 #define CMD_RESPONSE_GET_EDA '8'
johnb 13:302e7c1ea0b3 31 #define CMD_RESPONSE_SET_PID '9'
johnb 13:302e7c1ea0b3 32 #define CMD_RESPONSE_GET_PID '0'
johnb 13:302e7c1ea0b3 33
johnb 13:302e7c1ea0b3 34 extern Serial pc;
johnb 13:302e7c1ea0b3 35
johnb 8:1b48b619d7f6 36
johnb 8:1b48b619d7f6 37 /* Content for the various commands - value of 0 indicates a value to be populated (i.e. variable) */
johnb 8:1b48b619d7f6 38
johnb 13:302e7c1ea0b3 39 const uint8_t cmd_vr[] = { CMD_RESPONSE_GET_VR, 'V', 'R' };
johnb 13:302e7c1ea0b3 40 const uint8_t cmd_hv[] = { CMD_RESPONSE_GET_HV, 'H', 'V' };
johnb 13:302e7c1ea0b3 41
johnb 13:302e7c1ea0b3 42 const uint8_t cmd_ch[] = { CMD_RESPONSE_GET_CH, 'C', 'H' };
johnb 13:302e7c1ea0b3 43 const uint8_t cmd_set_ch[] = { CMD_RESPONSE_SET_CH, 'C', 'H', 0 };
johnb 13:302e7c1ea0b3 44
johnb 13:302e7c1ea0b3 45 const uint8_t cmd_ce[] = { CMD_RESPONSE_GET_CE, 'C', 'E' };
johnb 13:302e7c1ea0b3 46 const uint8_t cmd_set_ce[] = { CMD_RESPONSE_SET_CE, 'C', 'E', 0 };
johnb 13:302e7c1ea0b3 47
johnb 13:302e7c1ea0b3 48 const uint8_t cmd_eda[] = { CMD_RESPONSE_GET_EDA, 'A', '1' };
johnb 13:302e7c1ea0b3 49 const uint8_t cmd_set_eda[] = { CMD_RESPONSE_SET_EDA, 'A', '1', 0 };
johnb 13:302e7c1ea0b3 50
johnb 13:302e7c1ea0b3 51 const uint8_t cmd_pid[] = { CMD_RESPONSE_GET_PID, 'I', 'D' };
johnb 13:302e7c1ea0b3 52 const uint8_t cmd_set_pid[] = { CMD_RESPONSE_SET_PID, 'I', 'D', 0, 0 };
johnb 8:1b48b619d7f6 53
johnb 8:1b48b619d7f6 54 #define XBEE_CMD_POSN_FRAME_ID (4U)
johnb 13:302e7c1ea0b3 55 #define XBEE_CMD_POSN_STATUS (7U)
johnb 8:1b48b619d7f6 56 #define XBEE_CMD_POSN_PARAM_START (8U)
johnb 8:1b48b619d7f6 57
johnb 13:302e7c1ea0b3 58 #define XBEE_CMD_RESPONS_HAS_DATA( _p_len ) ((_p_len > ( XBEE_CMD_POSN_PARAM_START + 1 ))
johnb 13:302e7c1ea0b3 59
johnb 8:1b48b619d7f6 60 XBeeApiCmdAt::XBeeApiCmdAt() : XBeeApiFrameDecoder( ) , m_haveHwVer( false ),
johnb 13:302e7c1ea0b3 61 m_haveFwVer( false ),
johnb 13:302e7c1ea0b3 62 m_haveChan( false ),
johnb 13:302e7c1ea0b3 63 m_havePANId( false ),
johnb 13:302e7c1ea0b3 64 m_haveEDA( false ),
johnb 13:302e7c1ea0b3 65 m_haveCE( false )
johnb 8:1b48b619d7f6 66 {
johnb 8:1b48b619d7f6 67 }
johnb 8:1b48b619d7f6 68
johnb 8:1b48b619d7f6 69 bool XBeeApiCmdAt::decodeCallback( const uint8_t* const p_data, size_t p_len )
johnb 8:1b48b619d7f6 70 {
johnb 8:1b48b619d7f6 71 bool ret_val = false;
johnb 13:302e7c1ea0b3 72
johnb 13:302e7c1ea0b3 73 if( XBEE_CMD_AT_RESPONSE == p_data[ XBEE_CMD_POSN_API_ID ] ) {
johnb 13:302e7c1ea0b3 74
johnb 13:302e7c1ea0b3 75 switch( p_data[ XBEE_CMD_POSN_FRAME_ID ] ) {
johnb 8:1b48b619d7f6 76 case CMD_RESPONSE_GET_HV:
johnb 13:302e7c1ea0b3 77 if( p_data[ XBEE_CMD_POSN_STATUS ] == 0 )
johnb 13:302e7c1ea0b3 78 {
johnb 13:302e7c1ea0b3 79 m_hwVer = ((uint16_t)p_data[ XBEE_CMD_POSN_PARAM_START ] << 8) + p_data[ XBEE_CMD_POSN_PARAM_START + 1 ];
johnb 13:302e7c1ea0b3 80 m_haveHwVer = true;
johnb 13:302e7c1ea0b3 81 }
johnb 13:302e7c1ea0b3 82 else
johnb 13:302e7c1ea0b3 83 {
johnb 13:302e7c1ea0b3 84 pc.printf("\r\nERROR1\r\n");
johnb 13:302e7c1ea0b3 85 }
johnb 13:302e7c1ea0b3 86 ret_val = true;
johnb 13:302e7c1ea0b3 87 break;
johnb 13:302e7c1ea0b3 88
johnb 13:302e7c1ea0b3 89 case CMD_RESPONSE_GET_VR:
johnb 13:302e7c1ea0b3 90 if( p_data[ XBEE_CMD_POSN_STATUS ] == 0 )
johnb 13:302e7c1ea0b3 91 {
johnb 13:302e7c1ea0b3 92 m_fwVer = ((uint16_t)p_data[ XBEE_CMD_POSN_PARAM_START ] << 8) + p_data[ XBEE_CMD_POSN_PARAM_START + 1 ];
johnb 13:302e7c1ea0b3 93 m_haveFwVer = true;
johnb 13:302e7c1ea0b3 94 }
johnb 13:302e7c1ea0b3 95 else
johnb 13:302e7c1ea0b3 96 {
johnb 13:302e7c1ea0b3 97 pc.printf("\r\nERROR2\r\n");
johnb 13:302e7c1ea0b3 98 }
johnb 13:302e7c1ea0b3 99 ret_val = true;
johnb 13:302e7c1ea0b3 100 break;
johnb 13:302e7c1ea0b3 101
johnb 13:302e7c1ea0b3 102 case CMD_RESPONSE_GET_CH:
johnb 13:302e7c1ea0b3 103 case CMD_RESPONSE_SET_CH:
johnb 13:302e7c1ea0b3 104 if( p_data[ XBEE_CMD_POSN_STATUS ] == 0 )
johnb 13:302e7c1ea0b3 105 {
johnb 13:302e7c1ea0b3 106 if( CMD_RESPONSE_GET_CH == p_data[ XBEE_CMD_POSN_API_ID ] )
johnb 13:302e7c1ea0b3 107 {
johnb 13:302e7c1ea0b3 108 m_chan = p_data[ XBEE_CMD_POSN_PARAM_START ];
johnb 13:302e7c1ea0b3 109 }
johnb 13:302e7c1ea0b3 110 else
johnb 13:302e7c1ea0b3 111 {
johnb 13:302e7c1ea0b3 112 m_chan = m_chanPend;
johnb 13:302e7c1ea0b3 113 }
johnb 13:302e7c1ea0b3 114 #if 0
johnb 13:302e7c1ea0b3 115 printf("\r\n%02x (%2d) - %02x %02x %02x %02x %02x %02x %02x %02x %02x\r\n",p_data[ XBEE_CMD_POSN_API_ID ],p_len,
johnb 13:302e7c1ea0b3 116 p_data[0],p_data[1],p_data[2],p_data[3],p_data[4],p_data[5],p_data[6],p_data[7],p_data[8]);
johnb 13:302e7c1ea0b3 117 #endif
johnb 13:302e7c1ea0b3 118 m_haveChan = true;
johnb 13:302e7c1ea0b3 119 }
johnb 13:302e7c1ea0b3 120 else
johnb 13:302e7c1ea0b3 121 {
johnb 13:302e7c1ea0b3 122 /* TODO */
johnb 13:302e7c1ea0b3 123 pc.printf("\r\nERROR3\r\n");
johnb 13:302e7c1ea0b3 124 }
johnb 8:1b48b619d7f6 125 ret_val = true;
johnb 8:1b48b619d7f6 126 break;
johnb 13:302e7c1ea0b3 127
johnb 13:302e7c1ea0b3 128 case CMD_RESPONSE_SET_CE:
johnb 13:302e7c1ea0b3 129 case CMD_RESPONSE_GET_CE:
johnb 13:302e7c1ea0b3 130 if( p_data[ XBEE_CMD_POSN_STATUS ] == 0 )
johnb 13:302e7c1ea0b3 131 {
johnb 13:302e7c1ea0b3 132 if( CMD_RESPONSE_GET_CE == p_data[ XBEE_CMD_POSN_API_ID ] )
johnb 13:302e7c1ea0b3 133 {
johnb 13:302e7c1ea0b3 134 m_CE = p_data[ XBEE_CMD_POSN_PARAM_START ];
johnb 13:302e7c1ea0b3 135 }
johnb 13:302e7c1ea0b3 136 else
johnb 13:302e7c1ea0b3 137 {
johnb 13:302e7c1ea0b3 138 m_CE = m_CEPend;
johnb 13:302e7c1ea0b3 139 }
johnb 13:302e7c1ea0b3 140 m_haveCE = true;
johnb 13:302e7c1ea0b3 141 }
johnb 13:302e7c1ea0b3 142 else
johnb 13:302e7c1ea0b3 143 {
johnb 13:302e7c1ea0b3 144 pc.printf("\r\nERROR3\r\n");
johnb 13:302e7c1ea0b3 145 }
johnb 8:1b48b619d7f6 146 ret_val = true;
johnb 8:1b48b619d7f6 147 break;
johnb 13:302e7c1ea0b3 148
johnb 13:302e7c1ea0b3 149 case CMD_RESPONSE_SET_PID:
johnb 13:302e7c1ea0b3 150 case CMD_RESPONSE_GET_PID:
johnb 13:302e7c1ea0b3 151 if( p_data[ XBEE_CMD_POSN_STATUS ] == 0 )
johnb 13:302e7c1ea0b3 152 {
johnb 13:302e7c1ea0b3 153 if( CMD_RESPONSE_GET_PID == p_data[ XBEE_CMD_POSN_API_ID ] )
johnb 13:302e7c1ea0b3 154 {
johnb 13:302e7c1ea0b3 155 m_PANId = p_data[ XBEE_CMD_POSN_PARAM_START ];
johnb 13:302e7c1ea0b3 156 }
johnb 13:302e7c1ea0b3 157 else
johnb 13:302e7c1ea0b3 158 {
johnb 13:302e7c1ea0b3 159 m_PANId = m_PANIdPend;
johnb 13:302e7c1ea0b3 160 }
johnb 13:302e7c1ea0b3 161 m_havePANId = true;
johnb 13:302e7c1ea0b3 162 }
johnb 13:302e7c1ea0b3 163 else
johnb 13:302e7c1ea0b3 164 {
johnb 13:302e7c1ea0b3 165 pc.printf("\r\nERROR3\r\n");
johnb 13:302e7c1ea0b3 166 }
johnb 8:1b48b619d7f6 167 ret_val = true;
johnb 8:1b48b619d7f6 168 break;
johnb 13:302e7c1ea0b3 169
johnb 13:302e7c1ea0b3 170 case CMD_RESPONSE_SET_EDA:
johnb 13:302e7c1ea0b3 171 case CMD_RESPONSE_GET_EDA:
johnb 13:302e7c1ea0b3 172 if( p_data[ XBEE_CMD_POSN_STATUS ] == 0 )
johnb 13:302e7c1ea0b3 173 {
johnb 13:302e7c1ea0b3 174 if( CMD_RESPONSE_GET_EDA == p_data[ XBEE_CMD_POSN_API_ID ] )
johnb 13:302e7c1ea0b3 175 {
johnb 13:302e7c1ea0b3 176 m_EDA = p_data[ XBEE_CMD_POSN_PARAM_START ];
johnb 13:302e7c1ea0b3 177 }
johnb 13:302e7c1ea0b3 178 else
johnb 13:302e7c1ea0b3 179 {
johnb 13:302e7c1ea0b3 180 m_EDA = m_EDAPend;
johnb 13:302e7c1ea0b3 181 }
johnb 13:302e7c1ea0b3 182 m_haveEDA = true;
johnb 13:302e7c1ea0b3 183 }
johnb 13:302e7c1ea0b3 184 else
johnb 13:302e7c1ea0b3 185 {
johnb 13:302e7c1ea0b3 186 pc.printf("\r\nERROR3\r\n");
johnb 13:302e7c1ea0b3 187 }
johnb 13:302e7c1ea0b3 188 ret_val = true;
johnb 8:1b48b619d7f6 189 break;
johnb 13:302e7c1ea0b3 190
johnb 8:1b48b619d7f6 191 }
johnb 8:1b48b619d7f6 192 }
johnb 8:1b48b619d7f6 193 return ret_val;
johnb 8:1b48b619d7f6 194 }
johnb 8:1b48b619d7f6 195
johnb 8:1b48b619d7f6 196 bool XBeeApiCmdAt::setChannel( uint8_t const p_chan )
johnb 8:1b48b619d7f6 197 {
johnb 8:1b48b619d7f6 198 XBeeApiCmdAt::XBeeApiCmdAtChannelSet req( p_chan );
johnb 8:1b48b619d7f6 199 m_chanPend = p_chan;
johnb 8:1b48b619d7f6 200 m_device->SendFrame( &req );
johnb 8:1b48b619d7f6 201 return true;
johnb 8:1b48b619d7f6 202 }
johnb 8:1b48b619d7f6 203
johnb 8:1b48b619d7f6 204 bool XBeeApiCmdAt::requestHardwareVersion( void )
johnb 8:1b48b619d7f6 205 {
johnb 8:1b48b619d7f6 206 XBeeApiCmdAt::XBeeApiCmdAtHardwareVersionRequest req;
johnb 13:302e7c1ea0b3 207 m_haveHwVer = false;
johnb 8:1b48b619d7f6 208 m_device->SendFrame( &req );
johnb 8:1b48b619d7f6 209 return true;
johnb 8:1b48b619d7f6 210 }
johnb 13:302e7c1ea0b3 211
johnb 8:1b48b619d7f6 212 bool XBeeApiCmdAt::requestFirmwareVersion( void )
johnb 8:1b48b619d7f6 213 {
johnb 8:1b48b619d7f6 214 XBeeApiCmdAt::XBeeApiCmdAtFirmwareVersionRequest req;
johnb 8:1b48b619d7f6 215 m_haveFwVer = false;
johnb 13:302e7c1ea0b3 216 m_device->SendFrame( &req );
johnb 8:1b48b619d7f6 217 return true;
johnb 8:1b48b619d7f6 218 }
johnb 8:1b48b619d7f6 219
johnb 8:1b48b619d7f6 220 bool XBeeApiCmdAt::requestChannel( void )
johnb 8:1b48b619d7f6 221 {
johnb 8:1b48b619d7f6 222 XBeeApiCmdAt::XBeeApiCmdAtChannelRequest req;
johnb 8:1b48b619d7f6 223 m_haveChan = false;
johnb 8:1b48b619d7f6 224 m_device->SendFrame( &req );
johnb 8:1b48b619d7f6 225 return true;
johnb 8:1b48b619d7f6 226 }
johnb 8:1b48b619d7f6 227
johnb 13:302e7c1ea0b3 228 bool XBeeApiCmdAt::requestPanId( void )
johnb 13:302e7c1ea0b3 229 {
johnb 13:302e7c1ea0b3 230 XBeeApiCmdAt::XBeeApiCmdAtPANIdRequest req;
johnb 13:302e7c1ea0b3 231 m_havePANId = false;
johnb 13:302e7c1ea0b3 232 m_device->SendFrame( &req );
johnb 13:302e7c1ea0b3 233 return true;
johnb 13:302e7c1ea0b3 234 }
johnb 13:302e7c1ea0b3 235
johnb 13:302e7c1ea0b3 236 bool XBeeApiCmdAt::requestCoordinatorEnabled( void )
johnb 13:302e7c1ea0b3 237 {
johnb 13:302e7c1ea0b3 238 XBeeApiCmdAt::XBeeApiCmdAtCERequest req;
johnb 13:302e7c1ea0b3 239 m_haveCE = false;
johnb 13:302e7c1ea0b3 240 m_device->SendFrame( &req );
johnb 13:302e7c1ea0b3 241 return true;
johnb 13:302e7c1ea0b3 242 }
johnb 13:302e7c1ea0b3 243
johnb 13:302e7c1ea0b3 244 bool XBeeApiCmdAt::requestEndDeviceAssociationEnabled( void )
johnb 13:302e7c1ea0b3 245 {
johnb 13:302e7c1ea0b3 246 XBeeApiCmdAt::XBeeApiCmdAtEDARequest req;
johnb 13:302e7c1ea0b3 247 m_haveEDA = false;
johnb 13:302e7c1ea0b3 248 m_device->SendFrame( &req );
johnb 13:302e7c1ea0b3 249 return true;
johnb 13:302e7c1ea0b3 250 }
johnb 13:302e7c1ea0b3 251
johnb 8:1b48b619d7f6 252 bool XBeeApiCmdAt::getFirmwareVersion( uint16_t* const p_ver )
johnb 8:1b48b619d7f6 253 {
johnb 13:302e7c1ea0b3 254 if( m_haveFwVer ) {
johnb 8:1b48b619d7f6 255 *p_ver = m_fwVer;
johnb 8:1b48b619d7f6 256 }
johnb 8:1b48b619d7f6 257 return m_haveFwVer;
johnb 13:302e7c1ea0b3 258
johnb 8:1b48b619d7f6 259 }
johnb 8:1b48b619d7f6 260
johnb 8:1b48b619d7f6 261 bool XBeeApiCmdAt::getHardwareVersion( uint16_t* const p_ver )
johnb 8:1b48b619d7f6 262 {
johnb 13:302e7c1ea0b3 263 if( m_haveHwVer ) {
johnb 8:1b48b619d7f6 264 *p_ver = m_hwVer;
johnb 8:1b48b619d7f6 265 }
johnb 8:1b48b619d7f6 266 return m_haveHwVer;
johnb 8:1b48b619d7f6 267 }
johnb 8:1b48b619d7f6 268
johnb 8:1b48b619d7f6 269 bool XBeeApiCmdAt::getChannel( uint8_t* const p_chan )
johnb 8:1b48b619d7f6 270 {
johnb 13:302e7c1ea0b3 271 if( m_haveChan ) {
johnb 8:1b48b619d7f6 272 *p_chan = m_chan;
johnb 8:1b48b619d7f6 273 }
johnb 8:1b48b619d7f6 274 return m_haveChan;
johnb 8:1b48b619d7f6 275 }
johnb 8:1b48b619d7f6 276
johnb 13:302e7c1ea0b3 277 bool XBeeApiCmdAt::getCoordinatorEnabled( bool* const p_en )
johnb 13:302e7c1ea0b3 278 {
johnb 13:302e7c1ea0b3 279 if( m_haveCE ) {
johnb 13:302e7c1ea0b3 280 *p_en = m_CE;
johnb 13:302e7c1ea0b3 281 }
johnb 13:302e7c1ea0b3 282 return m_haveCE;
johnb 13:302e7c1ea0b3 283 }
johnb 13:302e7c1ea0b3 284
johnb 13:302e7c1ea0b3 285 bool XBeeApiCmdAt::setCoordinatorEnabled( const bool p_en )
johnb 13:302e7c1ea0b3 286 {
johnb 13:302e7c1ea0b3 287 XBeeApiCmdAt::XBeeApiCmdAtCESet ce( p_en );
johnb 13:302e7c1ea0b3 288 m_haveCE = false;
johnb 13:302e7c1ea0b3 289 m_CEPend = p_en;
johnb 13:302e7c1ea0b3 290 m_device->SendFrame( &ce );
johnb 13:302e7c1ea0b3 291 return true;
johnb 13:302e7c1ea0b3 292 }
johnb 13:302e7c1ea0b3 293
johnb 13:302e7c1ea0b3 294 bool XBeeApiCmdAt::getEndDeviceAssociationEnabled( bool* const p_en )
johnb 13:302e7c1ea0b3 295 {
johnb 13:302e7c1ea0b3 296 if( m_haveEDA ) {
johnb 13:302e7c1ea0b3 297 *p_en = m_EDA;
johnb 13:302e7c1ea0b3 298 }
johnb 13:302e7c1ea0b3 299 return m_haveEDA;
johnb 13:302e7c1ea0b3 300 }
johnb 13:302e7c1ea0b3 301 bool XBeeApiCmdAt::setEndDeviceAssociationEnabled( const bool p_en )
johnb 13:302e7c1ea0b3 302 {
johnb 13:302e7c1ea0b3 303 XBeeApiCmdAt::XBeeApiCmdAtEDASet req( p_en );
johnb 13:302e7c1ea0b3 304 m_haveEDA = false;
johnb 13:302e7c1ea0b3 305 m_EDAPend = p_en;
johnb 13:302e7c1ea0b3 306 m_device->SendFrame( &req );
johnb 13:302e7c1ea0b3 307 return true;
johnb 13:302e7c1ea0b3 308 }
johnb 13:302e7c1ea0b3 309
johnb 13:302e7c1ea0b3 310 bool XBeeApiCmdAt::getPanId( panId_t* const p_chan )
johnb 13:302e7c1ea0b3 311 {
johnb 13:302e7c1ea0b3 312 if( m_havePANId ) {
johnb 13:302e7c1ea0b3 313 *p_chan = m_PANId;
johnb 13:302e7c1ea0b3 314 }
johnb 13:302e7c1ea0b3 315 return m_havePANId;
johnb 13:302e7c1ea0b3 316
johnb 13:302e7c1ea0b3 317 }
johnb 13:302e7c1ea0b3 318 bool XBeeApiCmdAt::setPanId( const panId_t p_chan )
johnb 13:302e7c1ea0b3 319 {
johnb 13:302e7c1ea0b3 320 XBeeApiCmdAt::XBeeApiCmdAtPANIdSet panid( p_chan );
johnb 13:302e7c1ea0b3 321 m_havePANId = false;
johnb 13:302e7c1ea0b3 322 m_PANIdPend = p_chan;
johnb 13:302e7c1ea0b3 323 m_device->SendFrame( &panid );
johnb 13:302e7c1ea0b3 324 return true;
johnb 13:302e7c1ea0b3 325 }
johnb 13:302e7c1ea0b3 326
johnb 13:302e7c1ea0b3 327
johnb 13:302e7c1ea0b3 328 XBeeApiCmdAtBlocking::XBeeApiCmdAtBlocking( const uint16_t p_timeout, const uint16_t p_slice ) :
johnb 13:302e7c1ea0b3 329 XBeeApiCmdAt( ),
johnb 13:302e7c1ea0b3 330 m_timeout( p_timeout ),
johnb 13:302e7c1ea0b3 331 m_slice( p_slice )
johnb 8:1b48b619d7f6 332 {
johnb 8:1b48b619d7f6 333 }
johnb 8:1b48b619d7f6 334
johnb 13:302e7c1ea0b3 335 /**
johnb 11:bfcf1356027b 336 Macro to wrap around the "requestXXX" & "getXXX" methods and implement a blocking call.
johnb 11:bfcf1356027b 337 This macro is used as the basis for getXXX functions in XBeeApiCmdAtBlocking.
johnb 8:1b48b619d7f6 338
johnb 13:302e7c1ea0b3 339 Originally looked to achieve this using a template function passing method pointers, however
johnb 13:302e7c1ea0b3 340 there's no way to get a method pointer to the parent class implementation as opposed to the
johnb 13:302e7c1ea0b3 341 implementation in this class, meaning that the result was a recursive method call. The joys of
johnb 11:bfcf1356027b 342 polymorphism.
johnb 13:302e7c1ea0b3 343
johnb 11:bfcf1356027b 344 e.g. We pass a pointer to method getHardwareVersion(). The function receiving the pointer
johnb 11:bfcf1356027b 345 uses it to make a function call. The actual function that's called is (correctly)
johnb 11:bfcf1356027b 346 the one implemented in this class, however what we actually wanted in this case
johnb 11:bfcf1356027b 347 was to call the implementation in the base class. Using static_cast<> doesn't have
johnb 11:bfcf1356027b 348 any effect and taking the address of XBeeApiCmdAt::getHardwareVersion ends up with
johnb 11:bfcf1356027b 349 XBeeApiCmdAtBlocking::getHardwareVersion being called due to polymorphism. */
johnb 11:bfcf1356027b 350 #define BLOCKING_GET( _REQ_FN, _GET_FN, _VAR ) \
johnb 11:bfcf1356027b 351 bool ret_val = false; \
johnb 11:bfcf1356027b 352 uint16_t counter = m_timeout; \
johnb 11:bfcf1356027b 353 \
johnb 11:bfcf1356027b 354 if( _GET_FN( _VAR ) )\
johnb 11:bfcf1356027b 355 {\
johnb 11:bfcf1356027b 356 ret_val = true;\
johnb 11:bfcf1356027b 357 } \
johnb 11:bfcf1356027b 358 else if( _REQ_FN() )\
johnb 11:bfcf1356027b 359 {\
johnb 11:bfcf1356027b 360 bool cont = false;\
johnb 11:bfcf1356027b 361 \
johnb 11:bfcf1356027b 362 do{\
johnb 11:bfcf1356027b 363 wait_ms( m_slice );\
johnb 11:bfcf1356027b 364 if( _GET_FN( _VAR ) )\
johnb 11:bfcf1356027b 365 {\
johnb 11:bfcf1356027b 366 ret_val = true;\
johnb 11:bfcf1356027b 367 }\
johnb 11:bfcf1356027b 368 else if( counter > m_slice ) {\
johnb 11:bfcf1356027b 369 counter -= m_slice; \
johnb 11:bfcf1356027b 370 cont = true;\
johnb 11:bfcf1356027b 371 } \
johnb 11:bfcf1356027b 372 } while( cont );\
johnb 11:bfcf1356027b 373 }\
johnb 11:bfcf1356027b 374 \
johnb 8:1b48b619d7f6 375 return( ret_val );
johnb 8:1b48b619d7f6 376
johnb 13:302e7c1ea0b3 377 /**
johnb 11:bfcf1356027b 378 Macro to wrap around the "setXXX" & "getXXX" methods and implement a blocking call.
johnb 11:bfcf1356027b 379 This macro is used as the basis for setXXX functions in XBeeApiCmdAtBlocking.
johnb 11:bfcf1356027b 380 */
johnb 11:bfcf1356027b 381 #define BLOCKING_SET( _SET_FN, _GET_FN, _VAR, _TYPE ) \
johnb 11:bfcf1356027b 382 bool ret_val = false; \
johnb 11:bfcf1356027b 383 uint16_t counter = m_timeout; \
johnb 11:bfcf1356027b 384 _TYPE readback; \
johnb 11:bfcf1356027b 385 \
johnb 11:bfcf1356027b 386 if( _SET_FN( _VAR ) )\
johnb 11:bfcf1356027b 387 {\
johnb 11:bfcf1356027b 388 bool cont = false;\
johnb 11:bfcf1356027b 389 \
johnb 11:bfcf1356027b 390 do{\
johnb 11:bfcf1356027b 391 wait_ms( m_slice );\
johnb 11:bfcf1356027b 392 if( _GET_FN( &readback ) &&\
johnb 13:302e7c1ea0b3 393 ( readback == _VAR ))\
johnb 11:bfcf1356027b 394 {\
johnb 11:bfcf1356027b 395 ret_val = true;\
johnb 11:bfcf1356027b 396 }\
johnb 11:bfcf1356027b 397 else if( counter > m_slice ) {\
johnb 11:bfcf1356027b 398 counter -= m_slice; \
johnb 11:bfcf1356027b 399 cont = true;\
johnb 11:bfcf1356027b 400 } \
johnb 11:bfcf1356027b 401 } while( cont );\
johnb 11:bfcf1356027b 402 }\
johnb 11:bfcf1356027b 403 \
johnb 11:bfcf1356027b 404 return( ret_val );
johnb 8:1b48b619d7f6 405
johnb 13:302e7c1ea0b3 406
johnb 8:1b48b619d7f6 407 bool XBeeApiCmdAtBlocking::getHardwareVersion( uint16_t* const p_ver )
johnb 8:1b48b619d7f6 408 {
johnb 13:302e7c1ea0b3 409 BLOCKING_GET( XBeeApiCmdAt::requestHardwareVersion,
johnb 13:302e7c1ea0b3 410 XBeeApiCmdAt::getHardwareVersion,
johnb 11:bfcf1356027b 411 p_ver );
johnb 8:1b48b619d7f6 412 }
johnb 8:1b48b619d7f6 413
johnb 8:1b48b619d7f6 414 bool XBeeApiCmdAtBlocking::getFirmwareVersion( uint16_t* const p_ver )
johnb 8:1b48b619d7f6 415 {
johnb 14:edec6cd78ffb 416 BLOCKING_GET( XBeeApiCmdAt::requestFirmwareVersion,
johnb 14:edec6cd78ffb 417 XBeeApiCmdAt::getFirmwareVersion,
johnb 11:bfcf1356027b 418 p_ver );
johnb 8:1b48b619d7f6 419 }
johnb 8:1b48b619d7f6 420
johnb 8:1b48b619d7f6 421 bool XBeeApiCmdAtBlocking::getChannel( uint8_t* const p_chan )
johnb 8:1b48b619d7f6 422 {
johnb 14:edec6cd78ffb 423 BLOCKING_GET( XBeeApiCmdAt::requestChannel,
johnb 14:edec6cd78ffb 424 XBeeApiCmdAt::getChannel,
johnb 11:bfcf1356027b 425 p_chan );
johnb 8:1b48b619d7f6 426 }
johnb 13:302e7c1ea0b3 427
johnb 8:1b48b619d7f6 428 bool XBeeApiCmdAtBlocking::setChannel( uint8_t const p_chan )
johnb 8:1b48b619d7f6 429 {
johnb 14:edec6cd78ffb 430 BLOCKING_SET( XBeeApiCmdAt::setChannel,
johnb 14:edec6cd78ffb 431 XBeeApiCmdAt::getChannel,
johnb 11:bfcf1356027b 432 p_chan,
johnb 13:302e7c1ea0b3 433 uint8_t );
johnb 13:302e7c1ea0b3 434 }
johnb 13:302e7c1ea0b3 435
johnb 13:302e7c1ea0b3 436 bool XBeeApiCmdAtBlocking::getCoordinatorEnabled( bool* const p_en )
johnb 13:302e7c1ea0b3 437 {
johnb 13:302e7c1ea0b3 438 BLOCKING_GET( XBeeApiCmdAt::requestCoordinatorEnabled,
johnb 13:302e7c1ea0b3 439 XBeeApiCmdAt::getCoordinatorEnabled,
johnb 13:302e7c1ea0b3 440 p_en );
johnb 13:302e7c1ea0b3 441 }
johnb 13:302e7c1ea0b3 442
johnb 13:302e7c1ea0b3 443 bool XBeeApiCmdAtBlocking::setCoordinatorEnabled( const bool p_en )
johnb 13:302e7c1ea0b3 444 {
johnb 14:edec6cd78ffb 445 BLOCKING_SET( XBeeApiCmdAt::setCoordinatorEnabled,
johnb 14:edec6cd78ffb 446 XBeeApiCmdAt::getCoordinatorEnabled,
johnb 13:302e7c1ea0b3 447 p_en,
johnb 13:302e7c1ea0b3 448 bool );
johnb 13:302e7c1ea0b3 449 }
johnb 13:302e7c1ea0b3 450
johnb 13:302e7c1ea0b3 451 bool XBeeApiCmdAtBlocking::getEndDeviceAssociationEnabled( bool* const p_en )
johnb 13:302e7c1ea0b3 452 {
johnb 13:302e7c1ea0b3 453 BLOCKING_GET( XBeeApiCmdAt::requestEndDeviceAssociationEnabled,
johnb 13:302e7c1ea0b3 454 XBeeApiCmdAt::getEndDeviceAssociationEnabled,
johnb 13:302e7c1ea0b3 455 p_en );
johnb 8:1b48b619d7f6 456 }
johnb 8:1b48b619d7f6 457
johnb 13:302e7c1ea0b3 458 bool XBeeApiCmdAtBlocking::setEndDeviceAssociationEnabled( const bool p_en )
johnb 13:302e7c1ea0b3 459 {
johnb 14:edec6cd78ffb 460 BLOCKING_SET( XBeeApiCmdAt::setEndDeviceAssociationEnabled,
johnb 14:edec6cd78ffb 461 XBeeApiCmdAt::getEndDeviceAssociationEnabled,
johnb 13:302e7c1ea0b3 462 p_en,
johnb 13:302e7c1ea0b3 463 bool );
johnb 13:302e7c1ea0b3 464 }
johnb 13:302e7c1ea0b3 465
johnb 13:302e7c1ea0b3 466 bool XBeeApiCmdAtBlocking::getPanId( panId_t* const p_chan )
johnb 13:302e7c1ea0b3 467 {
johnb 13:302e7c1ea0b3 468 BLOCKING_GET( XBeeApiCmdAt::requestPanId,
johnb 13:302e7c1ea0b3 469 XBeeApiCmdAt::getPanId,
johnb 13:302e7c1ea0b3 470 p_chan );
johnb 13:302e7c1ea0b3 471 }
johnb 13:302e7c1ea0b3 472
johnb 13:302e7c1ea0b3 473 bool XBeeApiCmdAtBlocking::setPanId( const panId_t p_chan )
johnb 13:302e7c1ea0b3 474 {
johnb 14:edec6cd78ffb 475 BLOCKING_SET( XBeeApiCmdAt::setPanId,
johnb 14:edec6cd78ffb 476 XBeeApiCmdAt::getPanId,
johnb 13:302e7c1ea0b3 477 p_chan,
johnb 13:302e7c1ea0b3 478 panId_t );
johnb 13:302e7c1ea0b3 479 }
johnb 13:302e7c1ea0b3 480
johnb 13:302e7c1ea0b3 481
johnb 8:1b48b619d7f6 482 XBeeApiCmdAt::XBeeApiCmdAtFirmwareVersionRequest::XBeeApiCmdAtFirmwareVersionRequest( void ) : XBeeApiFrame( )
johnb 8:1b48b619d7f6 483 {
johnb 13:302e7c1ea0b3 484 m_apiId = XBEE_CMD_AT_CMD;
johnb 13:302e7c1ea0b3 485 m_data = cmd_vr;
johnb 13:302e7c1ea0b3 486 m_dataLen = sizeof( cmd_vr );
johnb 8:1b48b619d7f6 487 }
johnb 8:1b48b619d7f6 488
johnb 8:1b48b619d7f6 489 XBeeApiCmdAt::XBeeApiCmdAtHardwareVersionRequest::XBeeApiCmdAtHardwareVersionRequest( void ) : XBeeApiFrame( )
johnb 8:1b48b619d7f6 490 {
johnb 13:302e7c1ea0b3 491 m_apiId = XBEE_CMD_AT_CMD;
johnb 13:302e7c1ea0b3 492 m_data = cmd_hv;
johnb 13:302e7c1ea0b3 493 m_dataLen = sizeof( cmd_hv );
johnb 8:1b48b619d7f6 494 }
johnb 8:1b48b619d7f6 495
johnb 8:1b48b619d7f6 496 XBeeApiCmdAt::XBeeApiCmdAtChannelRequest::XBeeApiCmdAtChannelRequest( void ) : XBeeApiFrame( )
johnb 8:1b48b619d7f6 497 {
johnb 13:302e7c1ea0b3 498 m_apiId = XBEE_CMD_AT_CMD;
johnb 13:302e7c1ea0b3 499 m_data = cmd_ch;
johnb 13:302e7c1ea0b3 500 m_dataLen = sizeof( cmd_ch );
johnb 13:302e7c1ea0b3 501 }
johnb 13:302e7c1ea0b3 502
johnb 13:302e7c1ea0b3 503 XBeeApiCmdAt::XBeeApiCmdAtCERequest::XBeeApiCmdAtCERequest( void ) : XBeeApiFrame( )
johnb 13:302e7c1ea0b3 504 {
johnb 13:302e7c1ea0b3 505 m_apiId = XBEE_CMD_AT_CMD;
johnb 13:302e7c1ea0b3 506 m_data = cmd_ce;
johnb 13:302e7c1ea0b3 507 m_dataLen = sizeof( cmd_ce );
johnb 13:302e7c1ea0b3 508 }
johnb 13:302e7c1ea0b3 509
johnb 13:302e7c1ea0b3 510 XBeeApiCmdAt::XBeeApiCmdAtPANIdRequest::XBeeApiCmdAtPANIdRequest( void ) : XBeeApiFrame( )
johnb 13:302e7c1ea0b3 511 {
johnb 13:302e7c1ea0b3 512 m_apiId = XBEE_CMD_AT_CMD;
johnb 13:302e7c1ea0b3 513 m_data = cmd_pid;
johnb 13:302e7c1ea0b3 514 m_dataLen = sizeof( cmd_pid );
johnb 13:302e7c1ea0b3 515 }
johnb 13:302e7c1ea0b3 516
johnb 13:302e7c1ea0b3 517
johnb 13:302e7c1ea0b3 518 XBeeApiCmdAt::XBeeApiCmdAtEDARequest::XBeeApiCmdAtEDARequest( void ) : XBeeApiFrame( )
johnb 13:302e7c1ea0b3 519 {
johnb 13:302e7c1ea0b3 520 m_apiId = XBEE_CMD_AT_CMD;
johnb 13:302e7c1ea0b3 521 m_data = cmd_eda;
johnb 13:302e7c1ea0b3 522 m_dataLen = sizeof( cmd_eda );
johnb 8:1b48b619d7f6 523 }
johnb 8:1b48b619d7f6 524
johnb 8:1b48b619d7f6 525 XBeeApiCmdAt::XBeeApiCmdAtChannelSet::XBeeApiCmdAtChannelSet( const uint8_t p_chan ) : XBeeApiFrame( )
johnb 8:1b48b619d7f6 526 {
johnb 13:302e7c1ea0b3 527 m_apiId = XBEE_CMD_AT_CMD;
johnb 13:302e7c1ea0b3 528 m_buffer[0] = cmd_set_ch[0];
johnb 13:302e7c1ea0b3 529 m_buffer[1] = cmd_set_ch[1];
johnb 13:302e7c1ea0b3 530 m_buffer[2] = cmd_set_ch[2];
johnb 13:302e7c1ea0b3 531 m_buffer[3] = p_chan;
johnb 13:302e7c1ea0b3 532 m_data = m_buffer;
johnb 13:302e7c1ea0b3 533 m_dataLen = sizeof( cmd_set_ch );
johnb 13:302e7c1ea0b3 534 }
johnb 13:302e7c1ea0b3 535
johnb 13:302e7c1ea0b3 536 XBeeApiCmdAt::XBeeApiCmdAtCESet::XBeeApiCmdAtCESet( const bool p_en ) : XBeeApiFrame( )
johnb 13:302e7c1ea0b3 537 {
johnb 13:302e7c1ea0b3 538 m_apiId = XBEE_CMD_AT_CMD;
johnb 13:302e7c1ea0b3 539 m_buffer[0] = cmd_set_ce[0];
johnb 13:302e7c1ea0b3 540 m_buffer[1] = cmd_set_ce[1];
johnb 13:302e7c1ea0b3 541 m_buffer[2] = cmd_set_ce[2];
johnb 13:302e7c1ea0b3 542 m_buffer[3] = p_en;
johnb 13:302e7c1ea0b3 543 m_data = m_buffer;
johnb 13:302e7c1ea0b3 544 m_dataLen = sizeof( cmd_set_ce );
johnb 8:1b48b619d7f6 545 }
johnb 13:302e7c1ea0b3 546
johnb 13:302e7c1ea0b3 547 XBeeApiCmdAt::XBeeApiCmdAtEDASet::XBeeApiCmdAtEDASet( const bool p_en ) : XBeeApiFrame( )
johnb 13:302e7c1ea0b3 548 {
johnb 13:302e7c1ea0b3 549 m_apiId = XBEE_CMD_AT_CMD;
johnb 13:302e7c1ea0b3 550 m_buffer[0] = cmd_set_eda[0];
johnb 13:302e7c1ea0b3 551 m_buffer[1] = cmd_set_eda[1];
johnb 13:302e7c1ea0b3 552 m_buffer[2] = cmd_set_eda[2];
johnb 13:302e7c1ea0b3 553 m_buffer[3] = p_en;
johnb 13:302e7c1ea0b3 554 m_data = m_buffer;
johnb 13:302e7c1ea0b3 555 m_dataLen = sizeof( cmd_set_eda );
johnb 13:302e7c1ea0b3 556 }
johnb 13:302e7c1ea0b3 557
johnb 13:302e7c1ea0b3 558 XBeeApiCmdAt::XBeeApiCmdAtPANIdSet::XBeeApiCmdAtPANIdSet( const panId_t p_id ) : XBeeApiFrame( )
johnb 13:302e7c1ea0b3 559 {
johnb 13:302e7c1ea0b3 560 m_apiId = XBEE_CMD_AT_CMD;
johnb 13:302e7c1ea0b3 561 m_buffer[0] = cmd_set_pid[0];
johnb 13:302e7c1ea0b3 562 m_buffer[1] = cmd_set_pid[1];
johnb 13:302e7c1ea0b3 563 m_buffer[2] = cmd_set_pid[2];
johnb 13:302e7c1ea0b3 564 m_buffer[3] = p_id >> 8U;
johnb 13:302e7c1ea0b3 565 m_buffer[4] = p_id;
johnb 13:302e7c1ea0b3 566 m_data = m_buffer;
johnb 13:302e7c1ea0b3 567 m_dataLen = sizeof( cmd_set_pid );
johnb 13:302e7c1ea0b3 568 }