Library to easily communicate with XBee modules.

Fork of XBeeLib by Digi International Inc.

Committer:
basvuyk
Date:
Tue Mar 27 14:13:12 2018 +0000
Revision:
10:273032d9299a
Parent:
9:780db84ce891
Slave V1.0

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 6:06522f3a6642 105 RadioStatus XBeeDM::get_node_discovery_timeout(uint16_t * const timeout_ms)
hbujanda 6:06522f3a6642 106 {
hbujanda 6:06522f3a6642 107 AtCmdFrame::AtCmdResp cmdresp;
hbujanda 6:06522f3a6642 108 uint32_t var32;
hbujanda 6:06522f3a6642 109
hbujanda 6:06522f3a6642 110 cmdresp = get_param("N?", &var32);
hbujanda 6:06522f3a6642 111 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
hbujanda 6:06522f3a6642 112 return Failure;
hbujanda 6:06522f3a6642 113 }
hbujanda 6:06522f3a6642 114 *timeout_ms = (uint16_t)var32;
hbujanda 6:06522f3a6642 115
hbujanda 6:06522f3a6642 116 return Success;
hbujanda 6:06522f3a6642 117 }
hbujanda 6:06522f3a6642 118
hbujanda 6:06522f3a6642 119 RadioStatus XBeeDM::get_node_discovery_timeout(uint16_t * const timeout_ms, bool * const wait_for_complete_timeout)
hbujanda 6:06522f3a6642 120 {
hbujanda 6:06522f3a6642 121 const RadioStatus status = get_node_discovery_timeout(timeout_ms);
hbujanda 6:06522f3a6642 122
hbujanda 6:06522f3a6642 123 *wait_for_complete_timeout = false;
hbujanda 6:06522f3a6642 124
hbujanda 6:06522f3a6642 125 return status;
hbujanda 6:06522f3a6642 126 }
hbujanda 6:06522f3a6642 127
hbujanda 6:06522f3a6642 128 void XBeeDM::radio_status_update(AtCmdFrame::ModemStatus modem_status)
hbujanda 6:06522f3a6642 129 {
hbujanda 6:06522f3a6642 130 /* Update the radio status variables */
hbujanda 6:06522f3a6642 131 if (modem_status == AtCmdFrame::HwReset) {
hbujanda 6:06522f3a6642 132 _hw_reset_cnt++;
hbujanda 6:06522f3a6642 133 } else if (modem_status == AtCmdFrame::WdReset) {
hbujanda 6:06522f3a6642 134 _wd_reset_cnt++;
hbujanda 6:06522f3a6642 135 }
hbujanda 6:06522f3a6642 136
hbujanda 6:06522f3a6642 137 _modem_status = modem_status;
hbujanda 6:06522f3a6642 138
hbujanda 6:06522f3a6642 139 digi_log(LogLevelDebug, "\r\nUpdating radio status: %02x\r\n", modem_status);
hbujanda 6:06522f3a6642 140 }
hbujanda 6:06522f3a6642 141
hbujanda 6:06522f3a6642 142 TxStatus XBeeDM::send_data(const RemoteXBee& remote, const uint8_t *const data, uint16_t len, bool syncr)
hbujanda 6:06522f3a6642 143 {
hbujanda 6:06522f3a6642 144 if (!remote.is_valid_addr64b()) {
hbujanda 6:06522f3a6642 145 return TxStatusInvalidAddr;
hbujanda 6:06522f3a6642 146 }
hbujanda 6:06522f3a6642 147
hbujanda 6:06522f3a6642 148 const uint64_t remote64 = remote.get_addr64();
hbujanda 6:06522f3a6642 149 const uint16_t remote16 = remote.get_addr16();
hbujanda 6:06522f3a6642 150
hbujanda 6:06522f3a6642 151 TxFrameDM frame = TxFrameDM(remote64, remote16, BROADCAST_RADIUS_USE_NH,
hbujanda 6:06522f3a6642 152 _tx_options, data, len);
hbujanda 6:06522f3a6642 153 if (syncr) {
hbujanda 6:06522f3a6642 154 return send_data(&frame);
hbujanda 6:06522f3a6642 155 } else {
hbujanda 6:06522f3a6642 156 frame.set_data(0, 0); /* Set frame id to 0 so there is no answer */
hbujanda 6:06522f3a6642 157 send_api_frame(&frame);
hbujanda 6:06522f3a6642 158 return TxStatusSuccess;
hbujanda 6:06522f3a6642 159 }
hbujanda 6:06522f3a6642 160 }
hbujanda 6:06522f3a6642 161
hbujanda 6:06522f3a6642 162 TxStatus XBeeDM::send_data(const RemoteXBee& remote, uint8_t source_ep,
hbujanda 6:06522f3a6642 163 uint8_t dest_ep, uint16_t cluster_id, uint16_t profile_id,
hbujanda 6:06522f3a6642 164 const uint8_t *const data, uint16_t len, bool syncr)
hbujanda 6:06522f3a6642 165 {
hbujanda 6:06522f3a6642 166 if (!remote.is_valid_addr64b()) {
hbujanda 6:06522f3a6642 167 return TxStatusInvalidAddr;
hbujanda 6:06522f3a6642 168 }
hbujanda 6:06522f3a6642 169
hbujanda 6:06522f3a6642 170 const uint64_t remote64 = remote.get_addr64();
hbujanda 6:06522f3a6642 171 const uint16_t remote16 = remote.get_addr16();
hbujanda 6:06522f3a6642 172
hbujanda 6:06522f3a6642 173 TxFrameDM frame = TxFrameDM(remote64, remote16, source_ep, dest_ep,
hbujanda 6:06522f3a6642 174 cluster_id, profile_id, BROADCAST_RADIUS_USE_NH,
hbujanda 6:06522f3a6642 175 _tx_options, data, len);
hbujanda 6:06522f3a6642 176 if (syncr) {
hbujanda 6:06522f3a6642 177 return send_data(&frame);
hbujanda 6:06522f3a6642 178 } else {
hbujanda 6:06522f3a6642 179 frame.set_data(0, 0); /* Set frame id to 0 so there is no answer */
hbujanda 6:06522f3a6642 180 send_api_frame(&frame);
hbujanda 6:06522f3a6642 181 return TxStatusSuccess;
hbujanda 6:06522f3a6642 182 }
hbujanda 6:06522f3a6642 183 }
hbujanda 6:06522f3a6642 184
hbujanda 6:06522f3a6642 185 TxStatus XBeeDM::send_data_to_coordinator(const uint8_t *const data, uint16_t len, bool syncr)
hbujanda 6:06522f3a6642 186 {
hbujanda 6:06522f3a6642 187 const uint64_t remaddr = ADDR64_COORDINATOR;
hbujanda 6:06522f3a6642 188
hbujanda 6:06522f3a6642 189 TxFrameDM frame = TxFrameDM(remaddr, ADDR16_UNKNOWN, BROADCAST_RADIUS_USE_NH, _tx_options, data, len);
hbujanda 6:06522f3a6642 190 if (syncr) {
hbujanda 6:06522f3a6642 191 return send_data(&frame);
hbujanda 6:06522f3a6642 192 } else {
hbujanda 6:06522f3a6642 193 frame.set_data(0, 0); /* Set frame id to 0 so there is no answer */
hbujanda 6:06522f3a6642 194 send_api_frame(&frame);
hbujanda 6:06522f3a6642 195 return TxStatusSuccess;
hbujanda 6:06522f3a6642 196 }
hbujanda 6:06522f3a6642 197 }
hbujanda 6:06522f3a6642 198
hbujanda 6:06522f3a6642 199 RemoteXBeeDM XBeeDM::get_remote_node_by_id(const char * const node_id)
hbujanda 6:06522f3a6642 200 {
hbujanda 6:06522f3a6642 201 uint64_t addr64;
hbujanda 6:06522f3a6642 202 uint16_t addr16;
hbujanda 6:06522f3a6642 203 _get_remote_node_by_id(node_id, &addr64, &addr16);
hbujanda 6:06522f3a6642 204 return RemoteXBeeDM(addr64);
hbujanda 6:06522f3a6642 205 }
hbujanda 6:06522f3a6642 206
hbujanda 6:06522f3a6642 207 void XBeeDM::register_node_discovery_cb(node_discovery_dm_cb_t function)
hbujanda 6:06522f3a6642 208 {
hbujanda 6:06522f3a6642 209 if (_nd_handler == NULL) {
hbujanda 6:06522f3a6642 210 _nd_handler = new FH_NodeDiscoveryDM();
hbujanda 6:06522f3a6642 211 register_frame_handler(_nd_handler);
hbujanda 6:06522f3a6642 212 }
hbujanda 6:06522f3a6642 213 _nd_handler->register_node_discovery_cb(function);
hbujanda 6:06522f3a6642 214 }
hbujanda 6:06522f3a6642 215
hbujanda 6:06522f3a6642 216 void XBeeDM::unregister_node_discovery_cb()
hbujanda 6:06522f3a6642 217 {
hbujanda 6:06522f3a6642 218 if (_nd_handler != NULL) {
hbujanda 6:06522f3a6642 219 _nd_handler->unregister_node_discovery_cb();
hbujanda 6:06522f3a6642 220 unregister_frame_handler(_nd_handler);
hbujanda 6:06522f3a6642 221 delete _nd_handler;
hbujanda 6:06522f3a6642 222 _nd_handler = NULL; /* as delete does not set to NULL */
hbujanda 6:06522f3a6642 223 }
hbujanda 6:06522f3a6642 224 }
hbujanda 6:06522f3a6642 225
hbujanda 6:06522f3a6642 226 void XBeeDM::register_receive_cb(receive_dm_cb_t function)
hbujanda 6:06522f3a6642 227 {
hbujanda 6:06522f3a6642 228 if (_rx_pkt_handler == NULL) {
hbujanda 6:06522f3a6642 229 _rx_pkt_handler = new FH_RxPacketDM();
hbujanda 6:06522f3a6642 230 register_frame_handler(_rx_pkt_handler);
hbujanda 6:06522f3a6642 231 }
hbujanda 6:06522f3a6642 232 _rx_pkt_handler->register_receive_cb(function);
hbujanda 6:06522f3a6642 233 }
hbujanda 6:06522f3a6642 234
hbujanda 6:06522f3a6642 235 void XBeeDM::unregister_receive_cb()
hbujanda 6:06522f3a6642 236 {
hbujanda 6:06522f3a6642 237 if (_rx_pkt_handler != NULL) {
hbujanda 6:06522f3a6642 238 _rx_pkt_handler->unregister_receive_cb();
hbujanda 6:06522f3a6642 239 unregister_frame_handler(_rx_pkt_handler);
hbujanda 6:06522f3a6642 240 delete _rx_pkt_handler;
hbujanda 6:06522f3a6642 241 _rx_pkt_handler = NULL; /* as delete does not set to NULL */
hbujanda 6:06522f3a6642 242 }
hbujanda 6:06522f3a6642 243 }
hbujanda 6:06522f3a6642 244
hbujanda 6:06522f3a6642 245 void XBeeDM::register_io_sample_cb(io_data_cb_dm_t function)
hbujanda 6:06522f3a6642 246 {
hbujanda 6:06522f3a6642 247 if (_io_data_handler == NULL) {
hbujanda 6:06522f3a6642 248 _io_data_handler = new FH_IoDataSampeDM();
hbujanda 6:06522f3a6642 249 register_frame_handler(_io_data_handler);
hbujanda 6:06522f3a6642 250 }
hbujanda 6:06522f3a6642 251 _io_data_handler->register_io_data_cb(function);
hbujanda 6:06522f3a6642 252 }
hbujanda 6:06522f3a6642 253
hbujanda 6:06522f3a6642 254 void XBeeDM::unregister_io_sample_cb()
hbujanda 6:06522f3a6642 255 {
hbujanda 6:06522f3a6642 256 if (_io_data_handler != NULL) {
hbujanda 6:06522f3a6642 257 _io_data_handler->unregister_io_data_cb();
hbujanda 6:06522f3a6642 258 unregister_frame_handler(_io_data_handler);
hbujanda 6:06522f3a6642 259 delete _io_data_handler;
hbujanda 6:06522f3a6642 260 _io_data_handler = NULL; /* as delete does not set to NULL */
hbujanda 6:06522f3a6642 261 }
hbujanda 6:06522f3a6642 262 }
hbujanda 6:06522f3a6642 263
hbujanda 6:06522f3a6642 264 AtCmdFrame::AtCmdResp XBeeDM::get_param(const RemoteXBee& remote, const char * const param, uint32_t * const data)
hbujanda 6:06522f3a6642 265 {
hbujanda 6:06522f3a6642 266 if (!remote.is_valid_addr64b()) {
hbujanda 6:06522f3a6642 267 return AtCmdFrame::AtCmdRespInvalidAddr;
hbujanda 6:06522f3a6642 268 }
hbujanda 6:06522f3a6642 269
hbujanda 6:06522f3a6642 270 const uint64_t remote64 = remote.get_addr64();
hbujanda 6:06522f3a6642 271 const uint16_t remote16 = remote.get_addr16();
hbujanda 6:06522f3a6642 272 uint16_t len = sizeof *data;
hbujanda 6:06522f3a6642 273 AtCmdFrame::AtCmdResp atCmdResponse;
hbujanda 6:06522f3a6642 274
hbujanda 6:06522f3a6642 275 AtCmdFrame cmd_frame = AtCmdFrame(remote64, remote16, param);
hbujanda 6:06522f3a6642 276 atCmdResponse = send_at_cmd(&cmd_frame, (uint8_t *)data, &len, RadioRemote);
hbujanda 6:06522f3a6642 277
hbujanda 6:06522f3a6642 278 if (atCmdResponse == AtCmdFrame::AtCmdRespOk && len > sizeof *data) {
hbujanda 6:06522f3a6642 279 atCmdResponse = AtCmdFrame::AtCmdRespLenMismatch;
hbujanda 6:06522f3a6642 280 }
hbujanda 6:06522f3a6642 281
hbujanda 6:06522f3a6642 282 return atCmdResponse;
hbujanda 6:06522f3a6642 283 }
hbujanda 6:06522f3a6642 284
hbujanda 6:06522f3a6642 285 AtCmdFrame::AtCmdResp XBeeDM::set_param(const RemoteXBee& remote, const char * const param, uint32_t data)
hbujanda 6:06522f3a6642 286 {
hbujanda 6:06522f3a6642 287 if (!remote.is_valid_addr64b()) {
hbujanda 6:06522f3a6642 288 return AtCmdFrame::AtCmdRespInvalidAddr;
hbujanda 6:06522f3a6642 289 }
hbujanda 6:06522f3a6642 290
hbujanda 6:06522f3a6642 291 const uint64_t remote64 = remote.get_addr64();
hbujanda 6:06522f3a6642 292 const uint16_t remote16 = remote.get_addr16();
hbujanda 6:06522f3a6642 293
hbujanda 6:06522f3a6642 294 AtCmdFrame cmd_frame = AtCmdFrame(remote64, remote16, param, data);
hbujanda 6:06522f3a6642 295 return send_at_cmd(&cmd_frame, NULL, NULL, RadioRemote);
hbujanda 6:06522f3a6642 296 }
hbujanda 6:06522f3a6642 297
hbujanda 6:06522f3a6642 298 AtCmdFrame::AtCmdResp XBeeDM::set_param(const RemoteXBee& remote, const char * const param, const uint8_t * data, uint16_t len)
hbujanda 6:06522f3a6642 299 {
hbujanda 6:06522f3a6642 300 if (!remote.is_valid_addr64b()) {
hbujanda 6:06522f3a6642 301 return AtCmdFrame::AtCmdRespInvalidAddr;
hbujanda 6:06522f3a6642 302 }
hbujanda 6:06522f3a6642 303
hbujanda 6:06522f3a6642 304 const uint64_t remote64 = remote.get_addr64();
hbujanda 6:06522f3a6642 305 const uint16_t remote16 = remote.get_addr16();
hbujanda 6:06522f3a6642 306
hbujanda 6:06522f3a6642 307 AtCmdFrame cmd_frame = AtCmdFrame(remote64, remote16, param, data, len);
hbujanda 6:06522f3a6642 308 return send_at_cmd(&cmd_frame, NULL, NULL, RadioRemote);
hbujanda 6:06522f3a6642 309 }
hbujanda 6:06522f3a6642 310
hbujanda 6:06522f3a6642 311 AtCmdFrame::AtCmdResp XBeeDM::get_param(const RemoteXBee& remote, const char * const param, uint8_t * const data, uint16_t * const len)
hbujanda 6:06522f3a6642 312 {
hbujanda 6:06522f3a6642 313
hbujanda 6:06522f3a6642 314 if (!remote.is_valid_addr64b()) {
hbujanda 6:06522f3a6642 315 return AtCmdFrame::AtCmdRespInvalidAddr;
hbujanda 6:06522f3a6642 316 }
hbujanda 6:06522f3a6642 317
hbujanda 6:06522f3a6642 318 const uint64_t remote64 = remote.get_addr64();
hbujanda 6:06522f3a6642 319 const uint16_t remote16 = remote.get_addr16();
hbujanda 6:06522f3a6642 320
hbujanda 6:06522f3a6642 321 AtCmdFrame cmd_frame = AtCmdFrame(remote64, remote16, param);
hbujanda 6:06522f3a6642 322 return send_at_cmd(&cmd_frame, data, len, RadioRemote, false);
hbujanda 6:06522f3a6642 323 }
hbujanda 6:06522f3a6642 324
hbujanda 6:06522f3a6642 325 static void get_dio_cmd(XBeeDM::IoLine line, char * const iocmd)
hbujanda 6:06522f3a6642 326 {
hbujanda 6:06522f3a6642 327 if (line >= XBeeDM::DIO10_PWM0) {
hbujanda 6:06522f3a6642 328 iocmd[0] = 'P';
hbujanda 6:06522f3a6642 329 iocmd[1] = '0' + line - XBeeDM::DIO10_PWM0;
hbujanda 6:06522f3a6642 330 } else {
hbujanda 6:06522f3a6642 331 iocmd[0] = 'D';
hbujanda 6:06522f3a6642 332 iocmd[1] = '0' + line;
hbujanda 6:06522f3a6642 333 }
hbujanda 6:06522f3a6642 334 iocmd[2] = '\0';
hbujanda 6:06522f3a6642 335 }
hbujanda 6:06522f3a6642 336
hbujanda 6:06522f3a6642 337 RadioStatus XBeeDM::set_pin_config(const RemoteXBee& remote, IoLine line, IoMode mode)
hbujanda 6:06522f3a6642 338 {
hbujanda 6:06522f3a6642 339 AtCmdFrame::AtCmdResp cmdresp;
hbujanda 6:06522f3a6642 340 char iocmd[3];
hbujanda 6:06522f3a6642 341
hbujanda 6:06522f3a6642 342 get_dio_cmd(line, iocmd);
hbujanda 6:06522f3a6642 343
hbujanda 6:06522f3a6642 344 cmdresp = set_param(remote, iocmd, (uint8_t)mode);
hbujanda 6:06522f3a6642 345 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
hbujanda 6:06522f3a6642 346 digi_log(LogLevelError, "set_pin_config: set_param returned %d\r\n", cmdresp);
hbujanda 6:06522f3a6642 347 return Failure;
hbujanda 6:06522f3a6642 348 }
hbujanda 6:06522f3a6642 349
hbujanda 6:06522f3a6642 350 return Success;
hbujanda 6:06522f3a6642 351 }
hbujanda 6:06522f3a6642 352
hbujanda 6:06522f3a6642 353 RadioStatus XBeeDM::get_pin_config(const RemoteXBee& remote, IoLine line, IoMode * const mode)
hbujanda 6:06522f3a6642 354 {
hbujanda 6:06522f3a6642 355 AtCmdFrame::AtCmdResp cmdresp;
hbujanda 6:06522f3a6642 356 char iocmd[3];
hbujanda 6:06522f3a6642 357
hbujanda 6:06522f3a6642 358 get_dio_cmd(line, iocmd);
hbujanda 6:06522f3a6642 359
hbujanda 6:06522f3a6642 360 uint32_t var32;
hbujanda 6:06522f3a6642 361 cmdresp = get_param(remote, iocmd, &var32);
hbujanda 6:06522f3a6642 362 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
hbujanda 6:06522f3a6642 363 return Failure;
hbujanda 6:06522f3a6642 364 }
hbujanda 6:06522f3a6642 365 *mode = (IoMode)var32;
hbujanda 6:06522f3a6642 366
hbujanda 6:06522f3a6642 367 return Success;
hbujanda 6:06522f3a6642 368 }
hbujanda 6:06522f3a6642 369
hbujanda 6:06522f3a6642 370 RadioStatus XBeeDM::set_dio(const RemoteXBee& remote, IoLine line, DioVal val)
hbujanda 6:06522f3a6642 371 {
hbujanda 6:06522f3a6642 372 return set_pin_config(remote, line, val == Low ? DigitalOutLow : DigitalOutHigh);
hbujanda 6:06522f3a6642 373 }
hbujanda 6:06522f3a6642 374
hbujanda 6:06522f3a6642 375 RadioStatus XBeeDM::get_dio(const RemoteXBee& remote, IoLine line, DioVal * const val)
hbujanda 6:06522f3a6642 376 {
hbujanda 6:06522f3a6642 377 return get_iosample(remote).get_dio(line, val);
hbujanda 6:06522f3a6642 378 }
hbujanda 6:06522f3a6642 379
hbujanda 6:06522f3a6642 380 RadioStatus XBeeDM::get_adc(const RemoteXBee& remote, IoLine line, uint16_t * const val)
hbujanda 6:06522f3a6642 381 {
hbujanda 6:06522f3a6642 382 return get_iosample(remote).get_adc(line, val);
hbujanda 6:06522f3a6642 383 }
hbujanda 6:06522f3a6642 384
hbujanda 6:06522f3a6642 385 RadioStatus XBeeDM::set_pwm(const RemoteXBee& remote, IoLine line, float duty_cycle)
hbujanda 6:06522f3a6642 386 {
hbujanda 6:06522f3a6642 387 AtCmdFrame::AtCmdResp cmdresp;
hbujanda 6:06522f3a6642 388 char iocmd[3] = { 'M', '0', '\0' };
hbujanda 6:06522f3a6642 389
hbujanda 6:06522f3a6642 390 if (line != DIO10_PWM0 && line != DIO11_PWM1) {
hbujanda 6:06522f3a6642 391 return Failure;
hbujanda 6:06522f3a6642 392 }
hbujanda 6:06522f3a6642 393 if (line == DIO11_PWM1) {
hbujanda 6:06522f3a6642 394 iocmd[1] = '1';
hbujanda 6:06522f3a6642 395 }
hbujanda 6:06522f3a6642 396
hbujanda 6:06522f3a6642 397 uint16_t pwm_val = (uint16_t)(duty_cycle * DR_PWM_MAX_VAL / 100);
hbujanda 6:06522f3a6642 398
hbujanda 6:06522f3a6642 399 cmdresp = set_param(remote, iocmd, pwm_val);
hbujanda 6:06522f3a6642 400 return cmdresp == AtCmdFrame::AtCmdRespOk ? Success : Failure;
hbujanda 6:06522f3a6642 401 }
hbujanda 6:06522f3a6642 402
hbujanda 6:06522f3a6642 403 IOSampleDM XBeeDM::get_iosample(const RemoteXBee& remote)
hbujanda 6:06522f3a6642 404 {
hbujanda 6:06522f3a6642 405 uint8_t io_sample[MAX_IO_SAMPLE_DM_LEN];
hbujanda 6:06522f3a6642 406 uint16_t len = sizeof io_sample;
hbujanda 6:06522f3a6642 407
hbujanda 6:06522f3a6642 408 RadioStatus resp = _get_iosample(remote, io_sample, &len);
hbujanda 6:06522f3a6642 409 if (resp != Success) {
hbujanda 6:06522f3a6642 410 digi_log(LogLevelError, "XBeeDM::get_iosample failed to get an IOSample\r\n");
hbujanda 6:06522f3a6642 411 len = 0;
hbujanda 6:06522f3a6642 412 }
hbujanda 6:06522f3a6642 413
hbujanda 6:06522f3a6642 414 return IOSampleDM(io_sample, len);
hbujanda 6:06522f3a6642 415 }
hbujanda 6:06522f3a6642 416
hbujanda 6:06522f3a6642 417 static uint16_t get_dio_pr_mask(XBeeDM::IoLine line)
hbujanda 6:06522f3a6642 418 {
hbujanda 6:06522f3a6642 419 switch (line) {
hbujanda 6:06522f3a6642 420 case XBeeDM::DIO4:
hbujanda 6:06522f3a6642 421 return (1 << 0);
hbujanda 6:06522f3a6642 422 case XBeeDM::DIO3_AD3:
hbujanda 6:06522f3a6642 423 return (1 << 1);
hbujanda 6:06522f3a6642 424 case XBeeDM::DIO2_AD2:
hbujanda 6:06522f3a6642 425 return (1 << 2);
hbujanda 6:06522f3a6642 426 case XBeeDM::DIO1_AD1:
hbujanda 6:06522f3a6642 427 return (1 << 3);
hbujanda 6:06522f3a6642 428 case XBeeDM::DIO0_AD0:
hbujanda 6:06522f3a6642 429 return (1 << 4);
hbujanda 6:06522f3a6642 430 case XBeeDM::DIO6:
hbujanda 6:06522f3a6642 431 return (1 << 5);
hbujanda 6:06522f3a6642 432 case XBeeDM::DIO8:
hbujanda 6:06522f3a6642 433 return (1 << 6);
hbujanda 6:06522f3a6642 434 case XBeeDM::DIO5:
hbujanda 6:06522f3a6642 435 return (1 << 8);
hbujanda 6:06522f3a6642 436 case XBeeDM::DIO9:
hbujanda 6:06522f3a6642 437 return (1 << 9);
hbujanda 6:06522f3a6642 438 case XBeeDM::DIO12:
hbujanda 6:06522f3a6642 439 return (1 << 10);
hbujanda 6:06522f3a6642 440 case XBeeDM::DIO10_PWM0:
hbujanda 6:06522f3a6642 441 return (1 << 11);
hbujanda 6:06522f3a6642 442 case XBeeDM::DIO11_PWM1:
hbujanda 6:06522f3a6642 443 return (1 << 12);
hbujanda 6:06522f3a6642 444 case XBeeDM::DIO7:
hbujanda 6:06522f3a6642 445 return (1 << 13);
hbujanda 6:06522f3a6642 446 default:
hbujanda 6:06522f3a6642 447 return 0;
hbujanda 6:06522f3a6642 448 }
hbujanda 6:06522f3a6642 449 }
hbujanda 6:06522f3a6642 450
hbujanda 6:06522f3a6642 451 RadioStatus XBeeDM::set_pin_pull_up(const RemoteXBee& remote, IoLine line, bool enable)
hbujanda 6:06522f3a6642 452 {
hbujanda 6:06522f3a6642 453 AtCmdFrame::AtCmdResp cmdresp;
hbujanda 6:06522f3a6642 454 uint32_t var32;
hbujanda 6:06522f3a6642 455 uint16_t pr;
hbujanda 6:06522f3a6642 456
hbujanda 6:06522f3a6642 457 cmdresp = get_param(remote, "PR", &var32);
hbujanda 6:06522f3a6642 458 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
hbujanda 6:06522f3a6642 459 return Failure;
hbujanda 6:06522f3a6642 460 }
hbujanda 6:06522f3a6642 461 pr = var32;
hbujanda 6:06522f3a6642 462
hbujanda 6:06522f3a6642 463 const uint16_t dio_mask = get_dio_pr_mask(line);
hbujanda 6:06522f3a6642 464 if (dio_mask == 0) {
hbujanda 6:06522f3a6642 465 digi_log(LogLevelError, "XBeeDM::set_pin_pull_up: invalid pin %d\r\n", line);
hbujanda 6:06522f3a6642 466 return Failure;
hbujanda 6:06522f3a6642 467 }
hbujanda 6:06522f3a6642 468
hbujanda 6:06522f3a6642 469 if (enable) {
hbujanda 6:06522f3a6642 470 pr |= dio_mask;
hbujanda 6:06522f3a6642 471 } else {
hbujanda 6:06522f3a6642 472 pr &= ~dio_mask;
hbujanda 6:06522f3a6642 473 }
hbujanda 6:06522f3a6642 474
hbujanda 6:06522f3a6642 475 cmdresp = set_param(remote, "PR", pr);
hbujanda 6:06522f3a6642 476 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
hbujanda 6:06522f3a6642 477 return Failure;
hbujanda 6:06522f3a6642 478 }
hbujanda 6:06522f3a6642 479
hbujanda 6:06522f3a6642 480 return Success;
hbujanda 6:06522f3a6642 481 }
hbujanda 6:06522f3a6642 482
hbujanda 6:06522f3a6642 483 static uint16_t get_dio_ic_mask(XBeeDM::IoLine line)
hbujanda 6:06522f3a6642 484 {
hbujanda 6:06522f3a6642 485 if (line <= XBeeDM::DIO12) {
hbujanda 6:06522f3a6642 486 return (1 << line);
hbujanda 6:06522f3a6642 487 }
hbujanda 6:06522f3a6642 488 return 0;
hbujanda 6:06522f3a6642 489 }
hbujanda 6:06522f3a6642 490
hbujanda 6:06522f3a6642 491 RadioStatus XBeeDM::enable_dio_change_detection(const RemoteXBee& remote, IoLine line, bool enable)
hbujanda 6:06522f3a6642 492 {
hbujanda 6:06522f3a6642 493 if (line > DIO12) {
hbujanda 6:06522f3a6642 494 digi_log(LogLevelError, "XBeeDM::enable_dio_change_detection: pin not supported (%d)\r\n", line);
hbujanda 6:06522f3a6642 495 return Failure;
hbujanda 6:06522f3a6642 496 }
hbujanda 6:06522f3a6642 497
hbujanda 6:06522f3a6642 498 AtCmdFrame::AtCmdResp cmdresp;
hbujanda 6:06522f3a6642 499 uint32_t var32;
hbujanda 6:06522f3a6642 500 uint16_t ic;
hbujanda 6:06522f3a6642 501
hbujanda 6:06522f3a6642 502 cmdresp = get_param(remote, "IC", &var32);
hbujanda 6:06522f3a6642 503 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
hbujanda 6:06522f3a6642 504 return Failure;
hbujanda 6:06522f3a6642 505 }
hbujanda 6:06522f3a6642 506 ic = var32;
hbujanda 6:06522f3a6642 507
hbujanda 6:06522f3a6642 508 const uint16_t dio_mask = get_dio_ic_mask(line);
hbujanda 6:06522f3a6642 509 if (dio_mask == 0) {
hbujanda 6:06522f3a6642 510 digi_log(LogLevelError, "XBeeDM::enable_dio_change_detection: invalid pin %d\r\n", line);
hbujanda 6:06522f3a6642 511 return Failure;
hbujanda 6:06522f3a6642 512 }
hbujanda 6:06522f3a6642 513
hbujanda 6:06522f3a6642 514 if (enable) {
hbujanda 6:06522f3a6642 515 ic |= dio_mask;
hbujanda 6:06522f3a6642 516 } else {
hbujanda 6:06522f3a6642 517 ic &= ~dio_mask;
hbujanda 6:06522f3a6642 518 }
hbujanda 6:06522f3a6642 519
hbujanda 6:06522f3a6642 520 cmdresp = set_param(remote, "IC", ic);
hbujanda 6:06522f3a6642 521 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
hbujanda 6:06522f3a6642 522 return Failure;
hbujanda 6:06522f3a6642 523 }
hbujanda 6:06522f3a6642 524
hbujanda 6:06522f3a6642 525 return Success;
hbujanda 6:06522f3a6642 526 }
hbujanda 7:3ac2a461ce76 527
hbujanda 7:3ac2a461ce76 528 RadioStatus XBeeDM::config_poll_destination(const RemoteXBee& destination)
hbujanda 7:3ac2a461ce76 529 {
hbujanda 7:3ac2a461ce76 530 uint32_t dh;
hbujanda 7:3ac2a461ce76 531 uint32_t dl;
hbujanda 7:3ac2a461ce76 532
hbujanda 7:3ac2a461ce76 533 if (destination.is_valid_addr64b()) {
hbujanda 7:3ac2a461ce76 534 const uint64_t dest64 = destination.get_addr64();
hbujanda 7:3ac2a461ce76 535 dh = (uint32_t)((dest64 >> 32) & 0xFFFFFFFF);
hbujanda 7:3ac2a461ce76 536 dl = (uint32_t)((dest64 & 0xFFFFFFFF));
hbujanda 7:3ac2a461ce76 537 } else {
hbujanda 7:3ac2a461ce76 538 digi_log(LogLevelError, "config_poll_destination: Invalid destination");
hbujanda 7:3ac2a461ce76 539 return Failure;
hbujanda 7:3ac2a461ce76 540 }
hbujanda 7:3ac2a461ce76 541
hbujanda 7:3ac2a461ce76 542 AtCmdFrame::AtCmdResp cmdresp;
hbujanda 7:3ac2a461ce76 543
hbujanda 7:3ac2a461ce76 544 cmdresp = set_param("DH", dh);
hbujanda 7:3ac2a461ce76 545 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
hbujanda 7:3ac2a461ce76 546 digi_log(LogLevelError, "config_poll_destination: error %d:\r\n", cmdresp);
hbujanda 7:3ac2a461ce76 547 return Failure;
hbujanda 7:3ac2a461ce76 548 }
hbujanda 7:3ac2a461ce76 549
hbujanda 7:3ac2a461ce76 550 cmdresp = set_param("DL", dl);
hbujanda 7:3ac2a461ce76 551 if (cmdresp != AtCmdFrame::AtCmdRespOk) {
hbujanda 7:3ac2a461ce76 552 digi_log(LogLevelError, "config_poll_destination: error %d:\r\n", cmdresp);
hbujanda 7:3ac2a461ce76 553 return Failure;
hbujanda 7:3ac2a461ce76 554 }
hbujanda 7:3ac2a461ce76 555
hbujanda 7:3ac2a461ce76 556 return Success;
hbujanda 7:3ac2a461ce76 557 }