Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: STM32F103c8t6-LoRaWAN-lmic SX1276Lib mbed-STM32F103C8T6 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 "stm32f103c8t6.h" 00016 #include "mbed.h" 00017 00018 #include "lmic.h" 00019 #include "debug.h" 00020 00021 /*! 00022 * When set to 1 the application uses the Over-the-Air activation procedure 00023 * When set to 0 the application uses the Personalization activation procedure 00024 */ 00025 00026 #define SINGLE_CHANNEL_GATEWAY 1 00027 #define OVER_THE_AIR_ACTIVATION 1 00028 00029 #if( OVER_THE_AIR_ACTIVATION == 0 ) 00030 00031 /*! 00032 * Defines the network ID when using personalization activation procedure 00033 */ 00034 #define LORAWAN_NET_ID ( uint32_t )0x00000000 00035 00036 /*! 00037 * Defines the device address when using personalization activation procedure 00038 */ 00039 #define LORAWAN_DEV_ADDR ( uint32_t )0x12345679 00040 00041 #endif 00042 00043 /*! 00044 * Defines the application data transmission duty cycle 00045 */ 00046 #define APP_TX_DUTYCYCLE 60000 // 5 [s] value in ms 1min 00047 #define APP_TX_DUTYCYCLE_RND 50000 // 1 [s] value in ms 00048 00049 /*! 00050 * LoRaWAN Adaptative Data Rate 00051 */ 00052 #define LORAWAN_ADR_ON 1 00053 //#define LORAWAN_ADR_ON 1 00054 00055 /*! 00056 * LoRaWAN confirmed messages 00057 */ 00058 //#define LORAWAN_CONFIRMED_MSG_ON 1 00059 #define LORAWAN_CONFIRMED_MSG_ON 1 00060 /*! 00061 * LoRaWAN application port 00062 */ 00063 #define LORAWAN_APP_PORT 15 00064 00065 /*! 00066 * User application data buffer size 00067 */ 00068 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 ) 00069 #define LORAWAN_APP_DATA_SIZE 6 00070 00071 #else 00072 #define LORAWAN_APP_DATA_SIZE 1 00073 00074 #endif 00075 00076 ////////////////////////////////////////////////// 00077 // CONFIGURATION (FOR APPLICATION CALLBACKS BELOW) 00078 ////////////////////////////////////////////////// 00079 00080 //fe dc ba 98 76 54 32 10 00081 // application router ID (LSBF) 00082 static const uint8_t AppEui[8] = 00083 { 00084 0xb8, 0x27, 0xeb, 0xff, 0xff, 0xef, 0x00, 0x62 00085 }; 00086 00087 // unique device ID (LSBF) 00088 static const u1_t DevEui[8] = 00089 { 00090 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 00091 }; 00092 00093 // device-specific AES key (derived from device EUI) 00094 static const uint8_t DevKey[16] = 00095 { 00096 00097 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00098 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 00099 }; 00100 00101 #if( OVER_THE_AIR_ACTIVATION == 0 ) 00102 // network session key 00103 static uint8_t NwkSKey[] = 00104 { 00105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 00107 }; 00108 00109 // application session key 00110 static uint8_t ArtSKey[] = 00111 { 00112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 00114 }; 00115 00116 #endif 00117 00118 // LEDs and Frame jobs 00119 osjob_t rxLedJob; 00120 osjob_t txLedJob; 00121 osjob_t sendFrameJob; 00122 DigitalOut myled(LED1); 00123 00124 // LED state 00125 static bool AppLedStateOn = true; 00126 00127 ////////////////////////////////////////////////// 00128 // Utility functions 00129 ////////////////////////////////////////////////// 00130 /*! 00131 * \brief Computes a random number between min and max 00132 * 00133 * \param [IN] min range minimum value 00134 * \param [IN] max range maximum value 00135 * \retval random random value in range min..max 00136 */ 00137 int32_t randr( int32_t min, int32_t max ) 00138 { 00139 return ( int32_t )rand( ) % ( max - min + 1 ) + min; 00140 } 00141 00142 ////////////////////////////////////////////////// 00143 // APPLICATION CALLBACKS 00144 ////////////////////////////////////////////////// 00145 00146 // provide application router ID (8 bytes, LSBF) 00147 void os_getArtEui( uint8_t *buf ) 00148 { 00149 memcpy( buf, AppEui, 8 ); 00150 } 00151 00152 // provide device ID (8 bytes, LSBF) 00153 void os_getDevEui( uint8_t *buf ) 00154 { 00155 memcpy( buf, DevEui, 8 ); 00156 } 00157 00158 // provide device key (16 bytes) 00159 void os_getDevKey( uint8_t *buf ) 00160 { 00161 memcpy( buf, DevKey, 16 ); 00162 } 00163 00164 ////////////////////////////////////////////////// 00165 // MAIN - INITIALIZATION AND STARTUP 00166 ////////////////////////////////////////////////// 00167 00168 static void onRxLed( osjob_t* j ) 00169 { 00170 debug_val("LED2 = ", 0 ); 00171 } 00172 00173 static void onTxLed( osjob_t* j ) 00174 { 00175 debug_val("LED1 = ", 0 ); 00176 } 00177 00178 static void prepareTxFrame( void ) 00179 { 00180 LMIC.frame[0] = AppLedStateOn; 00181 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 ) 00182 LMIC.frame[1] = LMIC.seqnoDn >> 8; 00183 LMIC.frame[2] = LMIC.seqnoDn; 00184 LMIC.frame[3] = LMIC.rssi >> 8; 00185 LMIC.frame[4] = LMIC.rssi; 00186 LMIC.frame[5] = LMIC.snr; 00187 #endif 00188 } 00189 00190 void processRxFrame( void ) 00191 { 00192 switch( LMIC.frame[LMIC.dataBeg - 1] ) // Check Rx port number 00193 { 00194 case 1: // The application LED can be controlled on port 1 or 2 00195 case 2: 00196 if( LMIC.dataLen == 1 ) 00197 { 00198 AppLedStateOn = LMIC.frame[LMIC.dataBeg] & 0x01; 00199 debug_val( "LED3 = ", AppLedStateOn ); 00200 } 00201 break; 00202 default: 00203 break; 00204 } 00205 } 00206 00207 static void onSendFrame( osjob_t* j ) 00208 { 00209 prepareTxFrame( ); 00210 LMIC_setTxData2( LORAWAN_APP_PORT, LMIC.frame, LORAWAN_APP_DATA_SIZE, LORAWAN_CONFIRMED_MSG_ON ); 00211 00212 // Blink Tx LED 00213 debug_val( "LED1 = ", 1 ); 00214 os_setTimedCallback( &txLedJob, os_getTime( ) + ms2osticks( 25 ), onTxLed ); 00215 } 00216 00217 // Initialization job 00218 static void onInit( osjob_t* j ) 00219 { 00220 // reset MAC state 00221 LMIC_reset( ); 00222 //LMIC_setAdrMode( LORAWAN_ADR_ON ); 00223 LMIC_setAdrMode(0); 00224 LMIC_setLinkCheckMode(0); 00225 LMIC_disableTracking (); 00226 LMIC_stopPingable(); 00227 // LMIC_setDrTxpow(DR_SF7,14); 00228 00229 #if defined(CFG_eu868) 00230 //LMIC_setDrTxpow( DR_SF12, 14 ); 00231 LMIC_setDrTxpow(DR_SF12,14); 00232 #elif defined(CFG_us915) 00233 LMIC_setDrTxpow( DR_SF10, 14 ); 00234 #endif 00235 00236 // start joining 00237 #if( OVER_THE_AIR_ACTIVATION != 0 ) 00238 LMIC_startJoining( ); 00239 #else 00240 LMIC_setSession( LORAWAN_NET_ID, LORAWAN_DEV_ADDR, NwkSKey, ArtSKey ); 00241 onSendFrame( NULL ); 00242 #endif 00243 // init done - onEvent( ) callback will be invoked... 00244 } 00245 00246 int main( void ) 00247 { 00248 00249 #ifdef SINGLE_CHANNEL_GATEWAY 00250 //MAX_CHANNELS = 1; 00251 //MAX_BANDS = 1; 00252 //LIMIT_CHANNELS = 1; 00253 for (int i=1; i<16; i++) 00254 LMIC_disableChannel(i); 00255 #endif 00256 //confSysClock(); 00257 //DigitalOut myled(LED1); 00258 myled = 0; // turn the LED on 00259 00260 osjob_t initjob; 00261 // initialize runtime env 00262 os_init( ); 00263 // setup initial job 00264 os_setCallback( &initjob, onInit ); 00265 // execute scheduled jobs and events 00266 os_runloop( ); 00267 // (not reached) 00268 } 00269 00270 ////////////////////////////////////////////////// 00271 // LMIC EVENT CALLBACK 00272 ////////////////////////////////////////////////// 00273 void onEvent( ev_t ev ) 00274 { 00275 bool txOn = false; 00276 debug_event( ev ); 00277 00278 switch( ev ) 00279 { 00280 // network joined, session established 00281 case EV_JOINED: 00282 debug_val( "Net ID = ", LMIC.netid ); 00283 txOn = true; 00284 break; 00285 // scheduled data sent (optionally data received) 00286 case EV_TXCOMPLETE: 00287 debug_val( "Datarate = ", LMIC.datarate ); 00288 // Check if we have a downlink on either Rx1 or Rx2 windows 00289 if( ( LMIC.txrxFlags & ( TXRX_DNW1 | TXRX_DNW2 ) ) != 0 ) 00290 { 00291 debug_val( "LED2 = ", 1 ); 00292 os_setTimedCallback( &rxLedJob, os_getTime( ) + ms2osticks( 25 ), onRxLed ); 00293 00294 if( LMIC.dataLen != 0 ) 00295 { // data received in rx slot after tx 00296 debug_buf( LMIC.frame + LMIC.dataBeg, LMIC.dataLen ); 00297 processRxFrame( ); 00298 } 00299 } 00300 txOn = true; 00301 break; 00302 default: 00303 break; 00304 } 00305 myled = 1; // turn the LED off 00306 if( txOn == true ) 00307 { 00308 //Sends frame every APP_TX_DUTYCYCLE +/- APP_TX_DUTYCYCLE_RND random time (if not duty cycle limited) 00309 os_setTimedCallback( &sendFrameJob, 00310 os_getTime( ) + ms2osticks( ((APP_TX_DUTYCYCLE) + randr( 10000, 60000 ))*2 ), 00311 onSendFrame ); 00312 myled = !myled; // turn the LED on 00313 ////Sends frame as soon as possible (duty cylce limitations) 00314 //onSendFrame( NULL ); 00315 } 00316 }
Generated on Tue Jul 12 2022 22:56:04 by
1.7.2
