LoRaWAN-hello-world code for Tushar

Dependencies:   mbed LoRaWAN-lib

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 DigitalOut myled(D6);
00220 
00221 
00222 
00223 void SerialDisplayRefresh( void )
00224 {
00225     MibRequestConfirm_t mibReq;
00226 
00227     SerialDisplayInit( );
00228     SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION );
00229 
00230 #if( OVER_THE_AIR_ACTIVATION == 0 )
00231     SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID );
00232     SerialDisplayUpdateDevAddr( DevAddr );
00233     SerialDisplayUpdateKey( 12, NwkSKey );
00234     SerialDisplayUpdateKey( 13, AppSKey );
00235 #endif
00236     SerialDisplayUpdateEui( 5, DevEui );
00237     SerialDisplayUpdateEui( 6, AppEui );
00238     SerialDisplayUpdateKey( 7, AppKey );
00239 
00240     mibReq.Type = MIB_NETWORK_JOINED;
00241     LoRaMacMibGetRequestConfirm( &mibReq );
00242     SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined );
00243 
00244     SerialDisplayUpdateAdr( LORAWAN_ADR_ON );
00245 #if defined( USE_BAND_868 )
00246     SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON );
00247 #else
00248     SerialDisplayUpdateDutyCycle( false );
00249 #endif
00250     SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK );
00251 }
00252 
00253 void SerialRxProcess( void )
00254 {
00255     if( SerialDisplayReadable( ) == true )
00256     {
00257         switch( SerialDisplayGetChar( ) )
00258         {
00259             case 'R':
00260             case 'r':
00261                 // Refresh Serial screen
00262                 SerialDisplayRefresh( );
00263                 break;
00264             default:
00265                 break;
00266         }
00267     }
00268 }
00269 
00270 /*!
00271  * \brief   Prepares the payload of the frame
00272  */
00273 static void PrepareTxFrame( uint8_t port )
00274 {
00275     switch( port )
00276     {
00277     case 15:
00278         {
00279             AppData[0] = 0;
00280             if( IsTxConfirmed == true )
00281             {
00282                 AppData[1] = LoRaMacDownlinkStatus.DownlinkCounter >> 8;
00283                 AppData[2] = LoRaMacDownlinkStatus.DownlinkCounter;
00284                 AppData[3] = LoRaMacDownlinkStatus.Rssi >> 8;
00285                 AppData[4] = LoRaMacDownlinkStatus.Rssi;
00286                 AppData[5] = LoRaMacDownlinkStatus.Snr;
00287             }
00288         }
00289         break;
00290     case 224:
00291         if( ComplianceTest.LinkCheck == true )
00292         {
00293             ComplianceTest.LinkCheck = false;
00294             AppDataSize = 3;
00295             AppData[0] = 5;
00296             AppData[1] = ComplianceTest.DemodMargin;
00297             AppData[2] = ComplianceTest.NbGateways;
00298             ComplianceTest.State = 1;
00299         }
00300         else
00301         {
00302             switch( ComplianceTest.State )
00303             {
00304             case 4:
00305                 ComplianceTest.State = 1;
00306                 break;
00307             case 1:
00308                 AppDataSize = 2;
00309                 AppData[0] = ComplianceTest.DownLinkCounter >> 8;
00310                 AppData[1] = ComplianceTest.DownLinkCounter;
00311                 break;
00312             }
00313         }
00314         break;
00315     default:
00316         break;
00317     }
00318 }
00319 
00320 /*!
00321  * \brief   Prepares the payload of the frame
00322  *
00323  * \retval  [0: frame could be send, 1: error]
00324  */
00325 static bool SendFrame( void )
00326 {
00327     McpsReq_t mcpsReq;
00328     LoRaMacTxInfo_t txInfo;
00329 
00330     if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK )
00331     {
00332         // Send empty frame in order to flush MAC commands
00333         mcpsReq.Type = MCPS_UNCONFIRMED;
00334         mcpsReq.Req.Unconfirmed.fBuffer = NULL;
00335         mcpsReq.Req.Unconfirmed.fBufferSize = 0;
00336         mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
00337 
00338         LoRaMacUplinkStatus.Acked = false;
00339         LoRaMacUplinkStatus.Port = 0;
00340         LoRaMacUplinkStatus.Buffer = NULL;
00341         LoRaMacUplinkStatus.BufferSize = 0;
00342         SerialDisplayUpdateFrameType( false );
00343     }
00344     else
00345     {
00346         LoRaMacUplinkStatus.Acked = false;
00347         LoRaMacUplinkStatus.Port = AppPort;
00348         LoRaMacUplinkStatus.Buffer = AppData;
00349         LoRaMacUplinkStatus.BufferSize = AppDataSize;
00350         SerialDisplayUpdateFrameType( IsTxConfirmed );
00351 
00352         if( IsTxConfirmed == false )
00353         {
00354             mcpsReq.Type = MCPS_UNCONFIRMED;
00355             mcpsReq.Req.Unconfirmed.fPort = AppPort;
00356             mcpsReq.Req.Unconfirmed.fBuffer = AppData;
00357             mcpsReq.Req.Unconfirmed.fBufferSize = AppDataSize;
00358             mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
00359         }
00360         else
00361         {
00362             mcpsReq.Type = MCPS_CONFIRMED;
00363             mcpsReq.Req.Confirmed.fPort = AppPort;
00364             mcpsReq.Req.Confirmed.fBuffer = AppData;
00365             mcpsReq.Req.Confirmed.fBufferSize = AppDataSize;
00366             mcpsReq.Req.Confirmed.NbTrials = 8;
00367             mcpsReq.Req.Confirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
00368         }
00369     }
00370 
00371     if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK )
00372     {
00373         return false;
00374     }
00375     return true;
00376 }
00377 
00378 /*!
00379  * \brief Function executed on TxNextPacket Timeout event
00380  */
00381 static void OnTxNextPacketTimerEvent( void )
00382 {
00383     MibRequestConfirm_t mibReq;
00384     LoRaMacStatus_t status;
00385 
00386     TimerStop( &TxNextPacketTimer );
00387 
00388     mibReq.Type = MIB_NETWORK_JOINED;
00389     status = LoRaMacMibGetRequestConfirm( &mibReq );
00390 
00391     if( status == LORAMAC_STATUS_OK )
00392     {
00393         if( mibReq.Param.IsNetworkJoined == true )
00394         {
00395             DeviceState = DEVICE_STATE_SEND;
00396             NextTx = true;
00397         }
00398         else
00399         {
00400             DeviceState = DEVICE_STATE_JOIN;
00401         }
00402     }
00403 }
00404 
00405 
00406 /*!
00407  * \brief   MCPS-Confirm event function
00408  *
00409  * \param   [IN] mcpsConfirm - Pointer to the confirm structure,
00410  *               containing confirm attributes.
00411  */
00412 static void McpsConfirm( McpsConfirm_t *mcpsConfirm )
00413 {
00414     if( mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
00415     {
00416         switch( mcpsConfirm->McpsRequest )
00417         {
00418             case MCPS_UNCONFIRMED:
00419             {
00420                 // Check Datarate
00421                 // Check TxPower
00422                 break;
00423             }
00424             case MCPS_CONFIRMED:
00425             {
00426                 // Check Datarate
00427                 // Check TxPower
00428                 // Check AckReceived
00429                 // Check NbTrials
00430                 LoRaMacUplinkStatus.Acked = mcpsConfirm->AckReceived;
00431                 break;
00432             }
00433             case MCPS_PROPRIETARY:
00434             {
00435                 break;
00436             }
00437             default:
00438                 break;
00439         }
00440         LoRaMacUplinkStatus.Datarate = mcpsConfirm->Datarate;
00441         LoRaMacUplinkStatus.UplinkCounter = mcpsConfirm->UpLinkCounter;
00442 
00443         UplinkStatusUpdated = true;
00444     }
00445     NextTx = true;
00446 }
00447 
00448 /*!
00449  * \brief   MCPS-Indication event function
00450  *
00451  * \param   [IN] mcpsIndication - Pointer to the indication structure,
00452  *               containing indication attributes.
00453  */
00454 static void McpsIndication( McpsIndication_t *mcpsIndication )
00455 {
00456     if( mcpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK )
00457     {
00458         return;
00459     }
00460 
00461     switch( mcpsIndication->McpsIndication )
00462     {
00463         case MCPS_UNCONFIRMED:
00464         {
00465             break;
00466         }
00467         case MCPS_CONFIRMED:
00468         {
00469             break;
00470         }
00471         case MCPS_PROPRIETARY:
00472         {
00473             break;
00474         }
00475         case MCPS_MULTICAST:
00476         {
00477             break;
00478         }
00479         default:
00480             break;
00481     }
00482 
00483     // Check Multicast
00484     // Check Port
00485     // Check Datarate
00486     // Check FramePending
00487     // Check Buffer
00488     // Check BufferSize
00489     // Check Rssi
00490     // Check Snr
00491     // Check RxSlot
00492     LoRaMacDownlinkStatus.Rssi = mcpsIndication->Rssi;
00493     if( mcpsIndication->Snr & 0x80 ) // The SNR sign bit is 1
00494     {
00495         // Invert and divide by 4
00496         LoRaMacDownlinkStatus.Snr = ( ( ~mcpsIndication->Snr + 1 ) & 0xFF ) >> 2;
00497         LoRaMacDownlinkStatus.Snr = -LoRaMacDownlinkStatus.Snr;
00498     }
00499     else
00500     {
00501         // Divide by 4
00502         LoRaMacDownlinkStatus.Snr = ( mcpsIndication->Snr & 0xFF ) >> 2;
00503     }
00504     LoRaMacDownlinkStatus.DownlinkCounter++;
00505     LoRaMacDownlinkStatus.RxData = mcpsIndication->RxData;
00506     LoRaMacDownlinkStatus.Port = mcpsIndication->Port;
00507     LoRaMacDownlinkStatus.Buffer = mcpsIndication->Buffer;
00508     LoRaMacDownlinkStatus.BufferSize = mcpsIndication->BufferSize;
00509 
00510     if( ComplianceTest.Running == true )
00511     {
00512         ComplianceTest.DownLinkCounter++;
00513     }
00514 
00515     if( mcpsIndication->RxData == true )
00516     {
00517         switch( mcpsIndication->Port )
00518         {
00519         case 1: // The application LED can be controlled on port 1 or 2
00520         case 2:
00521             break;
00522         case 224:
00523             if( ComplianceTest.Running == false )
00524             {
00525                 // Check compliance test enable command (i)
00526                 if( ( mcpsIndication->BufferSize == 4 ) &&
00527                     ( mcpsIndication->Buffer[0] == 0x01 ) &&
00528                     ( mcpsIndication->Buffer[1] == 0x01 ) &&
00529                     ( mcpsIndication->Buffer[2] == 0x01 ) &&
00530                     ( mcpsIndication->Buffer[3] == 0x01 ) )
00531                 {
00532                     IsTxConfirmed = false;
00533                     AppPort = 224;
00534                     AppDataSize = 2;
00535                     ComplianceTest.DownLinkCounter = 0;
00536                     ComplianceTest.LinkCheck = false;
00537                     ComplianceTest.DemodMargin = 0;
00538                     ComplianceTest.NbGateways = 0;
00539                     ComplianceTest.Running = true;
00540                     ComplianceTest.State = 1;
00541 
00542                     MibRequestConfirm_t mibReq;
00543                     mibReq.Type = MIB_ADR;
00544                     mibReq.Param.AdrEnable = true;
00545                     LoRaMacMibSetRequestConfirm( &mibReq );
00546 
00547 #if defined( USE_BAND_868 )
00548                     LoRaMacTestSetDutyCycleOn( false );
00549 #endif
00550                 }
00551             }
00552             else
00553             {
00554                 ComplianceTest.State = mcpsIndication->Buffer[0];
00555                 switch( ComplianceTest.State )
00556                 {
00557                 case 0: // Check compliance test disable command (ii)
00558                     IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
00559                     AppPort = LORAWAN_APP_PORT;
00560                     AppDataSize = LORAWAN_APP_DATA_SIZE;
00561                     ComplianceTest.DownLinkCounter = 0;
00562                     ComplianceTest.Running = false;
00563 
00564                     MibRequestConfirm_t mibReq;
00565                     mibReq.Type = MIB_ADR;
00566                     mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
00567                     LoRaMacMibSetRequestConfirm( &mibReq );
00568 #if defined( USE_BAND_868 )
00569                     LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
00570 #endif
00571                     break;
00572                 case 1: // (iii, iv)
00573                     AppDataSize = 2;
00574                     break;
00575                 case 2: // Enable confirmed messages (v)
00576                     IsTxConfirmed = true;
00577                     ComplianceTest.State = 1;
00578                     break;
00579                 case 3:  // Disable confirmed messages (vi)
00580                     IsTxConfirmed = false;
00581                     ComplianceTest.State = 1;
00582                     break;
00583                 case 4: // (vii)
00584                     AppDataSize = mcpsIndication->BufferSize;
00585 
00586                     AppData[0] = 4;
00587                     for( uint8_t i = 1; i < AppDataSize; i++ )
00588                     {
00589                         AppData[i] = mcpsIndication->Buffer[i] + 1;
00590                     }
00591                     break;
00592                 case 5: // (viii)
00593                     {
00594                         MlmeReq_t mlmeReq;
00595                         mlmeReq.Type = MLME_LINK_CHECK;
00596                         LoRaMacMlmeRequest( &mlmeReq );
00597                     }
00598                     break;
00599                 case 6: // (ix)
00600                     {
00601                         MlmeReq_t mlmeReq;
00602 
00603                         // Disable TestMode and revert back to normal operation
00604                         IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
00605                         AppPort = LORAWAN_APP_PORT;
00606                         AppDataSize = LORAWAN_APP_DATA_SIZE;
00607                         ComplianceTest.DownLinkCounter = 0;
00608                         ComplianceTest.Running = false;
00609 
00610                         MibRequestConfirm_t mibReq;
00611                         mibReq.Type = MIB_ADR;
00612                         mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
00613                         LoRaMacMibSetRequestConfirm( &mibReq );
00614 #if defined( USE_BAND_868 )
00615                         LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
00616 #endif
00617 
00618                         mlmeReq.Type = MLME_JOIN;
00619 
00620                         mlmeReq.Req.Join.DevEui = DevEui;
00621                         mlmeReq.Req.Join.AppEui = AppEui;
00622                         mlmeReq.Req.Join.AppKey = AppKey;
00623                         mlmeReq.Req.Join.NbTrials = 3;
00624 
00625                         LoRaMacMlmeRequest( &mlmeReq );
00626                         DeviceState = DEVICE_STATE_SLEEP;
00627                     }
00628                     break;
00629                 case 7: // (x)
00630                     {
00631                         if( mcpsIndication->BufferSize == 3 )
00632                         {
00633                             MlmeReq_t mlmeReq;
00634                             mlmeReq.Type = MLME_TXCW;
00635                             mlmeReq.Req.TxCw.Timeout = ( uint16_t )( ( mcpsIndication->Buffer[1] << 8 ) | mcpsIndication->Buffer[2] );
00636                             LoRaMacMlmeRequest( &mlmeReq );
00637                         }
00638                         else if( mcpsIndication->BufferSize == 7 )
00639                         {
00640                             MlmeReq_t mlmeReq;
00641                             mlmeReq.Type = MLME_TXCW_1;
00642                             mlmeReq.Req.TxCw.Timeout = ( uint16_t )( ( mcpsIndication->Buffer[1] << 8 ) | mcpsIndication->Buffer[2] );
00643                             mlmeReq.Req.TxCw.Frequency = ( uint32_t )( ( mcpsIndication->Buffer[3] << 16 ) | ( mcpsIndication->Buffer[4] << 8 ) | mcpsIndication->Buffer[5] ) * 100;
00644                             mlmeReq.Req.TxCw.Power = mcpsIndication->Buffer[6];
00645                             LoRaMacMlmeRequest( &mlmeReq );
00646                         }
00647                         ComplianceTest.State = 1;
00648                     }
00649                     break;
00650                 default:
00651                     break;
00652                 }
00653             }
00654             break;
00655         default:
00656             break;
00657         }
00658     }
00659 
00660     DownlinkStatusUpdated = true;
00661 }
00662 
00663 /*!
00664  * \brief   MLME-Confirm event function
00665  *
00666  * \param   [IN] mlmeConfirm - Pointer to the confirm structure,
00667  *               containing confirm attributes.
00668  */
00669 static void MlmeConfirm( MlmeConfirm_t *mlmeConfirm )
00670 {
00671     switch( mlmeConfirm->MlmeRequest )
00672     {
00673         case MLME_JOIN:
00674         {
00675             if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
00676             {
00677                 // Status is OK, node has joined the network
00678                 IsNetworkJoinedStatusUpdate = true;
00679                 DeviceState = DEVICE_STATE_SEND;
00680             }
00681             else
00682             {
00683                 // Join was not successful. Try to join again
00684                 DeviceState = DEVICE_STATE_JOIN;
00685             }
00686             break;
00687         }
00688         case MLME_LINK_CHECK:
00689         {
00690             if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
00691             {
00692                 // Check DemodMargin
00693                 // Check NbGateways
00694                 if( ComplianceTest.Running == true )
00695                 {
00696                     ComplianceTest.LinkCheck = true;
00697                     ComplianceTest.DemodMargin = mlmeConfirm->DemodMargin;
00698                     ComplianceTest.NbGateways = mlmeConfirm->NbGateways;
00699                 }
00700             }
00701             break;
00702         }
00703         default:
00704             break;
00705     }
00706     NextTx = true;
00707     UplinkStatusUpdated = true;
00708 }
00709 
00710 void flash_builtin() {
00711     myled = 1;   // turn the LED on (HIGH is the voltage level)
00712     wait(2);                       // wait for a second
00713     myled = 0;    // turn the LED off by making the voltage LOW
00714     wait(1);
00715 }
00716 
00717 /**
00718  * Main application entry point.
00719  */
00720 Serial pc(SERIAL_TX, SERIAL_RX,115200);
00721 int MY_SetSysClock_PLL_HSE(void)
00722 {
00723     RCC_ClkInitTypeDef RCC_ClkInitStruct;
00724     RCC_OscInitTypeDef RCC_OscInitStruct;
00725 
00726     /* Enable HSE and activate PLL with HSE as source */
00727     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
00728     RCC_OscInitStruct.HSEState       = RCC_HSE_ON; /* External 8 MHz xtal on OSC_IN/OSC_OUT */
00729 
00730     // PLLCLK = (8 MHz * 8)/2 = 32 MHz
00731     RCC_OscInitStruct.PLL.PLLState        = RCC_PLL_ON;
00732     RCC_OscInitStruct.PLL.PLLSource       = RCC_PLLSOURCE_HSE;
00733     RCC_OscInitStruct.PLL.PLLMUL          = RCC_PLLMUL_8;
00734     RCC_OscInitStruct.PLL.PLLDIV          = RCC_PLLDIV_2;
00735     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
00736         return (-1); // FAIL
00737     }
00738 
00739     /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
00740     RCC_ClkInitStruct.ClockType      = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
00741     RCC_ClkInitStruct.SYSCLKSource   = RCC_SYSCLKSOURCE_PLLCLK; // 32 MHz
00742     RCC_ClkInitStruct.AHBCLKDivider  = RCC_SYSCLK_DIV1;         // 32 MHz
00743     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;           // 32 MHz
00744     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;           // 32 MHz
00745     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) {
00746         return (-2); // FAIL
00747     }
00748 
00749     /* Enable HSE and activate PLL with HSE as source */
00750     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_MSI;
00751     RCC_OscInitStruct.HSIState       = RCC_HSI_OFF;
00752     RCC_OscInitStruct.MSIState       = RCC_MSI_OFF;
00753     RCC_OscInitStruct.HSI48State     = RCC_HSI48_OFF;
00754     RCC_OscInitStruct.PLL.PLLState   = RCC_PLL_NONE;
00755     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
00756         return (-3); // FAIL
00757     }
00758         
00759     return 0; // OK
00760 }
00761 
00762 void my_patch(void)
00763 {
00764     int retVal;
00765     
00766     HAL_RCC_DeInit();
00767     retVal = MY_SetSysClock_PLL_HSE();
00768     if(retVal< 0)
00769     {
00770         // fail
00771         pc.printf("Failed to start HSE, ERR= %d\r\n", retVal);
00772         
00773         // indicate error
00774         while(1)
00775         {
00776             myled = 1;
00777             wait(0.2);
00778             myled = 0;
00779             wait(0.5);
00780         }
00781     }    
00782 }
00783 
00784 int main( void )
00785 {
00786     pc.printf("mbed-os-rev: %d.%d.%d   lib-rev: %d\r\n", \
00787             MBED_MAJOR_VERSION, MBED_MINOR_VERSION,MBED_PATCH_VERSION,MBED_LIBRARY_VERSION);
00788     pc.printf("BUILD= %s, SysClock= %d, RCC= %0X\r\n", __TIME__, SystemCoreClock, RCC->CR);   
00789     my_patch();
00790     pc.printf("NEW SysClock= %d, NEW RCC= %0X\r\n", SystemCoreClock, RCC->CR);
00791    
00792     flash_builtin();
00793     flash_builtin();
00794     flash_builtin();
00795     flash_builtin();
00796     
00797     LoRaMacPrimitives_t LoRaMacPrimitives;
00798     LoRaMacCallback_t LoRaMacCallbacks;
00799     MibRequestConfirm_t mibReq;
00800 
00801     BoardInit( );
00802     SerialDisplayInit( );
00803 
00804     SerialDisplayUpdateEui( 5, DevEui );
00805     SerialDisplayUpdateEui( 6, AppEui );
00806     SerialDisplayUpdateKey( 7, AppKey );
00807 
00808 #if( OVER_THE_AIR_ACTIVATION == 0 )
00809     SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID );
00810     SerialDisplayUpdateDevAddr( DevAddr );
00811     SerialDisplayUpdateKey( 12, NwkSKey );
00812     SerialDisplayUpdateKey( 13, AppSKey );
00813 #endif
00814 
00815     DeviceState = DEVICE_STATE_INIT;
00816 
00817     while( 1 )
00818     {
00819         SerialRxProcess( );
00820         flash_builtin();
00821         if( IsNetworkJoinedStatusUpdate == true )
00822         {
00823             IsNetworkJoinedStatusUpdate = false;
00824             mibReq.Type = MIB_NETWORK_JOINED;
00825             LoRaMacMibGetRequestConfirm( &mibReq );
00826             SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined );
00827         }
00828         if( UplinkStatusUpdated == true )
00829         {
00830             UplinkStatusUpdated = false;
00831             SerialDisplayUpdateUplink( LoRaMacUplinkStatus.Acked, LoRaMacUplinkStatus.Datarate, LoRaMacUplinkStatus.UplinkCounter, LoRaMacUplinkStatus.Port, LoRaMacUplinkStatus.Buffer, LoRaMacUplinkStatus.BufferSize );
00832         }
00833         if( DownlinkStatusUpdated == true )
00834         {
00835             DownlinkStatusUpdated = false;
00836             SerialDisplayUpdateDownlink( LoRaMacDownlinkStatus.RxData, LoRaMacDownlinkStatus.Rssi, LoRaMacDownlinkStatus.Snr, LoRaMacDownlinkStatus.DownlinkCounter, LoRaMacDownlinkStatus.Port, LoRaMacDownlinkStatus.Buffer, LoRaMacDownlinkStatus.BufferSize );
00837         }
00838         
00839         switch( DeviceState )
00840         {
00841             case DEVICE_STATE_INIT:
00842             {
00843                 LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm;
00844                 LoRaMacPrimitives.MacMcpsIndication = McpsIndication;
00845                 LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm;
00846                 LoRaMacCallbacks.GetBatteryLevel = BoardGetBatteryLevel;
00847                 LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks );
00848 
00849                 TimerInit( &TxNextPacketTimer, OnTxNextPacketTimerEvent );
00850 
00851                 mibReq.Type = MIB_ADR;
00852                 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
00853                 LoRaMacMibSetRequestConfirm( &mibReq );
00854 
00855                 mibReq.Type = MIB_PUBLIC_NETWORK;
00856                 mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK;
00857                 LoRaMacMibSetRequestConfirm( &mibReq );
00858 
00859 #if defined( USE_BAND_868 )
00860                 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
00861                 SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON );
00862 
00863 #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 )
00864                 LoRaMacChannelAdd( 3, ( ChannelParams_t )LC4 );
00865                 LoRaMacChannelAdd( 4, ( ChannelParams_t )LC5 );
00866                 LoRaMacChannelAdd( 5, ( ChannelParams_t )LC6 );
00867                 LoRaMacChannelAdd( 6, ( ChannelParams_t )LC7 );
00868                 LoRaMacChannelAdd( 7, ( ChannelParams_t )LC8 );
00869                 LoRaMacChannelAdd( 8, ( ChannelParams_t )LC9 );
00870                 LoRaMacChannelAdd( 9, ( ChannelParams_t )LC10 );
00871 
00872                 mibReq.Type = MIB_RX2_DEFAULT_CHANNEL;
00873                 mibReq.Param.Rx2DefaultChannel = ( Rx2ChannelParams_t ){ 869525000, DR_3 };
00874                 LoRaMacMibSetRequestConfirm( &mibReq );
00875 
00876                 mibReq.Type = MIB_RX2_CHANNEL;
00877                 mibReq.Param.Rx2Channel = ( Rx2ChannelParams_t ){ 869525000, DR_3 };
00878                 LoRaMacMibSetRequestConfirm( &mibReq );
00879 #endif
00880 
00881 #endif
00882                 SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION );
00883                 SerialDisplayUpdateAdr( LORAWAN_ADR_ON );
00884                 SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK );
00885 
00886                 LoRaMacDownlinkStatus.DownlinkCounter = 0;
00887 
00888                 DeviceState = DEVICE_STATE_JOIN;
00889                 break;
00890             }
00891             case DEVICE_STATE_JOIN:
00892             {
00893 #if( OVER_THE_AIR_ACTIVATION != 0 )
00894                 MlmeReq_t mlmeReq;
00895 
00896                 mlmeReq.Type = MLME_JOIN;
00897 
00898                 mlmeReq.Req.Join.DevEui = DevEui;
00899                 mlmeReq.Req.Join.AppEui = AppEui;
00900                 mlmeReq.Req.Join.AppKey = AppKey;
00901 
00902                 if( NextTx == true )
00903                 {
00904                     LoRaMacMlmeRequest( &mlmeReq );
00905                 }
00906                 DeviceState = DEVICE_STATE_SLEEP;
00907 #else
00908                 mibReq.Type = MIB_NET_ID;
00909                 mibReq.Param.NetID = LORAWAN_NETWORK_ID;
00910                 LoRaMacMibSetRequestConfirm( &mibReq );
00911 
00912                 mibReq.Type = MIB_DEV_ADDR;
00913                 mibReq.Param.DevAddr = DevAddr;
00914                 LoRaMacMibSetRequestConfirm( &mibReq );
00915 
00916                 mibReq.Type = MIB_NWK_SKEY;
00917                 mibReq.Param.NwkSKey = NwkSKey;
00918                 LoRaMacMibSetRequestConfirm( &mibReq );
00919 
00920                 mibReq.Type = MIB_APP_SKEY;
00921                 mibReq.Param.AppSKey = AppSKey;
00922                 LoRaMacMibSetRequestConfirm( &mibReq );
00923 
00924                 mibReq.Type = MIB_NETWORK_JOINED;
00925                 mibReq.Param.IsNetworkJoined = true;
00926                 LoRaMacMibSetRequestConfirm( &mibReq );
00927 
00928                 DeviceState = DEVICE_STATE_SEND;
00929 #endif
00930                 IsNetworkJoinedStatusUpdate = true;
00931                 break;
00932             }
00933             case DEVICE_STATE_SEND:
00934             {
00935                 if( NextTx == true )
00936                 {
00937                     SerialDisplayUpdateUplinkAcked( false );
00938                     SerialDisplayUpdateDonwlinkRxData( false );
00939                     PrepareTxFrame( AppPort );
00940 
00941                     NextTx = SendFrame( );
00942                 }
00943                 if( ComplianceTest.Running == true )
00944                 {
00945                     // Schedule next packet transmission
00946                     TxDutyCycleTime = 5000; // 5000 ms
00947                 }
00948                 else
00949                 {
00950                     // Schedule next packet transmission
00951                     TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND );
00952                 }
00953                 DeviceState = DEVICE_STATE_CYCLE;
00954                 break;
00955             }
00956             case DEVICE_STATE_CYCLE:
00957             {
00958                 DeviceState = DEVICE_STATE_SLEEP;
00959 
00960                 // Schedule next packet transmission
00961                 TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime );
00962                 TimerStart( &TxNextPacketTimer );
00963                 break;
00964             }
00965             case DEVICE_STATE_SLEEP:
00966             {
00967                 // Wake up through events
00968                 break;
00969             }
00970             default:
00971             {
00972                 DeviceState = DEVICE_STATE_INIT;
00973                 break;
00974             }
00975         }
00976     }
00977 }