XBee API mode library
Diff: Receive.cpp
- Revision:
- 8:776b8dc51932
- Parent:
- 4:c05dc188f177
- Child:
- 10:3da24a020e67
diff -r 19f03567ec4e -r 776b8dc51932 Receive.cpp --- 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