first draft
Dependencies: LMiC SX1272Libx mbed
Fork of LoRaWAN-lmic-app by
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 1 00025 00026 #if( OVER_THE_AIR_ACTIVATION == 0 ) 00027 00028 /*! 00029 * Defines the network ID when using personalization activation procedure 00030 */ 00031 #define LORAWAN_NET_ID ( uint32_t )0x00000000 00032 00033 /*! 00034 * Defines the device address when using personalization activation procedure 00035 */ 00036 #define LORAWAN_DEV_ADDR ( uint32_t )0x12345678 00037 00038 #endif 00039 00040 /*! 00041 * Defines the application data transmission duty cycle 00042 */ 00043 #define APP_TX_DUTYCYCLE 5000 // 5 [s] value in ms 00044 #define APP_TX_DUTYCYCLE_RND 1000 // 1 [s] value in ms 00045 00046 /*! 00047 * LoRaWAN Adaptative Data Rate 00048 */ 00049 #define LORAWAN_ADR_ON 1 00050 00051 /*! 00052 * LoRaWAN confirmed messages 00053 */ 00054 #define LORAWAN_CONFIRMED_MSG_ON 1 00055 00056 /*! 00057 * LoRaWAN application port 00058 */ 00059 #define LORAWAN_APP_PORT 15 00060 00061 /*! 00062 * User application data buffer size 00063 */ 00064 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 ) 00065 #define LORAWAN_APP_DATA_SIZE 6 00066 00067 #else 00068 #define LORAWAN_APP_DATA_SIZE 1 00069 00070 #endif 00071 Serial pc(PTE0, PTE1); 00072 #define LED_RED PTA1 00073 #define LED_YEL PTA2 00074 00075 /* version history */ 00076 /* version date comments */ 00077 /* 0.1 02/26/16 first working join - no tx/rx */ 00078 00079 #define MAJOR 0 00080 #define MINOR 1 00081 00082 DigitalOut led1(LED_RED); 00083 DigitalOut led2(LED_YEL); 00084 00085 ////////////////////////////////////////////////// 00086 // CONFIGURATION (FOR APPLICATION CALLBACKS BELOW) 00087 ////////////////////////////////////////////////// 00088 // application router ID (LSBF) 00089 //static const u1_t AppEui[8] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }; 00090 static const u1_t AppEui[8] = { 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00 }; 00091 00092 // unique device ID (LSBF) 00093 static const u1_t DevEui[8] = { 0x02, 0x00, 0x00, 0x00, 0x00, 0xee, 0xff, 0xc0 }; 00094 00095 // device-specific AES key (derived from device EUI) 00096 static const u1_t DevKey[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, }; 00097 // E4 -72 -71 -C5 -F5 -30 -A9 -9F -CF -C4 -0E -AB -EA -D7 -19 -42 00098 #if( OVER_THE_AIR_ACTIVATION == 0 ) 00099 // network session key 00100 static uint8_t NwkSKey[] = 00101 { 00102 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 00103 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C 00104 }; 00105 00106 // application session key 00107 static uint8_t ArtSKey[] = 00108 { 00109 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 00110 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C 00111 }; 00112 00113 #endif 00114 00115 // LEDs and Frame jobs 00116 osjob_t rxLedJob; 00117 osjob_t txLedJob; 00118 osjob_t sendFrameJob; 00119 00120 // LED state 00121 static bool AppLedStateOn = false; 00122 00123 ////////////////////////////////////////////////// 00124 // Utility functions 00125 ////////////////////////////////////////////////// 00126 /*! 00127 * \brief Computes a random number between min and max 00128 * 00129 * \param [IN] min range minimum value 00130 * \param [IN] max range maximum value 00131 * \retval random random value in range min..max 00132 */ 00133 int32_t randr( int32_t min, int32_t max ) 00134 { 00135 return ( int32_t )rand( ) % ( max - min + 1 ) + min; 00136 } 00137 00138 ////////////////////////////////////////////////// 00139 // APPLICATION CALLBACKS 00140 ////////////////////////////////////////////////// 00141 00142 // provide application router ID (8 bytes, LSBF) 00143 void os_getArtEui( uint8_t *buf ) 00144 { 00145 memcpy( buf, AppEui, 8 ); 00146 debug("os_getArtEui enter"); 00147 for(int i=0;i<8;i++) 00148 debug(" %02X",buf[i]); 00149 debug("\r\n"); 00150 } 00151 00152 // provide device ID (8 bytes, LSBF) 00153 void os_getDevEui( uint8_t *buf ) 00154 { 00155 memcpy( buf, DevEui, 8 ); 00156 debug("os_getDevEui enter"); 00157 for(int i=0;i<8;i++) 00158 debug(" %02X",buf[i]); 00159 debug("\r\n"); 00160 } 00161 00162 // provide device key (16 bytes) 00163 void os_getDevKey( uint8_t *buf ) 00164 { 00165 memcpy( buf, DevKey, 16 ); 00166 debug("os_getDevKey enter"); 00167 for(int i=0;i<16;i++) 00168 debug(" %02X",buf[i]); 00169 debug("\r\n"); 00170 } 00171 00172 ////////////////////////////////////////////////// 00173 // MAIN - INITIALIZATION AND STARTUP 00174 ////////////////////////////////////////////////// 00175 00176 static void onRxLed( osjob_t* j ) 00177 { 00178 led2 = 0; 00179 debug_val("LED2 = ", 0 ); 00180 } 00181 00182 static void onTxLed( osjob_t* j ) 00183 { 00184 led1 = 0; 00185 debug_val("LED1 = ", 0 ); 00186 } 00187 00188 static void prepareTxFrame( void ) 00189 { 00190 LMIC.frame[0] = AppLedStateOn; 00191 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 ) 00192 LMIC.frame[1] = LMIC.seqnoDn >> 8; 00193 LMIC.frame[2] = LMIC.seqnoDn; 00194 LMIC.frame[3] = LMIC.rssi >> 8; 00195 LMIC.frame[4] = LMIC.rssi; 00196 LMIC.frame[5] = LMIC.snr; 00197 #endif 00198 } 00199 00200 void processRxFrame( void ) 00201 { 00202 debug("processRxFrame enter\r\n"); 00203 switch( LMIC.frame[LMIC.dataBeg - 1] ) // Check Rx port number 00204 { 00205 case 1: // The application LED can be controlled on port 1 or 2 00206 case 2: 00207 if( LMIC.dataLen == 1 ) 00208 { 00209 AppLedStateOn = LMIC.frame[LMIC.dataBeg] & 0x01; 00210 debug_val( "LED3 = ", AppLedStateOn ); 00211 } 00212 break; 00213 default: 00214 break; 00215 } 00216 } 00217 00218 static void onSendFrame( osjob_t* j ) 00219 { 00220 debug("onSendFrame enter\r\n"); 00221 prepareTxFrame( ); 00222 LMIC_setTxData2( LORAWAN_APP_PORT, LMIC.frame, LORAWAN_APP_DATA_SIZE, LORAWAN_CONFIRMED_MSG_ON ); 00223 00224 // Blink Tx LED 00225 led1 = 1; 00226 debug_val( "LED1 = ", 1 ); 00227 os_setTimedCallback( &txLedJob, os_getTime( ) + ms2osticks( 25 ), onTxLed ); 00228 } 00229 00230 #if 1 00231 // Initialization job 00232 static void onInit( osjob_t* j ) 00233 { 00234 debug("onInit enter\r\n"); 00235 // reset MAC state 00236 LMIC_reset( ); 00237 LMIC_setAdrMode( LORAWAN_ADR_ON ); 00238 #if defined(CFG_eu868) 00239 LMIC_setDrTxpow( DR_SF12, 14 ); 00240 #elif defined(CFG_us915) 00241 LMIC_setDrTxpow( DR_SF10, 14 ); 00242 #endif 00243 00244 // start joining 00245 #if( OVER_THE_AIR_ACTIVATION != 0 ) 00246 LMIC_startJoining( ); 00247 #else 00248 LMIC_setSession( LORAWAN_NET_ID, LORAWAN_DEV_ADDR, NwkSKey, ArtSKey ); 00249 onSendFrame( NULL ); 00250 #endif 00251 // init done - onEvent( ) callback will be invoked... 00252 } 00253 #endif 00254 00255 #if 0 00256 // counter static 00257 int cnt = 0; 00258 // log text to USART and toggle LED 00259 static void onInit (osjob_t* job) 00260 { 00261 // say hello 00262 debug_str("Hello World!\r\n"); 00263 // log counter 00264 debug_val("cnt = ", cnt); 00265 // toggle LED 00266 if((cnt & 1) == 1) 00267 { 00268 led1 = 1; 00269 } 00270 else 00271 { 00272 led1 = 0; 00273 } 00274 debug_led(cnt & 1); 00275 cnt++; 00276 // reschedule job every second 00277 os_setTimedCallback(job, os_getTime()+sec2osticks(1), onInit); 00278 } 00279 #endif 00280 00281 int main( void ) 00282 { 00283 osjob_t initjob; 00284 00285 led1=1; 00286 led2=1; 00287 pc.baud(115200); 00288 printf( "\r\nLoRaWan Demo Application TJM V %d.%d\r\n",MAJOR, MINOR ); 00289 // initialize runtime env 00290 os_init( ); 00291 // setup initial job 00292 os_setCallback( &initjob, onInit ); 00293 // execute scheduled jobs and events 00294 os_runloop( ); 00295 // (not reached) 00296 } 00297 00298 ////////////////////////////////////////////////// 00299 // LMIC EVENT CALLBACK 00300 ////////////////////////////////////////////////// 00301 void onEvent( ev_t ev ) 00302 { 00303 debug("onEvent enter %d\r\n",ev); 00304 bool txOn = false; 00305 debug_event( ev ); 00306 00307 switch( ev ) 00308 { 00309 // network joined, session established 00310 case EV_JOINED: 00311 debug_val( "Net ID = ", LMIC.netid ); 00312 txOn = true; 00313 break; 00314 // scheduled data sent (optionally data received) 00315 case EV_TXCOMPLETE: 00316 debug_val( "Datarate = ", LMIC.datarate ); 00317 // Check if we have a downlink on either Rx1 or Rx2 windows 00318 if( ( LMIC.txrxFlags & ( TXRX_DNW1 | TXRX_DNW2 ) ) != 0 ) 00319 { 00320 led2 = 1; 00321 debug_val( "LED2 = ", 1 ); 00322 os_setTimedCallback( &rxLedJob, os_getTime( ) + ms2osticks( 25 ), onRxLed ); 00323 00324 if( LMIC.dataLen != 0 ) 00325 { // data received in rx slot after tx 00326 debug_buf( LMIC.frame + LMIC.dataBeg, LMIC.dataLen ); 00327 processRxFrame( ); 00328 } 00329 } 00330 txOn = true; 00331 break; 00332 default: 00333 break; 00334 } 00335 if( txOn == true ) 00336 { 00337 //Sends frame every APP_TX_DUTYCYCLE +/- APP_TX_DUTYCYCLE_RND random time (if not duty cycle limited) 00338 os_setTimedCallback( &sendFrameJob, 00339 os_getTime( ) + ms2osticks( APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ) ), 00340 onSendFrame ); 00341 00342 ////Sends frame as soon as possible (duty cylce limitations) 00343 //onSendFrame( NULL ); 00344 } 00345 }
Generated on Thu Jul 14 2022 11:31:09 by 1.7.2