NAMote72 application example using LoRaWAN-lib MAC layer implementation

Dependencies:   LoRaWAN-lib SX1272Lib lib_gps lib_mpl3115a2 mbed

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)
 *
 * \remark In this application the value is automatically generated by calling
 *         BoardGetUniqueId function
 */
#define LORAWAN_DEVICE_EUI                          { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }

/*!
 * 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)
 *
 * \remark In this application the value is automatically generated using
 *         a pseudo random generator seeded with a value derived from
 *         BoardUniqueId value
 */
#define LORAWAN_DEVICE_ADDRESS                      ( uint32_t )0x00000000

/*!
 * 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 5:
        {
            Gps.service( );
            Mpl3115a2.ReadTemperature( );
            AppData[0] = AppLedStateOn;                        // (bit 0 == 1) => LED on
            AppData[1] = ( int32_t )Mpl3115a2.Temperature;     // Signed degrees Celcius in half degree units. So, +/-63 °C
            AppData[2] = BoardGetBatteryLevel( );              // Per LoRaWAN spec; 0 = Charging; 1...254 = level, 255 = N/A
            AppData[3] = ( Gps.LatitudeBinary >> 16 ) & 0xFF;
            AppData[4] = ( Gps.LatitudeBinary >> 8 ) & 0xFF;
            AppData[5] = Gps.LatitudeBinary & 0xFF;
            AppData[6] = ( Gps.LongitudeBinary >> 16 ) & 0xFF;
            AppData[7] = ( Gps.LongitudeBinary >> 8 ) & 0xFF;
            AppData[8] = Gps.LongitudeBinary & 0xFF;

            uint16_t altitudeGps = atoi( Gps.NmeaGpsData.NmeaAltitude );
            AppData[9] = ( altitudeGps >> 8 ) & 0xFF;
            AppData[10] = altitudeGps & 0xFF;
        }
        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                            5
Committer:
mluis
Date:
Mon Apr 24 13:42:18 2017 +0000
Revision:
9:37deeefbfe45
Parent:
7:51e20992a423
WARNING: Radio API timings changed from micro-seconds to milliseconds; ; Synchronized with https://github.com/Lora-net/LoRaMac-node git revision e506c246652fa44c3f24cecb89d0707b49ece739; Updated all libraries to the latest versions

Who changed what in which revision?

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