Application example using LoRaWAN-lib MAC layer implementation

Dependencies:   mbed LoRaWAN-lib SX1272Lib

LoRaWAN-demo is a ClassA device example project using LoRaWAN-lib and SX1272Lib libraries.

This demo application sends a frame every 4 to 6 seconds (randomly) and displays its current status using a serial port as display(VT100).

The serial port settings are as shown in below image. To access the serial port settings please click on "Setup" menu and then "Serial port..."

/media/uploads/mluis/serial_port_settings.png

The terminal window should be setup as shown in below image. To access the terminal window settings please click on "Setup" menu and then "Terminal..."

/media/uploads/mluis/terminal_window_settings.png

The image below shows the VT100 application status.

Application main screen

The application gives the possibility to either activate the device using

  • Over The Air Activation (OTAA)
  • Personalization activation (PA)

The activation mode can be adjusted in Comissioning.h by changing the following parameter:

/*!
 * When set to 1 the application uses the Over-the-Air activation procedure
 * When set to 0 the application uses the Personalization activation procedure
 */
#define OVER_THE_AIR_ACTIVATION                     1


The application gives the possibility to select which kind of network we are connecting to.

  • Public Network (true)
  • Private Network (false)

The netork type can be changed as follows:

/*!
 * Indicates if the end-device is to be connected to a private or public network
 */
#define LORAWAN_PUBLIC_NETWORK                      true


OTAA
When OTAA is selected the user must porvide a device EUI, an application EUI and an application key.
These can be adjusted by changing the following parameters:

/*!
 * Mote device IEEE EUI (big endian)
 */
#define LORAWAN_DEVICE_EUI                          { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 }

/*!
 * Application IEEE EUI (big endian)
 */
#define LORAWAN_APPLICATION_EUI                     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }

/*!
 * AES encryption/decryption cipher application key
 */
#define LORAWAN_APPLICATION_KEY                     { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }


PA
When PA is selected the user must porvide a network ID, a device address, a network session key and an application session key.
These can be adjusted by changing the following parameters:

/*!
 * Current network ID
 */
#define LORAWAN_NETWORK_ID                          ( uint32_t )0

/*!
 * Device address on the network (big endian)
 */
#define LORAWAN_DEVICE_ADDRESS                      ( uint32_t )0x12345678

/*!
 * AES encryption/decryption cipher network session key
 */
#define LORAWAN_NWKSKEY                             { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }

/*!
 * AES encryption/decryption cipher application session key
 */
#define LORAWAN_APPSKEY                             { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }


On top of main.c the user has the possibility to tweak some application settings such as:

  • Join requests transmission frequency
  • Frames transmission frequency
  • Application default datarate
  • Confirmed or Unconfirmed frames transmission
  • ADR (Adaptive Datarate) ON/OFF
  • Application port to be used by the transmitted frames

The join requests transmission frequency can be adjusted by changing the follwoing parameter:

/*!
 * Join requests trials duty cycle.
 */
#define OVER_THE_AIR_ACTIVATION_DUTYCYCLE           10000000  // 10 [s] value in us


The frame transmission frequency can be adjusted by changing the follwoing parameters:

/*!
 * Defines the application data transmission duty cycle. 5s, value in [us].
 */
#define APP_TX_DUTYCYCLE                            5000000

/*!
 * Defines a random delay for application data transmission duty cycle. 1s,
 * value in [us].
 */
#define APP_TX_DUTYCYCLE_RND                        1000000


The frame transmission scheduling is then executed as follows:

        if( ScheduleNextTx == true )
        {
            ScheduleNextTx = false;
            // Schedule next packet transmission
            TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND );
            TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime );
            TimerStart( &TxNextPacketTimer );
        }


The application default datarate can be adjusted by changing the following parameter:

Quote:

When ADR is off this setting is the fixed datarate that will be used by the application.
When ADR is on this setting is the initial datarate used by the application.

/*!
 * Default mote datarate
 */
#define LORAWAN_DEFAULT_DATARATE                    DR_0


The transmitted frame contents will depend on LORAWAN_CONFIRMED_MSG_ON value.

/*!
 * LoRaWAN confirmed messages
 */
#define LORAWAN_CONFIRMED_MSG_ON                    true
  • If LORAWAN_CONFIRMED_MSG_ON equals false then the application payload is one byte corresponding to the AppLed state.
  • If LORAWAN_CONFIRMED_MSG_ON equals true then the application payload is six bytes corresponding to the AppLed state, Downlink counter (unsigned 16 bits), received RSSI (signed 16 bits) and received SNR (signed 8 bits).

/*!
 * \brief   Prepares the payload of the frame
 */
static void PrepareTxFrame( uint8_t port )
{

    switch( port )
    {
    case 15:
        {
            AppData[0] = AppLedStateOn;
            if( IsTxConfirmed == true )
            {
                AppData[1] = LoRaMacDownlinkStatus.DownlinkCounter >> 8;
                AppData[2] = LoRaMacDownlinkStatus.DownlinkCounter;
                AppData[3] = LoRaMacDownlinkStatus.Rssi >> 8;
                AppData[4] = LoRaMacDownlinkStatus.Rssi;
                AppData[5] = LoRaMacDownlinkStatus.Snr;
            }
        }
        break;
    case 224:
...
}


The ADR enabling/disabling can be adjusted by changing the following parameter:

/*!
 * LoRaWAN Adaptive Data Rate
 *
 * \remark Please note that when ADR is enabled the end-device should be static
 */
#define LORAWAN_ADR_ON                              1


The application port can be adjusted by changing the following parameter:

/*!
 * LoRaWAN application port
 */
#define LORAWAN_APP_PORT                            15
Committer:
mluis
Date:
Fri May 13 15:14:44 2016 +0000
Revision:
3:3152aa75c58d
Parent:
2:2eeaeae2c725
Child:
5:62862ef9480b
Updated mbed, LoRaWAN-lib and SX1272Lib libraries.

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