hello world

Dependencies:   lib_gps lib_mpl3115a2 lmic_MOTE_L152RC mbed

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