Wireless interface using LoRa technology

Dependencies:   AlohaTransceiver RingBuffer SX1276Lib SerialInterfaceProtocol mbed L3PDU

Committer:
rba90
Date:
Tue Aug 23 04:50:11 2016 +0000
Revision:
19:6a59fb0ee921
Parent:
18:f37e567f0497
Child:
20:55e222eeede1
add function that report rssi and snr when transmit

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