XBee API mode library

Revision:
0:0232a97b3883
Child:
3:8453df14bd30
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Receive.cpp	Thu Jul 26 10:33:11 2012 +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"
+
+#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