A library with drivers for different peripherals on the LPC4088 QuickStart Board or related add-on boards.

Dependencies:   FATFileSystem

Dependents:   LPC4088test LPC4088test_ledonly LPC4088test_deleteall LPC4088_RAMtest ... more

Committer:
embeddedartists
Date:
Thu Jan 30 08:50:47 2014 +0100
Revision:
12:15597e45eea0
Parent:
7:e431d9d47db6
Added license information

Who changed what in which revision?

UserRevisionLine numberNew contents of line
embeddedartists 12:15597e45eea0 1 /*
embeddedartists 12:15597e45eea0 2 * Copyright 2013 Embedded Artists AB
embeddedartists 12:15597e45eea0 3 *
embeddedartists 12:15597e45eea0 4 * Licensed under the Apache License, Version 2.0 (the "License");
embeddedartists 12:15597e45eea0 5 * you may not use this file except in compliance with the License.
embeddedartists 12:15597e45eea0 6 * You may obtain a copy of the License at
embeddedartists 12:15597e45eea0 7 *
embeddedartists 12:15597e45eea0 8 * http://www.apache.org/licenses/LICENSE-2.0
embeddedartists 12:15597e45eea0 9 *
embeddedartists 12:15597e45eea0 10 * Unless required by applicable law or agreed to in writing, software
embeddedartists 12:15597e45eea0 11 * distributed under the License is distributed on an "AS IS" BASIS,
embeddedartists 12:15597e45eea0 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
embeddedartists 12:15597e45eea0 13 * See the License for the specific language governing permissions and
embeddedartists 12:15597e45eea0 14 * limitations under the License.
embeddedartists 12:15597e45eea0 15 */
embeddedartists 7:e431d9d47db6 16
embeddedartists 7:e431d9d47db6 17 #include "mbed.h"
embeddedartists 7:e431d9d47db6 18 #include "mbed_debug.h"
embeddedartists 7:e431d9d47db6 19 #include "XBee.h"
embeddedartists 7:e431d9d47db6 20
embeddedartists 7:e431d9d47db6 21 #define XBEE_END_CMD ("\r")
embeddedartists 7:e431d9d47db6 22 #define CR (0x0D)
embeddedartists 7:e431d9d47db6 23 #define RESP_OK ("OK")
embeddedartists 7:e431d9d47db6 24
embeddedartists 7:e431d9d47db6 25 #define XBEE_START_DEL (0x7E)
embeddedartists 7:e431d9d47db6 26
embeddedartists 7:e431d9d47db6 27 #define XBEE_API_ID_TX_64 (0x00)
embeddedartists 7:e431d9d47db6 28 #define XBEE_API_ID_AT_CMD (0x08)
embeddedartists 7:e431d9d47db6 29 #define XBEE_API_ID_AT_RESP (0x88)
embeddedartists 7:e431d9d47db6 30 #define XBEE_API_ID_TX_STAT (0x89)
embeddedartists 7:e431d9d47db6 31 #define XBEE_API_ID_RX_64 (0x80)
embeddedartists 7:e431d9d47db6 32 #define XBEE_API_ID_RX_16 (0x81)
embeddedartists 7:e431d9d47db6 33 #define XBEE_API_ID_MOD_STAT (0x8A)
embeddedartists 7:e431d9d47db6 34
embeddedartists 7:e431d9d47db6 35 #define XBEE_MOD_STAT_HW_RESET (0)
embeddedartists 7:e431d9d47db6 36 #define XBEE_MOD_STAT_WD_RESET (1)
embeddedartists 7:e431d9d47db6 37 #define XBEE_MOD_STAT_ASSOC (2)
embeddedartists 7:e431d9d47db6 38 #define XBEE_MOD_STAT_DIASSOC (3)
embeddedartists 7:e431d9d47db6 39 #define XBEE_MOD_STAT_SYNC_LOST (4)
embeddedartists 7:e431d9d47db6 40 #define XBEE_MOD_STAT_COORD_REALG (5)
embeddedartists 7:e431d9d47db6 41 #define XBEE_MOD_STAT_COORD_START (6)
embeddedartists 7:e431d9d47db6 42
embeddedartists 7:e431d9d47db6 43 #define XBEE_TX_STAT_SUCCESS (0)
embeddedartists 7:e431d9d47db6 44 #define XBEE_TX_STAT_NOACK (1)
embeddedartists 7:e431d9d47db6 45 #define XBEE_TX_STAT_CCA_FAIL (2)
embeddedartists 7:e431d9d47db6 46 #define XBEE_TX_STAT_PURGED (3)
embeddedartists 7:e431d9d47db6 47
embeddedartists 7:e431d9d47db6 48 #define XBEE_RECV_FRAME_TO (2000)
embeddedartists 7:e431d9d47db6 49
embeddedartists 7:e431d9d47db6 50 XBee::XBee(PinName tx, PinName rx, PinName reset, PinName sleep) :
embeddedartists 7:e431d9d47db6 51 _serial(tx, rx), _reset(reset), _sleep(sleep) {
embeddedartists 7:e431d9d47db6 52 _serial.baud(9600);
embeddedartists 7:e431d9d47db6 53 _serial.format(8, Serial::None, 1);
embeddedartists 7:e431d9d47db6 54
embeddedartists 7:e431d9d47db6 55 _serial.attach(this, &XBee::uartRxIrq, Serial::RxIrq);
embeddedartists 7:e431d9d47db6 56
embeddedartists 7:e431d9d47db6 57 rxqIn = 0;
embeddedartists 7:e431d9d47db6 58 rxqOut = 0;
embeddedartists 7:e431d9d47db6 59 _rfFrameTimeout = 0;
embeddedartists 7:e431d9d47db6 60 _rfFrameTimer.reset();
embeddedartists 7:e431d9d47db6 61
embeddedartists 7:e431d9d47db6 62 _rfState = RfStateFrame;
embeddedartists 7:e431d9d47db6 63 _rfPos = 0;
embeddedartists 7:e431d9d47db6 64 _rfFrameLen = 0;
embeddedartists 7:e431d9d47db6 65 _rfFrameId = 0;
embeddedartists 7:e431d9d47db6 66
embeddedartists 7:e431d9d47db6 67 _initialized = false;
embeddedartists 7:e431d9d47db6 68 _type = Coordinator;
embeddedartists 7:e431d9d47db6 69
embeddedartists 7:e431d9d47db6 70 _addrHi = 0;
embeddedartists 7:e431d9d47db6 71 _addrLo = 0;
embeddedartists 7:e431d9d47db6 72 _rssi = 0;
embeddedartists 7:e431d9d47db6 73 _frameId = 0;
embeddedartists 7:e431d9d47db6 74 _txStatus = TxStatusOk;
embeddedartists 7:e431d9d47db6 75 _recvData = NULL;
embeddedartists 7:e431d9d47db6 76 _recvLen = 0;
embeddedartists 7:e431d9d47db6 77
embeddedartists 7:e431d9d47db6 78 // we enter sleep when sleep pin is high
embeddedartists 7:e431d9d47db6 79 _sleep = 0;
embeddedartists 7:e431d9d47db6 80 }
embeddedartists 7:e431d9d47db6 81
embeddedartists 7:e431d9d47db6 82 XBee::XBeeError XBee::init(XBeeType type, const char* panId) {
embeddedartists 7:e431d9d47db6 83 XBeeError err = Ok;
embeddedartists 7:e431d9d47db6 84 char idBuf[10];
embeddedartists 7:e431d9d47db6 85
embeddedartists 7:e431d9d47db6 86 resetModule();
embeddedartists 7:e431d9d47db6 87
embeddedartists 7:e431d9d47db6 88 _type = type;
embeddedartists 7:e431d9d47db6 89
embeddedartists 7:e431d9d47db6 90 do {
embeddedartists 7:e431d9d47db6 91
embeddedartists 7:e431d9d47db6 92 if (panId == NULL || strlen(panId) != 4) {
embeddedartists 7:e431d9d47db6 93 err = ArgumentError;
embeddedartists 7:e431d9d47db6 94 break;
embeddedartists 7:e431d9d47db6 95 }
embeddedartists 7:e431d9d47db6 96
embeddedartists 7:e431d9d47db6 97 err = commandMode();
embeddedartists 7:e431d9d47db6 98 if (err != Ok) {
embeddedartists 7:e431d9d47db6 99 debug("XBee: +++ failed\n");
embeddedartists 7:e431d9d47db6 100 break;
embeddedartists 7:e431d9d47db6 101 }
embeddedartists 7:e431d9d47db6 102
embeddedartists 7:e431d9d47db6 103 // set the sleep mode to Hibernate
embeddedartists 7:e431d9d47db6 104 err = atSet("ATSM1");
embeddedartists 7:e431d9d47db6 105 if (err != Ok) {
embeddedartists 7:e431d9d47db6 106 debug("Xbee: ATSM1 failed\r\n");
embeddedartists 7:e431d9d47db6 107 break;
embeddedartists 7:e431d9d47db6 108 }
embeddedartists 7:e431d9d47db6 109
embeddedartists 7:e431d9d47db6 110 // change PAN ID to EAEA
embeddedartists 7:e431d9d47db6 111 sprintf(idBuf, "ATID%s", panId);
embeddedartists 7:e431d9d47db6 112 err = atSet(idBuf);
embeddedartists 7:e431d9d47db6 113 if (err != Ok) {
embeddedartists 7:e431d9d47db6 114 debug("Xbee: ATID failed\r\n");
embeddedartists 7:e431d9d47db6 115 break;
embeddedartists 7:e431d9d47db6 116 }
embeddedartists 7:e431d9d47db6 117
embeddedartists 7:e431d9d47db6 118 // use 64-bit addressing
embeddedartists 7:e431d9d47db6 119 err = atSet("ATMYFFFE");
embeddedartists 7:e431d9d47db6 120 if (err != Ok) {
embeddedartists 7:e431d9d47db6 121 debug("Xbee: ATMYFFFE failed\r\n");
embeddedartists 7:e431d9d47db6 122 break;
embeddedartists 7:e431d9d47db6 123 }
embeddedartists 7:e431d9d47db6 124
embeddedartists 7:e431d9d47db6 125 // Coordinator
embeddedartists 7:e431d9d47db6 126 if (type == Coordinator) {
embeddedartists 7:e431d9d47db6 127
embeddedartists 7:e431d9d47db6 128 // - will not perform Active Scan to locate PAN ID
embeddedartists 7:e431d9d47db6 129 // - will not perform Energy Scan to determine free channel
embeddedartists 7:e431d9d47db6 130 // - allow End devices to associate with this coordinator
embeddedartists 7:e431d9d47db6 131 err = atSet("ATA24");
embeddedartists 7:e431d9d47db6 132 if (err != Ok) {
embeddedartists 7:e431d9d47db6 133 debug("Xbee: ATA24 failed\r\n");
embeddedartists 7:e431d9d47db6 134 break;
embeddedartists 7:e431d9d47db6 135 }
embeddedartists 7:e431d9d47db6 136
embeddedartists 7:e431d9d47db6 137 // set this node as coordinator
embeddedartists 7:e431d9d47db6 138 err = atSet("ATCE1");
embeddedartists 7:e431d9d47db6 139 if (err != Ok) {
embeddedartists 7:e431d9d47db6 140 debug("Xbee: ATCE1 failed\r\n");
embeddedartists 7:e431d9d47db6 141 break;
embeddedartists 7:e431d9d47db6 142 }
embeddedartists 7:e431d9d47db6 143 }
embeddedartists 7:e431d9d47db6 144 else {
embeddedartists 7:e431d9d47db6 145 // - only associates with Coordinator on matching PAN ID
embeddedartists 7:e431d9d47db6 146 // - only associates with Coordinator on matching channel
embeddedartists 7:e431d9d47db6 147 // - device attempts association until success
embeddedartists 7:e431d9d47db6 148 err = atSet("ATA14");
embeddedartists 7:e431d9d47db6 149 if (err != Ok) {
embeddedartists 7:e431d9d47db6 150 debug("Xbee: ATA14 failed\r\n");
embeddedartists 7:e431d9d47db6 151 break;
embeddedartists 7:e431d9d47db6 152 }
embeddedartists 7:e431d9d47db6 153 }
embeddedartists 7:e431d9d47db6 154
embeddedartists 7:e431d9d47db6 155
embeddedartists 7:e431d9d47db6 156 // change to API mode
embeddedartists 7:e431d9d47db6 157 err = atSet("ATAP1");
embeddedartists 7:e431d9d47db6 158 if (err != Ok) {
embeddedartists 7:e431d9d47db6 159 debug("Xbee: ATAP1 failed\r\n");
embeddedartists 7:e431d9d47db6 160 break;
embeddedartists 7:e431d9d47db6 161 }
embeddedartists 7:e431d9d47db6 162
embeddedartists 7:e431d9d47db6 163 } while(0);
embeddedartists 7:e431d9d47db6 164
embeddedartists 7:e431d9d47db6 165
embeddedartists 7:e431d9d47db6 166 return err;
embeddedartists 7:e431d9d47db6 167 }
embeddedartists 7:e431d9d47db6 168
embeddedartists 7:e431d9d47db6 169 void XBee::process() {
embeddedartists 7:e431d9d47db6 170 uint32_t len = 0;
embeddedartists 7:e431d9d47db6 171 char data = 0;
embeddedartists 7:e431d9d47db6 172
embeddedartists 7:e431d9d47db6 173 if (_rfFrameTimeout > 0 && (int)_rfFrameTimeout < _rfFrameTimer.read_ms()) {
embeddedartists 7:e431d9d47db6 174 _rfState = RfStateFrame;
embeddedartists 7:e431d9d47db6 175 debug("Xbee: Frame timer expired\r\n");
embeddedartists 7:e431d9d47db6 176 _rfFrameTimeout = 0;
embeddedartists 7:e431d9d47db6 177 _rfFrameTimer.stop();
embeddedartists 7:e431d9d47db6 178 }
embeddedartists 7:e431d9d47db6 179
embeddedartists 7:e431d9d47db6 180 if (!uartRxQIsEmpty()) {
embeddedartists 7:e431d9d47db6 181
embeddedartists 7:e431d9d47db6 182 len = uartReceive(&data, 1);
embeddedartists 7:e431d9d47db6 183 if (len > 0) {
embeddedartists 7:e431d9d47db6 184 processByte(data);
embeddedartists 7:e431d9d47db6 185 }
embeddedartists 7:e431d9d47db6 186
embeddedartists 7:e431d9d47db6 187 }
embeddedartists 7:e431d9d47db6 188 }
embeddedartists 7:e431d9d47db6 189
embeddedartists 7:e431d9d47db6 190 XBee::XBeeError XBee::getRemoteAddress(uint32_t* addrHi, uint32_t* addrLo) {
embeddedartists 7:e431d9d47db6 191 if (!_initialized) {
embeddedartists 7:e431d9d47db6 192 return NotInitializedError;
embeddedartists 7:e431d9d47db6 193 }
embeddedartists 7:e431d9d47db6 194
embeddedartists 7:e431d9d47db6 195 if (addrHi == NULL || addrLo == NULL) {
embeddedartists 7:e431d9d47db6 196 return ArgumentError;
embeddedartists 7:e431d9d47db6 197 }
embeddedartists 7:e431d9d47db6 198
embeddedartists 7:e431d9d47db6 199 *addrHi = _addrHi;
embeddedartists 7:e431d9d47db6 200 *addrLo = _addrLo;
embeddedartists 7:e431d9d47db6 201
embeddedartists 7:e431d9d47db6 202 return Ok;
embeddedartists 7:e431d9d47db6 203 }
embeddedartists 7:e431d9d47db6 204
embeddedartists 7:e431d9d47db6 205 XBee::XBeeError XBee::getRssi(uint8_t* rssi ) {
embeddedartists 7:e431d9d47db6 206 if (!_initialized) {
embeddedartists 7:e431d9d47db6 207 return NotInitializedError;
embeddedartists 7:e431d9d47db6 208 }
embeddedartists 7:e431d9d47db6 209
embeddedartists 7:e431d9d47db6 210 if (rssi == NULL) {
embeddedartists 7:e431d9d47db6 211 return ArgumentError;
embeddedartists 7:e431d9d47db6 212 }
embeddedartists 7:e431d9d47db6 213
embeddedartists 7:e431d9d47db6 214 *rssi = _rssi;
embeddedartists 7:e431d9d47db6 215
embeddedartists 7:e431d9d47db6 216 return Ok;
embeddedartists 7:e431d9d47db6 217 }
embeddedartists 7:e431d9d47db6 218
embeddedartists 7:e431d9d47db6 219 XBee::XBeeError XBee::getTxStatus(uint8_t* frameId, XBeeTxStatus* status) {
embeddedartists 7:e431d9d47db6 220 if (!_initialized) {
embeddedartists 7:e431d9d47db6 221 return NotInitializedError;
embeddedartists 7:e431d9d47db6 222 }
embeddedartists 7:e431d9d47db6 223
embeddedartists 7:e431d9d47db6 224 if (frameId == NULL || status == NULL) {
embeddedartists 7:e431d9d47db6 225 return ArgumentError;
embeddedartists 7:e431d9d47db6 226 }
embeddedartists 7:e431d9d47db6 227
embeddedartists 7:e431d9d47db6 228 *frameId = _frameId;
embeddedartists 7:e431d9d47db6 229 *status = _txStatus;
embeddedartists 7:e431d9d47db6 230
embeddedartists 7:e431d9d47db6 231 return Ok;
embeddedartists 7:e431d9d47db6 232 }
embeddedartists 7:e431d9d47db6 233
embeddedartists 7:e431d9d47db6 234 XBee::XBeeError XBee::getData(char** data, uint8_t* len) {
embeddedartists 7:e431d9d47db6 235 if (!_initialized) {
embeddedartists 7:e431d9d47db6 236 return NotInitializedError;
embeddedartists 7:e431d9d47db6 237 }
embeddedartists 7:e431d9d47db6 238
embeddedartists 7:e431d9d47db6 239 if (data == NULL || len == NULL) {
embeddedartists 7:e431d9d47db6 240 return ArgumentError;
embeddedartists 7:e431d9d47db6 241 }
embeddedartists 7:e431d9d47db6 242
embeddedartists 7:e431d9d47db6 243 *data = _recvData;
embeddedartists 7:e431d9d47db6 244 *len = _recvLen;
embeddedartists 7:e431d9d47db6 245
embeddedartists 7:e431d9d47db6 246 return Ok;
embeddedartists 7:e431d9d47db6 247 }
embeddedartists 7:e431d9d47db6 248
embeddedartists 7:e431d9d47db6 249 XBee::XBeeError XBee::send(uint32_t addrHi, uint32_t addrLo, char* data,
embeddedartists 7:e431d9d47db6 250 uint8_t len, uint8_t* frameId)
embeddedartists 7:e431d9d47db6 251 {
embeddedartists 7:e431d9d47db6 252 if (!_initialized) {
embeddedartists 7:e431d9d47db6 253 return NotInitializedError;
embeddedartists 7:e431d9d47db6 254 }
embeddedartists 7:e431d9d47db6 255
embeddedartists 7:e431d9d47db6 256 return apiTx64(addrHi, addrLo, data, len, frameId);
embeddedartists 7:e431d9d47db6 257 }
embeddedartists 7:e431d9d47db6 258
embeddedartists 7:e431d9d47db6 259 XBee::XBeeError XBee::discoverNodes() {
embeddedartists 7:e431d9d47db6 260 if (!_initialized) {
embeddedartists 7:e431d9d47db6 261 return NotInitializedError;
embeddedartists 7:e431d9d47db6 262 }
embeddedartists 7:e431d9d47db6 263
embeddedartists 7:e431d9d47db6 264 return apiAtCmd("ND", 0, false);
embeddedartists 7:e431d9d47db6 265 }
embeddedartists 7:e431d9d47db6 266
embeddedartists 7:e431d9d47db6 267
embeddedartists 7:e431d9d47db6 268 XBee::XBeeError XBee::enterSleep() {
embeddedartists 7:e431d9d47db6 269 _sleep = 1;
embeddedartists 7:e431d9d47db6 270
embeddedartists 7:e431d9d47db6 271 return Ok;
embeddedartists 7:e431d9d47db6 272 }
embeddedartists 7:e431d9d47db6 273
embeddedartists 7:e431d9d47db6 274 XBee::XBeeError XBee::exitSleep() {
embeddedartists 7:e431d9d47db6 275 _sleep = 0;
embeddedartists 7:e431d9d47db6 276
embeddedartists 7:e431d9d47db6 277 return Ok;
embeddedartists 7:e431d9d47db6 278 }
embeddedartists 7:e431d9d47db6 279
embeddedartists 7:e431d9d47db6 280
embeddedartists 7:e431d9d47db6 281 void XBee::uartRxIrq() {
embeddedartists 7:e431d9d47db6 282 while(_serial.readable()) {
embeddedartists 7:e431d9d47db6 283 uartRxQPut(_serial.getc());
embeddedartists 7:e431d9d47db6 284 }
embeddedartists 7:e431d9d47db6 285 }
embeddedartists 7:e431d9d47db6 286
embeddedartists 7:e431d9d47db6 287 void XBee::uartRxQPut(uint8_t data)
embeddedartists 7:e431d9d47db6 288 {
embeddedartists 7:e431d9d47db6 289 // full
embeddedartists 7:e431d9d47db6 290 if (rxqOut == (rxqIn + 1) % RX_BUF_SIZE) {
embeddedartists 7:e431d9d47db6 291 return;
embeddedartists 7:e431d9d47db6 292 }
embeddedartists 7:e431d9d47db6 293
embeddedartists 7:e431d9d47db6 294 rxq[rxqIn] = data;
embeddedartists 7:e431d9d47db6 295 rxqIn = (rxqIn + 1) % RX_BUF_SIZE;
embeddedartists 7:e431d9d47db6 296 }
embeddedartists 7:e431d9d47db6 297
embeddedartists 7:e431d9d47db6 298 uint8_t XBee::uartRxQGet()
embeddedartists 7:e431d9d47db6 299 {
embeddedartists 7:e431d9d47db6 300 uint8_t d = 0;
embeddedartists 7:e431d9d47db6 301 // empty
embeddedartists 7:e431d9d47db6 302 if (rxqIn == rxqOut) {
embeddedartists 7:e431d9d47db6 303 return 0;
embeddedartists 7:e431d9d47db6 304 }
embeddedartists 7:e431d9d47db6 305
embeddedartists 7:e431d9d47db6 306 d = rxq[rxqOut];
embeddedartists 7:e431d9d47db6 307 rxqOut = (rxqOut + 1) % RX_BUF_SIZE;
embeddedartists 7:e431d9d47db6 308
embeddedartists 7:e431d9d47db6 309 return d;
embeddedartists 7:e431d9d47db6 310 }
embeddedartists 7:e431d9d47db6 311
embeddedartists 7:e431d9d47db6 312 bool XBee::uartRxQIsEmpty()
embeddedartists 7:e431d9d47db6 313 {
embeddedartists 7:e431d9d47db6 314 return (rxqIn == rxqOut);
embeddedartists 7:e431d9d47db6 315 }
embeddedartists 7:e431d9d47db6 316
embeddedartists 7:e431d9d47db6 317 uint32_t XBee::uartReceive(char *buf, uint32_t buflen)
embeddedartists 7:e431d9d47db6 318 {
embeddedartists 7:e431d9d47db6 319
embeddedartists 7:e431d9d47db6 320 uint32_t pos = 0;
embeddedartists 7:e431d9d47db6 321
embeddedartists 7:e431d9d47db6 322 while(buflen > 0 && !uartRxQIsEmpty()) {
embeddedartists 7:e431d9d47db6 323 buf[pos] = uartRxQGet();
embeddedartists 7:e431d9d47db6 324 pos++;
embeddedartists 7:e431d9d47db6 325 buflen--;
embeddedartists 7:e431d9d47db6 326 }
embeddedartists 7:e431d9d47db6 327
embeddedartists 7:e431d9d47db6 328 return pos;
embeddedartists 7:e431d9d47db6 329 }
embeddedartists 7:e431d9d47db6 330
embeddedartists 7:e431d9d47db6 331 int32_t XBee::uartReadLine(char* buf, uint32_t bufLen, uint32_t timeout)
embeddedartists 7:e431d9d47db6 332 {
embeddedartists 7:e431d9d47db6 333 uint32_t pos = 0;
embeddedartists 7:e431d9d47db6 334 uint32_t len = 0;
embeddedartists 7:e431d9d47db6 335 Timer tim;
embeddedartists 7:e431d9d47db6 336
embeddedartists 7:e431d9d47db6 337 tim.reset();
embeddedartists 7:e431d9d47db6 338 tim.start();
embeddedartists 7:e431d9d47db6 339
embeddedartists 7:e431d9d47db6 340 while(pos < bufLen && tim.read_ms() < (int)timeout) {
embeddedartists 7:e431d9d47db6 341
embeddedartists 7:e431d9d47db6 342 len = uartReceive(&buf[pos], 1);
embeddedartists 7:e431d9d47db6 343 if (len > 0 && buf[pos] == CR) {
embeddedartists 7:e431d9d47db6 344 buf[pos] = '\0';
embeddedartists 7:e431d9d47db6 345 break;
embeddedartists 7:e431d9d47db6 346 }
embeddedartists 7:e431d9d47db6 347
embeddedartists 7:e431d9d47db6 348 pos += len;
embeddedartists 7:e431d9d47db6 349 }
embeddedartists 7:e431d9d47db6 350
embeddedartists 7:e431d9d47db6 351 if (pos >= bufLen) {
embeddedartists 7:e431d9d47db6 352 return BufTooSmallError;
embeddedartists 7:e431d9d47db6 353 }
embeddedartists 7:e431d9d47db6 354
embeddedartists 7:e431d9d47db6 355 if (tim.read_ms() > (int)timeout) {
embeddedartists 7:e431d9d47db6 356 return TimeOutError;
embeddedartists 7:e431d9d47db6 357 }
embeddedartists 7:e431d9d47db6 358
embeddedartists 7:e431d9d47db6 359 return pos;
embeddedartists 7:e431d9d47db6 360 }
embeddedartists 7:e431d9d47db6 361
embeddedartists 7:e431d9d47db6 362 void XBee::resetModule() {
embeddedartists 7:e431d9d47db6 363 // reset pulse must be at least 200 ns. Using 1 ms.
embeddedartists 7:e431d9d47db6 364 _reset = 0;
embeddedartists 7:e431d9d47db6 365 wait_ms(1);
embeddedartists 7:e431d9d47db6 366 _reset = 1;
embeddedartists 7:e431d9d47db6 367
embeddedartists 7:e431d9d47db6 368 // wait to make sure the module has started
embeddedartists 7:e431d9d47db6 369 wait_ms(500);
embeddedartists 7:e431d9d47db6 370 rxqIn = 0;
embeddedartists 7:e431d9d47db6 371 rxqOut = 0;
embeddedartists 7:e431d9d47db6 372 }
embeddedartists 7:e431d9d47db6 373
embeddedartists 7:e431d9d47db6 374 XBee::XBeeError XBee::commandMode() {
embeddedartists 7:e431d9d47db6 375 XBeeError err = Ok;
embeddedartists 7:e431d9d47db6 376 int32_t lineLen = 0;
embeddedartists 7:e431d9d47db6 377 char ebuf[10];
embeddedartists 7:e431d9d47db6 378
embeddedartists 7:e431d9d47db6 379 _serial.printf("+++");
embeddedartists 7:e431d9d47db6 380
embeddedartists 7:e431d9d47db6 381 lineLen = uartReadLine(ebuf, 10, 1200);
embeddedartists 7:e431d9d47db6 382
embeddedartists 7:e431d9d47db6 383 do {
embeddedartists 7:e431d9d47db6 384 if (lineLen < 0) {
embeddedartists 7:e431d9d47db6 385 // error while reading
embeddedartists 7:e431d9d47db6 386 err = ReadError;
embeddedartists 7:e431d9d47db6 387 break;
embeddedartists 7:e431d9d47db6 388 }
embeddedartists 7:e431d9d47db6 389
embeddedartists 7:e431d9d47db6 390 if (strcmp(RESP_OK, (char*)ebuf) != 0) {
embeddedartists 7:e431d9d47db6 391 // didn't receive OK
embeddedartists 7:e431d9d47db6 392 err = CmdError;
embeddedartists 7:e431d9d47db6 393 break;
embeddedartists 7:e431d9d47db6 394 }
embeddedartists 7:e431d9d47db6 395 } while(0);
embeddedartists 7:e431d9d47db6 396
embeddedartists 7:e431d9d47db6 397 return err;
embeddedartists 7:e431d9d47db6 398 }
embeddedartists 7:e431d9d47db6 399
embeddedartists 7:e431d9d47db6 400 XBee::XBeeError XBee::atGet(const char* atCmd, char* resp, uint32_t respLen)
embeddedartists 7:e431d9d47db6 401 {
embeddedartists 7:e431d9d47db6 402
embeddedartists 7:e431d9d47db6 403 int32_t lineLen = 0;
embeddedartists 7:e431d9d47db6 404 XBeeError err = Ok;
embeddedartists 7:e431d9d47db6 405
embeddedartists 7:e431d9d47db6 406 _serial.printf("%s%s", atCmd, XBEE_END_CMD);
embeddedartists 7:e431d9d47db6 407
embeddedartists 7:e431d9d47db6 408 do {
embeddedartists 7:e431d9d47db6 409
embeddedartists 7:e431d9d47db6 410 // a response is expected
embeddedartists 7:e431d9d47db6 411 if (resp != NULL && respLen > 0) {
embeddedartists 7:e431d9d47db6 412 lineLen = uartReadLine(resp, respLen, 1000);
embeddedartists 7:e431d9d47db6 413
embeddedartists 7:e431d9d47db6 414 if (lineLen < 0) {
embeddedartists 7:e431d9d47db6 415 // error while reading
embeddedartists 7:e431d9d47db6 416 err = ReadError;
embeddedartists 7:e431d9d47db6 417 break;
embeddedartists 7:e431d9d47db6 418 }
embeddedartists 7:e431d9d47db6 419
embeddedartists 7:e431d9d47db6 420 }
embeddedartists 7:e431d9d47db6 421
embeddedartists 7:e431d9d47db6 422 } while(0);
embeddedartists 7:e431d9d47db6 423
embeddedartists 7:e431d9d47db6 424 return err;
embeddedartists 7:e431d9d47db6 425 }
embeddedartists 7:e431d9d47db6 426
embeddedartists 7:e431d9d47db6 427 XBee::XBeeError XBee::atSet(const char* atCmd)
embeddedartists 7:e431d9d47db6 428 {
embeddedartists 7:e431d9d47db6 429 char b[10];
embeddedartists 7:e431d9d47db6 430 XBeeError err = Ok;
embeddedartists 7:e431d9d47db6 431
embeddedartists 7:e431d9d47db6 432 err = atGet(atCmd, b, 10);
embeddedartists 7:e431d9d47db6 433 if (err == Ok) {
embeddedartists 7:e431d9d47db6 434
embeddedartists 7:e431d9d47db6 435 if (strcmp(RESP_OK, (char*)b) != 0) {
embeddedartists 7:e431d9d47db6 436 // didn't receive OK
embeddedartists 7:e431d9d47db6 437 err = CmdError;
embeddedartists 7:e431d9d47db6 438 }
embeddedartists 7:e431d9d47db6 439 }
embeddedartists 7:e431d9d47db6 440
embeddedartists 7:e431d9d47db6 441 return err;
embeddedartists 7:e431d9d47db6 442 }
embeddedartists 7:e431d9d47db6 443
embeddedartists 7:e431d9d47db6 444 void XBee::processByte(char data)
embeddedartists 7:e431d9d47db6 445 {
embeddedartists 7:e431d9d47db6 446 switch(_rfState) {
embeddedartists 7:e431d9d47db6 447 case RfStateFrame:
embeddedartists 7:e431d9d47db6 448 if (data == XBEE_START_DEL) {
embeddedartists 7:e431d9d47db6 449 _rfPos = 0;
embeddedartists 7:e431d9d47db6 450 _rfFrameLen = 0;
embeddedartists 7:e431d9d47db6 451 _rfState = RfStateLength;
embeddedartists 7:e431d9d47db6 452
embeddedartists 7:e431d9d47db6 453 // start timer to make sure an entire frame is received
embeddedartists 7:e431d9d47db6 454 // within a specific time
embeddedartists 7:e431d9d47db6 455 _rfFrameTimeout = XBEE_RECV_FRAME_TO;
embeddedartists 7:e431d9d47db6 456 _rfFrameTimer.reset();
embeddedartists 7:e431d9d47db6 457 _rfFrameTimer.start();
embeddedartists 7:e431d9d47db6 458 }
embeddedartists 7:e431d9d47db6 459
embeddedartists 7:e431d9d47db6 460 break;
embeddedartists 7:e431d9d47db6 461 case RfStateLength:
embeddedartists 7:e431d9d47db6 462 _rfFrameLen |= (data << (8*(1-_rfPos)));
embeddedartists 7:e431d9d47db6 463 _rfPos++;
embeddedartists 7:e431d9d47db6 464 if (_rfPos == 2) {
embeddedartists 7:e431d9d47db6 465 _rfPos = 0;
embeddedartists 7:e431d9d47db6 466 _rfState = RfStateData;
embeddedartists 7:e431d9d47db6 467
embeddedartists 7:e431d9d47db6 468 if (_rfFrameLen > XBEE_BUF_SZ) {
embeddedartists 7:e431d9d47db6 469 debug("Xbee: Frame len %d > max buffer len %d\r\n",
embeddedartists 7:e431d9d47db6 470 (int)_rfFrameLen, (int)XBEE_BUF_SZ);
embeddedartists 7:e431d9d47db6 471 _rfFrameLen = XBEE_BUF_SZ;
embeddedartists 7:e431d9d47db6 472 }
embeddedartists 7:e431d9d47db6 473
embeddedartists 7:e431d9d47db6 474 }
embeddedartists 7:e431d9d47db6 475 break;
embeddedartists 7:e431d9d47db6 476 case RfStateData:
embeddedartists 7:e431d9d47db6 477 _rfBuf[_rfPos++] = data;
embeddedartists 7:e431d9d47db6 478 // read up until checksum (1 byte)
embeddedartists 7:e431d9d47db6 479 if (_rfPos == _rfFrameLen+1) {
embeddedartists 7:e431d9d47db6 480 _rfState = RfStateFrame;
embeddedartists 7:e431d9d47db6 481
embeddedartists 7:e431d9d47db6 482 // cancel timer
embeddedartists 7:e431d9d47db6 483 _rfFrameTimeout = 0;
embeddedartists 7:e431d9d47db6 484 _rfFrameTimer.stop();
embeddedartists 7:e431d9d47db6 485
embeddedartists 7:e431d9d47db6 486 processFrame(_rfBuf, _rfPos);
embeddedartists 7:e431d9d47db6 487 }
embeddedartists 7:e431d9d47db6 488 break;
embeddedartists 7:e431d9d47db6 489
embeddedartists 7:e431d9d47db6 490 }
embeddedartists 7:e431d9d47db6 491 }
embeddedartists 7:e431d9d47db6 492
embeddedartists 7:e431d9d47db6 493 void XBee::processFrame(char* buf, uint32_t len)
embeddedartists 7:e431d9d47db6 494 {
embeddedartists 7:e431d9d47db6 495
embeddedartists 7:e431d9d47db6 496 uint32_t addrLo = 0;
embeddedartists 7:e431d9d47db6 497 uint32_t addrHi = 0;
embeddedartists 7:e431d9d47db6 498 char* b = NULL;
embeddedartists 7:e431d9d47db6 499 uint32_t bLen = 0;
embeddedartists 7:e431d9d47db6 500
embeddedartists 7:e431d9d47db6 501 if (len < 2) {
embeddedartists 7:e431d9d47db6 502 debug("Xbee: Invalid frame length (%d)\r\n", (int)len);
embeddedartists 7:e431d9d47db6 503 return;
embeddedartists 7:e431d9d47db6 504 }
embeddedartists 7:e431d9d47db6 505
embeddedartists 7:e431d9d47db6 506 // verify checksum
embeddedartists 7:e431d9d47db6 507 if (checksum(buf, len) != 0) {
embeddedartists 7:e431d9d47db6 508 debug("Xbee: Invalid checksum\r\n");
embeddedartists 7:e431d9d47db6 509 return;
embeddedartists 7:e431d9d47db6 510 }
embeddedartists 7:e431d9d47db6 511
embeddedartists 7:e431d9d47db6 512 switch(buf[0]) {
embeddedartists 7:e431d9d47db6 513 case XBEE_API_ID_AT_RESP:
embeddedartists 7:e431d9d47db6 514 if (len < 5) {
embeddedartists 7:e431d9d47db6 515 debug("Xbee: AT resp data too small: %d\r\n ", (int)len);
embeddedartists 7:e431d9d47db6 516 return;
embeddedartists 7:e431d9d47db6 517 }
embeddedartists 7:e431d9d47db6 518
embeddedartists 7:e431d9d47db6 519 // there is a value
embeddedartists 7:e431d9d47db6 520 if (len > 6) {
embeddedartists 7:e431d9d47db6 521 b = &buf[5];
embeddedartists 7:e431d9d47db6 522 bLen = len-5-1;
embeddedartists 7:e431d9d47db6 523 }
embeddedartists 7:e431d9d47db6 524
embeddedartists 7:e431d9d47db6 525 handleAtResponse(buf[1], &buf[2], buf[4], b, bLen);
embeddedartists 7:e431d9d47db6 526 break;
embeddedartists 7:e431d9d47db6 527 case XBEE_API_ID_TX_STAT:
embeddedartists 7:e431d9d47db6 528 handleTxStatus(buf[1], buf[2]);
embeddedartists 7:e431d9d47db6 529 break;
embeddedartists 7:e431d9d47db6 530 case XBEE_API_ID_RX_64:
embeddedartists 7:e431d9d47db6 531 if (len < 12) {
embeddedartists 7:e431d9d47db6 532 debug("Xbee: RX data too small: %d\r\n ", (int)len);
embeddedartists 7:e431d9d47db6 533 return;
embeddedartists 7:e431d9d47db6 534 }
embeddedartists 7:e431d9d47db6 535 addrHi = bufTo32bitInt(&buf[1]);
embeddedartists 7:e431d9d47db6 536 addrLo = bufTo32bitInt(&buf[5]);
embeddedartists 7:e431d9d47db6 537
embeddedartists 7:e431d9d47db6 538 processData(addrHi, addrLo, buf[9], buf[10], &buf[11], len-11-1);
embeddedartists 7:e431d9d47db6 539 break;
embeddedartists 7:e431d9d47db6 540 case XBEE_API_ID_RX_16:
embeddedartists 7:e431d9d47db6 541 debug("Xbee: RX 16 bit (unhandled)\r\n");
embeddedartists 7:e431d9d47db6 542 break;
embeddedartists 7:e431d9d47db6 543 case XBEE_API_ID_MOD_STAT:
embeddedartists 7:e431d9d47db6 544 handleModemStatus(buf[1]);
embeddedartists 7:e431d9d47db6 545 break;
embeddedartists 7:e431d9d47db6 546 default:
embeddedartists 7:e431d9d47db6 547 debug("Xbee: Unhandled API ID: %x\r\n ", buf[0]);
embeddedartists 7:e431d9d47db6 548
embeddedartists 7:e431d9d47db6 549 break;
embeddedartists 7:e431d9d47db6 550 }
embeddedartists 7:e431d9d47db6 551
embeddedartists 7:e431d9d47db6 552 }
embeddedartists 7:e431d9d47db6 553
embeddedartists 7:e431d9d47db6 554 void XBee::handleAtResponse(uint8_t frameId, char* atBuf, uint8_t status,
embeddedartists 7:e431d9d47db6 555 char* valueBuf, uint32_t valueLen)
embeddedartists 7:e431d9d47db6 556 {
embeddedartists 7:e431d9d47db6 557
embeddedartists 7:e431d9d47db6 558 if (strncmp("ND", (char*)atBuf, 2) == 0) {
embeddedartists 7:e431d9d47db6 559 handleDiscovery(status, valueBuf, valueLen);
embeddedartists 7:e431d9d47db6 560 }
embeddedartists 7:e431d9d47db6 561
embeddedartists 7:e431d9d47db6 562 }
embeddedartists 7:e431d9d47db6 563
embeddedartists 7:e431d9d47db6 564 void XBee::handleDiscovery(uint8_t status, char* buf, uint32_t len)
embeddedartists 7:e431d9d47db6 565 {
embeddedartists 7:e431d9d47db6 566
embeddedartists 7:e431d9d47db6 567 if (status == 0 && len >= 11) {
embeddedartists 7:e431d9d47db6 568 _addrHi = bufTo32bitInt(&buf[2]);
embeddedartists 7:e431d9d47db6 569 _addrLo = bufTo32bitInt(&buf[6]);
embeddedartists 7:e431d9d47db6 570 _rssi = buf[10];
embeddedartists 7:e431d9d47db6 571
embeddedartists 7:e431d9d47db6 572 _callbacks[CbNodeFound].call();
embeddedartists 7:e431d9d47db6 573
embeddedartists 7:e431d9d47db6 574 }
embeddedartists 7:e431d9d47db6 575 }
embeddedartists 7:e431d9d47db6 576
embeddedartists 7:e431d9d47db6 577 void XBee::handleTxStatus(uint8_t frameId, uint8_t status)
embeddedartists 7:e431d9d47db6 578 {
embeddedartists 7:e431d9d47db6 579 _frameId = frameId;
embeddedartists 7:e431d9d47db6 580 switch(status) {
embeddedartists 7:e431d9d47db6 581 case XBEE_TX_STAT_SUCCESS:
embeddedartists 7:e431d9d47db6 582 _txStatus = TxStatusOk;
embeddedartists 7:e431d9d47db6 583 break;
embeddedartists 7:e431d9d47db6 584 case XBEE_TX_STAT_NOACK:
embeddedartists 7:e431d9d47db6 585 _txStatus = TxStatusNoAck;
embeddedartists 7:e431d9d47db6 586 break;
embeddedartists 7:e431d9d47db6 587 case XBEE_TX_STAT_CCA_FAIL:
embeddedartists 7:e431d9d47db6 588 _txStatus = TxStatusCCA;
embeddedartists 7:e431d9d47db6 589 break;
embeddedartists 7:e431d9d47db6 590 case XBEE_TX_STAT_PURGED:
embeddedartists 7:e431d9d47db6 591 _txStatus = TxStatusPurged;
embeddedartists 7:e431d9d47db6 592 break;
embeddedartists 7:e431d9d47db6 593 }
embeddedartists 7:e431d9d47db6 594
embeddedartists 7:e431d9d47db6 595 _callbacks[CbTxStat].call();
embeddedartists 7:e431d9d47db6 596
embeddedartists 7:e431d9d47db6 597 }
embeddedartists 7:e431d9d47db6 598
embeddedartists 7:e431d9d47db6 599 void XBee::processData(uint32_t addrHi, uint32_t addrLo, uint8_t rssi,
embeddedartists 7:e431d9d47db6 600 uint8_t opt, char* buf, uint32_t len)
embeddedartists 7:e431d9d47db6 601 {
embeddedartists 7:e431d9d47db6 602 _addrHi = addrHi;
embeddedartists 7:e431d9d47db6 603 _addrLo = addrLo;
embeddedartists 7:e431d9d47db6 604 _rssi = rssi;
embeddedartists 7:e431d9d47db6 605 _recvData = buf;
embeddedartists 7:e431d9d47db6 606 _recvLen = len;
embeddedartists 7:e431d9d47db6 607
embeddedartists 7:e431d9d47db6 608 _callbacks[CbDataAvailable].call();
embeddedartists 7:e431d9d47db6 609 }
embeddedartists 7:e431d9d47db6 610
embeddedartists 7:e431d9d47db6 611 void XBee::handleModemStatus(uint8_t status) {
embeddedartists 7:e431d9d47db6 612
embeddedartists 7:e431d9d47db6 613 if (_type == Coordinator && status == XBEE_MOD_STAT_COORD_START) {
embeddedartists 7:e431d9d47db6 614 _initialized = true;
embeddedartists 7:e431d9d47db6 615 _callbacks[CbDeviceUp].call();
embeddedartists 7:e431d9d47db6 616 }
embeddedartists 7:e431d9d47db6 617 else if (_type == EndDevice && status == XBEE_MOD_STAT_ASSOC) {
embeddedartists 7:e431d9d47db6 618 _initialized = 1;
embeddedartists 7:e431d9d47db6 619 _callbacks[CbDeviceUp].call();
embeddedartists 7:e431d9d47db6 620 }
embeddedartists 7:e431d9d47db6 621 else if (_type == EndDevice && status == XBEE_MOD_STAT_DIASSOC) {
embeddedartists 7:e431d9d47db6 622 _initialized = false;
embeddedartists 7:e431d9d47db6 623 _callbacks[CbDeviceDown].call();
embeddedartists 7:e431d9d47db6 624 }
embeddedartists 7:e431d9d47db6 625
embeddedartists 7:e431d9d47db6 626 }
embeddedartists 7:e431d9d47db6 627
embeddedartists 7:e431d9d47db6 628 char XBee::checksum(char* buf, uint32_t len)
embeddedartists 7:e431d9d47db6 629 {
embeddedartists 7:e431d9d47db6 630 int i = 0;
embeddedartists 7:e431d9d47db6 631 char cs = 0;
embeddedartists 7:e431d9d47db6 632
embeddedartists 7:e431d9d47db6 633 for (i = 0; i < (int)len; i++) {
embeddedartists 7:e431d9d47db6 634 cs += buf[i];
embeddedartists 7:e431d9d47db6 635 }
embeddedartists 7:e431d9d47db6 636
embeddedartists 7:e431d9d47db6 637 return (0xFF - cs);
embeddedartists 7:e431d9d47db6 638 }
embeddedartists 7:e431d9d47db6 639
embeddedartists 7:e431d9d47db6 640 uint32_t XBee::bufTo32bitInt(const char* buf)
embeddedartists 7:e431d9d47db6 641 {
embeddedartists 7:e431d9d47db6 642 uint32_t v = 0;
embeddedartists 7:e431d9d47db6 643
embeddedartists 7:e431d9d47db6 644 v |= (buf[0] << 24);
embeddedartists 7:e431d9d47db6 645 v |= (buf[1] << 16);
embeddedartists 7:e431d9d47db6 646 v |= (buf[2] << 8);
embeddedartists 7:e431d9d47db6 647 v |= (buf[3]);
embeddedartists 7:e431d9d47db6 648
embeddedartists 7:e431d9d47db6 649 return v;
embeddedartists 7:e431d9d47db6 650 }
embeddedartists 7:e431d9d47db6 651
embeddedartists 7:e431d9d47db6 652 void XBee::int32bitToBuf(uint32_t v, char* buf)
embeddedartists 7:e431d9d47db6 653 {
embeddedartists 7:e431d9d47db6 654
embeddedartists 7:e431d9d47db6 655 buf[0] = ((v >> 24) & 0xff);
embeddedartists 7:e431d9d47db6 656 buf[1] = ((v >> 16) & 0xff);
embeddedartists 7:e431d9d47db6 657 buf[2] = ((v >> 8) & 0xff);
embeddedartists 7:e431d9d47db6 658 buf[3] = ((v >> 0) & 0xff);
embeddedartists 7:e431d9d47db6 659
embeddedartists 7:e431d9d47db6 660 }
embeddedartists 7:e431d9d47db6 661
embeddedartists 7:e431d9d47db6 662
embeddedartists 7:e431d9d47db6 663 XBee::XBeeError XBee::apiTx64(uint32_t addrHi, uint32_t addrLo, char* data,
embeddedartists 7:e431d9d47db6 664 uint32_t len, uint8_t* frameId)
embeddedartists 7:e431d9d47db6 665 {
embeddedartists 7:e431d9d47db6 666 char buf[100];
embeddedartists 7:e431d9d47db6 667
embeddedartists 7:e431d9d47db6 668
embeddedartists 7:e431d9d47db6 669 // limiting to 85 bytes data. Remaining 15 bytes belong to the
embeddedartists 7:e431d9d47db6 670 // frame
embeddedartists 7:e431d9d47db6 671 if (len > 85) {
embeddedartists 7:e431d9d47db6 672 return ArgumentError;
embeddedartists 7:e431d9d47db6 673 }
embeddedartists 7:e431d9d47db6 674
embeddedartists 7:e431d9d47db6 675 buf[0] = XBEE_START_DEL;
embeddedartists 7:e431d9d47db6 676
embeddedartists 7:e431d9d47db6 677 // length
embeddedartists 7:e431d9d47db6 678 buf[1] = 0;
embeddedartists 7:e431d9d47db6 679 buf[2] = 11+len;
embeddedartists 7:e431d9d47db6 680
embeddedartists 7:e431d9d47db6 681 // AP ID
embeddedartists 7:e431d9d47db6 682 buf[3] = XBEE_API_ID_TX_64;
embeddedartists 7:e431d9d47db6 683
embeddedartists 7:e431d9d47db6 684 // frame ID
embeddedartists 7:e431d9d47db6 685 buf[4] = getFrameId();
embeddedartists 7:e431d9d47db6 686
embeddedartists 7:e431d9d47db6 687
embeddedartists 7:e431d9d47db6 688 // address
embeddedartists 7:e431d9d47db6 689 int32bitToBuf(addrHi, &buf[5]);
embeddedartists 7:e431d9d47db6 690 int32bitToBuf(addrLo, &buf[9]);
embeddedartists 7:e431d9d47db6 691
embeddedartists 7:e431d9d47db6 692 // options
embeddedartists 7:e431d9d47db6 693 buf[13] = 0;
embeddedartists 7:e431d9d47db6 694
embeddedartists 7:e431d9d47db6 695 // data
embeddedartists 7:e431d9d47db6 696 memcpy(&buf[14], data, len);
embeddedartists 7:e431d9d47db6 697
embeddedartists 7:e431d9d47db6 698 // checksum
embeddedartists 7:e431d9d47db6 699 buf[14+len] = checksum(&buf[3], buf[2]);
embeddedartists 7:e431d9d47db6 700
embeddedartists 7:e431d9d47db6 701 if (frameId != NULL) {
embeddedartists 7:e431d9d47db6 702 *frameId = buf[4];
embeddedartists 7:e431d9d47db6 703 }
embeddedartists 7:e431d9d47db6 704
embeddedartists 7:e431d9d47db6 705
embeddedartists 7:e431d9d47db6 706 for (int i = 0; i < (15+len); i++) {
embeddedartists 7:e431d9d47db6 707 _serial.putc(buf[i]);
embeddedartists 7:e431d9d47db6 708 }
embeddedartists 7:e431d9d47db6 709
embeddedartists 7:e431d9d47db6 710
embeddedartists 7:e431d9d47db6 711 return Ok;
embeddedartists 7:e431d9d47db6 712 }
embeddedartists 7:e431d9d47db6 713
embeddedartists 7:e431d9d47db6 714 XBee::XBeeError XBee::apiAtCmd(const char* atCmd, uint32_t param, bool useParameter)
embeddedartists 7:e431d9d47db6 715 {
embeddedartists 7:e431d9d47db6 716 char buf[12];
embeddedartists 7:e431d9d47db6 717 int pos = 0;
embeddedartists 7:e431d9d47db6 718
embeddedartists 7:e431d9d47db6 719 buf[0] = XBEE_START_DEL;
embeddedartists 7:e431d9d47db6 720
embeddedartists 7:e431d9d47db6 721 // length
embeddedartists 7:e431d9d47db6 722 buf[1] = 0;
embeddedartists 7:e431d9d47db6 723 buf[2] = 4;
embeddedartists 7:e431d9d47db6 724 if (useParameter) {
embeddedartists 7:e431d9d47db6 725 buf[2] += 4;
embeddedartists 7:e431d9d47db6 726 }
embeddedartists 7:e431d9d47db6 727
embeddedartists 7:e431d9d47db6 728 // AP ID
embeddedartists 7:e431d9d47db6 729 buf[3] = XBEE_API_ID_AT_CMD;
embeddedartists 7:e431d9d47db6 730
embeddedartists 7:e431d9d47db6 731 // frame ID
embeddedartists 7:e431d9d47db6 732 buf[4] = getFrameId();
embeddedartists 7:e431d9d47db6 733
embeddedartists 7:e431d9d47db6 734 // AT cmd
embeddedartists 7:e431d9d47db6 735 buf[5] = atCmd[0];
embeddedartists 7:e431d9d47db6 736 buf[6] = atCmd[1];
embeddedartists 7:e431d9d47db6 737 pos = 7;
embeddedartists 7:e431d9d47db6 738
embeddedartists 7:e431d9d47db6 739 // AT parameter
embeddedartists 7:e431d9d47db6 740 if (useParameter) {
embeddedartists 7:e431d9d47db6 741 buf[pos++] = ((param >> 24) & 0xff);
embeddedartists 7:e431d9d47db6 742 buf[pos++] = ((param >> 16) & 0xff);
embeddedartists 7:e431d9d47db6 743 buf[pos++] = ((param >> 8) & 0xff);
embeddedartists 7:e431d9d47db6 744 buf[pos++] = ((param >> 0) & 0xff);
embeddedartists 7:e431d9d47db6 745 }
embeddedartists 7:e431d9d47db6 746
embeddedartists 7:e431d9d47db6 747 // checksum
embeddedartists 7:e431d9d47db6 748 buf[pos] = checksum(&buf[3], pos-3);
embeddedartists 7:e431d9d47db6 749 pos++;
embeddedartists 7:e431d9d47db6 750
embeddedartists 7:e431d9d47db6 751 for (int i = 0; i < pos; i++) {
embeddedartists 7:e431d9d47db6 752 _serial.putc(buf[i]);
embeddedartists 7:e431d9d47db6 753 }
embeddedartists 7:e431d9d47db6 754
embeddedartists 7:e431d9d47db6 755 return Ok;
embeddedartists 7:e431d9d47db6 756 }
embeddedartists 7:e431d9d47db6 757
embeddedartists 7:e431d9d47db6 758 uint8_t XBee::getFrameId(void)
embeddedartists 7:e431d9d47db6 759 {
embeddedartists 7:e431d9d47db6 760 _rfFrameId++;
embeddedartists 7:e431d9d47db6 761 if (_rfFrameId == 0) {
embeddedartists 7:e431d9d47db6 762 _rfFrameId = 1;
embeddedartists 7:e431d9d47db6 763 }
embeddedartists 7:e431d9d47db6 764
embeddedartists 7:e431d9d47db6 765 return _rfFrameId;
embeddedartists 7:e431d9d47db6 766 }