send GPS uplinks in Cayenne LPP format

Dependencies:   lib_gps lorawan1v1

radio chip selection

Radio chip driver is not included, because two options are available.
If you're using SX1272 or SX1276, then import sx127x driver into your program.
if you're using SX1261 or SX1262, then import sx126x driver into your program.
If you're using NAmote72 or Murata discovery, then you must import only sx127x driver.

See LoRaWAN library page for provisioning onto network: Commissioning.h

Connection To GPS Receiver

This demonstration depends on GPS receiver sending NMEA into one of the UART on your target CPU.
Such as GP-20U7.
Sends uplink in cayenne LPP format.

Connection to NUCLEO form factor

Jumper for auto-uplink: PC6->PC8 = CN10-2->CN10-4

nameconnector pinCPU pin
VddCN7-5
GndCN7-8
UARTCN7-2PC11

Connection to DISCO_L072CZ_LRWAN1

Jumper for auto-uplink: PA11->PA12 = CN3-14->CN3-15

nameconnector pinCPU pin
VddCN3-5
GndCN3-6
UARTCN3-21PA10
Committer:
Wayne Roberts
Date:
Tue Aug 14 09:34:49 2018 -0700
Revision:
3:2f57b7856222
Parent:
2:fdd36ff9b181
update libraries to latest

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wayne Roberts 0:d467d869e49c 1 /*
Wayne Roberts 0:d467d869e49c 2 / _____) _ | |
Wayne Roberts 0:d467d869e49c 3 ( (____ _____ ____ _| |_ _____ ____| |__
Wayne Roberts 0:d467d869e49c 4 \____ \| ___ | (_ _) ___ |/ ___) _ \
Wayne Roberts 0:d467d869e49c 5 _____) ) ____| | | || |_| ____( (___| | | |
Wayne Roberts 0:d467d869e49c 6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
Wayne Roberts 0:d467d869e49c 7 (C)2018 Semtech
Wayne Roberts 0:d467d869e49c 8
Wayne Roberts 0:d467d869e49c 9 Description: LoRaMac classB device implementation
Wayne Roberts 0:d467d869e49c 10
Wayne Roberts 0:d467d869e49c 11 License: Revised BSD License, see LICENSE.TXT file include in the project
Wayne Roberts 0:d467d869e49c 12
Wayne Roberts 0:d467d869e49c 13 */
Wayne Roberts 0:d467d869e49c 14
Wayne Roberts 0:d467d869e49c 15 #include "LoRaMac1v1.h"
Wayne Roberts 0:d467d869e49c 16 #include "LoRaMacString.h"
Wayne Roberts 0:d467d869e49c 17 #include "gps.h"
Wayne Roberts 0:d467d869e49c 18
Wayne Roberts 0:d467d869e49c 19 /*!
Wayne Roberts 0:d467d869e49c 20 * Defines the application data transmission duty cycle. 5s, value in [ms].
Wayne Roberts 0:d467d869e49c 21 */
Wayne Roberts 0:d467d869e49c 22 #define APP_TX_DUTYCYCLE_us 8000000
Wayne Roberts 0:d467d869e49c 23
Wayne Roberts 0:d467d869e49c 24 /*!
Wayne Roberts 0:d467d869e49c 25 * Defines a random delay for application data transmission duty cycle. 1s,
Wayne Roberts 0:d467d869e49c 26 * value in [ms].
Wayne Roberts 0:d467d869e49c 27 */
Wayne Roberts 0:d467d869e49c 28 #define APP_TX_DUTYCYCLE_RND_us 2000000
Wayne Roberts 0:d467d869e49c 29
Wayne Roberts 0:d467d869e49c 30 /*!
Wayne Roberts 0:d467d869e49c 31 * Default datarate
Wayne Roberts 0:d467d869e49c 32 */
Wayne Roberts 0:d467d869e49c 33
Wayne Roberts 0:d467d869e49c 34 #if defined( USE_BAND_ARIB_8CH )
Wayne Roberts 0:d467d869e49c 35 #define LORAWAN_DEFAULT_DATARATE DR_3
Wayne Roberts 0:d467d869e49c 36 #else
Wayne Roberts 0:d467d869e49c 37 #define LORAWAN_DEFAULT_DATARATE DR_0
Wayne Roberts 0:d467d869e49c 38 #endif
Wayne Roberts 0:d467d869e49c 39
Wayne Roberts 0:d467d869e49c 40 /*!
Wayne Roberts 0:d467d869e49c 41 * LoRaWAN confirmed messages
Wayne Roberts 0:d467d869e49c 42 */
Wayne Roberts 0:d467d869e49c 43 #define LORAWAN_CONFIRMED_MSG_ON false
Wayne Roberts 0:d467d869e49c 44
Wayne Roberts 0:d467d869e49c 45 /*!
Wayne Roberts 0:d467d869e49c 46 * LoRaWAN Adaptive Data Rate
Wayne Roberts 0:d467d869e49c 47 *
Wayne Roberts 0:d467d869e49c 48 * \remark Please note that when ADR is enabled the end-device should be static
Wayne Roberts 0:d467d869e49c 49 */
Wayne Roberts 0:d467d869e49c 50 #define LORAWAN_ADR_ON 1
Wayne Roberts 0:d467d869e49c 51
Wayne Roberts 0:d467d869e49c 52 #if defined( USE_BAND_868 )
Wayne Roberts 0:d467d869e49c 53
Wayne Roberts 0:d467d869e49c 54 /*!
Wayne Roberts 0:d467d869e49c 55 * LoRaWAN ETSI duty cycle control enable/disable
Wayne Roberts 0:d467d869e49c 56 *
Wayne Roberts 0:d467d869e49c 57 * \remark Please note that ETSI mandates duty cycled transmissions. Use only for test purposes
Wayne Roberts 0:d467d869e49c 58 */
Wayne Roberts 0:d467d869e49c 59 #define LORAWAN_DUTYCYCLE_ON false
Wayne Roberts 0:d467d869e49c 60
Wayne Roberts 0:d467d869e49c 61 #define USE_SEMTECH_DEFAULT_CHANNEL_LINEUP 1
Wayne Roberts 0:d467d869e49c 62
Wayne Roberts 0:d467d869e49c 63 #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 )
Wayne Roberts 0:d467d869e49c 64
Wayne Roberts 0:d467d869e49c 65 #define LC4 { 867100000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
Wayne Roberts 0:d467d869e49c 66 #define LC5 { 867300000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
Wayne Roberts 0:d467d869e49c 67 #define LC6 { 867500000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
Wayne Roberts 0:d467d869e49c 68 #define LC7 { 867700000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
Wayne Roberts 0:d467d869e49c 69 #define LC8 { 867900000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
Wayne Roberts 0:d467d869e49c 70 #define LC9 { 868800000, { ( ( DR_7 << 4 ) | DR_7 ) }, 2 }
Wayne Roberts 0:d467d869e49c 71 #define LC10 { 868300000, { ( ( DR_6 << 4 ) | DR_6 ) }, 1 }
Wayne Roberts 0:d467d869e49c 72
Wayne Roberts 0:d467d869e49c 73 #endif
Wayne Roberts 0:d467d869e49c 74
Wayne Roberts 0:d467d869e49c 75 #endif
Wayne Roberts 0:d467d869e49c 76
Wayne Roberts 0:d467d869e49c 77 /*!
Wayne Roberts 0:d467d869e49c 78 * LoRaWAN application port
Wayne Roberts 0:d467d869e49c 79 */
Wayne Roberts 0:d467d869e49c 80 #define LORAWAN_APP_PORT 2
Wayne Roberts 0:d467d869e49c 81
Wayne Roberts 0:d467d869e49c 82 /*!
Wayne Roberts 0:d467d869e49c 83 * User application data buffer size
Wayne Roberts 0:d467d869e49c 84 */
Wayne Roberts 0:d467d869e49c 85 #define LORAWAN_APP_DATA_SIZE 3
Wayne Roberts 0:d467d869e49c 86
Wayne Roberts 0:d467d869e49c 87
Wayne Roberts 0:d467d869e49c 88 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:d467d869e49c 89 static uint8_t DevEui[] = LORAWAN_DEVICE_EUI;
Wayne Roberts 0:d467d869e49c 90 static const uint8_t JoinEui[] = LORAWAN_JOIN_EUI;
Wayne Roberts 0:d467d869e49c 91 static const uint8_t NwkKey[] = LORAWAN_ROOT_NWKKEY;
Wayne Roberts 0:d467d869e49c 92 #ifdef LORAWAN_ROOT_APPKEY
Wayne Roberts 0:d467d869e49c 93 static const uint8_t AppKey[] = LORAWAN_ROOT_APPKEY;
Wayne Roberts 0:d467d869e49c 94 #endif
Wayne Roberts 0:d467d869e49c 95 #else
Wayne Roberts 0:d467d869e49c 96 static const uint8_t FNwkSIntKey[] = LORAWAN_FNwkSIntKey;
Wayne Roberts 0:d467d869e49c 97 static const uint8_t AppSKey[] = LORAWAN_APPSKEY;
Wayne Roberts 0:d467d869e49c 98 static const uint32_t DevAddr = LORAWAN_DEVICE_ADDRESS;
Wayne Roberts 0:d467d869e49c 99 #if defined(LORAWAN_SNwkSIntKey) && defined(LORAWAN_NwkSEncKey)
Wayne Roberts 0:d467d869e49c 100 static const uint8_t SNwkSIntKey[] = LORAWAN_SNwkSIntKey;
Wayne Roberts 0:d467d869e49c 101 static const uint8_t NwkSEncKey[] = LORAWAN_NwkSEncKey;
Wayne Roberts 0:d467d869e49c 102 #endif
Wayne Roberts 0:d467d869e49c 103 #endif
Wayne Roberts 0:d467d869e49c 104
Wayne Roberts 0:d467d869e49c 105
Wayne Roberts 0:d467d869e49c 106 #ifdef TARGET_DISCO_L072CZ_LRWAN1
Wayne Roberts 0:d467d869e49c 107 #define GREEN LED1
Wayne Roberts 0:d467d869e49c 108 #define RED2 LED2
Wayne Roberts 0:d467d869e49c 109 #define BLUE LED3
Wayne Roberts 0:d467d869e49c 110 #define RED4 LED4
Wayne Roberts 0:d467d869e49c 111 DigitalOut blue(BLUE);
Wayne Roberts 0:d467d869e49c 112 #define LED_ON 1
Wayne Roberts 0:d467d869e49c 113 #define LED_OFF 0
Wayne Roberts 0:d467d869e49c 114 #endif /* TARGET_DISCO_L072CZ_LRWAN1 */
Wayne Roberts 0:d467d869e49c 115 /*!
Wayne Roberts 0:d467d869e49c 116 * Application port
Wayne Roberts 0:d467d869e49c 117 */
Wayne Roberts 0:d467d869e49c 118 static uint8_t AppPort = LORAWAN_APP_PORT;
Wayne Roberts 0:d467d869e49c 119
Wayne Roberts 0:d467d869e49c 120 /*!
Wayne Roberts 0:d467d869e49c 121 * User application data size
Wayne Roberts 0:d467d869e49c 122 */
Wayne Roberts 0:d467d869e49c 123 static uint8_t gAppDataSize = LORAWAN_APP_DATA_SIZE;
Wayne Roberts 0:d467d869e49c 124
Wayne Roberts 0:d467d869e49c 125 /*!
Wayne Roberts 0:d467d869e49c 126 * User application data buffer size
Wayne Roberts 0:d467d869e49c 127 */
Wayne Roberts 0:d467d869e49c 128 #define LORAWAN_APP_DATA_MAX_SIZE 64
Wayne Roberts 0:d467d869e49c 129
Wayne Roberts 0:d467d869e49c 130 /*!
Wayne Roberts 0:d467d869e49c 131 * User application data
Wayne Roberts 0:d467d869e49c 132 */
Wayne Roberts 0:d467d869e49c 133 static uint8_t AppData[LORAWAN_APP_DATA_MAX_SIZE];
Wayne Roberts 0:d467d869e49c 134
Wayne Roberts 0:d467d869e49c 135 /*!
Wayne Roberts 0:d467d869e49c 136 * Indicates if the node is sending confirmed or unconfirmed messages
Wayne Roberts 0:d467d869e49c 137 */
Wayne Roberts 0:d467d869e49c 138 static uint8_t gIsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
Wayne Roberts 0:d467d869e49c 139
Wayne Roberts 0:d467d869e49c 140 /*!
Wayne Roberts 0:d467d869e49c 141 * Timer to handle the application data transmission duty cycle
Wayne Roberts 0:d467d869e49c 142 *
Wayne Roberts 0:d467d869e49c 143 */
Wayne Roberts 0:d467d869e49c 144 LowPowerTimeout tx_timeout;
Wayne Roberts 0:d467d869e49c 145
Wayne Roberts 0:d467d869e49c 146 /*!
Wayne Roberts 0:d467d869e49c 147 * Indicates if a new packet can be sent
Wayne Roberts 0:d467d869e49c 148 */
Wayne Roberts 0:d467d869e49c 149 static volatile struct {
Wayne Roberts 0:d467d869e49c 150 uint8_t startup : 1;
Wayne Roberts 0:d467d869e49c 151 uint8_t ackDownlink : 1;
Wayne Roberts 0:d467d869e49c 152 } flags;
Wayne Roberts 0:d467d869e49c 153
Wayne Roberts 0:d467d869e49c 154 /*!
Wayne Roberts 0:d467d869e49c 155 * Device states
Wayne Roberts 0:d467d869e49c 156 */
Wayne Roberts 0:d467d869e49c 157 volatile enum eDevicState
Wayne Roberts 0:d467d869e49c 158 {
Wayne Roberts 0:d467d869e49c 159 /* 0 */ DEVICE_STATE_INIT = 0,
Wayne Roberts 0:d467d869e49c 160 /* 1 */ DEVICE_STATE_SEND,
Wayne Roberts 0:d467d869e49c 161 /* 2 */ DEVICE_STATE_SLEEP,
Wayne Roberts 0:d467d869e49c 162 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:d467d869e49c 163 /* 3 */ DEVICE_STATE_JOIN,
Wayne Roberts 0:d467d869e49c 164 /* 4 */ DEVICE_STATE_JOIN_OK
Wayne Roberts 0:d467d869e49c 165 #endif /* LORAWAN_JOIN_EUI */
Wayne Roberts 0:d467d869e49c 166 } DeviceState, WakeUpState;
Wayne Roberts 0:d467d869e49c 167
Wayne Roberts 0:d467d869e49c 168 #if defined(TARGET_MOTE_L152RC) && !defined(TARGET_FF_ARDUINO)
Wayne Roberts 0:d467d869e49c 169 #define TARGET_FF_ARDUINO
Wayne Roberts 0:d467d869e49c 170 #endif
Wayne Roberts 0:d467d869e49c 171
Wayne Roberts 0:d467d869e49c 172 #if defined(TARGET_FF_ARDUINO)
Wayne Roberts 0:d467d869e49c 173 #ifdef TARGET_DISCO_L072CZ_LRWAN1
Wayne Roberts 0:d467d869e49c 174 #define LED_GREEN LED1
Wayne Roberts 0:d467d869e49c 175 #define LED_RED2 LED2 // next to LD7
Wayne Roberts 0:d467d869e49c 176 #define LED_BLUE LED3
Wayne Roberts 0:d467d869e49c 177 #define LED_RED4 LED4
Wayne Roberts 0:d467d869e49c 178 InterruptIn button_pin(USER_BUTTON);
Wayne Roberts 0:d467d869e49c 179 #define BUTTON_PRESSED 0
Wayne Roberts 0:d467d869e49c 180 DigitalOut extLed(LED_RED4);
Wayne Roberts 0:d467d869e49c 181 #else
Wayne Roberts 0:d467d869e49c 182 InterruptIn button_pin(D8);
Wayne Roberts 0:d467d869e49c 183 #define BUTTON_PRESSED 1
Wayne Roberts 0:d467d869e49c 184 DigitalOut extLed(D15);
Wayne Roberts 0:d467d869e49c 185 #endif
Wayne Roberts 0:d467d869e49c 186 #endif /* TARGET_FF_ARDUINO */
Wayne Roberts 0:d467d869e49c 187
Wayne Roberts 0:d467d869e49c 188 #define JUMPER_ENABLE
Wayne Roberts 0:d467d869e49c 189
Wayne Roberts 0:d467d869e49c 190 #if defined(JUMPER_ENABLE)
Wayne Roberts 0:d467d869e49c 191 #define TX_INTERVAL_US 15000000
Wayne Roberts 0:d467d869e49c 192 #if defined(TARGET_FF_MORPHO)
Wayne Roberts 0:d467d869e49c 193 #ifdef TARGET_DISCO_L072CZ_LRWAN1
Wayne Roberts 0:d467d869e49c 194 DigitalOut jumper_out(PA_11);
Wayne Roberts 0:d467d869e49c 195 InterruptIn jumper_in(PA_12);
Wayne Roberts 0:d467d869e49c 196 #else
Wayne Roberts 0:d467d869e49c 197 DigitalOut jumper_out(PC_8);
Wayne Roberts 0:d467d869e49c 198 InterruptIn jumper_in(PC_6);
Wayne Roberts 0:d467d869e49c 199 #endif
Wayne Roberts 0:d467d869e49c 200 #endif /* TARGET_FF_MORPHO */
Wayne Roberts 0:d467d869e49c 201 #endif /* JUMPER_ENABLE */
Wayne Roberts 0:d467d869e49c 202
Wayne Roberts 0:d467d869e49c 203 uint8_t c_ch;
Wayne Roberts 0:d467d869e49c 204 us_timestamp_t buttonStartAt;
Wayne Roberts 0:d467d869e49c 205
Wayne Roberts 0:d467d869e49c 206 #ifdef TARGET_FF_MORPHO
Wayne Roberts 0:d467d869e49c 207 /* https://www.sparkfun.com/products/13740 */
Wayne Roberts 0:d467d869e49c 208 #ifdef TARGET_DISCO_L072CZ_LRWAN1
Wayne Roberts 0:d467d869e49c 209 GPS gps(PA_9, PA_10, NC);
Wayne Roberts 0:d467d869e49c 210 #else
Wayne Roberts 0:d467d869e49c 211 GPS gps(PC_10, PC_11, NC);
Wayne Roberts 0:d467d869e49c 212 #endif
Wayne Roberts 0:d467d869e49c 213 #endif /* TARGET_FF_MORPHO */
Wayne Roberts 0:d467d869e49c 214
Wayne Roberts 0:d467d869e49c 215 /*!
Wayne Roberts 0:d467d869e49c 216 * LoRaWAN compliance tests support data
Wayne Roberts 0:d467d869e49c 217 */
Wayne Roberts 0:d467d869e49c 218 struct ComplianceTest_s
Wayne Roberts 0:d467d869e49c 219 {
Wayne Roberts 0:d467d869e49c 220 bool Running;
Wayne Roberts 0:d467d869e49c 221 uint8_t State;
Wayne Roberts 0:d467d869e49c 222 bool IsTxConfirmed;
Wayne Roberts 0:d467d869e49c 223 uint8_t AppPort;
Wayne Roberts 0:d467d869e49c 224 uint8_t AppDataSize;
Wayne Roberts 0:d467d869e49c 225 uint8_t *AppDataBuffer;
Wayne Roberts 0:d467d869e49c 226 uint16_t DownLinkCounter;
Wayne Roberts 0:d467d869e49c 227 bool LinkCheck;
Wayne Roberts 0:d467d869e49c 228 uint8_t DemodMargin;
Wayne Roberts 0:d467d869e49c 229 uint8_t NbGateways;
Wayne Roberts 0:d467d869e49c 230 }ComplianceTest;
Wayne Roberts 0:d467d869e49c 231
Wayne Roberts 0:d467d869e49c 232 #ifdef JUMPER_ENABLE
Wayne Roberts 0:d467d869e49c 233 void autoUplink()
Wayne Roberts 0:d467d869e49c 234 {
Wayne Roberts 0:d467d869e49c 235 if (jumper_in.read() == 1) {
Wayne Roberts 0:d467d869e49c 236 tx_timeout.attach_us(autoUplink, TX_INTERVAL_US);
Wayne Roberts 0:d467d869e49c 237 }
Wayne Roberts 0:d467d869e49c 238
Wayne Roberts 0:d467d869e49c 239 c_ch = 0xff;
Wayne Roberts 0:d467d869e49c 240 DeviceState = DEVICE_STATE_SEND;
Wayne Roberts 0:d467d869e49c 241 }
Wayne Roberts 0:d467d869e49c 242
Wayne Roberts 0:d467d869e49c 243 void jumper_callback()
Wayne Roberts 0:d467d869e49c 244 {
Wayne Roberts 0:d467d869e49c 245 tx_timeout.attach_us(autoUplink, TX_INTERVAL_US);
Wayne Roberts 0:d467d869e49c 246 }
Wayne Roberts 0:d467d869e49c 247 #endif /* JUMPER_ENABLE */
Wayne Roberts 0:d467d869e49c 248
Wayne Roberts 0:d467d869e49c 249
Wayne Roberts 0:d467d869e49c 250 #define LPP_DIGITAL_INPUT 0 // 1 byte
Wayne Roberts 0:d467d869e49c 251 #define LPP_DIGITAL_OUTPUT 1 // 1 byte
Wayne Roberts 0:d467d869e49c 252 #define LPP_ANALOG_INPUT 2 // 2 bytes, 0.01 signed
Wayne Roberts 0:d467d869e49c 253 #define LPP_ANALOG_OUTPUT 3 // 2 bytes, 0.01 signed
Wayne Roberts 0:d467d869e49c 254 #define LPP_LUMINOSITY 101 // 2 bytes, 1 lux unsigned
Wayne Roberts 0:d467d869e49c 255 #define LPP_PRESENCE 102 // 1 byte, 1
Wayne Roberts 0:d467d869e49c 256 #define LPP_TEMPERATURE 103 // 2 bytes, 0.1°C signed
Wayne Roberts 0:d467d869e49c 257 #define LPP_RELATIVE_HUMIDITY 104 // 1 byte, 0.5% unsigned
Wayne Roberts 0:d467d869e49c 258 #define LPP_ACCELEROMETER 113 // 2 bytes per axis, 0.001G
Wayne Roberts 0:d467d869e49c 259 #define LPP_BAROMETRIC_PRESSURE 115 // 2 bytes 0.1 hPa Unsigned
Wayne Roberts 0:d467d869e49c 260 #define LPP_GYROMETER 134 // 2 bytes per axis, 0.01 °/s
Wayne Roberts 0:d467d869e49c 261 #define LPP_GPS 136 // 3 byte lon/lat 0.0001 °, 3 bytes alt 0.01m
Wayne Roberts 0:d467d869e49c 262
Wayne Roberts 0:d467d869e49c 263
Wayne Roberts 0:d467d869e49c 264 // Data ID + Data Type + Data Size
Wayne Roberts 0:d467d869e49c 265 #define LPP_DIGITAL_INPUT_SIZE 3
Wayne Roberts 0:d467d869e49c 266 #define LPP_DIGITAL_OUTPUT_SIZE 3
Wayne Roberts 0:d467d869e49c 267 #define LPP_ANALOG_INPUT_SIZE 4
Wayne Roberts 0:d467d869e49c 268 #define LPP_ANALOG_OUTPUT_SIZE 4
Wayne Roberts 0:d467d869e49c 269 #define LPP_LUMINOSITY_SIZE 4
Wayne Roberts 0:d467d869e49c 270 #define LPP_PRESENCE_SIZE 3
Wayne Roberts 0:d467d869e49c 271 #define LPP_TEMPERATURE_SIZE 4
Wayne Roberts 0:d467d869e49c 272 #define LPP_RELATIVE_HUMIDITY_SIZE 3
Wayne Roberts 0:d467d869e49c 273 #define LPP_ACCELEROMETER_SIZE 8
Wayne Roberts 0:d467d869e49c 274 #define LPP_BAROMETRIC_PRESSURE_SIZE 4
Wayne Roberts 0:d467d869e49c 275 #define LPP_GYROMETER_SIZE 8
Wayne Roberts 0:d467d869e49c 276 #define LPP_GPS_SIZE 11
Wayne Roberts 0:d467d869e49c 277
Wayne Roberts 0:d467d869e49c 278 #define CAYENNE_CH_GPS 5
Wayne Roberts 0:d467d869e49c 279
Wayne Roberts 0:d467d869e49c 280 /*!
Wayne Roberts 0:d467d869e49c 281 * \brief Prepares the payload of the frame
Wayne Roberts 0:d467d869e49c 282 */
Wayne Roberts 0:d467d869e49c 283 static void PrepareTxFrame( uint8_t port )
Wayne Roberts 0:d467d869e49c 284 {
Wayne Roberts 0:d467d869e49c 285 int32_t lat, lon, alt;
Wayne Roberts 0:d467d869e49c 286
Wayne Roberts 0:d467d869e49c 287 while (button_pin.read() == BUTTON_PRESSED) {
Wayne Roberts 0:d467d869e49c 288 us_timestamp_t duration = LoRaMacReadTimer() - buttonStartAt;
Wayne Roberts 0:d467d869e49c 289 if (duration > 1000000) {
Wayne Roberts 0:d467d869e49c 290 gAppDataSize = 0;
Wayne Roberts 0:d467d869e49c 291 AppData[gAppDataSize++] = 0;
Wayne Roberts 0:d467d869e49c 292 return;
Wayne Roberts 0:d467d869e49c 293 }
Wayne Roberts 0:d467d869e49c 294 }
Wayne Roberts 0:d467d869e49c 295
Wayne Roberts 0:d467d869e49c 296 gps.service();
Wayne Roberts 0:d467d869e49c 297
Wayne Roberts 0:d467d869e49c 298 lat = gps.Latitude * 10000;
Wayne Roberts 0:d467d869e49c 299 lon = gps.Longitude * 10000;
Wayne Roberts 0:d467d869e49c 300 alt = atoi(gps.NmeaGpsData.NmeaAltitude) * 100;
Wayne Roberts 0:d467d869e49c 301
Wayne Roberts 0:d467d869e49c 302 gAppDataSize = 0;
Wayne Roberts 0:d467d869e49c 303 AppData[gAppDataSize++] = CAYENNE_CH_GPS;
Wayne Roberts 0:d467d869e49c 304 AppData[gAppDataSize++] = LPP_GPS;
Wayne Roberts 0:d467d869e49c 305 AppData[gAppDataSize++] = lat >> 16;
Wayne Roberts 0:d467d869e49c 306 AppData[gAppDataSize++] = lat >> 8;
Wayne Roberts 0:d467d869e49c 307 AppData[gAppDataSize++] = lat;
Wayne Roberts 0:d467d869e49c 308 AppData[gAppDataSize++] = lon >> 16;
Wayne Roberts 0:d467d869e49c 309 AppData[gAppDataSize++] = lon >> 8;
Wayne Roberts 0:d467d869e49c 310 AppData[gAppDataSize++] = lon;
Wayne Roberts 0:d467d869e49c 311 AppData[gAppDataSize++] = alt >> 16;
Wayne Roberts 0:d467d869e49c 312 AppData[gAppDataSize++] = alt >> 8;
Wayne Roberts 0:d467d869e49c 313 AppData[gAppDataSize++] = alt;
Wayne Roberts 0:d467d869e49c 314 }
Wayne Roberts 0:d467d869e49c 315
Wayne Roberts 0:d467d869e49c 316
Wayne Roberts 0:d467d869e49c 317 /*!
Wayne Roberts 0:d467d869e49c 318 * \brief Prepares the payload of the frame
Wayne Roberts 0:d467d869e49c 319 *
Wayne Roberts 0:d467d869e49c 320 * \retval [0: frame could be send, 1: error]
Wayne Roberts 0:d467d869e49c 321 */
Wayne Roberts 0:d467d869e49c 322 static LoRaMacStatus_t SendFrame(bool IsTxConfirmed, uint8_t AppDataSize)
Wayne Roberts 0:d467d869e49c 323 {
Wayne Roberts 0:d467d869e49c 324 LoRaMacStatus_t status;
Wayne Roberts 0:d467d869e49c 325 char str[64];
Wayne Roberts 0:d467d869e49c 326 McpsReq_t mcpsReq;
Wayne Roberts 0:d467d869e49c 327 LoRaMacTxInfo_t txInfo;
Wayne Roberts 0:d467d869e49c 328
Wayne Roberts 0:d467d869e49c 329 if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK )
Wayne Roberts 0:d467d869e49c 330 {
Wayne Roberts 0:d467d869e49c 331 // Send empty frame in order to flush MAC commands
Wayne Roberts 0:d467d869e49c 332 mcpsReq.Type = MCPS_UNCONFIRMED;
Wayne Roberts 0:d467d869e49c 333 mcpsReq.Req.fBuffer = NULL;
Wayne Roberts 0:d467d869e49c 334 mcpsReq.Req.fBufferSize = 0;
Wayne Roberts 0:d467d869e49c 335 mcpsReq.Req.Datarate = LORAWAN_DEFAULT_DATARATE;
Wayne Roberts 0:d467d869e49c 336 }
Wayne Roberts 0:d467d869e49c 337 else
Wayne Roberts 0:d467d869e49c 338 {
Wayne Roberts 0:d467d869e49c 339 if( IsTxConfirmed == false )
Wayne Roberts 0:d467d869e49c 340 {
Wayne Roberts 0:d467d869e49c 341 mcpsReq.Type = MCPS_UNCONFIRMED;
Wayne Roberts 0:d467d869e49c 342 mcpsReq.Req.fPort = AppPort;
Wayne Roberts 0:d467d869e49c 343 mcpsReq.Req.fBuffer = AppData;
Wayne Roberts 0:d467d869e49c 344 mcpsReq.Req.fBufferSize = AppDataSize;
Wayne Roberts 0:d467d869e49c 345 mcpsReq.Req.Datarate = LORAWAN_DEFAULT_DATARATE;
Wayne Roberts 0:d467d869e49c 346 }
Wayne Roberts 0:d467d869e49c 347 else
Wayne Roberts 0:d467d869e49c 348 {
Wayne Roberts 0:d467d869e49c 349 mcpsReq.Type = MCPS_CONFIRMED;
Wayne Roberts 0:d467d869e49c 350 mcpsReq.Req.fPort = AppPort;
Wayne Roberts 0:d467d869e49c 351 mcpsReq.Req.fBuffer = AppData;
Wayne Roberts 0:d467d869e49c 352 mcpsReq.Req.fBufferSize = AppDataSize;
Wayne Roberts 0:d467d869e49c 353 mcpsReq.Req.Datarate = LORAWAN_DEFAULT_DATARATE;
Wayne Roberts 0:d467d869e49c 354 }
Wayne Roberts 0:d467d869e49c 355 }
Wayne Roberts 0:d467d869e49c 356
Wayne Roberts 0:d467d869e49c 357 status = LoRaMacMcpsRequest( &mcpsReq );
Wayne Roberts 0:d467d869e49c 358 if (status == LORAMAC_STATUS_OK) {
Wayne Roberts 0:d467d869e49c 359 APP_PRINTF("sendFrame() OK ");
Wayne Roberts 0:d467d869e49c 360 if (mcpsReq.Req.fBufferSize > 0) {
Wayne Roberts 0:d467d869e49c 361 APP_PRINTF("FPort%u ", mcpsReq.Req.fPort);
Wayne Roberts 0:d467d869e49c 362 print_buf(AppData, mcpsReq.Req.fBufferSize, "uplink");
Wayne Roberts 0:d467d869e49c 363 }
Wayne Roberts 0:d467d869e49c 364 } else {
Wayne Roberts 0:d467d869e49c 365 LoRaMacStatus_to_string(status, str);
Wayne Roberts 0:d467d869e49c 366 APP_PRINTF("sendFrame() \e[31m%s rx%d\r\n", str, LoRaMacGetRxSlot());
Wayne Roberts 0:d467d869e49c 367 }
Wayne Roberts 0:d467d869e49c 368
Wayne Roberts 0:d467d869e49c 369 return status;
Wayne Roberts 0:d467d869e49c 370 } // ..SendFrame()
Wayne Roberts 0:d467d869e49c 371
Wayne Roberts 0:d467d869e49c 372 #define ACK_DEFER_US 800000
Wayne Roberts 0:d467d869e49c 373 void ack_isr()
Wayne Roberts 0:d467d869e49c 374 {
Wayne Roberts 0:d467d869e49c 375 SendFrame(false, 0);
Wayne Roberts 0:d467d869e49c 376 }
Wayne Roberts 0:d467d869e49c 377
Wayne Roberts 0:d467d869e49c 378 /*!
Wayne Roberts 0:d467d869e49c 379 * \brief MCPS-Confirm event function
Wayne Roberts 0:d467d869e49c 380 *
Wayne Roberts 0:d467d869e49c 381 * \param [IN] mcpsConfirm - Pointer to the confirm structure,
Wayne Roberts 0:d467d869e49c 382 * containing confirm attributes.
Wayne Roberts 0:d467d869e49c 383 */
Wayne Roberts 0:d467d869e49c 384 static void McpsConfirm( const McpsConfirm_t *mcpsConfirm )
Wayne Roberts 0:d467d869e49c 385 {
Wayne Roberts 0:d467d869e49c 386 char str[64];
Wayne Roberts 0:d467d869e49c 387
Wayne Roberts 0:d467d869e49c 388 APP_PRINTF("McpsConfirm up:%" PRIu32 "hz ", mcpsConfirm->UpLinkFreqHz);
Wayne Roberts 0:d467d869e49c 389 LoRaMacEventInfoStatus_to_string(mcpsConfirm->Status, str);
Wayne Roberts 0:d467d869e49c 390 if (mcpsConfirm->AckReceived)
Wayne Roberts 0:d467d869e49c 391 APP_PRINTF("Ack ");
Wayne Roberts 0:d467d869e49c 392 APP_PRINTF("dr%u FCntUp:%" PRIu32 " ", mcpsConfirm->Datarate, mcpsConfirm->UpLinkCounter);
Wayne Roberts 0:d467d869e49c 393 if (mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK) {
Wayne Roberts 0:d467d869e49c 394 APP_PRINTF("%s\r\n", str);
Wayne Roberts 0:d467d869e49c 395 } else {
Wayne Roberts 0:d467d869e49c 396 APP_PRINTF("\e[31m%s\e[0m\r\n", str);
Wayne Roberts 0:d467d869e49c 397 }
Wayne Roberts 0:d467d869e49c 398
Wayne Roberts 0:d467d869e49c 399 if (mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK)
Wayne Roberts 0:d467d869e49c 400 {
Wayne Roberts 0:d467d869e49c 401 switch( mcpsConfirm->McpsRequest )
Wayne Roberts 0:d467d869e49c 402 {
Wayne Roberts 0:d467d869e49c 403 case MCPS_UNCONFIRMED:
Wayne Roberts 0:d467d869e49c 404 {
Wayne Roberts 0:d467d869e49c 405 // Check Datarate
Wayne Roberts 0:d467d869e49c 406 // Check TxPower
Wayne Roberts 0:d467d869e49c 407 break;
Wayne Roberts 0:d467d869e49c 408 }
Wayne Roberts 0:d467d869e49c 409 case MCPS_CONFIRMED:
Wayne Roberts 0:d467d869e49c 410 {
Wayne Roberts 0:d467d869e49c 411 // Check Datarate
Wayne Roberts 0:d467d869e49c 412 // Check TxPower
Wayne Roberts 0:d467d869e49c 413 // Check AckReceived
Wayne Roberts 0:d467d869e49c 414 // Check NbTrials
Wayne Roberts 0:d467d869e49c 415 //LoRaMacUplinkStatus.Acked = mcpsConfirm->AckReceived;
Wayne Roberts 0:d467d869e49c 416 break;
Wayne Roberts 0:d467d869e49c 417 }
Wayne Roberts 0:d467d869e49c 418 case MCPS_PROPRIETARY:
Wayne Roberts 0:d467d869e49c 419 {
Wayne Roberts 0:d467d869e49c 420 break;
Wayne Roberts 0:d467d869e49c 421 }
Wayne Roberts 0:d467d869e49c 422 default:
Wayne Roberts 0:d467d869e49c 423 break;
Wayne Roberts 0:d467d869e49c 424 }
Wayne Roberts 0:d467d869e49c 425 DeviceState = DEVICE_STATE_SLEEP;
Wayne Roberts 0:d467d869e49c 426 } else {
Wayne Roberts 0:d467d869e49c 427 /* fail */
Wayne Roberts 0:d467d869e49c 428 DeviceState = DEVICE_STATE_SLEEP;
Wayne Roberts 0:d467d869e49c 429
Wayne Roberts 0:d467d869e49c 430 #if 0
Wayne Roberts 0:d467d869e49c 431 if (flags.startup && mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT) {
Wayne Roberts 0:d467d869e49c 432 }
Wayne Roberts 0:d467d869e49c 433 #endif /* if 0 */
Wayne Roberts 0:d467d869e49c 434 }
Wayne Roberts 0:d467d869e49c 435
Wayne Roberts 0:d467d869e49c 436 } // ..McpsConfirm()
Wayne Roberts 0:d467d869e49c 437
Wayne Roberts 0:d467d869e49c 438
Wayne Roberts 0:d467d869e49c 439 /*!
Wayne Roberts 0:d467d869e49c 440 * \brief MCPS-Indication event function
Wayne Roberts 0:d467d869e49c 441 *
Wayne Roberts 0:d467d869e49c 442 * \param [IN] mcpsIndication - Pointer to the indication structure,
Wayne Roberts 0:d467d869e49c 443 * containing indication attributes.
Wayne Roberts 0:d467d869e49c 444 */
Wayne Roberts 0:d467d869e49c 445 static void McpsIndication( const McpsIndication_t *mcpsIndication )
Wayne Roberts 0:d467d869e49c 446 {
Wayne Roberts 0:d467d869e49c 447 char str[64];
Wayne Roberts 0:d467d869e49c 448 int8_t Snr;
Wayne Roberts 0:d467d869e49c 449
Wayne Roberts 0:d467d869e49c 450 APP_PRINTF("McpsIndication rx%d ADR_ACK_CNT:%u ", mcpsIndication->RxSlot, mcpsIndication->ADR_ACK_CNT);
Wayne Roberts 0:d467d869e49c 451
Wayne Roberts 0:d467d869e49c 452 if (mcpsIndication->Snr & 0x80) { // The SNR sign bit is 1
Wayne Roberts 0:d467d869e49c 453 // Invert and divide by 4
Wayne Roberts 0:d467d869e49c 454 Snr = ( ( ~mcpsIndication->Snr + 1 ) & 0xFF ) >> 2;
Wayne Roberts 0:d467d869e49c 455 Snr = -Snr;
Wayne Roberts 0:d467d869e49c 456 } else {
Wayne Roberts 0:d467d869e49c 457 // Divide by 4
Wayne Roberts 0:d467d869e49c 458 Snr = ( mcpsIndication->Snr & 0xFF ) >> 2;
Wayne Roberts 0:d467d869e49c 459 }
Wayne Roberts 0:d467d869e49c 460
Wayne Roberts 0:d467d869e49c 461 if (mcpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK)
Wayne Roberts 0:d467d869e49c 462 {
Wayne Roberts 0:d467d869e49c 463 LoRaMacEventInfoStatus_to_string(mcpsIndication->Status, str);
Wayne Roberts 0:d467d869e49c 464 APP_PRINTF("\e[31m%s\e[0m\r\n", str);
Wayne Roberts 0:d467d869e49c 465 return;
Wayne Roberts 0:d467d869e49c 466 }
Wayne Roberts 0:d467d869e49c 467 APP_PRINTF("OK Snr:%d FCntDown:%u\r\n", Snr, mcpsIndication->receivedFCntDown);
Wayne Roberts 0:d467d869e49c 468
Wayne Roberts 0:d467d869e49c 469 switch( mcpsIndication->McpsIndication )
Wayne Roberts 0:d467d869e49c 470 {
Wayne Roberts 0:d467d869e49c 471 case MCPS_UNCONFIRMED:
Wayne Roberts 0:d467d869e49c 472 {
Wayne Roberts 0:d467d869e49c 473 break;
Wayne Roberts 0:d467d869e49c 474 }
Wayne Roberts 0:d467d869e49c 475 case MCPS_CONFIRMED:
Wayne Roberts 0:d467d869e49c 476 {
Wayne Roberts 0:d467d869e49c 477 if (flags.ackDownlink) {
Wayne Roberts 0:d467d869e49c 478 tx_timeout.attach_us(ack_isr, ACK_DEFER_US);
Wayne Roberts 0:d467d869e49c 479 APP_PRINTF("confAck ");
Wayne Roberts 0:d467d869e49c 480 }
Wayne Roberts 0:d467d869e49c 481 break;
Wayne Roberts 0:d467d869e49c 482 }
Wayne Roberts 0:d467d869e49c 483 case MCPS_PROPRIETARY:
Wayne Roberts 0:d467d869e49c 484 {
Wayne Roberts 0:d467d869e49c 485 break;
Wayne Roberts 0:d467d869e49c 486 }
Wayne Roberts 0:d467d869e49c 487 case MCPS_MULTICAST:
Wayne Roberts 0:d467d869e49c 488 {
Wayne Roberts 0:d467d869e49c 489 break;
Wayne Roberts 0:d467d869e49c 490 }
Wayne Roberts 0:d467d869e49c 491 default:
Wayne Roberts 0:d467d869e49c 492 break;
Wayne Roberts 0:d467d869e49c 493 }
Wayne Roberts 0:d467d869e49c 494
Wayne Roberts 0:d467d869e49c 495 // Check Multicast
Wayne Roberts 0:d467d869e49c 496 // Check Port
Wayne Roberts 0:d467d869e49c 497 // Check Datarate
Wayne Roberts 0:d467d869e49c 498 // Check FramePending
Wayne Roberts 0:d467d869e49c 499 // Check Buffer
Wayne Roberts 0:d467d869e49c 500 // Check BufferSize
Wayne Roberts 0:d467d869e49c 501 // Check Rssi
Wayne Roberts 0:d467d869e49c 502 // Check Snr
Wayne Roberts 0:d467d869e49c 503 // Check RxSlot
Wayne Roberts 0:d467d869e49c 504
Wayne Roberts 0:d467d869e49c 505
Wayne Roberts 0:d467d869e49c 506 if( ComplianceTest.Running == true )
Wayne Roberts 0:d467d869e49c 507 {
Wayne Roberts 0:d467d869e49c 508 ComplianceTest.DownLinkCounter++;
Wayne Roberts 0:d467d869e49c 509 }
Wayne Roberts 0:d467d869e49c 510
Wayne Roberts 0:d467d869e49c 511 if (mcpsIndication->RxData)
Wayne Roberts 0:d467d869e49c 512 {
Wayne Roberts 0:d467d869e49c 513 APP_PRINTF("FPort%u ", mcpsIndication->Port);
Wayne Roberts 0:d467d869e49c 514 print_buf(mcpsIndication->Buffer, mcpsIndication->BufferSize, "");
Wayne Roberts 0:d467d869e49c 515 #ifdef TARGET_DISCO_L072CZ_LRWAN1
Wayne Roberts 0:d467d869e49c 516 if (mcpsIndication->Buffer[0])
Wayne Roberts 0:d467d869e49c 517 blue = LED_ON;
Wayne Roberts 0:d467d869e49c 518 else
Wayne Roberts 0:d467d869e49c 519 blue = LED_OFF;
Wayne Roberts 0:d467d869e49c 520 #endif /* TARGET_DISCO_L072CZ_LRWAN1 */
Wayne Roberts 0:d467d869e49c 521
Wayne Roberts 0:d467d869e49c 522 switch( mcpsIndication->Port )
Wayne Roberts 0:d467d869e49c 523 {
Wayne Roberts 0:d467d869e49c 524 case 1: // The application LED can be controlled on port 1 or 2
Wayne Roberts 0:d467d869e49c 525 case 2:
Wayne Roberts 0:d467d869e49c 526 break;
Wayne Roberts 0:d467d869e49c 527 case 224:
Wayne Roberts 0:d467d869e49c 528 if( ComplianceTest.Running == false )
Wayne Roberts 0:d467d869e49c 529 {
Wayne Roberts 0:d467d869e49c 530 // Check compliance test enable command (i)
Wayne Roberts 0:d467d869e49c 531 if( ( mcpsIndication->BufferSize == 4 ) &&
Wayne Roberts 0:d467d869e49c 532 ( mcpsIndication->Buffer[0] == 0x01 ) &&
Wayne Roberts 0:d467d869e49c 533 ( mcpsIndication->Buffer[1] == 0x01 ) &&
Wayne Roberts 0:d467d869e49c 534 ( mcpsIndication->Buffer[2] == 0x01 ) &&
Wayne Roberts 0:d467d869e49c 535 ( mcpsIndication->Buffer[3] == 0x01 ) )
Wayne Roberts 0:d467d869e49c 536 {
Wayne Roberts 0:d467d869e49c 537 gIsTxConfirmed = false;
Wayne Roberts 0:d467d869e49c 538 AppPort = 224;
Wayne Roberts 0:d467d869e49c 539 gAppDataSize = 2;
Wayne Roberts 0:d467d869e49c 540 ComplianceTest.DownLinkCounter = 0;
Wayne Roberts 0:d467d869e49c 541 ComplianceTest.LinkCheck = false;
Wayne Roberts 0:d467d869e49c 542 ComplianceTest.DemodMargin = 0;
Wayne Roberts 0:d467d869e49c 543 ComplianceTest.NbGateways = 0;
Wayne Roberts 0:d467d869e49c 544 ComplianceTest.Running = true;
Wayne Roberts 0:d467d869e49c 545 ComplianceTest.State = 1;
Wayne Roberts 0:d467d869e49c 546
Wayne Roberts 0:d467d869e49c 547 MibRequestConfirm_t mibReq;
Wayne Roberts 0:d467d869e49c 548 mibReq.Type = MIB_ADR;
Wayne Roberts 0:d467d869e49c 549 mibReq.Param.AdrEnable = true;
Wayne Roberts 0:d467d869e49c 550 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 551
Wayne Roberts 0:d467d869e49c 552 #if defined( USE_BAND_868 )
Wayne Roberts 0:d467d869e49c 553 DutyCycleOn = false;
Wayne Roberts 0:d467d869e49c 554 #endif
Wayne Roberts 0:d467d869e49c 555 }
Wayne Roberts 0:d467d869e49c 556 }
Wayne Roberts 0:d467d869e49c 557 else
Wayne Roberts 0:d467d869e49c 558 {
Wayne Roberts 0:d467d869e49c 559 ComplianceTest.State = mcpsIndication->Buffer[0];
Wayne Roberts 0:d467d869e49c 560 switch( ComplianceTest.State )
Wayne Roberts 0:d467d869e49c 561 {
Wayne Roberts 0:d467d869e49c 562 case 0: // Check compliance test disable command (ii)
Wayne Roberts 0:d467d869e49c 563 gIsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
Wayne Roberts 0:d467d869e49c 564 AppPort = LORAWAN_APP_PORT;
Wayne Roberts 0:d467d869e49c 565 gAppDataSize = LORAWAN_APP_DATA_SIZE;
Wayne Roberts 0:d467d869e49c 566 ComplianceTest.DownLinkCounter = 0;
Wayne Roberts 0:d467d869e49c 567 ComplianceTest.Running = false;
Wayne Roberts 0:d467d869e49c 568
Wayne Roberts 0:d467d869e49c 569 MibRequestConfirm_t mibReq;
Wayne Roberts 0:d467d869e49c 570 mibReq.Type = MIB_ADR;
Wayne Roberts 0:d467d869e49c 571 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
Wayne Roberts 0:d467d869e49c 572 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 573 #if defined( USE_BAND_868 )
Wayne Roberts 0:d467d869e49c 574 DutyCycleOn = LORAWAN_DUTYCYCLE_ON;
Wayne Roberts 0:d467d869e49c 575 #endif
Wayne Roberts 0:d467d869e49c 576 break;
Wayne Roberts 0:d467d869e49c 577 case 1: // (iii, iv)
Wayne Roberts 0:d467d869e49c 578 gAppDataSize = 2;
Wayne Roberts 0:d467d869e49c 579 break;
Wayne Roberts 0:d467d869e49c 580 case 2: // Enable confirmed messages (v)
Wayne Roberts 0:d467d869e49c 581 gIsTxConfirmed = true;
Wayne Roberts 0:d467d869e49c 582 ComplianceTest.State = 1;
Wayne Roberts 0:d467d869e49c 583 break;
Wayne Roberts 0:d467d869e49c 584 case 3: // Disable confirmed messages (vi)
Wayne Roberts 0:d467d869e49c 585 gIsTxConfirmed = false;
Wayne Roberts 0:d467d869e49c 586 ComplianceTest.State = 1;
Wayne Roberts 0:d467d869e49c 587 break;
Wayne Roberts 0:d467d869e49c 588 case 4: // (vii)
Wayne Roberts 0:d467d869e49c 589 gAppDataSize = mcpsIndication->BufferSize;
Wayne Roberts 0:d467d869e49c 590
Wayne Roberts 0:d467d869e49c 591 AppData[0] = 4;
Wayne Roberts 0:d467d869e49c 592 for( uint8_t i = 1; i < gAppDataSize; i++ )
Wayne Roberts 0:d467d869e49c 593 {
Wayne Roberts 0:d467d869e49c 594 AppData[i] = mcpsIndication->Buffer[i] + 1;
Wayne Roberts 0:d467d869e49c 595 }
Wayne Roberts 0:d467d869e49c 596 break;
Wayne Roberts 0:d467d869e49c 597 case 5: // (viii)
Wayne Roberts 0:d467d869e49c 598 {
Wayne Roberts 0:d467d869e49c 599 MlmeReq_t mlmeReq;
Wayne Roberts 0:d467d869e49c 600 mlmeReq.Type = MLME_LINK_CHECK;
Wayne Roberts 0:d467d869e49c 601 LoRaMacMlmeRequest( &mlmeReq );
Wayne Roberts 0:d467d869e49c 602 }
Wayne Roberts 0:d467d869e49c 603 break;
Wayne Roberts 0:d467d869e49c 604 case 6: // (ix)
Wayne Roberts 0:d467d869e49c 605 {
Wayne Roberts 0:d467d869e49c 606 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:d467d869e49c 607 MlmeReq_t mlmeReq = {};
Wayne Roberts 0:d467d869e49c 608
Wayne Roberts 0:d467d869e49c 609 // Disable TestMode and revert back to normal operation
Wayne Roberts 0:d467d869e49c 610 gIsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
Wayne Roberts 0:d467d869e49c 611 AppPort = LORAWAN_APP_PORT;
Wayne Roberts 0:d467d869e49c 612 gAppDataSize = LORAWAN_APP_DATA_SIZE;
Wayne Roberts 0:d467d869e49c 613 ComplianceTest.DownLinkCounter = 0;
Wayne Roberts 0:d467d869e49c 614 ComplianceTest.Running = false;
Wayne Roberts 0:d467d869e49c 615
Wayne Roberts 0:d467d869e49c 616 MibRequestConfirm_t mibReq;
Wayne Roberts 0:d467d869e49c 617 mibReq.Type = MIB_ADR;
Wayne Roberts 0:d467d869e49c 618 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
Wayne Roberts 0:d467d869e49c 619 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 620 #if defined( USE_BAND_868 )
Wayne Roberts 0:d467d869e49c 621 DutyCycleOn = LORAWAN_DUTYCYCLE_ON;
Wayne Roberts 0:d467d869e49c 622 #endif
Wayne Roberts 0:d467d869e49c 623
Wayne Roberts 0:d467d869e49c 624 mlmeReq.Type = MLME_JOIN;
Wayne Roberts 0:d467d869e49c 625
Wayne Roberts 0:d467d869e49c 626 mlmeReq.Req.Join.DevEui = DevEui;
Wayne Roberts 0:d467d869e49c 627 mlmeReq.Req.Join.JoinEui = JoinEui;
Wayne Roberts 0:d467d869e49c 628 mlmeReq.Req.Join.NwkKey = NwkKey;
Wayne Roberts 0:d467d869e49c 629 #ifdef LORAWAN_ROOT_APPKEY
Wayne Roberts 0:d467d869e49c 630 mlmeReq.Req.Join.AppKey = AppKey;
Wayne Roberts 0:d467d869e49c 631 #endif /* LORAWAN_ROOT_APPKEY */
Wayne Roberts 0:d467d869e49c 632
Wayne Roberts 0:d467d869e49c 633 LoRaMacMlmeRequest( &mlmeReq );
Wayne Roberts 0:d467d869e49c 634 #endif /* LORAWAN_JOIN_EUI */
Wayne Roberts 0:d467d869e49c 635 DeviceState = DEVICE_STATE_SLEEP;
Wayne Roberts 0:d467d869e49c 636 }
Wayne Roberts 0:d467d869e49c 637 break;
Wayne Roberts 0:d467d869e49c 638 case 7: // Switch end device Class
Wayne Roberts 0:d467d869e49c 639 {
Wayne Roberts 0:d467d869e49c 640 MlmeReq_t mlmeReq;
Wayne Roberts 0:d467d869e49c 641
Wayne Roberts 0:d467d869e49c 642 mlmeReq.Type = MLME_SWITCH_CLASS;
Wayne Roberts 0:d467d869e49c 643
Wayne Roberts 0:d467d869e49c 644 // CLASS_A = 0, CLASS_B = 1, CLASS_C = 2
Wayne Roberts 0:d467d869e49c 645 mlmeReq.Req.SwitchClass.Class = ( DeviceClass_t )mcpsIndication->Buffer[1];
Wayne Roberts 0:d467d869e49c 646
Wayne Roberts 0:d467d869e49c 647 LoRaMacMlmeRequest( &mlmeReq );
Wayne Roberts 0:d467d869e49c 648
Wayne Roberts 0:d467d869e49c 649 PrepareTxFrame( AppPort );
Wayne Roberts 0:d467d869e49c 650 /*status =*/ SendFrame(gIsTxConfirmed, gAppDataSize);
Wayne Roberts 0:d467d869e49c 651 }
Wayne Roberts 0:d467d869e49c 652 break;
Wayne Roberts 0:d467d869e49c 653 case 8: // Send PingSlotInfoReq
Wayne Roberts 0:d467d869e49c 654 {
Wayne Roberts 0:d467d869e49c 655 MlmeReq_t mlmeReq;
Wayne Roberts 0:d467d869e49c 656
Wayne Roberts 0:d467d869e49c 657 mlmeReq.Type = MLME_PING_SLOT_INFO;
Wayne Roberts 0:d467d869e49c 658
Wayne Roberts 0:d467d869e49c 659 mlmeReq.Req.PingSlotInfo.Value = mcpsIndication->Buffer[1];
Wayne Roberts 0:d467d869e49c 660
Wayne Roberts 0:d467d869e49c 661 LoRaMacMlmeRequest( &mlmeReq );
Wayne Roberts 0:d467d869e49c 662 PrepareTxFrame( AppPort );
Wayne Roberts 0:d467d869e49c 663 /*status =*/ SendFrame(gIsTxConfirmed, gAppDataSize);
Wayne Roberts 0:d467d869e49c 664 }
Wayne Roberts 0:d467d869e49c 665 break;
Wayne Roberts 0:d467d869e49c 666 case 9: // Send BeaconTimingReq
Wayne Roberts 0:d467d869e49c 667 {
Wayne Roberts 0:d467d869e49c 668 MlmeReq_t mlmeReq;
Wayne Roberts 0:d467d869e49c 669
Wayne Roberts 0:d467d869e49c 670 mlmeReq.Type = MLME_BEACON_TIMING;
Wayne Roberts 0:d467d869e49c 671
Wayne Roberts 0:d467d869e49c 672 LoRaMacMlmeRequest( &mlmeReq );
Wayne Roberts 0:d467d869e49c 673 PrepareTxFrame( AppPort );
Wayne Roberts 0:d467d869e49c 674 /*status =*/ SendFrame(gIsTxConfirmed, gAppDataSize);
Wayne Roberts 0:d467d869e49c 675 }
Wayne Roberts 0:d467d869e49c 676 break;
Wayne Roberts 0:d467d869e49c 677 default:
Wayne Roberts 0:d467d869e49c 678 break;
Wayne Roberts 0:d467d869e49c 679 }
Wayne Roberts 0:d467d869e49c 680 }
Wayne Roberts 0:d467d869e49c 681 break;
Wayne Roberts 0:d467d869e49c 682 default:
Wayne Roberts 0:d467d869e49c 683 break;
Wayne Roberts 0:d467d869e49c 684 }
Wayne Roberts 0:d467d869e49c 685
Wayne Roberts 0:d467d869e49c 686 }
Wayne Roberts 0:d467d869e49c 687
Wayne Roberts 0:d467d869e49c 688 } // ..McpsIndication()
Wayne Roberts 0:d467d869e49c 689
Wayne Roberts 0:d467d869e49c 690 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:d467d869e49c 691 void
Wayne Roberts 0:d467d869e49c 692 join(uint8_t tries)
Wayne Roberts 0:d467d869e49c 693 {
Wayne Roberts 0:d467d869e49c 694 char str[64];
Wayne Roberts 0:d467d869e49c 695 LoRaMacStatus_t status;
Wayne Roberts 0:d467d869e49c 696 MlmeReq_t mlmeReq = { };
Wayne Roberts 0:d467d869e49c 697
Wayne Roberts 0:d467d869e49c 698 mlmeReq.Type = MLME_JOIN;
Wayne Roberts 0:d467d869e49c 699
Wayne Roberts 0:d467d869e49c 700 #ifdef LORAWAN_ROOT_APPKEY
Wayne Roberts 0:d467d869e49c 701 mlmeReq.Req.Join.AppKey = AppKey;
Wayne Roberts 0:d467d869e49c 702 #endif
Wayne Roberts 0:d467d869e49c 703 mlmeReq.Req.Join.DevEui = DevEui;
Wayne Roberts 0:d467d869e49c 704 mlmeReq.Req.Join.JoinEui = JoinEui;
Wayne Roberts 0:d467d869e49c 705 mlmeReq.Req.Join.NwkKey = NwkKey;
Wayne Roberts 0:d467d869e49c 706 mlmeReq.Req.Join.NbTrials = tries;
Wayne Roberts 0:d467d869e49c 707 status = LoRaMacMlmeRequest( &mlmeReq );
Wayne Roberts 0:d467d869e49c 708 if (status != LORAMAC_STATUS_OK) {
Wayne Roberts 0:d467d869e49c 709 LoRaMacStatus_to_string(status, str);
Wayne Roberts 0:d467d869e49c 710 } else {
Wayne Roberts 0:d467d869e49c 711 extLed = 1;
Wayne Roberts 0:d467d869e49c 712 flags.startup = 1;
Wayne Roberts 0:d467d869e49c 713 }
Wayne Roberts 0:d467d869e49c 714 }
Wayne Roberts 0:d467d869e49c 715 #endif /* LORAWAN_JOIN_EUI */
Wayne Roberts 0:d467d869e49c 716
Wayne Roberts 0:d467d869e49c 717 /*!
Wayne Roberts 0:d467d869e49c 718 * \brief MLME-Confirm event function
Wayne Roberts 0:d467d869e49c 719 *
Wayne Roberts 0:d467d869e49c 720 * \param [IN] mlmeConfirm - Pointer to the confirm structure,
Wayne Roberts 0:d467d869e49c 721 * containing confirm attributes.
Wayne Roberts 0:d467d869e49c 722 */
Wayne Roberts 0:d467d869e49c 723 static void MlmeConfirm( const MlmeConfirm_t *mlmeConfirm )
Wayne Roberts 0:d467d869e49c 724 {
Wayne Roberts 0:d467d869e49c 725 char str[64];
Wayne Roberts 0:d467d869e49c 726 static uint8_t failCnt = 0;
Wayne Roberts 0:d467d869e49c 727
Wayne Roberts 0:d467d869e49c 728 Mlme_to_string(mlmeConfirm->MlmeRequest, str);
Wayne Roberts 0:d467d869e49c 729 APP_PRINTF("MlmeConfirm %s ", str);
Wayne Roberts 0:d467d869e49c 730 LoRaMacEventInfoStatus_to_string(mlmeConfirm->Status, str);
Wayne Roberts 0:d467d869e49c 731 if (mlmeConfirm->Status != LORAMAC_EVENT_INFO_STATUS_OK) {
Wayne Roberts 0:d467d869e49c 732 APP_PRINTF("\e[31m%s \e[0m\r\n", str);
Wayne Roberts 0:d467d869e49c 733 } else {
Wayne Roberts 0:d467d869e49c 734 APP_PRINTF("%s\r\n", str);
Wayne Roberts 0:d467d869e49c 735 }
Wayne Roberts 0:d467d869e49c 736
Wayne Roberts 0:d467d869e49c 737 #if defined(LORAWAN_ROOT_APPKEY) && defined(LORAWAN_JOIN_EUI)
Wayne Roberts 0:d467d869e49c 738 /* 1v1 joinNonce is incrementing non-volatile value */
Wayne Roberts 0:d467d869e49c 739 if (mlmeConfirm->MlmeRequest == MLME_JOIN) {
Wayne Roberts 0:d467d869e49c 740 vt.APP_PRINTF(" rxJoinNonce:%u vs %u",
Wayne Roberts 0:d467d869e49c 741 mlmeConfirm->fields.join.rxJoinNonce,
Wayne Roberts 0:d467d869e49c 742 mlmeConfirm->fields.join.myJoinNonce
Wayne Roberts 0:d467d869e49c 743 );
Wayne Roberts 0:d467d869e49c 744 }
Wayne Roberts 0:d467d869e49c 745 #endif /* LORAWAN_ROOT_APPKEY */
Wayne Roberts 0:d467d869e49c 746
Wayne Roberts 0:d467d869e49c 747 if (mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK)
Wayne Roberts 0:d467d869e49c 748 {
Wayne Roberts 0:d467d869e49c 749 failCnt = 0;
Wayne Roberts 0:d467d869e49c 750 switch (mlmeConfirm->MlmeRequest)
Wayne Roberts 0:d467d869e49c 751 {
Wayne Roberts 0:d467d869e49c 752 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:d467d869e49c 753 case MLME_JOIN:
Wayne Roberts 0:d467d869e49c 754 {
Wayne Roberts 0:d467d869e49c 755 // Status is OK, node has joined the network
Wayne Roberts 0:d467d869e49c 756 /* collect any mac cmds from server until expected channel mask */
Wayne Roberts 0:d467d869e49c 757 extLed = 0;
Wayne Roberts 0:d467d869e49c 758 DeviceState = DEVICE_STATE_JOIN_OK;
Wayne Roberts 0:d467d869e49c 759 break;
Wayne Roberts 0:d467d869e49c 760 }
Wayne Roberts 0:d467d869e49c 761 #endif /* LORAWAN_JOIN_EUI*/
Wayne Roberts 0:d467d869e49c 762 case MLME_LINK_CHECK:
Wayne Roberts 0:d467d869e49c 763 {
Wayne Roberts 0:d467d869e49c 764 // Check DemodMargin
Wayne Roberts 0:d467d869e49c 765 // Check NbGateways
Wayne Roberts 0:d467d869e49c 766 if( ComplianceTest.Running == true )
Wayne Roberts 0:d467d869e49c 767 {
Wayne Roberts 0:d467d869e49c 768 ComplianceTest.LinkCheck = true;
Wayne Roberts 0:d467d869e49c 769 ComplianceTest.DemodMargin = mlmeConfirm->fields.link.DemodMargin;
Wayne Roberts 0:d467d869e49c 770 ComplianceTest.NbGateways = mlmeConfirm->fields.link.NbGateways;
Wayne Roberts 0:d467d869e49c 771 }
Wayne Roberts 0:d467d869e49c 772 break;
Wayne Roberts 0:d467d869e49c 773 }
Wayne Roberts 0:d467d869e49c 774 case MLME_TIME_REQ:
Wayne Roberts 0:d467d869e49c 775 break;
Wayne Roberts 0:d467d869e49c 776 default:
Wayne Roberts 0:d467d869e49c 777 /* TODO: handle unknown MLME request */
Wayne Roberts 0:d467d869e49c 778 DeviceState = DEVICE_STATE_SLEEP;
Wayne Roberts 0:d467d869e49c 779 break;
Wayne Roberts 0:d467d869e49c 780 }
Wayne Roberts 0:d467d869e49c 781 }
Wayne Roberts 0:d467d869e49c 782 else // not ok...
Wayne Roberts 0:d467d869e49c 783 {
Wayne Roberts 0:d467d869e49c 784 failCnt++;
Wayne Roberts 0:d467d869e49c 785
Wayne Roberts 0:d467d869e49c 786 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:d467d869e49c 787 if (failCnt > 5) {
Wayne Roberts 0:d467d869e49c 788 join(1);
Wayne Roberts 0:d467d869e49c 789 return;
Wayne Roberts 0:d467d869e49c 790 }
Wayne Roberts 0:d467d869e49c 791 #endif
Wayne Roberts 0:d467d869e49c 792
Wayne Roberts 0:d467d869e49c 793 switch( mlmeConfirm->MlmeRequest )
Wayne Roberts 0:d467d869e49c 794 {
Wayne Roberts 0:d467d869e49c 795 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:d467d869e49c 796 case MLME_JOIN:
Wayne Roberts 0:d467d869e49c 797 {
Wayne Roberts 0:d467d869e49c 798 // Join failed, restart join procedure
Wayne Roberts 0:d467d869e49c 799 break;
Wayne Roberts 0:d467d869e49c 800 }
Wayne Roberts 0:d467d869e49c 801 #endif /* LORAWAN_JOIN_EUI */
Wayne Roberts 0:d467d869e49c 802 case MLME_LINK_CHECK:
Wayne Roberts 0:d467d869e49c 803 DeviceState = DEVICE_STATE_SLEEP;
Wayne Roberts 0:d467d869e49c 804 break;
Wayne Roberts 0:d467d869e49c 805 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:d467d869e49c 806 case MLME_REJOIN_0:
Wayne Roberts 0:d467d869e49c 807 break;
Wayne Roberts 0:d467d869e49c 808 case MLME_REJOIN_2:
Wayne Roberts 0:d467d869e49c 809 break;
Wayne Roberts 0:d467d869e49c 810 case MLME_TIME_REQ:
Wayne Roberts 0:d467d869e49c 811 break;
Wayne Roberts 0:d467d869e49c 812 #endif /* LORAWAN_JOIN_EUI */
Wayne Roberts 0:d467d869e49c 813 default:
Wayne Roberts 0:d467d869e49c 814 DeviceState = DEVICE_STATE_SLEEP;
Wayne Roberts 0:d467d869e49c 815 break;
Wayne Roberts 0:d467d869e49c 816 }
Wayne Roberts 0:d467d869e49c 817 }
Wayne Roberts 0:d467d869e49c 818 } // ..MlmeConfirm
Wayne Roberts 0:d467d869e49c 819
Wayne Roberts 0:d467d869e49c 820 static void MlmeIndication( const MlmeIndication_t *MlmeIndication )
Wayne Roberts 0:d467d869e49c 821 {
Wayne Roberts 0:d467d869e49c 822 char str[48];
Wayne Roberts 0:d467d869e49c 823 MibRequestConfirm_t mibReq;
Wayne Roberts 0:d467d869e49c 824
Wayne Roberts 0:d467d869e49c 825 Mlme_to_string(MlmeIndication->MlmeIndication, str);
Wayne Roberts 0:d467d869e49c 826 APP_PRINTF("MlmeIndication %s ", str);
Wayne Roberts 0:d467d869e49c 827 LoRaMacEventInfoStatus_to_string(MlmeIndication->Status, str);
Wayne Roberts 0:d467d869e49c 828 if (MlmeIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK) {
Wayne Roberts 0:d467d869e49c 829 APP_PRINTF("\e[31m%s \e[0m\r\n", str);
Wayne Roberts 0:d467d869e49c 830 } else {
Wayne Roberts 0:d467d869e49c 831 APP_PRINTF("%s\r\n", str);
Wayne Roberts 0:d467d869e49c 832 }
Wayne Roberts 0:d467d869e49c 833
Wayne Roberts 0:d467d869e49c 834 switch( MlmeIndication->MlmeIndication )
Wayne Roberts 0:d467d869e49c 835 {
Wayne Roberts 0:d467d869e49c 836 case MLME_SWITCH_CLASS:
Wayne Roberts 0:d467d869e49c 837 {
Wayne Roberts 0:d467d869e49c 838 /* mac gave up on beacon */
Wayne Roberts 0:d467d869e49c 839 mibReq.Type = MIB_DEVICE_CLASS;
Wayne Roberts 0:d467d869e49c 840 mibReq.Param.Class = CLASS_A;
Wayne Roberts 0:d467d869e49c 841 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 842
Wayne Roberts 0:d467d869e49c 843 // Switch to class A again
Wayne Roberts 0:d467d869e49c 844 DeviceState = DEVICE_STATE_SLEEP; // class-B manual switch
Wayne Roberts 0:d467d869e49c 845 break;
Wayne Roberts 0:d467d869e49c 846 }
Wayne Roberts 0:d467d869e49c 847 case MLME_BEACON:
Wayne Roberts 0:d467d869e49c 848 {
Wayne Roberts 0:d467d869e49c 849 LoRaMacEventInfoStatus_to_string(MlmeIndication->Status, str);
Wayne Roberts 0:d467d869e49c 850 break;
Wayne Roberts 0:d467d869e49c 851
Wayne Roberts 0:d467d869e49c 852 }
Wayne Roberts 0:d467d869e49c 853 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:d467d869e49c 854 case MLME_JOIN:
Wayne Roberts 0:d467d869e49c 855 APP_PRINTF("%" PRIu32 "hz try%u ", MlmeIndication->freqHz, MlmeIndication->JoinRequestTrials);
Wayne Roberts 0:d467d869e49c 856 break;
Wayne Roberts 0:d467d869e49c 857 #endif /* !LORAWAN_JOIN_EUI */
Wayne Roberts 0:d467d869e49c 858 default:
Wayne Roberts 0:d467d869e49c 859 break;
Wayne Roberts 0:d467d869e49c 860 }
Wayne Roberts 0:d467d869e49c 861
Wayne Roberts 0:d467d869e49c 862 } // ..MlmeIndication()
Wayne Roberts 0:d467d869e49c 863
Wayne Roberts 0:d467d869e49c 864 uint8_t periodicity;
Wayne Roberts 0:d467d869e49c 865
Wayne Roberts 0:d467d869e49c 866
Wayne Roberts 0:d467d869e49c 867 void SerialRxProcess( void )
Wayne Roberts 0:d467d869e49c 868 {
Wayne Roberts 0:d467d869e49c 869 char str[48];
Wayne Roberts 0:d467d869e49c 870 MibRequestConfirm_t mibReq;
Wayne Roberts 0:d467d869e49c 871 LoRaMacStatus_t status;
Wayne Roberts 0:d467d869e49c 872 MlmeReq_t mlmeReq;
Wayne Roberts 0:d467d869e49c 873 #ifndef LORAWAN_JOIN_EUI
Wayne Roberts 0:d467d869e49c 874 static uint8_t icnt = 0;
Wayne Roberts 0:d467d869e49c 875 #endif
Wayne Roberts 0:d467d869e49c 876
Wayne Roberts 0:d467d869e49c 877 if( pc.readable( ) == true ) {
Wayne Roberts 0:d467d869e49c 878 char ch = pc.getc();
Wayne Roberts 0:d467d869e49c 879 #ifndef LORAWAN_JOIN_EUI
Wayne Roberts 0:d467d869e49c 880 if (ch == 'I') {
Wayne Roberts 0:d467d869e49c 881 if (++icnt == 3) {
Wayne Roberts 0:d467d869e49c 882 APP_PRINTF("reset-fcnts\r\n");
Wayne Roberts 0:d467d869e49c 883 eeprom_clear(EEPROM_AFCNTDWN);
Wayne Roberts 0:d467d869e49c 884 eeprom_clear(EEPROM_NFCNTDWN);
Wayne Roberts 0:d467d869e49c 885 eeprom_clear(EEPROM_FCNTUP);
Wayne Roberts 0:d467d869e49c 886 }
Wayne Roberts 0:d467d869e49c 887 } else
Wayne Roberts 0:d467d869e49c 888 icnt = 0;
Wayne Roberts 0:d467d869e49c 889 #endif /* !LORAWAN_JOIN_EUI */
Wayne Roberts 0:d467d869e49c 890
Wayne Roberts 0:d467d869e49c 891 if ( ch >= '0' && ch <= '9') {
Wayne Roberts 0:d467d869e49c 892 c_ch = ch - '0';
Wayne Roberts 0:d467d869e49c 893 DeviceState = DEVICE_STATE_SEND;
Wayne Roberts 0:d467d869e49c 894 return;
Wayne Roberts 0:d467d869e49c 895 }
Wayne Roberts 0:d467d869e49c 896 switch( ch ) {
Wayne Roberts 0:d467d869e49c 897 case 'L':
Wayne Roberts 0:d467d869e49c 898 mlmeReq.Type = MLME_LINK_CHECK;
Wayne Roberts 0:d467d869e49c 899 status = LoRaMacMlmeRequest( &mlmeReq );
Wayne Roberts 0:d467d869e49c 900 if (status == LORAMAC_STATUS_OK)
Wayne Roberts 0:d467d869e49c 901 SendFrame(false, 0);
Wayne Roberts 0:d467d869e49c 902 else {
Wayne Roberts 0:d467d869e49c 903 LoRaMacStatus_to_string(status, str);
Wayne Roberts 0:d467d869e49c 904 APP_PRINTF("%s\r\n", str);
Wayne Roberts 0:d467d869e49c 905 }
Wayne Roberts 0:d467d869e49c 906 break;
Wayne Roberts 0:d467d869e49c 907 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:d467d869e49c 908 case 'j':
Wayne Roberts 0:d467d869e49c 909 DeviceState = DEVICE_STATE_JOIN;
Wayne Roberts 0:d467d869e49c 910 break;
Wayne Roberts 0:d467d869e49c 911 #endif
Wayne Roberts 0:d467d869e49c 912 case 'a':
Wayne Roberts 0:d467d869e49c 913 flags.ackDownlink ^= 1;
Wayne Roberts 0:d467d869e49c 914 APP_PRINTF("ackDownlink:%u\r\n", flags.ackDownlink);
Wayne Roberts 0:d467d869e49c 915 break;
Wayne Roberts 0:d467d869e49c 916 case '.':
Wayne Roberts 0:d467d869e49c 917 uint16_t altitudeGps;
Wayne Roberts 0:d467d869e49c 918 print_buf(DevEui, 8, "DevEui");
Wayne Roberts 0:d467d869e49c 919 mibReq.Type = MIB_DEV_ADDR;
Wayne Roberts 0:d467d869e49c 920 LoRaMacMibGetRequestConfirm( &mibReq );
Wayne Roberts 2:fdd36ff9b181 921 APP_PRINTF("DevAddr:%08lx ", mibReq.Param.DevAddr);
Wayne Roberts 0:d467d869e49c 922 mibReq.Type = MIB_RX2_CHANNEL;
Wayne Roberts 0:d467d869e49c 923 LoRaMacMibGetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 924 APP_PRINTF(" rx2 %uhz dr%u, ackDownlink:%u\r\n", mibReq.Param.Rx2Channel.FrequencyHz, mibReq.Param.Rx2Channel.Datarate, flags.ackDownlink);
Wayne Roberts 0:d467d869e49c 925 LoRaMacPrintStatus();
Wayne Roberts 0:d467d869e49c 926 gps.service();
Wayne Roberts 2:fdd36ff9b181 927 str[0] = gps.NmeaGpsData.NmeaUtcTime[0]; // hour
Wayne Roberts 2:fdd36ff9b181 928 str[1] = gps.NmeaGpsData.NmeaUtcTime[1];
Wayne Roberts 2:fdd36ff9b181 929 str[2] = ':';
Wayne Roberts 2:fdd36ff9b181 930 str[3] = gps.NmeaGpsData.NmeaUtcTime[2]; // minute
Wayne Roberts 2:fdd36ff9b181 931 str[4] = gps.NmeaGpsData.NmeaUtcTime[3];
Wayne Roberts 2:fdd36ff9b181 932 str[5] = ':';
Wayne Roberts 2:fdd36ff9b181 933 str[6] = gps.NmeaGpsData.NmeaUtcTime[4]; // second
Wayne Roberts 2:fdd36ff9b181 934 str[7] = gps.NmeaGpsData.NmeaUtcTime[5];
Wayne Roberts 2:fdd36ff9b181 935 str[8] = 'Z';
Wayne Roberts 2:fdd36ff9b181 936 str[9] = 0;
Wayne Roberts 2:fdd36ff9b181 937 APP_PRINTF("%s ", str);
Wayne Roberts 0:d467d869e49c 938 altitudeGps = atoi( gps.NmeaGpsData.NmeaAltitude );
Wayne Roberts 0:d467d869e49c 939 APP_PRINTF("gps %f, %f, %d\r\n", gps.Latitude, gps.Longitude, altitudeGps);
Wayne Roberts 0:d467d869e49c 940 break;
Wayne Roberts 0:d467d869e49c 941 case '?':
Wayne Roberts 0:d467d869e49c 942 APP_PRINTF("C start classC\r\n");
Wayne Roberts 0:d467d869e49c 943 APP_PRINTF("L send link check\r\n");
Wayne Roberts 0:d467d869e49c 944 APP_PRINTF("j send joinReq\r\n");
Wayne Roberts 0:d467d869e49c 945 APP_PRINTF("a toggle ackDownlink\r\n");
Wayne Roberts 0:d467d869e49c 946 APP_PRINTF(". print status\r\n");
Wayne Roberts 0:d467d869e49c 947 break;
Wayne Roberts 0:d467d869e49c 948 default:
Wayne Roberts 0:d467d869e49c 949 break;
Wayne Roberts 0:d467d869e49c 950 }
Wayne Roberts 0:d467d869e49c 951 }
Wayne Roberts 0:d467d869e49c 952 }
Wayne Roberts 0:d467d869e49c 953
Wayne Roberts 0:d467d869e49c 954 static void button_isr()
Wayne Roberts 0:d467d869e49c 955 {
Wayne Roberts 0:d467d869e49c 956 c_ch = 0xff;
Wayne Roberts 0:d467d869e49c 957 DeviceState = DEVICE_STATE_SEND;
Wayne Roberts 0:d467d869e49c 958 buttonStartAt = LoRaMacReadTimer();
Wayne Roberts 0:d467d869e49c 959 }
Wayne Roberts 0:d467d869e49c 960
Wayne Roberts 0:d467d869e49c 961 static const LoRaMacPrimitives_t LoRaMacPrimitives = {
Wayne Roberts 0:d467d869e49c 962 McpsConfirm,
Wayne Roberts 0:d467d869e49c 963 McpsIndication,
Wayne Roberts 0:d467d869e49c 964 MlmeConfirm,
Wayne Roberts 0:d467d869e49c 965 MlmeIndication
Wayne Roberts 0:d467d869e49c 966 };
Wayne Roberts 0:d467d869e49c 967
Wayne Roberts 0:d467d869e49c 968 static const LoRaMacCallback_t LoRaMacCallbacks = {
Wayne Roberts 0:d467d869e49c 969 BoardGetBatteryLevel,
Wayne Roberts 0:d467d869e49c 970 NULL
Wayne Roberts 0:d467d869e49c 971 };
Wayne Roberts 0:d467d869e49c 972
Wayne Roberts 0:d467d869e49c 973 /**
Wayne Roberts 0:d467d869e49c 974 * Main application entry point.
Wayne Roberts 0:d467d869e49c 975 */
Wayne Roberts 0:d467d869e49c 976 int main()
Wayne Roberts 0:d467d869e49c 977 {
Wayne Roberts 0:d467d869e49c 978 LoRaMacStatus_t status;
Wayne Roberts 0:d467d869e49c 979 MibRequestConfirm_t mibReq;
Wayne Roberts 0:d467d869e49c 980
Wayne Roberts 0:d467d869e49c 981 DeviceState = DEVICE_STATE_INIT;
Wayne Roberts 0:d467d869e49c 982
Wayne Roberts 0:d467d869e49c 983 if (sleep_manager_can_deep_sleep())
Wayne Roberts 0:d467d869e49c 984 sleep_manager_lock_deep_sleep(); // prevent deep sleep
Wayne Roberts 0:d467d869e49c 985
Wayne Roberts 0:d467d869e49c 986 #ifdef JUMPER_ENABLE
Wayne Roberts 0:d467d869e49c 987 jumper_out = 1;
Wayne Roberts 0:d467d869e49c 988 jumper_in.mode(PullDown);
Wayne Roberts 0:d467d869e49c 989 jumper_in.rise(jumper_callback);
Wayne Roberts 0:d467d869e49c 990 // Q: does InterruptIn.rise() call immediately if already high?
Wayne Roberts 0:d467d869e49c 991 if (jumper_in.read())
Wayne Roberts 0:d467d869e49c 992 jumper_callback(); // A: probably not
Wayne Roberts 0:d467d869e49c 993 #endif /* JUMPER_ENABLE */
Wayne Roberts 0:d467d869e49c 994
Wayne Roberts 0:d467d869e49c 995 gps.init();
Wayne Roberts 0:d467d869e49c 996
Wayne Roberts 0:d467d869e49c 997 while( 1 )
Wayne Roberts 0:d467d869e49c 998 {
Wayne Roberts 0:d467d869e49c 999 SerialRxProcess( );
Wayne Roberts 0:d467d869e49c 1000
Wayne Roberts 0:d467d869e49c 1001 switch( DeviceState )
Wayne Roberts 0:d467d869e49c 1002 {
Wayne Roberts 0:d467d869e49c 1003 case DEVICE_STATE_INIT:
Wayne Roberts 0:d467d869e49c 1004 {
Wayne Roberts 0:d467d869e49c 1005 status = LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks );
Wayne Roberts 0:d467d869e49c 1006 if (LORAMAC_STATUS_OK != status) {
Wayne Roberts 0:d467d869e49c 1007 char str[48];
Wayne Roberts 0:d467d869e49c 1008 LoRaMacStatus_to_string(status, str);
Wayne Roberts 0:d467d869e49c 1009 APP_PRINTF("MacInit: %s\r\n", str);
Wayne Roberts 0:d467d869e49c 1010 for (;;) asm("nop");
Wayne Roberts 0:d467d869e49c 1011 }
Wayne Roberts 0:d467d869e49c 1012
Wayne Roberts 0:d467d869e49c 1013 c_ch = 0xff;
Wayne Roberts 0:d467d869e49c 1014 button_pin.mode(PullDown);
Wayne Roberts 0:d467d869e49c 1015 #ifdef TARGET_DISCO_L072CZ_LRWAN1
Wayne Roberts 0:d467d869e49c 1016 button_pin.fall(button_isr);
Wayne Roberts 0:d467d869e49c 1017 #else
Wayne Roberts 0:d467d869e49c 1018 button_pin.rise(button_isr);
Wayne Roberts 0:d467d869e49c 1019 #endif
Wayne Roberts 0:d467d869e49c 1020
Wayne Roberts 0:d467d869e49c 1021 mibReq.Type = MIB_ADR;
Wayne Roberts 0:d467d869e49c 1022 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
Wayne Roberts 0:d467d869e49c 1023 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 1024
Wayne Roberts 0:d467d869e49c 1025 mibReq.Type = MIB_PUBLIC_NETWORK;
Wayne Roberts 0:d467d869e49c 1026 mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK;
Wayne Roberts 0:d467d869e49c 1027 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 1028
Wayne Roberts 0:d467d869e49c 1029 #if defined( USE_BAND_868 )
Wayne Roberts 0:d467d869e49c 1030 DutyCycleOn = LORAWAN_DUTYCYCLE_ON ;
Wayne Roberts 0:d467d869e49c 1031 #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 )
Wayne Roberts 0:d467d869e49c 1032 LoRaMacChannelAdd( 3, ( ChannelParams_t )LC4 );
Wayne Roberts 0:d467d869e49c 1033 LoRaMacChannelAdd( 4, ( ChannelParams_t )LC5 );
Wayne Roberts 0:d467d869e49c 1034 LoRaMacChannelAdd( 5, ( ChannelParams_t )LC6 );
Wayne Roberts 0:d467d869e49c 1035 LoRaMacChannelAdd( 6, ( ChannelParams_t )LC7 );
Wayne Roberts 0:d467d869e49c 1036 LoRaMacChannelAdd( 7, ( ChannelParams_t )LC8 );
Wayne Roberts 0:d467d869e49c 1037 LoRaMacChannelAdd( 8, ( ChannelParams_t )LC9 );
Wayne Roberts 0:d467d869e49c 1038 LoRaMacChannelAdd( 9, ( ChannelParams_t )LC10 );
Wayne Roberts 0:d467d869e49c 1039
Wayne Roberts 0:d467d869e49c 1040 mibReq.Type = MIB_RX2_CHANNEL;
Wayne Roberts 0:d467d869e49c 1041 mibReq.Param.Rx2Channel = ( Rx2ChannelParams_t ){ 869525000, DR_3 };
Wayne Roberts 0:d467d869e49c 1042 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 1043 #endif
Wayne Roberts 0:d467d869e49c 1044
Wayne Roberts 0:d467d869e49c 1045 #endif
Wayne Roberts 0:d467d869e49c 1046
Wayne Roberts 0:d467d869e49c 1047 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:d467d869e49c 1048
Wayne Roberts 0:d467d869e49c 1049 #ifndef SENETCO /* for senet, use network provided DevEUI */
Wayne Roberts 0:d467d869e49c 1050 // Initialize LoRaMac device unique ID
Wayne Roberts 0:d467d869e49c 1051 HardwareIDtoDevEUI(DevEui);
Wayne Roberts 0:d467d869e49c 1052 #ifdef LORAWAN_ROOT_APPKEY
Wayne Roberts 0:d467d869e49c 1053 // inverted DevEui provisioned as v1.1 on server (non-inv = lorawan1v0)
Wayne Roberts 0:d467d869e49c 1054 for (int i = 0; i < 8; i++)
Wayne Roberts 0:d467d869e49c 1055 DevEui[i] ^= 0xff;
Wayne Roberts 0:d467d869e49c 1056 #endif /* LORAWAN_ROOT_APPKEY */
Wayne Roberts 0:d467d869e49c 1057 #endif /* !SENETCO */
Wayne Roberts 0:d467d869e49c 1058 print_buf(DevEui, 8, "DevEui");
Wayne Roberts 0:d467d869e49c 1059 DeviceState = DEVICE_STATE_JOIN;
Wayne Roberts 0:d467d869e49c 1060 #else /* ABP... */
Wayne Roberts 0:d467d869e49c 1061
Wayne Roberts 0:d467d869e49c 1062 mibReq.Type = MIB_DEV_ADDR;
Wayne Roberts 0:d467d869e49c 1063 mibReq.Param.DevAddr = DevAddr;
Wayne Roberts 0:d467d869e49c 1064 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 1065 SerialDisplayUpdateDevAddr(DevAddr);
Wayne Roberts 0:d467d869e49c 1066
Wayne Roberts 0:d467d869e49c 1067 mibReq.Type = MIB_APP_SKEY;
Wayne Roberts 0:d467d869e49c 1068 mibReq.Param.key = AppSKey;
Wayne Roberts 0:d467d869e49c 1069 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 1070 SerialDisplayUpdateKey(ROW_AppSKey, AppSKey);
Wayne Roberts 0:d467d869e49c 1071
Wayne Roberts 0:d467d869e49c 1072 #if defined(LORAWAN_SNwkSIntKey) && defined(LORAWAN_NwkSEncKey)
Wayne Roberts 0:d467d869e49c 1073 /* lorawan 1v1 ABP */
Wayne Roberts 0:d467d869e49c 1074 mibReq.Type = MIB_NwkSEncKey;
Wayne Roberts 0:d467d869e49c 1075 mibReq.Param.key = NwkSEncKey;
Wayne Roberts 0:d467d869e49c 1076 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 1077 SerialDisplayUpdateKey(ROW_NwkSEncKey, NwkSEncKey);
Wayne Roberts 0:d467d869e49c 1078
Wayne Roberts 0:d467d869e49c 1079 mibReq.Type = MIB_SNwkSIntKey;
Wayne Roberts 0:d467d869e49c 1080 mibReq.Param.key = SNwkSIntKey;
Wayne Roberts 0:d467d869e49c 1081 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 1082 SerialDisplayUpdateKey(ROW_SNwkSIntKey, SNwkSIntKey);
Wayne Roberts 0:d467d869e49c 1083
Wayne Roberts 0:d467d869e49c 1084 mibReq.Type = MIB_FNwkSIntKey;
Wayne Roberts 0:d467d869e49c 1085 mibReq.Param.key = FNwkSIntKey;
Wayne Roberts 0:d467d869e49c 1086 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 1087 SerialDisplayUpdateKey(ROW_FNwkSIntKey, mibReq.Param.key);
Wayne Roberts 0:d467d869e49c 1088 #else
Wayne Roberts 0:d467d869e49c 1089 /* lorawan 1v0 ABP */
Wayne Roberts 0:d467d869e49c 1090 mibReq.Type = MIB_NwkSKey;
Wayne Roberts 0:d467d869e49c 1091 mibReq.Param.key = FNwkSIntKey;
Wayne Roberts 0:d467d869e49c 1092 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 1093 SerialDisplayUpdateKey(ROW_FNwkSIntKey, mibReq.Param.key);
Wayne Roberts 0:d467d869e49c 1094 #endif
Wayne Roberts 0:d467d869e49c 1095
Wayne Roberts 0:d467d869e49c 1096 DeviceState = DEVICE_STATE_SLEEP;
Wayne Roberts 0:d467d869e49c 1097 #endif /* !LORAWAN_JOIN_EUI */
Wayne Roberts 0:d467d869e49c 1098
Wayne Roberts 0:d467d869e49c 1099 #if defined( USE_BAND_ARIB_8CH )
Wayne Roberts 0:d467d869e49c 1100 mibReq.Type = MIB_MAX_LISTEN_TIME;
Wayne Roberts 0:d467d869e49c 1101 mibReq.Param.MaxListenTime = 7000000;
Wayne Roberts 0:d467d869e49c 1102 LoRaMacMibSetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 1103 #endif /* USE_BAND_ARIB_8CH */
Wayne Roberts 0:d467d869e49c 1104
Wayne Roberts 0:d467d869e49c 1105 flags.ackDownlink = 1;
Wayne Roberts 0:d467d869e49c 1106 flags.startup = 1;
Wayne Roberts 0:d467d869e49c 1107 break;
Wayne Roberts 0:d467d869e49c 1108 }
Wayne Roberts 0:d467d869e49c 1109 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:d467d869e49c 1110 case DEVICE_STATE_JOIN:
Wayne Roberts 0:d467d869e49c 1111 {
Wayne Roberts 0:d467d869e49c 1112 join(8);
Wayne Roberts 0:d467d869e49c 1113 DeviceState = DEVICE_STATE_SLEEP;
Wayne Roberts 0:d467d869e49c 1114 break;
Wayne Roberts 0:d467d869e49c 1115 }
Wayne Roberts 0:d467d869e49c 1116 case DEVICE_STATE_JOIN_OK:
Wayne Roberts 0:d467d869e49c 1117 MibRequestConfirm_t mibReq;
Wayne Roberts 0:d467d869e49c 1118 mibReq.Type = MIB_NETWORK_JOINED;
Wayne Roberts 0:d467d869e49c 1119 LoRaMacMibGetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 1120 if (mibReq.Param.IsNetworkJoined)
Wayne Roberts 0:d467d869e49c 1121 APP_PRINTF("joined ");
Wayne Roberts 0:d467d869e49c 1122 mibReq.Type = MIB_DEV_ADDR;
Wayne Roberts 0:d467d869e49c 1123 LoRaMacMibGetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 1124 APP_PRINTF("DevAddr:%08" PRIx32 "\r\n", mibReq.Param.DevAddr);
Wayne Roberts 0:d467d869e49c 1125 mibReq.Type = MIB_FNwkSIntKey;
Wayne Roberts 0:d467d869e49c 1126 LoRaMacMibGetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 1127 print_buf(mibReq.Param.key, 16, "FNwkSIntKey");
Wayne Roberts 0:d467d869e49c 1128 mibReq.Type = MIB_APP_SKEY;
Wayne Roberts 0:d467d869e49c 1129 LoRaMacMibGetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 1130 print_buf(mibReq.Param.key, 16, "AppSKey");
Wayne Roberts 0:d467d869e49c 1131
Wayne Roberts 0:d467d869e49c 1132 #ifdef LORAWAN_ROOT_APPKEY
Wayne Roberts 0:d467d869e49c 1133 mibReq.Type = MIB_SNwkSIntKey;
Wayne Roberts 0:d467d869e49c 1134 LoRaMacMibGetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 1135 SerialDisplayUpdateKey(ROW_SNwkSIntKey, mibReq.Param.key);
Wayne Roberts 0:d467d869e49c 1136 mibReq.Type = MIB_NwkSEncKey;
Wayne Roberts 0:d467d869e49c 1137 LoRaMacMibGetRequestConfirm( &mibReq );
Wayne Roberts 0:d467d869e49c 1138 SerialDisplayUpdateKey(ROW_NwkSEncKey, mibReq.Param.key);
Wayne Roberts 0:d467d869e49c 1139 #endif /* LORAWAN_ROOT_APPKEY */
Wayne Roberts 0:d467d869e49c 1140 DeviceState = DEVICE_STATE_SLEEP;
Wayne Roberts 0:d467d869e49c 1141 break;
Wayne Roberts 0:d467d869e49c 1142 #endif /* LORAWAN_JOIN_EUI */
Wayne Roberts 0:d467d869e49c 1143 case DEVICE_STATE_SEND:
Wayne Roberts 0:d467d869e49c 1144 PrepareTxFrame( AppPort );
Wayne Roberts 0:d467d869e49c 1145 status = SendFrame(gIsTxConfirmed, gAppDataSize);
Wayne Roberts 0:d467d869e49c 1146 if (status == LORAMAC_STATUS_OK) {
Wayne Roberts 0:d467d869e49c 1147 /* McpsConfirm or McpsIndication callback will continue */
Wayne Roberts 0:d467d869e49c 1148 }
Wayne Roberts 0:d467d869e49c 1149 DeviceState = DEVICE_STATE_SLEEP;
Wayne Roberts 0:d467d869e49c 1150 break;
Wayne Roberts 0:d467d869e49c 1151 case DEVICE_STATE_SLEEP:
Wayne Roberts 0:d467d869e49c 1152 {
Wayne Roberts 0:d467d869e49c 1153 // Wake up through events
Wayne Roberts 0:d467d869e49c 1154 sleep_manager_sleep_auto();
Wayne Roberts 0:d467d869e49c 1155 break;
Wayne Roberts 0:d467d869e49c 1156 }
Wayne Roberts 0:d467d869e49c 1157 default:
Wayne Roberts 0:d467d869e49c 1158 DeviceState = DEVICE_STATE_INIT;
Wayne Roberts 0:d467d869e49c 1159 break;
Wayne Roberts 0:d467d869e49c 1160 } // ..switch( DeviceState )
Wayne Roberts 0:d467d869e49c 1161
Wayne Roberts 0:d467d869e49c 1162 gps.service();
Wayne Roberts 0:d467d869e49c 1163
Wayne Roberts 0:d467d869e49c 1164 LoRaMacUserContext();
Wayne Roberts 0:d467d869e49c 1165 } // ..while( 1 )
Wayne Roberts 0:d467d869e49c 1166 }