Wireless interface using LoRa technology

Dependencies:   AlohaTransceiver RingBuffer SX1276Lib SerialInterfaceProtocol mbed L3PDU

Committer:
rba90
Date:
Tue Sep 06 03:09:59 2016 +0000
Revision:
28:0c59edd704a0
Parent:
25:faa87315c44f
Child:
29:020355bfe3a6
report snr and rssi in application

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rba90 0:1e42d79b42e1 1 #include "mbed.h"
rba90 0:1e42d79b42e1 2 #include "AlohaTransceiver.h"
rba90 0:1e42d79b42e1 3 #include "SerialInterfaceProtocol.h"
rba90 0:1e42d79b42e1 4 #include "AlohaFrame.h"
rba90 14:25e836a5a7bf 5 #include "ControlPacket.h"
rba90 14:25e836a5a7bf 6 #include "DataBlockPacket.h"
rba90 0:1e42d79b42e1 7
rba90 0:1e42d79b42e1 8 Serial pc(USBTX, USBRX);
rba90 0:1e42d79b42e1 9
rba90 0:1e42d79b42e1 10 // sip uses two buffer queues
rba90 0:1e42d79b42e1 11 CircularBuffer<uint8_t> SerialInputBuffer;
rba90 0:1e42d79b42e1 12 CircularBuffer<uint8_t> SerialOutputBuffer;
rba90 0:1e42d79b42e1 13 SerialInterfaceProtocol SIP(&SerialInputBuffer, &SerialOutputBuffer);
rba90 0:1e42d79b42e1 14
rba90 0:1e42d79b42e1 15 // aloha transceiver
rba90 8:332099ece6e9 16 AlohaTransceiver aloha(DEVICE_ID);
rba90 0:1e42d79b42e1 17 AlohaFrame txFrame;
rba90 0:1e42d79b42e1 18
rba90 19:6a59fb0ee921 19 // convert fp32 to 4 byte string
rba90 19:6a59fb0ee921 20 typedef union
rba90 19:6a59fb0ee921 21 {
rba90 19:6a59fb0ee921 22 float fp32;
rba90 19:6a59fb0ee921 23 uint8_t bytes[4];
rba90 19:6a59fb0ee921 24 } float_bytes_32;
rba90 19:6a59fb0ee921 25
rba90 19:6a59fb0ee921 26 typedef union
rba90 19:6a59fb0ee921 27 {
rba90 19:6a59fb0ee921 28 int16_t int16;
rba90 19:6a59fb0ee921 29 uint8_t bytes[2];
rba90 19:6a59fb0ee921 30 } int_string_16;
rba90 19:6a59fb0ee921 31
rba90 19:6a59fb0ee921 32
rba90 0:1e42d79b42e1 33 void serialInterruptHandler() {
rba90 0:1e42d79b42e1 34 // Note: you need to actually read from the serial to clear the RX interrupt
rba90 0:1e42d79b42e1 35 int c = pc.getc();
rba90 0:1e42d79b42e1 36
rba90 0:1e42d79b42e1 37 // add to buffer
rba90 0:1e42d79b42e1 38 if (SerialInputBuffer.isLocked())
rba90 0:1e42d79b42e1 39 {
rba90 0:1e42d79b42e1 40 printf("Mutex Locked\r\n");
rba90 0:1e42d79b42e1 41 }
rba90 0:1e42d79b42e1 42 else
rba90 0:1e42d79b42e1 43 {
rba90 0:1e42d79b42e1 44 SerialInputBuffer.enqueue((uint8_t) c);
rba90 0:1e42d79b42e1 45 }
rba90 0:1e42d79b42e1 46 }
rba90 0:1e42d79b42e1 47
rba90 0:1e42d79b42e1 48 int toggleChecksum(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length)
rba90 0:1e42d79b42e1 49 {
rba90 0:1e42d79b42e1 50 // one payload
rba90 0:1e42d79b42e1 51 if (payload_length != 1)
rba90 0:1e42d79b42e1 52 {
rba90 0:1e42d79b42e1 53 sprintf((char *) response, "Wrong Payload Length\r\n");
rba90 0:1e42d79b42e1 54 *response_length = 22;
rba90 0:1e42d79b42e1 55 return 1;
rba90 0:1e42d79b42e1 56 }
rba90 0:1e42d79b42e1 57
rba90 0:1e42d79b42e1 58 if ((bool) payload[0])
rba90 0:1e42d79b42e1 59 {
rba90 0:1e42d79b42e1 60 SIP.enableChecksum();
rba90 0:1e42d79b42e1 61 }
rba90 0:1e42d79b42e1 62 else
rba90 0:1e42d79b42e1 63 {
rba90 0:1e42d79b42e1 64 SIP.disableChecksum();
rba90 0:1e42d79b42e1 65 }
rba90 0:1e42d79b42e1 66
rba90 0:1e42d79b42e1 67 return 0;
rba90 0:1e42d79b42e1 68 }
rba90 0:1e42d79b42e1 69
rba90 9:e13e02aa4a2f 70 /*
rba90 9:e13e02aa4a2f 71 * Format:
rba90 14:25e836a5a7bf 72 * < : start flag
rba90 14:25e836a5a7bf 73 * 02 : command
rba90 14:25e836a5a7bf 74 * xx : length
rba90 14:25e836a5a7bf 75 * xx: : 00: get, 01: set
rba90 14:25e836a5a7bf 76 * xx : index for parameters
rba90 9:e13e02aa4a2f 77 * ...
rba90 14:25e836a5a7bf 78 * ff :checksum (not currently in used)
rba90 9:e13e02aa4a2f 79 * > :end flag
rba90 9:e13e02aa4a2f 80 */
rba90 9:e13e02aa4a2f 81 int configureRadio(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length)
rba90 9:e13e02aa4a2f 82 {
rba90 9:e13e02aa4a2f 83 // read settings from radio
rba90 9:e13e02aa4a2f 84 #if USE_MODEM_LORA == 1
rba90 9:e13e02aa4a2f 85 AlohaTransceiver::LoRaSettings_t *settings = aloha.getSettings();
rba90 9:e13e02aa4a2f 86 #elif USE_MODEM_FSK == 1
rba90 9:e13e02aa4a2f 87 AlohaTransceiver::FskSettings_t *settings = aloha.getSettings();
rba90 9:e13e02aa4a2f 88 #else
rba90 9:e13e02aa4a2f 89 #error "Please define a modem in the compiler options."
rba90 9:e13e02aa4a2f 90 #endif
rba90 9:e13e02aa4a2f 91
rba90 9:e13e02aa4a2f 92 if (payload_length < 2)
rba90 9:e13e02aa4a2f 93 {
rba90 9:e13e02aa4a2f 94 sprintf((char *) response, "Wrong Payload Length\r\n");
rba90 9:e13e02aa4a2f 95 *response_length = 22;
rba90 9:e13e02aa4a2f 96 return 1;
rba90 9:e13e02aa4a2f 97 }
rba90 9:e13e02aa4a2f 98
rba90 9:e13e02aa4a2f 99 // true is set, false is get
rba90 9:e13e02aa4a2f 100 bool isSet = (bool) payload[0];
rba90 9:e13e02aa4a2f 101 uint8_t idx = payload[1];
rba90 9:e13e02aa4a2f 102
rba90 9:e13e02aa4a2f 103 switch(idx)
rba90 9:e13e02aa4a2f 104 {
rba90 9:e13e02aa4a2f 105 case 0x00: // Power
rba90 9:e13e02aa4a2f 106 {
rba90 9:e13e02aa4a2f 107 if (isSet)
rba90 9:e13e02aa4a2f 108 {
rba90 9:e13e02aa4a2f 109 int8_t Power = (int8_t) payload[2];
rba90 9:e13e02aa4a2f 110 settings->Power = Power;
rba90 9:e13e02aa4a2f 111
rba90 9:e13e02aa4a2f 112 return 0;
rba90 9:e13e02aa4a2f 113 }
rba90 9:e13e02aa4a2f 114 else
rba90 9:e13e02aa4a2f 115 {
rba90 9:e13e02aa4a2f 116 response[0] = (uint8_t) settings->Power;
rba90 9:e13e02aa4a2f 117 *response_length = 1;
rba90 9:e13e02aa4a2f 118
rba90 9:e13e02aa4a2f 119 return 0;
rba90 9:e13e02aa4a2f 120 }
rba90 9:e13e02aa4a2f 121 }
rba90 9:e13e02aa4a2f 122
rba90 9:e13e02aa4a2f 123 case 0x01: // Bandwidth
rba90 9:e13e02aa4a2f 124 {
rba90 9:e13e02aa4a2f 125 if (isSet)
rba90 9:e13e02aa4a2f 126 {
rba90 9:e13e02aa4a2f 127 uint32_t Bandwidth = (payload[5]) |
rba90 9:e13e02aa4a2f 128 (payload[4] << 8) |
rba90 9:e13e02aa4a2f 129 (payload[3] << 16) |
rba90 9:e13e02aa4a2f 130 (payload[2] << 24);
rba90 9:e13e02aa4a2f 131 settings->Bandwidth = Bandwidth;
rba90 9:e13e02aa4a2f 132
rba90 9:e13e02aa4a2f 133 return 0;
rba90 9:e13e02aa4a2f 134 }
rba90 9:e13e02aa4a2f 135 else
rba90 9:e13e02aa4a2f 136 {
rba90 9:e13e02aa4a2f 137 response[3] = (uint8_t) (settings->Bandwidth);
rba90 9:e13e02aa4a2f 138 response[2] = (uint8_t) (settings->Bandwidth >> 8);
rba90 9:e13e02aa4a2f 139 response[1] = (uint8_t) (settings->Bandwidth >> 16);
rba90 9:e13e02aa4a2f 140 response[0] = (uint8_t) (settings->Bandwidth >> 24);
rba90 9:e13e02aa4a2f 141 *response_length = 4;
rba90 9:e13e02aa4a2f 142
rba90 9:e13e02aa4a2f 143 return 0;
rba90 9:e13e02aa4a2f 144 }
rba90 9:e13e02aa4a2f 145
rba90 9:e13e02aa4a2f 146 }
rba90 9:e13e02aa4a2f 147
rba90 9:e13e02aa4a2f 148 case 0x02: // Datarate, AKA Spreading Factor
rba90 9:e13e02aa4a2f 149 {
rba90 9:e13e02aa4a2f 150 if (isSet)
rba90 9:e13e02aa4a2f 151 {
rba90 9:e13e02aa4a2f 152 uint32_t Datarate = (payload[5]) |
rba90 9:e13e02aa4a2f 153 (payload[4] << 8) |
rba90 9:e13e02aa4a2f 154 (payload[3] << 16) |
rba90 9:e13e02aa4a2f 155 (payload[2] << 24);
rba90 9:e13e02aa4a2f 156 settings->Datarate = Datarate;
rba90 9:e13e02aa4a2f 157
rba90 9:e13e02aa4a2f 158 return 0;
rba90 9:e13e02aa4a2f 159 }
rba90 9:e13e02aa4a2f 160 else
rba90 9:e13e02aa4a2f 161 {
rba90 9:e13e02aa4a2f 162 response[3] = (uint8_t) (settings->Datarate);
rba90 9:e13e02aa4a2f 163 response[2] = (uint8_t) (settings->Datarate >> 8);
rba90 9:e13e02aa4a2f 164 response[1] = (uint8_t) (settings->Datarate >> 16);
rba90 9:e13e02aa4a2f 165 response[0] = (uint8_t) (settings->Datarate >> 24);
rba90 9:e13e02aa4a2f 166 *response_length = 4;
rba90 9:e13e02aa4a2f 167
rba90 9:e13e02aa4a2f 168 return 0;
rba90 9:e13e02aa4a2f 169 }
rba90 9:e13e02aa4a2f 170 }
rba90 9:e13e02aa4a2f 171
rba90 9:e13e02aa4a2f 172 case 0x03: // Coderate
rba90 9:e13e02aa4a2f 173 {
rba90 9:e13e02aa4a2f 174 if (isSet)
rba90 9:e13e02aa4a2f 175 {
rba90 9:e13e02aa4a2f 176 uint8_t Coderate = payload[2];
rba90 9:e13e02aa4a2f 177 settings->Coderate = Coderate;
rba90 9:e13e02aa4a2f 178
rba90 9:e13e02aa4a2f 179 return 0;
rba90 9:e13e02aa4a2f 180 }
rba90 9:e13e02aa4a2f 181 else
rba90 9:e13e02aa4a2f 182 {
rba90 9:e13e02aa4a2f 183 response[0] = (uint8_t) settings->Coderate;
rba90 9:e13e02aa4a2f 184 *response_length = 1;
rba90 9:e13e02aa4a2f 185
rba90 9:e13e02aa4a2f 186 return 0;
rba90 9:e13e02aa4a2f 187 }
rba90 9:e13e02aa4a2f 188 }
rba90 9:e13e02aa4a2f 189
rba90 9:e13e02aa4a2f 190 case 0x04: //Preamble Length
rba90 9:e13e02aa4a2f 191 {
rba90 9:e13e02aa4a2f 192 if (isSet)
rba90 9:e13e02aa4a2f 193 {
rba90 9:e13e02aa4a2f 194 uint16_t PreambleLen = payload[3] | (payload[2] << 8);
rba90 9:e13e02aa4a2f 195 settings->PreambleLen = PreambleLen;
rba90 9:e13e02aa4a2f 196 return 0;
rba90 9:e13e02aa4a2f 197 }
rba90 9:e13e02aa4a2f 198 else
rba90 9:e13e02aa4a2f 199 {
rba90 9:e13e02aa4a2f 200 response[1] = (uint8_t) (settings->PreambleLen);
rba90 9:e13e02aa4a2f 201 response[0] = (uint8_t)(settings->PreambleLen >> 8);
rba90 9:e13e02aa4a2f 202 *response_length = 2;
rba90 9:e13e02aa4a2f 203
rba90 9:e13e02aa4a2f 204 return 0;
rba90 9:e13e02aa4a2f 205 }
rba90 9:e13e02aa4a2f 206 }
rba90 9:e13e02aa4a2f 207
rba90 9:e13e02aa4a2f 208 case 0x05: //Symbol Timeout
rba90 9:e13e02aa4a2f 209 {
rba90 9:e13e02aa4a2f 210 if (isSet)
rba90 9:e13e02aa4a2f 211 {
rba90 9:e13e02aa4a2f 212 uint16_t SymbolTimeout = payload[3] | (payload[2] << 8);
rba90 9:e13e02aa4a2f 213 settings->SymbolTimeout = SymbolTimeout;
rba90 9:e13e02aa4a2f 214 return 0;
rba90 9:e13e02aa4a2f 215 }
rba90 9:e13e02aa4a2f 216 else
rba90 9:e13e02aa4a2f 217 {
rba90 9:e13e02aa4a2f 218 response[1] = (uint8_t) (settings->SymbolTimeout);
rba90 9:e13e02aa4a2f 219 response[0] = (uint8_t) (settings->SymbolTimeout >> 8);
rba90 9:e13e02aa4a2f 220 *response_length = 2;
rba90 9:e13e02aa4a2f 221
rba90 9:e13e02aa4a2f 222 return 0;
rba90 9:e13e02aa4a2f 223 }
rba90 9:e13e02aa4a2f 224 }
rba90 9:e13e02aa4a2f 225
rba90 9:e13e02aa4a2f 226 case 0x06: //FixLen
rba90 9:e13e02aa4a2f 227 {
rba90 9:e13e02aa4a2f 228 if (isSet)
rba90 9:e13e02aa4a2f 229 {
rba90 9:e13e02aa4a2f 230 bool FixLen = payload[2];
rba90 9:e13e02aa4a2f 231 settings->FixLen = FixLen;
rba90 9:e13e02aa4a2f 232 return 0;
rba90 9:e13e02aa4a2f 233 }
rba90 9:e13e02aa4a2f 234 else
rba90 9:e13e02aa4a2f 235 {
rba90 9:e13e02aa4a2f 236 response[0] = (bool) (settings->SymbolTimeout);
rba90 9:e13e02aa4a2f 237 *response_length = 1;
rba90 9:e13e02aa4a2f 238
rba90 9:e13e02aa4a2f 239 return 0;
rba90 9:e13e02aa4a2f 240 }
rba90 9:e13e02aa4a2f 241 }
rba90 9:e13e02aa4a2f 242
rba90 9:e13e02aa4a2f 243 case 0x07: //PayloadLen
rba90 9:e13e02aa4a2f 244 {
rba90 9:e13e02aa4a2f 245 if (isSet)
rba90 9:e13e02aa4a2f 246 {
rba90 9:e13e02aa4a2f 247 uint8_t PayloadLen = payload[2];
rba90 9:e13e02aa4a2f 248 settings->PayloadLen = PayloadLen;
rba90 9:e13e02aa4a2f 249 return 0;
rba90 9:e13e02aa4a2f 250 }
rba90 9:e13e02aa4a2f 251 else
rba90 9:e13e02aa4a2f 252 {
rba90 9:e13e02aa4a2f 253 response[0] = (uint8_t) (settings->PayloadLen);
rba90 9:e13e02aa4a2f 254
rba90 9:e13e02aa4a2f 255 return 0;
rba90 9:e13e02aa4a2f 256 }
rba90 9:e13e02aa4a2f 257 }
rba90 9:e13e02aa4a2f 258
rba90 9:e13e02aa4a2f 259 case 0x08: //CrcOn
rba90 9:e13e02aa4a2f 260 {
rba90 9:e13e02aa4a2f 261 if (isSet) {
rba90 9:e13e02aa4a2f 262 bool CrcOn = payload[2];
rba90 9:e13e02aa4a2f 263 settings->CrcOn = CrcOn;
rba90 9:e13e02aa4a2f 264 return 0;
rba90 9:e13e02aa4a2f 265 }
rba90 9:e13e02aa4a2f 266 else
rba90 9:e13e02aa4a2f 267 {
rba90 9:e13e02aa4a2f 268 response[0] = (bool) (settings->CrcOn);
rba90 9:e13e02aa4a2f 269
rba90 9:e13e02aa4a2f 270 return 0;
rba90 9:e13e02aa4a2f 271 }
rba90 9:e13e02aa4a2f 272 }
rba90 9:e13e02aa4a2f 273
rba90 9:e13e02aa4a2f 274 case 0x09: //FreqHopOn
rba90 9:e13e02aa4a2f 275 {
rba90 9:e13e02aa4a2f 276 if (isSet) {
rba90 9:e13e02aa4a2f 277 bool FreqHopOn = payload[2];
rba90 9:e13e02aa4a2f 278 settings->FreqHopOn = FreqHopOn;
rba90 9:e13e02aa4a2f 279 return 0;
rba90 9:e13e02aa4a2f 280 }
rba90 9:e13e02aa4a2f 281 else
rba90 9:e13e02aa4a2f 282 {
rba90 9:e13e02aa4a2f 283 response[0] = (bool) (settings->FreqHopOn);
rba90 9:e13e02aa4a2f 284
rba90 9:e13e02aa4a2f 285 return 0;
rba90 9:e13e02aa4a2f 286 }
rba90 9:e13e02aa4a2f 287 }
rba90 9:e13e02aa4a2f 288
rba90 9:e13e02aa4a2f 289 case 0x0A: //HopPeriod
rba90 9:e13e02aa4a2f 290 {
rba90 9:e13e02aa4a2f 291 if (isSet) {
rba90 9:e13e02aa4a2f 292 uint8_t HopPeriod = payload[2];
rba90 9:e13e02aa4a2f 293 settings->HopPeriod = HopPeriod;
rba90 9:e13e02aa4a2f 294 return 0;
rba90 9:e13e02aa4a2f 295 }
rba90 9:e13e02aa4a2f 296 else
rba90 9:e13e02aa4a2f 297 {
rba90 9:e13e02aa4a2f 298 response[0] = (uint8_t) (settings->HopPeriod);
rba90 9:e13e02aa4a2f 299 return 0;
rba90 9:e13e02aa4a2f 300 }
rba90 9:e13e02aa4a2f 301 }
rba90 9:e13e02aa4a2f 302
rba90 9:e13e02aa4a2f 303 case 0x0B: //IqInverted
rba90 9:e13e02aa4a2f 304 {
rba90 9:e13e02aa4a2f 305 if (isSet) {
rba90 9:e13e02aa4a2f 306 bool IqInverted = payload[2];
rba90 9:e13e02aa4a2f 307 settings->IqInverted = IqInverted;
rba90 9:e13e02aa4a2f 308 return 0;
rba90 9:e13e02aa4a2f 309 }
rba90 9:e13e02aa4a2f 310 else
rba90 9:e13e02aa4a2f 311 {
rba90 9:e13e02aa4a2f 312 response[0] = (bool) (settings->IqInverted);
rba90 9:e13e02aa4a2f 313 return 0;
rba90 9:e13e02aa4a2f 314 }
rba90 9:e13e02aa4a2f 315 }
rba90 9:e13e02aa4a2f 316
rba90 9:e13e02aa4a2f 317 case 0x0C: //RxContinuous
rba90 9:e13e02aa4a2f 318 {
rba90 9:e13e02aa4a2f 319 if(isSet)
rba90 9:e13e02aa4a2f 320 {
rba90 9:e13e02aa4a2f 321 bool RxContinuous = payload[2];
rba90 9:e13e02aa4a2f 322 settings->RxContinuous = RxContinuous;
rba90 9:e13e02aa4a2f 323 return 0;
rba90 9:e13e02aa4a2f 324 }
rba90 9:e13e02aa4a2f 325 else
rba90 9:e13e02aa4a2f 326 {
rba90 9:e13e02aa4a2f 327 response[0] = (bool) (settings->RxContinuous);
rba90 9:e13e02aa4a2f 328 return 0;
rba90 9:e13e02aa4a2f 329 }
rba90 9:e13e02aa4a2f 330 }
rba90 9:e13e02aa4a2f 331
rba90 9:e13e02aa4a2f 332 case 0x0D: //TxTimeout
rba90 9:e13e02aa4a2f 333 {
rba90 9:e13e02aa4a2f 334 if (isSet)
rba90 9:e13e02aa4a2f 335 {
rba90 9:e13e02aa4a2f 336 uint32_t TxTimeout = (payload[5]) |
rba90 9:e13e02aa4a2f 337 (payload[4] << 8) |
rba90 9:e13e02aa4a2f 338 (payload[3] << 16) |
rba90 9:e13e02aa4a2f 339 (payload[2] << 24);
rba90 9:e13e02aa4a2f 340 settings->TxTimeout = TxTimeout;
rba90 9:e13e02aa4a2f 341 return 0;
rba90 9:e13e02aa4a2f 342 }
rba90 9:e13e02aa4a2f 343 else
rba90 9:e13e02aa4a2f 344 {
rba90 9:e13e02aa4a2f 345 response[3] = (uint8_t) (settings->TxTimeout);
rba90 9:e13e02aa4a2f 346 response[2] = (uint8_t) (settings->TxTimeout >> 8);
rba90 9:e13e02aa4a2f 347 response[1] = (uint8_t) (settings->TxTimeout >> 16);
rba90 9:e13e02aa4a2f 348 response[0] = (uint8_t) (settings->TxTimeout >> 24);
rba90 9:e13e02aa4a2f 349 *response_length = 4;
rba90 9:e13e02aa4a2f 350
rba90 9:e13e02aa4a2f 351 return 0;
rba90 9:e13e02aa4a2f 352 }
rba90 9:e13e02aa4a2f 353 }
rba90 9:e13e02aa4a2f 354
rba90 9:e13e02aa4a2f 355
rba90 9:e13e02aa4a2f 356 default:
rba90 9:e13e02aa4a2f 357 {
rba90 9:e13e02aa4a2f 358 break;
rba90 9:e13e02aa4a2f 359 }
rba90 9:e13e02aa4a2f 360
rba90 9:e13e02aa4a2f 361 //case
rba90 9:e13e02aa4a2f 362 }
rba90 9:e13e02aa4a2f 363
rba90 9:e13e02aa4a2f 364
rba90 9:e13e02aa4a2f 365 return 0;
rba90 9:e13e02aa4a2f 366 }
rba90 9:e13e02aa4a2f 367
rba90 9:e13e02aa4a2f 368 int radioUpdateSettings(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length)
rba90 9:e13e02aa4a2f 369 {
rba90 9:e13e02aa4a2f 370 aloha.updateSettings();
rba90 9:e13e02aa4a2f 371
rba90 9:e13e02aa4a2f 372 return 0;
rba90 9:e13e02aa4a2f 373 }
rba90 9:e13e02aa4a2f 374
rba90 14:25e836a5a7bf 375 /*
rba90 14:25e836a5a7bf 376 * Format:
rba90 14:25e836a5a7bf 377 * < : start flag
rba90 14:25e836a5a7bf 378 * 04 : command
rba90 14:25e836a5a7bf 379 * 02 : length (2 bytes in this case)
rba90 14:25e836a5a7bf 380 * 00/01 : query for temperature or door sensor
rba90 14:25e836a5a7bf 381 * xx : node to query
rba90 14:25e836a5a7bf 382 * ff : checksum (not currently in used)
rba90 14:25e836a5a7bf 383 * > : end flag
rba90 14:25e836a5a7bf 384 */
rba90 14:25e836a5a7bf 385 int querySensors(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length)
rba90 6:19457108c899 386 {
rba90 14:25e836a5a7bf 387 // check with payloads
rba90 14:25e836a5a7bf 388 if (payload_length != 2)
rba90 14:25e836a5a7bf 389 {
rba90 14:25e836a5a7bf 390 sprintf((char *) response, "Wrong Payload Length");
rba90 14:25e836a5a7bf 391 *response_length = 20;
rba90 14:25e836a5a7bf 392 return 1;
rba90 14:25e836a5a7bf 393 }
rba90 14:25e836a5a7bf 394
rba90 14:25e836a5a7bf 395 // decode the user message
rba90 23:378bd4d025d0 396 uint8_t source_type = payload[0];
rba90 14:25e836a5a7bf 397 uint8_t node_id = payload[1];
rba90 6:19457108c899 398
rba90 14:25e836a5a7bf 399 // create a command packet
rba90 14:25e836a5a7bf 400 ControlPacket packet;
rba90 14:25e836a5a7bf 401
rba90 14:25e836a5a7bf 402 // sequence id is not in used in this case
rba90 14:25e836a5a7bf 403 packet.setSequenceID(0x0);
rba90 14:25e836a5a7bf 404
rba90 14:25e836a5a7bf 405 // set source id as current device id
rba90 14:25e836a5a7bf 406 packet.setSourceID(aloha.getDeviceID());
rba90 14:25e836a5a7bf 407
rba90 14:25e836a5a7bf 408 // set destination id as node id
rba90 14:25e836a5a7bf 409 packet.setDestinationID(node_id);
rba90 6:19457108c899 410
rba90 19:6a59fb0ee921 411 // set command as query (0 in this case)
rba90 19:6a59fb0ee921 412 packet.setCommand(0x0);
rba90 6:19457108c899 413
rba90 14:25e836a5a7bf 414 // store sensor type in data block 0
rba90 23:378bd4d025d0 415 packet.setData(0, source_type);
rba90 14:25e836a5a7bf 416
rba90 14:25e836a5a7bf 417 // generate crc
rba90 14:25e836a5a7bf 418 packet.generateCrc();
rba90 14:25e836a5a7bf 419
rba90 25:faa87315c44f 420 aloha.send(&packet);
rba90 11:9590f3c9d915 421
rba90 11:9590f3c9d915 422 return 0;
rba90 11:9590f3c9d915 423 }
rba90 11:9590f3c9d915 424
rba90 19:6a59fb0ee921 425 int queryServiceQuality(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length)
rba90 19:6a59fb0ee921 426 {
rba90 19:6a59fb0ee921 427 // decode user message
rba90 19:6a59fb0ee921 428 uint8_t node_id = payload[0];
rba90 23:378bd4d025d0 429 uint8_t source_type = 0x2; // query for service quality
rba90 19:6a59fb0ee921 430
rba90 19:6a59fb0ee921 431 // create a command packet
rba90 19:6a59fb0ee921 432 ControlPacket packet;
rba90 19:6a59fb0ee921 433
rba90 19:6a59fb0ee921 434 // layer 3 sequence id is not used in this case
rba90 19:6a59fb0ee921 435 packet.setSequenceID(0x0);
rba90 19:6a59fb0ee921 436
rba90 19:6a59fb0ee921 437 // set source id as current device id
rba90 19:6a59fb0ee921 438 packet.setSourceID(aloha.getDeviceID());
rba90 19:6a59fb0ee921 439
rba90 19:6a59fb0ee921 440 // set destination id as node id
rba90 19:6a59fb0ee921 441 packet.setDestinationID(node_id);
rba90 19:6a59fb0ee921 442
rba90 23:378bd4d025d0 443 // set command as query (treat it similar to sensor)
rba90 23:378bd4d025d0 444 packet.setCommand(0x0);
rba90 23:378bd4d025d0 445
rba90 23:378bd4d025d0 446 // store sensor type in data block 0
rba90 23:378bd4d025d0 447 packet.setData(0, source_type);
rba90 19:6a59fb0ee921 448
rba90 19:6a59fb0ee921 449 // generate crc
rba90 19:6a59fb0ee921 450 packet.generateCrc();
rba90 19:6a59fb0ee921 451
rba90 25:faa87315c44f 452 aloha.send(&packet);
rba90 19:6a59fb0ee921 453
rba90 19:6a59fb0ee921 454 return 0;
rba90 19:6a59fb0ee921 455 }
rba90 19:6a59fb0ee921 456
rba90 14:25e836a5a7bf 457 void AlohaDataPacketHandler(uint8_t *payload, uint8_t payload_length, uint8_t src_addr)
rba90 14:25e836a5a7bf 458 {
rba90 14:25e836a5a7bf 459 // try to decode packet
rba90 14:25e836a5a7bf 460 BasicPacket packet(payload);
rba90 2:ae85337d4ca7 461
rba90 14:25e836a5a7bf 462 // verify crc
rba90 15:182b95c25cf2 463 // skip this for now
rba90 14:25e836a5a7bf 464
rba90 14:25e836a5a7bf 465 // process the packet based on different feature id
rba90 14:25e836a5a7bf 466 BasicPacket::L3Fid_t fid = (BasicPacket::L3Fid_t) packet.getFid();
rba90 2:ae85337d4ca7 467
rba90 14:25e836a5a7bf 468 // we don't care about the type conversion. just create a new one.
rba90 14:25e836a5a7bf 469 switch (fid)
rba90 3:a4f6abad9378 470 {
rba90 14:25e836a5a7bf 471 case BasicPacket::L3ControlPacket:
rba90 14:25e836a5a7bf 472 {
rba90 14:25e836a5a7bf 473 ControlPacket controlPacket(payload);
rba90 14:25e836a5a7bf 474
rba90 19:6a59fb0ee921 475 // execute command
rba90 19:6a59fb0ee921 476 uint8_t command = controlPacket.getCommand();
rba90 19:6a59fb0ee921 477 switch(command)
rba90 19:6a59fb0ee921 478 {
rba90 23:378bd4d025d0 479 case 0x0: // query
rba90 19:6a59fb0ee921 480 {
rba90 23:378bd4d025d0 481 // execute query
rba90 23:378bd4d025d0 482 uint8_t sensor_type = controlPacket.getData(0);
rba90 23:378bd4d025d0 483 switch (sensor_type)
rba90 23:378bd4d025d0 484 {
rba90 23:378bd4d025d0 485 case 0x0: // temperature: NULL
rba90 23:378bd4d025d0 486 {
rba90 23:378bd4d025d0 487 break;
rba90 23:378bd4d025d0 488 }
rba90 23:378bd4d025d0 489 case 0x1: // door: NULL
rba90 23:378bd4d025d0 490 {
rba90 23:378bd4d025d0 491 break;
rba90 23:378bd4d025d0 492 }
rba90 23:378bd4d025d0 493 case 0x2: // service quality
rba90 23:378bd4d025d0 494 {
rba90 23:378bd4d025d0 495 int_string_16 rssi;
rba90 23:378bd4d025d0 496 uint8_t snr;
rba90 23:378bd4d025d0 497
rba90 23:378bd4d025d0 498 // get rssi and snr
rba90 23:378bd4d025d0 499 rssi.int16 = aloha.getRssi();
rba90 23:378bd4d025d0 500 snr = aloha.getSnr();
rba90 23:378bd4d025d0 501
rba90 23:378bd4d025d0 502 // create a response
rba90 23:378bd4d025d0 503 DataBlockPacket response;
rba90 23:378bd4d025d0 504
rba90 23:378bd4d025d0 505 // set sequence id (the sequence id is configured as incoming sequence id + 1)
rba90 23:378bd4d025d0 506 response.setSequenceID(controlPacket.getSequenceID() + 1);
rba90 23:378bd4d025d0 507
rba90 23:378bd4d025d0 508 // set source id (the source id is the current device ID)
rba90 23:378bd4d025d0 509 response.setSourceID(aloha.getDeviceID());
rba90 23:378bd4d025d0 510
rba90 23:378bd4d025d0 511 // set destination id (the destination ID is the original source address)
rba90 23:378bd4d025d0 512 response.setDestinationID(controlPacket.getSourceID());
rba90 23:378bd4d025d0 513
rba90 23:378bd4d025d0 514 // set source type (service quality)
rba90 23:378bd4d025d0 515 response.setSourceType(0x2);
rba90 23:378bd4d025d0 516
rba90 23:378bd4d025d0 517 // set payload type (byte)
rba90 23:378bd4d025d0 518 response.setPayloadType(0x0);
rba90 23:378bd4d025d0 519
rba90 23:378bd4d025d0 520 // set payload
rba90 23:378bd4d025d0 521 response.setData(0, (uint8_t) snr); // store SNR
rba90 23:378bd4d025d0 522 response.setData(1, (uint8_t) rssi.bytes[0]); // store higher bits of RSSI
rba90 23:378bd4d025d0 523 response.setData(2, (uint8_t) rssi.bytes[1]); // store lower bits of RSSI
rba90 23:378bd4d025d0 524
rba90 23:378bd4d025d0 525 // calculate crc
rba90 23:378bd4d025d0 526 response.generateCrc();
rba90 23:378bd4d025d0 527
rba90 25:faa87315c44f 528 aloha.send(&response);
rba90 23:378bd4d025d0 529
rba90 23:378bd4d025d0 530 break;
rba90 23:378bd4d025d0 531 }
rba90 23:378bd4d025d0 532
rba90 23:378bd4d025d0 533 default:
rba90 23:378bd4d025d0 534 break;
rba90 23:378bd4d025d0 535 }
rba90 19:6a59fb0ee921 536
rba90 19:6a59fb0ee921 537 break;
rba90 19:6a59fb0ee921 538 }
rba90 23:378bd4d025d0 539
rba90 19:6a59fb0ee921 540 default:
rba90 19:6a59fb0ee921 541 break;
rba90 19:6a59fb0ee921 542 }
rba90 14:25e836a5a7bf 543
rba90 14:25e836a5a7bf 544 break;
rba90 14:25e836a5a7bf 545 }
rba90 19:6a59fb0ee921 546
rba90 14:25e836a5a7bf 547 case BasicPacket::L3DataBlockPacket:
rba90 14:25e836a5a7bf 548 {
rba90 14:25e836a5a7bf 549 DataBlockPacket dataBlockPacket(payload);
rba90 14:25e836a5a7bf 550
rba90 23:378bd4d025d0 551 uint8_t source_type = dataBlockPacket.getSourceType();
rba90 23:378bd4d025d0 552 switch(source_type)
rba90 15:182b95c25cf2 553 {
rba90 15:182b95c25cf2 554 case 0x0: // temperature sensor
rba90 15:182b95c25cf2 555 {
rba90 28:0c59edd704a0 556 uint8_t payload[9];
rba90 16:ab2d9341997a 557
rba90 16:ab2d9341997a 558 // copy sensor type
rba90 23:378bd4d025d0 559 payload[0] = 0x0; // assume 0x00 is temperature sensor
rba90 16:ab2d9341997a 560
rba90 16:ab2d9341997a 561 // copy sensor data
rba90 23:378bd4d025d0 562 payload[1] = dataBlockPacket.getSourceID(); // assume we only use one byte
rba90 16:ab2d9341997a 563
rba90 16:ab2d9341997a 564 // copy address of source node
rba90 16:ab2d9341997a 565 payload[2] = dataBlockPacket.getData(0);
rba90 28:0c59edd704a0 566 for (uint8_t i = 0; i < 4; i++)
rba90 28:0c59edd704a0 567 {
rba90 28:0c59edd704a0 568 payload[i + 2] = dataBlockPacket.getData(i + 1);
rba90 28:0c59edd704a0 569 }
rba90 28:0c59edd704a0 570
rba90 28:0c59edd704a0 571 // copy snr
rba90 28:0c59edd704a0 572 payload[6] = (uint8_t) aloha.getSnr();
rba90 28:0c59edd704a0 573
rba90 28:0c59edd704a0 574 // copy rssi
rba90 28:0c59edd704a0 575 int_string_16 rssi;
rba90 28:0c59edd704a0 576 rssi.int16 = aloha.getRssi();
rba90 28:0c59edd704a0 577
rba90 28:0c59edd704a0 578 payload[7] = rssi.bytes[0];
rba90 28:0c59edd704a0 579 payload[8] = rssi.bytes[1];
rba90 16:ab2d9341997a 580
rba90 16:ab2d9341997a 581 // make response
rba90 28:0c59edd704a0 582 SIP.respond(0xf0, payload, 9);
rba90 16:ab2d9341997a 583
rba90 15:182b95c25cf2 584 break;
rba90 15:182b95c25cf2 585 }
rba90 16:ab2d9341997a 586 case 0x1: // door sensor
rba90 15:182b95c25cf2 587 {
rba90 28:0c59edd704a0 588 uint8_t payload[6];
rba90 16:ab2d9341997a 589
rba90 16:ab2d9341997a 590 // copy sensor type
rba90 23:378bd4d025d0 591 payload[0] = 0x1;
rba90 16:ab2d9341997a 592
rba90 16:ab2d9341997a 593 // copy sensor data
rba90 23:378bd4d025d0 594 payload[1] = dataBlockPacket.getSourceID();
rba90 16:ab2d9341997a 595
rba90 16:ab2d9341997a 596 // copy address of source node
rba90 16:ab2d9341997a 597 payload[2] = dataBlockPacket.getData(0);
rba90 16:ab2d9341997a 598
rba90 28:0c59edd704a0 599 // copy snr
rba90 28:0c59edd704a0 600 payload[3] = (uint8_t) aloha.getSnr();
rba90 28:0c59edd704a0 601
rba90 28:0c59edd704a0 602 // copy rssi
rba90 28:0c59edd704a0 603 int_string_16 rssi;
rba90 28:0c59edd704a0 604 rssi.int16 = aloha.getRssi();
rba90 28:0c59edd704a0 605
rba90 28:0c59edd704a0 606 payload[4] = rssi.bytes[0];
rba90 28:0c59edd704a0 607 payload[5] = rssi.bytes[1];
rba90 28:0c59edd704a0 608
rba90 16:ab2d9341997a 609 // make response
rba90 28:0c59edd704a0 610 SIP.respond(0xf0, payload, 6);
rba90 16:ab2d9341997a 611
rba90 15:182b95c25cf2 612 break;
rba90 15:182b95c25cf2 613 }
rba90 23:378bd4d025d0 614 case 0x2: // service quality
rba90 23:378bd4d025d0 615 {
rba90 23:378bd4d025d0 616 uint8_t payload[8];
rba90 23:378bd4d025d0 617
rba90 23:378bd4d025d0 618 // copy source type
rba90 23:378bd4d025d0 619 payload[0] = 0x2;
rba90 23:378bd4d025d0 620
rba90 23:378bd4d025d0 621 // copy sensor data
rba90 23:378bd4d025d0 622 payload[1] = dataBlockPacket.getSourceID();
rba90 23:378bd4d025d0 623
rba90 23:378bd4d025d0 624 // first byte is the snr of foreign host
rba90 23:378bd4d025d0 625 payload[2] = dataBlockPacket.getData(0);
rba90 23:378bd4d025d0 626
rba90 23:378bd4d025d0 627 // second and third byte are the rssi of foreign host
rba90 23:378bd4d025d0 628 payload[3] = dataBlockPacket.getData(1);
rba90 23:378bd4d025d0 629 payload[4] = dataBlockPacket.getData(2);
rba90 23:378bd4d025d0 630
rba90 23:378bd4d025d0 631 // fourth byte is the snr of local host
rba90 23:378bd4d025d0 632 payload[5] = (uint8_t) aloha.getSnr();
rba90 23:378bd4d025d0 633
rba90 23:378bd4d025d0 634 // fifth and sixth byte are the rssi of local host
rba90 23:378bd4d025d0 635 int_string_16 rssi;
rba90 23:378bd4d025d0 636 rssi.int16 = aloha.getRssi();
rba90 23:378bd4d025d0 637
rba90 23:378bd4d025d0 638 payload[6] = rssi.bytes[0];
rba90 23:378bd4d025d0 639 payload[7] = rssi.bytes[1];
rba90 23:378bd4d025d0 640
rba90 23:378bd4d025d0 641 // make response
rba90 23:378bd4d025d0 642 SIP.respond(0xf0, payload, 8);
rba90 23:378bd4d025d0 643
rba90 23:378bd4d025d0 644 break;
rba90 23:378bd4d025d0 645 }
rba90 23:378bd4d025d0 646
rba90 15:182b95c25cf2 647 default:
rba90 15:182b95c25cf2 648 break;
rba90 15:182b95c25cf2 649 }
rba90 15:182b95c25cf2 650
rba90 14:25e836a5a7bf 651 break;
rba90 14:25e836a5a7bf 652 }
rba90 14:25e836a5a7bf 653 default:
rba90 14:25e836a5a7bf 654 break;
rba90 3:a4f6abad9378 655 }
rba90 0:1e42d79b42e1 656 }
rba90 0:1e42d79b42e1 657
rba90 14:25e836a5a7bf 658
rba90 0:1e42d79b42e1 659 int main() {
rba90 0:1e42d79b42e1 660 // initialize radio module
rba90 5:445f35444a6a 661 aloha.boardInit();
rba90 6:19457108c899 662 aloha.updateSettings();
rba90 6:19457108c899 663 aloha.enable();
rba90 0:1e42d79b42e1 664
rba90 0:1e42d79b42e1 665 // attach serial interrupt handler
rba90 0:1e42d79b42e1 666 pc.attach(&serialInterruptHandler);
rba90 0:1e42d79b42e1 667
rba90 0:1e42d79b42e1 668 // register callback functions for SIP
rba90 0:1e42d79b42e1 669 SIP.registerCommand(0x00, toggleChecksum);
rba90 19:6a59fb0ee921 670 SIP.registerCommand(0x01, queryServiceQuality);
rba90 9:e13e02aa4a2f 671 SIP.registerCommand(0x02, configureRadio);
rba90 9:e13e02aa4a2f 672 SIP.registerCommand(0x03, radioUpdateSettings);
rba90 14:25e836a5a7bf 673 SIP.registerCommand(0x04, querySensors);
rba90 0:1e42d79b42e1 674
rba90 0:1e42d79b42e1 675 // register callback functions for aloha transceiver
rba90 14:25e836a5a7bf 676 aloha.registerType(AlohaFrame::Aloha_Data, AlohaDataPacketHandler);
rba90 0:1e42d79b42e1 677
rba90 0:1e42d79b42e1 678 while(1) {
rba90 0:1e42d79b42e1 679 SIP.poll();
rba90 0:1e42d79b42e1 680 aloha.poll();
rba90 0:1e42d79b42e1 681
rba90 0:1e42d79b42e1 682 while (SerialOutputBuffer.getCounter() > 0)
rba90 0:1e42d79b42e1 683 {
rba90 0:1e42d79b42e1 684 uint8_t ch;
rba90 0:1e42d79b42e1 685 ch = SerialOutputBuffer.dequeue();
rba90 0:1e42d79b42e1 686 pc.putc(ch);
rba90 0:1e42d79b42e1 687 }
rba90 0:1e42d79b42e1 688 }
rba90 0:1e42d79b42e1 689 }