Wireless interface using LoRa technology

Dependencies:   AlohaTransceiver RingBuffer SX1276Lib_inAir SerialInterfaceProtocol mbed L3PDU

Committer:
rba90
Date:
Fri Sep 02 04:44:18 2016 +0000
Revision:
25:2fff6d1b4eb6
Parent:
24:e41b5098ed0a
Child:
27:9196cb5859f7
update according to submodule

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