XBee API mode library
Revision 17:2f728fd13bc0, committed 2013-03-21
- 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
--- 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);