XBee API mode library

Files at this revision

API Documentation at this revision

Comitter:
yamaguch
Date:
Thu Mar 21 06:51:31 2013 +0000
Parent:
16:cdfcb63b2c4b
Commit message:
rewrote to use rtos Semaphore only

Changed in this revision

Dump.cpp Show annotated file Show diff for this revision Revisions of this file
Receive.cpp Show annotated file Show diff for this revision Revisions of this file
RingBuffer.h Show diff for this revision Revisions of this file
Scan.cpp Show annotated file Show diff for this revision Revisions of this file
Send.cpp Show annotated file Show diff for this revision Revisions of this file
XBee.cpp Show annotated file Show diff for this revision Revisions of this file
XBee.h Show annotated file Show diff for this revision Revisions of this file
--- a/Dump.cpp	Wed Mar 20 00:28:27 2013 +0000
+++ b/Dump.cpp	Thu Mar 21 06:51:31 2013 +0000
@@ -23,6 +23,10 @@
 #include "XBee.h"
 #include <ctype.h>
 
+#define INDEX(n)    ((n) % BUFSIZE)
+#define SIZE(b, i)  (b[i] << 8 | b[INDEX(i + 1)])
+#define min(x, y)   ((x) <= (y) ? (x) : (y))
+
 void XBee::dump() {
     if (received != out || (in == out && free != 0))
         return;
--- a/Receive.cpp	Wed Mar 20 00:28:27 2013 +0000
+++ b/Receive.cpp	Thu Mar 21 06:51:31 2013 +0000
@@ -22,11 +22,15 @@
 
 #include "XBee.h"
 
-#define LOCK()          NVIC_DisableIRQ(UARTx_IRQn[_serial.index])
-#define UNLOCK()        NVIC_EnableIRQ(UARTx_IRQn[_serial.index])
+#define LOCK()      NVIC_DisableIRQ(UARTx_IRQn[_serial.index])
+#define UNLOCK()    NVIC_EnableIRQ(UARTx_IRQn[_serial.index])
+#define INDEX(n)    ((n) % BUFSIZE)
+#define SIZE(b, i)  (b[i] << 8 | b[INDEX(i + 1)])
+
 const IRQn_Type UARTx_IRQn[] = {UART0_IRQn, UART1_IRQn, UART2_IRQn, UART3_IRQn};
 
 XBee::FrameType XBee::receive(float timeout) {
+    timer.reset();
     flush();
 
     while (true) {
@@ -43,13 +47,13 @@
             free += (2 + size);
             UNLOCK();
             continue;
-        } else if (timeout <= 0) {
+        } else if (timeout <= timer.read()) {
             UNLOCK();
             return None;
+        } else {
+            UNLOCK();
+            sem.wait((int) ((timeout - timer.read()) * 1000));
         }
-        UNLOCK();
-        wait(0.001);
-        timeout -= 0.001;
     }
 }
 
@@ -60,8 +64,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) {
+    timer.reset();
     LOCK();
 
     while (out != in && getFrameType(buf[INDEX(out + 2)]) == None) {
@@ -77,23 +81,21 @@
                 UNLOCK();
                 return index;
             }
-            //::printf("seekFor: index = %02X\n", index);
             int size = SIZE(buf, index);
             index = INDEX(index + 2 + size);
             continue;
-        } else if (timeout <= 0) {
+        } else if (timeout <= timer.read()) {
             UNLOCK();
             return -1;
+        } else {
+            UNLOCK();
+            sem.wait((int) ((timeout - timer.read()) * 1000));
+            LOCK();
         }
-        UNLOCK();
-        wait(0.001);
-        timeout -= 0.001;
-        LOCK();
     }
 }
 
-XBee::FrameType XBee::getFrameType(char c)
-{
+XBee::FrameType XBee::getFrameType(char c) {
     switch (c) {
         case 0x00:
             return None;
@@ -120,8 +122,7 @@
     }
 }
 
-void XBee::flush()
-{
+void XBee::flush() {
     LOCK();
     if (received == out) {
         do {
@@ -162,7 +163,7 @@
     }
 
     if (c != -1) {
-        if (apiMode == 2) {
+        if (api == 2) {
             if (escaped) {
                 c ^= 0x20;
                 escaped = false;
@@ -209,6 +210,7 @@
                     free = in <= out ? out - in : BUFSIZE + out - in; // maybe in == out, then free == 0, but != BUFSIZE
                 }
                 state = UNKNOWN;
+                sem.release();
                 break;
                 
             default:
--- a/RingBuffer.h	Wed Mar 20 00:28:27 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
-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
-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 RING_BUFFER_H
-#define RING_BUFFER_H
-
-#include <stdio.h>
-template <typename T, size_t SIZE>
-class RingBuffer {
-public:
-    RingBuffer() : head(0), tail(0) {
-    }
-
-    int writable() {
-        return head < tail ? tail - head - 1 : tail - head + (sizeof(buf) / sizeof(T)) - 1;
-    }
-
-    int readable() {
-        return tail <= head ? head - tail : head - tail + (sizeof(buf) / sizeof(T)) - 1;
-    }
-
-    T putc(T c) {
-        if (!writable())
-            return (T) -1;
-
-        buf[head] = c;
-        head = (head + 1) % (sizeof(buf) / sizeof(T));
-
-        return c;
-    }
-
-    int getc() {
-        if (readable()) {
-            T c = buf[tail];
-            tail = (tail + 1) % (sizeof(buf) / sizeof(T));
-            return c;
-        }
-        return -1;
-    }
-
-    T operator=(T c) {
-        return putc(c);
-    }
-
-    operator int() {
-        return (int) getc();
-    }
-
-    int head, tail;
-    T buf[SIZE];
-};
-
-#endif
\ No newline at end of file
--- a/Scan.cpp	Wed Mar 20 00:28:27 2013 +0000
+++ b/Scan.cpp	Thu Mar 21 06:51:31 2013 +0000
@@ -22,6 +22,70 @@
 
 #include "XBee.h"
 
+#define INDEX(n)    ((n) % BUFSIZE)
+#define SIZE(b, i)  (b[i] << 8 | b[INDEX(i + 1)])
+#define min(x, y)   ((x) <= (y) ? (x) : (y))
+
+bool XBee::scan(XBeeFrameID& id) {
+    return scan(XBee::FrameID, id.raw_address(), 1);
+}
+
+bool XBee::scan(XBeeRetryCount& count) {
+    return scan(XBee::RetryCount, count.raw_address(), 1);
+}
+
+bool XBee::scan(XBeeStatus& status) {
+    return scan(XBee::Status, status.raw_address(), 1);
+}
+
+bool XBee::scan(XBeeDeliveryStatus& status) {
+    return scan(XBee::DeliveryStatus, status.raw_address(), 1);
+}
+
+bool XBee::scan(XBeeDiscoveryStatus& status) {
+    return scan(XBee::DiscoveryStatus, status.raw_address(), 1);
+}
+
+bool XBee::scan(XBeeReceiveOptions& options) {
+    return scan(XBee::ReceiveOptions, options.raw_address(), 1);
+}
+
+bool XBee::scan(XBeeDeviceType& device) {
+    return scan(XBee::DeviceType, device.raw_address(), 1);
+}
+
+bool XBee::scan(XBeeSourceEvent& event) {
+    return scan(XBee::SourceEvent, event.raw_address(), 1);
+}
+
+bool XBee::scan(XBeeAddress64& address64) {
+    return scan(XBee::Address64, address64.raw_address(), 8);
+}
+
+bool XBee::scan(XBeeAddress16& address16) {
+    return scan(XBee::Address16, address16.raw_address(), 2);
+}
+
+bool XBee::scan(XBeeATCommand& command) {
+    return scan(XBee::ATCommand, command.raw_address(), 3);
+}
+
+bool XBee::scan(XBeeCommandData& data) {
+    return scan(XBee::CommandData, data.raw_address(), data.capacity, &data.size);
+}
+
+bool XBee::scan(XBeeReceivedData& data) {
+    return scan(XBee::ReceivedData, data.raw_address(), data.capacity, &data.size);
+}
+
+bool XBee::scan(XBeeNodeIdentifier& ni) {
+    return scan(XBee::NIString, ni.raw_address(), ni.capacity, &ni.size);
+}
+
+bool XBee::scan(XBeeRawData& data) {
+    return scan(XBee::RawData, data.raw_address(), data.capacity, &data.size);
+}
+
 bool XBee::scan(ValueType type, char *value, int maxlength, int *length) {
     if (received != out || (in == out && free != 0))
         return false;
--- a/Send.cpp	Wed Mar 20 00:28:27 2013 +0000
+++ b/Send.cpp	Thu Mar 21 06:51:31 2013 +0000
@@ -23,8 +23,11 @@
 #include "XBee.h"
 #include <stdarg.h>
 
-#define LOCK()          NVIC_DisableIRQ(UARTx_IRQn[_serial.index])
-#define UNLOCK()        NVIC_EnableIRQ(UARTx_IRQn[_serial.index])
+#define LOCK()      NVIC_DisableIRQ(UARTx_IRQn[_serial.index])
+#define UNLOCK()    NVIC_EnableIRQ(UARTx_IRQn[_serial.index])
+#define INDEX(n)    ((n) % BUFSIZE)
+#define SIZE(b, i)  (b[i] << 8 | b[INDEX(i + 1)])
+
 const IRQn_Type UARTx_IRQn[] = {UART0_IRQn, UART1_IRQn, UART2_IRQn, UART3_IRQn};
 
 void XBee::sendCommand(const char *command, int8_t param, bool queue) {
@@ -208,7 +211,7 @@
 
     send(PREAMBLE);
 
-    if (apiMode == 2) {
+    if (api == 2) {
         send2((length >> 8) & 255);
         send2(length & 255);
         for (int i = 0; i < length; i++) {
--- a/XBee.cpp	Wed Mar 20 00:28:27 2013 +0000
+++ b/XBee.cpp	Thu Mar 21 06:51:31 2013 +0000
@@ -22,44 +22,55 @@
 
 #include "XBee.h"
 
-#define LOCK()          NVIC_DisableIRQ(UARTx_IRQn[_serial.index])
-#define UNLOCK()        NVIC_EnableIRQ(UARTx_IRQn[_serial.index])
+#define LOCK()      NVIC_DisableIRQ(UARTx_IRQn[_serial.index])
+#define UNLOCK()    NVIC_EnableIRQ(UARTx_IRQn[_serial.index])
+#define INDEX(n)    ((n) % BUFSIZE)
+#define SIZE(b, i)  (b[i] << 8 | b[INDEX(i + 1)])
+#define min(x, y)   ((x) <= (y) ? (x) : (y))
+
 const IRQn_Type UARTx_IRQn[] = {UART0_IRQn, UART1_IRQn, UART2_IRQn, UART3_IRQn};
 
-XBee::XBee(Serial& ser, int apiMode)
-    : Serial(ser), mon(USBTX, USBRX), apiMode(apiMode),
+XBee::XBee(Serial& ser, int api)
+    : Serial(ser), mon(USBTX, USBRX), sem(0), api(api),
       in(0), out(0), received(-1), free(BUFSIZE), frame_id(1), sendConfirmation(0) {
     memset(buf, 0, BUFSIZE);
     attach(this, &XBee::rxISR, RxIrq);
+    timer.start();
 }
 
-XBee::XBee(PinName tx, PinName rx, int apiMode)
-    : Serial(tx, rx), mon(USBTX, USBRX), apiMode(apiMode),
+XBee::XBee(PinName tx, PinName rx, int api)
+    : Serial(tx, rx), mon(USBTX, USBRX), sem(0), api(api),
       in(0), out(0), received(-1), free(BUFSIZE), frame_id(1), sendConfirmation(0) {
     memset(buf, 0, BUFSIZE);
     attach(this, &XBee::rxISR, RxIrq);
+    timer.start();
 }
 
-XBee::XBee(Serial& ser, Serial& mon, int apiMode)
-    : Serial(ser), mon(mon), apiMode(apiMode),
+XBee::XBee(Serial& ser, Serial& mon, int api)
+    : Serial(ser), mon(mon), sem(0), api(api),
       in(0), out(0), received(-1), free(BUFSIZE), frame_id(1), sendConfirmation(0) {
     memset(buf, 0, BUFSIZE);
     attach(this, &XBee::rxISR, RxIrq);
+    timer.start();
 }
 
-XBee::XBee(PinName tx, PinName rx, Serial& mon, int apiMode)
-    : Serial(tx, rx), mon(mon), apiMode(apiMode),
+XBee::XBee(PinName tx, PinName rx, Serial& mon, int api)
+    : Serial(tx, rx), mon(mon), sem(0), api(api),
       in(0), out(0), received(-1), free(BUFSIZE), frame_id(1), sendConfirmation(0) {
     memset(buf, 0, BUFSIZE);
     attach(this, &XBee::rxISR, RxIrq);
+    timer.start();
 }
 
 bool XBee::init(float timeout) {
-    while (readable()) getc();
-    while (timeout > 0 && getFirmwareVersion() == -1) {
-        timeout -= 1;
+    Timer timer2;
+    timer2.start();
+    
+    while (readable())
+        getc();
+        
+    while (timer2.read() < timeout && getFirmwareVersion() == -1)
         wait(0.8);
-    }
 
     switch (getFirmwareVersion() & 0xFF00) {
         case 0x2100:
@@ -200,8 +211,4 @@
     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
--- a/XBee.h	Wed Mar 20 00:28:27 2013 +0000
+++ b/XBee.h	Thu Mar 21 06:51:31 2013 +0000
@@ -25,14 +25,11 @@
 
 #include "mbed.h"
 #include "XBeeDataTypes.h"
+#include "rtos.h"
 
-#define min(x, y)       ((x) < (y) ? (x) : (y))
-#define INDEX(n)        ((n) % BUFSIZE)
-#define SIZE(b, i)      (b[i] << 8 | b[INDEX(i + 1)])
-
-const int BUFSIZE = 512;
 const char ESCAPE = 0x7D;
 const char PREAMBLE = 0x7E;
+const int BUFSIZE = 512;
 
 /**
  * class for XBee module API mode interface
@@ -199,30 +196,27 @@
      * 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
+     * @param api API mode either 1 or 2 (use escape; default)
      */
-    XBee(Serial& ser, int apiMode = 2);
+    XBee(Serial& ser, int api = 2);
 
     /**
      * creates an XBee interface object.
      *
      * @param tx TX pin connected to XBee
      * @param rx RX pin connected to XBee
-     * @param apiMode API mode either 1 or 2 (use escape; default)
-     * @param debug display debugging (I/O state) information through LEDs
+     * @param api API mode either 1 or 2 (use escape; default)
      */
-    XBee(PinName tx, PinName rx, int apiMode = 2);
+    XBee(PinName tx, PinName rx, int api = 2);
 
     /**
      * 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
+     * @param api API mode either 1 or 2 (use escape; default)
      */
-    XBee(Serial& ser, Serial& mon, int apiMode = 2);
+    XBee(Serial& ser, Serial& mon, int api = 2);
 
     /**
      * creates an XBee interface object.
@@ -230,10 +224,9 @@
      * @param tx TX pin connected to XBee
      * @param rx RX pin connected to XBee
      * @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
+     * @param api API mode either 1 or 2 (use escape; default)
      */
-    XBee(PinName tx, PinName rx, Serial& mon, int apiMode = 2);
+    XBee(PinName tx, PinName rx, Serial& mon, int api = 2);
     
     /**
      * initializes XBee module.
@@ -400,21 +393,21 @@
      *
      * @param true if scan succeeded, false otherwise
      */
-    bool scan(XBeeFrameID& id) { return scan(XBee::FrameID, id.raw_address(), 1); }
-    bool scan(XBeeRetryCount& count) { return scan(XBee::RetryCount, count.raw_address(), 1); }
-    bool scan(XBeeStatus& status) { return scan(XBee::Status, status.raw_address(), 1); }
-    bool scan(XBeeDeliveryStatus& status) { return scan(XBee::DeliveryStatus, status.raw_address(), 1); }
-    bool scan(XBeeDiscoveryStatus& status) { return scan(XBee::DiscoveryStatus, status.raw_address(), 1); }
-    bool scan(XBeeReceiveOptions& options) { return scan(XBee::ReceiveOptions, options.raw_address(), 1); }
-    bool scan(XBeeDeviceType& device) { return scan(XBee::DeviceType, device.raw_address(), 1); }
-    bool scan(XBeeSourceEvent& event) { return scan(XBee::SourceEvent, event.raw_address(), 1); }
-    bool scan(XBeeAddress64& address64) { return scan(XBee::Address64, address64.raw_address(), 8); }
-    bool scan(XBeeAddress16& address16) { return scan(XBee::Address16, address16.raw_address(), 2); }
-    bool scan(XBeeATCommand& command) { return scan(XBee::ATCommand, command.raw_address(), 3); }
-    bool scan(XBeeCommandData& data) { return scan(XBee::CommandData, data.raw_address(), data.capacity, &data.size); }
-    bool scan(XBeeReceivedData& data) { return scan(XBee::ReceivedData, data.raw_address(), data.capacity, &data.size); }
-    bool scan(XBeeNodeIdentifier& ni) { return scan(XBee::NIString, ni.raw_address(), ni.capacity, &ni.size); }
-    bool scan(XBeeRawData& data) { return scan(XBee::RawData, data.raw_address(), data.capacity, &data.size); }
+    bool scan(XBeeFrameID& id);
+    bool scan(XBeeRetryCount& count);
+    bool scan(XBeeStatus& status);
+    bool scan(XBeeDeliveryStatus& status);
+    bool scan(XBeeDiscoveryStatus& status);
+    bool scan(XBeeReceiveOptions& options);
+    bool scan(XBeeDeviceType& device);
+    bool scan(XBeeSourceEvent& event);
+    bool scan(XBeeAddress64& address64);
+    bool scan(XBeeAddress16& address16);
+    bool scan(XBeeATCommand& command);
+    bool scan(XBeeCommandData& data);
+    bool scan(XBeeReceivedData& data);
+    bool scan(XBeeNodeIdentifier& ni);
+    bool scan(XBeeRawData& data);
     
     /**
      * scan received data according to the specified format.
@@ -443,13 +436,6 @@
     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();
@@ -468,14 +454,15 @@
 
 private:
     Serial mon;
-    int apiMode;
+    Timer timer;
+    Semaphore sem;
+    int api;
     volatile int cur, in, out, received, free;
     char frame_id;
     float sendConfirmation;
     char destination64[8];
     char destination16[2];
     char buf[BUFSIZE];
-    bool debug;
 
     void send(char c);
     void send2(char c);