Xbee changes 2

Fork of XBeeLib by Digi International Inc.

Committer:
hbujanda
Date:
Fri Jul 29 12:10:38 2016 +0200
Revision:
8:b5f4a0e92249
Parent:
7:3ac2a461ce76
Child:
9:780db84ce891
Automatic upload

Who changed what in which revision?

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