Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: SX1272lib-PABOOST-HW-Modification mbed
Fork of LoRaWAN_ELMO_TxRx_Template by
Diff: main.cpp
- Revision:
- 1:2be292bd43f9
- Parent:
- 0:c58229885f95
- Child:
- 3:73c2fa59588c
--- a/main.cpp Wed Dec 16 14:25:16 2015 +0000
+++ b/main.cpp Tue Mar 15 23:27:24 2016 +0000
@@ -1,34 +1,28 @@
-/*
-
-Description: MBED LoRaWAN example application
-
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 Semtech
+Description: LoRaMac classA device implementation
License: Revised BSD License, see LICENSE.TXT file include in the project
-
-Maintainer: Espotel
+Maintainer: Miguel Luis and Gregory Cristian
*/
-#include "mbed.h"
+/*! \file classA/LoRaMote/main.c */
#include <string.h>
#include <math.h>
-//#include "board.h"
-
-#include "LoRaMac.h"
-#include "utilities.h"
+#include "mbed.h"
-#define USE_BAND_868
-/*!
- * 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
+#include "utilities.h"
+#include "LoRaMac.h"
+#include "Comissioning.h"
-/*!
- * Indicates if the end-device is to be connected to a private or public network
- */
-#define LORAWAN_PUBLIC_NETWORK true
-#if( OVER_THE_AIR_ACTIVATION != 0 )
+DigitalOut Led1(LED1);
+DigitalOut Led2(LED2);
/*!
* Join requests trials duty cycle.
@@ -36,65 +30,15 @@
#define OVER_THE_AIR_ACTIVATION_DUTYCYCLE 10000000 // 10 [s] value in us
/*!
- * Mote device IEEE EUI
- *
- * \remark must be written as a little endian value (reverse order of normal reading)
- *
- * \remark In this application the value is automatically generated by calling
- * BoardGetUniqueId function
+ * Defines the application data transmission duty cycle. 5s, value in [us].
*/
-#define LORAWAN_DEVICE_EUI { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
-
-/*!
- * Application IEEE EUI
- *
- * \remark must be written as a little endian value (reverse order of normal reading)
- */
-//#define LORAWAN_APPLICATION_EUI { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }
-#define LORAWAN_APPLICATION_EUI { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
-
-/*!
- * AES encryption/decryption cipher application key
- */
-
-#define LORAWAN_APPLICATION_KEY { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00 }
-//#define LORAWAN_APPLICATION_KEY { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
-
-#else
+#define APP_TX_DUTYCYCLE 5000000
/*!
- * Current network ID
- */
-#define LORAWAN_NETWORK_ID ( uint32_t )0
-
-/*!
- * Device address on the network
- *
- * \remark must be written as a big endian value (normal reading order)
- *
- * \remark In this application the value is automatically generated using
- * a pseudo random generator seeded with a value derived from
- * BoardUniqueId value
+ * Defines a random delay for application data transmission duty cycle. 1s,
+ * value in [us].
*/
-#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 }
-
-#endif
-
-/*!
- * Defines the application data transmission duty cycle
- */
-#define APP_TX_DUTYCYCLE 5000000 // 5 [s] value in us
-#define APP_TX_DUTYCYCLE_RND 1000000 // 1 [s] value in us
+#define APP_TX_DUTYCYCLE_RND 1000000
/*!
* LoRaWAN confirmed messages
@@ -102,19 +46,37 @@
#define LORAWAN_CONFIRMED_MSG_ON false
/*!
- * LoRaWAN Adaptative Data Rate
+ * LoRaWAN Adaptive Data Rate
*
* \remark Please note that when ADR is enabled the end-device should be static
*/
#define LORAWAN_ADR_ON 1
+#if defined( USE_BAND_868 )
+
+#include "LoRaMacTest.h"
+
/*!
* LoRaWAN ETSI duty cycle control enable/disable
*
* \remark Please note that ETSI mandates duty cycled transmissions. Use only for test purposes
*/
#define LORAWAN_DUTYCYCLE_ON true
-#define LORAWAN_DUTYCYCLE_OFF false
+
+#define USE_SEMTECH_DEFAULT_CHANNEL_LINEUP 1
+
+#if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 )
+
+#define LC4 { 867100000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
+#define LC5 { 867300000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
+#define LC6 { 867500000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
+#define LC7 { 867700000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
+#define LC8 { 867900000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
+#define LC9 { 868800000, { ( ( DR_7 << 4 ) | DR_7 ) }, 2 }
+
+#endif
+
+#endif
/*!
* LoRaWAN application port
@@ -124,8 +86,16 @@
/*!
* User application data buffer size
*/
+#if defined( USE_BAND_868 )
+
#define LORAWAN_APP_DATA_SIZE 16
+#elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
+
+#define LORAWAN_APP_DATA_SIZE 11
+
+#endif
+
#if( OVER_THE_AIR_ACTIVATION != 0 )
static uint8_t DevEui[] = LORAWAN_DEVICE_EUI;
@@ -145,11 +115,6 @@
#endif
/*!
- * Indicates if the MAC layer has already joined a network.
- */
-static bool IsNetworkJoined = false;
-
-/*!
* Application port
*/
static uint8_t AppPort = LORAWAN_APP_PORT;
@@ -169,7 +134,6 @@
*/
static uint8_t AppData[LORAWAN_APP_DATA_MAX_SIZE];
-
/*!
* Indicates if the node is sending confirmed or unconfirmed messages
*/
@@ -180,49 +144,62 @@
*/
static uint32_t TxDutyCycleTime;
+/*!
+ * Timer to handle the application data transmission duty cycle
+ */
+static Timeout TxNextPacketTimer;
-static void OnTxNextPacketTimerEvent( void );
-static Timeout TxNextPacketTimer;//(OnTxNextPacketTimerEvent, osTimerOnce);
-
-#if( OVER_THE_AIR_ACTIVATION != 0 )
+/*!
+ * Specifies the state of the application LED
+ */
+static bool AppLedStateOn = false;
-static void OnJoinReqTimerEvent( void );
/*!
- * Defines the join request timer
+ * Timer to handle the state of LED1
*/
-static Timeout JoinReqTimer;//(OnJoinReqTimerEvent, osTimerOnce);
+static Timeout Led1Timer;
-#endif
+/*!
+ * Timer to handle the state of LED2
+ */
+static Timeout Led2Timer;
/*!
* Indicates if a new packet can be sent
*/
-static bool TxNextPacket = true;
-static bool ScheduleNextTx = false;
-static bool DownlinkStatusUpdate = false;
-
-static bool AppLedStateOn = false;
+static bool NextTx = true;
-static LoRaMacCallbacks_t LoRaMacCallbacks;
-/*
-static TimerEvent_t Led1Timer;
-volatile bool Led1StateChanged = false;
-static TimerEvent_t Led2Timer;
-volatile bool Led2StateChanged = false;
-static TimerEvent_t Led4Timer;
-volatile bool Led4StateChanged = false;
-
-volatile bool Led3StateChanged = false;
-*/
-static bool ComplianceTestOn = false;
-static uint8_t ComplianceTestState = 0;
-static uint16_t ComplianceTestDownLinkCounter = 0;
-static bool ComplianceTestLinkCheck = false;
-static uint8_t ComplianceTestDemodMargin = 0;
-static uint8_t ComplianceTestNbGateways = 0;
+/*!
+ * Device states
+ */
+static enum eDevicState
+{
+ DEVICE_STATE_INIT,
+ DEVICE_STATE_JOIN,
+ DEVICE_STATE_SEND,
+ DEVICE_STATE_CYCLE,
+ DEVICE_STATE_SLEEP
+}DeviceState;
/*!
- * Prepares the frame buffer to be sent
+ * LoRaWAN compliance tests support data
+ */
+struct ComplianceTest_s
+{
+ bool Running;
+ uint8_t State;
+ bool IsTxConfirmed;
+ uint8_t AppPort;
+ uint8_t AppDataSize;
+ uint8_t *AppDataBuffer;
+ uint16_t DownLinkCounter;
+ bool LinkCheck;
+ uint8_t DemodMargin;
+ uint8_t NbGateways;
+}ComplianceTest;
+
+/*!
+ * \brief Prepares the payload of the frame
*/
static void PrepareTxFrame( uint8_t port )
{
@@ -230,6 +207,7 @@
{
case 2:
{
+#if defined( USE_BAND_868 )
uint16_t pressure = 0;
int16_t altitudeBar = 0;
int16_t temperature = 0;
@@ -260,109 +238,334 @@
AppData[13] = longitude & 0xFF;
AppData[14] = ( altitudeGps >> 8 ) & 0xFF;
AppData[15] = altitudeGps & 0xFF;
+#elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
+ int16_t temperature = 0;
+ int32_t latitude, longitude = 0;
+ uint16_t altitudeGps = 0xFFFF;
+ uint8_t batteryLevel = 0;
+
+ temperature = ( int16_t )( MPL3115ReadTemperature( ) * 100 ); // in °C * 100
+
+ batteryLevel = BoardGetBatteryLevel( ); // 1 (very low) to 254 (fully charged)
+ GpsGetLatestGpsPositionBinary( &latitude, &longitude );
+ altitudeGps = GpsGetLatestGpsAltitude( ); // in m
+
+ AppData[0] = AppLedStateOn;
+ AppData[1] = temperature;
+ AppData[2] = batteryLevel;
+ AppData[3] = ( latitude >> 16 ) & 0xFF;
+ AppData[4] = ( latitude >> 8 ) & 0xFF;
+ AppData[5] = latitude & 0xFF;
+ AppData[6] = ( longitude >> 16 ) & 0xFF;
+ AppData[7] = ( longitude >> 8 ) & 0xFF;
+ AppData[8] = longitude & 0xFF;
+ AppData[9] = ( altitudeGps >> 8 ) & 0xFF;
+ AppData[10] = altitudeGps & 0xFF;
+#endif
}
break;
case 224:
- if( ComplianceTestLinkCheck == true )
+ if( ComplianceTest.LinkCheck == true )
{
- printf("ComplianceTestLinkCheck\r\n");
- ComplianceTestLinkCheck = false;
+ ComplianceTest.LinkCheck = false;
AppDataSize = 3;
AppData[0] = 5;
- AppData[1] = ComplianceTestDemodMargin;
- AppData[2] = ComplianceTestNbGateways;
- ComplianceTestState = 1;
+ AppData[1] = ComplianceTest.DemodMargin;
+ AppData[2] = ComplianceTest.NbGateways;
+ ComplianceTest.State = 1;
}
else
{
- if( ComplianceTestState == 1 )
+ switch( ComplianceTest.State )
{
- printf("Sending downlink COUNTER!!!!\r\n");
+ case 4:
+ ComplianceTest.State = 1;
+ break;
+ case 1:
AppDataSize = 2;
- AppData[0] = ComplianceTestDownLinkCounter >> 8;
- AppData[1] = ComplianceTestDownLinkCounter;
+ AppData[0] = ComplianceTest.DownLinkCounter >> 8;
+ AppData[1] = ComplianceTest.DownLinkCounter;
+ break;
}
}
+ break;
default:
break;
}
}
-static void ProcessRxFrame( LoRaMacEventFlags_t *flags, LoRaMacEventInfo_t *info )
+/*!
+ * \brief Prepares the payload of the frame
+ *
+ * \retval [0: frame could be send, 1: error]
+ */
+static bool SendFrame( void )
{
- switch( info->RxPort ) // Check Rx port number
+ McpsReq_t mcpsReq;
+ LoRaMacTxInfo_t txInfo;
+
+ if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK )
+ {
+ // Send empty frame in order to flush MAC commands
+ mcpsReq.Type = MCPS_UNCONFIRMED;
+ mcpsReq.Req.Unconfirmed.fBuffer = NULL;
+ mcpsReq.Req.Unconfirmed.fBufferSize = 0;
+ mcpsReq.Req.Unconfirmed.Datarate = DR_0;
+ }
+ else
+ {
+ if( IsTxConfirmed == false )
+ {
+ mcpsReq.Type = MCPS_UNCONFIRMED;
+ mcpsReq.Req.Unconfirmed.fPort = AppPort;
+ mcpsReq.Req.Unconfirmed.fBuffer = AppData;
+ mcpsReq.Req.Unconfirmed.fBufferSize = AppDataSize;
+ mcpsReq.Req.Unconfirmed.Datarate = DR_0;
+ }
+ else
+ {
+ mcpsReq.Type = MCPS_CONFIRMED;
+ mcpsReq.Req.Confirmed.fPort = AppPort;
+ mcpsReq.Req.Confirmed.fBuffer = AppData;
+ mcpsReq.Req.Confirmed.fBufferSize = AppDataSize;
+ mcpsReq.Req.Confirmed.NbTrials = 8;
+ mcpsReq.Req.Confirmed.Datarate = DR_0;
+ }
+ }
+
+ if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK )
+ {
+ return false;
+ }
+ return true;
+}
+
+/*!
+ * \brief Function executed on TxNextPacket Timeout event
+ */
+static void OnTxNextPacketTimerEvent( void )
+{
+ MibRequestConfirm_t mibReq;
+ LoRaMacStatus_t status;
+
+ TxNextPacketTimer.detach();
+
+ mibReq.Type = MIB_NETWORK_JOINED;
+ status = LoRaMacMibGetRequestConfirm( &mibReq );
+
+ if( status == LORAMAC_STATUS_OK )
{
- case 1: // The application LED can be controlled on port 1 or 2
- case 2:
- if( info->RxBufferSize == 1 )
+ if( mibReq.Param.IsNetworkJoined == true )
+ {
+ DeviceState = DEVICE_STATE_SEND;
+ NextTx = true;
+ }
+ else
+ {
+ DeviceState = DEVICE_STATE_JOIN;
+ }
+ }
+}
+
+/*!
+ * \brief Function executed on Led 1 Timeout event
+ */
+static void OnLed1TimerEvent( void )
+{
+ Led1Timer.detach();
+ // Switch LED 1 OFF
+ Led1 = 1;
+}
+
+/*!
+ * \brief Function executed on Led 2 Timeout event
+ */
+static void OnLed2TimerEvent( void )
+{
+ Led2Timer.detach();
+ // Switch LED 2 OFF
+ Led2 = 1;
+}
+
+/*!
+ * \brief MCPS-Confirm event function
+ *
+ * \param [IN] McpsConfirm - Pointer to the confirm structure,
+ * containing confirm attributes.
+ */
+static void McpsConfirm( McpsConfirm_t *McpsConfirm )
+{
+ if( McpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
+ {
+ switch( McpsConfirm->McpsRequest )
{
- AppLedStateOn = info->RxBuffer[0] & 0x01;
- //Led3StateChanged = true;
+ case MCPS_UNCONFIRMED:
+ {
+ // Check Datarate
+ // Check TxPower
+ break;
+ }
+ case MCPS_CONFIRMED:
+ {
+ // Check Datarate
+ // Check TxPower
+ // Check AckReceived
+ // Check NbTrials
+ break;
+ }
+ case MCPS_PROPRIETARY:
+ {
+ break;
+ }
+ default:
+ break;
}
- break;
+
+ // Switch LED 1 ON
+ Led1 = 0;
+ Led1Timer.attach_us(OnLed1TimerEvent, 25000);
+ }
+ NextTx = true;
+}
+
+/*!
+ * \brief MCPS-Indication event function
+ *
+ * \param [IN] McpsIndication - Pointer to the indication structure,
+ * containing indication attributes.
+ */
+static void McpsIndication( McpsIndication_t *McpsIndication )
+{
+ if( McpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK )
+ {
+ return;
+ }
+
+ switch( McpsIndication->McpsIndication )
+ {
+ case MCPS_UNCONFIRMED:
+ {
+ break;
+ }
+ case MCPS_CONFIRMED:
+ {
+ break;
+ }
+ case MCPS_PROPRIETARY:
+ {
+ break;
+ }
+ case MCPS_MULTICAST:
+ {
+ break;
+ }
+ default:
+ break;
+ }
+
+ // Check Multicast
+ // Check Port
+ // Check Datarate
+ // Check FramePending
+ // Check Buffer
+ // Check BufferSize
+ // Check Rssi
+ // Check Snr
+ // Check RxSlot
+
+ if( ComplianceTest.Running == true )
+ {
+ ComplianceTest.DownLinkCounter++;
+ }
+
+ if( McpsIndication->RxData == true )
+ {
+ switch( McpsIndication->Port )
+ {
+ case 1: // The application LED can be controlled on port 1 or 2
+ case 2:
+ if( McpsIndication->BufferSize == 1 )
+ {
+ AppLedStateOn = McpsIndication->Buffer[0] & 0x01;
+ //GpioWrite( &Led3, ( ( AppLedStateOn & 0x01 ) != 0 ) ? 0 : 1 );
+ }
+ break;
case 224:
- if( ComplianceTestOn == false )
+ if( ComplianceTest.Running == false )
{
// Check compliance test enable command (i)
- if( ( info->RxBufferSize == 4 ) &&
- ( info->RxBuffer[0] == 0x01 ) &&
- ( info->RxBuffer[1] == 0x01 ) &&
- ( info->RxBuffer[2] == 0x01 ) &&
- ( info->RxBuffer[3] == 0x01 ) )
+ if( ( McpsIndication->BufferSize == 4 ) &&
+ ( McpsIndication->Buffer[0] == 0x01 ) &&
+ ( McpsIndication->Buffer[1] == 0x01 ) &&
+ ( McpsIndication->Buffer[2] == 0x01 ) &&
+ ( McpsIndication->Buffer[3] == 0x01 ) )
{
IsTxConfirmed = false;
AppPort = 224;
AppDataSize = 2;
- ComplianceTestDownLinkCounter = 0;
- ComplianceTestLinkCheck = false;
- ComplianceTestDemodMargin = 0;
- ComplianceTestNbGateways = 0;
- ComplianceTestOn = true;
- ComplianceTestState = 1;
+ ComplianceTest.DownLinkCounter = 0;
+ ComplianceTest.LinkCheck = false;
+ ComplianceTest.DemodMargin = 0;
+ ComplianceTest.NbGateways = 0;
+ ComplianceTest.Running = true;
+ ComplianceTest.State = 1;
- LoRaMacSetAdrOn( true );
- LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_OFF );
+ MibRequestConfirm_t mibReq;
+ mibReq.Type = MIB_ADR;
+ mibReq.Param.AdrEnable = true;
+ LoRaMacMibSetRequestConfirm( &mibReq );
+
+#if defined( USE_BAND_868 )
+ LoRaMacTestSetDutyCycleOn( false );
+#endif
}
}
else
{
- ComplianceTestState = info->RxBuffer[0];
- switch( ComplianceTestState )
+ ComplianceTest.State = McpsIndication->Buffer[0];
+ switch( ComplianceTest.State )
{
case 0: // Check compliance test disable command (ii)
IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
AppPort = LORAWAN_APP_PORT;
AppDataSize = LORAWAN_APP_DATA_SIZE;
- ComplianceTestDownLinkCounter = 0;
- ComplianceTestOn = false;
+ ComplianceTest.DownLinkCounter = 0;
+ ComplianceTest.Running = false;
- LoRaMacSetAdrOn( LORAWAN_ADR_ON );
+ MibRequestConfirm_t mibReq;
+ mibReq.Type = MIB_ADR;
+ mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
+ LoRaMacMibSetRequestConfirm( &mibReq );
+#if defined( USE_BAND_868 )
LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
+#endif
break;
case 1: // (iii, iv)
AppDataSize = 2;
break;
case 2: // Enable confirmed messages (v)
IsTxConfirmed = true;
- ComplianceTestState = 1;
+ ComplianceTest.State = 1;
break;
case 3: // Disable confirmed messages (vi)
IsTxConfirmed = false;
- ComplianceTestState = 1;
+ ComplianceTest.State = 1;
break;
case 4: // (vii)
- AppDataSize = info->RxBufferSize;
- printf("VII <------------------- rozmiar %i \r\n", AppDataSize);
+ AppDataSize = McpsIndication->BufferSize;
+
AppData[0] = 4;
for( uint8_t i = 1; i < AppDataSize; i++ )
{
-
- printf("VII <-------------------dodaje \r\n");
- AppData[i] = info->RxBuffer[i] + 1;
+ AppData[i] = McpsIndication->Buffer[i] + 1;
}
break;
case 5: // (viii)
- LoRaMacLinkCheckReq( );
+ {
+ MlmeReq_t mlmeReq;
+ mlmeReq.Type = MLME_LINK_CHECK;
+ LoRaMacMlmeRequest( &mlmeReq );
+ }
break;
default:
break;
@@ -371,274 +574,196 @@
break;
default:
break;
- }
-
- if( ( ComplianceTestOn == true ) && ( flags->Bits.LinkCheck == 1 ) )
- {
- ComplianceTestLinkCheck = true;
- ComplianceTestDemodMargin = info->DemodMargin;
- ComplianceTestNbGateways = info->NbGateways;
- }
-
- #warning needed extension to check counter scopes
-}
-
-static bool SendFrame( void )
-{
- uint8_t sendFrameStatus = 0;
-
- if( IsTxConfirmed == false )
- {
- sendFrameStatus = LoRaMacSendFrame( AppPort, AppData, AppDataSize );
- }
- else
- {
- sendFrameStatus = LoRaMacSendConfirmedFrame( AppPort, AppData, AppDataSize, 8 );
+ }
}
- switch( sendFrameStatus )
- {
- case 5: // NO_FREE_CHANNEL
- // Try again later
- return true;
- default:
- return false;
- }
-}
-
-#if( OVER_THE_AIR_ACTIVATION != 0 )
-
-/*!
- * \brief Function executed on JoinReq Timeout event
- */
-static void OnJoinReqTimerEvent( void )
-{
- JoinReqTimer.detach();
- TxNextPacket = true;
-}
-
-#endif
-
-/*!
- * \brief Function executed on TxNextPacket Timeout event
- */
-static void OnTxNextPacketTimerEvent( void )
-{
- //TimerStop( &TxNextPacketTimer );
- //TxNextPacketTimer.stop();
- TxNextPacketTimer.detach();
- TxNextPacket = true;
+ // Switch LED 2 ON for each received downlink
+ Led2 = 0;
+ Led2Timer.attach_us(OnLed2TimerEvent, 25000);
}
/*!
- * \brief Function executed on Led 1 Timeout event
- */
-/*static void OnLed1TimerEvent( void )
-{
- TimerStop( &Led1Timer );
- Led1StateChanged = true;
-}*/
-
-/*!
- * \brief Function executed on Led 2 Timeout event
- */
-/*static void OnLed2TimerEvent( void )
-{
- TimerStop( &Led2Timer );
- Led2StateChanged = true;
-}*/
-
-/*!
- * \brief Function executed on Led 4 Timeout event
- */
-/*void OnLed4TimerEvent( void )
-{
- TimerStop( &Led4Timer );
- Led4StateChanged = true;
-}*/
-
-/*!
- * \brief Function to be executed on MAC layer event
+ * \brief MLME-Confirm event function
+ *
+ * \param [IN] MlmeConfirm - Pointer to the confirm structure,
+ * containing confirm attributes.
*/
-static void OnMacEvent( LoRaMacEventFlags_t *flags, LoRaMacEventInfo_t *info )
+static void MlmeConfirm( MlmeConfirm_t *MlmeConfirm )
{
- if( flags->Bits.JoinAccept == 1 )
+ if( MlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
{
-#if( OVER_THE_AIR_ACTIVATION != 0 )
- JoinReqTimer.detach();
-#endif
- IsNetworkJoined = true;
- }
- else
- {
- if( flags->Bits.Tx == 1 )
+ switch( MlmeConfirm->MlmeRequest )
{
- }
-
- if( flags->Bits.Rx == 1 )
- {
- if( ComplianceTestOn == true )
+ case MLME_JOIN:
{
- ComplianceTestDownLinkCounter++;
+ // Status is OK, node has joined the network
+ break;
}
- if( flags->Bits.RxData == true )
+ case MLME_LINK_CHECK:
{
- ProcessRxFrame( flags, info );
+ // Check DemodMargin
+ // Check NbGateways
+ if( ComplianceTest.Running == true )
+ {
+ ComplianceTest.LinkCheck = true;
+ ComplianceTest.DemodMargin = MlmeConfirm->DemodMargin;
+ ComplianceTest.NbGateways = MlmeConfirm->NbGateways;
+ }
+ break;
}
-
- DownlinkStatusUpdate = true;
- //TimerStart( &Led2Timer );
+ default:
+ break;
}
}
- // Schedule a new transmission
- ScheduleNextTx = true;
+ NextTx = true;
}
/**
* Main application entry point.
*/
-
int main( void )
{
-#if( OVER_THE_AIR_ACTIVATION != 0 )
- uint8_t sendFrameStatus = 0;
-#endif
- bool trySendingFrameAgain = false;
+ LoRaMacPrimitives_t LoRaMacPrimitives;
+ LoRaMacCallback_t LoRaMacCallbacks;
+ MibRequestConfirm_t mibReq;
-#warning HW and RADIO CHIP must be configured!!!!
//BoardInitMcu( );
//BoardInitPeriph( );
- //hal_init();
- //radio_init();
- LoRaMacCallbacks.MacEvent = OnMacEvent;
- //LoRaMacCallbacks.GetBatteryLevel = BoardGetBatteryLevel;
- LoRaMacInit( &LoRaMacCallbacks );
-
- IsNetworkJoined = false;
-
-#if( OVER_THE_AIR_ACTIVATION == 0 )
- // Random seed initialization
- #warning seed initialization must be implemented
- srand1( 1 );
- // Choose a random device address based on Board unique ID
- // NwkAddr rand [0, 33554431]
- DevAddr = randr( 0, 0x01FFFFFF );
-
- LoRaMacInitNwkIds( LORAWAN_NETWORK_ID, DevAddr, NwkSKey, AppSKey );
- IsNetworkJoined = true;
-#else
- // Initialize LoRaMac device unique ID
- //BoardGetUniqueId( DevEui );
-#endif
-
- TxNextPacket = true;
-
- //TimerInit( &Led1Timer, OnLed1TimerEvent );
- //TimerSetValue( &Led1Timer, 25000 );
-
- //TimerInit( &Led2Timer, OnLed2TimerEvent );
- //TimerSetValue( &Led2Timer, 25000 );
-
- //TimerInit( &Led4Timer, OnLed4TimerEvent );
- //TimerSetValue( &Led4Timer, 25000 );
-
- LoRaMacSetAdrOn( LORAWAN_ADR_ON );
- #warning dutycycleON OFFFFFFFFFFFFF!!!!!!!!!!!!!!!!!!!!!!!
-// LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
- LoRaMacTestSetDutyCycleOn( 0 );
- LoRaMacSetPublicNetwork( LORAWAN_PUBLIC_NETWORK );
+ DeviceState = DEVICE_STATE_INIT;
while( 1 )
{
- while( IsNetworkJoined == false )
- {
-#if( OVER_THE_AIR_ACTIVATION != 0 )
- if( TxNextPacket == true )
- {
- printf("Trial to join network... txnextpacket %i \r\n", TxNextPacket);
- TxNextPacket = false;
-
- sendFrameStatus = LoRaMacJoinReq( DevEui, AppEui, AppKey );
- printf("status = %i\r\n", sendFrameStatus);
- switch( sendFrameStatus )
- {
- case 1: // BUSY
- printf("busy...\r\n");
- break;
- case 0: // OK
- case 2: // NO_NETWORK_JOINED
- case 3: // LENGTH_PORT_ERROR
- case 4: // MAC_CMD_ERROR
- case 6: // DEVICE_OFF
- default:
- // Relaunch timer for next trial
- JoinReqTimer.attach_us(OnJoinReqTimerEvent, OVER_THE_AIR_ACTIVATION_DUTYCYCLE);
- break;
- }
- }
- //TimerLowPowerHandler( );
-#endif
- }
-
-/*
- if( Led1StateChanged == true )
- {
- Led1StateChanged = false;
- // Switch LED 1 OFF
- GpioWrite( &Led1, 1 );
- }
- if( Led2StateChanged == true )
- {
- Led2StateChanged = false;
- // Switch LED 2 OFF
- GpioWrite( &Led2, 1 );
- }
- if( Led3StateChanged == true )
+ switch( DeviceState )
{
- Led3StateChanged = false;
- GpioWrite( &Led3, ( ( AppLedStateOn & 0x01 ) != 0 ) ? 0 : 1 );
- }
- if( Led4StateChanged == true )
- {
- Led4StateChanged = false;
- // Switch LED 4 OFF
- GpioWrite( &Led4, 1 );
- }*/
- if( DownlinkStatusUpdate == true )
- {
- DownlinkStatusUpdate = false;
- // Switch LED 2 ON for each received downlink
- //GpioWrite( &Led2, 0 );
- }
+ case DEVICE_STATE_INIT:
+ {
+ LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm;
+ LoRaMacPrimitives.MacMcpsIndication = McpsIndication;
+ LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm;
+ //LoRaMacCallbacks.GetBatteryLevel = BoardGetBatteryLevel;
+ LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks );
+
+ mibReq.Type = MIB_ADR;
+ mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
+ LoRaMacMibSetRequestConfirm( &mibReq );
+
+ mibReq.Type = MIB_PUBLIC_NETWORK;
+ mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK;
+ LoRaMacMibSetRequestConfirm( &mibReq );
+
+#if defined( USE_BAND_868 )
+ LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
+
+#if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 )
+ LoRaMacChannelAdd( 3, ( ChannelParams_t )LC4 );
+ LoRaMacChannelAdd( 4, ( ChannelParams_t )LC5 );
+ LoRaMacChannelAdd( 5, ( ChannelParams_t )LC6 );
+ LoRaMacChannelAdd( 6, ( ChannelParams_t )LC7 );
+ LoRaMacChannelAdd( 7, ( ChannelParams_t )LC8 );
+ LoRaMacChannelAdd( 8, ( ChannelParams_t )LC9 );
+#endif
- if( ScheduleNextTx == true )
- {
- printf("Sending data...");
- ScheduleNextTx = false;
+#endif
+ DeviceState = DEVICE_STATE_JOIN;
+ break;
+ }
+ case DEVICE_STATE_JOIN:
+ {
+#if( OVER_THE_AIR_ACTIVATION != 0 )
+ MlmeReq_t mlmeReq;
+
+ #warning BoardGetUniqueId not needed in test software - commented out
+ // Initialize LoRaMac device unique ID
+ // BoardGetUniqueId( DevEui );
+
+ mlmeReq.Type = MLME_JOIN;
+
+ mlmeReq.Req.Join.DevEui = DevEui;
+ mlmeReq.Req.Join.AppEui = AppEui;
+ mlmeReq.Req.Join.AppKey = AppKey;
+
+ if( NextTx == true )
+ {
+ LoRaMacMlmeRequest( &mlmeReq );
+ }
+
+ // Schedule next packet transmission
+ TxDutyCycleTime = OVER_THE_AIR_ACTIVATION_DUTYCYCLE;
+ DeviceState = DEVICE_STATE_CYCLE;
+
+#else
+ // Random seed initialization
+ srand1( BoardGetRandomSeed( ) );
+
+ // Choose a random device address
+ DevAddr = randr( 0, 0x01FFFFFF );
- // Schedule next packet transmission
- TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND );
- TxNextPacketTimer.attach_us(OnTxNextPacketTimerEvent, TxDutyCycleTime);
- }
+ mibReq.Type = MIB_NET_ID;
+ mibReq.Param.NetID = LORAWAN_NETWORK_ID;
+ LoRaMacMibSetRequestConfirm( &mibReq );
+
+ mibReq.Type = MIB_DEV_ADDR;
+ mibReq.Param.DevAddr = DevAddr;
+ LoRaMacMibSetRequestConfirm( &mibReq );
+
+ mibReq.Type = MIB_NWK_SKEY;
+ mibReq.Param.NwkSKey = NwkSKey;
+ LoRaMacMibSetRequestConfirm( &mibReq );
+
+ mibReq.Type = MIB_APP_SKEY;
+ mibReq.Param.AppSKey = AppSKey;
+ LoRaMacMibSetRequestConfirm( &mibReq );
+
+ mibReq.Type = MIB_NETWORK_JOINED;
+ mibReq.Param.IsNetworkJoined = true;
+ LoRaMacMibSetRequestConfirm( &mibReq );
+
+ DeviceState = DEVICE_STATE_SEND;
+#endif
+ break;
+ }
+ case DEVICE_STATE_SEND:
+ {
+ if( NextTx == true )
+ {
+ PrepareTxFrame( AppPort );
- if( trySendingFrameAgain == true )
- {
- trySendingFrameAgain = SendFrame( );
+ NextTx = SendFrame( );
+ }
+ if( ComplianceTest.Running == true )
+ {
+ // Schedule next packet transmission as soon as possible
+ TxDutyCycleTime = 300000; // 300 ms
+ }
+ else
+ {
+ // Schedule next packet transmission
+ TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND );
+ }
+ DeviceState = DEVICE_STATE_CYCLE;
+ break;
+ }
+ case DEVICE_STATE_CYCLE:
+ {
+ DeviceState = DEVICE_STATE_SLEEP;
+
+ // Schedule next packet transmission
+ TxNextPacketTimer.attach_us(OnTxNextPacketTimerEvent, TxDutyCycleTime);
+ break;
+ }
+ case DEVICE_STATE_SLEEP:
+ {
+ // Wake up through events
+ #warning TimerLowPowerHandler disabled
+ //TimerLowPowerHandler( );
+ break;
+ }
+ default:
+ {
+ DeviceState = DEVICE_STATE_INIT;
+ break;
+ }
}
- if( TxNextPacket == true )
- {
- TxNextPacket = false;
-
- PrepareTxFrame( AppPort );
-
- // Switch LED 1 ON
- //GpioWrite( &Led1, 0 );
- //TimerStart( &Led1Timer );
-
- trySendingFrameAgain = SendFrame( );
- }
-
- //TimerLowPowerHandler( );
}
-}
+}
\ No newline at end of file
