Senet network coverage survey tool

Dependencies:   GeoPosition Senet_Packet lib_gps lib_mma8451q lib_mpl3115a2 lib_sx9500 lmic_MOTE_L152RC mbed-src

Senet Network Coverage Program

Test Senet Network coverage with various data rates and transmit powers

/media/uploads/shaunkrnelson/norammote.jpg

Configure Device ID and App Key

For your device to connect to the Senet Network, set Device ID and App Key in Commissioning.h

Commissioning.h

/* CHANGE: Device ID  registered to your Developer Portal account */
 u1_t reverse_DEVEUI[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 

/* CHANGE: Device App Key. To get this select the device, click on Gear button at top left then select Device Edit */  
u1_t DEVKEY[16]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
                                                                        
/*NOCHANGE: Senet Developer Portal Application ID */ 
 u1_t reverse_APPEUI[8]={0x00,0x25,0x0C,0x00,0x00,0x01,0x00,0x01};
 

Connecting to the Senet Network

When the device is turned on the USR LED will blink while it is joining the Senet Network. When LED state changes to solid green it has joined the network. Failure to join network will be the result of:

  1. No network coverage in that area
  2. App Key configuration is incorrect

Siting Mode

The device is in Siting test mode when positioned vertically with LEDs facing up. The Siting test consists of transmitting Senet GPS packets with acknowledgment requested at transmit power levels 14, 20, 30 in that order. For each power level the device will attempt 3 transmits at DR0, stopping if ack is received and moving on to next tx power. After first run through all powers at DR0 the test will stop if acknowledgements received at all power levels; otherwise, the test will proceed to alternate between 3 transmits at DR4 and 3 at DR0 for remaining unacknowledged tx powers until ack received.

Siting LED Profile

  1. USR
    1. Blink fast while joining
    2. Solid when joined and GPS lock
    3. Blink slow when not GPS lock
  1. RED
    1. 30 dBm status indicator
    2. Blink on transmit
    3. Solid after downlink received
  1. YELLOW
    1. 20 dBm status indicator
    2. Blink on transmit
    3. Solid after ack received
  1. GREEN
    1. 14 dBm status indicator
    2. Blink on transmit
    3. Solid after downlink received

Range Mode

The device is in this mode when not in the siting orientation.
This test consists of transmitting 8 packets at:

  1. DR3 Tx Power 14
  2. DR0 Tx Power 14
  3. DR4 Tx Power 20
  4. DR3 Tx Power 20
  5. DR0 Tx Power 20
  6. DR4 Tx Power 26
  7. DR3 Tx Power 30
  8. DR0 Tx Power 30

After transmit cycle completes the next test will start in 560 seconds unless following:

  1. After 140 seconds if no ack received
  2. After 80 seconds if 30 meters travelled from last transmit location

Range LED Profile

  • USR
    • Blink fast while joining
    • Solid when joined and GPS lock
    • Blink slow when not GPS locked
  • RED
    • Transmit indicator
    • Blink on transmit
  • YELLOW
    • Ack indicator
    • Set at beginning of transmit cycle and cleared when ack received
  • GREEN
    • V3 Mote
      • Test indicator
      • Solid while test transmit cycle in progress
    • V2 Mote
      • Not controllable by firmware

Switching Mode

Set mote orientation to desired mode. After a few seconds the new orientation will be detected and the device will indicate it is switching mode by blinking the red, yellow and green LEDs simultaneously for a couple seconds before switching to the new mode.

Committer:
dkjendal
Date:
Tue Aug 23 16:06:18 2016 +0000
Revision:
13:89ddcc4dfc66
Parent:
10:72c5e2cfa473
Child:
14:b2c6a9dc039c
SenorPacket receive to light some leds

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shaunkrnelson 0:46990814dc89 1 #include "mbed.h"
shaunkrnelson 0:46990814dc89 2 #include "lmic.h"
shaunkrnelson 0:46990814dc89 3 #include "debug.h"
shaunkrnelson 0:46990814dc89 4 #include "gps.h"
shaunkrnelson 0:46990814dc89 5 #include "mpl3115a2.h"
shaunkrnelson 0:46990814dc89 6 #include "mma8451q.h"
shaunkrnelson 0:46990814dc89 7 #include "sx9500.h"
shaunkrnelson 0:46990814dc89 8 #include "GeoPosition.h"
shaunkrnelson 0:46990814dc89 9 #include "senet_packet.h"
shaunkrnelson 0:46990814dc89 10
shaunkrnelson 1:fbf2fb2c2718 11 // Automatically generated by the program_device script
shaunkrnelson 1:fbf2fb2c2718 12 #include "Commissioning.h"
shaunkrnelson 3:35e8af53c6cf 13 #define NORAM_MOTE_DEVICE_TYPE 0x001001
shaunkrnelson 1:fbf2fb2c2718 14 #define MAJOR 1
shaunkrnelson 1:fbf2fb2c2718 15 #define MINOR 1
shaunkrnelson 3:35e8af53c6cf 16 #define POINT 2
shaunkrnelson 1:fbf2fb2c2718 17 #define BUILD_NUMBER 0
shaunkrnelson 1:fbf2fb2c2718 18 #define DEVELOPER_ID 0
shaunkrnelson 0:46990814dc89 19
dkjendal 4:059d004186ed 20 #define DR_TX_FLOATING
shaunkrnelson 0:46990814dc89 21
shaunkrnelson 0:46990814dc89 22 // provide application router ID (8 bytes, LSBF)
shaunkrnelson 0:46990814dc89 23 void os_getArtEui (u1_t* buf) {
shaunkrnelson 0:46990814dc89 24 //memcpy(buf, APPEUI, 8);
shaunkrnelson 0:46990814dc89 25 LMIC_reverse_memcpy(buf, reverse_APPEUI, 8);
shaunkrnelson 0:46990814dc89 26 }
shaunkrnelson 0:46990814dc89 27
shaunkrnelson 0:46990814dc89 28 // provide device ID (8 bytes, LSBF)
shaunkrnelson 0:46990814dc89 29 void os_getDevEui (u1_t* buf) {
shaunkrnelson 0:46990814dc89 30 //memcpy(buf, DEVEUI, 8);
shaunkrnelson 0:46990814dc89 31 LMIC_reverse_memcpy(buf, reverse_DEVEUI, 8);
shaunkrnelson 0:46990814dc89 32 }
shaunkrnelson 0:46990814dc89 33
shaunkrnelson 0:46990814dc89 34 // provide device key (16 bytes)
shaunkrnelson 0:46990814dc89 35 void os_getDevKey (u1_t* buf) {
shaunkrnelson 0:46990814dc89 36 memcpy(buf, DEVKEY, 16);
shaunkrnelson 0:46990814dc89 37 }
shaunkrnelson 0:46990814dc89 38
shaunkrnelson 0:46990814dc89 39 typedef enum {
shaunkrnelson 0:46990814dc89 40 MOTE_NONE = 0,
shaunkrnelson 0:46990814dc89 41 MOTE_V2,
shaunkrnelson 0:46990814dc89 42 MOTE_V3
shaunkrnelson 0:46990814dc89 43 } mote_version_e;
shaunkrnelson 0:46990814dc89 44
shaunkrnelson 0:46990814dc89 45 /***********************************************************************
shaunkrnelson 0:46990814dc89 46 * END LORA Device configuration
shaunkrnelson 0:46990814dc89 47 ***********************************************************************/
shaunkrnelson 0:46990814dc89 48
shaunkrnelson 0:46990814dc89 49 // Following is peripheral configuration
shaunkrnelson 0:46990814dc89 50 GPS gps(PB_6, PB_7, PB_11);
shaunkrnelson 0:46990814dc89 51 GeoPosition lastTxPos;
shaunkrnelson 0:46990814dc89 52
shaunkrnelson 0:46990814dc89 53 // I2C Bus connecting sensors
shaunkrnelson 0:46990814dc89 54 I2C i2c(I2C_SDA, I2C_SCL);
shaunkrnelson 0:46990814dc89 55 DigitalIn i2c_int_pin(PB_4);
shaunkrnelson 0:46990814dc89 56
shaunkrnelson 0:46990814dc89 57 // Accelerometer
shaunkrnelson 0:46990814dc89 58 MMA8451Q mma8451q(i2c, i2c_int_pin);
shaunkrnelson 0:46990814dc89 59 // Altimeter
shaunkrnelson 0:46990814dc89 60 MPL3115A2 mpl3115a2(i2c, i2c_int_pin);
shaunkrnelson 0:46990814dc89 61 // Proximity sensor
shaunkrnelson 0:46990814dc89 62 SX9500 sx9500(i2c, PA_9, PA_10);
shaunkrnelson 0:46990814dc89 63
shaunkrnelson 0:46990814dc89 64 // Applicative transmit datarate
shaunkrnelson 0:46990814dc89 65 u1_t dr = 0;
shaunkrnelson 0:46990814dc89 66 // Applicative transmit power
shaunkrnelson 0:46990814dc89 67 u1_t pw = 0;
dkjendal 4:059d004186ed 68 // x-y-z orientation
dkjendal 4:059d004186ed 69 uint16_t orientation_mask = 0x0000;
dkjendal 13:89ddcc4dfc66 70 uint16_t temperature = 0;
dkjendal 13:89ddcc4dfc66 71 uint16_t pressure = 0;
dkjendal 4:059d004186ed 72 // is the device moving or not
dkjendal 4:059d004186ed 73 bool stationary = true;
shaunkrnelson 0:46990814dc89 74
shaunkrnelson 0:46990814dc89 75 // LEDs
shaunkrnelson 0:46990814dc89 76 #define LED_RED PB_1
shaunkrnelson 0:46990814dc89 77 #define LED_YEL PB_10
shaunkrnelson 0:46990814dc89 78 #define LED_GREEN PC_3
shaunkrnelson 0:46990814dc89 79 #define LED_USR PA_5
shaunkrnelson 0:46990814dc89 80
shaunkrnelson 0:46990814dc89 81 DigitalOut ledRed(LED_RED);
shaunkrnelson 0:46990814dc89 82 DigitalOut ledYellow(LED_YEL);
shaunkrnelson 0:46990814dc89 83 DigitalOut ledGreen(LED_GREEN);
shaunkrnelson 0:46990814dc89 84 DigitalOut ledUsr(LED_USR);
shaunkrnelson 0:46990814dc89 85
shaunkrnelson 0:46990814dc89 86 DigitalOut pc_7(PC_7);
shaunkrnelson 0:46990814dc89 87 DigitalIn pc_1(PC_1);
shaunkrnelson 0:46990814dc89 88 AnalogIn *bat;
shaunkrnelson 0:46990814dc89 89
shaunkrnelson 0:46990814dc89 90 uint8_t ReadBatteryLevel()
shaunkrnelson 0:46990814dc89 91 {
shaunkrnelson 0:46990814dc89 92 uint8_t level = 0;
shaunkrnelson 0:46990814dc89 93
shaunkrnelson 0:46990814dc89 94 if(bat != NULL)
shaunkrnelson 1:fbf2fb2c2718 95 level = ((bat->read_u16() >> 8) + (bat->read_u16() >> 9))>>5;
shaunkrnelson 0:46990814dc89 96
shaunkrnelson 0:46990814dc89 97 debug("Battery level: %d\r\n", level);
shaunkrnelson 0:46990814dc89 98 return level;
shaunkrnelson 0:46990814dc89 99 }
shaunkrnelson 0:46990814dc89 100
shaunkrnelson 0:46990814dc89 101 // Get Mote version
shaunkrnelson 0:46990814dc89 102 mote_version_e get_mote_version()
shaunkrnelson 0:46990814dc89 103 {
shaunkrnelson 0:46990814dc89 104 static mote_version_e mote_version = MOTE_NONE;
shaunkrnelson 0:46990814dc89 105
shaunkrnelson 0:46990814dc89 106 if (mote_version == MOTE_NONE)
shaunkrnelson 0:46990814dc89 107 {
shaunkrnelson 0:46990814dc89 108 pc_7 = 1;
shaunkrnelson 0:46990814dc89 109 char first = pc_1;
shaunkrnelson 0:46990814dc89 110 pc_7 = 0;
shaunkrnelson 0:46990814dc89 111
shaunkrnelson 0:46990814dc89 112 if (first && !pc_1) {
shaunkrnelson 0:46990814dc89 113 printf("v2\r\n");
shaunkrnelson 0:46990814dc89 114 mote_version = MOTE_V2;
shaunkrnelson 0:46990814dc89 115 bat = new AnalogIn(PA_0);
shaunkrnelson 0:46990814dc89 116 } else {
shaunkrnelson 0:46990814dc89 117 printf("v3\r\n");
shaunkrnelson 0:46990814dc89 118 mote_version = MOTE_V3;
shaunkrnelson 0:46990814dc89 119 bat = new AnalogIn(PA_1);
shaunkrnelson 0:46990814dc89 120 }
shaunkrnelson 0:46990814dc89 121 }
shaunkrnelson 0:46990814dc89 122 return mote_version;
shaunkrnelson 0:46990814dc89 123 }
shaunkrnelson 0:46990814dc89 124
shaunkrnelson 0:46990814dc89 125 void board_peripherals_init()
shaunkrnelson 0:46990814dc89 126 {
shaunkrnelson 0:46990814dc89 127 ledRed = 1;
shaunkrnelson 0:46990814dc89 128 ledYellow = 1;
shaunkrnelson 0:46990814dc89 129 ledGreen = 1;
shaunkrnelson 0:46990814dc89 130 ledUsr = 0;
shaunkrnelson 0:46990814dc89 131
shaunkrnelson 0:46990814dc89 132 // Start GPS
shaunkrnelson 0:46990814dc89 133 gps.init();
shaunkrnelson 0:46990814dc89 134 if(get_mote_version() == MOTE_V3)
shaunkrnelson 0:46990814dc89 135 gps.en_invert = false;
shaunkrnelson 0:46990814dc89 136 else
shaunkrnelson 0:46990814dc89 137 gps.en_invert = true;
shaunkrnelson 0:46990814dc89 138
shaunkrnelson 0:46990814dc89 139 gps.enable(false);
shaunkrnelson 0:46990814dc89 140
shaunkrnelson 0:46990814dc89 141 GPIOA->MODER |= 0x01415500; // unused pins as outputs: PA4, PA5, PA6, PA7, PA8, (PA11,PA12 USB)
shaunkrnelson 0:46990814dc89 142 //printf("GPIOA->MODER:%08x\r\n", GPIOA->MODER);
shaunkrnelson 0:46990814dc89 143
shaunkrnelson 0:46990814dc89 144 GPIOB->MODER |= 0x00000401; // unused pins as outputs: PB0(HDR_DIO1), PB5 (PB10 pulled hi by LED), PB3-T_SWO
shaunkrnelson 0:46990814dc89 145 //printf("GPIOB->MODER:%08x\r\n", GPIOB->MODER);
shaunkrnelson 0:46990814dc89 146
shaunkrnelson 0:46990814dc89 147 GPIOC->MODER |= 0x00000045; // unused pins as outputs: PC0(hdr_fem_csd) PC1(hdr_fem_ctx) PC3(SPI3_enable)
shaunkrnelson 0:46990814dc89 148 //printf("GPIOC->MODER:%08x\r\n", GPIOC->MODER);
shaunkrnelson 0:46990814dc89 149
shaunkrnelson 0:46990814dc89 150 sx9500.RegProxCtrl0.bits.sensor_en = 3; // only CS0 and CS1 connected
shaunkrnelson 0:46990814dc89 151 sx9500.write(SX9500_REG_PROXCTRL0, sx9500.RegProxCtrl0.octet);
shaunkrnelson 0:46990814dc89 152
shaunkrnelson 0:46990814dc89 153 // set PROXTHRESH to 80 because CS1 has 48 showing always on PROXDIFF
shaunkrnelson 0:46990814dc89 154 sx9500.write(SX9500_REG_PROXCTRL6, 0x04);
shaunkrnelson 0:46990814dc89 155
shaunkrnelson 0:46990814dc89 156 // Enable accelerometer orientation detection
shaunkrnelson 0:46990814dc89 157 #define DEBUG
shaunkrnelson 0:46990814dc89 158 #ifdef DEBUG
shaunkrnelson 0:46990814dc89 159 mma8451q.verbose = true;
shaunkrnelson 0:46990814dc89 160 #endif
shaunkrnelson 0:46990814dc89 161 mma8451q.orient_detect();
shaunkrnelson 0:46990814dc89 162 mma8451q.set_active(true);
shaunkrnelson 0:46990814dc89 163
shaunkrnelson 0:46990814dc89 164 mpl3115a2.init();
shaunkrnelson 0:46990814dc89 165 mpl3115a2.SetModeStandby();
shaunkrnelson 0:46990814dc89 166
shaunkrnelson 0:46990814dc89 167 gps.enable(true);
shaunkrnelson 0:46990814dc89 168 }
shaunkrnelson 0:46990814dc89 169
shaunkrnelson 0:46990814dc89 170 // application commmon
shaunkrnelson 0:46990814dc89 171 bool gps_service()
shaunkrnelson 0:46990814dc89 172 {
shaunkrnelson 0:46990814dc89 173 gps.have_fix = false;
shaunkrnelson 0:46990814dc89 174 if (gps.enabled()) {
shaunkrnelson 0:46990814dc89 175 for(int32_t i = 0; i < 10; i++)
shaunkrnelson 0:46990814dc89 176 {
shaunkrnelson 0:46990814dc89 177 gps.service();
shaunkrnelson 0:46990814dc89 178 if (gps.have_fix == true) {
shaunkrnelson 0:46990814dc89 179 return true;
shaunkrnelson 0:46990814dc89 180 }
shaunkrnelson 0:46990814dc89 181 else
shaunkrnelson 1:fbf2fb2c2718 182 wait(.1);
shaunkrnelson 0:46990814dc89 183 }
shaunkrnelson 0:46990814dc89 184 }
shaunkrnelson 0:46990814dc89 185 return false;
shaunkrnelson 0:46990814dc89 186 }
shaunkrnelson 0:46990814dc89 187
shaunkrnelson 0:46990814dc89 188
shaunkrnelson 0:46990814dc89 189
shaunkrnelson 0:46990814dc89 190 static void restore_hsi()
shaunkrnelson 0:46990814dc89 191 {
shaunkrnelson 0:46990814dc89 192 RCC_OscInitTypeDef osc_init;
shaunkrnelson 0:46990814dc89 193 /* if HSI was shut off in deep sleep (needed for AnalogIn) */
shaunkrnelson 0:46990814dc89 194 HAL_RCC_GetOscConfig(&osc_init);
shaunkrnelson 0:46990814dc89 195 if (osc_init.HSIState != RCC_HSI_ON) {
shaunkrnelson 0:46990814dc89 196 // Enable the HSI (to clock the ADC)
shaunkrnelson 0:46990814dc89 197 osc_init.OscillatorType = RCC_OSCILLATORTYPE_HSI;
shaunkrnelson 0:46990814dc89 198 osc_init.HSIState = RCC_HSI_ON;
shaunkrnelson 0:46990814dc89 199 osc_init.PLL.PLLState = RCC_PLL_NONE;
shaunkrnelson 0:46990814dc89 200 HAL_RCC_OscConfig(&osc_init);
shaunkrnelson 0:46990814dc89 201 }
shaunkrnelson 0:46990814dc89 202 }
shaunkrnelson 0:46990814dc89 203
shaunkrnelson 0:46990814dc89 204
shaunkrnelson 0:46990814dc89 205 u1_t PrepareDataFrame( SenetPacketT type )
shaunkrnelson 0:46990814dc89 206 {
shaunkrnelson 0:46990814dc89 207 u1_t pktLen = 0;
shaunkrnelson 0:46990814dc89 208
shaunkrnelson 0:46990814dc89 209 restore_hsi();
shaunkrnelson 0:46990814dc89 210
shaunkrnelson 0:46990814dc89 211 switch (type)
shaunkrnelson 0:46990814dc89 212 {
shaunkrnelson 0:46990814dc89 213 case SELF_ID_PACKET:
shaunkrnelson 0:46990814dc89 214 {
shaunkrnelson 0:46990814dc89 215 // Self Id packet type serialized to the LMIC frame buffer
shaunkrnelson 0:46990814dc89 216 SelfIdPacket packet(LMIC.frame, MAX_LEN_FRAME);
shaunkrnelson 1:fbf2fb2c2718 217
shaunkrnelson 0:46990814dc89 218 // Device Type
shaunkrnelson 0:46990814dc89 219 packet.setDeviceType(NORAM_MOTE_DEVICE_TYPE, get_mote_version());
shaunkrnelson 0:46990814dc89 220
shaunkrnelson 0:46990814dc89 221 // Software version
shaunkrnelson 0:46990814dc89 222 packet.setSwVersion(MAJOR, MINOR, POINT, BUILD_NUMBER, DEVELOPER_ID);
shaunkrnelson 0:46990814dc89 223
shaunkrnelson 0:46990814dc89 224 // Battery level
shaunkrnelson 0:46990814dc89 225 packet.setBatteryLevel(ReadBatteryLevel());
shaunkrnelson 0:46990814dc89 226
shaunkrnelson 0:46990814dc89 227 // Serialize packet to LMIC transmit buffer
shaunkrnelson 0:46990814dc89 228 pktLen = packet.serialize();
shaunkrnelson 0:46990814dc89 229
shaunkrnelson 0:46990814dc89 230 break;
shaunkrnelson 0:46990814dc89 231 }
dkjendal 4:059d004186ed 232 case SENSOR_PACKET:
dkjendal 4:059d004186ed 233 {
dkjendal 4:059d004186ed 234 // Read Sensors
dkjendal 4:059d004186ed 235 mpl3115a2.SetModeActive();
dkjendal 13:89ddcc4dfc66 236 pressure = mpl3115a2.ReadBarometer();
dkjendal 13:89ddcc4dfc66 237 temperature = mpl3115a2.ReadTemperature();
dkjendal 4:059d004186ed 238 mpl3115a2.SetModeStandby();
dkjendal 4:059d004186ed 239
dkjendal 4:059d004186ed 240 // Sensor packet type serialized to the LMIC frame buffer
dkjendal 4:059d004186ed 241 SensorPacket packet(LMIC.frame, MAX_LEN_FRAME);
dkjendal 4:059d004186ed 242 packet.setPrimarySensor(orientation_mask);
dkjendal 4:059d004186ed 243 packet.setTemperature(temperature);
dkjendal 4:059d004186ed 244 packet.setPressure(pressure);
dkjendal 4:059d004186ed 245
dkjendal 4:059d004186ed 246 // Serialize packet to LMIC transmit buffer
dkjendal 4:059d004186ed 247 pktLen = packet.serialize();
dkjendal 4:059d004186ed 248
dkjendal 4:059d004186ed 249 break;
dkjendal 4:059d004186ed 250 }
shaunkrnelson 0:46990814dc89 251 case GPS_PACKET:
shaunkrnelson 0:46990814dc89 252 default:
shaunkrnelson 0:46990814dc89 253 {
shaunkrnelson 0:46990814dc89 254 // Gps packet type serialized to the LMIC frame buffer
shaunkrnelson 0:46990814dc89 255 GpsPacket packet(LMIC.frame, MAX_LEN_FRAME);
shaunkrnelson 1:fbf2fb2c2718 256
shaunkrnelson 0:46990814dc89 257 // set packet transmit power
shaunkrnelson 0:46990814dc89 258 packet.setTxPower(pw);
shaunkrnelson 0:46990814dc89 259
shaunkrnelson 1:fbf2fb2c2718 260 // Set packet coordinates
shaunkrnelson 1:fbf2fb2c2718 261 uint16_t altitudeGps = atoi(gps.NmeaGpsData.NmeaAltitude);
shaunkrnelson 1:fbf2fb2c2718 262 packet.setCoordinates(gps.LatitudeBinary, gps.LongitudeBinary, altitudeGps);
shaunkrnelson 1:fbf2fb2c2718 263 lastTxPos.set(gps.Latitude,gps.Longitude);
shaunkrnelson 1:fbf2fb2c2718 264
shaunkrnelson 0:46990814dc89 265 // Serialize packet
shaunkrnelson 0:46990814dc89 266 pktLen = packet.serialize();
shaunkrnelson 0:46990814dc89 267 break;
shaunkrnelson 0:46990814dc89 268 }
shaunkrnelson 0:46990814dc89 269 }
shaunkrnelson 0:46990814dc89 270
shaunkrnelson 0:46990814dc89 271 return pktLen;
shaunkrnelson 0:46990814dc89 272 }
shaunkrnelson 0:46990814dc89 273
shaunkrnelson 0:46990814dc89 274 void displayBuildInfo()
shaunkrnelson 0:46990814dc89 275 {
shaunkrnelson 0:46990814dc89 276 debug("Range & Site Tester\r\n");
shaunkrnelson 0:46990814dc89 277 debug("Version %02d.%02d.%02d.%04d.%02d\r\n",MAJOR,MINOR,POINT,BUILD_NUMBER,DEVELOPER_ID);
shaunkrnelson 0:46990814dc89 278 debug("\r\nDevEUI: %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\r\n",
shaunkrnelson 0:46990814dc89 279 reverse_DEVEUI[0],
shaunkrnelson 0:46990814dc89 280 reverse_DEVEUI[1],
shaunkrnelson 0:46990814dc89 281 reverse_DEVEUI[2],
shaunkrnelson 0:46990814dc89 282 reverse_DEVEUI[3],
shaunkrnelson 0:46990814dc89 283 reverse_DEVEUI[4],
shaunkrnelson 0:46990814dc89 284 reverse_DEVEUI[5],
shaunkrnelson 0:46990814dc89 285 reverse_DEVEUI[6],
shaunkrnelson 0:46990814dc89 286 reverse_DEVEUI[7]);
shaunkrnelson 0:46990814dc89 287 debug("AppEUI: %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\r\n",
shaunkrnelson 0:46990814dc89 288 reverse_APPEUI[0],
shaunkrnelson 0:46990814dc89 289 reverse_APPEUI[1],
shaunkrnelson 0:46990814dc89 290 reverse_APPEUI[2],
shaunkrnelson 0:46990814dc89 291 reverse_APPEUI[3],
shaunkrnelson 0:46990814dc89 292 reverse_APPEUI[4],
shaunkrnelson 0:46990814dc89 293 reverse_APPEUI[5],
shaunkrnelson 0:46990814dc89 294 reverse_APPEUI[6],
shaunkrnelson 0:46990814dc89 295 reverse_APPEUI[7]);
shaunkrnelson 0:46990814dc89 296 }
shaunkrnelson 0:46990814dc89 297
shaunkrnelson 0:46990814dc89 298
shaunkrnelson 0:46990814dc89 299 void startLMIC()
shaunkrnelson 0:46990814dc89 300 {
shaunkrnelson 0:46990814dc89 301 // reset MAC state
shaunkrnelson 0:46990814dc89 302 LMIC_reset();
dkjendal 4:059d004186ed 303 #ifdef DR_TX_FLOATING
dkjendal 4:059d004186ed 304 LMIC_setAdrMode(true);
dkjendal 4:059d004186ed 305 #endif
shaunkrnelson 0:46990814dc89 306 // start joining
shaunkrnelson 0:46990814dc89 307 LMIC_startJoining();
shaunkrnelson 0:46990814dc89 308 }
shaunkrnelson 0:46990814dc89 309
shaunkrnelson 0:46990814dc89 310
shaunkrnelson 0:46990814dc89 311
shaunkrnelson 0:46990814dc89 312 // Operational mode
shaunkrnelson 0:46990814dc89 313 enum OperMode
shaunkrnelson 0:46990814dc89 314 {
shaunkrnelson 0:46990814dc89 315 // Range testing
shaunkrnelson 0:46990814dc89 316 RANGE_TEST,
shaunkrnelson 0:46990814dc89 317 // Site testing
shaunkrnelson 0:46990814dc89 318 SITE_TEST,
shaunkrnelson 0:46990814dc89 319 // Sending self-id packet
shaunkrnelson 0:46990814dc89 320 SELF_ID,
shaunkrnelson 0:46990814dc89 321 // No mode set
shaunkrnelson 0:46990814dc89 322 IDLE
shaunkrnelson 0:46990814dc89 323 };
shaunkrnelson 0:46990814dc89 324
shaunkrnelson 0:46990814dc89 325 // OS job management objects
shaunkrnelson 0:46990814dc89 326 static osjob_t statusLedJob;
shaunkrnelson 0:46990814dc89 327 static osjob_t txLedJob;
shaunkrnelson 0:46990814dc89 328 static osjob_t orientationJob;
shaunkrnelson 0:46990814dc89 329 static osjob_t sendFrameJob;
shaunkrnelson 0:46990814dc89 330
shaunkrnelson 0:46990814dc89 331 // Mote orientation is checked periodically. The mote test mode
shaunkrnelson 0:46990814dc89 332 // is selected by orientation. When mote is vertical it is in
shaunkrnelson 0:46990814dc89 333 // site test mode and range test mode when horizontal.
shaunkrnelson 0:46990814dc89 334 // Note that changing mote mode will abort previous mode testing
shaunkrnelson 0:46990814dc89 335 #define ORIENTATION_CHECK_PERIOD 5
shaunkrnelson 0:46990814dc89 336
shaunkrnelson 0:46990814dc89 337 // Debounce orientation change
shaunkrnelson 0:46990814dc89 338 #define ORIENTATION_DEBOUNCE_TIME 5
shaunkrnelson 0:46990814dc89 339
shaunkrnelson 0:46990814dc89 340 #define STATUS_FAST_BLINK 1
shaunkrnelson 0:46990814dc89 341 #define STATUS_SLOW_BLINK 4
shaunkrnelson 0:46990814dc89 342 #define STATUS_OK_PERIOD 5
shaunkrnelson 0:46990814dc89 343
shaunkrnelson 0:46990814dc89 344 static u4_t txCount = 0;
shaunkrnelson 0:46990814dc89 345 static ostime_t lastTestDoneT = 0;
shaunkrnelson 0:46990814dc89 346 static bool ackRequested = false;
shaunkrnelson 0:46990814dc89 347 static OperMode operMode = IDLE;
shaunkrnelson 0:46990814dc89 348 static OperMode txMode = IDLE;
shaunkrnelson 0:46990814dc89 349
shaunkrnelson 0:46990814dc89 350 //////////////////////////////////////////////////
shaunkrnelson 0:46990814dc89 351 // Range test configuration
shaunkrnelson 0:46990814dc89 352 //////////////////////////////////////////////////
shaunkrnelson 0:46990814dc89 353 #define RANGE_TXCYCLE_TRANSMITS 8
shaunkrnelson 0:46990814dc89 354 #define RANGE_NEXT_TEST_LONG 560
shaunkrnelson 0:46990814dc89 355 #define RANGE_NEXT_TEST_NOACK 140
shaunkrnelson 0:46990814dc89 356 #define RANGE_NEXT_TEST_DISTANCE 80
shaunkrnelson 0:46990814dc89 357 #define RANGE_NEXT_TEST_MIN_TIME 80
shaunkrnelson 0:46990814dc89 358 #define RANGE_NEXT_TX 5
shaunkrnelson 0:46990814dc89 359 #define RANGE_START_TEST_DISTANCE 30 // meters
shaunkrnelson 0:46990814dc89 360 #define RANGE_NEXT_TEST_DISTANCE_T 15
shaunkrnelson 0:46990814dc89 361
shaunkrnelson 0:46990814dc89 362
shaunkrnelson 0:46990814dc89 363 //////////////////////////////////////////////////
shaunkrnelson 0:46990814dc89 364 // Site test configuration
shaunkrnelson 0:46990814dc89 365 //////////////////////////////////////////////////
shaunkrnelson 0:46990814dc89 366 #define SITE_TX_PW1 14
shaunkrnelson 0:46990814dc89 367 #define SITE_TX_PW2 20
shaunkrnelson 0:46990814dc89 368 #define SITE_TX_PW3 30
shaunkrnelson 0:46990814dc89 369 #define SITE_GREEN_LED_PW SITE_TX_PW1
shaunkrnelson 0:46990814dc89 370 #define SITE_YELLOW_LED_PW SITE_TX_PW2
shaunkrnelson 0:46990814dc89 371 #define SITE_RED_LED_PW SITE_TX_PW3
shaunkrnelson 0:46990814dc89 372
shaunkrnelson 0:46990814dc89 373 static u1_t siteDrs[2] = {0,4};
shaunkrnelson 0:46990814dc89 374 static u1_t sitePws[3] = {SITE_TX_PW1, SITE_TX_PW2, SITE_TX_PW3};
shaunkrnelson 0:46990814dc89 375 static u1_t siteAck[3] = {0,0,0};
shaunkrnelson 0:46990814dc89 376 static u1_t siteDr = 0;
shaunkrnelson 0:46990814dc89 377 static u1_t sitePw = 0;
shaunkrnelson 0:46990814dc89 378 static u1_t siteDrPwAttempts = 0;
shaunkrnelson 0:46990814dc89 379 #define SITE_DR_MAX sizeof(siteDrs)
shaunkrnelson 0:46990814dc89 380 #define SITE_PW_MAX sizeof(sitePws)
shaunkrnelson 0:46990814dc89 381 #define SITE_PW_DR_ATTEMPTS 3
shaunkrnelson 0:46990814dc89 382
shaunkrnelson 0:46990814dc89 383
shaunkrnelson 0:46990814dc89 384 static void txLedCb(osjob_t *job)
shaunkrnelson 0:46990814dc89 385 {
shaunkrnelson 0:46990814dc89 386 if(operMode == RANGE_TEST)
shaunkrnelson 0:46990814dc89 387 {
shaunkrnelson 0:46990814dc89 388 ledRed = 1;
shaunkrnelson 0:46990814dc89 389 }
shaunkrnelson 0:46990814dc89 390 else if(operMode == SITE_TEST)
shaunkrnelson 0:46990814dc89 391 {
shaunkrnelson 0:46990814dc89 392 switch(pw)
shaunkrnelson 0:46990814dc89 393 {
shaunkrnelson 0:46990814dc89 394 case SITE_GREEN_LED_PW:
shaunkrnelson 0:46990814dc89 395 ledGreen = 1;
shaunkrnelson 0:46990814dc89 396 break;
shaunkrnelson 0:46990814dc89 397 case SITE_YELLOW_LED_PW:
shaunkrnelson 0:46990814dc89 398 ledYellow = 1;
shaunkrnelson 0:46990814dc89 399 break;
shaunkrnelson 0:46990814dc89 400 case SITE_RED_LED_PW:
shaunkrnelson 0:46990814dc89 401 ledRed = 1;
shaunkrnelson 0:46990814dc89 402 break;
shaunkrnelson 0:46990814dc89 403 }
shaunkrnelson 0:46990814dc89 404 }
shaunkrnelson 0:46990814dc89 405 }
shaunkrnelson 0:46990814dc89 406
shaunkrnelson 0:46990814dc89 407
shaunkrnelson 0:46990814dc89 408 static void onSendFrame(osjob_t* j)
shaunkrnelson 0:46990814dc89 409 {
shaunkrnelson 1:fbf2fb2c2718 410 u1_t pktSize = 0;
shaunkrnelson 0:46990814dc89 411
shaunkrnelson 0:46990814dc89 412 // Return if still transmitting. Next transmit will be scheduled by onEvent() when tx finishes
shaunkrnelson 0:46990814dc89 413 if (LMIC.opmode & OP_TXRXPEND)
shaunkrnelson 0:46990814dc89 414 return;
shaunkrnelson 0:46990814dc89 415
shaunkrnelson 0:46990814dc89 416 if(operMode == RANGE_TEST)
shaunkrnelson 0:46990814dc89 417 {
shaunkrnelson 0:46990814dc89 418 // Select dr and tx power
shaunkrnelson 0:46990814dc89 419 switch(txCount&0x07)
shaunkrnelson 0:46990814dc89 420 {
shaunkrnelson 0:46990814dc89 421 case 0:
shaunkrnelson 0:46990814dc89 422 dr = 3;
shaunkrnelson 0:46990814dc89 423 pw = 14;
shaunkrnelson 0:46990814dc89 424 ackRequested = true; // set this on the first tx of the group
shaunkrnelson 0:46990814dc89 425 ledYellow = 0;
shaunkrnelson 0:46990814dc89 426 ledGreen = 0;
shaunkrnelson 0:46990814dc89 427 break;
shaunkrnelson 0:46990814dc89 428 case 1:
shaunkrnelson 0:46990814dc89 429 dr = 0;
shaunkrnelson 0:46990814dc89 430 pw = 14;
shaunkrnelson 0:46990814dc89 431 break;
shaunkrnelson 0:46990814dc89 432 case 2:
shaunkrnelson 0:46990814dc89 433 dr = 4;
shaunkrnelson 0:46990814dc89 434 pw = 20;
shaunkrnelson 0:46990814dc89 435 break;
shaunkrnelson 0:46990814dc89 436 case 3:
shaunkrnelson 0:46990814dc89 437 dr = 3;
shaunkrnelson 0:46990814dc89 438 pw = 20;
shaunkrnelson 0:46990814dc89 439 break;
shaunkrnelson 0:46990814dc89 440 case 4:
shaunkrnelson 0:46990814dc89 441 dr = 0;
shaunkrnelson 0:46990814dc89 442 pw = 20;
shaunkrnelson 0:46990814dc89 443 break;
shaunkrnelson 0:46990814dc89 444 case 5:
shaunkrnelson 0:46990814dc89 445 dr = 4;
shaunkrnelson 0:46990814dc89 446 pw = 26;
shaunkrnelson 0:46990814dc89 447 break;
shaunkrnelson 0:46990814dc89 448 case 6:
shaunkrnelson 0:46990814dc89 449 dr = 3;
shaunkrnelson 0:46990814dc89 450 pw = 30;
shaunkrnelson 0:46990814dc89 451 break;
shaunkrnelson 0:46990814dc89 452 case 7:
shaunkrnelson 0:46990814dc89 453 dr = 0;
shaunkrnelson 0:46990814dc89 454 pw = 30;
shaunkrnelson 0:46990814dc89 455 break;
shaunkrnelson 0:46990814dc89 456 }
shaunkrnelson 0:46990814dc89 457 // Blink transmit LED
shaunkrnelson 0:46990814dc89 458 ledRed = 0;
shaunkrnelson 0:46990814dc89 459 os_setTimedCallback( &txLedJob, os_getTime() + 1, txLedCb);
shaunkrnelson 0:46990814dc89 460 }
shaunkrnelson 0:46990814dc89 461 else if (operMode == SITE_TEST)
shaunkrnelson 0:46990814dc89 462 {
shaunkrnelson 0:46990814dc89 463 ackRequested = true;
shaunkrnelson 0:46990814dc89 464
shaunkrnelson 0:46990814dc89 465 if((siteDr < SITE_DR_MAX) && (sitePw < SITE_PW_MAX))
shaunkrnelson 0:46990814dc89 466 {
shaunkrnelson 0:46990814dc89 467 dr = siteDrs[siteDr];
shaunkrnelson 0:46990814dc89 468 pw = sitePws[sitePw];
shaunkrnelson 0:46990814dc89 469 }
shaunkrnelson 0:46990814dc89 470 // Restarting test
shaunkrnelson 0:46990814dc89 471 else
shaunkrnelson 0:46990814dc89 472 {
shaunkrnelson 0:46990814dc89 473 debug("Bad dr=%d or pw=%d index\r\n", siteDr, sitePw);
shaunkrnelson 0:46990814dc89 474 siteDr = 0;
shaunkrnelson 0:46990814dc89 475 sitePw = 0;
shaunkrnelson 0:46990814dc89 476 }
shaunkrnelson 0:46990814dc89 477 // Blink tx LED
shaunkrnelson 0:46990814dc89 478 switch(pw)
shaunkrnelson 0:46990814dc89 479 {
shaunkrnelson 0:46990814dc89 480 case SITE_GREEN_LED_PW:
shaunkrnelson 0:46990814dc89 481 ledGreen = 0;
shaunkrnelson 0:46990814dc89 482 break;
shaunkrnelson 0:46990814dc89 483 case SITE_YELLOW_LED_PW:
shaunkrnelson 0:46990814dc89 484 ledYellow = 0;
shaunkrnelson 0:46990814dc89 485 break;
shaunkrnelson 0:46990814dc89 486 case SITE_RED_LED_PW:
shaunkrnelson 0:46990814dc89 487 ledRed = 0;
shaunkrnelson 0:46990814dc89 488 break;
shaunkrnelson 0:46990814dc89 489 }
shaunkrnelson 0:46990814dc89 490 os_setTimedCallback( &txLedJob, os_getTime() + 1, txLedCb);
shaunkrnelson 0:46990814dc89 491 }
dkjendal 4:059d004186ed 492 #ifndef DR_TX_FLOATING
dkjendal 4:059d004186ed 493 // Set next dr and tx power
dkjendal 4:059d004186ed 494 LMIC_setDrTxpow(dr,pw);
dkjendal 4:059d004186ed 495 #else
dkjendal 4:059d004186ed 496 pw = LMIC.txpow;
dkjendal 4:059d004186ed 497 #endif
shaunkrnelson 1:fbf2fb2c2718 498 // Send GPS data
shaunkrnelson 1:fbf2fb2c2718 499 for(int32_t i=0; i<3; i++)
shaunkrnelson 1:fbf2fb2c2718 500 {
shaunkrnelson 1:fbf2fb2c2718 501 if(gps_service() == true)
shaunkrnelson 1:fbf2fb2c2718 502 {
dkjendal 4:059d004186ed 503 if(!stationary || (0 != txCount&0x7))
dkjendal 4:059d004186ed 504 pktSize = PrepareDataFrame(GPS_PACKET);
dkjendal 4:059d004186ed 505
shaunkrnelson 1:fbf2fb2c2718 506 break;
shaunkrnelson 1:fbf2fb2c2718 507 }
shaunkrnelson 1:fbf2fb2c2718 508 }
shaunkrnelson 1:fbf2fb2c2718 509
dkjendal 4:059d004186ed 510 // if unable to get GPS or stationary, send sensor packet
shaunkrnelson 1:fbf2fb2c2718 511 if(0 == pktSize)
dkjendal 4:059d004186ed 512 pktSize = PrepareDataFrame(SENSOR_PACKET);
shaunkrnelson 0:46990814dc89 513
shaunkrnelson 0:46990814dc89 514
shaunkrnelson 0:46990814dc89 515 txCount++;
shaunkrnelson 0:46990814dc89 516 txMode = operMode;
shaunkrnelson 0:46990814dc89 517
shaunkrnelson 0:46990814dc89 518 debug("onSendFrame mode=%d: dr=%d, pw=%d, ack=%d\r\n",operMode, dr, pw, ackRequested);
shaunkrnelson 0:46990814dc89 519 LMIC_setTxData2(1, LMIC.frame, pktSize, ackRequested);
shaunkrnelson 0:46990814dc89 520 }
shaunkrnelson 0:46990814dc89 521
shaunkrnelson 0:46990814dc89 522 static void checkIfRangeTestStart(osjob_t *job)
shaunkrnelson 0:46990814dc89 523 {
shaunkrnelson 0:46990814dc89 524 const ostime_t waitT = ackRequested ? RANGE_NEXT_TEST_NOACK : RANGE_NEXT_TEST_LONG;
shaunkrnelson 0:46990814dc89 525 const ostime_t startT = lastTestDoneT + sec2osticks(waitT);
shaunkrnelson 0:46990814dc89 526
shaunkrnelson 0:46990814dc89 527 debug("%u seconds elapsed since last test\r\n",osticks2ms(os_getTime()-lastTestDoneT)/1000);
shaunkrnelson 0:46990814dc89 528
dkjendal 4:059d004186ed 529 stationary = true;
dkjendal 4:059d004186ed 530 if(gps_service())
shaunkrnelson 0:46990814dc89 531 {
shaunkrnelson 0:46990814dc89 532 // Do we have last tx coordinates
shaunkrnelson 0:46990814dc89 533 if((lastTxPos.latitude() == 0) && (lastTxPos.longitude() == 0))
shaunkrnelson 0:46990814dc89 534 {
shaunkrnelson 0:46990814dc89 535 // Set last tx position to current location
shaunkrnelson 0:46990814dc89 536 lastTxPos.set(gps.Latitude,gps.Longitude);
dkjendal 4:059d004186ed 537 stationary = false;
shaunkrnelson 0:46990814dc89 538 }
shaunkrnelson 0:46990814dc89 539 else
shaunkrnelson 0:46990814dc89 540 {
shaunkrnelson 0:46990814dc89 541 GeoPosition location(gps.Latitude, gps.Longitude);
shaunkrnelson 0:46990814dc89 542 double distance = location.distance(lastTxPos);
shaunkrnelson 0:46990814dc89 543
shaunkrnelson 0:46990814dc89 544 if(distance >= RANGE_START_TEST_DISTANCE)
shaunkrnelson 0:46990814dc89 545 {
shaunkrnelson 0:46990814dc89 546 debug("position change %f >= %u\r\n",distance, RANGE_START_TEST_DISTANCE);
dkjendal 4:059d004186ed 547 stationary = false;
shaunkrnelson 0:46990814dc89 548 os_setCallback( &sendFrameJob, onSendFrame );
shaunkrnelson 0:46990814dc89 549 return;
shaunkrnelson 0:46990814dc89 550 }
shaunkrnelson 0:46990814dc89 551 }
shaunkrnelson 0:46990814dc89 552 }
dkjendal 4:059d004186ed 553 else if(os_getTime() >= startT)
dkjendal 4:059d004186ed 554 {
dkjendal 4:059d004186ed 555 os_setCallback( &sendFrameJob, onSendFrame );
dkjendal 4:059d004186ed 556 }
shaunkrnelson 0:46990814dc89 557
shaunkrnelson 0:46990814dc89 558 // Schedule next check
shaunkrnelson 0:46990814dc89 559 ostime_t nextChkT = os_getTime() + sec2osticks(RANGE_NEXT_TEST_DISTANCE_T);
shaunkrnelson 0:46990814dc89 560
shaunkrnelson 0:46990814dc89 561 // If distance check time less than test start, schedule distance check
shaunkrnelson 0:46990814dc89 562 if(nextChkT <= startT)
shaunkrnelson 0:46990814dc89 563 {
shaunkrnelson 0:46990814dc89 564 os_setTimedCallback( &sendFrameJob, nextChkT, checkIfRangeTestStart);
shaunkrnelson 0:46990814dc89 565 }
shaunkrnelson 0:46990814dc89 566 // Else test start less than distance check time
shaunkrnelson 0:46990814dc89 567 else
shaunkrnelson 0:46990814dc89 568 {
shaunkrnelson 0:46990814dc89 569 os_setTimedCallback( &sendFrameJob, startT, onSendFrame);
shaunkrnelson 0:46990814dc89 570 }
shaunkrnelson 0:46990814dc89 571 }
shaunkrnelson 0:46990814dc89 572
shaunkrnelson 0:46990814dc89 573 static void preTestStart(osjob_t *job)
shaunkrnelson 0:46990814dc89 574 {
shaunkrnelson 0:46990814dc89 575 static u1_t wait = 0;
shaunkrnelson 0:46990814dc89 576
shaunkrnelson 0:46990814dc89 577 // onEvent will initiate test on join or tx complete
shaunkrnelson 0:46990814dc89 578 if(((LMIC.opmode & OP_JOINING) != 0) || ((LMIC.opmode & OP_TXRXPEND) != 0))
shaunkrnelson 0:46990814dc89 579 return;
shaunkrnelson 0:46990814dc89 580
shaunkrnelson 0:46990814dc89 581 if(wait < 6)
shaunkrnelson 0:46990814dc89 582 {
shaunkrnelson 0:46990814dc89 583 if((wait & 1) == 0)
shaunkrnelson 0:46990814dc89 584 {
shaunkrnelson 0:46990814dc89 585 ledRed = 0;
shaunkrnelson 0:46990814dc89 586 ledGreen = 0;
shaunkrnelson 0:46990814dc89 587 ledYellow = 0;
shaunkrnelson 0:46990814dc89 588 }
shaunkrnelson 0:46990814dc89 589 else
shaunkrnelson 0:46990814dc89 590 {
shaunkrnelson 0:46990814dc89 591 ledRed = 1;
shaunkrnelson 0:46990814dc89 592 ledGreen = 1;
shaunkrnelson 0:46990814dc89 593 ledYellow = 1;
shaunkrnelson 0:46990814dc89 594 }
shaunkrnelson 0:46990814dc89 595 wait++;
shaunkrnelson 0:46990814dc89 596 os_setTimedCallback( &sendFrameJob, os_getTime() + sec2osticks(1), preTestStart);
shaunkrnelson 0:46990814dc89 597 }
shaunkrnelson 0:46990814dc89 598 else
shaunkrnelson 0:46990814dc89 599 {
shaunkrnelson 0:46990814dc89 600 wait = 0;
shaunkrnelson 0:46990814dc89 601 os_setCallback( &sendFrameJob, onSendFrame);
shaunkrnelson 0:46990814dc89 602 }
shaunkrnelson 0:46990814dc89 603 }
shaunkrnelson 0:46990814dc89 604
dkjendal 13:89ddcc4dfc66 605 void processDownlink(uint8_t *frame, uint8_t flen)
dkjendal 13:89ddcc4dfc66 606 {
dkjendal 13:89ddcc4dfc66 607 uint8_t version = frame[0];
dkjendal 13:89ddcc4dfc66 608 uint8_t type = frame[1];
dkjendal 13:89ddcc4dfc66 609
dkjendal 13:89ddcc4dfc66 610 if(version != 0x01)
dkjendal 13:89ddcc4dfc66 611 {
dkjendal 13:89ddcc4dfc66 612 debug("%s: invalid packet version %d\r\n",__func__, version);
dkjendal 13:89ddcc4dfc66 613 }
dkjendal 13:89ddcc4dfc66 614
dkjendal 13:89ddcc4dfc66 615 switch(type)
dkjendal 13:89ddcc4dfc66 616 {
dkjendal 13:89ddcc4dfc66 617 #if 0
dkjendal 13:89ddcc4dfc66 618 case CONTROL_PACKET:
dkjendal 13:89ddcc4dfc66 619 {
dkjendal 13:89ddcc4dfc66 620 ConfigWordPacket cfgPkt;
dkjendal 13:89ddcc4dfc66 621
dkjendal 13:89ddcc4dfc66 622 // Transmit self id frame on next tx
dkjendal 13:89ddcc4dfc66 623 txRequested |= 1<<CONTROL_PACKET;
dkjendal 13:89ddcc4dfc66 624
dkjendal 13:89ddcc4dfc66 625 if(cfgPkt.deserialize(frame, flen) == -1)
dkjendal 13:89ddcc4dfc66 626 {
dkjendal 13:89ddcc4dfc66 627 debug("%s: Deserialze config packet failed\r\n",__func__);
dkjendal 13:89ddcc4dfc66 628 return;
dkjendal 13:89ddcc4dfc66 629 }
dkjendal 13:89ddcc4dfc66 630 else if(cfgPkt.authKey != AuthMaster)
dkjendal 13:89ddcc4dfc66 631 {
dkjendal 13:89ddcc4dfc66 632 debug("%s: config authentication failed\r\n",__func__);
dkjendal 13:89ddcc4dfc66 633 }
dkjendal 13:89ddcc4dfc66 634 else
dkjendal 13:89ddcc4dfc66 635 {
dkjendal 13:89ddcc4dfc66 636 uint32_t cfgword = moteConfig.getConfigWord();
dkjendal 13:89ddcc4dfc66 637 cfgword &= ~cfgPkt.mask;
dkjendal 13:89ddcc4dfc66 638 cfgword |= cfgPkt.config & cfgPkt.mask;
dkjendal 13:89ddcc4dfc66 639
dkjendal 13:89ddcc4dfc66 640 debug("%s: configword=%x\r\n",__func__,cfgword);
dkjendal 13:89ddcc4dfc66 641 if(ProcessConfigWord(cfgword, cfgPkt.mask) == true)
dkjendal 13:89ddcc4dfc66 642 {
dkjendal 13:89ddcc4dfc66 643 moteConfig.setConfigWord(cfgword);
dkjendal 13:89ddcc4dfc66 644 moteConfig.writeConfig();
dkjendal 13:89ddcc4dfc66 645 }
dkjendal 13:89ddcc4dfc66 646 }
dkjendal 13:89ddcc4dfc66 647 break;
dkjendal 13:89ddcc4dfc66 648 }
dkjendal 13:89ddcc4dfc66 649 case SELF_ID_PACKET:
dkjendal 13:89ddcc4dfc66 650 txRequested |= 1<<SELF_ID_PACKET;
dkjendal 13:89ddcc4dfc66 651 break;
dkjendal 13:89ddcc4dfc66 652 #endif
dkjendal 13:89ddcc4dfc66 653 case SENSOR_PACKET:
dkjendal 13:89ddcc4dfc66 654 {
dkjendal 13:89ddcc4dfc66 655 SensorPacket sensorPacket;
dkjendal 13:89ddcc4dfc66 656 if(sensorPacket.deserialize(frame,flen) <= 0)
dkjendal 13:89ddcc4dfc66 657 {
dkjendal 13:89ddcc4dfc66 658 debug("%s: Deserialze sensor packet failed\r\n",__func__);
dkjendal 13:89ddcc4dfc66 659 return;
dkjendal 13:89ddcc4dfc66 660 }
dkjendal 13:89ddcc4dfc66 661 if((sensorPacket.sensorValue[0].isSet)&&(sensorPacket.sensorValue[0].value == orientation_mask))
dkjendal 13:89ddcc4dfc66 662 ledYellow = 1;
dkjendal 13:89ddcc4dfc66 663 if((sensorPacket.sensorValue[1].isSet)&&(sensorPacket.sensorValue[1].value == temperature))
dkjendal 13:89ddcc4dfc66 664 ledGreen = 1;
dkjendal 13:89ddcc4dfc66 665 if((sensorPacket.sensorValue[2].isSet)&&(sensorPacket.sensorValue[2].value == pressure))
dkjendal 13:89ddcc4dfc66 666 ledRed = 1;
dkjendal 13:89ddcc4dfc66 667 break;
dkjendal 13:89ddcc4dfc66 668 }
dkjendal 13:89ddcc4dfc66 669 default:
dkjendal 13:89ddcc4dfc66 670 debug("%s: packet type=%d, version=%d\r\n",__func__,type, version);
dkjendal 13:89ddcc4dfc66 671 break;
dkjendal 13:89ddcc4dfc66 672 }
dkjendal 13:89ddcc4dfc66 673 }
shaunkrnelson 0:46990814dc89 674
shaunkrnelson 0:46990814dc89 675 // Protocol event handler
shaunkrnelson 0:46990814dc89 676 void onEvent (ev_t ev)
shaunkrnelson 0:46990814dc89 677 {
shaunkrnelson 0:46990814dc89 678 debug_event(ev);
shaunkrnelson 0:46990814dc89 679 switch(ev)
shaunkrnelson 0:46990814dc89 680 {
shaunkrnelson 0:46990814dc89 681 // network joined, session established
shaunkrnelson 0:46990814dc89 682 case EV_JOINED:
shaunkrnelson 1:fbf2fb2c2718 683 {
shaunkrnelson 1:fbf2fb2c2718 684 displayBuildInfo();
shaunkrnelson 1:fbf2fb2c2718 685 //
shaunkrnelson 0:46990814dc89 686 // Disable link check validation
shaunkrnelson 0:46990814dc89 687 LMIC_setLinkCheckMode(false);
shaunkrnelson 0:46990814dc89 688
shaunkrnelson 1:fbf2fb2c2718 689 // Start transmitting
shaunkrnelson 1:fbf2fb2c2718 690 os_setCallback( &sendFrameJob, onSendFrame);
shaunkrnelson 0:46990814dc89 691
shaunkrnelson 0:46990814dc89 692 break;
shaunkrnelson 0:46990814dc89 693 }
shaunkrnelson 0:46990814dc89 694 // scheduled data sent (optionally data received)
shaunkrnelson 0:46990814dc89 695 case EV_TXCOMPLETE:
shaunkrnelson 0:46990814dc89 696 // Check transmitted frame mode matches running mode. If not, skip results
shaunkrnelson 0:46990814dc89 697 // and start sending frames for current mode
shaunkrnelson 0:46990814dc89 698 if(txMode != operMode)
shaunkrnelson 0:46990814dc89 699 {
shaunkrnelson 0:46990814dc89 700 // Prepare to start test
shaunkrnelson 0:46990814dc89 701 os_setCallback( &sendFrameJob, preTestStart);
shaunkrnelson 0:46990814dc89 702 }
shaunkrnelson 0:46990814dc89 703 else if(operMode == RANGE_TEST)
shaunkrnelson 0:46990814dc89 704 {
shaunkrnelson 0:46990814dc89 705 // Check ack received
shaunkrnelson 0:46990814dc89 706 if((LMIC.txrxFlags & (TXRX_DNW1|TXRX_DNW2) )!= 0 )
shaunkrnelson 0:46990814dc89 707 {
shaunkrnelson 0:46990814dc89 708 ackRequested = false;
shaunkrnelson 0:46990814dc89 709 ledYellow = 1;
shaunkrnelson 0:46990814dc89 710 }
shaunkrnelson 0:46990814dc89 711
shaunkrnelson 0:46990814dc89 712 if(0 == (txCount & 0x07))
shaunkrnelson 0:46990814dc89 713 {
shaunkrnelson 0:46990814dc89 714 // Schedule job to check for range test restart
shaunkrnelson 0:46990814dc89 715 lastTestDoneT = os_getTime();
shaunkrnelson 0:46990814dc89 716 os_setTimedCallback( &sendFrameJob, lastTestDoneT + sec2osticks(RANGE_NEXT_TEST_MIN_TIME), checkIfRangeTestStart);
shaunkrnelson 0:46990814dc89 717 debug("Check for test restart in %u seconds\r\n",RANGE_NEXT_TEST_MIN_TIME);
shaunkrnelson 0:46990814dc89 718
shaunkrnelson 0:46990814dc89 719 // Turn off transmit cycle indicator led
shaunkrnelson 0:46990814dc89 720 ledGreen = 1;
shaunkrnelson 0:46990814dc89 721 }
shaunkrnelson 0:46990814dc89 722 else
shaunkrnelson 0:46990814dc89 723 {
shaunkrnelson 0:46990814dc89 724 os_setTimedCallback( &sendFrameJob, os_getTime() + sec2osticks(RANGE_NEXT_TX), onSendFrame);
shaunkrnelson 0:46990814dc89 725 }
shaunkrnelson 0:46990814dc89 726 }
shaunkrnelson 0:46990814dc89 727 else if(operMode == SITE_TEST)
shaunkrnelson 0:46990814dc89 728 {
shaunkrnelson 0:46990814dc89 729 // Ack received
shaunkrnelson 0:46990814dc89 730 if(((LMIC.txrxFlags & (TXRX_DNW1|TXRX_DNW2) ) != 0 ))
shaunkrnelson 0:46990814dc89 731 {
shaunkrnelson 0:46990814dc89 732 siteAck[sitePw] = 1;
shaunkrnelson 0:46990814dc89 733
shaunkrnelson 0:46990814dc89 734 // Turn on LED
shaunkrnelson 0:46990814dc89 735 switch(pw)
shaunkrnelson 0:46990814dc89 736 {
shaunkrnelson 0:46990814dc89 737 case SITE_GREEN_LED_PW:
shaunkrnelson 0:46990814dc89 738 ledGreen = 0;
shaunkrnelson 0:46990814dc89 739 break;
shaunkrnelson 0:46990814dc89 740 case SITE_YELLOW_LED_PW:
shaunkrnelson 0:46990814dc89 741 ledYellow = 0;
shaunkrnelson 0:46990814dc89 742 break;
shaunkrnelson 0:46990814dc89 743 case SITE_RED_LED_PW:
shaunkrnelson 0:46990814dc89 744 ledRed = 0;
shaunkrnelson 0:46990814dc89 745 break;
shaunkrnelson 0:46990814dc89 746 }
shaunkrnelson 0:46990814dc89 747
shaunkrnelson 0:46990814dc89 748 // Set next tx power first transmit rate
shaunkrnelson 0:46990814dc89 749 sitePw++;
shaunkrnelson 0:46990814dc89 750 siteDrPwAttempts = 0;
shaunkrnelson 0:46990814dc89 751 }
shaunkrnelson 0:46990814dc89 752 // No ACK
shaunkrnelson 0:46990814dc89 753 else if(++siteDrPwAttempts >= SITE_PW_DR_ATTEMPTS)
shaunkrnelson 0:46990814dc89 754 {
shaunkrnelson 0:46990814dc89 755 sitePw++;
shaunkrnelson 0:46990814dc89 756 siteDrPwAttempts = 0;
shaunkrnelson 0:46990814dc89 757 }
shaunkrnelson 0:46990814dc89 758
shaunkrnelson 0:46990814dc89 759 if(sitePw >= SITE_PW_MAX)
shaunkrnelson 0:46990814dc89 760 {
shaunkrnelson 0:46990814dc89 761 sitePw=0;
shaunkrnelson 0:46990814dc89 762 siteDr++;
shaunkrnelson 0:46990814dc89 763 if(siteDr >= SITE_DR_MAX)
shaunkrnelson 0:46990814dc89 764 siteDr=0;
shaunkrnelson 0:46990814dc89 765 }
shaunkrnelson 0:46990814dc89 766
shaunkrnelson 0:46990814dc89 767 if(siteAck[sitePw] == 0)
shaunkrnelson 0:46990814dc89 768 {
shaunkrnelson 0:46990814dc89 769 os_setTimedCallback( &sendFrameJob, os_getTime() + sec2osticks(1), onSendFrame );
shaunkrnelson 0:46990814dc89 770 }
shaunkrnelson 0:46990814dc89 771 else
shaunkrnelson 0:46990814dc89 772 {
shaunkrnelson 0:46990814dc89 773 bool foundNACK = false;
shaunkrnelson 0:46990814dc89 774
shaunkrnelson 0:46990814dc89 775 for(uint32_t i=sitePw; i < SITE_PW_MAX;i++)
shaunkrnelson 0:46990814dc89 776 {
shaunkrnelson 0:46990814dc89 777 if(siteAck[i] == 0)
shaunkrnelson 0:46990814dc89 778 {
shaunkrnelson 0:46990814dc89 779 sitePw = i;
shaunkrnelson 0:46990814dc89 780 os_setTimedCallback( &sendFrameJob, os_getTime() + sec2osticks(1), onSendFrame );
shaunkrnelson 0:46990814dc89 781 foundNACK = true;
shaunkrnelson 0:46990814dc89 782 break;
shaunkrnelson 0:46990814dc89 783 }
shaunkrnelson 0:46990814dc89 784 }
shaunkrnelson 0:46990814dc89 785
shaunkrnelson 0:46990814dc89 786 if(foundNACK == false)
shaunkrnelson 0:46990814dc89 787 {
shaunkrnelson 0:46990814dc89 788 siteDr++;
shaunkrnelson 0:46990814dc89 789 if(siteDr >= SITE_DR_MAX)
shaunkrnelson 0:46990814dc89 790 siteDr=0;
shaunkrnelson 0:46990814dc89 791
shaunkrnelson 0:46990814dc89 792 for(uint32_t i=0; i < sitePw;i++)
shaunkrnelson 0:46990814dc89 793 {
shaunkrnelson 0:46990814dc89 794 if(siteAck[i] == 0)
shaunkrnelson 0:46990814dc89 795 {
shaunkrnelson 0:46990814dc89 796 sitePw = i;
shaunkrnelson 0:46990814dc89 797 os_setTimedCallback( &sendFrameJob, os_getTime() + sec2osticks(1), onSendFrame );
shaunkrnelson 0:46990814dc89 798 break;
shaunkrnelson 0:46990814dc89 799 }
shaunkrnelson 0:46990814dc89 800 }
shaunkrnelson 0:46990814dc89 801 }
shaunkrnelson 0:46990814dc89 802 }
shaunkrnelson 0:46990814dc89 803 }
shaunkrnelson 0:46990814dc89 804 break;
shaunkrnelson 0:46990814dc89 805 default:
shaunkrnelson 0:46990814dc89 806 break;
shaunkrnelson 0:46990814dc89 807 }
shaunkrnelson 0:46990814dc89 808 }
shaunkrnelson 0:46990814dc89 809
shaunkrnelson 0:46990814dc89 810
shaunkrnelson 0:46990814dc89 811 static void statusLedCb(osjob_t *job)
shaunkrnelson 0:46990814dc89 812 {
shaunkrnelson 0:46990814dc89 813 ostime_t sleep;
shaunkrnelson 0:46990814dc89 814
shaunkrnelson 0:46990814dc89 815 if(ledUsr == 1)
shaunkrnelson 0:46990814dc89 816 {
shaunkrnelson 0:46990814dc89 817 if((LMIC.opmode & OP_JOINING) != 0)
shaunkrnelson 0:46990814dc89 818 {
shaunkrnelson 0:46990814dc89 819 ledUsr = 0;
shaunkrnelson 0:46990814dc89 820 sleep = STATUS_FAST_BLINK;
shaunkrnelson 0:46990814dc89 821 }
shaunkrnelson 0:46990814dc89 822 else if(gps.have_fix == false)
shaunkrnelson 0:46990814dc89 823 {
shaunkrnelson 0:46990814dc89 824 ledUsr = 0;
shaunkrnelson 0:46990814dc89 825 sleep = STATUS_SLOW_BLINK;
shaunkrnelson 0:46990814dc89 826 }
shaunkrnelson 0:46990814dc89 827 else
shaunkrnelson 0:46990814dc89 828 {
shaunkrnelson 0:46990814dc89 829 sleep = STATUS_OK_PERIOD;
shaunkrnelson 0:46990814dc89 830 }
shaunkrnelson 0:46990814dc89 831 }
shaunkrnelson 0:46990814dc89 832 else
shaunkrnelson 0:46990814dc89 833 {
shaunkrnelson 0:46990814dc89 834 ledUsr = 1;
shaunkrnelson 0:46990814dc89 835 sleep = 1;
shaunkrnelson 0:46990814dc89 836 }
shaunkrnelson 0:46990814dc89 837
shaunkrnelson 0:46990814dc89 838 os_setTimedCallback( &statusLedJob, os_getTime() + sec2osticks(sleep), statusLedCb );
shaunkrnelson 0:46990814dc89 839 }
shaunkrnelson 0:46990814dc89 840
dkjendal 4:059d004186ed 841 bool leds_are_down = false;
shaunkrnelson 0:46990814dc89 842
shaunkrnelson 0:46990814dc89 843 static void orientationJobCb(osjob_t *job)
shaunkrnelson 0:46990814dc89 844 {
shaunkrnelson 0:46990814dc89 845 static MMA_orientation last;
shaunkrnelson 8:6757b3e3bf3d 846 MMA_orientation orientation;
shaunkrnelson 0:46990814dc89 847 int sleepTime = ORIENTATION_CHECK_PERIOD;
shaunkrnelson 0:46990814dc89 848
shaunkrnelson 0:46990814dc89 849 mma8451q.service();
shaunkrnelson 8:6757b3e3bf3d 850 orientation = mma8451q.getOrientation();
shaunkrnelson 0:46990814dc89 851
shaunkrnelson 8:6757b3e3bf3d 852 if(orientation != last)
shaunkrnelson 0:46990814dc89 853 {
shaunkrnelson 8:6757b3e3bf3d 854 last = orientation;
shaunkrnelson 0:46990814dc89 855 sleepTime = ORIENTATION_DEBOUNCE_TIME;
shaunkrnelson 0:46990814dc89 856 }
shaunkrnelson 0:46990814dc89 857 else
shaunkrnelson 8:6757b3e3bf3d 858 {
shaunkrnelson 9:65a83f20cf3b 859 /* Get orientation using the portrait/landscape status
shaunkrnelson 9:65a83f20cf3b 860 * When viewing device from front orientation is:
shaunkrnelson 10:72c5e2cfa473 861 * - LED UP = landscape right
shaunkrnelson 9:65a83f20cf3b 862 * - LED LEFT = portrait up
shaunkrnelson 10:72c5e2cfa473 863 * - LED DOWN = landscape left
shaunkrnelson 9:65a83f20cf3b 864 * - LED RIGHT = portrait down
shaunkrnelson 9:65a83f20cf3b 865 *
shaunkrnelson 9:65a83f20cf3b 866 * NOTE:
shaunkrnelson 9:65a83f20cf3b 867 * When low is true the device is flat and the orientation will always be portrait up
shaunkrnelson 9:65a83f20cf3b 868 *
shaunkrnelson 9:65a83f20cf3b 869 */
shaunkrnelson 9:65a83f20cf3b 870
shaunkrnelson 10:72c5e2cfa473 871 bool flat = false;
shaunkrnelson 10:72c5e2cfa473 872 bool up = false;
shaunkrnelson 10:72c5e2cfa473 873 bool down = false;
shaunkrnelson 10:72c5e2cfa473 874 bool right = false;
shaunkrnelson 10:72c5e2cfa473 875 bool left = false;
shaunkrnelson 7:6a23db89f2a6 876
shaunkrnelson 7:6a23db89f2a6 877 if(orientation.low)
shaunkrnelson 7:6a23db89f2a6 878 {
shaunkrnelson 9:65a83f20cf3b 879 flat = true;
shaunkrnelson 7:6a23db89f2a6 880 }
shaunkrnelson 10:72c5e2cfa473 881 else if(orientation.right)
shaunkrnelson 7:6a23db89f2a6 882 {
shaunkrnelson 7:6a23db89f2a6 883 up = true;
shaunkrnelson 7:6a23db89f2a6 884 }
shaunkrnelson 9:65a83f20cf3b 885 else if(orientation.up)
shaunkrnelson 9:65a83f20cf3b 886 {
shaunkrnelson 9:65a83f20cf3b 887 left = true;
shaunkrnelson 9:65a83f20cf3b 888 }
shaunkrnelson 10:72c5e2cfa473 889 else if(orientation.left)
shaunkrnelson 7:6a23db89f2a6 890 {
shaunkrnelson 7:6a23db89f2a6 891 down = true;
shaunkrnelson 7:6a23db89f2a6 892 }
shaunkrnelson 9:65a83f20cf3b 893 else if(orientation.down)
shaunkrnelson 9:65a83f20cf3b 894 {
shaunkrnelson 9:65a83f20cf3b 895 right = true;
shaunkrnelson 7:6a23db89f2a6 896 }
shaunkrnelson 7:6a23db89f2a6 897
shaunkrnelson 9:65a83f20cf3b 898 const OperMode mode = up ? SITE_TEST : RANGE_TEST;
shaunkrnelson 9:65a83f20cf3b 899
shaunkrnelson 9:65a83f20cf3b 900 uint16_t new_orientation_mask;
shaunkrnelson 8:6757b3e3bf3d 901
shaunkrnelson 10:72c5e2cfa473 902 /* Orientation mask values
shaunkrnelson 10:72c5e2cfa473 903 * - LED-UP = 1000
shaunkrnelson 10:72c5e2cfa473 904 * - LED-LEFT = 0100
shaunkrnelson 10:72c5e2cfa473 905 * - LED-DOWN = 0010
shaunkrnelson 10:72c5e2cfa473 906 * - LED-RIGHT = 0001
shaunkrnelson 10:72c5e2cfa473 907 * Flat
shaunkrnelson 10:72c5e2cfa473 908 * - front is up = 2000
shaunkrnelson 10:72c5e2cfa473 909 * - front is down = 2100
shaunkrnelson 10:72c5e2cfa473 910 */
shaunkrnelson 9:65a83f20cf3b 911 if(!flat)
shaunkrnelson 9:65a83f20cf3b 912 {
shaunkrnelson 9:65a83f20cf3b 913 new_orientation_mask = (up << 12) | (left << 8) | (down << 4) | right;
shaunkrnelson 9:65a83f20cf3b 914 }
shaunkrnelson 9:65a83f20cf3b 915 else
shaunkrnelson 9:65a83f20cf3b 916 {
shaunkrnelson 9:65a83f20cf3b 917 new_orientation_mask = (2 << 12) | (orientation.back << 8);
shaunkrnelson 9:65a83f20cf3b 918 }
shaunkrnelson 9:65a83f20cf3b 919
shaunkrnelson 9:65a83f20cf3b 920 leds_are_down = down;
shaunkrnelson 0:46990814dc89 921
shaunkrnelson 8:6757b3e3bf3d 922 bool send_now = new_orientation_mask != orientation_mask;
shaunkrnelson 8:6757b3e3bf3d 923 orientation_mask = new_orientation_mask;
shaunkrnelson 8:6757b3e3bf3d 924
shaunkrnelson 0:46990814dc89 925 if(mode != operMode)
shaunkrnelson 0:46990814dc89 926 {
shaunkrnelson 0:46990814dc89 927 debug("Change to %s mode\r\n", mode==SITE_TEST?"Site":"Range");
shaunkrnelson 0:46990814dc89 928
shaunkrnelson 0:46990814dc89 929 // onEvent will start test if currently joining or transmitting
shaunkrnelson 0:46990814dc89 930 if(((LMIC.opmode & OP_JOINING) == 0) && ((LMIC.opmode & OP_TXRXPEND) == 0))
shaunkrnelson 0:46990814dc89 931 {
shaunkrnelson 0:46990814dc89 932 if(operMode != IDLE)
shaunkrnelson 0:46990814dc89 933 {
shaunkrnelson 0:46990814dc89 934 os_setCallback( &sendFrameJob, preTestStart);
shaunkrnelson 0:46990814dc89 935 }
shaunkrnelson 0:46990814dc89 936 else
shaunkrnelson 0:46990814dc89 937 {
shaunkrnelson 0:46990814dc89 938 os_setCallback( &sendFrameJob, onSendFrame);
shaunkrnelson 0:46990814dc89 939 }
shaunkrnelson 0:46990814dc89 940 }
shaunkrnelson 0:46990814dc89 941
shaunkrnelson 0:46990814dc89 942 // Set mode
shaunkrnelson 0:46990814dc89 943 operMode = mode;
shaunkrnelson 0:46990814dc89 944
shaunkrnelson 0:46990814dc89 945 // Reset test indicator LEDs
shaunkrnelson 0:46990814dc89 946 ledRed = 1;
shaunkrnelson 0:46990814dc89 947 ledGreen = 1;
shaunkrnelson 0:46990814dc89 948 ledYellow = 1;
shaunkrnelson 0:46990814dc89 949
shaunkrnelson 0:46990814dc89 950 // Reset test state
shaunkrnelson 0:46990814dc89 951 txCount = 0;
shaunkrnelson 0:46990814dc89 952 siteDr = 0;
shaunkrnelson 0:46990814dc89 953 sitePw = 0;
shaunkrnelson 0:46990814dc89 954 memset(siteAck, 0, sizeof(siteAck));
shaunkrnelson 0:46990814dc89 955 }
dkjendal 4:059d004186ed 956 else if (send_now)
dkjendal 4:059d004186ed 957 os_setCallback( &sendFrameJob, onSendFrame);
shaunkrnelson 0:46990814dc89 958 }
shaunkrnelson 0:46990814dc89 959
shaunkrnelson 0:46990814dc89 960 os_setTimedCallback( &orientationJob, os_getTime() + sec2osticks(sleepTime), orientationJobCb );
shaunkrnelson 0:46990814dc89 961 }
shaunkrnelson 0:46990814dc89 962
shaunkrnelson 0:46990814dc89 963 // Kick off initial jobs
shaunkrnelson 0:46990814dc89 964 void application_init()
shaunkrnelson 0:46990814dc89 965 {
shaunkrnelson 0:46990814dc89 966 // Start status led job
shaunkrnelson 0:46990814dc89 967 os_setCallback(&statusLedJob, statusLedCb);
shaunkrnelson 0:46990814dc89 968
shaunkrnelson 0:46990814dc89 969 // Start orientation job - Test will start once orientation is determined
shaunkrnelson 0:46990814dc89 970 os_setCallback(&orientationJob, orientationJobCb);
shaunkrnelson 0:46990814dc89 971
shaunkrnelson 0:46990814dc89 972 // Get current gps coordinates
shaunkrnelson 0:46990814dc89 973 if(gps_service() == true)
shaunkrnelson 0:46990814dc89 974 lastTxPos.set(gps.Latitude,gps.Longitude);
shaunkrnelson 0:46990814dc89 975 else
shaunkrnelson 0:46990814dc89 976 lastTxPos.set(0,0);
shaunkrnelson 0:46990814dc89 977 }
shaunkrnelson 0:46990814dc89 978
shaunkrnelson 0:46990814dc89 979
shaunkrnelson 0:46990814dc89 980 int main(void)
shaunkrnelson 0:46990814dc89 981 {
shaunkrnelson 0:46990814dc89 982 // initialize runtime env
shaunkrnelson 0:46990814dc89 983 os_init();
shaunkrnelson 0:46990814dc89 984
shaunkrnelson 0:46990814dc89 985 // initialize debug system
shaunkrnelson 0:46990814dc89 986 debug_init();
shaunkrnelson 0:46990814dc89 987
shaunkrnelson 0:46990814dc89 988 // Display build info
shaunkrnelson 0:46990814dc89 989 displayBuildInfo();
shaunkrnelson 0:46990814dc89 990
shaunkrnelson 0:46990814dc89 991 // initialize peripherals
shaunkrnelson 0:46990814dc89 992 board_peripherals_init();
shaunkrnelson 0:46990814dc89 993
shaunkrnelson 0:46990814dc89 994 // Application initialization
shaunkrnelson 0:46990814dc89 995 application_init();
shaunkrnelson 0:46990814dc89 996
shaunkrnelson 0:46990814dc89 997 // Start protocol
shaunkrnelson 0:46990814dc89 998 startLMIC();
shaunkrnelson 0:46990814dc89 999
shaunkrnelson 0:46990814dc89 1000 // execute scheduled jobs and events
shaunkrnelson 0:46990814dc89 1001 os_runloop();
shaunkrnelson 0:46990814dc89 1002 // (not reached)
shaunkrnelson 0:46990814dc89 1003 }
shaunkrnelson 0:46990814dc89 1004