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:
Mon Nov 11 09:39:58 2013 +0000
Revision:
7:e431d9d47db6
Child:
12:15597e45eea0
Added XBee class. Tested with XBee S1

Who changed what in which revision?

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