XBee API mode library

Revision:
16:cdfcb63b2c4b
Parent:
14:af6e497bbf52
Child:
17:2f728fd13bc0
--- a/Receive.cpp	Thu Mar 14 09:45:41 2013 +0000
+++ b/Receive.cpp	Wed Mar 20 00:28:27 2013 +0000
@@ -22,14 +22,9 @@
 
 #include "XBee.h"
 
-#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) {
     flush();
@@ -53,14 +48,8 @@
             return None;
         }
         UNLOCK();
-
-#ifndef XBEE_RTOS
         wait(0.001);
         timeout -= 0.001;
-#else
-        Thread::wait(50);
-        timeout -= 0.05;
-#endif
     }
 }
 
@@ -71,30 +60,40 @@
  * 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 index = out;
+int XBee::seekFor(FrameType type, char id, float timeout)
+{
+    LOCK();
 
-    while (timeout > 0) {
-       if (index != in) {
-            if (getFrameType(buf[INDEX(index + 2)]) == type && (id == 0 || buf[INDEX(index + 3)] == id))
+    while (out != in && getFrameType(buf[INDEX(out + 2)]) == None) {
+        int size = SIZE(buf, out);
+        out = INDEX(out + 2 + size);
+        free += 2 + size;
+    }
+
+    int index = out;
+    while (true) {
+        if (index != in) {
+            if (getFrameType(buf[INDEX(index + 2)]) == type && (id == 0 || buf[INDEX(index + 3)] == id)) {
+                UNLOCK();
                 return index;
+            }
+            //::printf("seekFor: index = %02X\n", index);
             int size = SIZE(buf, index);
             index = INDEX(index + 2 + size);
-        } else {
-#ifndef XBEE_RTOS
+            continue;
+        } else if (timeout <= 0) {
+            UNLOCK();
+            return -1;
+        }
+        UNLOCK();
         wait(0.001);
         timeout -= 0.001;
-#else
-        Thread::wait(10);
-        timeout -= 0.01;
-#endif
-        }
+        LOCK();
     }
-    
-    return -1;
 }
 
-XBee::FrameType XBee::getFrameType(char c) {
+XBee::FrameType XBee::getFrameType(char c)
+{
     switch (c) {
         case 0x00:
             return None;
@@ -121,7 +120,8 @@
     }
 }
 
-void XBee::flush() {
+void XBee::flush()
+{
     LOCK();
     if (received == out) {
         do {
@@ -129,27 +129,46 @@
             out = INDEX(out + 2 + size);
             free += 2 + size;
         } while (out != in && getFrameType(buf[INDEX(out + 2)]) == None);
-        if (debug) leds = leds & 12; //**LEDS=xx00
     }
     UNLOCK();
 }
 
-#ifndef XBEE_RTOS
-void XBee::rxInterruptHandler() {
+void XBee::rxISR() {
+    static enum {UNKNOWN, LENGTH1, LENGTH2, DATA, SUMCHECK} state = UNKNOWN;
     static bool escaped = false;
+    int c = -1;
+    
+    switch (_serial.index) {
+        case 0: {// USBTX, USBRX
+            uint32_t UART_0_IIR = LPC_UART0->IIR;
+            if (readable()) c = LPC_UART0->RBR;
+        }
+        break;
+        case 1: {// p13/14
+            uint32_t UART_1_IIR = LPC_UART1->IIR;
+            if (readable()) c = LPC_UART1->RBR;
+        }
+        break;
+        case 2: {// p28/27
+            uint32_t UART_2_IIR = LPC_UART2->IIR;
+            if (readable()) c = LPC_UART2->RBR;
+        }
+        break;
+        case 3: {// p9/10
+            uint32_t UART_3_IIR = LPC_UART3->IIR;
+            if (readable()) c = LPC_UART3->RBR;
+        }
+        break;
+    }
 
-    if (debug) leds = leds ^ 4; //**LEDS=x@xx
-
-    while (readable()) {
-        char c = getc() & 255;
-
+    if (c != -1) {
         if (apiMode == 2) {
             if (escaped) {
                 c ^= 0x20;
                 escaped = false;
             } else if (c == ESCAPE) {
                 escaped = true;
-                continue;
+                return;
             }
         }
 
@@ -159,142 +178,42 @@
                 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;
+                        out = INDEX(out + size + 2);
+                        free += (size + 2);
                     }
                     buf[INDEX(cur + 1)] = c;
                     cur = INDEX(cur + 2);
-                    if (debug) leds = (leds & 12) | 1; //**LEDS=xx01
-                } else {
+                } 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;
+                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
+                if ((c & 255) == 255) {
                     in = cur;
-                    free = in < out ? out - in : BUFSIZE + out - in;
+                    free = in <= out ? out - in : BUFSIZE + out - in; // maybe in == out, then free == 0, but != BUFSIZE
                 }
                 state = UNKNOWN;
                 break;
+                
             default:
-                if (c == PREAMBLE) state = LENGTH1;
-                if (debug) leds = (leds & 12) | 1; //**LEDS=xx01
+                if (c == PREAMBLE)
+                    state = LENGTH1;
         }
     }
-}
-#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;
-        notify();
-    }
-}
-
-void XBee::run() {
-    bool escaped = false;
-
-    while (true) {
-        wait();
-        mutex.lock();
-        if (debug && rxBuf.readable()) leds = leds ^ 4; // x@xx
-
-        while (rxBuf.readable()) {
-            char c = rxBuf.getc() & 255;
-            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);
-                        }
-                        buf[INDEX(cur + 1)] = c;
-                        cur = INDEX(cur + 2);
-                        if (debug) leds = (leds & 12) | 2; // xx10
-                    } else {
-                        state = UNKNOWN;
-                        if (debug) 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; // maybe in == out, then free == 0, but != BUFSIZE
-                    }
-                    state = UNKNOWN;
-                    break;
-                default:
-                    if (c == PREAMBLE) state = LENGTH1;
-                    if (debug) leds = (leds & 12) | 1; //**LEDS=xx01
-            }
-        }
-        mutex.unlock();
-    }
-}
-#endif
\ No newline at end of file
+}
\ No newline at end of file