Sending IKS01A1 temperature sensor to LoRaWAN port-5 uplink

Dependencies:   X_NUCLEO_IKS01A1 mbed LoRaWAN-lib SX1276Lib

Fork of LoRaWAN-demo-76 by Semtech

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002  / _____)             _              | |
00003 ( (____  _____ ____ _| |_ _____  ____| |__
00004  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
00005  _____) ) ____| | | || |_| ____( (___| | | |
00006 (______/|_____)_|_|_| \__)_____)\____)_| |_|
00007     (C)2015 Semtech
00008 
00009 Description: LoRaMac classA device implementation
00010 
00011 License: Revised BSD License, see LICENSE.TXT file include in the project
00012 
00013 Maintainer: Miguel Luis and Gregory Cristian
00014 */
00015 #include "mbed.h"
00016 #include "board.h"
00017 #include "radio.h"
00018 
00019 #include "LoRaMac.h"
00020 #include "Comissioning.h"
00021 #include "SerialDisplay.h"
00022 #include "x_nucleo_iks01a1.h"
00023 #include "vt100.h"
00024 extern VT100 vt;
00025 
00026 /*!
00027  * Defines the application data transmission duty cycle. 5s, value in [us].
00028  */
00029 #define APP_TX_DUTYCYCLE                            15000000
00030 
00031 /*!
00032  * Defines a random delay for application data transmission duty cycle. 1s,
00033  * value in [us].
00034  */
00035 #define APP_TX_DUTYCYCLE_RND                        3000000
00036 
00037 /*!
00038  * Default datarate
00039  */
00040 #define LORAWAN_DEFAULT_DATARATE                    DR_0
00041 
00042 /*!
00043  * LoRaWAN confirmed messages
00044  */
00045 #define LORAWAN_CONFIRMED_MSG_ON                    true
00046 
00047 /*!
00048  * LoRaWAN Adaptive Data Rate
00049  *
00050  * \remark Please note that when ADR is enabled the end-device should be static
00051  */
00052 #define LORAWAN_ADR_ON                              1
00053 
00054 #if defined( USE_BAND_868 )
00055 
00056 #include "LoRaMacTest.h"
00057 
00058 /*!
00059  * LoRaWAN ETSI duty cycle control enable/disable
00060  *
00061  * \remark Please note that ETSI mandates duty cycled transmissions. Use only for test purposes
00062  */
00063 #define LORAWAN_DUTYCYCLE_ON                        true
00064 
00065 #define USE_SEMTECH_DEFAULT_CHANNEL_LINEUP          1
00066 
00067 #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 ) 
00068 
00069 #define LC4                { 867100000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
00070 #define LC5                { 867300000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
00071 #define LC6                { 867500000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
00072 #define LC7                { 867700000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
00073 #define LC8                { 867900000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
00074 #define LC9                { 868800000, { ( ( DR_7 << 4 ) | DR_7 ) }, 2 }
00075 #define LC10               { 868300000, { ( ( DR_6 << 4 ) | DR_6 ) }, 1 }
00076 
00077 #endif
00078 
00079 #endif
00080 
00081 /*!
00082  * LoRaWAN application port
00083  */
00084 #define LORAWAN_APP_PORT                            5 //15
00085 
00086 /*!
00087  * User application data buffer size
00088  */
00089 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 )
00090 #define LORAWAN_APP_DATA_SIZE                       6
00091 
00092 #else
00093 #define LORAWAN_APP_DATA_SIZE                       1
00094 
00095 #endif
00096 
00097 static uint8_t DevEui[] = LORAWAN_DEVICE_EUI;
00098 static uint8_t AppEui[] = LORAWAN_APPLICATION_EUI;
00099 static uint8_t AppKey[] = LORAWAN_APPLICATION_KEY;
00100 
00101 #if( OVER_THE_AIR_ACTIVATION == 0 )
00102 
00103 static uint8_t NwkSKey[] = LORAWAN_NWKSKEY;
00104 static uint8_t AppSKey[] = LORAWAN_APPSKEY;
00105 
00106 /*!
00107  * Device address
00108  */
00109 static uint32_t DevAddr = LORAWAN_DEVICE_ADDRESS;
00110 
00111 #endif
00112 
00113 /*!
00114  * Application port
00115  */
00116 static uint8_t AppPort = LORAWAN_APP_PORT;
00117 
00118 /*!
00119  * User application data size
00120  */
00121 static uint8_t AppDataSize = LORAWAN_APP_DATA_SIZE;
00122 
00123 /*!
00124  * User application data buffer size
00125  */
00126 #define LORAWAN_APP_DATA_MAX_SIZE                           64
00127 
00128 /*!
00129  * User application data
00130  */
00131 static uint8_t AppData[LORAWAN_APP_DATA_MAX_SIZE];
00132 
00133 /*!
00134  * Indicates if the node is sending confirmed or unconfirmed messages
00135  */
00136 static uint8_t IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
00137 
00138 /*!
00139  * Defines the application data transmission duty cycle
00140  */
00141 static uint32_t TxDutyCycleTime;
00142 
00143 /*!
00144  * Timer to handle the application data transmission duty cycle
00145  */
00146 static TimerEvent_t TxNextPacketTimer;
00147 
00148 /*!
00149  * Specifies the state of the application LED
00150  */
00151 static bool AppLedStateOn = false;
00152 volatile bool Led3StateChanged = false;
00153 /*!
00154  * Timer to handle the state of LED1
00155  */
00156 static TimerEvent_t Led1Timer;
00157 volatile bool Led1State = false;
00158 volatile bool Led1StateChanged = false;
00159 /*!
00160  * Timer to handle the state of LED2
00161  */
00162 static TimerEvent_t Led2Timer;
00163 volatile bool Led2State = false;
00164 volatile bool Led2StateChanged = false;
00165 
00166 /*!
00167  * Indicates if a new packet can be sent
00168  */
00169 static bool NextTx = true;
00170 
00171 /*!
00172  * Device states
00173  */
00174 static enum eDevicState
00175 {
00176     DEVICE_STATE_INIT,
00177     DEVICE_STATE_JOIN,
00178     DEVICE_STATE_SEND,
00179     DEVICE_STATE_CYCLE,
00180     DEVICE_STATE_SLEEP
00181 }DeviceState;
00182 
00183 /*!
00184  * LoRaWAN compliance tests support data
00185  */
00186 struct ComplianceTest_s
00187 {
00188     bool Running;
00189     uint8_t State;
00190     bool IsTxConfirmed;
00191     uint8_t AppPort;
00192     uint8_t AppDataSize;
00193     uint8_t *AppDataBuffer;
00194     uint16_t DownLinkCounter;
00195     bool LinkCheck;
00196     uint8_t DemodMargin;
00197     uint8_t NbGateways;
00198 }ComplianceTest;
00199 
00200 /*
00201  * SerialDisplay managment variables
00202  */
00203 
00204 /*!
00205  * Indicates if the MAC layer network join status has changed.
00206  */
00207 static bool IsNetworkJoinedStatusUpdate = false;
00208 
00209 /*!
00210  * Strucure containing the Uplink status
00211  */
00212 struct sLoRaMacUplinkStatus
00213 {
00214     uint8_t Acked;
00215     int8_t Datarate;
00216     uint16_t UplinkCounter;
00217     uint8_t Port;
00218     uint8_t *Buffer;
00219     uint8_t BufferSize;
00220 }LoRaMacUplinkStatus;
00221 volatile bool UplinkStatusUpdated = false;
00222 
00223 /*!
00224  * Strucure containing the Downlink status
00225  */
00226 struct sLoRaMacDownlinkStatus
00227 {
00228     int16_t Rssi;
00229     int8_t Snr;
00230     uint16_t DownlinkCounter;
00231     bool RxData;
00232     uint8_t Port;
00233     uint8_t *Buffer;
00234     uint8_t BufferSize;
00235 }LoRaMacDownlinkStatus;
00236 volatile bool DownlinkStatusUpdated = false;
00237 
00238 void SerialDisplayRefresh( void )
00239 {
00240     MibRequestConfirm_t mibReq;
00241 
00242     SerialDisplayInit( );
00243     SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION );
00244 
00245 #if( OVER_THE_AIR_ACTIVATION == 0 )
00246     SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID );
00247     SerialDisplayUpdateDevAddr( DevAddr );
00248     SerialDisplayUpdateKey( 12, NwkSKey );
00249     SerialDisplayUpdateKey( 13, AppSKey );
00250 #endif
00251     SerialDisplayUpdateEui( 5, DevEui );
00252     SerialDisplayUpdateEui( 6, AppEui );
00253     SerialDisplayUpdateKey( 7, AppKey );
00254 
00255     mibReq.Type = MIB_NETWORK_JOINED;
00256     LoRaMacMibGetRequestConfirm( &mibReq );
00257     SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined );
00258 
00259     SerialDisplayUpdateAdr( LORAWAN_ADR_ON );
00260 #if defined( USE_BAND_868 )
00261     SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON );
00262 #else
00263     SerialDisplayUpdateDutyCycle( false );
00264 #endif
00265     SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK );
00266     
00267     SerialDisplayUpdateLedState( 3, AppLedStateOn );
00268 }
00269 
00270 void SerialRxProcess( void )
00271 {
00272     if( SerialDisplayReadable( ) == true )
00273     {
00274         switch( SerialDisplayGetChar( ) )
00275         {
00276             case 'R':
00277             case 'r':
00278                 // Refresh Serial screen
00279                 SerialDisplayRefresh( );
00280                 break;
00281             default:
00282                 break;
00283         }
00284     }
00285 }
00286 
00287 static X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance();
00288 static TempSensor *temp_sensor1 = mems_expansion_board->ht_sensor;
00289 /*!
00290  * \brief   Prepares the payload of the frame
00291  */
00292 static void PrepareTxFrame( uint8_t port )
00293 {
00294     switch( port )
00295     {
00296     case 5:
00297         unsigned int ret;
00298         float TEMPERATURE_Value;
00299         AppDataSize = 11;
00300         AppData[0] = AppLedStateOn;
00301         ret |= (!CALL_METH(temp_sensor1, GetTemperature, &TEMPERATURE_Value, 0.0f) ? 0x0 : 0x1);
00302         vt.SetCursorPos( 43, 1 );
00303         vt.printf( "temp:%f", TEMPERATURE_Value );
00304         AppData[1] = (int)TEMPERATURE_Value * 2;
00305         break;
00306     case 15:
00307         {
00308             AppData[0] = AppLedStateOn;
00309             if( IsTxConfirmed == true )
00310             {
00311                 AppData[1] = LoRaMacDownlinkStatus.DownlinkCounter >> 8;
00312                 AppData[2] = LoRaMacDownlinkStatus.DownlinkCounter;
00313                 AppData[3] = LoRaMacDownlinkStatus.Rssi >> 8;
00314                 AppData[4] = LoRaMacDownlinkStatus.Rssi;
00315                 AppData[5] = LoRaMacDownlinkStatus.Snr;
00316             }
00317         }
00318         break;
00319     case 224:
00320         if( ComplianceTest.LinkCheck == true )
00321         {
00322             ComplianceTest.LinkCheck = false;
00323             AppDataSize = 3;
00324             AppData[0] = 5;
00325             AppData[1] = ComplianceTest.DemodMargin;
00326             AppData[2] = ComplianceTest.NbGateways;
00327             ComplianceTest.State = 1;
00328         }
00329         else
00330         {
00331             switch( ComplianceTest.State )
00332             {
00333             case 4:
00334                 ComplianceTest.State = 1;
00335                 break;
00336             case 1:
00337                 AppDataSize = 2;
00338                 AppData[0] = ComplianceTest.DownLinkCounter >> 8;
00339                 AppData[1] = ComplianceTest.DownLinkCounter;
00340                 break;
00341             }
00342         }
00343         break;
00344     default:
00345         break;
00346     }
00347 }
00348 
00349 /*!
00350  * \brief   Prepares the payload of the frame
00351  *
00352  * \retval  [0: frame could be send, 1: error]
00353  */
00354 static bool SendFrame( void )
00355 {
00356     McpsReq_t mcpsReq;
00357     LoRaMacTxInfo_t txInfo;
00358     
00359     if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK )
00360     {
00361         // Send empty frame in order to flush MAC commands
00362         mcpsReq.Type = MCPS_UNCONFIRMED;
00363         mcpsReq.Req.Unconfirmed.fBuffer = NULL;
00364         mcpsReq.Req.Unconfirmed.fBufferSize = 0;
00365         mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
00366 
00367         LoRaMacUplinkStatus.Acked = false;
00368         LoRaMacUplinkStatus.Port = 0;
00369         LoRaMacUplinkStatus.Buffer = NULL;
00370         LoRaMacUplinkStatus.BufferSize = 0;
00371         SerialDisplayUpdateFrameType( false );
00372     }
00373     else
00374     {
00375         LoRaMacUplinkStatus.Acked = false;
00376         LoRaMacUplinkStatus.Port = AppPort;
00377         LoRaMacUplinkStatus.Buffer = AppData;
00378         LoRaMacUplinkStatus.BufferSize = AppDataSize;
00379         SerialDisplayUpdateFrameType( IsTxConfirmed );
00380 
00381         if( IsTxConfirmed == false )
00382         {
00383             mcpsReq.Type = MCPS_UNCONFIRMED;
00384             mcpsReq.Req.Unconfirmed.fPort = AppPort;
00385             mcpsReq.Req.Unconfirmed.fBuffer = AppData;
00386             mcpsReq.Req.Unconfirmed.fBufferSize = AppDataSize;
00387             mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
00388         }
00389         else
00390         {
00391             mcpsReq.Type = MCPS_CONFIRMED;
00392             mcpsReq.Req.Confirmed.fPort = AppPort;
00393             mcpsReq.Req.Confirmed.fBuffer = AppData;
00394             mcpsReq.Req.Confirmed.fBufferSize = AppDataSize;
00395             mcpsReq.Req.Confirmed.NbTrials = 8;
00396             mcpsReq.Req.Confirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
00397         }
00398     }
00399 
00400     if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK )
00401     {
00402         return false;
00403     }
00404     return true;
00405 }
00406 
00407 /*!
00408  * \brief Function executed on TxNextPacket Timeout event
00409  */
00410 static void OnTxNextPacketTimerEvent( void )
00411 {
00412     MibRequestConfirm_t mibReq;
00413     LoRaMacStatus_t status;
00414 
00415     TimerStop( &TxNextPacketTimer );
00416 
00417     mibReq.Type = MIB_NETWORK_JOINED;
00418     status = LoRaMacMibGetRequestConfirm( &mibReq );
00419 
00420     if( status == LORAMAC_STATUS_OK )
00421     {
00422         if( mibReq.Param.IsNetworkJoined == true )
00423         {
00424             DeviceState = DEVICE_STATE_SEND;
00425             NextTx = true;
00426         }
00427         else
00428         {
00429             DeviceState = DEVICE_STATE_JOIN;
00430         }
00431     }
00432 }
00433 
00434 /*!
00435  * \brief Function executed on Led 1 Timeout event
00436  */
00437 static void OnLed1TimerEvent( void )
00438 {
00439     TimerStop( &Led1Timer );
00440     // Switch LED 1 OFF
00441     Led1State = false;
00442     Led1StateChanged = true;
00443 }
00444 
00445 /*!
00446  * \brief Function executed on Led 2 Timeout event
00447  */
00448 static void OnLed2TimerEvent( void )
00449 {
00450     TimerStop( &Led2Timer );
00451     // Switch LED 2 OFF
00452     Led2State = false;
00453     Led2StateChanged = true;
00454 }
00455 
00456 /*!
00457  * \brief   MCPS-Confirm event function
00458  *
00459  * \param   [IN] mcpsConfirm - Pointer to the confirm structure,
00460  *               containing confirm attributes.
00461  */
00462 static void McpsConfirm( McpsConfirm_t *mcpsConfirm )
00463 {
00464     if( mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
00465     {
00466         switch( mcpsConfirm->McpsRequest )
00467         {
00468             case MCPS_UNCONFIRMED:
00469             {
00470                 // Check Datarate
00471                 // Check TxPower
00472                 break;
00473             }
00474             case MCPS_CONFIRMED:
00475             {
00476                 // Check Datarate
00477                 // Check TxPower
00478                 // Check AckReceived
00479                 // Check NbTrials
00480                 LoRaMacUplinkStatus.Acked = mcpsConfirm->AckReceived;
00481                 break;
00482             }
00483             case MCPS_PROPRIETARY:
00484             {
00485                 break;
00486             }
00487             default:
00488                 break;
00489         }
00490         LoRaMacUplinkStatus.Datarate = mcpsConfirm->Datarate;
00491         LoRaMacUplinkStatus.UplinkCounter = mcpsConfirm->UpLinkCounter;
00492 
00493         // Switch LED 1 ON
00494         Led1State = true;
00495         Led1StateChanged = true;
00496         TimerStart( &Led1Timer );
00497 
00498         UplinkStatusUpdated = true;
00499     }
00500     NextTx = true;
00501 }
00502 
00503 /*!
00504  * \brief   MCPS-Indication event function
00505  *
00506  * \param   [IN] mcpsIndication - Pointer to the indication structure,
00507  *               containing indication attributes.
00508  */
00509 static void McpsIndication( McpsIndication_t *mcpsIndication )
00510 {
00511     if( mcpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK )
00512     {
00513         return;
00514     }
00515 
00516     switch( mcpsIndication->McpsIndication )
00517     {
00518         case MCPS_UNCONFIRMED:
00519         {
00520             break;
00521         }
00522         case MCPS_CONFIRMED:
00523         {
00524             break;
00525         }
00526         case MCPS_PROPRIETARY:
00527         {
00528             break;
00529         }
00530         case MCPS_MULTICAST:
00531         {
00532             break;
00533         }
00534         default:
00535             break;
00536     }
00537 
00538     // Check Multicast
00539     // Check Port
00540     // Check Datarate
00541     // Check FramePending
00542     // Check Buffer
00543     // Check BufferSize
00544     // Check Rssi
00545     // Check Snr
00546     // Check RxSlot
00547     LoRaMacDownlinkStatus.Rssi = mcpsIndication->Rssi;
00548     if( mcpsIndication->Snr & 0x80 ) // The SNR sign bit is 1
00549     {
00550         // Invert and divide by 4
00551         LoRaMacDownlinkStatus.Snr = ( ( ~mcpsIndication->Snr + 1 ) & 0xFF ) >> 2;
00552         LoRaMacDownlinkStatus.Snr = -LoRaMacDownlinkStatus.Snr;
00553     }
00554     else
00555     {
00556         // Divide by 4
00557         LoRaMacDownlinkStatus.Snr = ( mcpsIndication->Snr & 0xFF ) >> 2;
00558     }
00559     LoRaMacDownlinkStatus.DownlinkCounter++;
00560     LoRaMacDownlinkStatus.RxData = mcpsIndication->RxData;
00561     LoRaMacDownlinkStatus.Port = mcpsIndication->Port;
00562     LoRaMacDownlinkStatus.Buffer = mcpsIndication->Buffer;
00563     LoRaMacDownlinkStatus.BufferSize = mcpsIndication->BufferSize;
00564 
00565     if( ComplianceTest.Running == true )
00566     {
00567         ComplianceTest.DownLinkCounter++;
00568     }
00569 
00570     if( mcpsIndication->RxData == true )
00571     {
00572         switch( mcpsIndication->Port )
00573         {
00574         case 1: // The application LED can be controlled on port 1 or 2
00575         case 2:
00576             if( mcpsIndication->BufferSize == 1 )
00577             {
00578                 AppLedStateOn = mcpsIndication->Buffer[0] & 0x01;
00579                 Led3StateChanged = true;
00580             }
00581             break;
00582         case 224:
00583             if( ComplianceTest.Running == false )
00584             {
00585                 // Check compliance test enable command (i)
00586                 if( ( mcpsIndication->BufferSize == 4 ) &&
00587                     ( mcpsIndication->Buffer[0] == 0x01 ) &&
00588                     ( mcpsIndication->Buffer[1] == 0x01 ) &&
00589                     ( mcpsIndication->Buffer[2] == 0x01 ) &&
00590                     ( mcpsIndication->Buffer[3] == 0x01 ) )
00591                 {
00592                     IsTxConfirmed = false;
00593                     AppPort = 224;
00594                     AppDataSize = 2;
00595                     ComplianceTest.DownLinkCounter = 0;
00596                     ComplianceTest.LinkCheck = false;
00597                     ComplianceTest.DemodMargin = 0;
00598                     ComplianceTest.NbGateways = 0;
00599                     ComplianceTest.Running = true;
00600                     ComplianceTest.State = 1;
00601                     
00602                     MibRequestConfirm_t mibReq;
00603                     mibReq.Type = MIB_ADR;
00604                     mibReq.Param.AdrEnable = true;
00605                     LoRaMacMibSetRequestConfirm( &mibReq );
00606 
00607 #if defined( USE_BAND_868 )
00608                     LoRaMacTestSetDutyCycleOn( false );
00609 #endif
00610                 }
00611             }
00612             else
00613             {
00614                 ComplianceTest.State = mcpsIndication->Buffer[0];
00615                 switch( ComplianceTest.State )
00616                 {
00617                 case 0: // Check compliance test disable command (ii)
00618                     IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
00619                     AppPort = LORAWAN_APP_PORT;
00620                     AppDataSize = LORAWAN_APP_DATA_SIZE;
00621                     ComplianceTest.DownLinkCounter = 0;
00622                     ComplianceTest.Running = false;
00623                     
00624                     MibRequestConfirm_t mibReq;
00625                     mibReq.Type = MIB_ADR;
00626                     mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
00627                     LoRaMacMibSetRequestConfirm( &mibReq );
00628 #if defined( USE_BAND_868 )
00629                     LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
00630 #endif
00631                     break;
00632                 case 1: // (iii, iv)
00633                     AppDataSize = 2;
00634                     break;
00635                 case 2: // Enable confirmed messages (v)
00636                     IsTxConfirmed = true;
00637                     ComplianceTest.State = 1;
00638                     break;
00639                 case 3:  // Disable confirmed messages (vi)
00640                     IsTxConfirmed = false;
00641                     ComplianceTest.State = 1;
00642                     break;
00643                 case 4: // (vii)
00644                     AppDataSize = mcpsIndication->BufferSize;
00645 
00646                     AppData[0] = 4;
00647                     for( uint8_t i = 1; i < AppDataSize; i++ )
00648                     {
00649                         AppData[i] = mcpsIndication->Buffer[i] + 1;
00650                     }
00651                     break;
00652                 case 5: // (viii)
00653                     {
00654                         MlmeReq_t mlmeReq;
00655                         mlmeReq.Type = MLME_LINK_CHECK;
00656                         LoRaMacMlmeRequest( &mlmeReq );
00657                     }
00658                     break;
00659                 case 6: // (ix)
00660                     {
00661                         MlmeReq_t mlmeReq;
00662 
00663                         mlmeReq.Type = MLME_JOIN;
00664 
00665                         mlmeReq.Req.Join.DevEui = DevEui;
00666                         mlmeReq.Req.Join.AppEui = AppEui;
00667                         mlmeReq.Req.Join.AppKey = AppKey;
00668 
00669                         LoRaMacMlmeRequest( &mlmeReq );
00670                         DeviceState = DEVICE_STATE_SLEEP;
00671                     }
00672                     break;
00673                 default:
00674                     break;
00675                 }
00676             }
00677             break;
00678         default:
00679             break;
00680         }
00681     }
00682 
00683     // Switch LED 2 ON for each received downlink
00684     Led2State = true;
00685     Led2StateChanged = true;
00686     TimerStart( &Led2Timer );
00687     DownlinkStatusUpdated = true;
00688 }
00689 
00690 /*!
00691  * \brief   MLME-Confirm event function
00692  *
00693  * \param   [IN] mlmeConfirm - Pointer to the confirm structure,
00694  *               containing confirm attributes.
00695  */
00696 static void MlmeConfirm( MlmeConfirm_t *mlmeConfirm )
00697 {
00698     if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
00699     {
00700         switch( mlmeConfirm->MlmeRequest )
00701         {
00702             case MLME_JOIN:
00703             {
00704                 // Status is OK, node has joined the network
00705                 IsNetworkJoinedStatusUpdate = true;
00706                 DeviceState = DEVICE_STATE_SEND;
00707                 NextTx = true;
00708                 break;
00709             }
00710             case MLME_LINK_CHECK:
00711             {
00712                 // Check DemodMargin
00713                 // Check NbGateways
00714                 if( ComplianceTest.Running == true )
00715                 {
00716                     ComplianceTest.LinkCheck = true;
00717                     ComplianceTest.DemodMargin = mlmeConfirm->DemodMargin;
00718                     ComplianceTest.NbGateways = mlmeConfirm->NbGateways;
00719                 }
00720                 break;
00721             }
00722             default:
00723                 break;
00724         }
00725     }
00726     NextTx = true;
00727     UplinkStatusUpdated = true;
00728 }
00729 
00730 /**
00731  * Main application entry point.
00732  */
00733 int main( void )
00734 {
00735     LoRaMacPrimitives_t LoRaMacPrimitives;
00736     LoRaMacCallback_t LoRaMacCallbacks;
00737     MibRequestConfirm_t mibReq;
00738 
00739     BoardInit( );
00740     SerialDisplayInit( );
00741 
00742     SerialDisplayUpdateEui( 5, DevEui );
00743     SerialDisplayUpdateEui( 6, AppEui );
00744     SerialDisplayUpdateKey( 7, AppKey );
00745 
00746 #if( OVER_THE_AIR_ACTIVATION == 0 )
00747     SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID );
00748     SerialDisplayUpdateDevAddr( DevAddr );
00749     SerialDisplayUpdateKey( 12, NwkSKey );
00750     SerialDisplayUpdateKey( 13, AppSKey );
00751 #endif
00752 
00753     DeviceState = DEVICE_STATE_INIT;
00754 
00755     while( 1 )
00756     {
00757         SerialRxProcess( );
00758         if( IsNetworkJoinedStatusUpdate == true )
00759         {
00760             IsNetworkJoinedStatusUpdate = false;
00761             mibReq.Type = MIB_NETWORK_JOINED;
00762             LoRaMacMibGetRequestConfirm( &mibReq );
00763             SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined );
00764         }
00765         if( Led1StateChanged == true )
00766         {
00767             Led1StateChanged = false;
00768             SerialDisplayUpdateLedState( 1, Led1State );
00769         }
00770         if( Led2StateChanged == true )
00771         {
00772             Led2StateChanged = false;
00773             SerialDisplayUpdateLedState( 2, Led2State );
00774         }
00775         if( Led3StateChanged == true )
00776         {
00777             Led3StateChanged = false;
00778             SerialDisplayUpdateLedState( 3, AppLedStateOn );
00779         }
00780         if( UplinkStatusUpdated == true )
00781         {
00782             UplinkStatusUpdated = false;
00783             SerialDisplayUpdateUplink( LoRaMacUplinkStatus.Acked, LoRaMacUplinkStatus.Datarate, LoRaMacUplinkStatus.UplinkCounter, LoRaMacUplinkStatus.Port, LoRaMacUplinkStatus.Buffer, LoRaMacUplinkStatus.BufferSize );
00784         }
00785         if( DownlinkStatusUpdated == true )
00786         {
00787             DownlinkStatusUpdated = false;
00788             SerialDisplayUpdateLedState( 2, Led2State );
00789             SerialDisplayUpdateDownlink( LoRaMacDownlinkStatus.RxData, LoRaMacDownlinkStatus.Rssi, LoRaMacDownlinkStatus.Snr, LoRaMacDownlinkStatus.DownlinkCounter, LoRaMacDownlinkStatus.Port, LoRaMacDownlinkStatus.Buffer, LoRaMacDownlinkStatus.BufferSize );
00790         }
00791         
00792         switch( DeviceState )
00793         {
00794             case DEVICE_STATE_INIT:
00795             {
00796                 uint8_t id2;
00797                 LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm;
00798                 LoRaMacPrimitives.MacMcpsIndication = McpsIndication;
00799                 LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm;
00800                 LoRaMacCallbacks.GetBatteryLevel = BoardGetBatteryLevel;
00801                 LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks );
00802 
00803                 TimerInit( &TxNextPacketTimer, OnTxNextPacketTimerEvent );
00804 
00805                 TimerInit( &Led1Timer, OnLed1TimerEvent );
00806                 TimerSetValue( &Led1Timer, 25000 );
00807 
00808                 TimerInit( &Led2Timer, OnLed2TimerEvent );
00809                 TimerSetValue( &Led2Timer, 25000 );
00810 
00811                 mibReq.Type = MIB_ADR;
00812                 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
00813                 LoRaMacMibSetRequestConfirm( &mibReq );
00814 
00815                 mibReq.Type = MIB_PUBLIC_NETWORK;
00816                 mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK;
00817                 LoRaMacMibSetRequestConfirm( &mibReq );
00818 
00819 #if defined( USE_BAND_868 )
00820                 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
00821                 SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON );
00822 
00823 #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 ) 
00824                 LoRaMacChannelAdd( 3, ( ChannelParams_t )LC4 );
00825                 LoRaMacChannelAdd( 4, ( ChannelParams_t )LC5 );
00826                 LoRaMacChannelAdd( 5, ( ChannelParams_t )LC6 );
00827                 LoRaMacChannelAdd( 6, ( ChannelParams_t )LC7 );
00828                 LoRaMacChannelAdd( 7, ( ChannelParams_t )LC8 );
00829                 LoRaMacChannelAdd( 8, ( ChannelParams_t )LC9 );
00830                 LoRaMacChannelAdd( 9, ( ChannelParams_t )LC10 );
00831 
00832                 mibReq.Type = MIB_RX2_CHANNEL;
00833                 mibReq.Param.Rx2Channel = ( Rx2ChannelParams_t ){ 869525000, DR_3 };
00834                 LoRaMacMibSetRequestConfirm( &mibReq );
00835 #endif
00836 
00837 #endif
00838                 SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION );
00839                 SerialDisplayUpdateAdr( LORAWAN_ADR_ON );
00840                 SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK );
00841 
00842                 LoRaMacDownlinkStatus.DownlinkCounter = 0;
00843 
00844                 DeviceState = DEVICE_STATE_JOIN;
00845                 
00846                 CALL_METH(temp_sensor1, ReadID, &id2, 0x0);
00847                 break;
00848             }
00849             case DEVICE_STATE_JOIN:
00850             {
00851 #if( OVER_THE_AIR_ACTIVATION != 0 )
00852                 MlmeReq_t mlmeReq;
00853 
00854                 mlmeReq.Type = MLME_JOIN;
00855 
00856                 mlmeReq.Req.Join.DevEui = DevEui;
00857                 mlmeReq.Req.Join.AppEui = AppEui;
00858                 mlmeReq.Req.Join.AppKey = AppKey;
00859 
00860                 if( NextTx == true )
00861                 {
00862                     LoRaMacMlmeRequest( &mlmeReq );
00863                 }
00864                 DeviceState = DEVICE_STATE_SLEEP;
00865 #else
00866                 mibReq.Type = MIB_NET_ID;
00867                 mibReq.Param.NetID = LORAWAN_NETWORK_ID;
00868                 LoRaMacMibSetRequestConfirm( &mibReq );
00869 
00870                 mibReq.Type = MIB_DEV_ADDR;
00871                 mibReq.Param.DevAddr = DevAddr;
00872                 LoRaMacMibSetRequestConfirm( &mibReq );
00873 
00874                 mibReq.Type = MIB_NWK_SKEY;
00875                 mibReq.Param.NwkSKey = NwkSKey;
00876                 LoRaMacMibSetRequestConfirm( &mibReq );
00877 
00878                 mibReq.Type = MIB_APP_SKEY;
00879                 mibReq.Param.AppSKey = AppSKey;
00880                 LoRaMacMibSetRequestConfirm( &mibReq );
00881 
00882                 mibReq.Type = MIB_NETWORK_JOINED;
00883                 mibReq.Param.IsNetworkJoined = true;
00884                 LoRaMacMibSetRequestConfirm( &mibReq );
00885 
00886                 DeviceState = DEVICE_STATE_SEND;
00887 #endif
00888                 IsNetworkJoinedStatusUpdate = true;
00889                 break;
00890             }
00891             case DEVICE_STATE_SEND:
00892             {
00893                 if( NextTx == true )
00894                 {
00895                     SerialDisplayUpdateUplinkAcked( false );
00896                     SerialDisplayUpdateDonwlinkRxData( false );
00897                     PrepareTxFrame( AppPort );
00898 
00899                     NextTx = SendFrame( );
00900                 }
00901                 if( ComplianceTest.Running == true )
00902                 {
00903                     // Schedule next packet transmission
00904                     TxDutyCycleTime = 5000000; // 5000000 us
00905                 }
00906                 else
00907                 {
00908                     // Schedule next packet transmission
00909                     TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND );
00910                 }
00911                 DeviceState = DEVICE_STATE_CYCLE;
00912                 break;
00913             }
00914             case DEVICE_STATE_CYCLE:
00915             {
00916                 DeviceState = DEVICE_STATE_SLEEP;
00917 
00918                 // Schedule next packet transmission
00919                 TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime );
00920                 TimerStart( &TxNextPacketTimer );
00921                 break;
00922             }
00923             case DEVICE_STATE_SLEEP:
00924             {
00925                 // Wake up through events
00926                 break;
00927             }
00928             default:
00929             {
00930                 DeviceState = DEVICE_STATE_INIT;
00931                 break;
00932             }
00933         }
00934     }
00935 }