XBee API mode library

Revision:
8:776b8dc51932
Parent:
4:c05dc188f177
Child:
10:3da24a020e67
--- a/Receive.cpp	Fri Jan 25 02:26:14 2013 +0000
+++ b/Receive.cpp	Tue Jan 29 13:46:41 2013 +0000
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2011, Senio Networks, Inc.
+Copyright (c) 2013, 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
@@ -22,34 +22,51 @@
 
 #include "XBee.h"
 
-#define disableIRQ()    NVIC_DisableIRQ(UARTx_IRQn[_serial.index])
-#define enableIRQ()     NVIC_EnableIRQ(UARTx_IRQn[_serial.index])
-
+#ifndef XBEE_RTOS
+#define LOCK()          NVIC_DisableIRQ(UARTx_IRQn[_serial.index])
+#define UNLOCK()        NVIC_EnableIRQ(UARTx_IRQn[_serial.index])
 const IRQn_Type UARTx_IRQn[] = {UART0_IRQn, UART1_IRQn, UART2_IRQn, UART3_IRQn};
+#else
+#define LOCK()          mutex.lock()
+#define UNLOCK()        mutex.unlock();
+#endif
 
-XBee::FrameType XBee::receive(float timeout) {
+XBee::FrameType XBee::receive(float timeout)
+{
     flush();
+
     while (true) {
-        disableIRQ();
+        LOCK();
+        //::printf(">receive()\n");
         if (out != in || free == 0) {
             FrameType type = getFrameType(buf[INDEX(out + 2)]);
             if (type != None) {
                 received = out;
-                enableIRQ();
+                //::printf("<receive()1\n");
+                UNLOCK();
                 return type;
             }
             int size = SIZE(buf, out);
             out = INDEX(out + 2 + size);
             free += (2 + size);
-            enableIRQ();
+            //::printf("<receive()2\n");
+            UNLOCK();
             continue;
         } else if (timeout <= 0) {
-            enableIRQ();
+            //::printf("<receive()3\n");
+            UNLOCK();
             return None;
         }
-        enableIRQ();
+        //::printf("<receive()4\n");
+        UNLOCK();
+
+#ifndef XBEE_RTOS
         wait(0.001);
         timeout -= 0.001;
+#else
+        Thread::wait(50);
+        timeout -= 0.05;
+#endif
     }
 }
 
@@ -60,7 +77,8 @@
  * if the frame is found before timeout, returns the index of the packet, otherwise -1.
  *
  */
-int XBee::seekFor(FrameType type, char id, float timeout) {
+int XBee::seekFor(FrameType type, char id, float timeout)
+{
     int index = out;
     while (true) {
         if (index != in) {
@@ -72,12 +90,18 @@
         } else if (timeout <= 0) {
             return -1;
         }
+#ifndef XBEE_RTOS
         wait(0.001);
         timeout -= 0.001;
+#else
+        Thread::wait(10);
+        timeout -= 0.01;
+#endif
     }
 }
 
-XBee::FrameType XBee::getFrameType(char c) {
+XBee::FrameType XBee::getFrameType(char c)
+{
     switch (c) {
         case 0x00:
             return None;
@@ -104,8 +128,9 @@
     }
 }
 
-void XBee::flush() {
-    disableIRQ();
+void XBee::flush()
+{
+    LOCK();
     if (received == out) {
         do {
             int size = SIZE(buf, out);
@@ -114,14 +139,29 @@
         } while (out != in && getFrameType(buf[INDEX(out + 2)]) == None);
         if (debug) leds = leds & 12; //**LEDS=xx00
     }
-    enableIRQ();
+    UNLOCK();
 }
 
-void XBee::rxInterruptHandler() {
+#ifndef XBEE_RTOS
+void XBee::rxInterruptHandler()
+{
+    static  bool escaped = false;
+
     if (debug) leds = leds ^ 4; //**LEDS=x@xx
 
     while (readable()) {
         char c = getc() & 255;
+
+        if (apiMode == 2) {
+            if (escaped) {
+                c ^= 0x20;
+                escaped = false;
+            } else if (c == ESCAPE) {
+                escaped = true;
+                continue;
+            }
+        }
+
         switch (state) {
             case LENGTH1:
                 cur = in;
@@ -157,7 +197,7 @@
                 if (c == 255) {
                     if (debug) leds = (leds & 12) | 3; //**LEDS=xx11
                     in = cur;
-                    free = in <= out ? out - in : BUFSIZE + out - in;
+                    free = in < out ? out - in : BUFSIZE + out - in;
                 }
                 state = UNKNOWN;
                 break;
@@ -167,65 +207,203 @@
         }
     }
 }
-
-void XBee::rxInterruptHandler2() {
-    static bool escaped = false;
+#else
+void XBee::rxISR()
+{
+    int c = -1;
+    switch (_serial.index) {
+        case 0: {
+            uint32_t UART_0_IIR = LPC_UART0->IIR;
+            if (readable()) c = LPC_UART0->RBR;
+        }
+        break;
+        case 1: {
+            uint32_t UART_1_IIR = LPC_UART1->IIR;
+            if (readable()) c = LPC_UART1->RBR;
+        }
+        break;
+        case 2: {
+            uint32_t UART_2_IIR = LPC_UART2->IIR;
+            if (readable()) c = LPC_UART2->RBR;
+        }
+        break;
+        case 3: {
+            uint32_t UART_3_IIR = LPC_UART3->IIR;
+            if (readable()) c = LPC_UART3->RBR;
+        }
+        break;
+    }
+    
+    if (c != -1) {
+        rxBuf = c;
+        signal();
+    }
+}
 
-    if (debug) leds = leds ^ 4; // x@xx
+void XBee::run()
+{
+    bool escaped = false;
 
-    while (readable()) {
-        char c = getc() & 255;
+    while (true) {
+        signalWait();
+        mutex.lock();
+        if (debug && rxBuf.readable()) leds = leds ^ 4; // x@xx
 
-        if (escaped) {
-            c ^= 0x20;
-            escaped = false;
-        } else if (c == ESCAPE) {
-            escaped = true;
-            continue;
-        }
+        while (rxBuf.readable()) {
+            char c = rxBuf.getc() & 255;
+            //::printf("getc = %02X\n", c);
+            if (apiMode == 2) {
+                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);
+            switch (state) {
+                case LENGTH1:
+                    cur = in;
+                    buf[cur] = c;
+                    state = LENGTH2;
+                    break;
+                case LENGTH2:
+                    //::printf(">length2 in = %04X, out = %04X, free = %d\n", in, out, free);
+                    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
+                    }
+                    //::printf("<length2 in = %04X, out = %04X, free = %d\n", in, out, free);
+                    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; // maybe in == out, then free == 0, but != BUFSIZE
                     }
-                    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;
+                default:
+                    if (c == PREAMBLE) state = LENGTH1;
+                    if (debug) leds = (leds & 12) | 1; //**LEDS=xx01
+            }
+        }
+        mutex.unlock();
+    }
+}
+#endif
+#if 0
+void XBee::rxHandler(void const *args)
+{
+    bool escaped = false;
+
+    XBee& self = *((XBee *) args);
+    BusOut& leds = self.leds;
+    int& apiMode = self.apiMode;
+    volatile int& cur = self.cur;
+    volatile int& in = self.in;
+    volatile int& out = self.out;
+    volatile int& free = self.free;
+    bool& debug = self.debug;
+    Mutex& mutex = self.mutex;
+
+    //int prevFree = free;
+
+    while (true) {
+        mutex.lock();
+        //if (prevFree != free) {
+        //::printf("rx in = %04X, out = %04X, free = %d -> %d\n", in, out, prevFree, free);
+        //prevFree = free;
+        //}
+        if (debug && self.readable()) leds = leds ^ 4; // x@xx
+
+        while (self.readable()) {
+            //if (prevFree != free) {
+            //::printf("length2 in = %04X, out = %04X, free = %d -> %d\n", in, out, prevFree, free);
+            //prevFree = free;
+            //}
+            char c = self.getc() & 255;
+
+            if (apiMode == 2) {
+                if (escaped) {
+                    c ^= 0x20;
+                    escaped = false;
+                } else if (c == ESCAPE) {
+                    escaped = true;
+                    continue;
                 }
-                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
+            }
+
+            switch (self.state) {
+                case LENGTH1:
+                    cur = in;
+                    self.buf[cur] = c;
+                    self.state = LENGTH2;
+                    break;
+                case LENGTH2:
+                    //::printf(">length2 in = %04X, out = %04X, free = %d\n", in, out, free);
+                    if ((self.buf[cur] << 8 | c) + 2 < BUFSIZE) {
+                        self.state = DATA;
+                        while (free < (self.buf[cur] << 8 | c) + 2) {
+                            int size = SIZE(self.buf, out);
+                            out = INDEX(out + size + 2);
+                            free += (size + 2);
+                        }
+                        self.buf[INDEX(cur + 1)] = c;
+                        cur = INDEX(cur + 2);
+                        if (debug) leds = (leds & 12) | 2; // xx10
+                        //::printf("<length2 in = %04X, out = %04X, free = %d\n", in, out, free);
+                    } else {
+                        self.state = UNKNOWN;
+                        leds = leds & 12; //** update leds
+                    }
+                    break;
+                case DATA:
+                    self.buf[cur] = c;
+                    cur = INDEX(cur + 1);
+                    if (debug) leds = (leds & 12) | (cur & 3); //**LEDS=xx@@
+                    if (cur == INDEX(in + 2 + SIZE(self.buf, in))) self.state = SUMCHECK;
+                    break;
+                case SUMCHECK:
+                    //::printf(">sumcheck in = %04X, out = %04X, free = %d\n", in, out, free);
+                    for (int i = INDEX(in + 2); i != cur; i = INDEX(i + 1)) {
+                        c += self.buf[i];
+                    }
+                    if (c == 255) {
+                        if (debug) leds = (leds & 12) | 3; //**LEDS=xx11
+                        in = cur;
+                        free = in <= out ? out - in : BUFSIZE + out - in; // maybe in == out then free == 0, but != BUFSIZE
+                    }
+                    self.state = UNKNOWN;
+                    //::printf("<sumcheck in = %04X, out = %04X, free = %d\n", in, out, free);
+                    break;
+                default:
+                    if (c == PREAMBLE) self.state = LENGTH1;
+                    if (debug) leds = (leds & 12) | 1; //**LEDS=xx01
+            }
         }
+        mutex.unlock();
+        Thread::wait(1);
     }
-}
\ No newline at end of file
+}
+#endif
\ No newline at end of file