XBee API mode library

Committer:
yamaguch
Date:
Thu Mar 14 09:38:54 2013 +0000
Revision:
14:af6e497bbf52
Parent:
10:3da24a020e67
Child:
16:cdfcb63b2c4b
did some reformat / cleanups

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yamaguch 0:0232a97b3883 1 /*
yamaguch 8:776b8dc51932 2 Copyright (c) 2013, Senio Networks, Inc.
yamaguch 0:0232a97b3883 3
yamaguch 0:0232a97b3883 4 Permission is hereby granted, free of charge, to any person obtaining a copy
yamaguch 0:0232a97b3883 5 of this software and associated documentation files (the "Software"), to deal
yamaguch 0:0232a97b3883 6 in the Software without restriction, including without limitation the rights
yamaguch 0:0232a97b3883 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
yamaguch 0:0232a97b3883 8 copies of the Software, and to permit persons to whom the Software is
yamaguch 0:0232a97b3883 9 furnished to do so, subject to the following conditions:
yamaguch 0:0232a97b3883 10
yamaguch 0:0232a97b3883 11 The above copyright notice and this permission notice shall be included in
yamaguch 0:0232a97b3883 12 all copies or substantial portions of the Software.
yamaguch 0:0232a97b3883 13
yamaguch 0:0232a97b3883 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
yamaguch 0:0232a97b3883 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
yamaguch 0:0232a97b3883 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
yamaguch 0:0232a97b3883 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
yamaguch 0:0232a97b3883 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
yamaguch 0:0232a97b3883 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
yamaguch 0:0232a97b3883 20 THE SOFTWARE.
yamaguch 0:0232a97b3883 21 */
yamaguch 0:0232a97b3883 22
yamaguch 0:0232a97b3883 23 #include "XBee.h"
yamaguch 0:0232a97b3883 24
yamaguch 8:776b8dc51932 25 #ifndef XBEE_RTOS
yamaguch 8:776b8dc51932 26 #define LOCK() NVIC_DisableIRQ(UARTx_IRQn[_serial.index])
yamaguch 8:776b8dc51932 27 #define UNLOCK() NVIC_EnableIRQ(UARTx_IRQn[_serial.index])
yamaguch 0:0232a97b3883 28 const IRQn_Type UARTx_IRQn[] = {UART0_IRQn, UART1_IRQn, UART2_IRQn, UART3_IRQn};
yamaguch 8:776b8dc51932 29 #else
yamaguch 8:776b8dc51932 30 #define LOCK() mutex.lock()
yamaguch 8:776b8dc51932 31 #define UNLOCK() mutex.unlock();
yamaguch 8:776b8dc51932 32 #endif
yamaguch 0:0232a97b3883 33
yamaguch 14:af6e497bbf52 34 XBee::FrameType XBee::receive(float timeout) {
yamaguch 0:0232a97b3883 35 flush();
yamaguch 8:776b8dc51932 36
yamaguch 0:0232a97b3883 37 while (true) {
yamaguch 8:776b8dc51932 38 LOCK();
yamaguch 0:0232a97b3883 39 if (out != in || free == 0) {
yamaguch 0:0232a97b3883 40 FrameType type = getFrameType(buf[INDEX(out + 2)]);
yamaguch 0:0232a97b3883 41 if (type != None) {
yamaguch 0:0232a97b3883 42 received = out;
yamaguch 8:776b8dc51932 43 UNLOCK();
yamaguch 0:0232a97b3883 44 return type;
yamaguch 0:0232a97b3883 45 }
yamaguch 0:0232a97b3883 46 int size = SIZE(buf, out);
yamaguch 0:0232a97b3883 47 out = INDEX(out + 2 + size);
yamaguch 0:0232a97b3883 48 free += (2 + size);
yamaguch 8:776b8dc51932 49 UNLOCK();
yamaguch 0:0232a97b3883 50 continue;
yamaguch 0:0232a97b3883 51 } else if (timeout <= 0) {
yamaguch 8:776b8dc51932 52 UNLOCK();
yamaguch 0:0232a97b3883 53 return None;
yamaguch 0:0232a97b3883 54 }
yamaguch 8:776b8dc51932 55 UNLOCK();
yamaguch 8:776b8dc51932 56
yamaguch 8:776b8dc51932 57 #ifndef XBEE_RTOS
yamaguch 0:0232a97b3883 58 wait(0.001);
yamaguch 0:0232a97b3883 59 timeout -= 0.001;
yamaguch 8:776b8dc51932 60 #else
yamaguch 8:776b8dc51932 61 Thread::wait(50);
yamaguch 8:776b8dc51932 62 timeout -= 0.05;
yamaguch 8:776b8dc51932 63 #endif
yamaguch 0:0232a97b3883 64 }
yamaguch 0:0232a97b3883 65 }
yamaguch 0:0232a97b3883 66
yamaguch 0:0232a97b3883 67 /*
yamaguch 0:0232a97b3883 68 * function seekFor() -
yamaguch 0:0232a97b3883 69 *
yamaguch 3:8453df14bd30 70 * searches buf[] in range between the index out and in for a frame of specified type and id.
yamaguch 0:0232a97b3883 71 * if the frame is found before timeout, returns the index of the packet, otherwise -1.
yamaguch 0:0232a97b3883 72 *
yamaguch 0:0232a97b3883 73 */
yamaguch 10:3da24a020e67 74 int XBee::seekFor(FrameType type, char id, float timeout) {
yamaguch 0:0232a97b3883 75 int index = out;
yamaguch 10:3da24a020e67 76
yamaguch 10:3da24a020e67 77 while (timeout > 0) {
yamaguch 10:3da24a020e67 78 if (index != in) {
yamaguch 3:8453df14bd30 79 if (getFrameType(buf[INDEX(index + 2)]) == type && (id == 0 || buf[INDEX(index + 3)] == id))
yamaguch 0:0232a97b3883 80 return index;
yamaguch 0:0232a97b3883 81 int size = SIZE(buf, index);
yamaguch 0:0232a97b3883 82 index = INDEX(index + 2 + size);
yamaguch 10:3da24a020e67 83 } else {
yamaguch 8:776b8dc51932 84 #ifndef XBEE_RTOS
yamaguch 0:0232a97b3883 85 wait(0.001);
yamaguch 0:0232a97b3883 86 timeout -= 0.001;
yamaguch 8:776b8dc51932 87 #else
yamaguch 8:776b8dc51932 88 Thread::wait(10);
yamaguch 8:776b8dc51932 89 timeout -= 0.01;
yamaguch 8:776b8dc51932 90 #endif
yamaguch 10:3da24a020e67 91 }
yamaguch 0:0232a97b3883 92 }
yamaguch 10:3da24a020e67 93
yamaguch 10:3da24a020e67 94 return -1;
yamaguch 0:0232a97b3883 95 }
yamaguch 0:0232a97b3883 96
yamaguch 14:af6e497bbf52 97 XBee::FrameType XBee::getFrameType(char c) {
yamaguch 0:0232a97b3883 98 switch (c) {
yamaguch 0:0232a97b3883 99 case 0x00:
yamaguch 0:0232a97b3883 100 return None;
yamaguch 0:0232a97b3883 101 case 0x88:
yamaguch 0:0232a97b3883 102 return ATCommandResponse;
yamaguch 0:0232a97b3883 103 case 0x8A:
yamaguch 0:0232a97b3883 104 return ModemStatus;
yamaguch 0:0232a97b3883 105 case 0x8B:
yamaguch 0:0232a97b3883 106 return ZigBeeTransmitStatus;
yamaguch 0:0232a97b3883 107 case 0x90:
yamaguch 0:0232a97b3883 108 return ZigBeeReceivePacket;
yamaguch 0:0232a97b3883 109 case 0x91:
yamaguch 0:0232a97b3883 110 return ZigBeeExplicitRxIndicator;
yamaguch 0:0232a97b3883 111 case 0x92:
yamaguch 0:0232a97b3883 112 return ZigBeeIODataSampleRxIndicator;
yamaguch 0:0232a97b3883 113 case 0x94:
yamaguch 0:0232a97b3883 114 return XBeeSensorReadIndicator;
yamaguch 0:0232a97b3883 115 case 0x95:
yamaguch 0:0232a97b3883 116 return NodeIdentificationIndicator;
yamaguch 0:0232a97b3883 117 case 0x97:
yamaguch 0:0232a97b3883 118 return RemoteCommandResponse;
yamaguch 0:0232a97b3883 119 default:
yamaguch 0:0232a97b3883 120 return Other;
yamaguch 0:0232a97b3883 121 }
yamaguch 0:0232a97b3883 122 }
yamaguch 0:0232a97b3883 123
yamaguch 14:af6e497bbf52 124 void XBee::flush() {
yamaguch 8:776b8dc51932 125 LOCK();
yamaguch 0:0232a97b3883 126 if (received == out) {
yamaguch 0:0232a97b3883 127 do {
yamaguch 0:0232a97b3883 128 int size = SIZE(buf, out);
yamaguch 0:0232a97b3883 129 out = INDEX(out + 2 + size);
yamaguch 0:0232a97b3883 130 free += 2 + size;
yamaguch 0:0232a97b3883 131 } while (out != in && getFrameType(buf[INDEX(out + 2)]) == None);
yamaguch 0:0232a97b3883 132 if (debug) leds = leds & 12; //**LEDS=xx00
yamaguch 0:0232a97b3883 133 }
yamaguch 8:776b8dc51932 134 UNLOCK();
yamaguch 0:0232a97b3883 135 }
yamaguch 0:0232a97b3883 136
yamaguch 8:776b8dc51932 137 #ifndef XBEE_RTOS
yamaguch 14:af6e497bbf52 138 void XBee::rxInterruptHandler() {
yamaguch 14:af6e497bbf52 139 static bool escaped = false;
yamaguch 8:776b8dc51932 140
yamaguch 0:0232a97b3883 141 if (debug) leds = leds ^ 4; //**LEDS=x@xx
yamaguch 0:0232a97b3883 142
yamaguch 0:0232a97b3883 143 while (readable()) {
yamaguch 0:0232a97b3883 144 char c = getc() & 255;
yamaguch 8:776b8dc51932 145
yamaguch 8:776b8dc51932 146 if (apiMode == 2) {
yamaguch 8:776b8dc51932 147 if (escaped) {
yamaguch 8:776b8dc51932 148 c ^= 0x20;
yamaguch 8:776b8dc51932 149 escaped = false;
yamaguch 8:776b8dc51932 150 } else if (c == ESCAPE) {
yamaguch 8:776b8dc51932 151 escaped = true;
yamaguch 8:776b8dc51932 152 continue;
yamaguch 8:776b8dc51932 153 }
yamaguch 8:776b8dc51932 154 }
yamaguch 8:776b8dc51932 155
yamaguch 0:0232a97b3883 156 switch (state) {
yamaguch 0:0232a97b3883 157 case LENGTH1:
yamaguch 0:0232a97b3883 158 cur = in;
yamaguch 0:0232a97b3883 159 buf[cur] = c;
yamaguch 0:0232a97b3883 160 state = LENGTH2;
yamaguch 0:0232a97b3883 161 break;
yamaguch 0:0232a97b3883 162 case LENGTH2:
yamaguch 0:0232a97b3883 163 if ((buf[cur] << 8 | c) + 2 < BUFSIZE) {
yamaguch 0:0232a97b3883 164 state = DATA;
yamaguch 0:0232a97b3883 165 while (free < (buf[cur] << 8 | c) + 2) {
yamaguch 0:0232a97b3883 166 int size = SIZE(buf, out);
yamaguch 0:0232a97b3883 167 out = INDEX(out + 2 + size);
yamaguch 0:0232a97b3883 168 free += size + 2;
yamaguch 0:0232a97b3883 169 }
yamaguch 0:0232a97b3883 170 buf[INDEX(cur + 1)] = c;
yamaguch 0:0232a97b3883 171 cur = INDEX(cur + 2);
yamaguch 0:0232a97b3883 172 if (debug) leds = (leds & 12) | 1; //**LEDS=xx01
yamaguch 0:0232a97b3883 173 } else {
yamaguch 0:0232a97b3883 174 state = UNKNOWN;
yamaguch 0:0232a97b3883 175 if (debug) leds = leds & 12; //**LEDS=xx00
yamaguch 0:0232a97b3883 176 }
yamaguch 0:0232a97b3883 177 break;
yamaguch 0:0232a97b3883 178 case DATA:
yamaguch 0:0232a97b3883 179 buf[cur] = c;
yamaguch 0:0232a97b3883 180 cur = INDEX(cur + 1);
yamaguch 0:0232a97b3883 181 if (debug) leds = (leds & 12) | (cur & 3); //**LEDS=xx@@
yamaguch 0:0232a97b3883 182 if (cur == INDEX(in + 2 + SIZE(buf, in))) state = SUMCHECK;
yamaguch 0:0232a97b3883 183 break;
yamaguch 0:0232a97b3883 184 case SUMCHECK:
yamaguch 0:0232a97b3883 185 for (int i = INDEX(in + 2); i != cur; i = INDEX(i + 1)) {
yamaguch 0:0232a97b3883 186 c += buf[i];
yamaguch 0:0232a97b3883 187 }
yamaguch 0:0232a97b3883 188 if (c == 255) {
yamaguch 0:0232a97b3883 189 if (debug) leds = (leds & 12) | 3; //**LEDS=xx11
yamaguch 0:0232a97b3883 190 in = cur;
yamaguch 8:776b8dc51932 191 free = in < out ? out - in : BUFSIZE + out - in;
yamaguch 0:0232a97b3883 192 }
yamaguch 0:0232a97b3883 193 state = UNKNOWN;
yamaguch 0:0232a97b3883 194 break;
yamaguch 0:0232a97b3883 195 default:
yamaguch 0:0232a97b3883 196 if (c == PREAMBLE) state = LENGTH1;
yamaguch 0:0232a97b3883 197 if (debug) leds = (leds & 12) | 1; //**LEDS=xx01
yamaguch 0:0232a97b3883 198 }
yamaguch 0:0232a97b3883 199 }
yamaguch 0:0232a97b3883 200 }
yamaguch 8:776b8dc51932 201 #else
yamaguch 14:af6e497bbf52 202 void XBee::rxISR() {
yamaguch 8:776b8dc51932 203 int c = -1;
yamaguch 8:776b8dc51932 204 switch (_serial.index) {
yamaguch 8:776b8dc51932 205 case 0: {
yamaguch 8:776b8dc51932 206 uint32_t UART_0_IIR = LPC_UART0->IIR;
yamaguch 8:776b8dc51932 207 if (readable()) c = LPC_UART0->RBR;
yamaguch 8:776b8dc51932 208 }
yamaguch 8:776b8dc51932 209 break;
yamaguch 8:776b8dc51932 210 case 1: {
yamaguch 8:776b8dc51932 211 uint32_t UART_1_IIR = LPC_UART1->IIR;
yamaguch 8:776b8dc51932 212 if (readable()) c = LPC_UART1->RBR;
yamaguch 8:776b8dc51932 213 }
yamaguch 8:776b8dc51932 214 break;
yamaguch 8:776b8dc51932 215 case 2: {
yamaguch 8:776b8dc51932 216 uint32_t UART_2_IIR = LPC_UART2->IIR;
yamaguch 8:776b8dc51932 217 if (readable()) c = LPC_UART2->RBR;
yamaguch 8:776b8dc51932 218 }
yamaguch 8:776b8dc51932 219 break;
yamaguch 8:776b8dc51932 220 case 3: {
yamaguch 8:776b8dc51932 221 uint32_t UART_3_IIR = LPC_UART3->IIR;
yamaguch 8:776b8dc51932 222 if (readable()) c = LPC_UART3->RBR;
yamaguch 8:776b8dc51932 223 }
yamaguch 8:776b8dc51932 224 break;
yamaguch 8:776b8dc51932 225 }
yamaguch 8:776b8dc51932 226
yamaguch 8:776b8dc51932 227 if (c != -1) {
yamaguch 8:776b8dc51932 228 rxBuf = c;
yamaguch 10:3da24a020e67 229 notify();
yamaguch 8:776b8dc51932 230 }
yamaguch 8:776b8dc51932 231 }
yamaguch 0:0232a97b3883 232
yamaguch 14:af6e497bbf52 233 void XBee::run() {
yamaguch 8:776b8dc51932 234 bool escaped = false;
yamaguch 0:0232a97b3883 235
yamaguch 8:776b8dc51932 236 while (true) {
yamaguch 10:3da24a020e67 237 wait();
yamaguch 8:776b8dc51932 238 mutex.lock();
yamaguch 8:776b8dc51932 239 if (debug && rxBuf.readable()) leds = leds ^ 4; // x@xx
yamaguch 0:0232a97b3883 240
yamaguch 8:776b8dc51932 241 while (rxBuf.readable()) {
yamaguch 8:776b8dc51932 242 char c = rxBuf.getc() & 255;
yamaguch 8:776b8dc51932 243 if (apiMode == 2) {
yamaguch 8:776b8dc51932 244 if (escaped) {
yamaguch 8:776b8dc51932 245 c ^= 0x20;
yamaguch 8:776b8dc51932 246 escaped = false;
yamaguch 8:776b8dc51932 247 } else if (c == ESCAPE) {
yamaguch 8:776b8dc51932 248 escaped = true;
yamaguch 8:776b8dc51932 249 continue;
yamaguch 8:776b8dc51932 250 }
yamaguch 8:776b8dc51932 251 }
yamaguch 0:0232a97b3883 252
yamaguch 8:776b8dc51932 253 switch (state) {
yamaguch 8:776b8dc51932 254 case LENGTH1:
yamaguch 8:776b8dc51932 255 cur = in;
yamaguch 8:776b8dc51932 256 buf[cur] = c;
yamaguch 8:776b8dc51932 257 state = LENGTH2;
yamaguch 8:776b8dc51932 258 break;
yamaguch 8:776b8dc51932 259 case LENGTH2:
yamaguch 8:776b8dc51932 260 if ((buf[cur] << 8 | c) + 2 < BUFSIZE) {
yamaguch 8:776b8dc51932 261 state = DATA;
yamaguch 8:776b8dc51932 262 while (free < (buf[cur] << 8 | c) + 2) {
yamaguch 8:776b8dc51932 263 int size = SIZE(buf, out);
yamaguch 8:776b8dc51932 264 out = INDEX(out + size + 2);
yamaguch 8:776b8dc51932 265 free += (size + 2);
yamaguch 8:776b8dc51932 266 }
yamaguch 8:776b8dc51932 267 buf[INDEX(cur + 1)] = c;
yamaguch 8:776b8dc51932 268 cur = INDEX(cur + 2);
yamaguch 8:776b8dc51932 269 if (debug) leds = (leds & 12) | 2; // xx10
yamaguch 8:776b8dc51932 270 } else {
yamaguch 8:776b8dc51932 271 state = UNKNOWN;
yamaguch 10:3da24a020e67 272 if (debug) leds = leds & 12; //** update leds
yamaguch 8:776b8dc51932 273 }
yamaguch 8:776b8dc51932 274 break;
yamaguch 8:776b8dc51932 275 case DATA:
yamaguch 8:776b8dc51932 276 buf[cur] = c;
yamaguch 8:776b8dc51932 277 cur = INDEX(cur + 1);
yamaguch 8:776b8dc51932 278 if (debug) leds = (leds & 12) | (cur & 3); //**LEDS=xx@@
yamaguch 8:776b8dc51932 279 if (cur == INDEX(in + 2 + SIZE(buf, in))) state = SUMCHECK;
yamaguch 8:776b8dc51932 280 break;
yamaguch 8:776b8dc51932 281 case SUMCHECK:
yamaguch 8:776b8dc51932 282 for (int i = INDEX(in + 2); i != cur; i = INDEX(i + 1)) {
yamaguch 8:776b8dc51932 283 c += buf[i];
yamaguch 8:776b8dc51932 284 }
yamaguch 8:776b8dc51932 285 if (c == 255) {
yamaguch 8:776b8dc51932 286 if (debug) leds = (leds & 12) | 3; //**LEDS=xx11
yamaguch 8:776b8dc51932 287 in = cur;
yamaguch 8:776b8dc51932 288 free = in <= out ? out - in : BUFSIZE + out - in; // maybe in == out, then free == 0, but != BUFSIZE
yamaguch 0:0232a97b3883 289 }
yamaguch 0:0232a97b3883 290 state = UNKNOWN;
yamaguch 8:776b8dc51932 291 break;
yamaguch 8:776b8dc51932 292 default:
yamaguch 8:776b8dc51932 293 if (c == PREAMBLE) state = LENGTH1;
yamaguch 8:776b8dc51932 294 if (debug) leds = (leds & 12) | 1; //**LEDS=xx01
yamaguch 8:776b8dc51932 295 }
yamaguch 8:776b8dc51932 296 }
yamaguch 8:776b8dc51932 297 mutex.unlock();
yamaguch 8:776b8dc51932 298 }
yamaguch 8:776b8dc51932 299 }
yamaguch 8:776b8dc51932 300 #endif