Amir Chaudhary / Mbed 2 deprecated LoRaWAN-hello-world_Class_C_Anish

Dependencies:   mbed LoRaWAN-lib SX1276Lib

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 "Commissioning.h"
00021 #include "SerialDisplay.h"
00022 
00023 /*!
00024  * Defines the application data transmission duty cycle. 5s, value in [ms].
00025  */
00026 #define APP_TX_DUTYCYCLE                            5000
00027 
00028 /*!
00029  * Defines a random delay for application data transmission duty cycle. 1s,
00030  * value in [ms].
00031  */
00032 #define APP_TX_DUTYCYCLE_RND                        1000
00033 
00034 /*!
00035  * Default datarate
00036  */
00037 #define LORAWAN_DEFAULT_DATARATE                    DR_0
00038 
00039 /*!
00040  * LoRaWAN confirmed messages
00041  */
00042 #define LORAWAN_CONFIRMED_MSG_ON                    true
00043 
00044 /*!
00045  * LoRaWAN Adaptive Data Rate
00046  *
00047  * \remark Please note that when ADR is enabled the end-device should be static
00048  */
00049 #define LORAWAN_ADR_ON                              1
00050 
00051 #if defined( USE_BAND_868 )
00052 
00053 #include "LoRaMacTest.h"
00054 
00055 /*!
00056  * LoRaWAN ETSI duty cycle control enable/disable
00057  *
00058  * \remark Please note that ETSI mandates duty cycled transmissions. Use only for test purposes
00059  */
00060 #define LORAWAN_DUTYCYCLE_ON                        false
00061 
00062 #define USE_SEMTECH_DEFAULT_CHANNEL_LINEUP          1
00063 
00064 #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 )
00065 
00066 #define LC4                { 867100000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
00067 #define LC5                { 867300000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
00068 #define LC6                { 867500000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
00069 #define LC7                { 867700000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
00070 #define LC8                { 867900000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
00071 #define LC9                { 868800000, { ( ( DR_7 << 4 ) | DR_7 ) }, 2 }
00072 #define LC10               { 868300000, { ( ( DR_6 << 4 ) | DR_6 ) }, 1 }
00073 
00074 #endif
00075 
00076 #endif
00077 
00078 /*!
00079  * LoRaWAN application port
00080  */
00081 #define LORAWAN_APP_PORT                            15
00082 
00083 /*!
00084  * User application data buffer size
00085  */
00086 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 )
00087 #define LORAWAN_APP_DATA_SIZE                       6
00088 
00089 #else
00090 #define LORAWAN_APP_DATA_SIZE                       1
00091 
00092 #endif
00093 
00094 static uint8_t DevEui[] = LORAWAN_DEVICE_EUI;
00095 static uint8_t AppEui[] = LORAWAN_APPLICATION_EUI;
00096 static uint8_t AppKey[] = LORAWAN_APPLICATION_KEY;
00097 
00098 #if( OVER_THE_AIR_ACTIVATION == 0 )
00099 
00100 static uint8_t NwkSKey[] = LORAWAN_NWKSKEY;
00101 static uint8_t AppSKey[] = LORAWAN_APPSKEY;
00102 
00103 /*!
00104  * Device address
00105  */
00106 static uint32_t DevAddr = LORAWAN_DEVICE_ADDRESS;
00107 
00108 #endif
00109 
00110 /*!
00111  * Application port
00112  */
00113 static uint8_t AppPort = LORAWAN_APP_PORT;
00114 
00115 /*!
00116  * User application data size
00117  */
00118 static uint8_t AppDataSize = LORAWAN_APP_DATA_SIZE;
00119 
00120 /*!
00121  * User application data buffer size
00122  */
00123 #define LORAWAN_APP_DATA_MAX_SIZE                           64
00124 
00125 /*!
00126  * User application data
00127  */
00128 static uint8_t AppData[LORAWAN_APP_DATA_MAX_SIZE];
00129 
00130 /*!
00131  * Indicates if the node is sending confirmed or unconfirmed messages
00132  */
00133 static uint8_t IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
00134 
00135 /*!
00136  * Defines the application data transmission duty cycle
00137  */
00138 static uint32_t TxDutyCycleTime;
00139 
00140 /*!
00141  * Timer to handle the application data transmission duty cycle
00142  */
00143 static TimerEvent_t TxNextPacketTimer;
00144 
00145 /*!
00146  * Indicates if a new packet can be sent
00147  */
00148 static bool NextTx = true;
00149 
00150 /*!
00151  * Device states
00152  */
00153 static enum eDeviceState
00154 {
00155     DEVICE_STATE_INIT,
00156     DEVICE_STATE_JOIN,
00157     DEVICE_STATE_SEND,
00158     DEVICE_STATE_CYCLE,
00159     DEVICE_STATE_SLEEP
00160 }DeviceState;
00161 
00162 /*!
00163  * LoRaWAN compliance tests support data
00164  */
00165 struct ComplianceTest_s
00166 {
00167     bool Running;
00168     uint8_t State;
00169     bool IsTxConfirmed;
00170     uint8_t AppPort;
00171     uint8_t AppDataSize;
00172     uint8_t *AppDataBuffer;
00173     uint16_t DownLinkCounter;
00174     bool LinkCheck;
00175     uint8_t DemodMargin;
00176     uint8_t NbGateways;
00177 }ComplianceTest;
00178 
00179 /*
00180  * SerialDisplay managment variables
00181  */
00182 
00183 /*!
00184  * Indicates if the MAC layer network join status has changed.
00185  */
00186 static bool IsNetworkJoinedStatusUpdate = false;
00187 
00188 /*!
00189  * Strucure containing the Uplink status
00190  */
00191 struct sLoRaMacUplinkStatus
00192 {
00193     uint8_t Acked;
00194     int8_t Datarate;
00195     uint16_t UplinkCounter;
00196     uint8_t Port;
00197     uint8_t *Buffer;
00198     uint8_t BufferSize;
00199 }LoRaMacUplinkStatus;
00200 volatile bool UplinkStatusUpdated = false;
00201 
00202 /*!
00203  * Strucure containing the Downlink status
00204  */
00205 struct sLoRaMacDownlinkStatus
00206 {
00207     int16_t Rssi;
00208     int8_t Snr;
00209     uint16_t DownlinkCounter;
00210     bool RxData;
00211     uint8_t Port;
00212     uint8_t *Buffer;
00213     uint8_t BufferSize;
00214 }LoRaMacDownlinkStatus;
00215 volatile bool DownlinkStatusUpdated = false;
00216 
00217 
00218 // Application Globals
00219 
00220 /*BLUE and green led pin?
00221 D7 == Green
00222 D8 == Blue 
00223 Pelase proceed
00224 
00225  */
00226  DigitalOut myled(D6);
00227 DigitalOut myGreenLed(D7); // ON = Lora Connected
00228 DigitalOut myBlueLed(D8);  // Blink twice = Sends data or increments counter value Pelase proceed
00229 
00230 void SerialDisplayRefresh( void )
00231 {
00232     MibRequestConfirm_t mibReq;
00233 
00234     SerialDisplayInit( );
00235     SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION );
00236 
00237 #if( OVER_THE_AIR_ACTIVATION == 0 )
00238     SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID );
00239     SerialDisplayUpdateDevAddr( DevAddr );
00240     SerialDisplayUpdateKey( 12, NwkSKey );
00241     SerialDisplayUpdateKey( 13, AppSKey );
00242 #endif
00243     SerialDisplayUpdateEui( 5, DevEui );
00244     SerialDisplayUpdateEui( 6, AppEui );
00245     SerialDisplayUpdateKey( 7, AppKey );
00246 
00247     mibReq.Type = MIB_NETWORK_JOINED;
00248     LoRaMacMibGetRequestConfirm( &mibReq );
00249     SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined );
00250 
00251     SerialDisplayUpdateAdr( LORAWAN_ADR_ON );
00252 #if defined( USE_BAND_868 )
00253     SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON );
00254 #else
00255     SerialDisplayUpdateDutyCycle( false );
00256 #endif
00257     SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK );
00258 }
00259 
00260 void SerialRxProcess( void )
00261 {
00262     if( SerialDisplayReadable( ) == true )
00263     {
00264         switch( SerialDisplayGetChar( ) )
00265         {
00266             case 'R':
00267             case 'r':
00268                 // Refresh Serial screen
00269                 SerialDisplayRefresh( );
00270                 break;
00271             default:
00272                 break;
00273         }
00274     }
00275 }
00276 
00277 /*!
00278  * \brief   Prepares the payload of the frame
00279  */
00280 static void PrepareTxFrame( uint8_t port )
00281 {
00282     switch( port )
00283     {
00284     case 15:
00285         {
00286             AppData[0] = 0;
00287             if( IsTxConfirmed == true )
00288             {
00289                 AppData[1] = LoRaMacDownlinkStatus.DownlinkCounter >> 8;
00290                 AppData[2] = LoRaMacDownlinkStatus.DownlinkCounter;
00291                 AppData[3] = LoRaMacDownlinkStatus.Rssi >> 8;
00292                 AppData[4] = LoRaMacDownlinkStatus.Rssi;
00293                 AppData[5] = LoRaMacDownlinkStatus.Snr;
00294             }
00295         }
00296         break;
00297     case 224:
00298         if( ComplianceTest.LinkCheck == true )
00299         {
00300             ComplianceTest.LinkCheck = false;
00301             AppDataSize = 3;
00302             AppData[0] = 5;
00303             AppData[1] = ComplianceTest.DemodMargin;
00304             AppData[2] = ComplianceTest.NbGateways;
00305             ComplianceTest.State = 1;
00306         }
00307         else
00308         {
00309             switch( ComplianceTest.State )
00310             {
00311             case 4:
00312                 ComplianceTest.State = 1;
00313                 break;
00314             case 1:
00315                 AppDataSize = 2;
00316                 AppData[0] = ComplianceTest.DownLinkCounter >> 8;
00317                 AppData[1] = ComplianceTest.DownLinkCounter;
00318                 break;
00319             }
00320         }
00321         break;
00322     default:
00323         break;
00324     }
00325 }
00326 
00327 /*!
00328  * \brief   Prepares the payload of the frame
00329  *
00330  * \retval  [0: frame could be send, 1: error]
00331  */
00332 static bool SendFrame( void )
00333 {
00334     McpsReq_t mcpsReq;
00335     LoRaMacTxInfo_t txInfo;
00336 
00337     if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK )
00338     {
00339         // Send empty frame in order to flush MAC commands
00340         mcpsReq.Type = MCPS_UNCONFIRMED;
00341         mcpsReq.Req.Unconfirmed.fBuffer = NULL;
00342         mcpsReq.Req.Unconfirmed.fBufferSize = 0;
00343         mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
00344 
00345         LoRaMacUplinkStatus.Acked = false;
00346         LoRaMacUplinkStatus.Port = 0;
00347         LoRaMacUplinkStatus.Buffer = NULL;
00348         LoRaMacUplinkStatus.BufferSize = 0;
00349         SerialDisplayUpdateFrameType( false );
00350     }
00351     else
00352     {
00353         LoRaMacUplinkStatus.Acked = false;
00354         LoRaMacUplinkStatus.Port = AppPort;
00355         LoRaMacUplinkStatus.Buffer = AppData;
00356         LoRaMacUplinkStatus.BufferSize = AppDataSize;
00357         SerialDisplayUpdateFrameType( IsTxConfirmed );
00358 
00359         if( IsTxConfirmed == false )
00360         {
00361             mcpsReq.Type = MCPS_UNCONFIRMED;
00362             mcpsReq.Req.Unconfirmed.fPort = AppPort;
00363             mcpsReq.Req.Unconfirmed.fBuffer = AppData;
00364             mcpsReq.Req.Unconfirmed.fBufferSize = AppDataSize;
00365             mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
00366         }
00367         else
00368         {
00369             mcpsReq.Type = MCPS_CONFIRMED;
00370             mcpsReq.Req.Confirmed.fPort = AppPort;
00371             mcpsReq.Req.Confirmed.fBuffer = AppData;
00372             mcpsReq.Req.Confirmed.fBufferSize = AppDataSize;
00373             mcpsReq.Req.Confirmed.NbTrials = 8;
00374             mcpsReq.Req.Confirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
00375         }
00376     }
00377 
00378     if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK )
00379     {
00380         return false;
00381     }
00382     return true;
00383 }
00384 
00385 /*!
00386  * \brief Function executed on TxNextPacket Timeout event
00387  */
00388 static void OnTxNextPacketTimerEvent( void )
00389 {
00390     MibRequestConfirm_t mibReq;
00391     LoRaMacStatus_t status;
00392 
00393     TimerStop( &TxNextPacketTimer );
00394 
00395     mibReq.Type = MIB_NETWORK_JOINED;
00396     status = LoRaMacMibGetRequestConfirm( &mibReq );
00397 
00398     if( status == LORAMAC_STATUS_OK )
00399     {
00400         if( mibReq.Param.IsNetworkJoined == true )
00401         {
00402             DeviceState = DEVICE_STATE_SEND;
00403             NextTx = true;
00404         }
00405         else
00406         {
00407             DeviceState = DEVICE_STATE_JOIN;
00408         }
00409     }
00410 }
00411 
00412 
00413 /*!
00414  * \brief   MCPS-Confirm event function
00415  *
00416  * \param   [IN] mcpsConfirm - Pointer to the confirm structure,
00417  *               containing confirm attributes.
00418  */
00419 static void McpsConfirm( McpsConfirm_t *mcpsConfirm )
00420 {
00421     if( mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
00422     {
00423         switch( mcpsConfirm->McpsRequest )
00424         {
00425             case MCPS_UNCONFIRMED:
00426             {
00427                 // Check Datarate
00428                 // Check TxPower
00429                 break;
00430             }
00431             case MCPS_CONFIRMED:
00432             {
00433                 // Check Datarate
00434                 // Check TxPower
00435                 // Check AckReceived
00436                 // Check NbTrials
00437                 LoRaMacUplinkStatus.Acked = mcpsConfirm->AckReceived;
00438                 break;
00439             }
00440             case MCPS_PROPRIETARY:
00441             {
00442                 break;
00443             }
00444             default:
00445                 break;
00446         }
00447         LoRaMacUplinkStatus.Datarate = mcpsConfirm->Datarate;
00448         LoRaMacUplinkStatus.UplinkCounter = mcpsConfirm->UpLinkCounter;
00449 
00450         UplinkStatusUpdated = true;
00451     }
00452     NextTx = true;
00453 }
00454 
00455 /*!
00456  * \brief   MCPS-Indication event function
00457  *
00458  * \param   [IN] mcpsIndication - Pointer to the indication structure,
00459  *               containing indication attributes.
00460  */
00461 static void McpsIndication( McpsIndication_t *mcpsIndication )
00462 {
00463     if( mcpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK )
00464     {
00465         return;
00466     }
00467 
00468     switch( mcpsIndication->McpsIndication )
00469     {
00470         case MCPS_UNCONFIRMED:
00471         {
00472             break;
00473         }
00474         case MCPS_CONFIRMED:
00475         {
00476             break;
00477         }
00478         case MCPS_PROPRIETARY:
00479         {
00480             break;
00481         }
00482         case MCPS_MULTICAST:
00483         {
00484             break;
00485         }
00486         default:
00487             break;
00488     }
00489 
00490     // Check Multicast
00491     // Check Port
00492     // Check Datarate
00493     // Check FramePending
00494     // Check Buffer
00495     // Check BufferSize
00496     // Check Rssi
00497     // Check Snr
00498     // Check RxSlot
00499     LoRaMacDownlinkStatus.Rssi = mcpsIndication->Rssi;
00500     if( mcpsIndication->Snr & 0x80 ) // The SNR sign bit is 1
00501     {
00502         // Invert and divide by 4
00503         LoRaMacDownlinkStatus.Snr = ( ( ~mcpsIndication->Snr + 1 ) & 0xFF ) >> 2;
00504         LoRaMacDownlinkStatus.Snr = -LoRaMacDownlinkStatus.Snr;
00505     }
00506     else
00507     {
00508         // Divide by 4
00509         LoRaMacDownlinkStatus.Snr = ( mcpsIndication->Snr & 0xFF ) >> 2;
00510     }
00511     LoRaMacDownlinkStatus.DownlinkCounter++;
00512     LoRaMacDownlinkStatus.RxData = mcpsIndication->RxData;
00513     LoRaMacDownlinkStatus.Port = mcpsIndication->Port;
00514     LoRaMacDownlinkStatus.Buffer = mcpsIndication->Buffer;
00515     LoRaMacDownlinkStatus.BufferSize = mcpsIndication->BufferSize;
00516 
00517     if( ComplianceTest.Running == true )
00518     {
00519         ComplianceTest.DownLinkCounter++;
00520     }
00521 
00522     if( mcpsIndication->RxData == true )
00523     {
00524         switch( mcpsIndication->Port )
00525         {
00526         case 1: // The application LED can be controlled on port 1 or 2
00527         case 2:
00528             break;
00529         case 224:
00530             if( ComplianceTest.Running == false )
00531             {
00532                 // Check compliance test enable command (i)
00533                 if( ( mcpsIndication->BufferSize == 4 ) &&
00534                     ( mcpsIndication->Buffer[0] == 0x01 ) &&
00535                     ( mcpsIndication->Buffer[1] == 0x01 ) &&
00536                     ( mcpsIndication->Buffer[2] == 0x01 ) &&
00537                     ( mcpsIndication->Buffer[3] == 0x01 ) )
00538                 {
00539                     IsTxConfirmed = false;
00540                     AppPort = 224;
00541                     AppDataSize = 2;
00542                     ComplianceTest.DownLinkCounter = 0;
00543                     ComplianceTest.LinkCheck = false;
00544                     ComplianceTest.DemodMargin = 0;
00545                     ComplianceTest.NbGateways = 0;
00546                     ComplianceTest.Running = true;
00547                     ComplianceTest.State = 1;
00548 
00549                     MibRequestConfirm_t mibReq;
00550                     mibReq.Type = MIB_ADR;
00551                     mibReq.Param.AdrEnable = true;
00552                     LoRaMacMibSetRequestConfirm( &mibReq );
00553 
00554 #if defined( USE_BAND_868 )
00555                     LoRaMacTestSetDutyCycleOn( false );
00556 #endif
00557                 }
00558             }
00559             else
00560             {
00561                 ComplianceTest.State = mcpsIndication->Buffer[0];
00562                 switch( ComplianceTest.State )
00563                 {
00564                 case 0: // Check compliance test disable command (ii)
00565                     IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
00566                     AppPort = LORAWAN_APP_PORT;
00567                     AppDataSize = LORAWAN_APP_DATA_SIZE;
00568                     ComplianceTest.DownLinkCounter = 0;
00569                     ComplianceTest.Running = false;
00570 
00571                     MibRequestConfirm_t mibReq;
00572                     mibReq.Type = MIB_ADR;
00573                     mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
00574                     LoRaMacMibSetRequestConfirm( &mibReq );
00575 #if defined( USE_BAND_868 )
00576                     LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
00577 #endif
00578                     break;
00579                 case 1: // (iii, iv)
00580                     AppDataSize = 2;
00581                     break;
00582                 case 2: // Enable confirmed messages (v)
00583                     IsTxConfirmed = true;
00584                     ComplianceTest.State = 1;
00585                     break;
00586                 case 3:  // Disable confirmed messages (vi)
00587                     IsTxConfirmed = false;
00588                     ComplianceTest.State = 1;
00589                     break;
00590                 case 4: // (vii)
00591                     AppDataSize = mcpsIndication->BufferSize;
00592 
00593                     AppData[0] = 4;
00594                     for( uint8_t i = 1; i < AppDataSize; i++ )
00595                     {
00596                         AppData[i] = mcpsIndication->Buffer[i] + 1;
00597                     }
00598                     break;
00599                 case 5: // (viii)
00600                     {
00601                         MlmeReq_t mlmeReq;
00602                         mlmeReq.Type = MLME_LINK_CHECK;
00603                         LoRaMacMlmeRequest( &mlmeReq );
00604                     }
00605                     break;
00606                 case 6: // (ix)
00607                     {
00608                         MlmeReq_t mlmeReq;
00609 
00610                         // Disable TestMode and revert back to normal operation
00611                         IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
00612                         AppPort = LORAWAN_APP_PORT;
00613                         AppDataSize = LORAWAN_APP_DATA_SIZE;
00614                         ComplianceTest.DownLinkCounter = 0;
00615                         ComplianceTest.Running = false;
00616 
00617                         MibRequestConfirm_t mibReq;
00618                         mibReq.Type = MIB_ADR;
00619                         mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
00620                         LoRaMacMibSetRequestConfirm( &mibReq );
00621 #if defined( USE_BAND_868 )
00622                         LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
00623 #endif
00624 
00625                         mlmeReq.Type = MLME_JOIN;
00626 
00627                         mlmeReq.Req.Join.DevEui = DevEui;
00628                         mlmeReq.Req.Join.AppEui = AppEui;
00629                         mlmeReq.Req.Join.AppKey = AppKey;
00630                         mlmeReq.Req.Join.NbTrials = 3;
00631 
00632                         LoRaMacMlmeRequest( &mlmeReq );
00633                         DeviceState = DEVICE_STATE_SLEEP;
00634                     }
00635                     break;
00636                 case 7: // (x)
00637                     {
00638                         if( mcpsIndication->BufferSize == 3 )
00639                         {
00640                             MlmeReq_t mlmeReq;
00641                             mlmeReq.Type = MLME_TXCW;
00642                             mlmeReq.Req.TxCw.Timeout = ( uint16_t )( ( mcpsIndication->Buffer[1] << 8 ) | mcpsIndication->Buffer[2] );
00643                             LoRaMacMlmeRequest( &mlmeReq );
00644                         }
00645                         else if( mcpsIndication->BufferSize == 7 )
00646                         {
00647                             MlmeReq_t mlmeReq;
00648                             mlmeReq.Type = MLME_TXCW_1;
00649                             mlmeReq.Req.TxCw.Timeout = ( uint16_t )( ( mcpsIndication->Buffer[1] << 8 ) | mcpsIndication->Buffer[2] );
00650                             mlmeReq.Req.TxCw.Frequency = ( uint32_t )( ( mcpsIndication->Buffer[3] << 16 ) | ( mcpsIndication->Buffer[4] << 8 ) | mcpsIndication->Buffer[5] ) * 100;
00651                             mlmeReq.Req.TxCw.Power = mcpsIndication->Buffer[6];
00652                             LoRaMacMlmeRequest( &mlmeReq );
00653                         }
00654                         ComplianceTest.State = 1;
00655                     }
00656                     break;
00657                 default:
00658                     break;
00659                 }
00660             }
00661             break;
00662         default:
00663             break;
00664         }
00665     }
00666 
00667     DownlinkStatusUpdated = true;
00668 }
00669 
00670 /*!
00671  * \brief   MLME-Confirm event function
00672  *
00673  * \param   [IN] mlmeConfirm - Pointer to the confirm structure,
00674  *               containing confirm attributes.
00675  */
00676 static void MlmeConfirm( MlmeConfirm_t *mlmeConfirm )
00677 {
00678     switch( mlmeConfirm->MlmeRequest )
00679     {
00680         case MLME_JOIN:
00681         {
00682             if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
00683             {
00684                 // Status is OK, node has joined the network
00685                 IsNetworkJoinedStatusUpdate = true;
00686                 DeviceState = DEVICE_STATE_SEND;
00687             }
00688             else
00689             {
00690                 // Join was not successful. Try to join again
00691                 DeviceState = DEVICE_STATE_JOIN;
00692             }
00693             break;
00694         }
00695         case MLME_LINK_CHECK:
00696         {
00697             if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
00698             {
00699                 // Check DemodMargin
00700                 // Check NbGateways
00701                 if( ComplianceTest.Running == true )
00702                 {
00703                     ComplianceTest.LinkCheck = true;
00704                     ComplianceTest.DemodMargin = mlmeConfirm->DemodMargin;
00705                     ComplianceTest.NbGateways = mlmeConfirm->NbGateways;
00706                 }
00707             }
00708             break;
00709         }
00710         default:
00711             break;
00712     }
00713     NextTx = true;
00714     UplinkStatusUpdated = true;
00715 }
00716 
00717 void flash_builtin() {
00718     myled = 1;   // turn the LED on (HIGH is the voltage level)
00719     wait(2);                       // wait for a second
00720     myled = 0;    // turn the LED off by making the voltage LOW
00721     wait(1);
00722 }
00723 
00724 /**
00725  * Main application entry point.
00726  */
00727 Serial pc(SERIAL_TX, SERIAL_RX,115200);
00728 int MY_SetSysClock_PLL_HSE(void)
00729 {
00730     RCC_ClkInitTypeDef RCC_ClkInitStruct;
00731     RCC_OscInitTypeDef RCC_OscInitStruct;
00732 
00733     /* Enable HSE and activate PLL with HSE as source */
00734     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
00735     RCC_OscInitStruct.HSEState       = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */
00736 
00737     // PLLCLK = (8 MHz * 8)/2 = 32 MHz
00738     RCC_OscInitStruct.PLL.PLLState        = RCC_PLL_ON;
00739     RCC_OscInitStruct.PLL.PLLSource       = RCC_PLLSOURCE_HSE;
00740     RCC_OscInitStruct.PLL.PLLMUL          = RCC_PLLMUL_8;
00741     RCC_OscInitStruct.PLL.PLLDIV          = RCC_PLLDIV_2;
00742     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
00743         return (-1); // FAIL
00744     }
00745 
00746     /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
00747     RCC_ClkInitStruct.ClockType      = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
00748     RCC_ClkInitStruct.SYSCLKSource   = RCC_SYSCLKSOURCE_PLLCLK; // 32 MHz
00749     RCC_ClkInitStruct.AHBCLKDivider  = RCC_SYSCLK_DIV1;         // 32 MHz
00750     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;           // 32 MHz
00751     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;           // 32 MHz
00752     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) {
00753         return (-2); // FAIL
00754     }
00755 
00756     /* Enable HSE and activate PLL with HSE as source */
00757     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_MSI;
00758     RCC_OscInitStruct.HSIState       = RCC_HSI_OFF;
00759     RCC_OscInitStruct.MSIState       = RCC_MSI_OFF;
00760     RCC_OscInitStruct.HSI48State     = RCC_HSI48_OFF;
00761     RCC_OscInitStruct.PLL.PLLState   = RCC_PLL_NONE;
00762     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
00763         return (-3); // FAIL
00764     }
00765         
00766     return 0; // OK
00767 }
00768 
00769 void my_patch(void)
00770 {
00771     int retVal;
00772     
00773     HAL_RCC_DeInit();
00774     retVal = MY_SetSysClock_PLL_HSE();
00775     if(retVal< 0)
00776     {
00777         // fail
00778         pc.printf("Failed to start HSE, ERR= %d\r\n", retVal);
00779         
00780         // indicate error
00781         while(1)
00782         {
00783             myled = 1;
00784             wait(0.2);
00785             myled = 0;
00786             wait(0.5);
00787         }
00788     }    
00789 }
00790 
00791 int main( void )
00792 {
00793     pc.printf("mbed-os-rev: %d.%d.%d   lib-rev: %d\r\n", \
00794             MBED_MAJOR_VERSION, MBED_MINOR_VERSION,MBED_PATCH_VERSION,MBED_LIBRARY_VERSION);
00795     pc.printf("BUILD= %s, SysClock= %d, RCC= %0X\r\n", __TIME__, SystemCoreClock, RCC->CR);   
00796     my_patch();
00797     pc.printf("NEW SysClock= %d, NEW RCC= %0X\r\n", SystemCoreClock, RCC->CR);
00798    
00799     flash_builtin();
00800     flash_builtin();
00801     flash_builtin();
00802     flash_builtin();
00803     
00804     LoRaMacPrimitives_t LoRaMacPrimitives;
00805     LoRaMacCallback_t LoRaMacCallbacks;
00806     MibRequestConfirm_t mibReq;
00807 
00808     BoardInit( );
00809     SerialDisplayInit( );
00810 
00811     SerialDisplayUpdateEui( 5, DevEui );
00812     SerialDisplayUpdateEui( 6, AppEui );
00813     SerialDisplayUpdateKey( 7, AppKey );
00814 
00815 #if( OVER_THE_AIR_ACTIVATION == 0 )
00816     SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID );
00817     SerialDisplayUpdateDevAddr( DevAddr );
00818     SerialDisplayUpdateKey( 12, NwkSKey );
00819     SerialDisplayUpdateKey( 13, AppSKey );
00820 #endif
00821 
00822     myGreenLed = 0;
00823     myBlueLed = 0;
00824     DeviceState = DEVICE_STATE_INIT;
00825 
00826     while( 1 )
00827     {
00828         SerialRxProcess( );
00829         flash_builtin();
00830         if( IsNetworkJoinedStatusUpdate == true )
00831         {
00832             IsNetworkJoinedStatusUpdate = false;
00833             mibReq.Type = MIB_NETWORK_JOINED;
00834             LoRaMacMibGetRequestConfirm( &mibReq );
00835             SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined );
00836             if(mibReq.Param.IsNetworkJoined == true)
00837                 myGreenLed = 1;
00838             else
00839                 myGreenLed = 0;
00840         }
00841         if( UplinkStatusUpdated == true )
00842         {
00843             UplinkStatusUpdated = false;
00844             SerialDisplayUpdateUplink( LoRaMacUplinkStatus.Acked, LoRaMacUplinkStatus.Datarate, LoRaMacUplinkStatus.UplinkCounter, LoRaMacUplinkStatus.Port, LoRaMacUplinkStatus.Buffer, LoRaMacUplinkStatus.BufferSize );
00845             
00846             myBlueLed = 1; wait(1); myBlueLed = 0; wait(1);
00847             myBlueLed = 1; wait(1); myBlueLed = 0; wait(1);
00848         }
00849         if( DownlinkStatusUpdated == true )
00850         {
00851             DownlinkStatusUpdated = false;
00852             SerialDisplayUpdateDownlink( LoRaMacDownlinkStatus.RxData, LoRaMacDownlinkStatus.Rssi, LoRaMacDownlinkStatus.Snr, LoRaMacDownlinkStatus.DownlinkCounter, LoRaMacDownlinkStatus.Port, LoRaMacDownlinkStatus.Buffer, LoRaMacDownlinkStatus.BufferSize );
00853         }
00854         
00855         switch( DeviceState )
00856         {
00857             case DEVICE_STATE_INIT:
00858             {
00859                 LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm;
00860                 LoRaMacPrimitives.MacMcpsIndication = McpsIndication;
00861                 LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm;
00862                 LoRaMacCallbacks.GetBatteryLevel = BoardGetBatteryLevel;
00863                 LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks );
00864 
00865                 TimerInit( &TxNextPacketTimer, OnTxNextPacketTimerEvent );
00866 
00867                 mibReq.Type = MIB_ADR;
00868                 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
00869                 LoRaMacMibSetRequestConfirm( &mibReq );
00870 
00871                 mibReq.Type = MIB_PUBLIC_NETWORK;
00872                 mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK;
00873                 
00874                 
00875                 LoRaMacMibSetRequestConfirm( &mibReq );
00876                 
00877                 
00878 /*Class C updated Code Start----------------------------------------------------*/
00879                 mibReq.Type = MIB_DEVICE_CLASS;
00880                 mibReq.Param.Class = CLASS_C;
00881                 LoRaMacMibSetRequestConfirm( &mibReq );
00882 /* Class C updated Code END----------------------------------------------------*/
00883 
00884 #if defined( USE_BAND_868 )
00885                 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
00886                 SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON );
00887 
00888 #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 )
00889                 LoRaMacChannelAdd( 3, ( ChannelParams_t )LC4 );
00890                 LoRaMacChannelAdd( 4, ( ChannelParams_t )LC5 );
00891                 LoRaMacChannelAdd( 5, ( ChannelParams_t )LC6 );
00892                 LoRaMacChannelAdd( 6, ( ChannelParams_t )LC7 );
00893                 LoRaMacChannelAdd( 7, ( ChannelParams_t )LC8 );
00894                 LoRaMacChannelAdd( 8, ( ChannelParams_t )LC9 );
00895                 LoRaMacChannelAdd( 9, ( ChannelParams_t )LC10 );
00896 
00897                 mibReq.Type = MIB_RX2_DEFAULT_CHANNEL;
00898                 mibReq.Param.Rx2DefaultChannel = ( Rx2ChannelParams_t ){ 869525000, DR_3 };
00899                 LoRaMacMibSetRequestConfirm( &mibReq );
00900 
00901                 mibReq.Type = MIB_RX2_CHANNEL;
00902                 mibReq.Param.Rx2Channel = ( Rx2ChannelParams_t ){ 869525000, DR_3 };
00903                 LoRaMacMibSetRequestConfirm( &mibReq );
00904 #endif
00905 
00906 #endif
00907                 SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION );
00908                 SerialDisplayUpdateAdr( LORAWAN_ADR_ON );
00909                 SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK );
00910 
00911                 LoRaMacDownlinkStatus.DownlinkCounter = 0;
00912 
00913                 DeviceState = DEVICE_STATE_JOIN;
00914                 break;
00915             }
00916             case DEVICE_STATE_JOIN:
00917             {
00918 #if( OVER_THE_AIR_ACTIVATION != 0 )
00919                 MlmeReq_t mlmeReq;
00920 
00921                 mlmeReq.Type = MLME_JOIN;
00922 
00923                 mlmeReq.Req.Join.DevEui = DevEui;
00924                 mlmeReq.Req.Join.AppEui = AppEui;
00925                 mlmeReq.Req.Join.AppKey = AppKey;
00926 
00927                 if( NextTx == true )
00928                 {
00929                     LoRaMacMlmeRequest( &mlmeReq );
00930                 }
00931                 DeviceState = DEVICE_STATE_SLEEP;
00932 #else
00933                 mibReq.Type = MIB_NET_ID;
00934                 mibReq.Param.NetID = LORAWAN_NETWORK_ID;
00935                 LoRaMacMibSetRequestConfirm( &mibReq );
00936 
00937                 mibReq.Type = MIB_DEV_ADDR;
00938                 mibReq.Param.DevAddr = DevAddr;
00939                 LoRaMacMibSetRequestConfirm( &mibReq );
00940 
00941                 mibReq.Type = MIB_NWK_SKEY;
00942                 mibReq.Param.NwkSKey = NwkSKey;
00943                 LoRaMacMibSetRequestConfirm( &mibReq );
00944 
00945                 mibReq.Type = MIB_APP_SKEY;
00946                 mibReq.Param.AppSKey = AppSKey;
00947                 LoRaMacMibSetRequestConfirm( &mibReq );
00948 
00949                 mibReq.Type = MIB_NETWORK_JOINED;
00950                 mibReq.Param.IsNetworkJoined = true;
00951                 LoRaMacMibSetRequestConfirm( &mibReq );
00952 
00953                 DeviceState = DEVICE_STATE_SEND;
00954 #endif
00955                 IsNetworkJoinedStatusUpdate = true;
00956                 break;
00957             }
00958             case DEVICE_STATE_SEND:
00959             {
00960                 
00961                 if( NextTx == true )
00962                 {
00963                     SerialDisplayUpdateUplinkAcked( false );
00964                     SerialDisplayUpdateDonwlinkRxData( false );
00965                     PrepareTxFrame( AppPort );
00966 
00967                     NextTx = SendFrame( );
00968                 }
00969                 if( ComplianceTest.Running == true )
00970                 {
00971                     // Schedule next packet transmission
00972                     TxDutyCycleTime = 5000; // 5000 ms
00973                 }
00974                 else
00975                 {
00976                     // Schedule next packet transmission
00977                     TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND );
00978                 }
00979                 
00980                 DeviceState = DEVICE_STATE_CYCLE;
00981                 break;
00982             }
00983             case DEVICE_STATE_CYCLE:
00984             {
00985                 DeviceState = DEVICE_STATE_SLEEP;
00986 
00987                 // Schedule next packet transmission
00988                 TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime );
00989                 TimerStart( &TxNextPacketTimer );
00990                 break;
00991             }
00992             case DEVICE_STATE_SLEEP:
00993             {
00994                 // Wake up through events
00995                 break;
00996             }
00997             default:
00998             {
00999                 DeviceState = DEVICE_STATE_INIT;
01000                 break;
01001             }
01002         }
01003     }
01004 }