Wireless interface using LoRa technology

Dependencies:   AlohaTransceiver RingBuffer SX1276Lib_inAir SerialInterfaceProtocol mbed L3PDU

Committer:
rba90
Date:
Wed Aug 31 03:39:04 2016 +0000
Revision:
20:ff70a415660a
Parent:
18:ce8dc94163d8
Child:
22:fea9289f31b3
treat query for service quality as normal query

Who changed what in which revision?

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