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 Jul 28 12:48:33 2014 +0000
Revision:
52:0950b05d5270
Parent:
51:a7d0d2ef9261
Child:
53:7b65422d7a32
Add initial support for decoding IO frames.

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 50:f76b7e7959a2 43 #define CMD_RESPONSE_GET_D0 'k'
johnb 50:f76b7e7959a2 44 #define CMD_RESPONSE_GET_D1 'l'
johnb 50:f76b7e7959a2 45 #define CMD_RESPONSE_GET_D2 'm'
johnb 50:f76b7e7959a2 46 #define CMD_RESPONSE_GET_D3 'n'
johnb 50:f76b7e7959a2 47 #define CMD_RESPONSE_GET_D4 'o'
johnb 50:f76b7e7959a2 48 #define CMD_RESPONSE_GET_D5 'p'
johnb 50:f76b7e7959a2 49 #define CMD_RESPONSE_GET_D6 'q'
johnb 50:f76b7e7959a2 50 #define CMD_RESPONSE_GET_D7 'r'
johnb 51:a7d0d2ef9261 51 #define CMD_RESPONSE_SET_D0 's'
johnb 51:a7d0d2ef9261 52 #define CMD_RESPONSE_SET_D1 't'
johnb 51:a7d0d2ef9261 53 #define CMD_RESPONSE_SET_D2 'u'
johnb 51:a7d0d2ef9261 54 #define CMD_RESPONSE_SET_D3 'v'
johnb 51:a7d0d2ef9261 55 #define CMD_RESPONSE_SET_D4 'w'
johnb 51:a7d0d2ef9261 56 #define CMD_RESPONSE_SET_D5 'x'
johnb 51:a7d0d2ef9261 57 #define CMD_RESPONSE_SET_D6 'y'
johnb 51:a7d0d2ef9261 58 #define CMD_RESPONSE_SET_D7 'z'
johnb 51:a7d0d2ef9261 59 #define CMD_RESPONSE_SET_IC 'A'
johnb 51:a7d0d2ef9261 60 #define CMD_RESPONSE_GET_IC 'B'
johnb 51:a7d0d2ef9261 61 #define CMD_RESPONSE_SET_IO 'C'
johnb 51:a7d0d2ef9261 62 #define CMD_RESPONSE_SET_IR 'D'
johnb 51:a7d0d2ef9261 63 #define CMD_RESPONSE_GET_IR 'E'
johnb 51:a7d0d2ef9261 64 #define CMD_RESPONSE_SET_DH 'F'
johnb 51:a7d0d2ef9261 65 #define CMD_RESPONSE_GET_DH 'G'
johnb 51:a7d0d2ef9261 66 #define CMD_RESPONSE_SET_DL 'H'
johnb 51:a7d0d2ef9261 67 #define CMD_RESPONSE_GET_DL 'I'
johnb 51:a7d0d2ef9261 68 #define CMD_RESPONSE_SET_WR 'J'
johnb 51:a7d0d2ef9261 69 #define CMD_RESPONSE_SET_AC 'K'
johnb 51:a7d0d2ef9261 70 #define CMD_RESPONSE_SET_FR 'L'
johnb 51:a7d0d2ef9261 71 #define CMD_RESPONSE_SET_IS 'M'
johnb 13:302e7c1ea0b3 72
johnb 30:9532b01a1ae1 73 /** Lowest channel supported by the XBee S1 */
johnb 30:9532b01a1ae1 74 #define XBEE_CHAN_MIN 0x0b
johnb 30:9532b01a1ae1 75 /** Highest channel supported by the XBee S1 */
johnb 30:9532b01a1ae1 76 #define XBEE_CHAN_MAX 0x1a
johnb 13:302e7c1ea0b3 77
johnb 30:9532b01a1ae1 78 /** Lowest channel supported by the XBee S1 Pro */
johnb 30:9532b01a1ae1 79 #define XBEE_PRO_CHAN_MIN 0x0c
johnb 30:9532b01a1ae1 80 /** Highest channel supported by the XBee S1 Pro */
johnb 30:9532b01a1ae1 81 #define XBEE_PRO_CHAN_MAX 0x17
johnb 8:1b48b619d7f6 82
johnb 8:1b48b619d7f6 83 /* Content for the various commands - value of 0 indicates a value to be populated (i.e. variable) */
johnb 8:1b48b619d7f6 84
johnb 50:f76b7e7959a2 85 static const uint8_t cmd_vr[] = { 'V', 'R' };
johnb 50:f76b7e7959a2 86 static const uint8_t cmd_vr_get_fid = CMD_RESPONSE_GET_VR;
johnb 50:f76b7e7959a2 87
johnb 50:f76b7e7959a2 88 static const uint8_t cmd_hv[] = { 'H', 'V' };
johnb 50:f76b7e7959a2 89 static const uint8_t cmd_hv_get_fid = CMD_RESPONSE_GET_HV;
johnb 50:f76b7e7959a2 90
johnb 50:f76b7e7959a2 91 static const uint8_t cmd_sh[] = { 'S', 'H' };
johnb 50:f76b7e7959a2 92 static const uint8_t cmd_sh_get_fid = CMD_RESPONSE_GET_SH;
johnb 50:f76b7e7959a2 93
johnb 50:f76b7e7959a2 94 static const uint8_t cmd_sl[] = { 'S', 'L' };
johnb 50:f76b7e7959a2 95 static const uint8_t cmd_sl_get_fid = CMD_RESPONSE_GET_SL;
johnb 13:302e7c1ea0b3 96
johnb 50:f76b7e7959a2 97 static const uint8_t cmd_ch[] = { 'C', 'H' };
johnb 50:f76b7e7959a2 98 static const uint8_t cmd_ch_get_fid = CMD_RESPONSE_GET_CH;
johnb 50:f76b7e7959a2 99 static const uint8_t cmd_ch_set[] = { 'C', 'H', 0 };
johnb 50:f76b7e7959a2 100 static const uint8_t cmd_ch_set_fid = CMD_RESPONSE_SET_CH;
johnb 50:f76b7e7959a2 101
johnb 50:f76b7e7959a2 102 static const uint8_t cmd_ce[] = { 'C', 'E' };
johnb 50:f76b7e7959a2 103 static const uint8_t cmd_ce_get_fid = CMD_RESPONSE_GET_CE;
johnb 50:f76b7e7959a2 104 static const uint8_t cmd_ce_set[] = { 'C', 'E', 0 };
johnb 50:f76b7e7959a2 105 static const uint8_t cmd_ce_set_fid = CMD_RESPONSE_SET_CE;
johnb 13:302e7c1ea0b3 106
johnb 50:f76b7e7959a2 107 static const uint8_t cmd_eda[] = { 'A', '1' };
johnb 50:f76b7e7959a2 108 static const uint8_t cmd_eda_get_fid = CMD_RESPONSE_GET_EDA;
johnb 50:f76b7e7959a2 109 static const uint8_t cmd_eda_set[] = { 'A', '1', 0 };
johnb 50:f76b7e7959a2 110 static const uint8_t cmd_eda_set_fid = CMD_RESPONSE_SET_EDA;
johnb 32:af4e495afd62 111
johnb 50:f76b7e7959a2 112 static const uint8_t cmd_pid[] = { 'I', 'D' };
johnb 50:f76b7e7959a2 113 static const uint8_t cmd_pid_get_fid = CMD_RESPONSE_GET_PID;
johnb 50:f76b7e7959a2 114 static const uint8_t cmd_pid_set[] = { 'I', 'D', 0, 0 };
johnb 50:f76b7e7959a2 115 static const uint8_t cmd_pid_set_fid = CMD_RESPONSE_SET_PID;
johnb 13:302e7c1ea0b3 116
johnb 50:f76b7e7959a2 117 static const uint8_t cmd_my[] = { 'M', 'Y' };
johnb 50:f76b7e7959a2 118 static const uint8_t cmd_my_get_fid = CMD_RESPONSE_GET_MY;
johnb 50:f76b7e7959a2 119 static const uint8_t cmd_my_set[] = { 'M', 'Y', 0, 0 };
johnb 50:f76b7e7959a2 120 static const uint8_t cmd_my_set_fid = CMD_RESPONSE_SET_MY;
johnb 32:af4e495afd62 121
johnb 50:f76b7e7959a2 122 static const uint8_t cmd_rr[] = { 'R', 'R' };
johnb 50:f76b7e7959a2 123 static const uint8_t cmd_rr_get_fid = CMD_RESPONSE_GET_RR;
johnb 50:f76b7e7959a2 124 static const uint8_t cmd_rr_set[] = { 'R', 'R', 0 };
johnb 50:f76b7e7959a2 125 static const uint8_t cmd_rr_set_fid = CMD_RESPONSE_SET_RR;
johnb 50:f76b7e7959a2 126
johnb 50:f76b7e7959a2 127 static const uint8_t cmd_rn[] = { 'R', 'N' };
johnb 50:f76b7e7959a2 128 static const uint8_t cmd_rn_get_fid = CMD_RESPONSE_GET_RN;
johnb 50:f76b7e7959a2 129 static const uint8_t cmd_rn_set[] = { 'R', 'N', 0 };
johnb 50:f76b7e7959a2 130 static const uint8_t cmd_rn_set_fid = CMD_RESPONSE_SET_RN;
johnb 13:302e7c1ea0b3 131
johnb 50:f76b7e7959a2 132 static const uint8_t cmd_mm[] = { 'M', 'M' };
johnb 50:f76b7e7959a2 133 static const uint8_t cmd_mm_get_fid = CMD_RESPONSE_GET_MM;
johnb 50:f76b7e7959a2 134 static const uint8_t cmd_mm_set[] = { 'M', 'M', 0 };
johnb 50:f76b7e7959a2 135 static const uint8_t cmd_mm_set_fid = CMD_RESPONSE_SET_MM;
johnb 8:1b48b619d7f6 136
johnb 51:a7d0d2ef9261 137 static const uint8_t cmd_ic[] = { 'I', 'C' };
johnb 51:a7d0d2ef9261 138 static const uint8_t cmd_ic_get_fid = CMD_RESPONSE_GET_IC;
johnb 51:a7d0d2ef9261 139 static const uint8_t cmd_ic_set[] = { 'I', 'C', 0 };
johnb 51:a7d0d2ef9261 140 static const uint8_t cmd_ic_set_fid = CMD_RESPONSE_SET_IC;
johnb 51:a7d0d2ef9261 141
johnb 51:a7d0d2ef9261 142 static const uint8_t cmd_io_set[] = { 'I', 'O', 0 };
johnb 51:a7d0d2ef9261 143 static const uint8_t cmd_io_set_fid = CMD_RESPONSE_SET_IO;
johnb 51:a7d0d2ef9261 144
johnb 51:a7d0d2ef9261 145 static const uint8_t cmd_ir[] = { 'I', 'R' };
johnb 51:a7d0d2ef9261 146 static const uint8_t cmd_ir_get_fid = CMD_RESPONSE_GET_IR;
johnb 51:a7d0d2ef9261 147 static const uint8_t cmd_ir_set[] = { 'I', 'R', 0, 0 };
johnb 51:a7d0d2ef9261 148 static const uint8_t cmd_ir_set_fid = CMD_RESPONSE_SET_IR;
johnb 51:a7d0d2ef9261 149
johnb 51:a7d0d2ef9261 150 static const uint8_t cmd_dh[] = { 'D', 'H' };
johnb 51:a7d0d2ef9261 151 static const uint8_t cmd_dh_get_fid = CMD_RESPONSE_GET_DH;
johnb 51:a7d0d2ef9261 152 static const uint8_t cmd_dh_set[] = { 'D', 'H', 0, 0, 0, 0 };
johnb 51:a7d0d2ef9261 153 static const uint8_t cmd_dh_set_fid = CMD_RESPONSE_SET_DH;
johnb 51:a7d0d2ef9261 154
johnb 51:a7d0d2ef9261 155 static const uint8_t cmd_dl[] = { 'D', 'L' };
johnb 51:a7d0d2ef9261 156 static const uint8_t cmd_dl_get_fid = CMD_RESPONSE_GET_DL;
johnb 51:a7d0d2ef9261 157 static const uint8_t cmd_dl_set[] = { 'D', 'L', 0, 0, 0, 0 };
johnb 51:a7d0d2ef9261 158 static const uint8_t cmd_dl_set_fid = CMD_RESPONSE_SET_DL;
johnb 51:a7d0d2ef9261 159
johnb 51:a7d0d2ef9261 160 static const uint8_t cmd_wr[] = { 'W', 'R' };
johnb 51:a7d0d2ef9261 161 static const uint8_t cmd_wr_set_fid = CMD_RESPONSE_SET_WR;
johnb 51:a7d0d2ef9261 162
johnb 51:a7d0d2ef9261 163 static const uint8_t cmd_ac[] = { 'A', 'C' };
johnb 51:a7d0d2ef9261 164 static const uint8_t cmd_ac_set_fid = CMD_RESPONSE_SET_AC;
johnb 51:a7d0d2ef9261 165
johnb 51:a7d0d2ef9261 166 static const uint8_t cmd_fr[] = { 'F', 'R' };
johnb 51:a7d0d2ef9261 167 static const uint8_t cmd_fr_set_fid = CMD_RESPONSE_SET_FR;
johnb 51:a7d0d2ef9261 168
johnb 51:a7d0d2ef9261 169 static const uint8_t cmd_is[] = { 'I', 'S' };
johnb 51:a7d0d2ef9261 170 static const uint8_t cmd_is_set_fid = CMD_RESPONSE_SET_IS;
johnb 51:a7d0d2ef9261 171
johnb 50:f76b7e7959a2 172 static const uint8_t cmd_d[ XBEE_API_DIO_CHANNEL_COUNT ][2] = {{ 'D', '0' },
johnb 50:f76b7e7959a2 173 { 'D', '1' },
johnb 50:f76b7e7959a2 174 { 'D', '2' },
johnb 50:f76b7e7959a2 175 { 'D', '3' },
johnb 50:f76b7e7959a2 176 { 'D', '4' },
johnb 50:f76b7e7959a2 177 { 'D', '5' },
johnb 50:f76b7e7959a2 178 { 'D', '6' },
johnb 50:f76b7e7959a2 179 { 'D', '7' }};
johnb 50:f76b7e7959a2 180 static const uint8_t cmd_d_get_fid[ XBEE_API_DIO_CHANNEL_COUNT ] = { CMD_RESPONSE_GET_D0,
johnb 50:f76b7e7959a2 181 CMD_RESPONSE_GET_D1,
johnb 50:f76b7e7959a2 182 CMD_RESPONSE_GET_D2,
johnb 50:f76b7e7959a2 183 CMD_RESPONSE_GET_D3,
johnb 50:f76b7e7959a2 184 CMD_RESPONSE_GET_D4,
johnb 50:f76b7e7959a2 185 CMD_RESPONSE_GET_D5,
johnb 50:f76b7e7959a2 186 CMD_RESPONSE_GET_D6,
johnb 50:f76b7e7959a2 187 CMD_RESPONSE_GET_D7 };
johnb 31:c144106e55b5 188
johnb 50:f76b7e7959a2 189 #define XBEE_CMD_POSN_FRAME_ID XBEE_CMD_POSN_ID_SPECIFIC_DATA
johnb 13:302e7c1ea0b3 190 #define XBEE_CMD_POSN_STATUS (7U)
johnb 8:1b48b619d7f6 191 #define XBEE_CMD_POSN_PARAM_START (8U)
johnb 8:1b48b619d7f6 192
johnb 13:302e7c1ea0b3 193 #define XBEE_CMD_RESPONS_HAS_DATA( _p_len ) ((_p_len > ( XBEE_CMD_POSN_PARAM_START + 1 ))
johnb 13:302e7c1ea0b3 194
johnb 50:f76b7e7959a2 195 /** Template class to create an XBeeApiFrame which can be used to change
johnb 50:f76b7e7959a2 196 the value of one of the XBee parameters. This class is used by the
johnb 50:f76b7e7959a2 197 setXXX methods in XBeeApiCmdAt */
johnb 50:f76b7e7959a2 198 template< typename T >
johnb 50:f76b7e7959a2 199 class XBeeApiCmdAtSet : public XBeeApiFrame {
johnb 50:f76b7e7959a2 200 uint8_t m_buffer[ XBEE_API_CMD_SET_HEADER_LEN + sizeof( T ) ];
johnb 50:f76b7e7959a2 201 public:
johnb 50:f76b7e7959a2 202 /** Constructor
johnb 50:f76b7e7959a2 203
johnb 50:f76b7e7959a2 204 \param p_data Pointer to a buffer of length 2 bytes identifying
johnb 50:f76b7e7959a2 205 the command, e.g. 'V', 'R' would set up a version
johnb 50:f76b7e7959a2 206 request
johnb 50:f76b7e7959a2 207 \param p_val New value for the parameter
johnb 50:f76b7e7959a2 208 */
johnb 50:f76b7e7959a2 209 XBeeApiCmdAtSet( const uint8_t p_frameId,
johnb 50:f76b7e7959a2 210 const uint8_t* const p_data,
johnb 50:f76b7e7959a2 211 const T p_val );
johnb 50:f76b7e7959a2 212 /** Destructor */
johnb 50:f76b7e7959a2 213 virtual ~XBeeApiCmdAtSet();
johnb 50:f76b7e7959a2 214 };
johnb 50:f76b7e7959a2 215
johnb 50:f76b7e7959a2 216 class XBeeApiCmdAtReq : public XBeeApiFrame {
johnb 50:f76b7e7959a2 217 uint8_t m_buffer[ XBEE_API_CMD_REQ_HEADER_LEN ];
johnb 50:f76b7e7959a2 218 public:
johnb 50:f76b7e7959a2 219 /** Constructor
johnb 50:f76b7e7959a2 220
johnb 50:f76b7e7959a2 221 \param p_data Pointer to a buffer of length 2 bytes identifying
johnb 50:f76b7e7959a2 222 the command, e.g. 'V', 'R' would set up a version
johnb 50:f76b7e7959a2 223 request
johnb 50:f76b7e7959a2 224 \param p_val New value for the parameter
johnb 50:f76b7e7959a2 225 */
johnb 50:f76b7e7959a2 226 XBeeApiCmdAtReq( const uint8_t p_frameId,
johnb 50:f76b7e7959a2 227 const uint8_t* const p_data );
johnb 50:f76b7e7959a2 228 /** Destructor */
johnb 50:f76b7e7959a2 229 virtual ~XBeeApiCmdAtReq();
johnb 50:f76b7e7959a2 230 };
johnb 50:f76b7e7959a2 231
johnb 29:c6d037cceb02 232 XBeeApiCmdAt::XBeeApiCmdAt( XBeeDevice* const p_device ) : XBeeApiFrameDecoder( p_device ) ,
johnb 31:c144106e55b5 233 m_have_hwVer( false ),
johnb 31:c144106e55b5 234 m_have_fwVer( false ),
johnb 31:c144106e55b5 235 m_have_chan( false ),
johnb 31:c144106e55b5 236 m_have_PANId( false ),
johnb 31:c144106e55b5 237 m_have_EDA( false ),
johnb 31:c144106e55b5 238 m_have_CE( false ),
johnb 32:af4e495afd62 239 m_have_sourceAddress( false ),
johnb 32:af4e495afd62 240 m_have_snLow( false ),
johnb 32:af4e495afd62 241 m_have_snHigh( false ),
johnb 32:af4e495afd62 242 m_have_retries( false ),
johnb 32:af4e495afd62 243 m_have_randomDelaySlots( false ),
johnb 51:a7d0d2ef9261 244 m_have_macMode( false ),
johnb 51:a7d0d2ef9261 245 m_have_dioChangeDetectMask( false ),
johnb 51:a7d0d2ef9261 246 m_have_dioLevels( false ),
johnb 51:a7d0d2ef9261 247 m_have_sampleRate( false ),
johnb 51:a7d0d2ef9261 248 m_have_destHigh( false ),
johnb 51:a7d0d2ef9261 249 m_have_destLow ( false ),
johnb 51:a7d0d2ef9261 250 m_writeCount( 0 ),
johnb 51:a7d0d2ef9261 251 m_applyCount( 0 ),
johnb 51:a7d0d2ef9261 252 m_resetCount( 0 ),
johnb 51:a7d0d2ef9261 253 m_sampleCount( 0 )
johnb 8:1b48b619d7f6 254 {
johnb 52:0950b05d5270 255 uint8_t i;
johnb 52:0950b05d5270 256 for( i = 0;
johnb 51:a7d0d2ef9261 257 i < XBEE_API_DIO_CHANNEL_COUNT;
johnb 51:a7d0d2ef9261 258 i++ )
johnb 51:a7d0d2ef9261 259 {
johnb 51:a7d0d2ef9261 260 m_have_d[ i ] = false;
johnb 52:0950b05d5270 261 m_ioDigitalUpdatedTime[ i ] = 0;
johnb 52:0950b05d5270 262 }
johnb 52:0950b05d5270 263 for( i = 0;
johnb 52:0950b05d5270 264 i < XBEE_API_ADC_CHANNEL_COUNT;
johnb 52:0950b05d5270 265 i++ )
johnb 52:0950b05d5270 266 {
johnb 52:0950b05d5270 267 m_ioAnalogueUpdatedTime[ i ] = 0;
johnb 51:a7d0d2ef9261 268 }
johnb 8:1b48b619d7f6 269 }
johnb 8:1b48b619d7f6 270
johnb 51:a7d0d2ef9261 271 #define RESPONSE_OK( _data ) (_data[ statusPosn ] == 0)
johnb 51:a7d0d2ef9261 272
johnb 51:a7d0d2ef9261 273 #define PROCESS_SET_RESPONSE( _type, _var ) \
johnb 51:a7d0d2ef9261 274 case CMD_RESPONSE_SET_ ## _type: \
johnb 51:a7d0d2ef9261 275 if( RESPONSE_OK( p_data )) \
johnb 51:a7d0d2ef9261 276 { \
johnb 51:a7d0d2ef9261 277 m_ ## _var = m_ ## _var ## Pend; \
johnb 51:a7d0d2ef9261 278 m_have_ ## _var = true; \
johnb 51:a7d0d2ef9261 279 } \
johnb 51:a7d0d2ef9261 280 else \
johnb 51:a7d0d2ef9261 281 { \
johnb 51:a7d0d2ef9261 282 /* TODO */ \
johnb 51:a7d0d2ef9261 283 } \
johnb 51:a7d0d2ef9261 284 ret_val = true; \
johnb 51:a7d0d2ef9261 285 break;
johnb 51:a7d0d2ef9261 286
johnb 51:a7d0d2ef9261 287 #define PROCESS_SET_GET_RESPONSE_GENERIC( _type, _var, _src, _t, _sfx ) \
johnb 32:af4e495afd62 288 case CMD_RESPONSE_SET_ ## _type: \
johnb 32:af4e495afd62 289 case CMD_RESPONSE_GET_ ## _type: \
johnb 51:a7d0d2ef9261 290 if( RESPONSE_OK( p_data )) \
johnb 32:af4e495afd62 291 { \
johnb 50:f76b7e7959a2 292 if( CMD_RESPONSE_GET_ ## _type == p_data[ XBEE_CMD_POSN_FRAME_ID ] ) \
johnb 32:af4e495afd62 293 { \
johnb 51:a7d0d2ef9261 294 m_ ##_var ##_sfx = (_t) (_src); \
johnb 32:af4e495afd62 295 } \
johnb 32:af4e495afd62 296 else \
johnb 32:af4e495afd62 297 { \
johnb 51:a7d0d2ef9261 298 m_ ##_var ##_sfx = m_ ## _var ## Pend ## _sfx; \
johnb 32:af4e495afd62 299 } \
johnb 51:a7d0d2ef9261 300 m_have_ ##_var ##_sfx = true; \
johnb 32:af4e495afd62 301 } \
johnb 32:af4e495afd62 302 else \
johnb 32:af4e495afd62 303 { \
johnb 32:af4e495afd62 304 /* TODO */ \
johnb 32:af4e495afd62 305 } \
johnb 32:af4e495afd62 306 ret_val = true; \
johnb 32:af4e495afd62 307 break;
johnb 32:af4e495afd62 308
johnb 32:af4e495afd62 309 #define PROCESS_GET_RESPONSE_GENERIC( _type, _var, _src ) \
johnb 32:af4e495afd62 310 case CMD_RESPONSE_GET_ ## _type: \
johnb 51:a7d0d2ef9261 311 if( RESPONSE_OK( p_data )) \
johnb 32:af4e495afd62 312 { \
johnb 32:af4e495afd62 313 m_ ##_var = _src; \
johnb 32:af4e495afd62 314 m_have_ ## _var = true; \
johnb 32:af4e495afd62 315 } \
johnb 32:af4e495afd62 316 else \
johnb 32:af4e495afd62 317 { \
johnb 32:af4e495afd62 318 /* TODO */ \
johnb 32:af4e495afd62 319 } \
johnb 32:af4e495afd62 320 ret_val = true; \
johnb 32:af4e495afd62 321 break;
johnb 32:af4e495afd62 322
johnb 51:a7d0d2ef9261 323 #define PROCESS_SET_GET_RESPONSE_8BIT_WITHCAST( _type, _var, _t, _sfx ) PROCESS_SET_GET_RESPONSE_GENERIC( _type, _var, p_data[ dataPosn ], _t, _sfx )
johnb 51:a7d0d2ef9261 324 #define PROCESS_SET_GET_RESPONSE_8BIT( _type, _var ) PROCESS_SET_GET_RESPONSE_GENERIC( _type, _var, p_data[ dataPosn ], uint8_t, )
johnb 51:a7d0d2ef9261 325 #define PROCESS_SET_GET_RESPONSE_16BIT( _type, _var ) PROCESS_SET_GET_RESPONSE_GENERIC( _type, _var, ((uint16_t)p_data[ dataPosn ] << 8) | p_data[ dataPosn + 1 ], uint16_t, )
johnb 51:a7d0d2ef9261 326 #define PROCESS_SET_GET_RESPONSE_32BIT( _type, _var ) PROCESS_SET_GET_RESPONSE_GENERIC( _type, _var, ((uint32_t)p_data[ dataPosn ] << 24) |\
johnb 51:a7d0d2ef9261 327 ((uint32_t)p_data[ dataPosn + 1 ] << 16) |\
johnb 51:a7d0d2ef9261 328 ((uint32_t)p_data[ dataPosn + 2 ] << 8) |\
johnb 51:a7d0d2ef9261 329 ((uint32_t)p_data[ dataPosn + 3 ]), uint32_t, )
johnb 50:f76b7e7959a2 330
johnb 50:f76b7e7959a2 331 #define PROCESS_GET_RESPONSE_16BIT( _type, _var ) PROCESS_GET_RESPONSE_GENERIC( _type, _var, ((uint16_t)p_data[ dataPosn ] << 8) | p_data[ dataPosn + 1 ] )
johnb 50:f76b7e7959a2 332 #define PROCESS_GET_RESPONSE_32BIT( _type, _var ) PROCESS_GET_RESPONSE_GENERIC( _type, _var, ((uint32_t)p_data[ dataPosn ] << 24) |\
johnb 50:f76b7e7959a2 333 ((uint32_t)p_data[ dataPosn + 1 ] << 16) |\
johnb 50:f76b7e7959a2 334 ((uint32_t)p_data[ dataPosn + 2 ] << 8) |\
johnb 50:f76b7e7959a2 335 ((uint32_t)p_data[ dataPosn + 3 ]))
johnb 50:f76b7e7959a2 336
johnb 50:f76b7e7959a2 337 size_t XBeeApiCmdAt::getResponseStatusPos( void ) const
johnb 50:f76b7e7959a2 338 {
johnb 50:f76b7e7959a2 339 return XBEE_CMD_POSN_STATUS;
johnb 50:f76b7e7959a2 340 }
johnb 32:af4e495afd62 341
johnb 50:f76b7e7959a2 342 bool XBeeApiCmdAt::processResponseFrame( const uint8_t* const p_data, size_t p_len )
johnb 50:f76b7e7959a2 343 {
johnb 50:f76b7e7959a2 344 bool ret_val = false;
johnb 50:f76b7e7959a2 345 size_t statusPosn = getResponseStatusPos();
johnb 50:f76b7e7959a2 346 size_t dataPosn = statusPosn + 1;
johnb 50:f76b7e7959a2 347
johnb 50:f76b7e7959a2 348 switch( p_data[ XBEE_CMD_POSN_FRAME_ID ] )
johnb 50:f76b7e7959a2 349 {
johnb 51:a7d0d2ef9261 350 case CMD_RESPONSE_SET_WR:
johnb 51:a7d0d2ef9261 351 if( RESPONSE_OK( p_data ))
johnb 51:a7d0d2ef9261 352 {
johnb 51:a7d0d2ef9261 353 m_writeCount++;
johnb 51:a7d0d2ef9261 354 }
johnb 51:a7d0d2ef9261 355 ret_val = true;
johnb 51:a7d0d2ef9261 356 break;
johnb 51:a7d0d2ef9261 357 case CMD_RESPONSE_SET_AC:
johnb 51:a7d0d2ef9261 358 if( RESPONSE_OK( p_data ))
johnb 51:a7d0d2ef9261 359 {
johnb 51:a7d0d2ef9261 360 m_applyCount++;
johnb 51:a7d0d2ef9261 361 }
johnb 51:a7d0d2ef9261 362 ret_val = true;
johnb 51:a7d0d2ef9261 363 break;
johnb 51:a7d0d2ef9261 364 case CMD_RESPONSE_SET_FR:
johnb 51:a7d0d2ef9261 365 if( RESPONSE_OK( p_data ))
johnb 51:a7d0d2ef9261 366 {
johnb 51:a7d0d2ef9261 367 m_resetCount++;
johnb 51:a7d0d2ef9261 368 }
johnb 51:a7d0d2ef9261 369 ret_val = true;
johnb 51:a7d0d2ef9261 370 break;
johnb 51:a7d0d2ef9261 371 case CMD_RESPONSE_SET_IS:
johnb 51:a7d0d2ef9261 372 if( RESPONSE_OK( p_data ))
johnb 51:a7d0d2ef9261 373 {
johnb 51:a7d0d2ef9261 374 m_sampleCount++;
johnb 51:a7d0d2ef9261 375 }
johnb 51:a7d0d2ef9261 376 ret_val = true;
johnb 51:a7d0d2ef9261 377 break;
johnb 50:f76b7e7959a2 378 PROCESS_GET_RESPONSE_16BIT( HV, hwVer )
johnb 50:f76b7e7959a2 379 PROCESS_GET_RESPONSE_16BIT( VR, fwVer )
johnb 50:f76b7e7959a2 380
johnb 50:f76b7e7959a2 381 PROCESS_SET_GET_RESPONSE_8BIT( CH, chan )
johnb 50:f76b7e7959a2 382 PROCESS_SET_GET_RESPONSE_8BIT( CE, CE )
johnb 50:f76b7e7959a2 383 PROCESS_SET_GET_RESPONSE_16BIT( PID, PANId )
johnb 50:f76b7e7959a2 384 PROCESS_SET_GET_RESPONSE_8BIT( EDA, EDA )
johnb 50:f76b7e7959a2 385 PROCESS_SET_GET_RESPONSE_8BIT( RR, retries )
johnb 50:f76b7e7959a2 386 PROCESS_SET_GET_RESPONSE_16BIT( MY, sourceAddress )
johnb 50:f76b7e7959a2 387 PROCESS_GET_RESPONSE_32BIT( SH, snHigh )
johnb 50:f76b7e7959a2 388 PROCESS_GET_RESPONSE_32BIT( SL, snLow )
johnb 51:a7d0d2ef9261 389 PROCESS_SET_GET_RESPONSE_32BIT( DH, destHigh )
johnb 51:a7d0d2ef9261 390 PROCESS_SET_GET_RESPONSE_32BIT( DL, destLow )
johnb 50:f76b7e7959a2 391 PROCESS_SET_GET_RESPONSE_8BIT( RN, randomDelaySlots )
johnb 51:a7d0d2ef9261 392 PROCESS_SET_GET_RESPONSE_8BIT_WITHCAST( MM, macMode, XBeeApiMACMode_e, )
johnb 50:f76b7e7959a2 393 /* TODO: Add D0, D1, D2 response handling */
johnb 51:a7d0d2ef9261 394 PROCESS_SET_GET_RESPONSE_8BIT_WITHCAST( D0, d, XBeeApiDioConfig_e, [0] )
johnb 51:a7d0d2ef9261 395 PROCESS_SET_GET_RESPONSE_8BIT( IC, dioChangeDetectMask )
johnb 51:a7d0d2ef9261 396 PROCESS_SET_RESPONSE( IO, dioLevels )
johnb 51:a7d0d2ef9261 397 PROCESS_SET_GET_RESPONSE_16BIT( IR, sampleRate )
johnb 50:f76b7e7959a2 398 }
johnb 32:af4e495afd62 399
johnb 50:f76b7e7959a2 400 return ret_val;
johnb 50:f76b7e7959a2 401 }
johnb 32:af4e495afd62 402
johnb 52:0950b05d5270 403 #define DIO_CHANNEL_MASK (0x01FFU)
johnb 52:0950b05d5270 404 #define ADC_CHANNEL_MASK (0x7E00U)
johnb 52:0950b05d5270 405
johnb 52:0950b05d5270 406 bool XBeeApiCmdAt::processIOFrame( const uint8_t* const p_data, size_t p_len, const size_t p_start )
johnb 52:0950b05d5270 407 {
johnb 52:0950b05d5270 408 #if 0
johnb 52:0950b05d5270 409 /* This is the number of sample sets that are contained in the packet, set using the IT AT command */
johnb 52:0950b05d5270 410 uint8_t sampleCount = p_data[ p_start ];
johnb 52:0950b05d5270 411 #endif
johnb 52:0950b05d5270 412
johnb 52:0950b05d5270 413 uint16_t channelMask = (((uint16_t)p_data[ p_start + 1 ]) << 8) |
johnb 52:0950b05d5270 414 ((uint16_t)p_data[ p_start + 2 ]);
johnb 52:0950b05d5270 415 const uint8_t* dataPtr = &( p_data[ p_start + 3 ] );
johnb 52:0950b05d5270 416 const uint16_t dioMask = channelMask & DIO_CHANNEL_MASK;
johnb 52:0950b05d5270 417 uint16_t adcMask = (channelMask & ADC_CHANNEL_MASK) >> 9U;
johnb 52:0950b05d5270 418 uint8_t adc = 0;
johnb 52:0950b05d5270 419
johnb 52:0950b05d5270 420 time_t seconds = time( NULL );
johnb 52:0950b05d5270 421
johnb 52:0950b05d5270 422 if( dioMask )
johnb 52:0950b05d5270 423 {
johnb 52:0950b05d5270 424 uint16_t dioData = (((uint16_t)dataPtr[ 0 ]) << 8U) |
johnb 52:0950b05d5270 425 (uint16_t)dataPtr[ 1 ];
johnb 52:0950b05d5270 426 dataPtr += 2;
johnb 52:0950b05d5270 427
johnb 52:0950b05d5270 428 for( unsigned i = 0;
johnb 52:0950b05d5270 429 i < XBEE_API_DIO_CHANNEL_COUNT;
johnb 52:0950b05d5270 430 i++ )
johnb 52:0950b05d5270 431 {
johnb 52:0950b05d5270 432 if(( dioMask >> i ) & 0x01 )
johnb 52:0950b05d5270 433 {
johnb 52:0950b05d5270 434 m_ioDigitalState[i] = ( dioData >> i ) & 0x01;
johnb 52:0950b05d5270 435 m_ioDigitalUpdatedTime[i] = seconds;
johnb 52:0950b05d5270 436 }
johnb 52:0950b05d5270 437 }
johnb 52:0950b05d5270 438 }
johnb 52:0950b05d5270 439
johnb 52:0950b05d5270 440 while( adcMask )
johnb 52:0950b05d5270 441 {
johnb 52:0950b05d5270 442 if( adcMask & 0x01 )
johnb 52:0950b05d5270 443 {
johnb 52:0950b05d5270 444 uint16_t adcData = (((uint16_t)dataPtr[ 0 ]) << 8U) |
johnb 52:0950b05d5270 445 (uint16_t)dataPtr[ 1 ];
johnb 52:0950b05d5270 446 dataPtr += 2;
johnb 52:0950b05d5270 447
johnb 52:0950b05d5270 448 m_ioAnalogueVal[adc] = adcData;
johnb 52:0950b05d5270 449 m_ioAnalogueUpdatedTime[adc] = seconds;
johnb 52:0950b05d5270 450 }
johnb 52:0950b05d5270 451 adcMask = adcMask >> 1U;
johnb 52:0950b05d5270 452 adc++;
johnb 52:0950b05d5270 453 }
johnb 52:0950b05d5270 454
johnb 52:0950b05d5270 455 return true;
johnb 52:0950b05d5270 456 }
johnb 52:0950b05d5270 457
johnb 52:0950b05d5270 458 #define XBEE_IO_PACKET_ADDRESS (XBEE_CMD_POSN_ID_SPECIFIC_DATA)
johnb 52:0950b05d5270 459 #define XBEE_IO_PACKET_64BIT_DATA_START (XBEE_IO_PACKET_ADDRESS + sizeof( uint64_t) + 1U + 1U)
johnb 52:0950b05d5270 460 #define XBEE_IO_PACKET_16BIT_DATA_START (XBEE_IO_PACKET_ADDRESS + sizeof( uint16_t) + 1U + 1U)
johnb 52:0950b05d5270 461
johnb 8:1b48b619d7f6 462 bool XBeeApiCmdAt::decodeCallback( const uint8_t* const p_data, size_t p_len )
johnb 8:1b48b619d7f6 463 {
johnb 8:1b48b619d7f6 464 bool ret_val = false;
johnb 13:302e7c1ea0b3 465
johnb 50:f76b7e7959a2 466 if( XBEE_CMD_AT_RESPONSE == p_data[ XBEE_CMD_POSN_API_ID ] )
johnb 50:f76b7e7959a2 467 {
johnb 50:f76b7e7959a2 468 ret_val = processResponseFrame( p_data, p_len );
johnb 52:0950b05d5270 469 }
johnb 52:0950b05d5270 470 else if( XBEE_CMD_RX_16B_IO == p_data[ XBEE_CMD_POSN_API_ID ] )
johnb 52:0950b05d5270 471 {
johnb 52:0950b05d5270 472 uint16_t src16BitAddr = (((uint16_t)p_data[ XBEE_IO_PACKET_ADDRESS ]) << 8U) |
johnb 52:0950b05d5270 473 p_data[ XBEE_IO_PACKET_ADDRESS + 1 ];
johnb 52:0950b05d5270 474 if( m_have_sourceAddress &&
johnb 52:0950b05d5270 475 ( src16BitAddr == m_sourceAddress ))
johnb 52:0950b05d5270 476 {
johnb 52:0950b05d5270 477 ret_val = processIOFrame( p_data, p_len, XBEE_IO_PACKET_16BIT_DATA_START );
johnb 52:0950b05d5270 478 }
johnb 8:1b48b619d7f6 479 }
johnb 52:0950b05d5270 480 else if( XBEE_CMD_RX_64B_IO == p_data[ XBEE_CMD_POSN_API_ID ] )
johnb 52:0950b05d5270 481 {
johnb 52:0950b05d5270 482 uint32_t srcAddrHigh = (((uint64_t)p_data[ XBEE_IO_PACKET_ADDRESS ]) << 24U) |
johnb 52:0950b05d5270 483 (((uint64_t)p_data[ XBEE_IO_PACKET_ADDRESS + 1 ]) << 16U) |
johnb 52:0950b05d5270 484 (((uint64_t)p_data[ XBEE_IO_PACKET_ADDRESS + 2 ]) << 8U) |
johnb 52:0950b05d5270 485 (((uint64_t)p_data[ XBEE_IO_PACKET_ADDRESS + 3 ]));
johnb 52:0950b05d5270 486 uint32_t srcAddrLow = (((uint64_t)p_data[ XBEE_IO_PACKET_ADDRESS + 4 ]) << 24U) |
johnb 52:0950b05d5270 487 (((uint64_t)p_data[ XBEE_IO_PACKET_ADDRESS + 5 ]) << 16U) |
johnb 52:0950b05d5270 488 (((uint64_t)p_data[ XBEE_IO_PACKET_ADDRESS + 6 ]) << 8U) |
johnb 52:0950b05d5270 489 ((uint64_t)p_data[ XBEE_IO_PACKET_ADDRESS + 7 ]);
johnb 52:0950b05d5270 490 if( m_have_snLow &&
johnb 52:0950b05d5270 491 m_have_snHigh &&
johnb 52:0950b05d5270 492 ( srcAddrHigh == m_snHigh ) &&
johnb 52:0950b05d5270 493 ( srcAddrLow == m_snLow ))
johnb 52:0950b05d5270 494 {
johnb 52:0950b05d5270 495 ret_val = processIOFrame( p_data, p_len, XBEE_IO_PACKET_64BIT_DATA_START );
johnb 52:0950b05d5270 496 }
johnb 52:0950b05d5270 497 }
johnb 52:0950b05d5270 498 else
johnb 52:0950b05d5270 499 {
johnb 52:0950b05d5270 500 }
johnb 52:0950b05d5270 501
johnb 8:1b48b619d7f6 502 return ret_val;
johnb 8:1b48b619d7f6 503 }
johnb 8:1b48b619d7f6 504
johnb 8:1b48b619d7f6 505 bool XBeeApiCmdAt::setChannel( uint8_t const p_chan )
johnb 8:1b48b619d7f6 506 {
johnb 29:c6d037cceb02 507 bool ret_val = false;
johnb 29:c6d037cceb02 508
johnb 29:c6d037cceb02 509 if((( m_device->getXBeeModel() == XBeeDevice::XBEEDEVICE_S1 ) &&
johnb 29:c6d037cceb02 510 ( p_chan >= XBEE_CHAN_MIN ) &&
johnb 29:c6d037cceb02 511 ( p_chan <= XBEE_CHAN_MAX )) ||
johnb 29:c6d037cceb02 512 (( m_device->getXBeeModel() == XBeeDevice::XBEEDEVICE_S1_PRO ) &&
johnb 29:c6d037cceb02 513 ( p_chan >= XBEE_PRO_CHAN_MIN ) &&
johnb 29:c6d037cceb02 514 ( p_chan <= XBEE_PRO_CHAN_MAX )))
johnb 29:c6d037cceb02 515 {
johnb 29:c6d037cceb02 516 m_chanPend = p_chan;
johnb 50:f76b7e7959a2 517 SendCmd_uint8_t( cmd_ch_set_fid, cmd_ch_set, p_chan );
johnb 29:c6d037cceb02 518 ret_val = true;
johnb 29:c6d037cceb02 519 }
johnb 29:c6d037cceb02 520 return ret_val;
johnb 8:1b48b619d7f6 521 }
johnb 8:1b48b619d7f6 522
johnb 50:f76b7e7959a2 523 void XBeeApiCmdAt::SendReq( const uint8_t p_frameId,
johnb 50:f76b7e7959a2 524 const uint8_t* p_data )
johnb 50:f76b7e7959a2 525 {
johnb 50:f76b7e7959a2 526 XBeeApiCmdAtReq req( p_frameId, p_data );
johnb 50:f76b7e7959a2 527 m_device->SendFrame( &req );
johnb 50:f76b7e7959a2 528 }
johnb 50:f76b7e7959a2 529
johnb 50:f76b7e7959a2 530
johnb 31:c144106e55b5 531 #define MAKE_REQUEST( _name, _mnemonic, _cmd ) \
johnb 31:c144106e55b5 532 bool XBeeApiCmdAt::request ## _name( void ) \
johnb 31:c144106e55b5 533 {\
johnb 50:f76b7e7959a2 534 m_have_ ## _mnemonic = false; \
johnb 50:f76b7e7959a2 535 SendReq( _cmd ## _get_fid, _cmd ); \
johnb 31:c144106e55b5 536 return true;\
johnb 8:1b48b619d7f6 537 }
johnb 8:1b48b619d7f6 538
johnb 51:a7d0d2ef9261 539 MAKE_REQUEST( HardwareVersion, hwVer, cmd_hv )
johnb 51:a7d0d2ef9261 540 MAKE_REQUEST( FirmwareVersion, fwVer, cmd_vr )
johnb 51:a7d0d2ef9261 541 MAKE_REQUEST( Channel, chan, cmd_ch )
johnb 51:a7d0d2ef9261 542 MAKE_REQUEST( PanId, PANId, cmd_pid )
johnb 51:a7d0d2ef9261 543 MAKE_REQUEST( CoordinatorEnabled, CE, cmd_ce )
johnb 51:a7d0d2ef9261 544 MAKE_REQUEST( EndDeviceAssociationEnabled, EDA, cmd_eda )
johnb 51:a7d0d2ef9261 545 MAKE_REQUEST( SourceAddress, sourceAddress, cmd_my )
johnb 51:a7d0d2ef9261 546 MAKE_REQUEST( Retries, retries, cmd_rr )
johnb 51:a7d0d2ef9261 547 MAKE_REQUEST( RandomDelaySlots, randomDelaySlots, cmd_rn )
johnb 51:a7d0d2ef9261 548 MAKE_REQUEST( MacMode, macMode, cmd_mm )
johnb 51:a7d0d2ef9261 549 MAKE_REQUEST( SerialNumberHigh, snHigh, cmd_sh )
johnb 51:a7d0d2ef9261 550 MAKE_REQUEST( SerialNumberLow, snLow, cmd_sl )
johnb 51:a7d0d2ef9261 551 MAKE_REQUEST( DioChangeDetectMask, dioChangeDetectMask, cmd_ic )
johnb 51:a7d0d2ef9261 552 MAKE_REQUEST( SampleRate, sampleRate, cmd_ir )
johnb 51:a7d0d2ef9261 553 MAKE_REQUEST( DestinationAddressHigh, destHigh, cmd_dh )
johnb 51:a7d0d2ef9261 554 MAKE_REQUEST( DestinationAddressLow, destLow, cmd_dl )
johnb 51:a7d0d2ef9261 555
johnb 51:a7d0d2ef9261 556 bool XBeeApiCmdAt::requestWriteSettings( void )
johnb 51:a7d0d2ef9261 557 {
johnb 51:a7d0d2ef9261 558 SendReq( cmd_wr_set_fid, cmd_wr );
johnb 51:a7d0d2ef9261 559 return true;
johnb 51:a7d0d2ef9261 560 }
johnb 51:a7d0d2ef9261 561
johnb 51:a7d0d2ef9261 562 bool XBeeApiCmdAt::requestApplyChanges( void )
johnb 51:a7d0d2ef9261 563 {
johnb 51:a7d0d2ef9261 564 SendReq( cmd_ac_set_fid, cmd_ac );
johnb 51:a7d0d2ef9261 565 return true;
johnb 51:a7d0d2ef9261 566 }
johnb 51:a7d0d2ef9261 567
johnb 51:a7d0d2ef9261 568 bool XBeeApiCmdAt::requestReset( void )
johnb 51:a7d0d2ef9261 569 {
johnb 51:a7d0d2ef9261 570 SendReq( cmd_fr_set_fid, cmd_fr );
johnb 51:a7d0d2ef9261 571 return true;
johnb 51:a7d0d2ef9261 572 }
johnb 51:a7d0d2ef9261 573
johnb 51:a7d0d2ef9261 574 bool XBeeApiCmdAt::requestForceSample( void )
johnb 51:a7d0d2ef9261 575 {
johnb 51:a7d0d2ef9261 576 SendReq( cmd_is_set_fid, cmd_is );
johnb 51:a7d0d2ef9261 577 return true;
johnb 51:a7d0d2ef9261 578 }
johnb 32:af4e495afd62 579
johnb 32:af4e495afd62 580 bool XBeeApiCmdAt::requestSerialNumber( void )
johnb 32:af4e495afd62 581 {
johnb 50:f76b7e7959a2 582 requestSerialNumberHigh();
johnb 50:f76b7e7959a2 583 requestSerialNumberLow();
johnb 32:af4e495afd62 584 return true;
johnb 32:af4e495afd62 585 }
johnb 8:1b48b619d7f6 586
johnb 51:a7d0d2ef9261 587 bool XBeeApiCmdAt::requestDestinationAddress( void )
johnb 51:a7d0d2ef9261 588 {
johnb 51:a7d0d2ef9261 589 requestDestinationAddressHigh();
johnb 51:a7d0d2ef9261 590 requestDestinationAddressLow();
johnb 51:a7d0d2ef9261 591 return true;
johnb 51:a7d0d2ef9261 592 }
johnb 51:a7d0d2ef9261 593
johnb 50:f76b7e7959a2 594 bool XBeeApiCmdAt::requestDioConfig( const uint8_t p_chanNo )
johnb 50:f76b7e7959a2 595 {
johnb 50:f76b7e7959a2 596 bool ret_val = false;
johnb 50:f76b7e7959a2 597 if( p_chanNo < XBEE_API_DIO_CHANNEL_COUNT )
johnb 50:f76b7e7959a2 598 {
johnb 50:f76b7e7959a2 599 m_have_d[ p_chanNo ] = false;
johnb 50:f76b7e7959a2 600 SendReq( cmd_d_get_fid[ p_chanNo ], cmd_d[ p_chanNo ] );
johnb 50:f76b7e7959a2 601 ret_val = true;
johnb 50:f76b7e7959a2 602 }
johnb 50:f76b7e7959a2 603 return ret_val;
johnb 50:f76b7e7959a2 604 }
johnb 50:f76b7e7959a2 605
johnb 52:0950b05d5270 606 time_t XBeeApiCmdAt::getDigitalState( const uint8_t p_chanNo, bool& p_state )
johnb 52:0950b05d5270 607 {
johnb 52:0950b05d5270 608 time_t ret_val = 0;
johnb 52:0950b05d5270 609 if( p_chanNo < XBEE_API_DIO_CHANNEL_COUNT )
johnb 52:0950b05d5270 610 {
johnb 52:0950b05d5270 611 p_state = m_ioDigitalState[ p_chanNo ];
johnb 52:0950b05d5270 612 ret_val = m_ioDigitalUpdatedTime[ p_chanNo ];
johnb 52:0950b05d5270 613 }
johnb 52:0950b05d5270 614 return ret_val;
johnb 52:0950b05d5270 615 }
johnb 52:0950b05d5270 616
johnb 52:0950b05d5270 617 time_t XBeeApiCmdAt::getAnalogueValue( const uint8_t p_chanNo, uint16_t& p_val )
johnb 52:0950b05d5270 618 {
johnb 52:0950b05d5270 619 time_t ret_val = 0;
johnb 52:0950b05d5270 620 if( p_chanNo < XBEE_API_ADC_CHANNEL_COUNT )
johnb 52:0950b05d5270 621 {
johnb 52:0950b05d5270 622 p_val = m_ioAnalogueVal[ p_chanNo ];
johnb 52:0950b05d5270 623 ret_val = m_ioAnalogueUpdatedTime[ p_chanNo ];
johnb 52:0950b05d5270 624 }
johnb 52:0950b05d5270 625 return ret_val;
johnb 52:0950b05d5270 626 }
johnb 50:f76b7e7959a2 627
johnb 31:c144106e55b5 628 #define MAKE_GET(_name, _mnemonic, _type ) \
johnb 31:c144106e55b5 629 bool XBeeApiCmdAt::get ## _name( _type* const p_param ) \
johnb 31:c144106e55b5 630 {\
johnb 31:c144106e55b5 631 if( m_have_ ## _mnemonic ) {\
johnb 31:c144106e55b5 632 *p_param = m_ ## _mnemonic;\
johnb 31:c144106e55b5 633 } \
johnb 31:c144106e55b5 634 return m_have_ ## _mnemonic; \
johnb 13:302e7c1ea0b3 635 }
johnb 13:302e7c1ea0b3 636
johnb 51:a7d0d2ef9261 637 MAKE_GET( FirmwareVersion, fwVer, uint16_t )
johnb 51:a7d0d2ef9261 638 MAKE_GET( HardwareVersion, hwVer, uint16_t )
johnb 51:a7d0d2ef9261 639 MAKE_GET( Channel, chan, uint8_t )
johnb 51:a7d0d2ef9261 640 MAKE_GET( CoordinatorEnabled, CE, bool )
johnb 51:a7d0d2ef9261 641 MAKE_GET( EndDeviceAssociationEnabled, EDA, bool )
johnb 51:a7d0d2ef9261 642 MAKE_GET( PanId, PANId, panId_t )
johnb 51:a7d0d2ef9261 643 MAKE_GET( SourceAddress, sourceAddress, uint16_t )
johnb 51:a7d0d2ef9261 644 MAKE_GET( Retries, retries, uint8_t )
johnb 51:a7d0d2ef9261 645 MAKE_GET( RandomDelaySlots, randomDelaySlots, uint8_t )
johnb 51:a7d0d2ef9261 646 MAKE_GET( MacMode, macMode, XBeeApiMACMode_e )
johnb 51:a7d0d2ef9261 647 MAKE_GET( DioChangeDetectMask, dioChangeDetectMask, uint8_t )
johnb 51:a7d0d2ef9261 648 MAKE_GET( DioLevels, dioLevels, uint8_t )
johnb 51:a7d0d2ef9261 649 MAKE_GET( SampleRate, sampleRate, uint16_t )
johnb 51:a7d0d2ef9261 650 MAKE_GET( DestinationAddressHigh, destHigh, uint32_t )
johnb 51:a7d0d2ef9261 651 MAKE_GET( DestinationAddressLow, destLow, uint32_t )
johnb 32:af4e495afd62 652
johnb 32:af4e495afd62 653 bool XBeeApiCmdAt::getSerialNumber( uint64_t* const p_sn )
johnb 32:af4e495afd62 654 {
johnb 32:af4e495afd62 655 /* Need both halves to have the complete serial number */
johnb 32:af4e495afd62 656 bool have_sn = m_have_snLow && m_have_snHigh;
johnb 32:af4e495afd62 657 if( have_sn )
johnb 32:af4e495afd62 658 {
johnb 32:af4e495afd62 659 *p_sn = m_snHigh;
johnb 32:af4e495afd62 660 *p_sn = *p_sn << 32U;
johnb 32:af4e495afd62 661 *p_sn |= m_snLow;
johnb 32:af4e495afd62 662 }
johnb 32:af4e495afd62 663 return( have_sn );
johnb 32:af4e495afd62 664 }
johnb 25:db6874b7ac4b 665
johnb 51:a7d0d2ef9261 666 bool XBeeApiCmdAt::getDestinationAddress( uint64_t* const p_addr )
johnb 51:a7d0d2ef9261 667 {
johnb 51:a7d0d2ef9261 668 bool have_da = m_have_destLow && m_have_destHigh;
johnb 51:a7d0d2ef9261 669 if( have_da )
johnb 51:a7d0d2ef9261 670 {
johnb 51:a7d0d2ef9261 671 *p_addr = m_destHigh;
johnb 51:a7d0d2ef9261 672 *p_addr = *p_addr << 32U;
johnb 51:a7d0d2ef9261 673 *p_addr |= m_destLow;
johnb 51:a7d0d2ef9261 674 }
johnb 51:a7d0d2ef9261 675 return( have_da );
johnb 51:a7d0d2ef9261 676
johnb 51:a7d0d2ef9261 677 }
johnb 51:a7d0d2ef9261 678
johnb 50:f76b7e7959a2 679 bool XBeeApiCmdAt::getDioConfig( const uint8_t p_chanNo, XBeeApiDioConfig_e* const p_conf )
johnb 50:f76b7e7959a2 680 {
johnb 50:f76b7e7959a2 681 bool ret_val = false;
johnb 50:f76b7e7959a2 682 if( p_chanNo < XBEE_API_DIO_CHANNEL_COUNT )
johnb 50:f76b7e7959a2 683 {
johnb 50:f76b7e7959a2 684 if( m_have_d[ p_chanNo ] )
johnb 50:f76b7e7959a2 685 {
johnb 50:f76b7e7959a2 686 *p_conf = m_d[ p_chanNo ];
johnb 50:f76b7e7959a2 687 ret_val = true;
johnb 50:f76b7e7959a2 688 }
johnb 50:f76b7e7959a2 689 }
johnb 50:f76b7e7959a2 690 return ret_val;
johnb 50:f76b7e7959a2 691 }
johnb 50:f76b7e7959a2 692
johnb 50:f76b7e7959a2 693 #define MAKE_SET( _name, _mnemonic, _cmd, _type, _transmit_type ) \
johnb 31:c144106e55b5 694 bool XBeeApiCmdAt::set ## _name( const _type p_param ) \
johnb 31:c144106e55b5 695 {\
johnb 31:c144106e55b5 696 m_have_ ## _mnemonic = false;\
johnb 31:c144106e55b5 697 m_## _mnemonic ## Pend = p_param;\
johnb 50:f76b7e7959a2 698 SendCmd_ ## _transmit_type ( _cmd ## _fid, _cmd, p_param ); \
johnb 31:c144106e55b5 699 return true;\
johnb 13:302e7c1ea0b3 700 }
johnb 13:302e7c1ea0b3 701
johnb 51:a7d0d2ef9261 702 MAKE_SET( CoordinatorEnabled, CE, cmd_ce_set, bool, uint8_t )
johnb 51:a7d0d2ef9261 703 MAKE_SET( EndDeviceAssociationEnabled, EDA, cmd_eda_set, bool, uint8_t )
johnb 51:a7d0d2ef9261 704 MAKE_SET( PanId, PANId, cmd_pid_set, uint16_t, uint16_t )
johnb 51:a7d0d2ef9261 705 MAKE_SET( SourceAddress, sourceAddress, cmd_my_set, uint16_t, uint16_t )
johnb 51:a7d0d2ef9261 706 MAKE_SET( Retries, retries, cmd_rr_set, uint8_t, uint16_t )
johnb 51:a7d0d2ef9261 707 MAKE_SET( RandomDelaySlots, randomDelaySlots, cmd_rn_set, uint8_t, uint16_t )
johnb 51:a7d0d2ef9261 708 MAKE_SET( MacMode, macMode, cmd_mm_set, XBeeApiMACMode_e, uint8_t )
johnb 51:a7d0d2ef9261 709 MAKE_SET( DioChangeDetectMask, dioChangeDetectMask, cmd_ic_set, uint8_t, uint8_t )
johnb 51:a7d0d2ef9261 710 MAKE_SET( DioLevels, dioLevels, cmd_io_set, uint8_t, uint8_t )
johnb 51:a7d0d2ef9261 711 MAKE_SET( SampleRate, sampleRate, cmd_ir_set, uint16_t, uint16_t )
johnb 51:a7d0d2ef9261 712 MAKE_SET( DestinationAddressHigh, destHigh, cmd_dh_set, uint32_t, uint32_t )
johnb 51:a7d0d2ef9261 713 MAKE_SET( DestinationAddressLow, destLow, cmd_dl_set, uint32_t, uint32_t )
johnb 50:f76b7e7959a2 714
johnb 50:f76b7e7959a2 715
johnb 50:f76b7e7959a2 716 bool XBeeApiCmdAt::setDioConfig( const uint8_t p_chanNo, const XBeeApiDioConfig_e p_conf )
johnb 50:f76b7e7959a2 717 {
johnb 50:f76b7e7959a2 718 bool ret_val = false;
johnb 50:f76b7e7959a2 719 if( p_chanNo < XBEE_API_DIO_CHANNEL_COUNT )
johnb 50:f76b7e7959a2 720 {
johnb 51:a7d0d2ef9261 721 /* TODO: Add check that p_conf is valid for this channel */
johnb 50:f76b7e7959a2 722 m_have_d[ p_chanNo ] = false;
johnb 50:f76b7e7959a2 723 m_dPend[ p_chanNo ] = p_conf;
johnb 50:f76b7e7959a2 724 SendCmd_uint8_t( cmd_d_get_fid[ p_chanNo ], cmd_d[ p_chanNo ], p_conf );
johnb 50:f76b7e7959a2 725 }
johnb 50:f76b7e7959a2 726 return ret_val;
johnb 50:f76b7e7959a2 727 }
johnb 50:f76b7e7959a2 728
johnb 51:a7d0d2ef9261 729 bool XBeeApiCmdAt::setDestinationAddress( const uint64_t p_addr )
johnb 51:a7d0d2ef9261 730 {
johnb 51:a7d0d2ef9261 731 m_have_destHigh = m_have_destLow = false;
johnb 51:a7d0d2ef9261 732
johnb 51:a7d0d2ef9261 733 setDestinationAddressHigh( p_addr >> 32U );
johnb 51:a7d0d2ef9261 734 setDestinationAddressLow( p_addr );
johnb 51:a7d0d2ef9261 735
johnb 51:a7d0d2ef9261 736 return true;
johnb 51:a7d0d2ef9261 737 }
johnb 51:a7d0d2ef9261 738
johnb 51:a7d0d2ef9261 739
johnb 51:a7d0d2ef9261 740
johnb 50:f76b7e7959a2 741 void XBeeApiCmdAt::SendCmd_uint8_t( const uint8_t p_frameId,
johnb 50:f76b7e7959a2 742 const uint8_t* const p_data,
johnb 50:f76b7e7959a2 743 const uint8_t& p_val )
johnb 50:f76b7e7959a2 744 {
johnb 50:f76b7e7959a2 745 XBeeApiCmdAtSet<uint8_t> req( p_frameId, p_data, p_val );
johnb 50:f76b7e7959a2 746 m_device->SendFrame( &req );
johnb 50:f76b7e7959a2 747 }
johnb 50:f76b7e7959a2 748
johnb 50:f76b7e7959a2 749 void XBeeApiCmdAt::SendCmd_uint16_t( const uint8_t p_frameId,
johnb 50:f76b7e7959a2 750 const uint8_t* const p_data,
johnb 50:f76b7e7959a2 751 const uint16_t& p_val )
johnb 50:f76b7e7959a2 752 {
johnb 50:f76b7e7959a2 753 XBeeApiCmdAtSet<uint16_t> req( p_frameId, p_data, p_val );
johnb 50:f76b7e7959a2 754 m_device->SendFrame( &req );
johnb 50:f76b7e7959a2 755 }
johnb 13:302e7c1ea0b3 756
johnb 51:a7d0d2ef9261 757 void XBeeApiCmdAt::SendCmd_uint32_t( const uint8_t p_frameId,
johnb 51:a7d0d2ef9261 758 const uint8_t* const p_data,
johnb 51:a7d0d2ef9261 759 const uint32_t& p_val )
johnb 8:1b48b619d7f6 760 {
johnb 51:a7d0d2ef9261 761 XBeeApiCmdAtSet<uint32_t> req( p_frameId, p_data, p_val );
johnb 51:a7d0d2ef9261 762 m_device->SendFrame( &req );
johnb 50:f76b7e7959a2 763 }
johnb 31:c144106e55b5 764
johnb 25:db6874b7ac4b 765 template < typename T >
johnb 50:f76b7e7959a2 766 XBeeApiCmdAtSet<T>::XBeeApiCmdAtSet( const uint8_t p_frameId,
johnb 50:f76b7e7959a2 767 const uint8_t* const p_data,
johnb 50:f76b7e7959a2 768 const T p_val ) : XBeeApiFrame( )
johnb 8:1b48b619d7f6 769 {
johnb 25:db6874b7ac4b 770 size_t s;
johnb 25:db6874b7ac4b 771 uint8_t* dest;
johnb 25:db6874b7ac4b 772 const uint8_t* src = (uint8_t*)(&p_val);
johnb 25:db6874b7ac4b 773
johnb 13:302e7c1ea0b3 774 m_apiId = XBEE_CMD_AT_CMD;
johnb 25:db6874b7ac4b 775
johnb 50:f76b7e7959a2 776 m_buffer[0] = p_frameId;
johnb 50:f76b7e7959a2 777 m_buffer[1] = p_data[0];
johnb 50:f76b7e7959a2 778 m_buffer[2] = p_data[1];
johnb 25:db6874b7ac4b 779
johnb 36:cc7e8d1e35dd 780 m_dataLen = sizeof( m_buffer );
johnb 36:cc7e8d1e35dd 781
johnb 36:cc7e8d1e35dd 782 /* TODO: This copy code isn't portable - it's assuming that the data in
johnb 36:cc7e8d1e35dd 783 * p_data is little endian */
johnb 36:cc7e8d1e35dd 784
johnb 36:cc7e8d1e35dd 785 dest = &( m_buffer[ m_dataLen - 1 ] );
johnb 25:db6874b7ac4b 786
johnb 25:db6874b7ac4b 787 for( s = 0;
johnb 25:db6874b7ac4b 788 s < sizeof( T );
johnb 36:cc7e8d1e35dd 789 s++, dest--, src++ ) {
johnb 25:db6874b7ac4b 790 *dest = *src;
johnb 25:db6874b7ac4b 791 }
johnb 25:db6874b7ac4b 792
johnb 50:f76b7e7959a2 793 m_data = m_buffer;
johnb 50:f76b7e7959a2 794 }
johnb 13:302e7c1ea0b3 795
johnb 25:db6874b7ac4b 796 template < typename T >
johnb 50:f76b7e7959a2 797 XBeeApiCmdAtSet<T>::~XBeeApiCmdAtSet()
johnb 50:f76b7e7959a2 798 {
johnb 50:f76b7e7959a2 799 }
johnb 50:f76b7e7959a2 800
johnb 50:f76b7e7959a2 801 XBeeApiCmdAtReq::XBeeApiCmdAtReq( const uint8_t p_frameId,
johnb 50:f76b7e7959a2 802 const uint8_t* const p_data )
johnb 50:f76b7e7959a2 803 {
johnb 50:f76b7e7959a2 804 m_apiId = XBEE_CMD_AT_CMD;
johnb 50:f76b7e7959a2 805
johnb 50:f76b7e7959a2 806 m_buffer[0] = p_frameId;
johnb 50:f76b7e7959a2 807 m_buffer[1] = p_data[0];
johnb 50:f76b7e7959a2 808 m_buffer[2] = p_data[1];
johnb 50:f76b7e7959a2 809
johnb 50:f76b7e7959a2 810 m_dataLen = sizeof( m_buffer );
johnb 50:f76b7e7959a2 811 m_data = m_buffer;
johnb 50:f76b7e7959a2 812 }
johnb 50:f76b7e7959a2 813
johnb 50:f76b7e7959a2 814 XBeeApiCmdAtReq::~XBeeApiCmdAtReq()
johnb 13:302e7c1ea0b3 815 {
johnb 25:db6874b7ac4b 816 }