XBee API mode library 1.0

Committer:
yamaguch
Date:
Thu Apr 12 10:27:28 2012 +0000
Revision:
4:4a11f50ffb64
Parent:
3:48f7780963e2
updated API documents

Who changed what in which revision?

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