Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 0:ea8459db49ef, committed 2011-11-01
- Comitter:
- yamaguch
- Date:
- Tue Nov 01 09:04:12 2011 +0000
- Child:
- 1:58a1c083cf8d
- Commit message:
- 0.9
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Dump.cpp Tue Nov 01 09:04:12 2011 +0000
@@ -0,0 +1,147 @@
+/*
+Copyright (c) 2011, Senio Networks, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "XBee.h"
+#include "macros.h"
+#include <ctype.h>
+
+void XBee::dump() {
+ if (received != out || (in == out && free != 0))
+ return;
+
+ switch (getFrameType(buf[INDEX(out + 2)])) {
+ case ATCommandResponse: {
+ char id, name[2], status, data[16];
+ int length = 0;
+ scan(FrameID, &id);
+ scan(ATCommand, name, sizeof(name));
+ scan(Status, &status);
+ scan(CommandData, data, sizeof(data), &length);
+ mon.printf("ATCommandResponse, Id=%d, Nm=%c%c, St=%02X, ", id & 255, name[0], name[1], status);
+ if (name[0] == 'I' && name[1] == 'S' && status == 0)
+ dumpIOSample(data, length);
+ else
+ dump(data, length);
+ }
+ break;
+
+ case ModemStatus: {
+ char status;
+ scan(Status, &status);
+ mon.printf("ModemStatus, St=%02X\n", status);
+ }
+ break;
+
+ case ZigBeeTransmitStatus: {
+ char id, address16[2], retry, delivery, discovery;
+ scan(FrameID, &id);
+ scan(Address16, address16, sizeof(address16));
+ scan(RetryCount, &retry);
+ scan(DeliveryStatus, &delivery);
+ scan(DiscoveryStatus, &discovery);
+ mon.printf("ZigBeeTransmitStatus, Id=%d, ad=%02X%02X, Rty=%d, Dlv=%02X, Dsc=%02X\n",
+ id & 255, address16[0], address16[1], retry & 255, delivery, discovery);
+ }
+ break;
+
+ case ZigBeeReceivePacket: {
+ char address64[8], address16[2], options, data[32];
+ int length = 0;
+ scan(Address64, address64, sizeof(address64));
+ scan(Address16, address16, sizeof(address16));
+ scan(ReceiveOptions, &options);
+ scan(ReceivedData, data, sizeof(data), &length);
+ mon.printf("ZigBeeReceivePacket, AD=%02X%02X%02X%02X %02X%02X%02X%02X, ad=%02X%02X, Op=%02X, Length=%d, ",
+ address64[0], address64[1], address64[2], address64[3], address64[4], address64[5],
+ address64[6], address64[7], address16[0], address16[1], options, length);
+ dump(data, min(sizeof(data), length));
+ }
+ break;
+
+ case ZigBeeIODataSampleRxIndicator: {
+ char address64[8], address16[2], options, data[16];
+ int length = 0;
+ scan(Address64, address64, sizeof(address64));
+ scan(Address16, address16, sizeof(address16));
+ scan(ReceiveOptions, &options);
+ scan(ReceivedData, data, sizeof(data), &length);
+ mon.printf("ZigBeeIODataSampleRxIndicator, AD=%02X%02X%02X%02X %02X%02X%02X%02X, ad=%02X%02X, Op=%02X, ",
+ address64[0], address64[1], address64[2], address64[3], address64[4], address64[5],
+ address64[6], address64[7], address16[0], address16[1], options);
+ dumpIOSample(data, length);
+ }
+ break;
+
+ case RemoteCommandResponse: {
+ char address64[8], address16[2], id, name[2], status, data[16];
+ int length = 0;
+ scan(Address64, address64, sizeof(address64));
+ scan(Address16, address16, sizeof(address16));
+ scan(FrameID, &id);
+ scan(ATCommand, name, sizeof(name));
+ scan(Status, &status);
+ scan(CommandData, data, sizeof(data), &length);
+ mon.printf("RemoteCommandResponse, AD=%02X%02X%02X%02X %02X%02X%02X%02X, ad=%02X%02X, Id=%d, Nm=%c%c, St=%02X, ",
+ address64[0], address64[1], address64[2], address64[3], address64[4], address64[5],
+ address64[6], address64[7], address16[0], address16[1], id & 255, name[0], name[1], status);
+ if (name[0] == 'I' && name[1] == 'S' && status == 0)
+ dumpIOSample(data, length);
+ else
+ dump(data, length);
+ }
+ break;
+
+ default: {
+ char data[32];
+ int length = 0;
+ scan(RawData, data, sizeof(data), &length);
+ mon.printf("Frametype:%02X, Length=%d, Data=", buf[INDEX(out + 2)] & 255, length);
+ dump(data, min(sizeof(data), length));
+ }
+ }
+}
+
+void XBee::dumpAll() {
+ mon.printf("cur = %04X\n", cur);
+ mon.printf("in = %04X\n", in);
+ mon.printf("out = %04X\n", out);
+ mon.printf("received = %04X\n", received);
+ mon.printf("free = %d\n", free);
+ for (int i = 0; i < BUFSIZE; i += 16) {
+ mon.printf("%04X: ", i);
+ dump(buf + i, 16);
+ }
+}
+
+void XBee::dump(char* data, int length) {
+ for (int i = 0; i < length; i++) mon.printf("%02X", data[i]);
+ mon.printf(" | ");
+ for (int i = 0; i < length; i++) mon.printf("%c", isprint(data[i]) ? data[i] : '.');
+ mon.printf("\n");
+}
+
+void XBee::dumpIOSample(char* data, int length) {
+ if (length > 0) {
+ IOSample sample(data);
+ sample.print(mon);
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/IOSample.cpp Tue Nov 01 09:04:12 2011 +0000
@@ -0,0 +1,83 @@
+/*
+Copyright (c) 2011, Senio Networks, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "IOSample.h"
+
+IOSample::BitArray::BitArray(int mask, int values) {
+ this->mask = mask;
+ this->values = values;
+}
+
+int IOSample::BitArray::operator[](int i) {
+ return valueAt(i);
+}
+
+int IOSample::BitArray::valueAt(int i) {
+ if (mask & 1 << i) {
+ return (values >> i) & 1;
+ } else
+ return -1;
+}
+
+IOSample::IntArray::IntArray(int mask, char *value) {
+ this->mask = mask;
+ this->values = value;
+}
+
+int IOSample::IntArray::operator[](int i) {
+ return valueAt(i);
+}
+
+int IOSample::IntArray::valueAt(int i) {
+ if (mask & 1 << i) {
+ int count = 0;
+ for (int j = 0; j < i; j++) {
+ if (mask & 1 << j) count++;
+ }
+ char *p = values + 2 * count;
+ return (p[0] << 8) | p[1];
+ } else
+ return -1;
+}
+
+IOSample::IOSample(char *data)
+ : dio((data[1] << 8 | data[2]), (data[1] << 8 | data[2]) ? (data[4] << 8 | data[5]) : 0),
+ ad(data[3], (data[1] << 8 | data[2]) ? data + 6 : data + 4) {}
+
+void IOSample::print(Serial& mon) {
+ bool first = true;
+ for (int i = 0; i < 16; i++)
+ if (dio[i] != -1)
+ if (first) {
+ mon.printf("DIO%d=%d", i, dio[i]);
+ first = false;
+ } else
+ mon.printf(", DIO%d=%d", i, dio[i]);
+ for (int i = 0; i < 8; i++)
+ if (ad[i] != -1)
+ if (first) {
+ mon.printf("AD%d=%d", i, ad[i]);
+ first = false;
+ } else
+ mon.printf(", AD%d=%d", i, ad[i]);
+ mon.printf("\n");
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/IOSample.h Tue Nov 01 09:04:12 2011 +0000
@@ -0,0 +1,99 @@
+/*
+Copyright (c) 2011, Senio Networks, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef IO_SAMPLE_H
+#define IO_SAMPLE_H
+
+#include "mbed.h"
+
+/**
+ * IO Sample wrapper class for formatted output
+ */
+class IOSample {
+public:
+ /**
+ * class for defining a bit array
+ */
+ class BitArray {
+ public:
+
+ /**
+ * creates a BitArray object
+ */
+ BitArray(int mask, int values);
+
+ /**
+ * operator shorthand for representing the i-th value
+ */
+ int operator[](int i);
+
+ private:
+ int mask;
+ int values;
+
+ int valueAt(int i);
+ };
+
+ /**
+ * class for defining an int array
+ */
+ class IntArray {
+ public:
+
+ /**
+ * creates an IntArray object
+ */
+ IntArray(int mask, char *value);
+
+ /**
+ * operator shorthand for representing the i-th value
+ */
+ int operator[](int i);
+
+ private:
+ int mask;
+ char *values;
+
+ int valueAt(int i);
+ };
+
+ /**
+ * creates an IOSample object
+ *
+ * @param data pointer to the raw IOSample data
+ */
+ IOSample(char *data);
+
+ /**
+ * prints DIO/AD values
+ *
+ * @param mon Serial object for output
+ */
+ void print(Serial& mon);
+
+ //** DIO array
+ BitArray dio;
+ //** AD array
+ IntArray ad;
+};
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Receive.cpp Tue Nov 01 09:04:12 2011 +0000
@@ -0,0 +1,231 @@
+/*
+Copyright (c) 2011, Senio Networks, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "XBee.h"
+#include "macros.h"
+#define disableIRQ() NVIC_DisableIRQ(UARTx_IRQn[_uidx])
+#define enableIRQ() NVIC_EnableIRQ(UARTx_IRQn[_uidx])
+
+const IRQn_Type UARTx_IRQn[] = {UART0_IRQn, UART1_IRQn, UART2_IRQn, UART3_IRQn};
+
+XBee::FrameType XBee::receive(float timeout) {
+ flush();
+ while (true) {
+ disableIRQ();
+ if (out != in || free == 0) {
+ FrameType type = getFrameType(buf[INDEX(out + 2)]);
+ if (type != None) {
+ received = out;
+ enableIRQ();
+ return type;
+ }
+ int size = SIZE(buf, out);
+ out = INDEX(out + 2 + size);
+ free += (2 + size);
+ enableIRQ();
+ continue;
+ } else if (timeout <= 0) {
+ enableIRQ();
+ return None;
+ }
+ enableIRQ();
+ wait(0.001);
+ timeout -= 0.001;
+ }
+}
+
+/*
+ * function seekFor() -
+ *
+ * searches buf[] in range between the index out and in for a specified frametype packet.
+ * if the frame is found before timeout, returns the index of the packet, otherwise -1.
+ *
+ */
+int XBee::seekFor(FrameType type, float timeout) {
+ int index = out;
+ while (true) {
+ if (index != in) {
+ if (getFrameType(buf[INDEX(index + 2)]) == type)
+ return index;
+ int size = SIZE(buf, index);
+ index = INDEX(index + 2 + size);
+ continue;
+ } else if (timeout <= 0) {
+ return -1;
+ }
+ wait(0.001);
+ timeout -= 0.001;
+ }
+}
+
+XBee::FrameType XBee::getFrameType(char c) {
+ switch (c) {
+ case 0x00:
+ return None;
+ case 0x88:
+ return ATCommandResponse;
+ case 0x8A:
+ return ModemStatus;
+ case 0x8B:
+ return ZigBeeTransmitStatus;
+ case 0x90:
+ return ZigBeeReceivePacket;
+ case 0x91:
+ return ZigBeeExplicitRxIndicator;
+ case 0x92:
+ return ZigBeeIODataSampleRxIndicator;
+ case 0x94:
+ return XBeeSensorReadIndicator;
+ case 0x95:
+ return NodeIdentificationIndicator;
+ case 0x97:
+ return RemoteCommandResponse;
+ default:
+ return Other;
+ }
+}
+
+void XBee::flush() {
+ disableIRQ();
+ if (received == out) {
+ do {
+ int size = SIZE(buf, out);
+ out = INDEX(out + 2 + size);
+ free += 2 + size;
+ } while (out != in && getFrameType(buf[INDEX(out + 2)]) == None);
+ if (debug) leds = leds & 12; //**LEDS=xx00
+ }
+ enableIRQ();
+}
+
+void XBee::rxInterruptHandler() {
+ if (debug) leds = leds ^ 4; //**LEDS=x@xx
+
+ while (readable()) {
+ char c = getc() & 255;
+ switch (state) {
+ case LENGTH1:
+ cur = in;
+ buf[cur] = c;
+ state = LENGTH2;
+ break;
+ case LENGTH2:
+ if ((buf[cur] << 8 | c) + 2 < BUFSIZE) {
+ state = DATA;
+ while (free < (buf[cur] << 8 | c) + 2) {
+ int size = SIZE(buf, out);
+ out = INDEX(out + 2 + size);
+ free += size + 2;
+ }
+ buf[INDEX(cur + 1)] = c;
+ cur = INDEX(cur + 2);
+ if (debug) leds = (leds & 12) | 1; //**LEDS=xx01
+ } else {
+ state = UNKNOWN;
+ if (debug) leds = leds & 12; //**LEDS=xx00
+ }
+ break;
+ case DATA:
+ buf[cur] = c;
+ cur = INDEX(cur + 1);
+ if (debug) leds = (leds & 12) | (cur & 3); //**LEDS=xx@@
+ if (cur == INDEX(in + 2 + SIZE(buf, in))) state = SUMCHECK;
+ break;
+ case SUMCHECK:
+ for (int i = INDEX(in + 2); i != cur; i = INDEX(i + 1)) {
+ c += buf[i];
+ }
+ if (c == 255) {
+ if (debug) leds = (leds & 12) | 3; //**LEDS=xx11
+ in = cur;
+ free = in <= out ? out - in : BUFSIZE + out - in;
+ }
+ state = UNKNOWN;
+ break;
+ default:
+ if (c == PREAMBLE) state = LENGTH1;
+ if (debug) leds = (leds & 12) | 1; //**LEDS=xx01
+ }
+ }
+}
+
+void XBee::rxInterruptHandler2() {
+ static bool escaped = false;
+
+ if (debug) leds = leds ^ 4; // x@xx
+
+ while (readable()) {
+ char c = getc() & 255;
+
+ if (escaped) {
+ c ^= 0x20;
+ escaped = false;
+ } else if (c == ESCAPE) {
+ escaped = true;
+ continue;
+ }
+
+ switch (state) {
+ case LENGTH1:
+ cur = in;
+ buf[cur] = c;
+ state = LENGTH2;
+ break;
+ case LENGTH2:
+ if ((buf[cur] << 8 | c) + 2 < BUFSIZE) {
+ state = DATA;
+ while (free < (buf[cur] << 8 | c) + 2) {
+ int size = SIZE(buf, out);
+ out = INDEX(out + size + 2);
+ free += (size + 2);
+ }
+ buf[INDEX(cur + 1)] = c;
+ cur = INDEX(cur + 2);
+ if (debug) leds = (leds & 12) | 2; // xx10
+ } else {
+ state = UNKNOWN;
+ leds = leds & 12; //** update leds
+ }
+ break;
+ case DATA:
+ buf[cur] = c;
+ cur = INDEX(cur + 1);
+ if (debug) leds = (leds & 12) | (cur & 3); //**LEDS=xx@@
+ if (cur == INDEX(in + 2 + SIZE(buf, in))) state = SUMCHECK;
+ break;
+ case SUMCHECK:
+ for (int i = INDEX(in + 2); i != cur; i = INDEX(i + 1)) {
+ c += buf[i];
+ }
+ if (c == 255) {
+ if (debug) leds = (leds & 12) | 3; //**LEDS=xx11
+ in = cur;
+ free = in <= out ? out - in : BUFSIZE + out - in;
+ }
+ state = UNKNOWN;
+ break;
+ default:
+ if (c == PREAMBLE) state = LENGTH1;
+ if (debug) leds = (leds & 12) | 1; //**LEDS=xx01
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Scan.cpp Tue Nov 01 09:04:12 2011 +0000
@@ -0,0 +1,136 @@
+/*
+Copyright (c) 2011, Senio Networks, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "XBee.h"
+#include "macros.h"
+
+bool XBee::scan(ValueType type, char *value, int maxlength, int *length) {
+ if (received != out || (in == out && free != 0))
+ return false;
+
+ return scan(out, type, value, maxlength, length);
+}
+
+bool XBee::scan(int index, ValueType type, char *value, int maxlength, int *length) {
+ int from = 0;
+ int len = 1;
+ FrameType frameType = getFrameType(buf[INDEX(index + 2)]);
+
+ if (frameType == (FrameType) None)
+ return false;
+
+ switch (type) {
+ case FrameID:
+ from = 1;
+ break;
+ case ATCommand:
+ switch (frameType) {
+ case ATCommandResponse:
+ from = 2;
+ break;
+ case RemoteCommandResponse:
+ from = 12;
+ break;
+ }
+ len = 2;
+ break;
+ case Status:
+ switch (frameType) {
+ case ATCommandResponse:
+ from = 4;
+ break;
+ case ModemStatus:
+ from = 1;
+ break;
+ case RemoteCommandResponse:
+ from = 14;
+ break;
+ }
+ break;
+ case CommandData:
+ switch (frameType) {
+ case ATCommandResponse:
+ from = 5;
+ len = SIZE(buf, index) - 5;
+ break;
+ case RemoteCommandResponse:
+ from = 15;
+ len = SIZE(buf, index) - 15;
+ break;
+ }
+ break;
+ case Address16:
+ switch (frameType) {
+ case ZigBeeTransmitStatus:
+ from = 4;
+ break;
+ case ZigBeeReceivePacket:
+ case ZigBeeIODataSampleRxIndicator:
+ from = 9;
+ break;
+ case RemoteCommandResponse:
+ from = 10;
+ break;
+ }
+ len = 2;
+ break;
+ case Address64:
+ switch (frameType) {
+ case ZigBeeReceivePacket:
+ case ZigBeeIODataSampleRxIndicator:
+ from = 1;
+ break;
+ case RemoteCommandResponse:
+ from = 2;
+ break;
+ }
+ len = 8;
+ break;
+ case RetryCount:
+ from = 4;
+ break;
+ case DeliveryStatus:
+ from = 5;
+ break;
+ case DiscoveryStatus:
+ from = 6;
+ break;
+ case ReceiveOptions:
+ from = 11;
+ break;
+ case ReceivedData:
+ from = 12;
+ len = SIZE(buf, index) - 12;
+ break;
+ case RawData:
+ from = 1;
+ len = SIZE(buf, index) - 1;
+ break;
+ }
+
+ if (from > 0) {
+ copy(value, INDEX(index + 2 + from), min(len, maxlength));
+ if (length) *length = len;
+ return true;
+ } else
+ return false;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Send.cpp Tue Nov 01 09:04:12 2011 +0000
@@ -0,0 +1,158 @@
+/*
+Copyright (c) 2011, Senio Networks, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "XBee.h"
+#include "macros.h"
+#include <stdarg.h>
+
+void XBee::sendCommand(char *command, char *param, int param_length, bool queue) {
+ char buf[param_length + 4];
+
+ createAtRequest(frame_id, command, param, param_length, queue, buf, sizeof(buf));
+ sendFrame(buf, param_length + 4);
+ frame_id = frame_id % 255 + 1;
+}
+
+void XBee::sendRemoteCommand(char *command, char *param, int param_length, char options) {
+ char buf[param_length + 15];
+
+ createRemoteAtRequest(frame_id, command, param, param_length, options, buf, sizeof(buf));
+ sendFrame(buf, param_length + 15);
+ frame_id = frame_id % 255 + 1;
+}
+
+void XBee::send(char *data, int length) {
+ char buf[length + 14];
+
+ createTxRequest(frame_id, data, length, buf, sizeof(buf));
+ sendFrame(buf, length + 14);
+ frame_id = frame_id % 255 + 1;
+}
+
+bool XBee::sendConfirm(char *data, int length) {
+ send(data, length);
+
+ int index = seekFor(ZigBeeTransmitStatus, 3.0);
+ if (index != -1) {
+ char delivery;
+ scan(index, DeliveryStatus, &delivery);
+ buf[INDEX(index + 2)] = 0x00;
+ return delivery == 0;
+ }
+ return false;
+}
+
+int XBee::printf(const char *format, ...) {
+ va_list argv;
+ va_start(argv, format);
+ char buf[256];
+ int length = vsnprintf(buf, sizeof buf, format, argv);
+ return length > 0 && sendConfirm(buf, length) ? length : -1;
+}
+
+void XBee::send(char c) {
+ while (!writeable()) wait_us(100);
+ putc(c);
+}
+
+void XBee::send2(char c) {
+ switch (c) {
+ case 0x7E:
+ case 0x7D:
+ case 0x11:
+ case 0x13:
+ send(ESCAPE);
+ send(c ^ 0x20);
+ break;
+ default:
+ send(c);
+ }
+}
+
+void XBee::sendFrame(char* frame, int length) {
+ char checksum = 255;
+ if (debug) leds = leds | 8; //**LEDS=1xxx
+
+ send(PREAMBLE);
+
+ if (apiMode == 2) {
+ send2((length >> 8) & 255);
+ send2(length & 255);
+ for (int i = 0; i < length; i++) {
+ send2(frame[i]);
+ checksum -= frame[i];
+ }
+ send2(checksum);
+ } else {
+ send((length >> 8) & 255);
+ send(length & 255);
+ for (int i = 0; i < length; i++) {
+ send(frame[i]);
+ checksum -= frame[i];
+ }
+ send(checksum);
+ }
+ if (debug) leds = leds & 7; //**LEDS=0xxx
+}
+
+int XBee::createTxRequest(char frame_id, char* data, int data_length, char* buf, int buf_size) {
+ if (data_length + 14 > buf_size) return -1;
+
+ buf[0] = 0x10; // frame type
+ buf[1] = frame_id;
+ for (int i = 0; i < 8; i++) buf[i + 2] = destination64[i];
+ buf[10] = destination16[0]; // 16 bit dest address
+ buf[11] = destination16[1]; // 16 bit dest address
+ buf[12] = 0;
+ buf[13] = 0;
+ for (int i = 0; i < data_length; i++) buf[i + 14] = data[i];
+
+ return data_length + 14;
+}
+
+int XBee::createAtRequest(char frame_id, char* command, char* param, int param_length, bool queue, char* buf, int buf_size) {
+ if (param_length + 4 > buf_size) return -1;
+
+ buf[0] = queue ? 0x09 : 0x08; // frame type
+ buf[1] = frame_id;
+ buf[2] = command[0];
+ buf[3] = command[1];
+ for (int i = 0; i < param_length; i++) buf[i + 4] = param[i];
+
+ return param_length + 4;
+}
+
+int XBee::createRemoteAtRequest(char frame_id, char* command, char* param, int param_length, char options, char* buf, int buf_size) {
+ if (param_length + 4 > buf_size) return -1;
+
+ buf[0] = 0x17; // frame type
+ buf[1] = frame_id;
+ memcpy(buf + 2, destination64, 8);
+ buf[10] = destination16[0];
+ buf[11] = destination16[1];
+ buf[12] = options;
+ buf[13] = command[0];
+ buf[14] = command[1];
+ for (int i = 0; i < param_length; i++) buf[i + 15] = param[i];
+
+ return param_length + 15;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/XBee.cpp Tue Nov 01 09:04:12 2011 +0000
@@ -0,0 +1,140 @@
+/*
+Copyright (c) 2011, Senio Networks, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "XBee.h"
+#include "macros.h"
+
+XBee::XBee(Serial& ser, int apiMode, bool debug)
+ : Serial(ser), mon(USBTX, USBRX), leds(LED1, LED2, LED3, LED4), apiMode(apiMode),
+ state(UNKNOWN), in(0), out(0), received(-1), free(BUFSIZE), frame_id(1), debug(debug) {
+ memset(buf, 0, BUFSIZE);
+ attach(this, apiMode == 1 ? &XBee::rxInterruptHandler : &XBee::rxInterruptHandler2, Serial::RxIrq);
+}
+
+XBee::XBee(Serial& ser, Serial& mon, int apiMode, bool debug)
+ : Serial(ser), mon(mon), leds(LED1, LED2, LED3, LED4), apiMode(apiMode),
+ state(UNKNOWN), in(0), out(0), received(-1), free(BUFSIZE), frame_id(1), debug(debug) {
+ memset(buf, 0, BUFSIZE);
+ attach(this, apiMode == 1 ? &XBee::rxInterruptHandler : &XBee::rxInterruptHandler2, Serial::RxIrq);
+}
+
+bool XBee::init(float timeout) {
+ while (readable()) getc();
+ while (timeout > 0 && getFirmwareVersion() == -1) {
+ timeout -= 1;
+ wait(0.8);
+ }
+
+ switch (getFirmwareVersion() & 0xFF00) {
+ case 0x2100:
+ setDestination(0xFFFFULL, 0xFFFE);
+ return true;
+
+ case 0x2300:
+ case 0x2900:
+ setDestination(0x00ULL);
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+void XBee::setDestination(unsigned long long address64, unsigned short address16) {
+ char addr64[] = {BYTE(address64, 7), BYTE(address64, 6), BYTE(address64, 5), BYTE(address64, 4),
+ BYTE(address64, 3), BYTE(address64, 2), BYTE(address64, 1), BYTE(address64, 0)
+ };
+ char addr16[] = {BYTE(address16, 1), BYTE(address16, 0)};
+ setDestination(addr64, addr16);
+}
+
+void XBee::setDestination(char address64[]) {
+ char address16[] = {0xFF, 0xFE};
+ setDestination(address64, address16);
+}
+
+void XBee::setDestination(char address64[], char address16[]) {
+ for (int i = 0; i < sizeof(destination64); i++)
+ destination64[i] = address64[i];
+ destination16[0] = address16[0];
+ destination16[1] = address16[1];
+}
+
+XBee::operator bool() {
+ return getFirmwareVersion() != -1;
+}
+
+char XBee::getFrameID() {
+ return frame_id;
+}
+
+void *XBee::executeCommand(char *command, char* param, int param_length) {
+ static char data[21];
+ bool succeeded = false;
+ char id = getFrameID();
+
+ sendCommand(command, param, param_length);
+ int index = seekFor(XBee::ATCommandResponse, 0.1);
+ if (index != -1) {
+ char id2, status;
+ if (scan(index, FrameID, &id2) && id == id2 && scan(index, Status, &status) && status == 0) {
+ memset(data, 0, sizeof(data));
+ if ((command[0] == 'N' && command[1] == 'I') ||
+ (command[0] == 'I' && command[1] == 'S')) {
+ if (scan(index, CommandData, data, sizeof(data)))
+ succeeded = true;
+ } else {
+ char buf2[8];
+ int length;
+ if (scan(index, CommandData, buf2, sizeof(buf2), &length) && length <= sizeof(buf2)) {
+ for (int i = 0; i < length; i++)
+ data[i] = buf2[length - i - 1];
+ succeeded = true;
+ }
+ }
+ }
+ buf[INDEX(index + 2)] = 0x00;
+ }
+
+ return succeeded ? data : 0;
+}
+
+int XBee::getFirmwareVersion() {
+ static int firmwareVersion = -1;
+
+ if (firmwareVersion == -1) {
+ unsigned short *data = (unsigned short *) executeCommand("VR");
+ if (data) firmwareVersion = *data; //data[0] << 8 | data[1];
+ }
+ return firmwareVersion;
+}
+
+void XBee::copy(char *toBuf, int fromIndex, int length) {
+ int length1 = min(BUFSIZE - fromIndex, length);
+ memcpy(toBuf, &buf[fromIndex], length1);
+ if (length1 < length)
+ memcpy(toBuf + length1, &buf[0], length - length1);
+}
+
+void XBee::setDebug(bool debug) {
+ this->debug = debug;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/XBee.h Tue Nov 01 09:04:12 2011 +0000
@@ -0,0 +1,272 @@
+/*
+Copyright (c) 2011, Senio Networks, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef XBEE_H
+#define XBEE_H
+
+#include "mbed.h"
+#include "IOSample.h"
+
+const int BUFSIZE = 512;
+const char ESCAPE = 0x7D;
+const char PREAMBLE = 0x7E;
+
+/**
+ * class for XBee module API mode interface
+ */
+class XBee : public Serial {
+public:
+ /***/
+ enum FrameType {
+ None = 0,
+ ATCommandResponse,
+ ModemStatus,
+ ZigBeeTransmitStatus,
+ ZigBeeReceivePacket,
+ ZigBeeExplicitRxIndicator,
+ ZigBeeIODataSampleRxIndicator,
+ XBeeSensorReadIndicator,
+ NodeIdentificationIndicator,
+ RemoteCommandResponse,
+ Other
+ };
+ /***/
+ enum ValueType {
+ FrameID,
+ ATCommand,
+ Status,
+ CommandData,
+ Address16,
+ Address64,
+ RetryCount,
+ DeliveryStatus,
+ DiscoveryStatus,
+ ReceiveOptions,
+ ReceivedData,
+ RawData
+ };
+
+ /**
+ * creates an XBee interface object.
+ *
+ * @param ser Serial object through which XBee module is connected to mbed
+ * @param apiMode API mode either 1 or 2 (use escape; default)
+ * @param debug display debugging (I/O state) information through LEDs
+ */
+ XBee(Serial& ser, int apiMode = 2, bool debug = false);
+
+ /**
+ * creates an XBee interface object.
+ *
+ * @param ser Serial object through which XBee module is connected to mbed
+ * @param mon alternate Serial object for monitoring (use serial ports other than USBTX/USBRX)
+ * @param apiMode API mode either 1 or 2 (use escape; default)
+ * @param debug display debugging (I/O state) information through LEDs
+ */
+ XBee(Serial& ser, Serial& mon, int apiMode = 2, bool debug = false);
+
+ /**
+ * initializes XBee module.
+ *
+ * issues VR command to test XBee modem connection
+ *
+ * @returns true if initialization succeeded, false otherwise
+ */
+ bool init(float timeout = 15.0);
+
+ /**
+ * sets destination addresses.
+ *
+ * @param address64 64-bit destination address in unsigned long long
+ * @param address16 16-bit destination address in unsigned short
+ */
+ void setDestination(unsigned long long address64, unsigned short address16 = 0xFFFE);
+
+ /**
+ * sets destination addresses.
+ *
+ * @param address64 64-bit destination address in bytes (big endian)
+ * @param address16 16-bit destination address in bytes
+ */
+ void setDestination(char address64[], char address16[]);
+
+ /**
+ * sets 64-bit destination address.
+ *
+ * this function is used when 16-bit address is unknown
+ * @param address64 64-bit destination address in bytes (big endian)
+ */
+ void setDestination(char address64[]);
+
+ /**
+ * sends an AT command.
+ *
+ * @param command AT command char string
+ * @param param parameter to the AT command (pointer to byte array)
+ * @param param_length parameter length in bytes
+ * @param queue true if command paramter is to be queued
+ */
+ void sendCommand(char* command, char* param = 0, int param_length = 0, bool queue = false);
+
+ /**
+ * sends a remote AT command.
+ *
+ * sends an AT command to the XBee(s) at the destination address
+ *
+ * @param command AT command char string
+ * @param param parameter to the AT command (pointer to byte array)
+ * @param param_length parameter length in bytes
+ * @param options remote command options
+ */
+ void sendRemoteCommand(char* command, char* param = 0, int param_length = 0, char options = 0x02);
+
+
+ /**
+ * executes an AT command then gets its result.
+ *
+ * @param command AT command char string
+ * @param param parameter to the AT command (pointer to byte array)
+ * @param param_length parameter length in bytes
+ *
+ * @returns pointer to the command result, if the result is a number (char, short, long, long long),
+ * the address to the number will be returned; otherwise the address to the byte array
+ * containing the command response will be returned.
+ */
+ void *executeCommand(char *command, char* param = 0, int laram_length = 0);
+
+ /**
+ * sends data to the XBee(s) at the destination address.
+ *
+ * @param data address to the data (byte array)
+ * @param length data length in bytes
+ */
+ void send(char *data, int length);
+
+ /**
+ * sends data and confirm the transmit status.
+ *
+ * @param data address to the data (byte array)
+ * @param length data length in bytes
+ *
+ * @returns true if sent successfully, false otherwise (either timeout or send error occurred)
+ */
+ bool sendConfirm(char *data, int length);
+
+ /**
+ * sends data to the destination using printf format.
+ *
+ * @param format printf format string, followed by corresponding arguments
+ *
+ * @returns the number of charancters sent, or negative if error occurred
+ */
+ int printf(const char *format, ...);
+
+ /**
+ * receives data frame from the XBee module.
+ *
+ * @param timeout seconds bofer time out
+ *
+ * @returns FrameType of the received frame data
+ */
+ FrameType receive(float timeout = 3.0);
+
+ /**
+ * scan received data according to the specified format.
+ *
+ * @param type ValueType of the data to be scanned
+ * @param value pointer to the byte array to store the scanned value
+ * @param maxlength max size of the value in bytes
+ * @param length pointer to an int to receive the actual data length
+ *
+ * @param true if scan succeeded, false otherwise
+ */
+ bool scan(ValueType type, char *value, int maxlength = 1, int *length = 0);
+
+ /**
+ * gets the XBee firmware version.
+ *
+ * @returns XBee firmwre version in int (unsigned short value)
+ */
+ int getFirmwareVersion();
+
+ /**
+ * gets the current frame ID.
+ *
+ * @returns frame ID number being used in the next send request
+ */
+ char getFrameID();
+
+ /**
+ * sets to run in debug mode.
+ *
+ * @param debug true to display debugging information
+ */
+ void setDebug(bool debug);
+
+ /**
+ * displays received data in dump format.
+ */
+ void dump();
+
+ /**
+ * displays the internal data fields and receive buffer in dump format.
+ */
+ void dumpAll();
+
+ /**
+ * operator overloading for testing XBee modem connection status.
+ *
+ * @returns false if XBee modem connection has an error
+ */
+ operator bool();
+
+private:
+ Serial mon;
+ BusOut leds;
+ int apiMode;
+ volatile enum {UNKNOWN, LENGTH1, LENGTH2, DATA, SUMCHECK} state;
+ volatile int cur, in, out, received, free;
+ char frame_id;
+ char destination64[8];
+ char destination16[2];
+ char buf[BUFSIZE];
+ bool debug;
+
+ void send(char c);
+ void send2(char c);
+ void sendFrame(char* frame, int length);
+ int createTxRequest(char frame_id, char* data, int data_length, char* buf, int buf_size);
+ int createAtRequest(char frame_id, char* command, char* param, int param_length, bool queue, char* buf, int buf_size);
+ int createRemoteAtRequest(char frame_id, char* command, char* param, int param_length, char options, char* buf, int buf_size);
+ int seekFor(FrameType type, float timeout);
+ FrameType getFrameType(char c);
+ bool scan(int i, ValueType type, char *value, int maxlength = 1, int *length = 0);
+ void flush();
+ void rxInterruptHandler();
+ void rxInterruptHandler2();
+
+ void dump(char* data, int length);
+ void dumpIOSample(char *data, int length);
+ void copy(char *toBuf, int fromIndex, int length);
+};
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/macros.h Tue Nov 01 09:04:12 2011 +0000 @@ -0,0 +1,26 @@ +/* +Copyright (c) 2011, Senio Networks, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#define min(x, y) ((x) < (y) ? (x) : (y)) +#define BYTE(a, n) ((char *) &(a))[n] +#define INDEX(n) ((n) % BUFSIZE) +#define SIZE(b, i) (b[i] << 8 | b[INDEX(i + 1)]) \ No newline at end of file