added other files

Dependencies:   lib_gps lib_mpl3115a2 lmic_MOTE_L152RC mbed

Fork of lmic_NAmote_GPS_tjm by Timothy Mulrooney

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)2013 Semtech
00008 
00009 Description: MBED 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 #include "lmic.h"
00017 #include "mpl3115a2.h"
00018 #include "gps.h"
00019 #include "debug.h"
00020 
00021 #define LORA_IT
00022 //#define SENET_F
00023 //#define SMTC
00024 
00025 typedef enum {
00026     MOTE_NONE = 0,
00027     MOTE_V2,
00028     MOTE_V3
00029 } mote_version_e;
00030 mote_version_e mote_version = MOTE_NONE;
00031 
00032 //DigitalOut pc_7(PTC1); /* *** TODO *** */
00033 //DigitalIn pc_1(PTC1); /* *** TODO *** */
00034 
00035 
00036 /* ****************************************** */
00037 /* ***** Basic App and Network Parameters *** */
00038 /* ****************************************** */
00039 // Hybrid Mode must be defined in lmic.h      //
00040 // DevEUI and Keys defined by Activation type //
00041 #define APP_DATA_SIZE               11
00042 #define APP_ACK                     0
00043 #define MS_DELAY_NEXT_TX               400
00044 #ifdef SMTC
00045 #define OVER_THE_AIR_ACTIVATION     1 //0
00046 #else
00047 #define OVER_THE_AIR_ACTIVATION     1
00048 #endif /* SMTC */
00049 
00050 /* ***************************************** */
00051 
00052 #define LED_RED         PTA1
00053 #define LED_YEL         PTA2
00054 
00055 static DigitalOut led1(LED_RED);
00056 static DigitalOut led2(LED_YEL);
00057 
00058 /*  gps(tx, rx, en); */
00059 //GPS gps(PTC1, PTC1, PTC1); /* *** TODO *** */
00060 
00061 I2C i2c(PTB3,PTB2);
00062 //DigitalIn i2c_int_pin(PTC1);
00063 //MPL3115A2 mpl3115a2(i2c, i2c_int_pin); /* *** TODO *** */
00064 AnalogIn *bat;
00065 #define LOW_BAT_THRESHOLD   3.45
00066 
00067 //////////////////////////////////////////////////
00068 // CONFIGURATION (FOR APPLICATION CALLBACKS BELOW)
00069 //////////////////////////////////////////////////
00070 #ifdef LORA_IT
00071 // application router ID (LSBF)
00072 //static const u1_t APPEUI[8]  = { 0x01, 0x00, 0x01, 0x00, 0x00, 0x0c, 0x25, 0x00  };
00073 static const u1_t reverse_APPEUI[8]  = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
00074 
00075 // unique device ID (LSBF)
00076 //static const u1_t DEVEUI[8]  = { 0x0f, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x25, 0x00 };
00077 static const u1_t reverse_DEVEUI[8]  = { 0x02, 0x00, 0x00, 0x00, 0x00, 0xee, 0xff, 0xc0 };
00078 
00079 // device-specific AES key (derived from device EUI)
00080 static const u1_t DEVKEY[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, };
00081                              //    E4   -72   -71   -C5   -F5   -30   -A9   -9F   -CF   -C4   -0E   -AB   -EA   -D7   -19   -42
00082 #endif /* LORA_IT */
00083 
00084 #ifdef SENET_F
00085 // application router ID (LSBF)
00086 //static const u1_t APPEUI[8]  = { 0x01, 0x00, 0x01, 0x00, 0x00, 0x0c, 0x25, 0x00  };
00087 static const u1_t reverse_APPEUI[8]  = { 0x00, 0x25, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x01 };
00088 
00089 // unique device ID (LSBF)
00090 //static const u1_t DEVEUI[8]  = { 0x0f, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x25, 0x00 };
00091 static const u1_t reverse_DEVEUI[8]  = { 0x00, 0x25, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x0F };
00092 
00093 // device-specific AES key (derived from device EUI)
00094 static const u1_t DEVKEY[16] = { 0xe4, 0x72, 0x71, 0xc5, 0xf5, 0x30, 0xa9, 0x9f, 0xcf, 0xc4, 0x0e, 0xab, 0xea, 0xd7, 0x19, 0x42, };
00095                              //    E4   -72   -71   -C5   -F5   -30   -A9   -9F   -CF   -C4   -0E   -AB   -EA   -D7   -19   -42
00096 #endif /* SENET_F */
00097 
00098 #ifdef SMTC
00099 // Semtech Activation (v1.x server)
00100 // application router ID (LSBF)
00101 static const u1_t reverse_APPEUI[8]  = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
00102     //AA-AA-AA-AA-FF-FF-FF-FF
00103 //static const u1_t APPEUI[8]  = { 0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xaa };   
00104 //static const u1_t reverse_APPEUI[8]  = { 0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff };  
00105 
00106 // unique device ID (LSBF)
00107 //static const u1_t DEVEUI[8]  = { 0x21, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x25, 0x00 };
00108 static const u1_t reverse_DEVEUI[8]  = { 0x00, 0x25, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x20 };
00109 //static const u1_t DEVEUI[8]  = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
00110 //static const u1_t reverse_DEVEUI[8]  = { 0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01 };
00111 
00112 // device-specific AES key (derived from device EUI)
00113 static const u1_t DEVKEY[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff  };
00114 //static const u1_t DEVKEY[16] = { 0xab, 0x89, 0xef, 0xcd, 0x23, 0x01, 0x67, 0x45, 0x54, 0x76, 0x10, 0x32, 0xdc, 0xfe, 0x98, 0xba };
00115 
00116 /*static uint8_t NwkSKey[] = 
00117 { 
00118     0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
00119     0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
00120 };
00121 
00122 static uint8_t ArtSKey[] = 
00123 { 
00124     0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
00125     0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
00126 };*/
00127 
00128 #endif /* SMTC */
00129 
00130 //////////////////////////////////////////////////
00131 // APPLICATION CALLBACKS
00132 //////////////////////////////////////////////////
00133 
00134 // provide application router ID (8 bytes, LSBF)
00135 void os_getArtEui (u1_t* buf) 
00136 {
00137     debug("os_getArtEui Enter\r\n");
00138     for(int i=0; i < 8; i++)
00139         debug("%02X ",reverse_APPEUI[i]);
00140     debug("\r\n");
00141     //memcpy(buf, APPEUI, 8);
00142     LMIC_reverse_memcpy(buf, reverse_APPEUI, 8);
00143 }
00144 
00145 // provide device ID (8 bytes, LSBF)
00146 void os_getDevEui (u1_t* buf) {
00147     debug("os_getDevEui Enter\r\n");
00148     for(int i=0; i < 8; i++)
00149         debug("%02X ",reverse_DEVEUI[i]);
00150     debug("\r\n");
00151     //memcpy(buf, DEVEUI, 8);
00152     LMIC_reverse_memcpy(buf, reverse_DEVEUI, 8);
00153 }
00154 
00155 // provide device key (16 bytes)
00156 void os_getDevKey (u1_t* buf) {
00157     debug("os_getDevKey Enter\r\n");
00158     for(int i=0; i < 16; i++)
00159         debug("%02X ",DEVKEY[i]);
00160     debug("\r\n");
00161     for(int i=0; i < 16; i++)
00162         debug("%c ",DEVKEY[i]);
00163     debug("\r\n");
00164    memcpy(buf, DEVKEY, 16);
00165 }
00166 
00167 //////////////////////////////////////////////////
00168 // MAIN - INITIALIZATION AND STARTUP
00169 //////////////////////////////////////////////////
00170 void get_mote_version()
00171 {
00172 //    char first;
00173       
00174 //    pc_7 = 1;
00175 //    first = pc_1;
00176 //    pc_7 = 0;
00177 //    if (first && !pc_1) {
00178 //        mote_version = MOTE_V2;
00179 //        printf("v2\r\n");
00180 //        bat = new AnalogIn(PA_0);
00181 //    } else {
00182 //        mote_version = MOTE_V3;
00183 //        printf("v3\r\n");
00184 //        bat = new AnalogIn(PA_1);
00185 //    }
00186 }
00187 
00188 #if 1
00189 // initial job
00190 static void initfunc (osjob_t* j) {
00191     debug_str("B: INITFUNC\n");
00192     // reset MAC state
00193     LMIC_reset();
00194     // start joining
00195 #if( OVER_THE_AIR_ACTIVATION != 0 )
00196     LMIC_startJoining();
00197 #else
00198     devaddr_t *serial_id = (devaddr_t *) 0x1FF800d0;        // cat3 device stm32l152rc
00199     LMIC_setSession( 0, *serial_id, NwkSKey, ArtSKey );
00200     debug_val("SN = ", *serial_id);
00201 #endif
00202      //init done - onEvent() callback will be invoked...
00203 
00204     //DEBUG_STR("E: INITFUNC");
00205     get_mote_version();
00206 //    if (mote_version == MOTE_V3)
00207 //        gps.en_invert = false;
00208 //    else
00209 //        gps.en_invert = true;
00210         
00211 //    gps.init();
00212 //    gps.enable(1);
00213     //gps.verbose = 1;
00214 
00215 //    mpl3115a2.init();
00216 }
00217 #endif
00218 
00219 #if 0
00220 // counter static 
00221 int cnt = 0; 
00222 // log text to USART and toggle LED
00223 static void initfunc (osjob_t* job) 
00224 { 
00225     // say hello 
00226     debug_str("Hello World!\r\n");
00227     // log counter 
00228     debug_val("cnt = ", cnt); 
00229     // toggle LED 
00230     debug_led(++cnt & 1); 
00231     // reschedule job every second 
00232     os_setTimedCallback(job, os_getTime()+sec2osticks(1), initfunc);
00233 }
00234 #endif
00235 
00236 
00237 int main(void)
00238 {
00239     osjob_t initjob;
00240  
00241     // initialize runtime env
00242     debug_init();
00243     os_init();
00244     // setup initial job
00245     os_setCallback(&initjob, initfunc);
00246     // execute scheduled jobs and events
00247     os_runloop();
00248     // (not reached)
00249 }
00250 
00251 //////////////////////////////////////////////////
00252 // LMIC EVENT CALLBACK
00253 //////////////////////////////////////////////////
00254 osjob_t rxLedJob;
00255 osjob_t txLedJob;
00256 osjob_t sendFrameJob;
00257 
00258 static void onRxLed (osjob_t* j) {
00259     debug_val("LED2 = ", 1 );
00260     led2 = 1;
00261 }
00262 
00263 static void onTxLed (osjob_t* j) {
00264     debug_val("LED1 = ", 1 );
00265     led1 = 1;
00266 }
00267 
00268 static void
00269 restore_hsi()
00270 {
00271 //    RCC_OscInitTypeDef osc_init;
00272     /* if HSI was shut off in deep sleep (needed for AnalogIn) */
00273 //    HAL_RCC_GetOscConfig(&osc_init);
00274 //    if (osc_init.HSIState != RCC_HSI_ON) {
00275 //        // Enable the HSI (to clock the ADC)
00276 //        osc_init.OscillatorType = RCC_OSCILLATORTYPE_HSI;
00277 //        osc_init.HSIState       = RCC_HSI_ON;
00278 //        osc_init.PLL.PLLState   = RCC_PLL_NONE;
00279 //        HAL_RCC_OscConfig(&osc_init);    
00280 //    }    
00281 }
00282 
00283 static bool AppLedStateOn = false;
00284 
00285 #define AIN_VREF        3.3     // stm32 internal refernce
00286 #define AIN_VBAT_DIV    2       // resistor divider
00287 static void PrepareDataFrame( void )
00288 {
00289     uint16_t altitudeGps;
00290     
00291     restore_hsi();
00292 
00293 //    gps.service();
00294     //printf("lat:%f  long:%f\r\n", gps.Latitude, gps.Longitude);
00295 //    mpl3115a2.ReadTemperature();
00296 
00297     // immediately prepare next transmission
00298     //LMIC.frame[0] = LMIC.rxq.snr;
00299     LMIC.frame[0] = AppLedStateOn; // (bit 0 == 1) => LED on
00300 //    LMIC.frame[1] = (int)mpl3115a2.Temperature; // Signed degrees Celcius in half degree units. So,  +/-63 C
00301     LMIC.frame[2] = (bat->read_u16() >> 8) + (bat->read_u16() >> 9) ; // per LoRaMAC spec; 0=Charging; 1...254 = level, 255 = N/A
00302     
00303 //    LMIC.frame[3] = ( gps.LatitudeBinary >> 16 ) & 0xFF;
00304 //    LMIC.frame[4] = ( gps.LatitudeBinary >> 8 ) & 0xFF;
00305 //    LMIC.frame[5] = gps.LatitudeBinary & 0xFF;
00306 //    LMIC.frame[6] = ( gps.LongitudeBinary >> 16 ) & 0xFF;
00307 //    LMIC.frame[7] = ( gps.LongitudeBinary >> 8 ) & 0xFF;
00308 //    LMIC.frame[8] = gps.LongitudeBinary & 0xFF;
00309 
00310 //    altitudeGps = atoi(gps.NmeaGpsData.NmeaAltitude);
00311     //printf("alt:%d\r\n", altitudeGps);
00312     LMIC.frame[9] = ( altitudeGps >> 8 ) & 0xFF;
00313     LMIC.frame[10] = altitudeGps & 0xFF;
00314     
00315 
00316     //printf("bat:%.2f\r\n", volts);
00317 #ifndef CHNL_HYBRID
00318     float volts = bat->read()*AIN_VREF*AIN_VBAT_DIV;
00319     if (volts < LOW_BAT_THRESHOLD)
00320         LMIC.txpow_limit = 20;
00321     else
00322         LMIC.txpow_limit = 30;
00323 #endif /* !CHNL_HYBRID */  
00324 }
00325 
00326 static void onSendFrame (osjob_t* j)
00327 {
00328     if (LMIC.opmode & OP_TXRXPEND)
00329         return;
00330         
00331     PrepareDataFrame( );
00332     // schedule transmission (port 1, data[], datalen 1, ACK requested)
00333     // (will be sent as soon as duty cycle permits)
00334              
00335     LMIC_setTxData2(5, LMIC.frame, APP_DATA_SIZE, APP_ACK);
00336 }
00337 
00338 void onEvent (ev_t ev) {
00339 
00340     debug_event(ev);
00341 
00342 //    gps.service();
00343 
00344     switch(ev) 
00345     {
00346     // network joined, session established
00347     case EV_JOINED:
00348         debug_val("Net ID = ", LMIC.netid);
00349         goto tx;
00350     // scheduled data sent (optionally data received)
00351     case EV_TXCOMPLETE:
00352         if(LMIC.dataLen) 
00353         { // data received in rx slot after tx
00354             debug_buf(LMIC.frame+LMIC.dataBeg, LMIC.dataLen);
00355             if(LMIC.dataLen == 1) { // set LED state if exactly one byte is received
00356                 AppLedStateOn = LMIC.frame[LMIC.dataBeg] & 0x01;
00357                 debug_val("LED3 = ", AppLedStateOn ? 0 : 1 );
00358             }
00359         }
00360         if((LMIC.txrxFlags & (TXRX_DNW1|TXRX_DNW2) )!= 0 )
00361         {
00362             debug_val("LED2 = ", 0 );
00363             led2 = 0;
00364             os_setTimedCallback( &rxLedJob, os_getTime() + ms2osticks(15), onRxLed );
00365         }
00366 tx:
00367         os_setTimedCallback( &sendFrameJob, os_getTime() + ms2osticks(MS_DELAY_NEXT_TX), onSendFrame ); // Change the Tx periodicity
00368         //onSendFrame(NULL);
00369         
00370         // Blink Tx LED
00371         debug_val("LED1 = ", 0 );
00372         led1 = 0;
00373         
00374         os_setTimedCallback( &txLedJob, os_getTime() + ms2osticks(25), onTxLed );
00375         break;
00376     default:
00377     debug("event: %d/n",ev);
00378         break;
00379     }
00380 }