XBee API mode library

Committer:
yamaguch
Date:
Thu Mar 21 06:51:31 2013 +0000
Revision:
17:2f728fd13bc0
Parent:
16:cdfcb63b2c4b
rewrote to use rtos Semaphore only

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