for India band 30dBm LoRa Module, DSPLoRa based on code from Semtech and as modified by Sachin Pukale/ TCL/

Dependencies:   mbed Chainable_RGB_LED DigitDisplay LoRaWAN-lib SX1276Lib

Fork of DSP_LoRaWAN by Akshay Mishra

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