XBee modules

Dependencies:   DigiLogger

Fork of XBeeLib by Digi International Inc.

Committer:
hbujanda
Date:
Fri Jul 29 12:10:38 2016 +0200
Revision:
8:b5f4a0e92249
Parent:
6:06522f3a6642
Child:
9:780db84ce891
Automatic upload

Who changed what in which revision?

UserRevisionLine numberNew contents of line
spastor 0:fcaad0dfa051 1 /**
spastor 0:fcaad0dfa051 2 * Copyright (c) 2015 Digi International Inc.,
spastor 0:fcaad0dfa051 3 * All rights not expressly granted are reserved.
spastor 0:fcaad0dfa051 4 *
spastor 0:fcaad0dfa051 5 * This Source Code Form is subject to the terms of the Mozilla Public
spastor 0:fcaad0dfa051 6 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
spastor 0:fcaad0dfa051 7 * You can obtain one at http://mozilla.org/MPL/2.0/.
spastor 0:fcaad0dfa051 8 *
spastor 0:fcaad0dfa051 9 * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
spastor 0:fcaad0dfa051 10 * =======================================================================
spastor 0:fcaad0dfa051 11 */
spastor 0:fcaad0dfa051 12 #include "XBee802.h"
spastor 0:fcaad0dfa051 13 #include "IO/IOSample802.h"
spastor 0:fcaad0dfa051 14 #include "Frames/802_Frames.h"
spastor 0:fcaad0dfa051 15 #include "FrameHandlers/FH_ModemStatus.h"
spastor 0:fcaad0dfa051 16
spastor 0:fcaad0dfa051 17 using namespace XBeeLib;
spastor 0:fcaad0dfa051 18
spastor 0:fcaad0dfa051 19 /* Class constructor */
spastor 0:fcaad0dfa051 20 XBee802::XBee802(PinName tx, PinName rx, PinName reset, PinName rts, PinName cts, int baud) :
spastor 0:fcaad0dfa051 21 XBee(tx, rx, reset, rts, cts, baud),
spastor 4:629712865107 22 _nd_handler(NULL), _rx_64b_handler(NULL), _rx_16b_handler(NULL),
spastor 0:fcaad0dfa051 23 _io_data_64b_handler(NULL), _io_data_16b_handler(NULL)
spastor 0:fcaad0dfa051 24 {
spastor 0:fcaad0dfa051 25
spastor 0:fcaad0dfa051 26 }
spastor 0:fcaad0dfa051 27
spastor 0:fcaad0dfa051 28 /* Class destructor */
spastor 0:fcaad0dfa051 29 XBee802::~XBee802()
spastor 0:fcaad0dfa051 30 {
spastor 0:fcaad0dfa051 31 unregister_node_discovery_cb();
spastor 0:fcaad0dfa051 32 unregister_receive_cb();
spastor 0:fcaad0dfa051 33 unregister_io_sample_cb();
spastor 0:fcaad0dfa051 34 }
spastor 0:fcaad0dfa051 35
spastor 0:fcaad0dfa051 36 RadioStatus XBee802::init()
spastor 0:fcaad0dfa051 37 {
spastor 0:fcaad0dfa051 38 RadioStatus retval = XBee::init();
spastor 4:629712865107 39 uint16_t addr16;
spastor 4:629712865107 40 RadioStatus error = get_network_address(&addr16);
spastor 4:629712865107 41 if (error == Success) {
spastor 4:629712865107 42 digi_log(LogLevelInfo, "ADDR16: %04x\r\n", addr16);
spastor 4:629712865107 43 } else {
spastor 4:629712865107 44 digi_log(LogLevelInfo, "ADDR16: UNKNOWN\r\n");
spastor 4:629712865107 45 }
spastor 4:629712865107 46
spastor 0:fcaad0dfa051 47 const RadioProtocol radioProtocol = get_radio_protocol();
spastor 0:fcaad0dfa051 48 if (radioProtocol != Raw_802_15_4) {
spastor 0:fcaad0dfa051 49 digi_log(LogLevelError, "Radio protocol does not match, needed a %d got a %d\r\n", Raw_802_15_4, radioProtocol);
spastor 0:fcaad0dfa051 50 retval = Failure;
spastor 0:fcaad0dfa051 51 }
spastor 0:fcaad0dfa051 52 assert(radioProtocol == Raw_802_15_4);
spastor 0:fcaad0dfa051 53
spastor 0:fcaad0dfa051 54 return retval;
spastor 0:fcaad0dfa051 55 }
spastor 0:fcaad0dfa051 56
spastor 0:fcaad0dfa051 57 RadioStatus XBee802::set_channel(uint8_t channel)
spastor 0:fcaad0dfa051 58 {
spastor 0:fcaad0dfa051 59 AtCmdFrame::AtCmdResp cmdresp;
spastor 0:fcaad0dfa051 60
hbujanda 6:06522f3a6642 61 /* Pro and Non-Pro modules have different channels available. The at
hbujanda 6:06522f3a6642 62 command will return an error if the selected channel is not available */
spastor 0:fcaad0dfa051 63 cmdresp = set_param("CH", channel);
spastor 0:fcaad0dfa051 64 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
spastor 0:fcaad0dfa051 65 return Failure;
spastor 0:fcaad0dfa051 66 }
spastor 0:fcaad0dfa051 67 return Success;
spastor 0:fcaad0dfa051 68 }
spastor 0:fcaad0dfa051 69
spastor 0:fcaad0dfa051 70 RadioStatus XBee802::get_channel(uint8_t * const channel)
spastor 0:fcaad0dfa051 71 {
spastor 0:fcaad0dfa051 72 if (channel == NULL) {
spastor 0:fcaad0dfa051 73 return Failure;
spastor 0:fcaad0dfa051 74 }
spastor 0:fcaad0dfa051 75 AtCmdFrame::AtCmdResp cmdresp;
spastor 0:fcaad0dfa051 76
spastor 0:fcaad0dfa051 77 uint32_t var32;
spastor 0:fcaad0dfa051 78 cmdresp = get_param("CH", &var32);
spastor 4:629712865107 79 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
spastor 0:fcaad0dfa051 80 return Failure;
spastor 4:629712865107 81 }
spastor 0:fcaad0dfa051 82 *channel = var32;
spastor 0:fcaad0dfa051 83 return Success;
spastor 0:fcaad0dfa051 84 }
spastor 0:fcaad0dfa051 85
spastor 0:fcaad0dfa051 86 RadioStatus XBee802::set_panid(uint16_t panid)
spastor 0:fcaad0dfa051 87 {
spastor 0:fcaad0dfa051 88 AtCmdFrame::AtCmdResp cmdresp;
spastor 0:fcaad0dfa051 89
spastor 0:fcaad0dfa051 90 cmdresp = set_param("ID", panid);
spastor 0:fcaad0dfa051 91 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
spastor 0:fcaad0dfa051 92 return Failure;
spastor 0:fcaad0dfa051 93 }
spastor 0:fcaad0dfa051 94 return Success;
spastor 0:fcaad0dfa051 95 }
spastor 0:fcaad0dfa051 96
spastor 0:fcaad0dfa051 97 RadioStatus XBee802::get_panid(uint16_t * const panid)
spastor 0:fcaad0dfa051 98 {
spastor 0:fcaad0dfa051 99 if (panid == NULL) {
spastor 0:fcaad0dfa051 100 return Failure;
spastor 0:fcaad0dfa051 101 }
spastor 0:fcaad0dfa051 102 AtCmdFrame::AtCmdResp cmdresp;
spastor 0:fcaad0dfa051 103
spastor 0:fcaad0dfa051 104 uint32_t var32;
spastor 0:fcaad0dfa051 105 cmdresp = get_param("ID", &var32);
spastor 4:629712865107 106 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
spastor 0:fcaad0dfa051 107 return Failure;
spastor 4:629712865107 108 }
spastor 0:fcaad0dfa051 109 *panid = var32;
spastor 0:fcaad0dfa051 110 return Success;
spastor 0:fcaad0dfa051 111 }
spastor 0:fcaad0dfa051 112
hbujanda 6:06522f3a6642 113 RadioStatus XBee802::get_network_address(uint16_t * const addr16)
hbujanda 6:06522f3a6642 114 {
hbujanda 6:06522f3a6642 115 if (addr16 == NULL) {
hbujanda 6:06522f3a6642 116 return Failure;
hbujanda 6:06522f3a6642 117 }
hbujanda 6:06522f3a6642 118 AtCmdFrame::AtCmdResp cmdresp;
hbujanda 6:06522f3a6642 119
hbujanda 6:06522f3a6642 120 uint32_t var32;
hbujanda 6:06522f3a6642 121 cmdresp = get_param("MY", &var32);
hbujanda 6:06522f3a6642 122 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
hbujanda 6:06522f3a6642 123 return Failure;
hbujanda 6:06522f3a6642 124 }
hbujanda 6:06522f3a6642 125 *addr16 = var32;
hbujanda 6:06522f3a6642 126 return Success;
hbujanda 6:06522f3a6642 127 }
hbujanda 6:06522f3a6642 128
spastor 0:fcaad0dfa051 129 RadioStatus XBee802::set_network_address(uint16_t addr16)
spastor 0:fcaad0dfa051 130 {
spastor 0:fcaad0dfa051 131 AtCmdFrame::AtCmdResp cmdresp;
spastor 0:fcaad0dfa051 132
spastor 0:fcaad0dfa051 133 cmdresp = set_param("MY", addr16);
spastor 0:fcaad0dfa051 134 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
spastor 0:fcaad0dfa051 135 return Failure;
spastor 0:fcaad0dfa051 136 }
spastor 0:fcaad0dfa051 137 return Success;
spastor 0:fcaad0dfa051 138 }
spastor 0:fcaad0dfa051 139
hbujanda 8:b5f4a0e92249 140 RadioStatus XBee802::set_tc_link_key(const uint8_t * const key, const uint16_t length)
hbujanda 8:b5f4a0e92249 141 {
hbujanda 8:b5f4a0e92249 142 if (key == NULL || length == 0 || length > 16) {
hbujanda 8:b5f4a0e92249 143 return Failure;
hbujanda 8:b5f4a0e92249 144 }
hbujanda 8:b5f4a0e92249 145 AtCmdFrame::AtCmdResp cmdresp;
hbujanda 8:b5f4a0e92249 146
hbujanda 8:b5f4a0e92249 147 cmdresp = set_param("KY", key, length);
hbujanda 8:b5f4a0e92249 148 return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
hbujanda 8:b5f4a0e92249 149 }
hbujanda 8:b5f4a0e92249 150
hbujanda 6:06522f3a6642 151 RadioStatus XBee802::get_node_discovery_timeout(uint16_t * const timeout_ms)
hbujanda 6:06522f3a6642 152 {
hbujanda 6:06522f3a6642 153 AtCmdFrame::AtCmdResp cmdresp;
hbujanda 6:06522f3a6642 154 uint32_t var32;
hbujanda 6:06522f3a6642 155
hbujanda 6:06522f3a6642 156 cmdresp = get_param("NT", &var32);
hbujanda 6:06522f3a6642 157 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
hbujanda 6:06522f3a6642 158 return Failure;
hbujanda 6:06522f3a6642 159 }
hbujanda 6:06522f3a6642 160 *timeout_ms = (uint16_t)var32;
hbujanda 6:06522f3a6642 161
hbujanda 6:06522f3a6642 162 /* No N? command available for this protocol. Add a fix 1s guard time */
hbujanda 6:06522f3a6642 163 *timeout_ms += 1000;
hbujanda 6:06522f3a6642 164
hbujanda 6:06522f3a6642 165 return Success;
hbujanda 6:06522f3a6642 166 }
hbujanda 6:06522f3a6642 167
hbujanda 6:06522f3a6642 168 RadioStatus XBee802::get_node_discovery_timeout(uint16_t * const timeout_ms, bool * const wait_for_complete_timeout)
hbujanda 6:06522f3a6642 169 {
hbujanda 6:06522f3a6642 170 const RadioStatus status = get_node_discovery_timeout(timeout_ms);
hbujanda 6:06522f3a6642 171
hbujanda 6:06522f3a6642 172 /* This protocol requires to wait for the complete timeout before attempting
hbujanda 6:06522f3a6642 173 to execute other commands */
hbujanda 6:06522f3a6642 174 *wait_for_complete_timeout = true;
hbujanda 6:06522f3a6642 175
hbujanda 6:06522f3a6642 176 return status;
hbujanda 6:06522f3a6642 177 }
hbujanda 6:06522f3a6642 178
spastor 0:fcaad0dfa051 179 void XBee802::radio_status_update(AtCmdFrame::ModemStatus modem_status)
spastor 0:fcaad0dfa051 180 {
spastor 0:fcaad0dfa051 181 /* Update the radio status variables */
spastor 4:629712865107 182 if (modem_status == AtCmdFrame::HwReset) {
spastor 0:fcaad0dfa051 183 _hw_reset_cnt++;
spastor 4:629712865107 184 } else if (modem_status == AtCmdFrame::WdReset) {
spastor 0:fcaad0dfa051 185 _wd_reset_cnt++;
spastor 4:629712865107 186 }
spastor 0:fcaad0dfa051 187
spastor 0:fcaad0dfa051 188 _modem_status = modem_status;
spastor 4:629712865107 189
spastor 0:fcaad0dfa051 190 digi_log(LogLevelDebug, "\r\nUpdating radio status: %02x\r\n", modem_status);
spastor 0:fcaad0dfa051 191 }
spastor 0:fcaad0dfa051 192
spastor 3:8662ebe83570 193 TxStatus XBee802::send_data(const RemoteXBee& remote, const uint8_t *const data, uint16_t len, bool syncr)
spastor 0:fcaad0dfa051 194 {
spastor 0:fcaad0dfa051 195 if (remote.is_valid_addr64b()) {
spastor 0:fcaad0dfa051 196 const uint64_t remote64 = remote.get_addr64();
spastor 0:fcaad0dfa051 197
spastor 0:fcaad0dfa051 198 digi_log(LogLevelDebug, "send_data ADDR64: %08x:%08x\r\n", UINT64_HI32(remote64), UINT64_LO32(remote64));
spastor 0:fcaad0dfa051 199
spastor 0:fcaad0dfa051 200 TxFrame802 frame = TxFrame802(remote64, _tx_options, data, len);
spastor 0:fcaad0dfa051 201
spastor 3:8662ebe83570 202 if (syncr) {
spastor 3:8662ebe83570 203 return send_data(&frame);
spastor 3:8662ebe83570 204 } else {
spastor 3:8662ebe83570 205 frame.set_data(0, 0); /* Set frame id to 0 so there is no answer */
spastor 3:8662ebe83570 206 send_api_frame(&frame);
spastor 3:8662ebe83570 207 return TxStatusSuccess;
spastor 3:8662ebe83570 208 }
spastor 0:fcaad0dfa051 209 }
spastor 0:fcaad0dfa051 210
spastor 0:fcaad0dfa051 211 if (remote.is_valid_addr16b()) {
spastor 0:fcaad0dfa051 212 const uint16_t remote16 = remote.get_addr16();
spastor 0:fcaad0dfa051 213
spastor 0:fcaad0dfa051 214 digi_log(LogLevelDebug, "send_data ADDR16: %04x\r\n", remote16);
spastor 0:fcaad0dfa051 215
spastor 0:fcaad0dfa051 216 TxFrame802 frame = TxFrame802(remote16, _tx_options, data, len);
spastor 0:fcaad0dfa051 217
spastor 3:8662ebe83570 218 if (syncr) {
spastor 3:8662ebe83570 219 return send_data(&frame);
spastor 3:8662ebe83570 220 } else {
spastor 3:8662ebe83570 221 frame.set_data(0, 0); /* Set frame id to 0 so there is no answer */
spastor 3:8662ebe83570 222 send_api_frame(&frame);
spastor 3:8662ebe83570 223 return TxStatusSuccess;
spastor 3:8662ebe83570 224 }
hbujanda 2:2ee1b6d51df2 225 }
hbujanda 2:2ee1b6d51df2 226
hbujanda 2:2ee1b6d51df2 227 return TxStatusInvalidAddr;
hbujanda 1:794d1d3e4a08 228 }
hbujanda 1:794d1d3e4a08 229
spastor 4:629712865107 230 XBee802::AssocStatus XBee802::get_assoc_status(void)
spastor 4:629712865107 231 {
spastor 4:629712865107 232 return (AssocStatus)get_AI();
spastor 4:629712865107 233 }
spastor 4:629712865107 234
hbujanda 2:2ee1b6d51df2 235 RemoteXBee802 XBee802::get_remote_node_by_id(const char * const node_id)
hbujanda 1:794d1d3e4a08 236 {
hbujanda 2:2ee1b6d51df2 237 uint64_t addr64;
hbujanda 2:2ee1b6d51df2 238 uint16_t addr16;
spastor 4:629712865107 239
hbujanda 2:2ee1b6d51df2 240 _get_remote_node_by_id(node_id, &addr64, &addr16);
hbujanda 2:2ee1b6d51df2 241 return RemoteXBee802(addr64, addr16);
spastor 0:fcaad0dfa051 242 }
spastor 0:fcaad0dfa051 243
spastor 0:fcaad0dfa051 244 void XBee802::register_node_discovery_cb(node_discovery_802_cb_t function)
spastor 0:fcaad0dfa051 245 {
spastor 0:fcaad0dfa051 246 if (_nd_handler == NULL) {
spastor 0:fcaad0dfa051 247 _nd_handler = new FH_NodeDiscovery802();
spastor 0:fcaad0dfa051 248 register_frame_handler(_nd_handler);
spastor 0:fcaad0dfa051 249 }
spastor 0:fcaad0dfa051 250 _nd_handler->register_node_discovery_cb(function);
spastor 0:fcaad0dfa051 251 }
spastor 0:fcaad0dfa051 252
spastor 0:fcaad0dfa051 253 void XBee802::unregister_node_discovery_cb()
spastor 0:fcaad0dfa051 254 {
spastor 0:fcaad0dfa051 255 if (_nd_handler != NULL) {
spastor 0:fcaad0dfa051 256 _nd_handler->unregister_node_discovery_cb();
spastor 0:fcaad0dfa051 257 unregister_frame_handler(_nd_handler);
spastor 0:fcaad0dfa051 258 delete _nd_handler;
spastor 0:fcaad0dfa051 259 _nd_handler = NULL; /* as delete does not set to NULL */
spastor 0:fcaad0dfa051 260 }
spastor 0:fcaad0dfa051 261 }
spastor 0:fcaad0dfa051 262
spastor 0:fcaad0dfa051 263 void XBee802::register_receive_cb(receive_802_cb_t function)
spastor 0:fcaad0dfa051 264 {
spastor 0:fcaad0dfa051 265 if (_rx_64b_handler == NULL) {
spastor 0:fcaad0dfa051 266 _rx_64b_handler = new FH_RxPacket64b802();
spastor 0:fcaad0dfa051 267 register_frame_handler(_rx_64b_handler);
spastor 0:fcaad0dfa051 268 }
spastor 0:fcaad0dfa051 269 _rx_64b_handler->register_receive_cb(function);
spastor 0:fcaad0dfa051 270
spastor 0:fcaad0dfa051 271 if (_rx_16b_handler == NULL) {
spastor 0:fcaad0dfa051 272 _rx_16b_handler = new FH_RxPacket16b802();
spastor 0:fcaad0dfa051 273 register_frame_handler(_rx_16b_handler);
spastor 0:fcaad0dfa051 274 }
spastor 0:fcaad0dfa051 275 _rx_16b_handler->register_receive_cb(function);
spastor 0:fcaad0dfa051 276 }
spastor 0:fcaad0dfa051 277
spastor 0:fcaad0dfa051 278 void XBee802::unregister_receive_cb()
spastor 0:fcaad0dfa051 279 {
spastor 0:fcaad0dfa051 280 if (_rx_64b_handler != NULL) {
spastor 0:fcaad0dfa051 281 _rx_64b_handler->unregister_receive_cb();
spastor 0:fcaad0dfa051 282 unregister_frame_handler(_rx_64b_handler);
spastor 0:fcaad0dfa051 283 delete _rx_64b_handler;
spastor 0:fcaad0dfa051 284 _rx_64b_handler = NULL; /* as delete does not set to NULL */
spastor 0:fcaad0dfa051 285 }
spastor 0:fcaad0dfa051 286
spastor 0:fcaad0dfa051 287 if (_rx_16b_handler != NULL) {
spastor 0:fcaad0dfa051 288 _rx_16b_handler->unregister_receive_cb();
spastor 0:fcaad0dfa051 289 unregister_frame_handler(_rx_16b_handler);
spastor 0:fcaad0dfa051 290 delete _rx_16b_handler;
spastor 0:fcaad0dfa051 291 _rx_16b_handler = NULL; /* as delete does not set to NULL */
spastor 0:fcaad0dfa051 292 }
spastor 0:fcaad0dfa051 293 }
spastor 0:fcaad0dfa051 294
spastor 0:fcaad0dfa051 295 void XBee802::register_io_sample_cb(io_data_cb_802_t function)
spastor 0:fcaad0dfa051 296 {
spastor 0:fcaad0dfa051 297 if (_io_data_64b_handler == NULL) {
spastor 0:fcaad0dfa051 298 _io_data_64b_handler = new FH_IoDataSampe64b802();
spastor 0:fcaad0dfa051 299 register_frame_handler(_io_data_64b_handler);
spastor 0:fcaad0dfa051 300 }
spastor 0:fcaad0dfa051 301 _io_data_64b_handler->register_io_data_cb(function);
spastor 0:fcaad0dfa051 302
spastor 0:fcaad0dfa051 303 if (_io_data_16b_handler == NULL) {
spastor 0:fcaad0dfa051 304 _io_data_16b_handler = new FH_IoDataSampe16b802();
spastor 0:fcaad0dfa051 305 register_frame_handler(_io_data_16b_handler);
spastor 0:fcaad0dfa051 306 }
spastor 0:fcaad0dfa051 307 _io_data_16b_handler->register_io_data_cb(function);
spastor 0:fcaad0dfa051 308 }
spastor 0:fcaad0dfa051 309
spastor 0:fcaad0dfa051 310 void XBee802::unregister_io_sample_cb()
spastor 0:fcaad0dfa051 311 {
spastor 0:fcaad0dfa051 312 if (_io_data_64b_handler != NULL) {
spastor 0:fcaad0dfa051 313 _io_data_64b_handler->unregister_io_data_cb();
spastor 0:fcaad0dfa051 314 unregister_frame_handler(_io_data_64b_handler);
spastor 0:fcaad0dfa051 315 delete _io_data_64b_handler;
spastor 0:fcaad0dfa051 316 _io_data_64b_handler = NULL; /* as delete does not set to NULL */
spastor 0:fcaad0dfa051 317 }
spastor 0:fcaad0dfa051 318
spastor 0:fcaad0dfa051 319 if (_io_data_16b_handler != NULL) {
spastor 0:fcaad0dfa051 320 _io_data_16b_handler->unregister_io_data_cb();
spastor 0:fcaad0dfa051 321 unregister_frame_handler(_io_data_16b_handler);
spastor 0:fcaad0dfa051 322 delete _io_data_16b_handler;
spastor 0:fcaad0dfa051 323 _io_data_16b_handler = NULL; /* as delete does not set to NULL */
spastor 0:fcaad0dfa051 324 }
spastor 0:fcaad0dfa051 325 }
spastor 0:fcaad0dfa051 326
spastor 0:fcaad0dfa051 327 AtCmdFrame::AtCmdResp XBee802::get_param(const RemoteXBee& remote, const char * const param, uint32_t * const data)
spastor 0:fcaad0dfa051 328 {
spastor 0:fcaad0dfa051 329 uint16_t len = sizeof *data;
spastor 0:fcaad0dfa051 330 AtCmdFrame::AtCmdResp atCmdResponse;
spastor 0:fcaad0dfa051 331
spastor 0:fcaad0dfa051 332 if (remote.is_valid_addr64b()) {
spastor 0:fcaad0dfa051 333 const uint64_t dev_addr64 = remote.get_addr64();
spastor 0:fcaad0dfa051 334
spastor 0:fcaad0dfa051 335 AtCmdFrame cmd_frame = AtCmdFrame(dev_addr64, param);
spastor 0:fcaad0dfa051 336 atCmdResponse = send_at_cmd(&cmd_frame, (uint8_t *)data, &len, RadioRemote);
spastor 0:fcaad0dfa051 337 } else if (remote.is_valid_addr16b()) {
spastor 0:fcaad0dfa051 338 const uint16_t dev_addr16 = remote.get_addr16();
spastor 0:fcaad0dfa051 339
spastor 0:fcaad0dfa051 340 AtCmdFrame cmd_frame = AtCmdFrame(dev_addr16, param);
spastor 0:fcaad0dfa051 341 atCmdResponse = send_at_cmd(&cmd_frame, (uint8_t *)data, &len, RadioRemote);
spastor 0:fcaad0dfa051 342 } else {
spastor 0:fcaad0dfa051 343 return AtCmdFrame::AtCmdRespInvalidAddr;
spastor 0:fcaad0dfa051 344 }
spastor 0:fcaad0dfa051 345
spastor 0:fcaad0dfa051 346 if (atCmdResponse == AtCmdFrame::AtCmdRespOk && len > sizeof *data) {
spastor 0:fcaad0dfa051 347 atCmdResponse = AtCmdFrame::AtCmdRespLenMismatch;
spastor 0:fcaad0dfa051 348 }
spastor 0:fcaad0dfa051 349
spastor 0:fcaad0dfa051 350 return atCmdResponse;
spastor 0:fcaad0dfa051 351 }
spastor 0:fcaad0dfa051 352
spastor 0:fcaad0dfa051 353 AtCmdFrame::AtCmdResp XBee802::set_param(const RemoteXBee& remote, const char * const param, uint32_t data)
spastor 0:fcaad0dfa051 354 {
spastor 0:fcaad0dfa051 355 if (remote.is_valid_addr64b()) {
spastor 0:fcaad0dfa051 356 const uint64_t dev_addr64 = remote.get_addr64();
spastor 0:fcaad0dfa051 357
spastor 0:fcaad0dfa051 358 AtCmdFrame cmd_frame = AtCmdFrame(dev_addr64, param, data);
spastor 0:fcaad0dfa051 359 return send_at_cmd(&cmd_frame, NULL, NULL, RadioRemote);
spastor 0:fcaad0dfa051 360 }
spastor 0:fcaad0dfa051 361
spastor 0:fcaad0dfa051 362 if (remote.is_valid_addr16b()) {
spastor 0:fcaad0dfa051 363 const uint16_t dev_addr16 = remote.get_addr16();
spastor 0:fcaad0dfa051 364
spastor 0:fcaad0dfa051 365 AtCmdFrame cmd_frame = AtCmdFrame(dev_addr16, param, data);
spastor 0:fcaad0dfa051 366 return send_at_cmd(&cmd_frame, NULL, NULL, RadioRemote);
spastor 0:fcaad0dfa051 367 }
spastor 0:fcaad0dfa051 368
spastor 0:fcaad0dfa051 369 return AtCmdFrame::AtCmdRespInvalidAddr;
spastor 0:fcaad0dfa051 370 }
spastor 0:fcaad0dfa051 371
spastor 0:fcaad0dfa051 372 AtCmdFrame::AtCmdResp XBee802::set_param(const RemoteXBee& remote, const char * const param, const uint8_t * data, uint16_t len)
spastor 0:fcaad0dfa051 373 {
spastor 0:fcaad0dfa051 374 if (remote.is_valid_addr64b()) {
spastor 0:fcaad0dfa051 375 const uint64_t dev_addr64 = remote.get_addr64();
spastor 0:fcaad0dfa051 376
spastor 0:fcaad0dfa051 377 AtCmdFrame cmd_frame = AtCmdFrame(dev_addr64, param, data, len);
spastor 0:fcaad0dfa051 378 return send_at_cmd(&cmd_frame, NULL, NULL, RadioRemote);
spastor 0:fcaad0dfa051 379 }
spastor 0:fcaad0dfa051 380
spastor 0:fcaad0dfa051 381 if (remote.is_valid_addr16b()) {
spastor 0:fcaad0dfa051 382 const uint16_t dev_addr16 = remote.get_addr16();
spastor 0:fcaad0dfa051 383
spastor 0:fcaad0dfa051 384 AtCmdFrame cmd_frame = AtCmdFrame(dev_addr16, param, data, len);
spastor 0:fcaad0dfa051 385 return send_at_cmd(&cmd_frame, NULL, NULL, RadioRemote);
spastor 0:fcaad0dfa051 386 }
spastor 0:fcaad0dfa051 387
spastor 0:fcaad0dfa051 388 return AtCmdFrame::AtCmdRespInvalidAddr;
spastor 0:fcaad0dfa051 389 }
spastor 0:fcaad0dfa051 390
spastor 0:fcaad0dfa051 391 AtCmdFrame::AtCmdResp XBee802::get_param(const RemoteXBee& remote, const char * const param, uint8_t * const data, uint16_t * const len)
spastor 0:fcaad0dfa051 392 {
spastor 0:fcaad0dfa051 393 if (remote.is_valid_addr64b()) {
spastor 0:fcaad0dfa051 394 uint64_t dev_addr64 = remote.get_addr64();
spastor 0:fcaad0dfa051 395
spastor 0:fcaad0dfa051 396 AtCmdFrame cmd_frame = AtCmdFrame(dev_addr64, param);
spastor 0:fcaad0dfa051 397 return send_at_cmd(&cmd_frame, data, len, RadioRemote, false);
spastor 0:fcaad0dfa051 398 }
spastor 0:fcaad0dfa051 399
spastor 0:fcaad0dfa051 400 if (remote.is_valid_addr16b()) {
spastor 0:fcaad0dfa051 401 uint16_t dev_addr16 = remote.get_addr16();
spastor 0:fcaad0dfa051 402
spastor 0:fcaad0dfa051 403 AtCmdFrame cmd_frame = AtCmdFrame(dev_addr16, param);
spastor 0:fcaad0dfa051 404 return send_at_cmd(&cmd_frame, data, len, RadioRemote, false);
spastor 0:fcaad0dfa051 405 }
spastor 0:fcaad0dfa051 406
spastor 0:fcaad0dfa051 407 return AtCmdFrame::AtCmdRespInvalidAddr;
spastor 0:fcaad0dfa051 408 }
spastor 0:fcaad0dfa051 409
spastor 0:fcaad0dfa051 410 static void get_dio_cmd(XBee802::IoLine line, char * const iocmd)
spastor 0:fcaad0dfa051 411 {
spastor 0:fcaad0dfa051 412 if (line >= XBee802::PWM0) {
spastor 0:fcaad0dfa051 413 iocmd[0] = 'P';
spastor 0:fcaad0dfa051 414 iocmd[1] = '0' + line - XBee802::PWM0;
spastor 0:fcaad0dfa051 415 } else {
spastor 0:fcaad0dfa051 416 iocmd[0] = 'D';
spastor 0:fcaad0dfa051 417 iocmd[1] = '0' + line;
spastor 0:fcaad0dfa051 418 }
spastor 0:fcaad0dfa051 419 iocmd[2] = '\0';
spastor 0:fcaad0dfa051 420 }
spastor 0:fcaad0dfa051 421
spastor 0:fcaad0dfa051 422 RadioStatus XBee802::set_pin_config(const RemoteXBee& remote, IoLine line, IoMode mode)
spastor 0:fcaad0dfa051 423 {
spastor 0:fcaad0dfa051 424 AtCmdFrame::AtCmdResp cmdresp;
spastor 0:fcaad0dfa051 425 char iocmd[3];
spastor 0:fcaad0dfa051 426
spastor 0:fcaad0dfa051 427 get_dio_cmd(line, iocmd);
spastor 0:fcaad0dfa051 428
spastor 0:fcaad0dfa051 429 cmdresp = set_param(remote, iocmd, (uint8_t)mode);
spastor 0:fcaad0dfa051 430 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
spastor 0:fcaad0dfa051 431 digi_log(LogLevelError, "set_pin_config: set_param returned %d\r\n", cmdresp);
spastor 0:fcaad0dfa051 432 return Failure;
spastor 0:fcaad0dfa051 433 }
spastor 0:fcaad0dfa051 434
spastor 0:fcaad0dfa051 435 return Success;
spastor 0:fcaad0dfa051 436 }
spastor 0:fcaad0dfa051 437
spastor 0:fcaad0dfa051 438 RadioStatus XBee802::get_pin_config(const RemoteXBee& remote, IoLine line, IoMode * const mode)
spastor 0:fcaad0dfa051 439 {
spastor 0:fcaad0dfa051 440 AtCmdFrame::AtCmdResp cmdresp;
spastor 0:fcaad0dfa051 441 char iocmd[3];
spastor 0:fcaad0dfa051 442
spastor 0:fcaad0dfa051 443 get_dio_cmd(line, iocmd);
spastor 0:fcaad0dfa051 444
spastor 0:fcaad0dfa051 445 uint32_t var32;
spastor 0:fcaad0dfa051 446 cmdresp = get_param(remote, iocmd, &var32);
spastor 0:fcaad0dfa051 447 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
spastor 0:fcaad0dfa051 448 return Failure;
spastor 0:fcaad0dfa051 449 }
spastor 0:fcaad0dfa051 450 *mode = (IoMode)var32;
spastor 0:fcaad0dfa051 451
spastor 0:fcaad0dfa051 452 return Success;
spastor 0:fcaad0dfa051 453 }
spastor 0:fcaad0dfa051 454
spastor 0:fcaad0dfa051 455 RadioStatus XBee802::set_dio(const RemoteXBee& remote, IoLine line, DioVal val)
spastor 0:fcaad0dfa051 456 {
spastor 0:fcaad0dfa051 457 if (line > DI8) {
spastor 0:fcaad0dfa051 458 digi_log(LogLevelError, "set_dio: Pin %d not supported as IO\r\n", line);
spastor 0:fcaad0dfa051 459 return Failure;
spastor 0:fcaad0dfa051 460 }
spastor 0:fcaad0dfa051 461
spastor 0:fcaad0dfa051 462 if (val == Low) {
spastor 0:fcaad0dfa051 463 return set_pin_config(remote, line, DigitalOutLow);
spastor 0:fcaad0dfa051 464 } else {
spastor 0:fcaad0dfa051 465 return set_pin_config(remote, line, DigitalOutHigh);
spastor 0:fcaad0dfa051 466 }
spastor 0:fcaad0dfa051 467 }
spastor 0:fcaad0dfa051 468
spastor 0:fcaad0dfa051 469 RadioStatus XBee802::get_dio(const RemoteXBee& remote, IoLine line, DioVal * const val)
spastor 0:fcaad0dfa051 470 {
spastor 3:8662ebe83570 471 return get_iosample(remote).get_dio(line, val);
spastor 0:fcaad0dfa051 472 }
spastor 0:fcaad0dfa051 473
spastor 0:fcaad0dfa051 474 RadioStatus XBee802::get_adc(const RemoteXBee& remote, IoLine line, uint16_t * const val)
spastor 0:fcaad0dfa051 475 {
spastor 3:8662ebe83570 476 return get_iosample(remote).get_adc(line, val);
spastor 0:fcaad0dfa051 477 }
spastor 0:fcaad0dfa051 478
spastor 0:fcaad0dfa051 479 RadioStatus XBee802::set_pwm(const RemoteXBee& remote, IoLine line, float duty_cycle)
spastor 0:fcaad0dfa051 480 {
spastor 0:fcaad0dfa051 481 AtCmdFrame::AtCmdResp cmdresp;
spastor 0:fcaad0dfa051 482 char iocmd[3] = { 'M', '0', '\0' };
spastor 4:629712865107 483
spastor 0:fcaad0dfa051 484 if (line != PWM0 && line != PWM1) {
spastor 0:fcaad0dfa051 485 return Failure;
spastor 0:fcaad0dfa051 486 }
spastor 0:fcaad0dfa051 487 if (line == PWM1) {
spastor 0:fcaad0dfa051 488 iocmd[1] = '1';
spastor 0:fcaad0dfa051 489 }
spastor 4:629712865107 490
spastor 0:fcaad0dfa051 491 uint16_t pwm_val = (uint16_t)(duty_cycle * DR_PWM_MAX_VAL / 100);
spastor 0:fcaad0dfa051 492
spastor 0:fcaad0dfa051 493 cmdresp = set_param(remote, iocmd, pwm_val);
spastor 4:629712865107 494 return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
spastor 0:fcaad0dfa051 495 }
spastor 0:fcaad0dfa051 496
spastor 3:8662ebe83570 497 IOSample802 XBee802::get_iosample(const RemoteXBee& remote)
spastor 3:8662ebe83570 498 {
spastor 3:8662ebe83570 499 uint8_t io_sample[MAX_IO_SAMPLE_802_LEN];
spastor 3:8662ebe83570 500 uint16_t len = sizeof io_sample;
spastor 3:8662ebe83570 501
spastor 3:8662ebe83570 502 RadioStatus resp = _get_iosample(remote, io_sample, &len);
spastor 3:8662ebe83570 503 if (resp != Success) {
spastor 3:8662ebe83570 504 digi_log(LogLevelError, "XBee802::get_iosample failed to get an IOSample\r\n");
spastor 3:8662ebe83570 505 len = 0;
spastor 3:8662ebe83570 506 }
spastor 3:8662ebe83570 507 return IOSample802(io_sample, len);
spastor 3:8662ebe83570 508 }
spastor 3:8662ebe83570 509
spastor 0:fcaad0dfa051 510 static uint8_t get_dio_mask(XBee802::IoLine line)
spastor 0:fcaad0dfa051 511 {
spastor 0:fcaad0dfa051 512 switch (line) {
spastor 0:fcaad0dfa051 513 case XBee802::DIO4_AD4:
spastor 0:fcaad0dfa051 514 return (1 << 0);
spastor 0:fcaad0dfa051 515 case XBee802::DIO3_AD3:
spastor 0:fcaad0dfa051 516 return (1 << 1);
spastor 0:fcaad0dfa051 517 case XBee802::DIO2_AD2:
spastor 0:fcaad0dfa051 518 return (1 << 2);
spastor 0:fcaad0dfa051 519 case XBee802::DIO1_AD1:
spastor 0:fcaad0dfa051 520 return (1 << 3);
spastor 0:fcaad0dfa051 521 case XBee802::DIO0_AD0:
spastor 0:fcaad0dfa051 522 return (1 << 4);
spastor 0:fcaad0dfa051 523 case XBee802::DIO6:
spastor 0:fcaad0dfa051 524 return (1 << 5);
spastor 0:fcaad0dfa051 525 case XBee802::DI8:
spastor 0:fcaad0dfa051 526 return (1 << 6);
spastor 0:fcaad0dfa051 527 default:
spastor 0:fcaad0dfa051 528 return 0;
spastor 0:fcaad0dfa051 529 }
spastor 0:fcaad0dfa051 530 }
spastor 0:fcaad0dfa051 531
spastor 0:fcaad0dfa051 532 RadioStatus XBee802::set_pin_pull_up(const RemoteXBee& remote, IoLine line, bool enable)
spastor 0:fcaad0dfa051 533 {
spastor 0:fcaad0dfa051 534 AtCmdFrame::AtCmdResp cmdresp;
spastor 0:fcaad0dfa051 535 uint32_t var32;
spastor 0:fcaad0dfa051 536 uint8_t pr;
spastor 0:fcaad0dfa051 537
spastor 0:fcaad0dfa051 538 cmdresp = get_param(remote, "PR", &var32);
spastor 4:629712865107 539 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
spastor 0:fcaad0dfa051 540 return Failure;
spastor 4:629712865107 541 }
spastor 0:fcaad0dfa051 542 pr = var32;
spastor 0:fcaad0dfa051 543
spastor 0:fcaad0dfa051 544 const uint8_t dio_mask = get_dio_mask(line);
spastor 0:fcaad0dfa051 545 if (dio_mask == 0) {
spastor 0:fcaad0dfa051 546 digi_log(LogLevelError, "XBee802::set_pin_pull_up: invalid pin %d\r\n", line);
spastor 0:fcaad0dfa051 547 return Failure;
spastor 0:fcaad0dfa051 548 }
spastor 0:fcaad0dfa051 549
spastor 0:fcaad0dfa051 550 if (enable) {
spastor 0:fcaad0dfa051 551 pr |= dio_mask;
spastor 0:fcaad0dfa051 552 } else {
spastor 0:fcaad0dfa051 553 pr &= ~dio_mask;
spastor 0:fcaad0dfa051 554 }
spastor 0:fcaad0dfa051 555
spastor 0:fcaad0dfa051 556 cmdresp = set_param(remote, "PR", pr);
spastor 4:629712865107 557 return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
spastor 0:fcaad0dfa051 558 }
spastor 0:fcaad0dfa051 559
spastor 0:fcaad0dfa051 560 static uint8_t get_dio_ic_mask(XBee802::IoLine line)
spastor 0:fcaad0dfa051 561 {
spastor 0:fcaad0dfa051 562 if (line < XBee802::DI8) {
spastor 0:fcaad0dfa051 563 return (1 << line);
spastor 0:fcaad0dfa051 564 }
spastor 0:fcaad0dfa051 565 return 0;
spastor 0:fcaad0dfa051 566 }
spastor 0:fcaad0dfa051 567
spastor 0:fcaad0dfa051 568 RadioStatus XBee802::enable_dio_change_detection(const RemoteXBee& remote, IoLine line, bool enable)
spastor 0:fcaad0dfa051 569 {
spastor 0:fcaad0dfa051 570 if (line > DIO7) {
spastor 0:fcaad0dfa051 571 digi_log(LogLevelError, "XBee802::enable_dio_change_detection: pin not supported (%d)\r\n", line);
spastor 0:fcaad0dfa051 572 return Failure;
spastor 0:fcaad0dfa051 573 }
spastor 0:fcaad0dfa051 574
spastor 0:fcaad0dfa051 575 AtCmdFrame::AtCmdResp cmdresp;
spastor 0:fcaad0dfa051 576 uint32_t var32;
spastor 0:fcaad0dfa051 577 uint8_t ic;
spastor 0:fcaad0dfa051 578
spastor 0:fcaad0dfa051 579 cmdresp = get_param(remote, "IC", &var32);
spastor 0:fcaad0dfa051 580 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
spastor 0:fcaad0dfa051 581 return Failure;
spastor 0:fcaad0dfa051 582 }
spastor 0:fcaad0dfa051 583 ic = var32;
spastor 0:fcaad0dfa051 584
spastor 0:fcaad0dfa051 585 const uint8_t dio_mask = get_dio_ic_mask(line);
spastor 0:fcaad0dfa051 586 if (dio_mask == 0) {
spastor 0:fcaad0dfa051 587 digi_log(LogLevelError, "XBeeZB::enable_dio_change_detection: invalid pin %d\r\n", line);
spastor 0:fcaad0dfa051 588 return Failure;
spastor 0:fcaad0dfa051 589 }
spastor 0:fcaad0dfa051 590
spastor 0:fcaad0dfa051 591 if (enable) {
spastor 0:fcaad0dfa051 592 ic |= dio_mask;
spastor 0:fcaad0dfa051 593 } else {
spastor 0:fcaad0dfa051 594 ic &= ~dio_mask;
spastor 0:fcaad0dfa051 595 }
spastor 0:fcaad0dfa051 596
spastor 0:fcaad0dfa051 597 cmdresp = set_param(remote, "IC", ic);
spastor 4:629712865107 598 return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
spastor 4:629712865107 599 }
spastor 0:fcaad0dfa051 600
spastor 0:fcaad0dfa051 601 #ifdef GET_PWM_AVAILABLE
spastor 0:fcaad0dfa051 602 RadioStatus XBee802::get_pwm(const RemoteXBee& remote, IoLine line, float * const duty_cycle)
spastor 0:fcaad0dfa051 603 {
spastor 0:fcaad0dfa051 604 AtCmdFrame::AtCmdResp cmdresp;
spastor 0:fcaad0dfa051 605 char iocmd[3] = { 'M', '0', '\0' };
spastor 4:629712865107 606
spastor 4:629712865107 607 if (line != PWM0 && line != PWM1) {
spastor 0:fcaad0dfa051 608 return Failure;
spastor 4:629712865107 609 }
spastor 0:fcaad0dfa051 610
spastor 4:629712865107 611 if (line == PWM1) {
spastor 0:fcaad0dfa051 612 iocmd[1] = '1';
spastor 4:629712865107 613 }
spastor 4:629712865107 614
spastor 0:fcaad0dfa051 615 uint16_t pwm_val;
spastor 0:fcaad0dfa051 616
spastor 0:fcaad0dfa051 617 cmdresp = get_param(remote, iocmd, &pwm_val);
spastor 4:629712865107 618 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
spastor 0:fcaad0dfa051 619 return Failure;
spastor 4:629712865107 620 }
spastor 0:fcaad0dfa051 621
spastor 0:fcaad0dfa051 622 *duty_cycle = (float)(pwm_val * 100 / DR_PWM_MAX_VAL);
spastor 0:fcaad0dfa051 623
spastor 0:fcaad0dfa051 624 return Success;
spastor 0:fcaad0dfa051 625 }
spastor 0:fcaad0dfa051 626 #endif