LoRaWAN demo 76 bootcamp

Dependencies:   mbed DigitDisplay Chainable_RGB_LED LoRaWAN-lib SX1276Lib

Committer:
mluis
Date:
Tue Jul 05 15:02:26 2016 +0000
Revision:
3:de1dcfbe175a
Parent:
1:21e3eef8200f
Child:
5:d87bb1eabccd
Synchronized example application with GitHub LoRaMac-node examples; Updated mbed and LoRaWAN-lib libraries

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mluis 0:cb80564f40e1 1 /*
mluis 0:cb80564f40e1 2 / _____) _ | |
mluis 0:cb80564f40e1 3 ( (____ _____ ____ _| |_ _____ ____| |__
mluis 0:cb80564f40e1 4 \____ \| ___ | (_ _) ___ |/ ___) _ \
mluis 0:cb80564f40e1 5 _____) ) ____| | | || |_| ____( (___| | | |
mluis 0:cb80564f40e1 6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
mluis 0:cb80564f40e1 7 (C)2015 Semtech
mluis 0:cb80564f40e1 8
mluis 0:cb80564f40e1 9 Description: LoRaMac classA device implementation
mluis 0:cb80564f40e1 10
mluis 0:cb80564f40e1 11 License: Revised BSD License, see LICENSE.TXT file include in the project
mluis 0:cb80564f40e1 12
mluis 0:cb80564f40e1 13 Maintainer: Miguel Luis and Gregory Cristian
mluis 0:cb80564f40e1 14 */
mluis 0:cb80564f40e1 15 #include "mbed.h"
mluis 0:cb80564f40e1 16 #include "board.h"
mluis 0:cb80564f40e1 17 #include "radio.h"
mluis 0:cb80564f40e1 18
mluis 0:cb80564f40e1 19 #include "LoRaMac.h"
mluis 0:cb80564f40e1 20 #include "Comissioning.h"
mluis 0:cb80564f40e1 21 #include "SerialDisplay.h"
mluis 0:cb80564f40e1 22 #include "DigitDisplay.h"
mluis 0:cb80564f40e1 23 #include "ChainableLED.h"
mluis 0:cb80564f40e1 24
mluis 0:cb80564f40e1 25 /*!
mluis 0:cb80564f40e1 26 * Defines the application data transmission duty cycle. 5s, value in [us].
mluis 0:cb80564f40e1 27 */
mluis 0:cb80564f40e1 28 #define APP_TX_DUTYCYCLE 5000000
mluis 0:cb80564f40e1 29
mluis 0:cb80564f40e1 30 /*!
mluis 0:cb80564f40e1 31 * Defines a random delay for application data transmission duty cycle. 1s,
mluis 0:cb80564f40e1 32 * value in [us].
mluis 0:cb80564f40e1 33 */
mluis 0:cb80564f40e1 34 #define APP_TX_DUTYCYCLE_RND 1000000
mluis 0:cb80564f40e1 35
mluis 0:cb80564f40e1 36 /*!
mluis 1:21e3eef8200f 37 * Default datarate
mluis 0:cb80564f40e1 38 */
mluis 0:cb80564f40e1 39 #define LORAWAN_DEFAULT_DATARATE DR_5
mluis 0:cb80564f40e1 40
mluis 0:cb80564f40e1 41 /*!
mluis 0:cb80564f40e1 42 * LoRaWAN confirmed messages
mluis 0:cb80564f40e1 43 */
mluis 0:cb80564f40e1 44 #define LORAWAN_CONFIRMED_MSG_ON false
mluis 0:cb80564f40e1 45
mluis 0:cb80564f40e1 46 /*!
mluis 0:cb80564f40e1 47 * LoRaWAN Adaptive Data Rate
mluis 0:cb80564f40e1 48 *
mluis 0:cb80564f40e1 49 * \remark Please note that when ADR is enabled the end-device should be static
mluis 0:cb80564f40e1 50 */
mluis 0:cb80564f40e1 51 #define LORAWAN_ADR_ON 1
mluis 0:cb80564f40e1 52
mluis 0:cb80564f40e1 53 #if defined( USE_BAND_868 )
mluis 0:cb80564f40e1 54
mluis 0:cb80564f40e1 55 #include "LoRaMacTest.h"
mluis 0:cb80564f40e1 56
mluis 0:cb80564f40e1 57 /*!
mluis 0:cb80564f40e1 58 * LoRaWAN ETSI duty cycle control enable/disable
mluis 0:cb80564f40e1 59 *
mluis 0:cb80564f40e1 60 * \remark Please note that ETSI mandates duty cycled transmissions. Use only for test purposes
mluis 0:cb80564f40e1 61 */
mluis 0:cb80564f40e1 62 #define LORAWAN_DUTYCYCLE_ON false
mluis 0:cb80564f40e1 63
mluis 1:21e3eef8200f 64 #define USE_SEMTECH_DEFAULT_CHANNEL_LINEUP 1
mluis 1:21e3eef8200f 65
mluis 1:21e3eef8200f 66 #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 )
mluis 1:21e3eef8200f 67
mluis 1:21e3eef8200f 68 #define LC4 { 867100000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
mluis 1:21e3eef8200f 69 #define LC5 { 867300000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
mluis 1:21e3eef8200f 70 #define LC6 { 867500000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
mluis 1:21e3eef8200f 71 #define LC7 { 867700000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
mluis 1:21e3eef8200f 72 #define LC8 { 867900000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
mluis 1:21e3eef8200f 73 #define LC9 { 868800000, { ( ( DR_7 << 4 ) | DR_7 ) }, 2 }
mluis 1:21e3eef8200f 74 #define LC10 { 868300000, { ( ( DR_6 << 4 ) | DR_6 ) }, 1 }
mluis 1:21e3eef8200f 75
mluis 1:21e3eef8200f 76 #endif
mluis 1:21e3eef8200f 77
mluis 0:cb80564f40e1 78 #endif
mluis 0:cb80564f40e1 79
mluis 0:cb80564f40e1 80 /*!
mluis 0:cb80564f40e1 81 * LoRaWAN application port
mluis 0:cb80564f40e1 82 */
mluis 0:cb80564f40e1 83 #define LORAWAN_APP_PORT 10
mluis 0:cb80564f40e1 84
mluis 0:cb80564f40e1 85 /*!
mluis 0:cb80564f40e1 86 * User application data buffer size
mluis 0:cb80564f40e1 87 */
mluis 0:cb80564f40e1 88 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 )
mluis 0:cb80564f40e1 89 #define LORAWAN_APP_DATA_SIZE 6
mluis 0:cb80564f40e1 90
mluis 0:cb80564f40e1 91 #else
mluis 0:cb80564f40e1 92 #define LORAWAN_APP_DATA_SIZE 5
mluis 0:cb80564f40e1 93
mluis 0:cb80564f40e1 94 #endif
mluis 0:cb80564f40e1 95
mluis 0:cb80564f40e1 96 static uint8_t DevEui[] = LORAWAN_DEVICE_EUI;
mluis 0:cb80564f40e1 97 static uint8_t AppEui[] = LORAWAN_APPLICATION_EUI;
mluis 0:cb80564f40e1 98 static uint8_t AppKey[] = LORAWAN_APPLICATION_KEY;
mluis 0:cb80564f40e1 99
mluis 3:de1dcfbe175a 100 #if( OVER_THE_AIR_ACTIVATION == 0 )
mluis 0:cb80564f40e1 101
mluis 0:cb80564f40e1 102 static uint8_t NwkSKey[] = LORAWAN_NWKSKEY;
mluis 0:cb80564f40e1 103 static uint8_t AppSKey[] = LORAWAN_APPSKEY;
mluis 0:cb80564f40e1 104
mluis 0:cb80564f40e1 105 /*!
mluis 0:cb80564f40e1 106 * Device address
mluis 0:cb80564f40e1 107 */
mluis 0:cb80564f40e1 108 static uint32_t DevAddr = LORAWAN_DEVICE_ADDRESS;
mluis 0:cb80564f40e1 109
mluis 0:cb80564f40e1 110 #endif
mluis 0:cb80564f40e1 111
mluis 0:cb80564f40e1 112 /*!
mluis 0:cb80564f40e1 113 * Application port
mluis 0:cb80564f40e1 114 */
mluis 0:cb80564f40e1 115 static uint8_t AppPort = LORAWAN_APP_PORT;
mluis 0:cb80564f40e1 116
mluis 0:cb80564f40e1 117 /*!
mluis 0:cb80564f40e1 118 * User application data size
mluis 0:cb80564f40e1 119 */
mluis 0:cb80564f40e1 120 static uint8_t AppDataSize = LORAWAN_APP_DATA_SIZE;
mluis 0:cb80564f40e1 121
mluis 0:cb80564f40e1 122 /*!
mluis 0:cb80564f40e1 123 * User application data buffer size
mluis 0:cb80564f40e1 124 */
mluis 0:cb80564f40e1 125 #define LORAWAN_APP_DATA_MAX_SIZE 64
mluis 0:cb80564f40e1 126
mluis 0:cb80564f40e1 127 /*!
mluis 0:cb80564f40e1 128 * User application data
mluis 0:cb80564f40e1 129 */
mluis 0:cb80564f40e1 130 static uint8_t AppData[LORAWAN_APP_DATA_MAX_SIZE];
mluis 0:cb80564f40e1 131
mluis 0:cb80564f40e1 132 /*!
mluis 0:cb80564f40e1 133 * Indicates if the node is sending confirmed or unconfirmed messages
mluis 0:cb80564f40e1 134 */
mluis 0:cb80564f40e1 135 static uint8_t IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
mluis 0:cb80564f40e1 136
mluis 0:cb80564f40e1 137 /*!
mluis 0:cb80564f40e1 138 * Defines the application data transmission duty cycle
mluis 0:cb80564f40e1 139 */
mluis 0:cb80564f40e1 140 static uint32_t TxDutyCycleTime;
mluis 0:cb80564f40e1 141
mluis 0:cb80564f40e1 142 /*!
mluis 0:cb80564f40e1 143 * Timer to handle the application data transmission duty cycle
mluis 0:cb80564f40e1 144 */
mluis 0:cb80564f40e1 145 static TimerEvent_t TxNextPacketTimer;
mluis 0:cb80564f40e1 146
mluis 0:cb80564f40e1 147 /*!
mluis 0:cb80564f40e1 148 * Specifies the state of the application LED
mluis 0:cb80564f40e1 149 */
mluis 0:cb80564f40e1 150 static bool AppLedStateOn = false;
mluis 0:cb80564f40e1 151 volatile bool Led3StateChanged = false;
mluis 0:cb80564f40e1 152 /*!
mluis 0:cb80564f40e1 153 * Timer to handle the state of LED1
mluis 0:cb80564f40e1 154 */
mluis 0:cb80564f40e1 155 static TimerEvent_t Led1Timer;
mluis 0:cb80564f40e1 156 volatile bool Led1State = false;
mluis 0:cb80564f40e1 157 volatile bool Led1StateChanged = false;
mluis 0:cb80564f40e1 158 /*!
mluis 0:cb80564f40e1 159 * Timer to handle the state of LED2
mluis 0:cb80564f40e1 160 */
mluis 0:cb80564f40e1 161 static TimerEvent_t Led2Timer;
mluis 0:cb80564f40e1 162 volatile bool Led2State = false;
mluis 0:cb80564f40e1 163 volatile bool Led2StateChanged = false;
mluis 0:cb80564f40e1 164
mluis 0:cb80564f40e1 165 /*!
mluis 0:cb80564f40e1 166 * Indicates if a new packet can be sent
mluis 0:cb80564f40e1 167 */
mluis 0:cb80564f40e1 168 static bool NextTx = true;
mluis 0:cb80564f40e1 169
mluis 0:cb80564f40e1 170 /*!
mluis 0:cb80564f40e1 171 * Hold the value returned from the Light Sensor
mluis 0:cb80564f40e1 172 */
mluis 0:cb80564f40e1 173 static float LightValue = 0.0;
mluis 0:cb80564f40e1 174
mluis 0:cb80564f40e1 175 /*!
mluis 0:cb80564f40e1 176 * Control the 3-color LED
mluis 0:cb80564f40e1 177 * 0: automatic (LED goes brigther as the light decrease,
mluis 0:cb80564f40e1 178 * 1: manual (The LED is controlled by the user)
mluis 0:cb80564f40e1 179 */
mluis 1:21e3eef8200f 180 static uint8_t LightMode = 0; // 0: automatic, 1: manual
mluis 0:cb80564f40e1 181
mluis 0:cb80564f40e1 182 /*!
mluis 0:cb80564f40e1 183 * Ticker to create a PWM for the buzzer
mluis 0:cb80564f40e1 184 */
mluis 1:21e3eef8200f 185 Ticker BuzzerTimer;
mluis 0:cb80564f40e1 186
mluis 0:cb80564f40e1 187
mluis 0:cb80564f40e1 188 /*!
mluis 0:cb80564f40e1 189 * Constructor for Buzzer
mluis 0:cb80564f40e1 190 */
mluis 1:21e3eef8200f 191 DigitalOut Buzzer( A3 );
mluis 0:cb80564f40e1 192
mluis 0:cb80564f40e1 193 /*!
mluis 0:cb80564f40e1 194 * Constructor for the 3-color LED
mluis 0:cb80564f40e1 195 */
mluis 0:cb80564f40e1 196 #define NUM_LED 3
mluis 1:21e3eef8200f 197 ChainableLED ColorLed( D6, D7, NUM_LED );
mluis 0:cb80564f40e1 198
mluis 0:cb80564f40e1 199 /*!
mluis 0:cb80564f40e1 200 * Constructor for Light Sensor
mluis 0:cb80564f40e1 201 */
mluis 0:cb80564f40e1 202 AnalogIn LightSens( A1 );
mluis 0:cb80564f40e1 203
mluis 0:cb80564f40e1 204 /*!
mluis 0:cb80564f40e1 205 * Constructor for 4 Digit 7 semgent display
mluis 0:cb80564f40e1 206 */
mluis 1:21e3eef8200f 207 DigitDisplay Display( D8, D9 );
mluis 0:cb80564f40e1 208
mluis 0:cb80564f40e1 209 /*!
mluis 0:cb80564f40e1 210 * Device states
mluis 0:cb80564f40e1 211 */
mluis 0:cb80564f40e1 212 static enum eDevicState
mluis 0:cb80564f40e1 213 {
mluis 0:cb80564f40e1 214 DEVICE_STATE_INIT,
mluis 0:cb80564f40e1 215 DEVICE_STATE_JOIN,
mluis 0:cb80564f40e1 216 DEVICE_STATE_SEND,
mluis 0:cb80564f40e1 217 DEVICE_STATE_CYCLE,
mluis 0:cb80564f40e1 218 DEVICE_STATE_SLEEP
mluis 0:cb80564f40e1 219 }DeviceState;
mluis 0:cb80564f40e1 220
mluis 0:cb80564f40e1 221 /*!
mluis 0:cb80564f40e1 222 * LoRaWAN compliance tests support data
mluis 0:cb80564f40e1 223 */
mluis 0:cb80564f40e1 224 struct ComplianceTest_s
mluis 0:cb80564f40e1 225 {
mluis 0:cb80564f40e1 226 bool Running;
mluis 0:cb80564f40e1 227 uint8_t State;
mluis 0:cb80564f40e1 228 bool IsTxConfirmed;
mluis 0:cb80564f40e1 229 uint8_t AppPort;
mluis 0:cb80564f40e1 230 uint8_t AppDataSize;
mluis 0:cb80564f40e1 231 uint8_t *AppDataBuffer;
mluis 0:cb80564f40e1 232 uint16_t DownLinkCounter;
mluis 0:cb80564f40e1 233 bool LinkCheck;
mluis 0:cb80564f40e1 234 uint8_t DemodMargin;
mluis 0:cb80564f40e1 235 uint8_t NbGateways;
mluis 0:cb80564f40e1 236 }ComplianceTest;
mluis 0:cb80564f40e1 237
mluis 0:cb80564f40e1 238 /*
mluis 0:cb80564f40e1 239 * SerialDisplay managment variables
mluis 0:cb80564f40e1 240 */
mluis 0:cb80564f40e1 241
mluis 0:cb80564f40e1 242 /*!
mluis 0:cb80564f40e1 243 * Indicates if the MAC layer network join status has changed.
mluis 0:cb80564f40e1 244 */
mluis 0:cb80564f40e1 245 static bool IsNetworkJoinedStatusUpdate = false;
mluis 0:cb80564f40e1 246
mluis 0:cb80564f40e1 247 /*!
mluis 0:cb80564f40e1 248 * Strucure containing the Uplink status
mluis 0:cb80564f40e1 249 */
mluis 0:cb80564f40e1 250 struct sLoRaMacUplinkStatus
mluis 0:cb80564f40e1 251 {
mluis 0:cb80564f40e1 252 uint8_t Acked;
mluis 0:cb80564f40e1 253 int8_t Datarate;
mluis 0:cb80564f40e1 254 uint16_t UplinkCounter;
mluis 0:cb80564f40e1 255 uint8_t Port;
mluis 0:cb80564f40e1 256 uint8_t *Buffer;
mluis 0:cb80564f40e1 257 uint8_t BufferSize;
mluis 0:cb80564f40e1 258 }LoRaMacUplinkStatus;
mluis 0:cb80564f40e1 259 volatile bool UplinkStatusUpdated = false;
mluis 0:cb80564f40e1 260
mluis 0:cb80564f40e1 261 /*!
mluis 0:cb80564f40e1 262 * Strucure containing the Downlink status
mluis 0:cb80564f40e1 263 */
mluis 0:cb80564f40e1 264 struct sLoRaMacDownlinkStatus
mluis 0:cb80564f40e1 265 {
mluis 0:cb80564f40e1 266 int16_t Rssi;
mluis 0:cb80564f40e1 267 int8_t Snr;
mluis 0:cb80564f40e1 268 uint16_t DownlinkCounter;
mluis 0:cb80564f40e1 269 bool RxData;
mluis 0:cb80564f40e1 270 uint8_t Port;
mluis 0:cb80564f40e1 271 uint8_t *Buffer;
mluis 0:cb80564f40e1 272 uint8_t BufferSize;
mluis 0:cb80564f40e1 273 }LoRaMacDownlinkStatus;
mluis 0:cb80564f40e1 274 volatile bool DownlinkStatusUpdated = false;
mluis 0:cb80564f40e1 275
mluis 0:cb80564f40e1 276 void SerialDisplayRefresh( void )
mluis 0:cb80564f40e1 277 {
mluis 0:cb80564f40e1 278 MibRequestConfirm_t mibReq;
mluis 0:cb80564f40e1 279
mluis 0:cb80564f40e1 280 SerialDisplayInit( );
mluis 0:cb80564f40e1 281 SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION );
mluis 0:cb80564f40e1 282
mluis 0:cb80564f40e1 283 #if( OVER_THE_AIR_ACTIVATION == 0 )
mluis 0:cb80564f40e1 284 SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID );
mluis 0:cb80564f40e1 285 SerialDisplayUpdateDevAddr( DevAddr );
mluis 0:cb80564f40e1 286 SerialDisplayUpdateKey( 12, NwkSKey );
mluis 0:cb80564f40e1 287 SerialDisplayUpdateKey( 13, AppSKey );
mluis 3:de1dcfbe175a 288 #endif
mluis 0:cb80564f40e1 289 SerialDisplayUpdateEui( 5, DevEui );
mluis 0:cb80564f40e1 290 SerialDisplayUpdateEui( 6, AppEui );
mluis 0:cb80564f40e1 291 SerialDisplayUpdateKey( 7, AppKey );
mluis 0:cb80564f40e1 292
mluis 0:cb80564f40e1 293 mibReq.Type = MIB_NETWORK_JOINED;
mluis 0:cb80564f40e1 294 LoRaMacMibGetRequestConfirm( &mibReq );
mluis 0:cb80564f40e1 295 SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined );
mluis 0:cb80564f40e1 296
mluis 0:cb80564f40e1 297 SerialDisplayUpdateAdr( LORAWAN_ADR_ON );
mluis 0:cb80564f40e1 298 #if defined( USE_BAND_868 )
mluis 0:cb80564f40e1 299 SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON );
mluis 0:cb80564f40e1 300 #else
mluis 0:cb80564f40e1 301 SerialDisplayUpdateDutyCycle( false );
mluis 0:cb80564f40e1 302 #endif
mluis 0:cb80564f40e1 303 SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK );
mluis 0:cb80564f40e1 304
mluis 0:cb80564f40e1 305 SerialDisplayUpdateLedState( 3, AppLedStateOn );
mluis 0:cb80564f40e1 306 }
mluis 0:cb80564f40e1 307
mluis 0:cb80564f40e1 308 void SerialRxProcess( void )
mluis 0:cb80564f40e1 309 {
mluis 0:cb80564f40e1 310 if( SerialDisplayReadable( ) == true )
mluis 0:cb80564f40e1 311 {
mluis 0:cb80564f40e1 312 switch( SerialDisplayGetChar( ) )
mluis 0:cb80564f40e1 313 {
mluis 0:cb80564f40e1 314 case 'R':
mluis 0:cb80564f40e1 315 case 'r':
mluis 0:cb80564f40e1 316 // Refresh Serial screen
mluis 0:cb80564f40e1 317 SerialDisplayRefresh( );
mluis 0:cb80564f40e1 318 break;
mluis 0:cb80564f40e1 319 default:
mluis 0:cb80564f40e1 320 break;
mluis 0:cb80564f40e1 321 }
mluis 0:cb80564f40e1 322 }
mluis 0:cb80564f40e1 323 }
mluis 0:cb80564f40e1 324
mluis 0:cb80564f40e1 325 /*!
mluis 0:cb80564f40e1 326 * \brief Prepares the payload of the frame
mluis 0:cb80564f40e1 327 */
mluis 0:cb80564f40e1 328 static void PrepareTxFrame( uint8_t port )
mluis 0:cb80564f40e1 329 {
mluis 0:cb80564f40e1 330 switch( port )
mluis 0:cb80564f40e1 331 {
mluis 0:cb80564f40e1 332 case 10:
mluis 0:cb80564f40e1 333 {
mluis 1:21e3eef8200f 334 uint32_t tempValue = ( uint32_t )( LightValue * 1000000.0 );
mluis 0:cb80564f40e1 335 AppData[0] = LightMode;
mluis 0:cb80564f40e1 336 AppData[1] = ( ( tempValue & 0xFF000000 ) >> 24 ) & 0xFF;
mluis 0:cb80564f40e1 337 AppData[2] = ( ( tempValue & 0x00FF0000 ) >> 16 ) & 0xFF;
mluis 0:cb80564f40e1 338 AppData[3] = ( ( tempValue & 0x0000FF00 ) >> 8 ) & 0xFF;
mluis 1:21e3eef8200f 339 AppData[4] = ( tempValue & 0x000000FF );
mluis 0:cb80564f40e1 340 }
mluis 0:cb80564f40e1 341 break;
mluis 0:cb80564f40e1 342 case 15:
mluis 0:cb80564f40e1 343 {
mluis 0:cb80564f40e1 344 AppData[0] = AppLedStateOn;
mluis 0:cb80564f40e1 345 if( IsTxConfirmed == true )
mluis 0:cb80564f40e1 346 {
mluis 0:cb80564f40e1 347 AppData[1] = LoRaMacDownlinkStatus.DownlinkCounter >> 8;
mluis 0:cb80564f40e1 348 AppData[2] = LoRaMacDownlinkStatus.DownlinkCounter;
mluis 0:cb80564f40e1 349 AppData[3] = LoRaMacDownlinkStatus.Rssi >> 8;
mluis 0:cb80564f40e1 350 AppData[4] = LoRaMacDownlinkStatus.Rssi;
mluis 0:cb80564f40e1 351 AppData[5] = LoRaMacDownlinkStatus.Snr;
mluis 0:cb80564f40e1 352 }
mluis 0:cb80564f40e1 353 }
mluis 0:cb80564f40e1 354 break;
mluis 0:cb80564f40e1 355 case 224:
mluis 0:cb80564f40e1 356 if( ComplianceTest.LinkCheck == true )
mluis 0:cb80564f40e1 357 {
mluis 0:cb80564f40e1 358 ComplianceTest.LinkCheck = false;
mluis 0:cb80564f40e1 359 AppDataSize = 3;
mluis 0:cb80564f40e1 360 AppData[0] = 5;
mluis 0:cb80564f40e1 361 AppData[1] = ComplianceTest.DemodMargin;
mluis 0:cb80564f40e1 362 AppData[2] = ComplianceTest.NbGateways;
mluis 0:cb80564f40e1 363 ComplianceTest.State = 1;
mluis 0:cb80564f40e1 364 }
mluis 0:cb80564f40e1 365 else
mluis 0:cb80564f40e1 366 {
mluis 0:cb80564f40e1 367 switch( ComplianceTest.State )
mluis 0:cb80564f40e1 368 {
mluis 0:cb80564f40e1 369 case 4:
mluis 0:cb80564f40e1 370 ComplianceTest.State = 1;
mluis 0:cb80564f40e1 371 break;
mluis 0:cb80564f40e1 372 case 1:
mluis 0:cb80564f40e1 373 AppDataSize = 2;
mluis 0:cb80564f40e1 374 AppData[0] = ComplianceTest.DownLinkCounter >> 8;
mluis 0:cb80564f40e1 375 AppData[1] = ComplianceTest.DownLinkCounter;
mluis 0:cb80564f40e1 376 break;
mluis 0:cb80564f40e1 377 }
mluis 0:cb80564f40e1 378 }
mluis 0:cb80564f40e1 379 break;
mluis 0:cb80564f40e1 380 default:
mluis 0:cb80564f40e1 381 break;
mluis 0:cb80564f40e1 382 }
mluis 0:cb80564f40e1 383 }
mluis 0:cb80564f40e1 384
mluis 0:cb80564f40e1 385 /*!
mluis 0:cb80564f40e1 386 * \brief Prepares the payload of the frame
mluis 0:cb80564f40e1 387 *
mluis 0:cb80564f40e1 388 * \retval [0: frame could be send, 1: error]
mluis 0:cb80564f40e1 389 */
mluis 0:cb80564f40e1 390 static bool SendFrame( void )
mluis 0:cb80564f40e1 391 {
mluis 0:cb80564f40e1 392 McpsReq_t mcpsReq;
mluis 0:cb80564f40e1 393 LoRaMacTxInfo_t txInfo;
mluis 0:cb80564f40e1 394
mluis 0:cb80564f40e1 395 if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK )
mluis 0:cb80564f40e1 396 {
mluis 0:cb80564f40e1 397 // Send empty frame in order to flush MAC commands
mluis 0:cb80564f40e1 398 mcpsReq.Type = MCPS_UNCONFIRMED;
mluis 0:cb80564f40e1 399 mcpsReq.Req.Unconfirmed.fBuffer = NULL;
mluis 0:cb80564f40e1 400 mcpsReq.Req.Unconfirmed.fBufferSize = 0;
mluis 0:cb80564f40e1 401 mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
mluis 1:21e3eef8200f 402
mluis 0:cb80564f40e1 403 LoRaMacUplinkStatus.Acked = false;
mluis 0:cb80564f40e1 404 LoRaMacUplinkStatus.Port = 0;
mluis 0:cb80564f40e1 405 LoRaMacUplinkStatus.Buffer = NULL;
mluis 0:cb80564f40e1 406 LoRaMacUplinkStatus.BufferSize = 0;
mluis 0:cb80564f40e1 407 SerialDisplayUpdateFrameType( false );
mluis 0:cb80564f40e1 408 }
mluis 0:cb80564f40e1 409 else
mluis 0:cb80564f40e1 410 {
mluis 0:cb80564f40e1 411 LoRaMacUplinkStatus.Acked = false;
mluis 0:cb80564f40e1 412 LoRaMacUplinkStatus.Port = AppPort;
mluis 0:cb80564f40e1 413 LoRaMacUplinkStatus.Buffer = AppData;
mluis 0:cb80564f40e1 414 LoRaMacUplinkStatus.BufferSize = AppDataSize;
mluis 0:cb80564f40e1 415 SerialDisplayUpdateFrameType( IsTxConfirmed );
mluis 0:cb80564f40e1 416
mluis 0:cb80564f40e1 417 if( IsTxConfirmed == false )
mluis 0:cb80564f40e1 418 {
mluis 0:cb80564f40e1 419 mcpsReq.Type = MCPS_UNCONFIRMED;
mluis 0:cb80564f40e1 420 mcpsReq.Req.Unconfirmed.fPort = AppPort;
mluis 0:cb80564f40e1 421 mcpsReq.Req.Unconfirmed.fBuffer = AppData;
mluis 0:cb80564f40e1 422 mcpsReq.Req.Unconfirmed.fBufferSize = AppDataSize;
mluis 0:cb80564f40e1 423 mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
mluis 0:cb80564f40e1 424 }
mluis 0:cb80564f40e1 425 else
mluis 0:cb80564f40e1 426 {
mluis 0:cb80564f40e1 427 mcpsReq.Type = MCPS_CONFIRMED;
mluis 0:cb80564f40e1 428 mcpsReq.Req.Confirmed.fPort = AppPort;
mluis 0:cb80564f40e1 429 mcpsReq.Req.Confirmed.fBuffer = AppData;
mluis 0:cb80564f40e1 430 mcpsReq.Req.Confirmed.fBufferSize = AppDataSize;
mluis 0:cb80564f40e1 431 mcpsReq.Req.Confirmed.NbTrials = 8;
mluis 0:cb80564f40e1 432 mcpsReq.Req.Confirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
mluis 0:cb80564f40e1 433 }
mluis 0:cb80564f40e1 434 }
mluis 0:cb80564f40e1 435
mluis 0:cb80564f40e1 436 if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK )
mluis 0:cb80564f40e1 437 {
mluis 0:cb80564f40e1 438 return false;
mluis 0:cb80564f40e1 439 }
mluis 0:cb80564f40e1 440 return true;
mluis 0:cb80564f40e1 441 }
mluis 0:cb80564f40e1 442
mluis 0:cb80564f40e1 443 /*!
mluis 0:cb80564f40e1 444 * \brief Function executed on TxNextPacket Timeout event
mluis 0:cb80564f40e1 445 */
mluis 0:cb80564f40e1 446 static void OnTxNextPacketTimerEvent( void )
mluis 0:cb80564f40e1 447 {
mluis 0:cb80564f40e1 448 MibRequestConfirm_t mibReq;
mluis 0:cb80564f40e1 449 LoRaMacStatus_t status;
mluis 0:cb80564f40e1 450
mluis 0:cb80564f40e1 451 TimerStop( &TxNextPacketTimer );
mluis 0:cb80564f40e1 452
mluis 0:cb80564f40e1 453 mibReq.Type = MIB_NETWORK_JOINED;
mluis 0:cb80564f40e1 454 status = LoRaMacMibGetRequestConfirm( &mibReq );
mluis 0:cb80564f40e1 455
mluis 0:cb80564f40e1 456 if( status == LORAMAC_STATUS_OK )
mluis 0:cb80564f40e1 457 {
mluis 0:cb80564f40e1 458 if( mibReq.Param.IsNetworkJoined == true )
mluis 0:cb80564f40e1 459 {
mluis 0:cb80564f40e1 460 DeviceState = DEVICE_STATE_SEND;
mluis 0:cb80564f40e1 461 NextTx = true;
mluis 0:cb80564f40e1 462 }
mluis 0:cb80564f40e1 463 else
mluis 0:cb80564f40e1 464 {
mluis 0:cb80564f40e1 465 DeviceState = DEVICE_STATE_JOIN;
mluis 0:cb80564f40e1 466 }
mluis 0:cb80564f40e1 467 }
mluis 0:cb80564f40e1 468 }
mluis 0:cb80564f40e1 469
mluis 0:cb80564f40e1 470 /*!
mluis 0:cb80564f40e1 471 * \brief Function executed on Led 1 Timeout event
mluis 0:cb80564f40e1 472 */
mluis 0:cb80564f40e1 473 static void OnLed1TimerEvent( void )
mluis 0:cb80564f40e1 474 {
mluis 0:cb80564f40e1 475 TimerStop( &Led1Timer );
mluis 0:cb80564f40e1 476 // Switch LED 1 OFF
mluis 0:cb80564f40e1 477 Led1State = false;
mluis 0:cb80564f40e1 478 Led1StateChanged = true;
mluis 0:cb80564f40e1 479 }
mluis 0:cb80564f40e1 480
mluis 0:cb80564f40e1 481 /*!
mluis 0:cb80564f40e1 482 * \brief Function executed on Led 2 Timeout event
mluis 0:cb80564f40e1 483 */
mluis 0:cb80564f40e1 484 static void OnLed2TimerEvent( void )
mluis 0:cb80564f40e1 485 {
mluis 0:cb80564f40e1 486 TimerStop( &Led2Timer );
mluis 0:cb80564f40e1 487 // Switch LED 2 OFF
mluis 0:cb80564f40e1 488 Led2State = false;
mluis 0:cb80564f40e1 489 Led2StateChanged = true;
mluis 0:cb80564f40e1 490 }
mluis 0:cb80564f40e1 491
mluis 0:cb80564f40e1 492 /*!
mluis 0:cb80564f40e1 493 * \brief Function executed on Buzzer Timeout event
mluis 0:cb80564f40e1 494 */
mluis 1:21e3eef8200f 495 static void OnBuzzerTimerEvent( void )
mluis 0:cb80564f40e1 496 {
mluis 1:21e3eef8200f 497 Buzzer = 0;
mluis 1:21e3eef8200f 498 BuzzerTimer.detach( );
mluis 0:cb80564f40e1 499 }
mluis 0:cb80564f40e1 500
mluis 0:cb80564f40e1 501 /*!
mluis 0:cb80564f40e1 502 * \brief MCPS-Confirm event function
mluis 0:cb80564f40e1 503 *
mluis 1:21e3eef8200f 504 * \param [IN] mcpsConfirm - Pointer to the confirm structure,
mluis 0:cb80564f40e1 505 * containing confirm attributes.
mluis 0:cb80564f40e1 506 */
mluis 1:21e3eef8200f 507 static void McpsConfirm( McpsConfirm_t *mcpsConfirm )
mluis 0:cb80564f40e1 508 {
mluis 1:21e3eef8200f 509 if( mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
mluis 0:cb80564f40e1 510 {
mluis 1:21e3eef8200f 511 switch( mcpsConfirm->McpsRequest )
mluis 0:cb80564f40e1 512 {
mluis 0:cb80564f40e1 513 case MCPS_UNCONFIRMED:
mluis 0:cb80564f40e1 514 {
mluis 0:cb80564f40e1 515 // Check Datarate
mluis 0:cb80564f40e1 516 // Check TxPower
mluis 0:cb80564f40e1 517 break;
mluis 0:cb80564f40e1 518 }
mluis 0:cb80564f40e1 519 case MCPS_CONFIRMED:
mluis 0:cb80564f40e1 520 {
mluis 0:cb80564f40e1 521 // Check Datarate
mluis 0:cb80564f40e1 522 // Check TxPower
mluis 0:cb80564f40e1 523 // Check AckReceived
mluis 1:21e3eef8200f 524 // Check NbTrials
mluis 1:21e3eef8200f 525 LoRaMacUplinkStatus.Acked = mcpsConfirm->AckReceived;
mluis 0:cb80564f40e1 526 break;
mluis 0:cb80564f40e1 527 }
mluis 0:cb80564f40e1 528 case MCPS_PROPRIETARY:
mluis 0:cb80564f40e1 529 {
mluis 0:cb80564f40e1 530 break;
mluis 0:cb80564f40e1 531 }
mluis 0:cb80564f40e1 532 default:
mluis 0:cb80564f40e1 533 break;
mluis 0:cb80564f40e1 534 }
mluis 1:21e3eef8200f 535 LoRaMacUplinkStatus.Datarate = mcpsConfirm->Datarate;
mluis 1:21e3eef8200f 536 LoRaMacUplinkStatus.UplinkCounter = mcpsConfirm->UpLinkCounter;
mluis 1:21e3eef8200f 537
mluis 3:de1dcfbe175a 538 // Switch LED 1 ON
mluis 3:de1dcfbe175a 539 Led1State = true;
mluis 3:de1dcfbe175a 540 Led1StateChanged = true;
mluis 3:de1dcfbe175a 541 TimerStart( &Led1Timer );
mluis 3:de1dcfbe175a 542
mluis 0:cb80564f40e1 543 UplinkStatusUpdated = true;
mluis 0:cb80564f40e1 544 }
mluis 0:cb80564f40e1 545 NextTx = true;
mluis 0:cb80564f40e1 546 }
mluis 0:cb80564f40e1 547
mluis 0:cb80564f40e1 548 /*!
mluis 0:cb80564f40e1 549 * \brief MCPS-Indication event function
mluis 0:cb80564f40e1 550 *
mluis 1:21e3eef8200f 551 * \param [IN] mcpsIndication - Pointer to the indication structure,
mluis 0:cb80564f40e1 552 * containing indication attributes.
mluis 0:cb80564f40e1 553 */
mluis 1:21e3eef8200f 554 static void McpsIndication( McpsIndication_t *mcpsIndication )
mluis 0:cb80564f40e1 555 {
mluis 1:21e3eef8200f 556 if( mcpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK )
mluis 0:cb80564f40e1 557 {
mluis 0:cb80564f40e1 558 return;
mluis 0:cb80564f40e1 559 }
mluis 0:cb80564f40e1 560
mluis 1:21e3eef8200f 561 switch( mcpsIndication->McpsIndication )
mluis 0:cb80564f40e1 562 {
mluis 0:cb80564f40e1 563 case MCPS_UNCONFIRMED:
mluis 0:cb80564f40e1 564 {
mluis 0:cb80564f40e1 565 break;
mluis 0:cb80564f40e1 566 }
mluis 0:cb80564f40e1 567 case MCPS_CONFIRMED:
mluis 0:cb80564f40e1 568 {
mluis 0:cb80564f40e1 569 break;
mluis 0:cb80564f40e1 570 }
mluis 0:cb80564f40e1 571 case MCPS_PROPRIETARY:
mluis 0:cb80564f40e1 572 {
mluis 0:cb80564f40e1 573 break;
mluis 0:cb80564f40e1 574 }
mluis 0:cb80564f40e1 575 case MCPS_MULTICAST:
mluis 0:cb80564f40e1 576 {
mluis 0:cb80564f40e1 577 break;
mluis 0:cb80564f40e1 578 }
mluis 0:cb80564f40e1 579 default:
mluis 0:cb80564f40e1 580 break;
mluis 0:cb80564f40e1 581 }
mluis 0:cb80564f40e1 582
mluis 0:cb80564f40e1 583 // Check Multicast
mluis 0:cb80564f40e1 584 // Check Port
mluis 0:cb80564f40e1 585 // Check Datarate
mluis 0:cb80564f40e1 586 // Check FramePending
mluis 0:cb80564f40e1 587 // Check Buffer
mluis 0:cb80564f40e1 588 // Check BufferSize
mluis 0:cb80564f40e1 589 // Check Rssi
mluis 0:cb80564f40e1 590 // Check Snr
mluis 0:cb80564f40e1 591 // Check RxSlot
mluis 1:21e3eef8200f 592 LoRaMacDownlinkStatus.Rssi = mcpsIndication->Rssi;
mluis 1:21e3eef8200f 593 if( mcpsIndication->Snr & 0x80 ) // The SNR sign bit is 1
mluis 0:cb80564f40e1 594 {
mluis 0:cb80564f40e1 595 // Invert and divide by 4
mluis 1:21e3eef8200f 596 LoRaMacDownlinkStatus.Snr = ( ( ~mcpsIndication->Snr + 1 ) & 0xFF ) >> 2;
mluis 0:cb80564f40e1 597 LoRaMacDownlinkStatus.Snr = -LoRaMacDownlinkStatus.Snr;
mluis 0:cb80564f40e1 598 }
mluis 0:cb80564f40e1 599 else
mluis 0:cb80564f40e1 600 {
mluis 0:cb80564f40e1 601 // Divide by 4
mluis 1:21e3eef8200f 602 LoRaMacDownlinkStatus.Snr = ( mcpsIndication->Snr & 0xFF ) >> 2;
mluis 0:cb80564f40e1 603 }
mluis 0:cb80564f40e1 604 LoRaMacDownlinkStatus.DownlinkCounter++;
mluis 1:21e3eef8200f 605 LoRaMacDownlinkStatus.RxData = mcpsIndication->RxData;
mluis 1:21e3eef8200f 606 LoRaMacDownlinkStatus.Port = mcpsIndication->Port;
mluis 1:21e3eef8200f 607 LoRaMacDownlinkStatus.Buffer = mcpsIndication->Buffer;
mluis 1:21e3eef8200f 608 LoRaMacDownlinkStatus.BufferSize = mcpsIndication->BufferSize;
mluis 0:cb80564f40e1 609
mluis 0:cb80564f40e1 610 if( ComplianceTest.Running == true )
mluis 0:cb80564f40e1 611 {
mluis 0:cb80564f40e1 612 ComplianceTest.DownLinkCounter++;
mluis 0:cb80564f40e1 613 }
mluis 0:cb80564f40e1 614
mluis 1:21e3eef8200f 615 if( mcpsIndication->RxData == true )
mluis 0:cb80564f40e1 616 {
mluis 1:21e3eef8200f 617 switch( mcpsIndication->Port )
mluis 0:cb80564f40e1 618 {
mluis 0:cb80564f40e1 619 case 1: // The application LED can be controlled on port 1 or 2
mluis 0:cb80564f40e1 620 case 2:
mluis 1:21e3eef8200f 621 if( mcpsIndication->BufferSize == 1 )
mluis 0:cb80564f40e1 622 {
mluis 1:21e3eef8200f 623 AppLedStateOn = mcpsIndication->Buffer[0] & 0x01;
mluis 0:cb80564f40e1 624 Led3StateChanged = true;
mluis 0:cb80564f40e1 625 }
mluis 0:cb80564f40e1 626 break;
mluis 0:cb80564f40e1 627 case 10:
mluis 1:21e3eef8200f 628 Display.write( 0, mcpsIndication->Buffer[0] );
mluis 1:21e3eef8200f 629 Display.write( 1, mcpsIndication->Buffer[1] );
mluis 1:21e3eef8200f 630 Display.write( 2, mcpsIndication->Buffer[2] );
mluis 1:21e3eef8200f 631 Display.write( 3, mcpsIndication->Buffer[3] );
mluis 0:cb80564f40e1 632 break;
mluis 0:cb80564f40e1 633 case 20:
mluis 1:21e3eef8200f 634 LightMode = mcpsIndication->Buffer[0];
mluis 0:cb80564f40e1 635 if( LightMode )
mluis 0:cb80564f40e1 636 {
mluis 1:21e3eef8200f 637 ColorLed.setColorRGB( 0, mcpsIndication->Buffer[1], mcpsIndication->Buffer[2], mcpsIndication->Buffer[3] );
mluis 0:cb80564f40e1 638 }
mluis 0:cb80564f40e1 639 break;
mluis 0:cb80564f40e1 640 case 30:
mluis 1:21e3eef8200f 641 BuzzerTimer.attach_us( &OnBuzzerTimerEvent, 200000 );
mluis 1:21e3eef8200f 642 Buzzer = 1;
mluis 0:cb80564f40e1 643 break;
mluis 0:cb80564f40e1 644 case 224:
mluis 0:cb80564f40e1 645 if( ComplianceTest.Running == false )
mluis 0:cb80564f40e1 646 {
mluis 0:cb80564f40e1 647 // Check compliance test enable command (i)
mluis 1:21e3eef8200f 648 if( ( mcpsIndication->BufferSize == 4 ) &&
mluis 1:21e3eef8200f 649 ( mcpsIndication->Buffer[0] == 0x01 ) &&
mluis 1:21e3eef8200f 650 ( mcpsIndication->Buffer[1] == 0x01 ) &&
mluis 1:21e3eef8200f 651 ( mcpsIndication->Buffer[2] == 0x01 ) &&
mluis 1:21e3eef8200f 652 ( mcpsIndication->Buffer[3] == 0x01 ) )
mluis 0:cb80564f40e1 653 {
mluis 0:cb80564f40e1 654 IsTxConfirmed = false;
mluis 0:cb80564f40e1 655 AppPort = 224;
mluis 0:cb80564f40e1 656 AppDataSize = 2;
mluis 0:cb80564f40e1 657 ComplianceTest.DownLinkCounter = 0;
mluis 0:cb80564f40e1 658 ComplianceTest.LinkCheck = false;
mluis 0:cb80564f40e1 659 ComplianceTest.DemodMargin = 0;
mluis 0:cb80564f40e1 660 ComplianceTest.NbGateways = 0;
mluis 0:cb80564f40e1 661 ComplianceTest.Running = true;
mluis 0:cb80564f40e1 662 ComplianceTest.State = 1;
mluis 0:cb80564f40e1 663
mluis 0:cb80564f40e1 664 MibRequestConfirm_t mibReq;
mluis 0:cb80564f40e1 665 mibReq.Type = MIB_ADR;
mluis 0:cb80564f40e1 666 mibReq.Param.AdrEnable = true;
mluis 0:cb80564f40e1 667 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:cb80564f40e1 668
mluis 0:cb80564f40e1 669 #if defined( USE_BAND_868 )
mluis 0:cb80564f40e1 670 LoRaMacTestSetDutyCycleOn( false );
mluis 0:cb80564f40e1 671 #endif
mluis 0:cb80564f40e1 672 }
mluis 0:cb80564f40e1 673 }
mluis 0:cb80564f40e1 674 else
mluis 0:cb80564f40e1 675 {
mluis 1:21e3eef8200f 676 ComplianceTest.State = mcpsIndication->Buffer[0];
mluis 0:cb80564f40e1 677 switch( ComplianceTest.State )
mluis 0:cb80564f40e1 678 {
mluis 0:cb80564f40e1 679 case 0: // Check compliance test disable command (ii)
mluis 0:cb80564f40e1 680 IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
mluis 0:cb80564f40e1 681 AppPort = LORAWAN_APP_PORT;
mluis 0:cb80564f40e1 682 AppDataSize = LORAWAN_APP_DATA_SIZE;
mluis 0:cb80564f40e1 683 ComplianceTest.DownLinkCounter = 0;
mluis 0:cb80564f40e1 684 ComplianceTest.Running = false;
mluis 0:cb80564f40e1 685
mluis 0:cb80564f40e1 686 MibRequestConfirm_t mibReq;
mluis 0:cb80564f40e1 687 mibReq.Type = MIB_ADR;
mluis 0:cb80564f40e1 688 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
mluis 0:cb80564f40e1 689 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:cb80564f40e1 690 #if defined( USE_BAND_868 )
mluis 0:cb80564f40e1 691 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
mluis 0:cb80564f40e1 692 #endif
mluis 0:cb80564f40e1 693 break;
mluis 0:cb80564f40e1 694 case 1: // (iii, iv)
mluis 0:cb80564f40e1 695 AppDataSize = 2;
mluis 0:cb80564f40e1 696 break;
mluis 0:cb80564f40e1 697 case 2: // Enable confirmed messages (v)
mluis 0:cb80564f40e1 698 IsTxConfirmed = true;
mluis 0:cb80564f40e1 699 ComplianceTest.State = 1;
mluis 0:cb80564f40e1 700 break;
mluis 0:cb80564f40e1 701 case 3: // Disable confirmed messages (vi)
mluis 0:cb80564f40e1 702 IsTxConfirmed = false;
mluis 0:cb80564f40e1 703 ComplianceTest.State = 1;
mluis 0:cb80564f40e1 704 break;
mluis 0:cb80564f40e1 705 case 4: // (vii)
mluis 1:21e3eef8200f 706 AppDataSize = mcpsIndication->BufferSize;
mluis 0:cb80564f40e1 707
mluis 0:cb80564f40e1 708 AppData[0] = 4;
mluis 0:cb80564f40e1 709 for( uint8_t i = 1; i < AppDataSize; i++ )
mluis 0:cb80564f40e1 710 {
mluis 1:21e3eef8200f 711 AppData[i] = mcpsIndication->Buffer[i] + 1;
mluis 0:cb80564f40e1 712 }
mluis 0:cb80564f40e1 713 break;
mluis 0:cb80564f40e1 714 case 5: // (viii)
mluis 0:cb80564f40e1 715 {
mluis 0:cb80564f40e1 716 MlmeReq_t mlmeReq;
mluis 0:cb80564f40e1 717 mlmeReq.Type = MLME_LINK_CHECK;
mluis 0:cb80564f40e1 718 LoRaMacMlmeRequest( &mlmeReq );
mluis 0:cb80564f40e1 719 }
mluis 0:cb80564f40e1 720 break;
mluis 3:de1dcfbe175a 721 case 6: // (ix)
mluis 3:de1dcfbe175a 722 {
mluis 3:de1dcfbe175a 723 MlmeReq_t mlmeReq;
mluis 3:de1dcfbe175a 724
mluis 3:de1dcfbe175a 725 mlmeReq.Type = MLME_JOIN;
mluis 3:de1dcfbe175a 726
mluis 3:de1dcfbe175a 727 mlmeReq.Req.Join.DevEui = DevEui;
mluis 3:de1dcfbe175a 728 mlmeReq.Req.Join.AppEui = AppEui;
mluis 3:de1dcfbe175a 729 mlmeReq.Req.Join.AppKey = AppKey;
mluis 3:de1dcfbe175a 730
mluis 3:de1dcfbe175a 731 LoRaMacMlmeRequest( &mlmeReq );
mluis 3:de1dcfbe175a 732 DeviceState = DEVICE_STATE_SLEEP;
mluis 3:de1dcfbe175a 733 }
mluis 3:de1dcfbe175a 734 break;
mluis 0:cb80564f40e1 735 default:
mluis 0:cb80564f40e1 736 break;
mluis 0:cb80564f40e1 737 }
mluis 0:cb80564f40e1 738 }
mluis 0:cb80564f40e1 739 break;
mluis 0:cb80564f40e1 740 default:
mluis 0:cb80564f40e1 741 break;
mluis 0:cb80564f40e1 742 }
mluis 0:cb80564f40e1 743 }
mluis 0:cb80564f40e1 744
mluis 0:cb80564f40e1 745 // Switch LED 2 ON for each received downlink
mluis 0:cb80564f40e1 746 Led2State = true;
mluis 0:cb80564f40e1 747 Led2StateChanged = true;
mluis 0:cb80564f40e1 748 TimerStart( &Led2Timer );
mluis 0:cb80564f40e1 749 DownlinkStatusUpdated = true;
mluis 0:cb80564f40e1 750 }
mluis 0:cb80564f40e1 751
mluis 0:cb80564f40e1 752 /*!
mluis 0:cb80564f40e1 753 * \brief MLME-Confirm event function
mluis 0:cb80564f40e1 754 *
mluis 1:21e3eef8200f 755 * \param [IN] mlmeConfirm - Pointer to the confirm structure,
mluis 0:cb80564f40e1 756 * containing confirm attributes.
mluis 0:cb80564f40e1 757 */
mluis 1:21e3eef8200f 758 static void MlmeConfirm( MlmeConfirm_t *mlmeConfirm )
mluis 0:cb80564f40e1 759 {
mluis 1:21e3eef8200f 760 if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
mluis 0:cb80564f40e1 761 {
mluis 1:21e3eef8200f 762 switch( mlmeConfirm->MlmeRequest )
mluis 0:cb80564f40e1 763 {
mluis 0:cb80564f40e1 764 case MLME_JOIN:
mluis 0:cb80564f40e1 765 {
mluis 0:cb80564f40e1 766 // Status is OK, node has joined the network
mluis 0:cb80564f40e1 767 IsNetworkJoinedStatusUpdate = true;
mluis 3:de1dcfbe175a 768 DeviceState = DEVICE_STATE_SEND;
mluis 3:de1dcfbe175a 769 NextTx = true;
mluis 0:cb80564f40e1 770 break;
mluis 0:cb80564f40e1 771 }
mluis 0:cb80564f40e1 772 case MLME_LINK_CHECK:
mluis 0:cb80564f40e1 773 {
mluis 0:cb80564f40e1 774 // Check DemodMargin
mluis 0:cb80564f40e1 775 // Check NbGateways
mluis 0:cb80564f40e1 776 if( ComplianceTest.Running == true )
mluis 0:cb80564f40e1 777 {
mluis 0:cb80564f40e1 778 ComplianceTest.LinkCheck = true;
mluis 1:21e3eef8200f 779 ComplianceTest.DemodMargin = mlmeConfirm->DemodMargin;
mluis 1:21e3eef8200f 780 ComplianceTest.NbGateways = mlmeConfirm->NbGateways;
mluis 0:cb80564f40e1 781 }
mluis 0:cb80564f40e1 782 break;
mluis 0:cb80564f40e1 783 }
mluis 0:cb80564f40e1 784 default:
mluis 0:cb80564f40e1 785 break;
mluis 0:cb80564f40e1 786 }
mluis 0:cb80564f40e1 787 }
mluis 0:cb80564f40e1 788 NextTx = true;
mluis 0:cb80564f40e1 789 UplinkStatusUpdated = true;
mluis 0:cb80564f40e1 790 }
mluis 0:cb80564f40e1 791
mluis 0:cb80564f40e1 792 /**
mluis 0:cb80564f40e1 793 * Main application entry point.
mluis 0:cb80564f40e1 794 */
mluis 0:cb80564f40e1 795 int main( void )
mluis 0:cb80564f40e1 796 {
mluis 0:cb80564f40e1 797 LoRaMacPrimitives_t LoRaMacPrimitives;
mluis 0:cb80564f40e1 798 LoRaMacCallback_t LoRaMacCallbacks;
mluis 0:cb80564f40e1 799 MibRequestConfirm_t mibReq;
mluis 0:cb80564f40e1 800
mluis 0:cb80564f40e1 801 BoardInit( );
mluis 0:cb80564f40e1 802 SerialDisplayInit( );
mluis 0:cb80564f40e1 803
mluis 1:21e3eef8200f 804 LightMode = 0; // 0: manual, 1: automatic
mluis 1:21e3eef8200f 805 Buzzer = 0; // 0: OFF, 1: ON
mluis 1:21e3eef8200f 806
mluis 3:de1dcfbe175a 807 SerialDisplayUpdateEui( 5, DevEui );
mluis 3:de1dcfbe175a 808 SerialDisplayUpdateEui( 6, AppEui );
mluis 3:de1dcfbe175a 809 SerialDisplayUpdateKey( 7, AppKey );
mluis 3:de1dcfbe175a 810
mluis 3:de1dcfbe175a 811 #if( OVER_THE_AIR_ACTIVATION == 0 )
mluis 3:de1dcfbe175a 812 SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID );
mluis 3:de1dcfbe175a 813 SerialDisplayUpdateDevAddr( DevAddr );
mluis 3:de1dcfbe175a 814 SerialDisplayUpdateKey( 12, NwkSKey );
mluis 3:de1dcfbe175a 815 SerialDisplayUpdateKey( 13, AppSKey );
mluis 3:de1dcfbe175a 816 #endif
mluis 3:de1dcfbe175a 817
mluis 0:cb80564f40e1 818 DeviceState = DEVICE_STATE_INIT;
mluis 0:cb80564f40e1 819
mluis 0:cb80564f40e1 820 while( 1 )
mluis 0:cb80564f40e1 821 {
mluis 0:cb80564f40e1 822 SerialRxProcess( );
mluis 0:cb80564f40e1 823 if( IsNetworkJoinedStatusUpdate == true )
mluis 0:cb80564f40e1 824 {
mluis 0:cb80564f40e1 825 IsNetworkJoinedStatusUpdate = false;
mluis 0:cb80564f40e1 826 mibReq.Type = MIB_NETWORK_JOINED;
mluis 0:cb80564f40e1 827 LoRaMacMibGetRequestConfirm( &mibReq );
mluis 0:cb80564f40e1 828 SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined );
mluis 0:cb80564f40e1 829 }
mluis 0:cb80564f40e1 830 if( Led1StateChanged == true )
mluis 0:cb80564f40e1 831 {
mluis 0:cb80564f40e1 832 Led1StateChanged = false;
mluis 0:cb80564f40e1 833 SerialDisplayUpdateLedState( 1, Led1State );
mluis 0:cb80564f40e1 834 }
mluis 0:cb80564f40e1 835 if( Led2StateChanged == true )
mluis 0:cb80564f40e1 836 {
mluis 0:cb80564f40e1 837 Led2StateChanged = false;
mluis 0:cb80564f40e1 838 SerialDisplayUpdateLedState( 2, Led2State );
mluis 0:cb80564f40e1 839 }
mluis 0:cb80564f40e1 840 if( Led3StateChanged == true )
mluis 0:cb80564f40e1 841 {
mluis 0:cb80564f40e1 842 Led3StateChanged = false;
mluis 0:cb80564f40e1 843 SerialDisplayUpdateLedState( 3, AppLedStateOn );
mluis 0:cb80564f40e1 844 }
mluis 0:cb80564f40e1 845 if( UplinkStatusUpdated == true )
mluis 0:cb80564f40e1 846 {
mluis 0:cb80564f40e1 847 UplinkStatusUpdated = false;
mluis 0:cb80564f40e1 848 SerialDisplayUpdateUplink( LoRaMacUplinkStatus.Acked, LoRaMacUplinkStatus.Datarate, LoRaMacUplinkStatus.UplinkCounter, LoRaMacUplinkStatus.Port, LoRaMacUplinkStatus.Buffer, LoRaMacUplinkStatus.BufferSize );
mluis 0:cb80564f40e1 849 }
mluis 0:cb80564f40e1 850 if( DownlinkStatusUpdated == true )
mluis 0:cb80564f40e1 851 {
mluis 0:cb80564f40e1 852 DownlinkStatusUpdated = false;
mluis 0:cb80564f40e1 853 SerialDisplayUpdateLedState( 2, Led2State );
mluis 0:cb80564f40e1 854 SerialDisplayUpdateDownlink( LoRaMacDownlinkStatus.RxData, LoRaMacDownlinkStatus.Rssi, LoRaMacDownlinkStatus.Snr, LoRaMacDownlinkStatus.DownlinkCounter, LoRaMacDownlinkStatus.Port, LoRaMacDownlinkStatus.Buffer, LoRaMacDownlinkStatus.BufferSize );
mluis 0:cb80564f40e1 855 }
mluis 0:cb80564f40e1 856
mluis 0:cb80564f40e1 857 switch( DeviceState )
mluis 0:cb80564f40e1 858 {
mluis 0:cb80564f40e1 859 case DEVICE_STATE_INIT:
mluis 0:cb80564f40e1 860 {
mluis 0:cb80564f40e1 861 LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm;
mluis 0:cb80564f40e1 862 LoRaMacPrimitives.MacMcpsIndication = McpsIndication;
mluis 0:cb80564f40e1 863 LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm;
mluis 0:cb80564f40e1 864 LoRaMacCallbacks.GetBatteryLevel = BoardGetBatteryLevel;
mluis 0:cb80564f40e1 865 LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks );
mluis 0:cb80564f40e1 866
mluis 0:cb80564f40e1 867 TimerInit( &TxNextPacketTimer, OnTxNextPacketTimerEvent );
mluis 0:cb80564f40e1 868
mluis 0:cb80564f40e1 869 TimerInit( &Led1Timer, OnLed1TimerEvent );
mluis 0:cb80564f40e1 870 TimerSetValue( &Led1Timer, 25000 );
mluis 0:cb80564f40e1 871
mluis 0:cb80564f40e1 872 TimerInit( &Led2Timer, OnLed2TimerEvent );
mluis 0:cb80564f40e1 873 TimerSetValue( &Led2Timer, 25000 );
mluis 0:cb80564f40e1 874
mluis 0:cb80564f40e1 875 mibReq.Type = MIB_ADR;
mluis 0:cb80564f40e1 876 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
mluis 0:cb80564f40e1 877 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:cb80564f40e1 878
mluis 0:cb80564f40e1 879 mibReq.Type = MIB_PUBLIC_NETWORK;
mluis 0:cb80564f40e1 880 mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK;
mluis 0:cb80564f40e1 881 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:cb80564f40e1 882
mluis 0:cb80564f40e1 883 #if defined( USE_BAND_868 )
mluis 0:cb80564f40e1 884 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
mluis 0:cb80564f40e1 885 SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON );
mluis 1:21e3eef8200f 886
mluis 1:21e3eef8200f 887 #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 )
mluis 1:21e3eef8200f 888 LoRaMacChannelAdd( 3, ( ChannelParams_t )LC4 );
mluis 1:21e3eef8200f 889 LoRaMacChannelAdd( 4, ( ChannelParams_t )LC5 );
mluis 1:21e3eef8200f 890 LoRaMacChannelAdd( 5, ( ChannelParams_t )LC6 );
mluis 1:21e3eef8200f 891 LoRaMacChannelAdd( 6, ( ChannelParams_t )LC7 );
mluis 1:21e3eef8200f 892 LoRaMacChannelAdd( 7, ( ChannelParams_t )LC8 );
mluis 1:21e3eef8200f 893 LoRaMacChannelAdd( 8, ( ChannelParams_t )LC9 );
mluis 1:21e3eef8200f 894 LoRaMacChannelAdd( 9, ( ChannelParams_t )LC10 );
mluis 3:de1dcfbe175a 895
mluis 3:de1dcfbe175a 896 mibReq.Type = MIB_RX2_CHANNEL;
mluis 3:de1dcfbe175a 897 mibReq.Param.Rx2Channel = ( Rx2ChannelParams_t ){ 869525000, DR_3 };
mluis 3:de1dcfbe175a 898 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 1:21e3eef8200f 899 #endif
mluis 1:21e3eef8200f 900
mluis 0:cb80564f40e1 901 #endif
mluis 0:cb80564f40e1 902 SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION );
mluis 0:cb80564f40e1 903 SerialDisplayUpdateAdr( LORAWAN_ADR_ON );
mluis 0:cb80564f40e1 904 SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK );
mluis 0:cb80564f40e1 905
mluis 0:cb80564f40e1 906 LoRaMacDownlinkStatus.DownlinkCounter = 0;
mluis 0:cb80564f40e1 907
mluis 0:cb80564f40e1 908 DeviceState = DEVICE_STATE_JOIN;
mluis 0:cb80564f40e1 909 break;
mluis 0:cb80564f40e1 910 }
mluis 0:cb80564f40e1 911 case DEVICE_STATE_JOIN:
mluis 0:cb80564f40e1 912 {
mluis 0:cb80564f40e1 913 #if( OVER_THE_AIR_ACTIVATION != 0 )
mluis 0:cb80564f40e1 914 MlmeReq_t mlmeReq;
mluis 0:cb80564f40e1 915
mluis 0:cb80564f40e1 916 mlmeReq.Type = MLME_JOIN;
mluis 0:cb80564f40e1 917
mluis 0:cb80564f40e1 918 mlmeReq.Req.Join.DevEui = DevEui;
mluis 0:cb80564f40e1 919 mlmeReq.Req.Join.AppEui = AppEui;
mluis 0:cb80564f40e1 920 mlmeReq.Req.Join.AppKey = AppKey;
mluis 0:cb80564f40e1 921
mluis 0:cb80564f40e1 922 if( NextTx == true )
mluis 0:cb80564f40e1 923 {
mluis 0:cb80564f40e1 924 LoRaMacMlmeRequest( &mlmeReq );
mluis 0:cb80564f40e1 925 }
mluis 3:de1dcfbe175a 926 DeviceState = DEVICE_STATE_SLEEP;
mluis 0:cb80564f40e1 927 #else
mluis 0:cb80564f40e1 928 mibReq.Type = MIB_NET_ID;
mluis 0:cb80564f40e1 929 mibReq.Param.NetID = LORAWAN_NETWORK_ID;
mluis 0:cb80564f40e1 930 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:cb80564f40e1 931
mluis 0:cb80564f40e1 932 mibReq.Type = MIB_DEV_ADDR;
mluis 0:cb80564f40e1 933 mibReq.Param.DevAddr = DevAddr;
mluis 0:cb80564f40e1 934 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:cb80564f40e1 935
mluis 0:cb80564f40e1 936 mibReq.Type = MIB_NWK_SKEY;
mluis 0:cb80564f40e1 937 mibReq.Param.NwkSKey = NwkSKey;
mluis 0:cb80564f40e1 938 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:cb80564f40e1 939
mluis 0:cb80564f40e1 940 mibReq.Type = MIB_APP_SKEY;
mluis 0:cb80564f40e1 941 mibReq.Param.AppSKey = AppSKey;
mluis 0:cb80564f40e1 942 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:cb80564f40e1 943
mluis 0:cb80564f40e1 944 mibReq.Type = MIB_NETWORK_JOINED;
mluis 0:cb80564f40e1 945 mibReq.Param.IsNetworkJoined = true;
mluis 0:cb80564f40e1 946 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:cb80564f40e1 947
mluis 0:cb80564f40e1 948 DeviceState = DEVICE_STATE_SEND;
mluis 0:cb80564f40e1 949 #endif
mluis 0:cb80564f40e1 950 IsNetworkJoinedStatusUpdate = true;
mluis 0:cb80564f40e1 951 break;
mluis 0:cb80564f40e1 952 }
mluis 0:cb80564f40e1 953 case DEVICE_STATE_SEND:
mluis 0:cb80564f40e1 954 {
mluis 0:cb80564f40e1 955 if( NextTx == true )
mluis 0:cb80564f40e1 956 {
mluis 0:cb80564f40e1 957 SerialDisplayUpdateUplinkAcked( false );
mluis 0:cb80564f40e1 958 SerialDisplayUpdateDonwlinkRxData( false );
mluis 0:cb80564f40e1 959 PrepareTxFrame( AppPort );
mluis 0:cb80564f40e1 960
mluis 0:cb80564f40e1 961 NextTx = SendFrame( );
mluis 0:cb80564f40e1 962 }
mluis 0:cb80564f40e1 963 if( ComplianceTest.Running == true )
mluis 0:cb80564f40e1 964 {
mluis 1:21e3eef8200f 965 // Schedule next packet transmission
mluis 1:21e3eef8200f 966 TxDutyCycleTime = 5000000; // 5000000 us
mluis 0:cb80564f40e1 967 }
mluis 0:cb80564f40e1 968 else
mluis 0:cb80564f40e1 969 {
mluis 0:cb80564f40e1 970 // Schedule next packet transmission
mluis 0:cb80564f40e1 971 TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND );
mluis 0:cb80564f40e1 972 }
mluis 0:cb80564f40e1 973 DeviceState = DEVICE_STATE_CYCLE;
mluis 0:cb80564f40e1 974 break;
mluis 0:cb80564f40e1 975 }
mluis 0:cb80564f40e1 976 case DEVICE_STATE_CYCLE:
mluis 0:cb80564f40e1 977 {
mluis 1:21e3eef8200f 978 DeviceState = DEVICE_STATE_SLEEP;
mluis 1:21e3eef8200f 979
mluis 0:cb80564f40e1 980 // Schedule next packet transmission
mluis 0:cb80564f40e1 981 TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime );
mluis 0:cb80564f40e1 982 TimerStart( &TxNextPacketTimer );
mluis 0:cb80564f40e1 983 break;
mluis 0:cb80564f40e1 984 }
mluis 0:cb80564f40e1 985 case DEVICE_STATE_SLEEP:
mluis 0:cb80564f40e1 986 {
mluis 0:cb80564f40e1 987 // Wake up through events
mluis 0:cb80564f40e1 988 break;
mluis 0:cb80564f40e1 989 }
mluis 0:cb80564f40e1 990 default:
mluis 0:cb80564f40e1 991 {
mluis 0:cb80564f40e1 992 DeviceState = DEVICE_STATE_INIT;
mluis 0:cb80564f40e1 993 break;
mluis 0:cb80564f40e1 994 }
mluis 0:cb80564f40e1 995
mluis 0:cb80564f40e1 996 }
mluis 1:21e3eef8200f 997
mluis 0:cb80564f40e1 998 // Read light sensor
mluis 1:21e3eef8200f 999 LightValue = ( 1 - ( LightSens.read( ) * 1.65 ) );
mluis 1:21e3eef8200f 1000
mluis 0:cb80564f40e1 1001 // Set automatic RGB from light sensor
mluis 0:cb80564f40e1 1002 if( LightMode == 0 )
mluis 0:cb80564f40e1 1003 {
mluis 1:21e3eef8200f 1004 ColorLed.setColorRGB( 0, ( uint8_t )( 255 * LightValue ), ( uint8_t )( 255 * LightValue ), ( uint8_t )( 255 * LightValue ) );
mluis 0:cb80564f40e1 1005 }
mluis 0:cb80564f40e1 1006 }
mluis 0:cb80564f40e1 1007 }