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:
Fri Feb 07 21:17:32 2014 +0000
Revision:
32:af4e495afd62
Parent:
31:c144106e55b5
Child:
36:cc7e8d1e35dd
Add methods to access more XBee parameters.

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 31:c144106e55b5 33 #define CMD_RESPONSE_SET_MY 'a'
johnb 31:c144106e55b5 34 #define CMD_RESPONSE_GET_MY 'b'
johnb 32:af4e495afd62 35 #define CMD_RESPONSE_GET_SH 'c'
johnb 32:af4e495afd62 36 #define CMD_RESPONSE_GET_SL 'd'
johnb 32:af4e495afd62 37 #define CMD_RESPONSE_SET_RR 'e'
johnb 32:af4e495afd62 38 #define CMD_RESPONSE_GET_RR 'f'
johnb 32:af4e495afd62 39 #define CMD_RESPONSE_SET_RN 'g'
johnb 32:af4e495afd62 40 #define CMD_RESPONSE_GET_RN 'h'
johnb 32:af4e495afd62 41 #define CMD_RESPONSE_SET_MM 'i'
johnb 32:af4e495afd62 42 #define CMD_RESPONSE_GET_MM 'j'
johnb 13:302e7c1ea0b3 43
johnb 30:9532b01a1ae1 44 /** Lowest channel supported by the XBee S1 */
johnb 30:9532b01a1ae1 45 #define XBEE_CHAN_MIN 0x0b
johnb 30:9532b01a1ae1 46 /** Highest channel supported by the XBee S1 */
johnb 30:9532b01a1ae1 47 #define XBEE_CHAN_MAX 0x1a
johnb 13:302e7c1ea0b3 48
johnb 30:9532b01a1ae1 49 /** Lowest channel supported by the XBee S1 Pro */
johnb 30:9532b01a1ae1 50 #define XBEE_PRO_CHAN_MIN 0x0c
johnb 30:9532b01a1ae1 51 /** Highest channel supported by the XBee S1 Pro */
johnb 30:9532b01a1ae1 52 #define XBEE_PRO_CHAN_MAX 0x17
johnb 8:1b48b619d7f6 53
johnb 8:1b48b619d7f6 54 /* Content for the various commands - value of 0 indicates a value to be populated (i.e. variable) */
johnb 8:1b48b619d7f6 55
johnb 32:af4e495afd62 56 static const uint8_t cmd_vr[] = { CMD_RESPONSE_GET_VR, 'V', 'R' };
johnb 32:af4e495afd62 57 static const uint8_t cmd_hv[] = { CMD_RESPONSE_GET_HV, 'H', 'V' };
johnb 32:af4e495afd62 58 static const uint8_t cmd_sh[] = { CMD_RESPONSE_GET_SH, 'S', 'H' };
johnb 32:af4e495afd62 59 static const uint8_t cmd_sl[] = { CMD_RESPONSE_GET_SL, 'S', 'L' };
johnb 13:302e7c1ea0b3 60
johnb 32:af4e495afd62 61 static const uint8_t cmd_ch[] = { CMD_RESPONSE_GET_CH, 'C', 'H' };
johnb 32:af4e495afd62 62 static const uint8_t cmd_set_ch[] = { CMD_RESPONSE_SET_CH, 'C', 'H', 0 };
johnb 13:302e7c1ea0b3 63
johnb 32:af4e495afd62 64 static const uint8_t cmd_ce[] = { CMD_RESPONSE_GET_CE, 'C', 'E' };
johnb 32:af4e495afd62 65 static const uint8_t cmd_set_ce[] = { CMD_RESPONSE_SET_CE, 'C', 'E', 0 };
johnb 32:af4e495afd62 66
johnb 32:af4e495afd62 67 static const uint8_t cmd_eda[] = { CMD_RESPONSE_GET_EDA, 'A', '1' };
johnb 32:af4e495afd62 68 static const uint8_t cmd_set_eda[] = { CMD_RESPONSE_SET_EDA, 'A', '1', 0 };
johnb 13:302e7c1ea0b3 69
johnb 32:af4e495afd62 70 static const uint8_t cmd_pid[] = { CMD_RESPONSE_GET_PID, 'I', 'D' };
johnb 32:af4e495afd62 71 static const uint8_t cmd_set_pid[] = { CMD_RESPONSE_SET_PID, 'I', 'D', 0, 0 };
johnb 32:af4e495afd62 72
johnb 32:af4e495afd62 73 static const uint8_t cmd_my[] = { CMD_RESPONSE_GET_MY, 'M', 'Y' };
johnb 32:af4e495afd62 74 static const uint8_t cmd_set_my[] = { CMD_RESPONSE_SET_MY, 'M', 'Y', 0, 0 };
johnb 13:302e7c1ea0b3 75
johnb 32:af4e495afd62 76 static const uint8_t cmd_rr[] = { CMD_RESPONSE_GET_RR, 'R', 'R' };
johnb 32:af4e495afd62 77 static const uint8_t cmd_set_rr[] = { CMD_RESPONSE_SET_RR, 'R', 'R', 0 };
johnb 8:1b48b619d7f6 78
johnb 32:af4e495afd62 79 static const uint8_t cmd_rn[] = { CMD_RESPONSE_GET_RN, 'R', 'N' };
johnb 32:af4e495afd62 80 static const uint8_t cmd_set_rn[] = { CMD_RESPONSE_SET_RN, 'R', 'N', 0 };
johnb 31:c144106e55b5 81
johnb 32:af4e495afd62 82 static const uint8_t cmd_mm[] = { CMD_RESPONSE_GET_MM, 'M', 'M' };
johnb 32:af4e495afd62 83 static const uint8_t cmd_set_mm[] = { CMD_RESPONSE_SET_MM, 'M', 'M', 0 };
johnb 31:c144106e55b5 84
johnb 8:1b48b619d7f6 85 #define XBEE_CMD_POSN_FRAME_ID (4U)
johnb 13:302e7c1ea0b3 86 #define XBEE_CMD_POSN_STATUS (7U)
johnb 8:1b48b619d7f6 87 #define XBEE_CMD_POSN_PARAM_START (8U)
johnb 8:1b48b619d7f6 88
johnb 13:302e7c1ea0b3 89 #define XBEE_CMD_RESPONS_HAS_DATA( _p_len ) ((_p_len > ( XBEE_CMD_POSN_PARAM_START + 1 ))
johnb 13:302e7c1ea0b3 90
johnb 29:c6d037cceb02 91 XBeeApiCmdAt::XBeeApiCmdAt( XBeeDevice* const p_device ) : XBeeApiFrameDecoder( p_device ) ,
johnb 31:c144106e55b5 92 m_have_hwVer( false ),
johnb 31:c144106e55b5 93 m_have_fwVer( false ),
johnb 31:c144106e55b5 94 m_have_chan( false ),
johnb 31:c144106e55b5 95 m_have_PANId( false ),
johnb 31:c144106e55b5 96 m_have_EDA( false ),
johnb 31:c144106e55b5 97 m_have_CE( false ),
johnb 32:af4e495afd62 98 m_have_sourceAddress( false ),
johnb 32:af4e495afd62 99 m_have_snLow( false ),
johnb 32:af4e495afd62 100 m_have_snHigh( false ),
johnb 32:af4e495afd62 101 m_have_retries( false ),
johnb 32:af4e495afd62 102 m_have_randomDelaySlots( false ),
johnb 32:af4e495afd62 103 m_have_macMode( false )
johnb 8:1b48b619d7f6 104 {
johnb 8:1b48b619d7f6 105 }
johnb 8:1b48b619d7f6 106
johnb 32:af4e495afd62 107 #define PROCESS_SET_GET_RESPONSE_GENERIC( _type, _var, _src, _t ) \
johnb 32:af4e495afd62 108 case CMD_RESPONSE_SET_ ## _type: \
johnb 32:af4e495afd62 109 case CMD_RESPONSE_GET_ ## _type: \
johnb 32:af4e495afd62 110 if( p_data[ XBEE_CMD_POSN_STATUS ] == 0 ) \
johnb 32:af4e495afd62 111 { \
johnb 32:af4e495afd62 112 if( CMD_RESPONSE_GET_ ## _type == p_data[ XBEE_CMD_POSN_API_ID ] ) \
johnb 32:af4e495afd62 113 { \
johnb 32:af4e495afd62 114 m_ ##_var = (_t) (_src); \
johnb 32:af4e495afd62 115 } \
johnb 32:af4e495afd62 116 else \
johnb 32:af4e495afd62 117 { \
johnb 32:af4e495afd62 118 m_ ## _var = m_ ## _var ## Pend; \
johnb 32:af4e495afd62 119 } \
johnb 32:af4e495afd62 120 m_have_ ## _var = true; \
johnb 32:af4e495afd62 121 } \
johnb 32:af4e495afd62 122 else \
johnb 32:af4e495afd62 123 { \
johnb 32:af4e495afd62 124 /* TODO */ \
johnb 32:af4e495afd62 125 } \
johnb 32:af4e495afd62 126 ret_val = true; \
johnb 32:af4e495afd62 127 break;
johnb 32:af4e495afd62 128
johnb 32:af4e495afd62 129 #define PROCESS_GET_RESPONSE_GENERIC( _type, _var, _src ) \
johnb 32:af4e495afd62 130 case CMD_RESPONSE_GET_ ## _type: \
johnb 32:af4e495afd62 131 if( p_data[ XBEE_CMD_POSN_STATUS ] == 0 ) \
johnb 32:af4e495afd62 132 { \
johnb 32:af4e495afd62 133 m_ ##_var = _src; \
johnb 32:af4e495afd62 134 m_have_ ## _var = true; \
johnb 32:af4e495afd62 135 } \
johnb 32:af4e495afd62 136 else \
johnb 32:af4e495afd62 137 { \
johnb 32:af4e495afd62 138 /* TODO */ \
johnb 32:af4e495afd62 139 } \
johnb 32:af4e495afd62 140 ret_val = true; \
johnb 32:af4e495afd62 141 break;
johnb 32:af4e495afd62 142
johnb 32:af4e495afd62 143 #define PROCESS_SET_GET_RESPONSE_8BIT_WITHCAST( _type, _var, _t ) PROCESS_SET_GET_RESPONSE_GENERIC( _type, _var, p_data[ XBEE_CMD_POSN_PARAM_START ], _t )
johnb 32:af4e495afd62 144 #define PROCESS_SET_GET_RESPONSE_8BIT( _type, _var ) PROCESS_SET_GET_RESPONSE_GENERIC( _type, _var, p_data[ XBEE_CMD_POSN_PARAM_START ], uint8_t )
johnb 32:af4e495afd62 145 #define PROCESS_SET_GET_RESPONSE_16BIT( _type, _var ) PROCESS_SET_GET_RESPONSE_GENERIC( _type, _var, ((uint16_t)p_data[ XBEE_CMD_POSN_PARAM_START ] << 8) | p_data[ XBEE_CMD_POSN_PARAM_START + 1 ], uint16_t )
johnb 32:af4e495afd62 146
johnb 32:af4e495afd62 147 #define PROCESS_GET_RESPONSE_16BIT( _type, _var ) PROCESS_GET_RESPONSE_GENERIC( _type, _var, ((uint16_t)p_data[ XBEE_CMD_POSN_PARAM_START ] << 8) | p_data[ XBEE_CMD_POSN_PARAM_START + 1 ] )
johnb 32:af4e495afd62 148 #define PROCESS_GET_RESPONSE_32BIT( _type, _var ) PROCESS_GET_RESPONSE_GENERIC( _type, _var, ((uint32_t)p_data[ XBEE_CMD_POSN_PARAM_START ] << 24) |\
johnb 32:af4e495afd62 149 ((uint32_t)p_data[ XBEE_CMD_POSN_PARAM_START + 1 ] << 16) |\
johnb 32:af4e495afd62 150 ((uint32_t)p_data[ XBEE_CMD_POSN_PARAM_START + 2 ] << 8) |\
johnb 32:af4e495afd62 151 ((uint32_t)p_data[ XBEE_CMD_POSN_PARAM_START + 3 ]))
johnb 32:af4e495afd62 152
johnb 32:af4e495afd62 153
johnb 8:1b48b619d7f6 154 bool XBeeApiCmdAt::decodeCallback( const uint8_t* const p_data, size_t p_len )
johnb 8:1b48b619d7f6 155 {
johnb 8:1b48b619d7f6 156 bool ret_val = false;
johnb 13:302e7c1ea0b3 157
johnb 13:302e7c1ea0b3 158 if( XBEE_CMD_AT_RESPONSE == p_data[ XBEE_CMD_POSN_API_ID ] ) {
johnb 13:302e7c1ea0b3 159
johnb 13:302e7c1ea0b3 160 switch( p_data[ XBEE_CMD_POSN_FRAME_ID ] ) {
johnb 32:af4e495afd62 161
johnb 32:af4e495afd62 162 PROCESS_GET_RESPONSE_16BIT( HV, hwVer )
johnb 32:af4e495afd62 163 PROCESS_GET_RESPONSE_16BIT( VR, fwVer )
johnb 32:af4e495afd62 164
johnb 32:af4e495afd62 165 PROCESS_SET_GET_RESPONSE_8BIT( CH, chan )
johnb 32:af4e495afd62 166 PROCESS_SET_GET_RESPONSE_8BIT( CE, CE )
johnb 32:af4e495afd62 167 PROCESS_SET_GET_RESPONSE_8BIT( PID, PANId )
johnb 32:af4e495afd62 168 PROCESS_SET_GET_RESPONSE_8BIT( EDA, EDA )
johnb 32:af4e495afd62 169 PROCESS_SET_GET_RESPONSE_8BIT( RR, retries )
johnb 32:af4e495afd62 170 PROCESS_SET_GET_RESPONSE_16BIT( MY, sourceAddress )
johnb 32:af4e495afd62 171 PROCESS_GET_RESPONSE_32BIT( SH, snHigh )
johnb 32:af4e495afd62 172 PROCESS_GET_RESPONSE_32BIT( SL, snLow )
johnb 32:af4e495afd62 173 PROCESS_SET_GET_RESPONSE_8BIT( RN, randomDelaySlots )
johnb 32:af4e495afd62 174 PROCESS_SET_GET_RESPONSE_8BIT_WITHCAST( MM, macMode, XBeeApiMACMode_e )
johnb 8:1b48b619d7f6 175 }
johnb 8:1b48b619d7f6 176 }
johnb 8:1b48b619d7f6 177 return ret_val;
johnb 8:1b48b619d7f6 178 }
johnb 8:1b48b619d7f6 179
johnb 8:1b48b619d7f6 180 bool XBeeApiCmdAt::setChannel( uint8_t const p_chan )
johnb 8:1b48b619d7f6 181 {
johnb 29:c6d037cceb02 182 bool ret_val = false;
johnb 29:c6d037cceb02 183
johnb 29:c6d037cceb02 184 if((( m_device->getXBeeModel() == XBeeDevice::XBEEDEVICE_S1 ) &&
johnb 29:c6d037cceb02 185 ( p_chan >= XBEE_CHAN_MIN ) &&
johnb 29:c6d037cceb02 186 ( p_chan <= XBEE_CHAN_MAX )) ||
johnb 29:c6d037cceb02 187 (( m_device->getXBeeModel() == XBeeDevice::XBEEDEVICE_S1_PRO ) &&
johnb 29:c6d037cceb02 188 ( p_chan >= XBEE_PRO_CHAN_MIN ) &&
johnb 29:c6d037cceb02 189 ( p_chan <= XBEE_PRO_CHAN_MAX )))
johnb 29:c6d037cceb02 190 {
johnb 29:c6d037cceb02 191 XBeeApiCmdAtSet<uint8_t> req( cmd_set_ch, p_chan );
johnb 29:c6d037cceb02 192
johnb 29:c6d037cceb02 193 m_chanPend = p_chan;
johnb 29:c6d037cceb02 194 m_device->SendFrame( &req );
johnb 29:c6d037cceb02 195 ret_val = true;
johnb 29:c6d037cceb02 196 }
johnb 29:c6d037cceb02 197 return ret_val;
johnb 8:1b48b619d7f6 198 }
johnb 8:1b48b619d7f6 199
johnb 31:c144106e55b5 200 #define MAKE_REQUEST( _name, _mnemonic, _cmd ) \
johnb 31:c144106e55b5 201 bool XBeeApiCmdAt::request ## _name( void ) \
johnb 31:c144106e55b5 202 {\
johnb 31:c144106e55b5 203 XBeeApiFrame req( XBEE_CMD_AT_CMD, _cmd, sizeof( _cmd ));\
johnb 31:c144106e55b5 204 m_have_ ## _mnemonic = false;\
johnb 31:c144106e55b5 205 m_device->SendFrame( &req );\
johnb 31:c144106e55b5 206 return true;\
johnb 8:1b48b619d7f6 207 }
johnb 8:1b48b619d7f6 208
johnb 31:c144106e55b5 209 MAKE_REQUEST( HardwareVersion, hwVer, cmd_hv )
johnb 31:c144106e55b5 210 MAKE_REQUEST( FirmwareVersion, fwVer, cmd_vr )
johnb 31:c144106e55b5 211 MAKE_REQUEST( Channel, chan, cmd_ch )
johnb 31:c144106e55b5 212 MAKE_REQUEST( PanId, PANId, cmd_pid )
johnb 31:c144106e55b5 213 MAKE_REQUEST( CoordinatorEnabled, CE, cmd_ce )
johnb 31:c144106e55b5 214 MAKE_REQUEST( EndDeviceAssociationEnabled, EDA, cmd_eda )
johnb 31:c144106e55b5 215 MAKE_REQUEST( SourceAddress, sourceAddress, cmd_my )
johnb 32:af4e495afd62 216 MAKE_REQUEST( Retries, retries, cmd_rr )
johnb 32:af4e495afd62 217 MAKE_REQUEST( RandomDelaySlots, randomDelaySlots, cmd_rn )
johnb 32:af4e495afd62 218 MAKE_REQUEST( MacMode, macMode, cmd_mm );
johnb 32:af4e495afd62 219
johnb 32:af4e495afd62 220 bool XBeeApiCmdAt::requestSerialNumber( void )
johnb 32:af4e495afd62 221 {
johnb 32:af4e495afd62 222 XBeeApiFrame req1( XBEE_CMD_AT_CMD, cmd_sh, sizeof( cmd_sh ));
johnb 32:af4e495afd62 223 XBeeApiFrame req2( XBEE_CMD_AT_CMD, cmd_sl, sizeof( cmd_sl ));
johnb 32:af4e495afd62 224 m_have_snHigh = m_have_snLow = false;
johnb 32:af4e495afd62 225 m_device->SendFrame( &req1 );
johnb 32:af4e495afd62 226 m_device->SendFrame( &req2 );
johnb 32:af4e495afd62 227 return true;
johnb 32:af4e495afd62 228 }
johnb 8:1b48b619d7f6 229
johnb 31:c144106e55b5 230 #define MAKE_GET(_name, _mnemonic, _type ) \
johnb 31:c144106e55b5 231 bool XBeeApiCmdAt::get ## _name( _type* const p_param ) \
johnb 31:c144106e55b5 232 {\
johnb 31:c144106e55b5 233 if( m_have_ ## _mnemonic ) {\
johnb 31:c144106e55b5 234 *p_param = m_ ## _mnemonic;\
johnb 31:c144106e55b5 235 } \
johnb 31:c144106e55b5 236 return m_have_ ## _mnemonic; \
johnb 13:302e7c1ea0b3 237 }
johnb 13:302e7c1ea0b3 238
johnb 31:c144106e55b5 239 MAKE_GET( FirmwareVersion, fwVer, uint16_t )
johnb 31:c144106e55b5 240 MAKE_GET( HardwareVersion, hwVer, uint16_t )
johnb 31:c144106e55b5 241 MAKE_GET( Channel, chan, uint8_t )
johnb 31:c144106e55b5 242 MAKE_GET( CoordinatorEnabled, CE, bool );
johnb 31:c144106e55b5 243 MAKE_GET( EndDeviceAssociationEnabled, EDA, bool )
johnb 31:c144106e55b5 244 MAKE_GET( PanId, PANId, panId_t )
johnb 31:c144106e55b5 245 MAKE_GET( SourceAddress, sourceAddress, uint16_t )
johnb 32:af4e495afd62 246 MAKE_GET( Retries, retries, uint8_t )
johnb 32:af4e495afd62 247 MAKE_GET( RandomDelaySlots, randomDelaySlots, uint8_t )
johnb 32:af4e495afd62 248 MAKE_GET( MacMode, macMode, XBeeApiMACMode_e )
johnb 32:af4e495afd62 249
johnb 32:af4e495afd62 250 bool XBeeApiCmdAt::getSerialNumber( uint64_t* const p_sn )
johnb 32:af4e495afd62 251 {
johnb 32:af4e495afd62 252 /* Need both halves to have the complete serial number */
johnb 32:af4e495afd62 253 bool have_sn = m_have_snLow && m_have_snHigh;
johnb 32:af4e495afd62 254 if( have_sn )
johnb 32:af4e495afd62 255 {
johnb 32:af4e495afd62 256 *p_sn = m_snHigh;
johnb 32:af4e495afd62 257 *p_sn = *p_sn << 32U;
johnb 32:af4e495afd62 258 *p_sn |= m_snLow;
johnb 32:af4e495afd62 259 }
johnb 32:af4e495afd62 260 return( have_sn );
johnb 32:af4e495afd62 261 }
johnb 25:db6874b7ac4b 262
johnb 31:c144106e55b5 263 #define MAKE_SET( _name, _mnemonic, _cmd, _type ) \
johnb 31:c144106e55b5 264 bool XBeeApiCmdAt::set ## _name( const _type p_param ) \
johnb 31:c144106e55b5 265 {\
johnb 31:c144106e55b5 266 XBeeApiCmdAtSet<_type> req( _cmd, p_param );\
johnb 31:c144106e55b5 267 \
johnb 31:c144106e55b5 268 m_have_ ## _mnemonic = false;\
johnb 31:c144106e55b5 269 m_## _mnemonic ## Pend = p_param;\
johnb 31:c144106e55b5 270 m_device->SendFrame( &req );\
johnb 31:c144106e55b5 271 return true;\
johnb 13:302e7c1ea0b3 272 }
johnb 13:302e7c1ea0b3 273
johnb 32:af4e495afd62 274 MAKE_SET( CoordinatorEnabled, CE, cmd_set_ce, bool )
johnb 32:af4e495afd62 275 MAKE_SET( EndDeviceAssociationEnabled, EDA, cmd_set_eda, bool )
johnb 32:af4e495afd62 276 MAKE_SET( PanId, PANId, cmd_set_pid, panId_t )
johnb 32:af4e495afd62 277 MAKE_SET( SourceAddress, sourceAddress, cmd_set_my, uint16_t )
johnb 32:af4e495afd62 278 MAKE_SET( Retries, retries, cmd_set_rr, uint8_t )
johnb 32:af4e495afd62 279 MAKE_SET( RandomDelaySlots, randomDelaySlots, cmd_set_rn, uint8_t )
johnb 32:af4e495afd62 280 MAKE_SET( MacMode, macMode, cmd_set_mm, XBeeApiMACMode_e )
johnb 13:302e7c1ea0b3 281
johnb 29:c6d037cceb02 282 XBeeApiCmdAtBlocking::XBeeApiCmdAtBlocking( XBeeDevice* const p_device, const uint16_t p_timeout, const uint16_t p_slice ) :
johnb 29:c6d037cceb02 283 XBeeApiCmdAt( p_device ),
johnb 13:302e7c1ea0b3 284 m_timeout( p_timeout ),
johnb 13:302e7c1ea0b3 285 m_slice( p_slice )
johnb 8:1b48b619d7f6 286 {
johnb 8:1b48b619d7f6 287 }
johnb 8:1b48b619d7f6 288
johnb 13:302e7c1ea0b3 289 /**
johnb 11:bfcf1356027b 290 Macro to wrap around the "requestXXX" & "getXXX" methods and implement a blocking call.
johnb 11:bfcf1356027b 291 This macro is used as the basis for getXXX functions in XBeeApiCmdAtBlocking.
johnb 8:1b48b619d7f6 292
johnb 13:302e7c1ea0b3 293 Originally looked to achieve this using a template function passing method pointers, however
johnb 13:302e7c1ea0b3 294 there's no way to get a method pointer to the parent class implementation as opposed to the
johnb 13:302e7c1ea0b3 295 implementation in this class, meaning that the result was a recursive method call. The joys of
johnb 11:bfcf1356027b 296 polymorphism.
johnb 13:302e7c1ea0b3 297
johnb 11:bfcf1356027b 298 e.g. We pass a pointer to method getHardwareVersion(). The function receiving the pointer
johnb 11:bfcf1356027b 299 uses it to make a function call. The actual function that's called is (correctly)
johnb 11:bfcf1356027b 300 the one implemented in this class, however what we actually wanted in this case
johnb 11:bfcf1356027b 301 was to call the implementation in the base class. Using static_cast<> doesn't have
johnb 11:bfcf1356027b 302 any effect and taking the address of XBeeApiCmdAt::getHardwareVersion ends up with
johnb 11:bfcf1356027b 303 XBeeApiCmdAtBlocking::getHardwareVersion being called due to polymorphism. */
johnb 11:bfcf1356027b 304 #define BLOCKING_GET( _REQ_FN, _GET_FN, _VAR ) \
johnb 11:bfcf1356027b 305 bool ret_val = false; \
johnb 11:bfcf1356027b 306 \
johnb 11:bfcf1356027b 307 if( _GET_FN( _VAR ) )\
johnb 11:bfcf1356027b 308 {\
johnb 11:bfcf1356027b 309 ret_val = true;\
johnb 11:bfcf1356027b 310 } \
johnb 11:bfcf1356027b 311 else if( _REQ_FN() )\
johnb 11:bfcf1356027b 312 {\
johnb 31:c144106e55b5 313 uint16_t counter = m_timeout; \
johnb 31:c144106e55b5 314 bool cont;\
johnb 11:bfcf1356027b 315 \
johnb 11:bfcf1356027b 316 do{\
johnb 31:c144106e55b5 317 cont = false; \
johnb 11:bfcf1356027b 318 wait_ms( m_slice );\
johnb 11:bfcf1356027b 319 if( _GET_FN( _VAR ) )\
johnb 11:bfcf1356027b 320 {\
johnb 11:bfcf1356027b 321 ret_val = true;\
johnb 11:bfcf1356027b 322 }\
johnb 11:bfcf1356027b 323 else if( counter > m_slice ) {\
johnb 11:bfcf1356027b 324 counter -= m_slice; \
johnb 11:bfcf1356027b 325 cont = true;\
johnb 11:bfcf1356027b 326 } \
johnb 11:bfcf1356027b 327 } while( cont );\
johnb 11:bfcf1356027b 328 }\
johnb 11:bfcf1356027b 329 \
johnb 8:1b48b619d7f6 330 return( ret_val );
johnb 8:1b48b619d7f6 331
johnb 13:302e7c1ea0b3 332 /**
johnb 11:bfcf1356027b 333 Macro to wrap around the "setXXX" & "getXXX" methods and implement a blocking call.
johnb 11:bfcf1356027b 334 This macro is used as the basis for setXXX functions in XBeeApiCmdAtBlocking.
johnb 11:bfcf1356027b 335 */
johnb 11:bfcf1356027b 336 #define BLOCKING_SET( _SET_FN, _GET_FN, _VAR, _TYPE ) \
johnb 11:bfcf1356027b 337 bool ret_val = false; \
johnb 11:bfcf1356027b 338 uint16_t counter = m_timeout; \
johnb 11:bfcf1356027b 339 _TYPE readback; \
johnb 11:bfcf1356027b 340 \
johnb 11:bfcf1356027b 341 if( _SET_FN( _VAR ) )\
johnb 11:bfcf1356027b 342 {\
johnb 31:c144106e55b5 343 bool cont;\
johnb 11:bfcf1356027b 344 \
johnb 11:bfcf1356027b 345 do{\
johnb 31:c144106e55b5 346 cont = false;\
johnb 11:bfcf1356027b 347 wait_ms( m_slice );\
johnb 11:bfcf1356027b 348 if( _GET_FN( &readback ) &&\
johnb 13:302e7c1ea0b3 349 ( readback == _VAR ))\
johnb 11:bfcf1356027b 350 {\
johnb 11:bfcf1356027b 351 ret_val = true;\
johnb 11:bfcf1356027b 352 }\
johnb 11:bfcf1356027b 353 else if( counter > m_slice ) {\
johnb 11:bfcf1356027b 354 counter -= m_slice; \
johnb 11:bfcf1356027b 355 cont = true;\
johnb 11:bfcf1356027b 356 } \
johnb 11:bfcf1356027b 357 } while( cont );\
johnb 11:bfcf1356027b 358 }\
johnb 11:bfcf1356027b 359 \
johnb 11:bfcf1356027b 360 return( ret_val );
johnb 8:1b48b619d7f6 361
johnb 13:302e7c1ea0b3 362
johnb 8:1b48b619d7f6 363 bool XBeeApiCmdAtBlocking::getHardwareVersion( uint16_t* const p_ver )
johnb 8:1b48b619d7f6 364 {
johnb 13:302e7c1ea0b3 365 BLOCKING_GET( XBeeApiCmdAt::requestHardwareVersion,
johnb 13:302e7c1ea0b3 366 XBeeApiCmdAt::getHardwareVersion,
johnb 11:bfcf1356027b 367 p_ver );
johnb 8:1b48b619d7f6 368 }
johnb 8:1b48b619d7f6 369
johnb 8:1b48b619d7f6 370 bool XBeeApiCmdAtBlocking::getFirmwareVersion( uint16_t* const p_ver )
johnb 8:1b48b619d7f6 371 {
johnb 14:edec6cd78ffb 372 BLOCKING_GET( XBeeApiCmdAt::requestFirmwareVersion,
johnb 14:edec6cd78ffb 373 XBeeApiCmdAt::getFirmwareVersion,
johnb 11:bfcf1356027b 374 p_ver );
johnb 8:1b48b619d7f6 375 }
johnb 8:1b48b619d7f6 376
johnb 32:af4e495afd62 377 bool XBeeApiCmdAtBlocking::getSerialNumber( uint64_t* const p_sn )
johnb 32:af4e495afd62 378 {
johnb 32:af4e495afd62 379 BLOCKING_GET( XBeeApiCmdAt::requestSerialNumber,
johnb 32:af4e495afd62 380 XBeeApiCmdAt::getSerialNumber,
johnb 32:af4e495afd62 381 p_sn );
johnb 32:af4e495afd62 382 }
johnb 32:af4e495afd62 383
johnb 8:1b48b619d7f6 384 bool XBeeApiCmdAtBlocking::getChannel( uint8_t* const p_chan )
johnb 8:1b48b619d7f6 385 {
johnb 14:edec6cd78ffb 386 BLOCKING_GET( XBeeApiCmdAt::requestChannel,
johnb 14:edec6cd78ffb 387 XBeeApiCmdAt::getChannel,
johnb 11:bfcf1356027b 388 p_chan );
johnb 8:1b48b619d7f6 389 }
johnb 13:302e7c1ea0b3 390
johnb 8:1b48b619d7f6 391 bool XBeeApiCmdAtBlocking::setChannel( uint8_t const p_chan )
johnb 8:1b48b619d7f6 392 {
johnb 14:edec6cd78ffb 393 BLOCKING_SET( XBeeApiCmdAt::setChannel,
johnb 14:edec6cd78ffb 394 XBeeApiCmdAt::getChannel,
johnb 11:bfcf1356027b 395 p_chan,
johnb 13:302e7c1ea0b3 396 uint8_t );
johnb 13:302e7c1ea0b3 397 }
johnb 13:302e7c1ea0b3 398
johnb 13:302e7c1ea0b3 399 bool XBeeApiCmdAtBlocking::getCoordinatorEnabled( bool* const p_en )
johnb 13:302e7c1ea0b3 400 {
johnb 13:302e7c1ea0b3 401 BLOCKING_GET( XBeeApiCmdAt::requestCoordinatorEnabled,
johnb 13:302e7c1ea0b3 402 XBeeApiCmdAt::getCoordinatorEnabled,
johnb 13:302e7c1ea0b3 403 p_en );
johnb 13:302e7c1ea0b3 404 }
johnb 13:302e7c1ea0b3 405
johnb 13:302e7c1ea0b3 406 bool XBeeApiCmdAtBlocking::setCoordinatorEnabled( const bool p_en )
johnb 13:302e7c1ea0b3 407 {
johnb 14:edec6cd78ffb 408 BLOCKING_SET( XBeeApiCmdAt::setCoordinatorEnabled,
johnb 14:edec6cd78ffb 409 XBeeApiCmdAt::getCoordinatorEnabled,
johnb 13:302e7c1ea0b3 410 p_en,
johnb 13:302e7c1ea0b3 411 bool );
johnb 13:302e7c1ea0b3 412 }
johnb 13:302e7c1ea0b3 413
johnb 13:302e7c1ea0b3 414 bool XBeeApiCmdAtBlocking::getEndDeviceAssociationEnabled( bool* const p_en )
johnb 13:302e7c1ea0b3 415 {
johnb 13:302e7c1ea0b3 416 BLOCKING_GET( XBeeApiCmdAt::requestEndDeviceAssociationEnabled,
johnb 13:302e7c1ea0b3 417 XBeeApiCmdAt::getEndDeviceAssociationEnabled,
johnb 13:302e7c1ea0b3 418 p_en );
johnb 8:1b48b619d7f6 419 }
johnb 8:1b48b619d7f6 420
johnb 13:302e7c1ea0b3 421 bool XBeeApiCmdAtBlocking::setEndDeviceAssociationEnabled( const bool p_en )
johnb 13:302e7c1ea0b3 422 {
johnb 14:edec6cd78ffb 423 BLOCKING_SET( XBeeApiCmdAt::setEndDeviceAssociationEnabled,
johnb 14:edec6cd78ffb 424 XBeeApiCmdAt::getEndDeviceAssociationEnabled,
johnb 13:302e7c1ea0b3 425 p_en,
johnb 13:302e7c1ea0b3 426 bool );
johnb 13:302e7c1ea0b3 427 }
johnb 13:302e7c1ea0b3 428
johnb 13:302e7c1ea0b3 429 bool XBeeApiCmdAtBlocking::getPanId( panId_t* const p_chan )
johnb 13:302e7c1ea0b3 430 {
johnb 13:302e7c1ea0b3 431 BLOCKING_GET( XBeeApiCmdAt::requestPanId,
johnb 13:302e7c1ea0b3 432 XBeeApiCmdAt::getPanId,
johnb 13:302e7c1ea0b3 433 p_chan );
johnb 13:302e7c1ea0b3 434 }
johnb 13:302e7c1ea0b3 435
johnb 13:302e7c1ea0b3 436 bool XBeeApiCmdAtBlocking::setPanId( const panId_t p_chan )
johnb 13:302e7c1ea0b3 437 {
johnb 14:edec6cd78ffb 438 BLOCKING_SET( XBeeApiCmdAt::setPanId,
johnb 14:edec6cd78ffb 439 XBeeApiCmdAt::getPanId,
johnb 13:302e7c1ea0b3 440 p_chan,
johnb 13:302e7c1ea0b3 441 panId_t );
johnb 13:302e7c1ea0b3 442 }
johnb 13:302e7c1ea0b3 443
johnb 31:c144106e55b5 444 bool XBeeApiCmdAtBlocking::getSourceAddress( uint16_t* const p_addr )
johnb 31:c144106e55b5 445 {
johnb 31:c144106e55b5 446 BLOCKING_GET( XBeeApiCmdAt::requestSourceAddress,
johnb 31:c144106e55b5 447 XBeeApiCmdAt::getSourceAddress,
johnb 31:c144106e55b5 448 p_addr );
johnb 31:c144106e55b5 449 }
johnb 31:c144106e55b5 450
johnb 31:c144106e55b5 451 bool XBeeApiCmdAtBlocking::setSourceAddress( const uint16_t p_addr )
johnb 31:c144106e55b5 452 {
johnb 31:c144106e55b5 453 BLOCKING_SET( XBeeApiCmdAt::setSourceAddress,
johnb 31:c144106e55b5 454 XBeeApiCmdAt::getSourceAddress,
johnb 31:c144106e55b5 455 p_addr,
johnb 31:c144106e55b5 456 uint16_t );
johnb 31:c144106e55b5 457 }
johnb 31:c144106e55b5 458
johnb 32:af4e495afd62 459 bool XBeeApiCmdAtBlocking::getRetries( uint8_t* const p_addr )
johnb 32:af4e495afd62 460 {
johnb 32:af4e495afd62 461 BLOCKING_GET( XBeeApiCmdAt::requestRetries,
johnb 32:af4e495afd62 462 XBeeApiCmdAt::getRetries,
johnb 32:af4e495afd62 463 p_addr );
johnb 32:af4e495afd62 464 }
johnb 32:af4e495afd62 465
johnb 32:af4e495afd62 466 bool XBeeApiCmdAtBlocking::setRetries( const uint8_t p_addr )
johnb 32:af4e495afd62 467 {
johnb 32:af4e495afd62 468 BLOCKING_SET( XBeeApiCmdAt::setRetries,
johnb 32:af4e495afd62 469 XBeeApiCmdAt::getRetries,
johnb 32:af4e495afd62 470 p_addr,
johnb 32:af4e495afd62 471 uint8_t );
johnb 32:af4e495afd62 472 }
johnb 32:af4e495afd62 473
johnb 32:af4e495afd62 474 bool XBeeApiCmdAtBlocking::getRandomDelaySlots( uint8_t* const p_addr )
johnb 32:af4e495afd62 475 {
johnb 32:af4e495afd62 476 BLOCKING_GET( XBeeApiCmdAt::requestRandomDelaySlots,
johnb 32:af4e495afd62 477 XBeeApiCmdAt::getRandomDelaySlots,
johnb 32:af4e495afd62 478 p_addr );
johnb 32:af4e495afd62 479 }
johnb 32:af4e495afd62 480
johnb 32:af4e495afd62 481 bool XBeeApiCmdAtBlocking::setRandomDelaySlots( const uint8_t p_addr )
johnb 32:af4e495afd62 482 {
johnb 32:af4e495afd62 483 BLOCKING_SET( XBeeApiCmdAt::setRandomDelaySlots,
johnb 32:af4e495afd62 484 XBeeApiCmdAt::getRandomDelaySlots,
johnb 32:af4e495afd62 485 p_addr,
johnb 32:af4e495afd62 486 uint8_t );
johnb 32:af4e495afd62 487 }
johnb 32:af4e495afd62 488
johnb 32:af4e495afd62 489 bool XBeeApiCmdAtBlocking::getMacMode( XBeeApiMACMode_e* const p_mode )
johnb 32:af4e495afd62 490 {
johnb 32:af4e495afd62 491 BLOCKING_GET( XBeeApiCmdAt::requestMacMode,
johnb 32:af4e495afd62 492 XBeeApiCmdAt::getMacMode,
johnb 32:af4e495afd62 493 p_mode );
johnb 32:af4e495afd62 494 }
johnb 32:af4e495afd62 495
johnb 32:af4e495afd62 496 bool XBeeApiCmdAtBlocking::setMacMode( const XBeeApiMACMode_e p_mode )
johnb 32:af4e495afd62 497 {
johnb 32:af4e495afd62 498 BLOCKING_SET( XBeeApiCmdAt::setMacMode,
johnb 32:af4e495afd62 499 XBeeApiCmdAt::getMacMode,
johnb 32:af4e495afd62 500 p_mode,
johnb 32:af4e495afd62 501 XBeeApiMACMode_e );
johnb 32:af4e495afd62 502 }
johnb 32:af4e495afd62 503
johnb 32:af4e495afd62 504
johnb 31:c144106e55b5 505
johnb 25:db6874b7ac4b 506 template < typename T >
johnb 25:db6874b7ac4b 507 XBeeApiCmdAt::XBeeApiCmdAtSet<T>::XBeeApiCmdAtSet( const uint8_t* const p_data,
johnb 25:db6874b7ac4b 508 const T p_val ) : XBeeApiFrame( )
johnb 8:1b48b619d7f6 509 {
johnb 25:db6874b7ac4b 510 size_t s;
johnb 25:db6874b7ac4b 511 uint8_t* dest;
johnb 25:db6874b7ac4b 512 const uint8_t* src = (uint8_t*)(&p_val);
johnb 25:db6874b7ac4b 513
johnb 13:302e7c1ea0b3 514 m_apiId = XBEE_CMD_AT_CMD;
johnb 25:db6874b7ac4b 515
johnb 25:db6874b7ac4b 516 m_buffer[0] = p_data[0];
johnb 25:db6874b7ac4b 517 m_buffer[1] = p_data[1];
johnb 25:db6874b7ac4b 518 m_buffer[2] = p_data[2];
johnb 25:db6874b7ac4b 519
johnb 25:db6874b7ac4b 520 dest = &( m_buffer[3] );
johnb 25:db6874b7ac4b 521
johnb 25:db6874b7ac4b 522 for( s = 0;
johnb 25:db6874b7ac4b 523 s < sizeof( T );
johnb 25:db6874b7ac4b 524 s++, dest++, src++ ) {
johnb 25:db6874b7ac4b 525 *dest = *src;
johnb 25:db6874b7ac4b 526 }
johnb 25:db6874b7ac4b 527
johnb 13:302e7c1ea0b3 528 m_data = m_buffer;
johnb 25:db6874b7ac4b 529 m_dataLen = sizeof( m_buffer );
johnb 8:1b48b619d7f6 530 }
johnb 13:302e7c1ea0b3 531
johnb 25:db6874b7ac4b 532 template < typename T >
johnb 25:db6874b7ac4b 533 XBeeApiCmdAt::XBeeApiCmdAtSet<T>::~XBeeApiCmdAtSet()
johnb 13:302e7c1ea0b3 534 {
johnb 25:db6874b7ac4b 535 }