XBee API mode library

Committer:
yamaguch
Date:
Wed Mar 20 00:28:27 2013 +0000
Revision:
16:cdfcb63b2c4b
Parent:
14:af6e497bbf52
Child:
17:2f728fd13bc0
non rtos version

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 #define LOCK() NVIC_DisableIRQ(UARTx_IRQn[_serial.index])
yamaguch 8:776b8dc51932 26 #define UNLOCK() NVIC_EnableIRQ(UARTx_IRQn[_serial.index])
yamaguch 0:0232a97b3883 27 const IRQn_Type UARTx_IRQn[] = {UART0_IRQn, UART1_IRQn, UART2_IRQn, UART3_IRQn};
yamaguch 0:0232a97b3883 28
yamaguch 14:af6e497bbf52 29 XBee::FrameType XBee::receive(float timeout) {
yamaguch 0:0232a97b3883 30 flush();
yamaguch 8:776b8dc51932 31
yamaguch 0:0232a97b3883 32 while (true) {
yamaguch 8:776b8dc51932 33 LOCK();
yamaguch 0:0232a97b3883 34 if (out != in || free == 0) {
yamaguch 0:0232a97b3883 35 FrameType type = getFrameType(buf[INDEX(out + 2)]);
yamaguch 0:0232a97b3883 36 if (type != None) {
yamaguch 0:0232a97b3883 37 received = out;
yamaguch 8:776b8dc51932 38 UNLOCK();
yamaguch 0:0232a97b3883 39 return type;
yamaguch 0:0232a97b3883 40 }
yamaguch 0:0232a97b3883 41 int size = SIZE(buf, out);
yamaguch 0:0232a97b3883 42 out = INDEX(out + 2 + size);
yamaguch 0:0232a97b3883 43 free += (2 + size);
yamaguch 8:776b8dc51932 44 UNLOCK();
yamaguch 0:0232a97b3883 45 continue;
yamaguch 0:0232a97b3883 46 } else if (timeout <= 0) {
yamaguch 8:776b8dc51932 47 UNLOCK();
yamaguch 0:0232a97b3883 48 return None;
yamaguch 0:0232a97b3883 49 }
yamaguch 8:776b8dc51932 50 UNLOCK();
yamaguch 0:0232a97b3883 51 wait(0.001);
yamaguch 0:0232a97b3883 52 timeout -= 0.001;
yamaguch 0:0232a97b3883 53 }
yamaguch 0:0232a97b3883 54 }
yamaguch 0:0232a97b3883 55
yamaguch 0:0232a97b3883 56 /*
yamaguch 0:0232a97b3883 57 * function seekFor() -
yamaguch 0:0232a97b3883 58 *
yamaguch 3:8453df14bd30 59 * searches buf[] in range between the index out and in for a frame of specified type and id.
yamaguch 0:0232a97b3883 60 * if the frame is found before timeout, returns the index of the packet, otherwise -1.
yamaguch 0:0232a97b3883 61 *
yamaguch 0:0232a97b3883 62 */
yamaguch 16:cdfcb63b2c4b 63 int XBee::seekFor(FrameType type, char id, float timeout)
yamaguch 16:cdfcb63b2c4b 64 {
yamaguch 16:cdfcb63b2c4b 65 LOCK();
yamaguch 10:3da24a020e67 66
yamaguch 16:cdfcb63b2c4b 67 while (out != in && getFrameType(buf[INDEX(out + 2)]) == None) {
yamaguch 16:cdfcb63b2c4b 68 int size = SIZE(buf, out);
yamaguch 16:cdfcb63b2c4b 69 out = INDEX(out + 2 + size);
yamaguch 16:cdfcb63b2c4b 70 free += 2 + size;
yamaguch 16:cdfcb63b2c4b 71 }
yamaguch 16:cdfcb63b2c4b 72
yamaguch 16:cdfcb63b2c4b 73 int index = out;
yamaguch 16:cdfcb63b2c4b 74 while (true) {
yamaguch 16:cdfcb63b2c4b 75 if (index != in) {
yamaguch 16:cdfcb63b2c4b 76 if (getFrameType(buf[INDEX(index + 2)]) == type && (id == 0 || buf[INDEX(index + 3)] == id)) {
yamaguch 16:cdfcb63b2c4b 77 UNLOCK();
yamaguch 0:0232a97b3883 78 return index;
yamaguch 16:cdfcb63b2c4b 79 }
yamaguch 16:cdfcb63b2c4b 80 //::printf("seekFor: index = %02X\n", index);
yamaguch 0:0232a97b3883 81 int size = SIZE(buf, index);
yamaguch 0:0232a97b3883 82 index = INDEX(index + 2 + size);
yamaguch 16:cdfcb63b2c4b 83 continue;
yamaguch 16:cdfcb63b2c4b 84 } else if (timeout <= 0) {
yamaguch 16:cdfcb63b2c4b 85 UNLOCK();
yamaguch 16:cdfcb63b2c4b 86 return -1;
yamaguch 16:cdfcb63b2c4b 87 }
yamaguch 16:cdfcb63b2c4b 88 UNLOCK();
yamaguch 0:0232a97b3883 89 wait(0.001);
yamaguch 0:0232a97b3883 90 timeout -= 0.001;
yamaguch 16:cdfcb63b2c4b 91 LOCK();
yamaguch 0:0232a97b3883 92 }
yamaguch 0:0232a97b3883 93 }
yamaguch 0:0232a97b3883 94
yamaguch 16:cdfcb63b2c4b 95 XBee::FrameType XBee::getFrameType(char c)
yamaguch 16:cdfcb63b2c4b 96 {
yamaguch 0:0232a97b3883 97 switch (c) {
yamaguch 0:0232a97b3883 98 case 0x00:
yamaguch 0:0232a97b3883 99 return None;
yamaguch 0:0232a97b3883 100 case 0x88:
yamaguch 0:0232a97b3883 101 return ATCommandResponse;
yamaguch 0:0232a97b3883 102 case 0x8A:
yamaguch 0:0232a97b3883 103 return ModemStatus;
yamaguch 0:0232a97b3883 104 case 0x8B:
yamaguch 0:0232a97b3883 105 return ZigBeeTransmitStatus;
yamaguch 0:0232a97b3883 106 case 0x90:
yamaguch 0:0232a97b3883 107 return ZigBeeReceivePacket;
yamaguch 0:0232a97b3883 108 case 0x91:
yamaguch 0:0232a97b3883 109 return ZigBeeExplicitRxIndicator;
yamaguch 0:0232a97b3883 110 case 0x92:
yamaguch 0:0232a97b3883 111 return ZigBeeIODataSampleRxIndicator;
yamaguch 0:0232a97b3883 112 case 0x94:
yamaguch 0:0232a97b3883 113 return XBeeSensorReadIndicator;
yamaguch 0:0232a97b3883 114 case 0x95:
yamaguch 0:0232a97b3883 115 return NodeIdentificationIndicator;
yamaguch 0:0232a97b3883 116 case 0x97:
yamaguch 0:0232a97b3883 117 return RemoteCommandResponse;
yamaguch 0:0232a97b3883 118 default:
yamaguch 0:0232a97b3883 119 return Other;
yamaguch 0:0232a97b3883 120 }
yamaguch 0:0232a97b3883 121 }
yamaguch 0:0232a97b3883 122
yamaguch 16:cdfcb63b2c4b 123 void XBee::flush()
yamaguch 16:cdfcb63b2c4b 124 {
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 }
yamaguch 8:776b8dc51932 133 UNLOCK();
yamaguch 0:0232a97b3883 134 }
yamaguch 0:0232a97b3883 135
yamaguch 16:cdfcb63b2c4b 136 void XBee::rxISR() {
yamaguch 16:cdfcb63b2c4b 137 static enum {UNKNOWN, LENGTH1, LENGTH2, DATA, SUMCHECK} state = UNKNOWN;
yamaguch 14:af6e497bbf52 138 static bool escaped = false;
yamaguch 16:cdfcb63b2c4b 139 int c = -1;
yamaguch 16:cdfcb63b2c4b 140
yamaguch 16:cdfcb63b2c4b 141 switch (_serial.index) {
yamaguch 16:cdfcb63b2c4b 142 case 0: {// USBTX, USBRX
yamaguch 16:cdfcb63b2c4b 143 uint32_t UART_0_IIR = LPC_UART0->IIR;
yamaguch 16:cdfcb63b2c4b 144 if (readable()) c = LPC_UART0->RBR;
yamaguch 16:cdfcb63b2c4b 145 }
yamaguch 16:cdfcb63b2c4b 146 break;
yamaguch 16:cdfcb63b2c4b 147 case 1: {// p13/14
yamaguch 16:cdfcb63b2c4b 148 uint32_t UART_1_IIR = LPC_UART1->IIR;
yamaguch 16:cdfcb63b2c4b 149 if (readable()) c = LPC_UART1->RBR;
yamaguch 16:cdfcb63b2c4b 150 }
yamaguch 16:cdfcb63b2c4b 151 break;
yamaguch 16:cdfcb63b2c4b 152 case 2: {// p28/27
yamaguch 16:cdfcb63b2c4b 153 uint32_t UART_2_IIR = LPC_UART2->IIR;
yamaguch 16:cdfcb63b2c4b 154 if (readable()) c = LPC_UART2->RBR;
yamaguch 16:cdfcb63b2c4b 155 }
yamaguch 16:cdfcb63b2c4b 156 break;
yamaguch 16:cdfcb63b2c4b 157 case 3: {// p9/10
yamaguch 16:cdfcb63b2c4b 158 uint32_t UART_3_IIR = LPC_UART3->IIR;
yamaguch 16:cdfcb63b2c4b 159 if (readable()) c = LPC_UART3->RBR;
yamaguch 16:cdfcb63b2c4b 160 }
yamaguch 16:cdfcb63b2c4b 161 break;
yamaguch 16:cdfcb63b2c4b 162 }
yamaguch 8:776b8dc51932 163
yamaguch 16:cdfcb63b2c4b 164 if (c != -1) {
yamaguch 8:776b8dc51932 165 if (apiMode == 2) {
yamaguch 8:776b8dc51932 166 if (escaped) {
yamaguch 8:776b8dc51932 167 c ^= 0x20;
yamaguch 8:776b8dc51932 168 escaped = false;
yamaguch 8:776b8dc51932 169 } else if (c == ESCAPE) {
yamaguch 8:776b8dc51932 170 escaped = true;
yamaguch 16:cdfcb63b2c4b 171 return;
yamaguch 8:776b8dc51932 172 }
yamaguch 8:776b8dc51932 173 }
yamaguch 8:776b8dc51932 174
yamaguch 0:0232a97b3883 175 switch (state) {
yamaguch 0:0232a97b3883 176 case LENGTH1:
yamaguch 0:0232a97b3883 177 cur = in;
yamaguch 0:0232a97b3883 178 buf[cur] = c;
yamaguch 0:0232a97b3883 179 state = LENGTH2;
yamaguch 0:0232a97b3883 180 break;
yamaguch 16:cdfcb63b2c4b 181
yamaguch 0:0232a97b3883 182 case LENGTH2:
yamaguch 0:0232a97b3883 183 if ((buf[cur] << 8 | c) + 2 < BUFSIZE) {
yamaguch 0:0232a97b3883 184 state = DATA;
yamaguch 0:0232a97b3883 185 while (free < (buf[cur] << 8 | c) + 2) {
yamaguch 0:0232a97b3883 186 int size = SIZE(buf, out);
yamaguch 16:cdfcb63b2c4b 187 out = INDEX(out + size + 2);
yamaguch 16:cdfcb63b2c4b 188 free += (size + 2);
yamaguch 0:0232a97b3883 189 }
yamaguch 0:0232a97b3883 190 buf[INDEX(cur + 1)] = c;
yamaguch 0:0232a97b3883 191 cur = INDEX(cur + 2);
yamaguch 16:cdfcb63b2c4b 192 } else
yamaguch 0:0232a97b3883 193 state = UNKNOWN;
yamaguch 0:0232a97b3883 194 break;
yamaguch 16:cdfcb63b2c4b 195
yamaguch 0:0232a97b3883 196 case DATA:
yamaguch 0:0232a97b3883 197 buf[cur] = c;
yamaguch 0:0232a97b3883 198 cur = INDEX(cur + 1);
yamaguch 16:cdfcb63b2c4b 199 if (cur == INDEX(in + 2 + SIZE(buf, in)))
yamaguch 16:cdfcb63b2c4b 200 state = SUMCHECK;
yamaguch 0:0232a97b3883 201 break;
yamaguch 16:cdfcb63b2c4b 202
yamaguch 0:0232a97b3883 203 case SUMCHECK:
yamaguch 0:0232a97b3883 204 for (int i = INDEX(in + 2); i != cur; i = INDEX(i + 1)) {
yamaguch 0:0232a97b3883 205 c += buf[i];
yamaguch 0:0232a97b3883 206 }
yamaguch 16:cdfcb63b2c4b 207 if ((c & 255) == 255) {
yamaguch 0:0232a97b3883 208 in = cur;
yamaguch 16:cdfcb63b2c4b 209 free = in <= out ? out - in : BUFSIZE + out - in; // maybe in == out, then free == 0, but != BUFSIZE
yamaguch 0:0232a97b3883 210 }
yamaguch 0:0232a97b3883 211 state = UNKNOWN;
yamaguch 0:0232a97b3883 212 break;
yamaguch 16:cdfcb63b2c4b 213
yamaguch 0:0232a97b3883 214 default:
yamaguch 16:cdfcb63b2c4b 215 if (c == PREAMBLE)
yamaguch 16:cdfcb63b2c4b 216 state = LENGTH1;
yamaguch 0:0232a97b3883 217 }
yamaguch 0:0232a97b3883 218 }
yamaguch 16:cdfcb63b2c4b 219 }