Astek

Dependencies:   mbed GPS_I2C_astek Sensors LSM9DS1 DigitDisplay Chainable_RGB_LED LoRaWAN-lib SX1272Lib

Committer:
RoddyRod
Date:
Fri Dec 27 16:05:09 2019 +0000
Revision:
10:58fa3853e803
Parent:
9:0083afd69815
astek;

Who changed what in which revision?

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