Hartmut J / Mbed 2 deprecated STM32F103C8T6_LoRaWAN-lmic-app

Dependencies:   LMiC_CFG_eu868 SX1276Lib mbed-STM32F103C8T6 mbed

Fork of LoRaWAN-lmic-app by Semtech

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* 
00002  / _____)             _              | |
00003 ( (____  _____ ____ _| |_ _____  ____| |__
00004  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
00005  _____) ) ____| | | || |_| ____( (___| | | |
00006 (______/|_____)_|_|_| \__)_____)\____)_| |_|
00007     (C)2015 Semtech
00008 
00009 Description: MBED LoRaWAN example application
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 
00017 #include "lmic.h"
00018 #include "debug.h"
00019 
00020 /*!
00021  * When set to 1 the application uses the Over-the-Air activation procedure
00022  * When set to 0 the application uses the Personalization activation procedure
00023  */
00024 #define OVER_THE_AIR_ACTIVATION                     0
00025 
00026 /*!
00027  * Defines the application data transmission duty cycle
00028  */
00029 #define APP_TX_DUTYCYCLE                            5000 // 5 [s] value in ms
00030 #define APP_TX_DUTYCYCLE_RND                        1000 // 1 [s] value in ms
00031 
00032 /*!
00033  * LoRaWAN Adaptative Data Rate
00034  */
00035 #define LORAWAN_ADR_ON                              1
00036 
00037 /*!
00038  * LoRaWAN confirmed messages
00039  */
00040 #define LORAWAN_CONFIRMED_MSG_ON                    0
00041 
00042 /*!
00043  * LoRaWAN application port
00044  */
00045 #define LORAWAN_APP_PORT                            15
00046 
00047 /*!
00048  * User application data buffer size
00049  */
00050 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 )
00051 #define LORAWAN_APP_DATA_SIZE                       6
00052 
00053 #else
00054 #define LORAWAN_APP_DATA_SIZE                       1
00055 
00056 #endif
00057 
00058 //////////////////////////////////////////////////
00059 // CONFIGURATION (FOR APPLICATION CALLBACKS BELOW)
00060 //////////////////////////////////////////////////
00061 
00062 // application router ID (LSBF)
00063 static const uint8_t AppEui[8] = { 0x5F, 0x14, 0x00, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 }; 
00064 
00065 // unique device ID (LSBF)
00066 static const u1_t DevEui[8] = { 0xDE, 0x3B, 0x5D, 0xEA, 0x00, 0x00, 0x00, 0x00 };
00067 
00068 // device-specific AES key (derived from device EUI)
00069 static const uint8_t DevKey[16] = { 0x3C, 0x4F, 0xCF, 0x09, 0x88, 0x15, 0xF7, 0xAB, 
00070                                     0xA6, 0xD2, 0xAE, 0x28, 0x16, 0x15, 0x7E, 0x2B };
00071 
00072 #if( OVER_THE_AIR_ACTIVATION == 0 )
00073 // network session key
00074 static uint8_t NwkSKey[] = { 0x3C, 0x4F, 0xCF, 0x09, 0x88, 0x15, 0xF7, 0xAB, 
00075                             0xA6, 0xD2, 0xAE, 0x28, 0x16, 0x15, 0x7E, 0x2B };
00076 
00077 // application session key
00078 static uint8_t ArtSKey[] = { 0x0D, 0xAB, 0x37, 0x36, 0xB4, 0x49, 0x6B, 0xC3, 
00079                             0xFA, 0x68, 0x0D, 0x28, 0x52, 0x73, 0x12, 0x6F };
00080 
00081 // LoRaWAN network ID 
00082 static const uint32_t NetId = 0x00000001;  
00083 
00084 // LoRaWAN end-device address (DevAddr)
00085 // See http://thethingsnetwork.org/wiki/AddressSpace
00086 static const uint32_t DevAddr = 0xEA5D3BDE ; // <-- Change this address for every node! 
00087 
00088 #endif
00089 
00090 
00091 // LEDs and Frame jobs
00092 osjob_t rxLedJob;
00093 osjob_t txLedJob;
00094 osjob_t sendFrameJob;
00095 
00096 // LED state
00097 static bool AppLedStateOn = false;
00098 
00099 //////////////////////////////////////////////////
00100 // Utility functions
00101 //////////////////////////////////////////////////
00102 /*!
00103  * \brief Computes a random number between min and max
00104  *
00105  * \param [IN] min range minimum value
00106  * \param [IN] max range maximum value
00107  * \retval random random value in range min..max
00108  */
00109 int32_t randr( int32_t min, int32_t max )
00110 {
00111     return ( int32_t )rand( ) % ( max - min + 1 ) + min;
00112 }
00113 
00114 //////////////////////////////////////////////////
00115 // APPLICATION CALLBACKS
00116 //////////////////////////////////////////////////
00117 
00118 // provide application router ID (8 bytes, LSBF)
00119 void os_getArtEui( uint8_t *buf )
00120 {
00121     memcpy( buf, AppEui, 8 );
00122 }
00123 
00124 // provide device ID (8 bytes, LSBF)
00125 void os_getDevEui( uint8_t *buf )
00126 {
00127     memcpy( buf, DevEui, 8 );
00128 }
00129 
00130 // provide device key (16 bytes)
00131 void os_getDevKey( uint8_t *buf )
00132 {
00133     memcpy( buf, DevKey, 16 );
00134 }
00135 
00136 //////////////////////////////////////////////////
00137 // MAIN - INITIALIZATION AND STARTUP
00138 //////////////////////////////////////////////////
00139 
00140 static void onRxLed( osjob_t* j )
00141 {
00142     debug_val("LED2 = ", 0 );
00143 }
00144 
00145 static void onTxLed( osjob_t* j )
00146 {
00147     debug_val("LED1 = ", 0 );
00148 }
00149 
00150 static void prepareTxFrame( void )
00151 {
00152     LMIC.frame[0] = AppLedStateOn;
00153 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 )
00154     LMIC.frame[1] = LMIC.seqnoDn >> 8;
00155     LMIC.frame[2] = LMIC.seqnoDn;
00156     LMIC.frame[3] = LMIC.rssi >> 8;
00157     LMIC.frame[4] = LMIC.rssi;
00158     LMIC.frame[5] = LMIC.snr;
00159 #endif    
00160 }
00161 
00162 void processRxFrame( void )
00163 {
00164     switch( LMIC.frame[LMIC.dataBeg - 1] ) // Check Rx port number
00165     {
00166         case 1: // The application LED can be controlled on port 1 or 2
00167         case 2:
00168             if( LMIC.dataLen == 1 )
00169             {
00170                 AppLedStateOn = LMIC.frame[LMIC.dataBeg] & 0x01;
00171                 debug_val( "LED3 = ", AppLedStateOn );
00172             }
00173             break;
00174         default:
00175             break;
00176     }
00177 }
00178 
00179 static void onSendFrame( osjob_t* j )
00180 {
00181     prepareTxFrame( );
00182     LMIC_setTxData2( LORAWAN_APP_PORT, LMIC.frame, LORAWAN_APP_DATA_SIZE, LORAWAN_CONFIRMED_MSG_ON );
00183 
00184     // Blink Tx LED
00185     debug_val( "LED1 = ", 1 );
00186     os_setTimedCallback( &txLedJob, os_getTime( ) + ms2osticks( 25 ), onTxLed );
00187 }
00188 
00189 // Initialization job
00190 static void onInit( osjob_t* j )
00191 {
00192     // reset MAC state
00193     LMIC_reset( );
00194     LMIC_setAdrMode( LORAWAN_ADR_ON );
00195 #if defined(CFG_eu868)
00196     LMIC_setDrTxpow( DR_SF12, 14 );
00197 #elif defined(CFG_us915)    
00198     LMIC_setDrTxpow( DR_SF10, 14 );
00199 #endif
00200 
00201     // start joining
00202 #if( OVER_THE_AIR_ACTIVATION != 0 )
00203     LMIC_startJoining( );
00204 #else
00205     LMIC_setSession( NetId, DevAddr, NwkSKey, ArtSKey );
00206     onSendFrame( NULL );
00207 #endif
00208     // init done - onEvent( ) callback will be invoked...
00209 }
00210 
00211 int main( void )
00212 {
00213     osjob_t initjob;
00214     
00215     debug_init ();
00216 
00217     // initialize runtime env
00218     os_init( );
00219     // setup initial job
00220     os_setCallback( &initjob, onInit );
00221     // execute scheduled jobs and events
00222     os_runloop( );
00223     // (not reached)
00224 }
00225 
00226 //////////////////////////////////////////////////
00227 // LMIC EVENT CALLBACK
00228 //////////////////////////////////////////////////
00229 void onEvent( ev_t ev )
00230 {
00231     bool txOn = false;
00232     debug_event( ev );
00233 
00234     switch( ev ) 
00235     {
00236     // network joined, session established
00237     case EV_JOINED:
00238         debug_val( "Net ID = ", LMIC.netid );
00239         txOn = true;
00240         break;
00241     // scheduled data sent (optionally data received)
00242     case EV_TXCOMPLETE:
00243         debug_val( "Datarate = ", LMIC.datarate );
00244         // Check if we have a downlink on either Rx1 or Rx2 windows
00245         if( ( LMIC.txrxFlags & ( TXRX_DNW1 | TXRX_DNW2 ) ) != 0 )
00246         {
00247             debug_val( "LED2 = ", 1 );
00248             os_setTimedCallback( &rxLedJob, os_getTime( ) + ms2osticks( 25 ), onRxLed );
00249 
00250             if( LMIC.dataLen != 0 )
00251             { // data received in rx slot after tx
00252                 debug_buf( LMIC.frame + LMIC.dataBeg, LMIC.dataLen );
00253                 processRxFrame( );
00254             }
00255         }
00256         txOn = true;
00257         break;
00258     default:
00259         break;
00260     }
00261     if( txOn == true )
00262     {
00263         //Sends frame every APP_TX_DUTYCYCLE +/- APP_TX_DUTYCYCLE_RND random time (if not duty cycle limited)
00264         os_setTimedCallback( &sendFrameJob,
00265                              os_getTime( ) + ms2osticks( APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ) ),
00266                              onSendFrame );
00267         
00268         ////Sends frame as soon as possible (duty cylce limitations)
00269         //onSendFrame( NULL );
00270     }
00271 }