Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Receive.cpp
00001 /* 00002 Copyright (c) 2011, Senio Networks, Inc. 00003 00004 Permission is hereby granted, free of charge, to any person obtaining a copy 00005 of this software and associated documentation files (the "Software"), to deal 00006 in the Software without restriction, including without limitation the rights 00007 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00008 copies of the Software, and to permit persons to whom the Software is 00009 furnished to do so, subject to the following conditions: 00010 00011 The above copyright notice and this permission notice shall be included in 00012 all copies or substantial portions of the Software. 00013 00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00020 THE SOFTWARE. 00021 */ 00022 00023 #include "XBee.h" 00024 00025 #define disableIRQ() NVIC_DisableIRQ(UARTx_IRQn[_uidx]) 00026 #define enableIRQ() NVIC_EnableIRQ(UARTx_IRQn[_uidx]) 00027 00028 const IRQn_Type UARTx_IRQn[] = {UART0_IRQn, UART1_IRQn, UART2_IRQn, UART3_IRQn}; 00029 00030 XBee::FrameType XBee::receive(float timeout) { 00031 flush(); 00032 while (true) { 00033 disableIRQ(); 00034 if (out != in || free == 0) { 00035 FrameType type = getFrameType(buf[INDEX(out + 2)]); 00036 if (type != None) { 00037 received = out; 00038 enableIRQ(); 00039 return type; 00040 } 00041 int size = SIZE(buf, out); 00042 out = INDEX(out + 2 + size); 00043 free += (2 + size); 00044 enableIRQ(); 00045 continue; 00046 } else if (timeout <= 0) { 00047 enableIRQ(); 00048 return None; 00049 } 00050 enableIRQ(); 00051 wait(0.001); 00052 timeout -= 0.001; 00053 } 00054 } 00055 00056 /* 00057 * function seekFor() - 00058 * 00059 * searches buf[] in range between the index out and in for a specified frametype packet. 00060 * if the frame is found before timeout, returns the index of the packet, otherwise -1. 00061 * 00062 */ 00063 int XBee::seekFor(FrameType type, float timeout) { 00064 int index = out; 00065 while (true) { 00066 if (index != in) { 00067 if (getFrameType(buf[INDEX(index + 2)]) == type) 00068 return index; 00069 int size = SIZE(buf, index); 00070 index = INDEX(index + 2 + size); 00071 continue; 00072 } else if (timeout <= 0) { 00073 return -1; 00074 } 00075 wait(0.001); 00076 timeout -= 0.001; 00077 } 00078 } 00079 00080 XBee::FrameType XBee::getFrameType(char c) { 00081 switch (c) { 00082 case 0x00: 00083 return None; 00084 case 0x88: 00085 return ATCommandResponse; 00086 case 0x8A: 00087 return ModemStatus; 00088 case 0x8B: 00089 return ZigBeeTransmitStatus; 00090 case 0x90: 00091 return ZigBeeReceivePacket; 00092 case 0x91: 00093 return ZigBeeExplicitRxIndicator; 00094 case 0x92: 00095 return ZigBeeIODataSampleRxIndicator; 00096 case 0x94: 00097 return XBeeSensorReadIndicator; 00098 case 0x95: 00099 return NodeIdentificationIndicator; 00100 case 0x97: 00101 return RemoteCommandResponse; 00102 default: 00103 return Other; 00104 } 00105 } 00106 00107 void XBee::flush() { 00108 disableIRQ(); 00109 if (received == out) { 00110 do { 00111 int size = SIZE(buf, out); 00112 out = INDEX(out + 2 + size); 00113 free += 2 + size; 00114 } while (out != in && getFrameType(buf[INDEX(out + 2)]) == None); 00115 if (debug) leds = leds & 12; //**LEDS=xx00 00116 } 00117 enableIRQ(); 00118 } 00119 00120 void XBee::rxInterruptHandler() { 00121 if (debug) leds = leds ^ 4; //**LEDS=x@xx 00122 00123 while (readable()) { 00124 char c = getc() & 255; 00125 switch (state) { 00126 case LENGTH1: 00127 cur = in; 00128 buf[cur] = c; 00129 state = LENGTH2; 00130 break; 00131 case LENGTH2: 00132 if ((buf[cur] << 8 | c) + 2 < BUFSIZE) { 00133 state = DATA; 00134 while (free < (buf[cur] << 8 | c) + 2) { 00135 int size = SIZE(buf, out); 00136 out = INDEX(out + 2 + size); 00137 free += size + 2; 00138 } 00139 buf[INDEX(cur + 1)] = c; 00140 cur = INDEX(cur + 2); 00141 if (debug) leds = (leds & 12) | 1; //**LEDS=xx01 00142 } else { 00143 state = UNKNOWN; 00144 if (debug) leds = leds & 12; //**LEDS=xx00 00145 } 00146 break; 00147 case DATA: 00148 buf[cur] = c; 00149 cur = INDEX(cur + 1); 00150 if (debug) leds = (leds & 12) | (cur & 3); //**LEDS=xx@@ 00151 if (cur == INDEX(in + 2 + SIZE(buf, in))) state = SUMCHECK; 00152 break; 00153 case SUMCHECK: 00154 for (int i = INDEX(in + 2); i != cur; i = INDEX(i + 1)) { 00155 c += buf[i]; 00156 } 00157 if (c == 255) { 00158 if (debug) leds = (leds & 12) | 3; //**LEDS=xx11 00159 in = cur; 00160 free = in <= out ? out - in : BUFSIZE + out - in; 00161 } 00162 state = UNKNOWN; 00163 break; 00164 default: 00165 if (c == PREAMBLE) state = LENGTH1; 00166 if (debug) leds = (leds & 12) | 1; //**LEDS=xx01 00167 } 00168 } 00169 } 00170 00171 void XBee::rxInterruptHandler2() { 00172 static bool escaped = false; 00173 00174 if (debug) leds = leds ^ 4; // x@xx 00175 00176 while (readable()) { 00177 char c = getc() & 255; 00178 00179 if (escaped) { 00180 c ^= 0x20; 00181 escaped = false; 00182 } else if (c == ESCAPE) { 00183 escaped = true; 00184 continue; 00185 } 00186 00187 switch (state) { 00188 case LENGTH1: 00189 cur = in; 00190 buf[cur] = c; 00191 state = LENGTH2; 00192 break; 00193 case LENGTH2: 00194 if ((buf[cur] << 8 | c) + 2 < BUFSIZE) { 00195 state = DATA; 00196 while (free < (buf[cur] << 8 | c) + 2) { 00197 int size = SIZE(buf, out); 00198 out = INDEX(out + size + 2); 00199 free += (size + 2); 00200 } 00201 buf[INDEX(cur + 1)] = c; 00202 cur = INDEX(cur + 2); 00203 if (debug) leds = (leds & 12) | 2; // xx10 00204 } else { 00205 state = UNKNOWN; 00206 leds = leds & 12; //** update leds 00207 } 00208 break; 00209 case DATA: 00210 buf[cur] = c; 00211 cur = INDEX(cur + 1); 00212 if (debug) leds = (leds & 12) | (cur & 3); //**LEDS=xx@@ 00213 if (cur == INDEX(in + 2 + SIZE(buf, in))) state = SUMCHECK; 00214 break; 00215 case SUMCHECK: 00216 for (int i = INDEX(in + 2); i != cur; i = INDEX(i + 1)) { 00217 c += buf[i]; 00218 } 00219 if (c == 255) { 00220 if (debug) leds = (leds & 12) | 3; //**LEDS=xx11 00221 in = cur; 00222 free = in <= out ? out - in : BUFSIZE + out - in; 00223 } 00224 state = UNKNOWN; 00225 break; 00226 default: 00227 if (c == PREAMBLE) state = LENGTH1; 00228 if (debug) leds = (leds & 12) | 1; //**LEDS=xx01 00229 } 00230 } 00231 }
Generated on Wed Jul 20 2022 22:15:57 by
