added other files

Dependencies:   lib_gps lib_mpl3115a2 lmic_MOTE_L152RC mbed

Fork of lmic_NAmote_GPS_tjm by Timothy Mulrooney

main.cpp

Committer:
tmulrooney
Date:
2016-02-09
Revision:
8:1069ed1d4464
Parent:
6:0b2b2d196ddd
Child:
9:f4d52e9625f7

File content as of revision 8:1069ed1d4464:

/*
 / _____)             _              | |
( (____  _____ ____ _| |_ _____  ____| |__
 \____ \| ___ |    (_   _) ___ |/ ___)  _ \
 _____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
    (C)2013 Semtech

Description: MBED example application

License: Revised BSD License, see LICENSE.TXT file include in the project

Maintainer: Miguel Luis and Gregory Cristian
*/
#include "mbed.h"
#include "lmic.h"
#include "mpl3115a2.h"
#include "gps.h"
#include "debug.h"

#define SENET_F
//#define SMTC

typedef enum {
    MOTE_NONE = 0,
    MOTE_V2,
    MOTE_V3
} mote_version_e;
mote_version_e mote_version = MOTE_NONE;

//DigitalOut pc_7(PTC1); /* *** TODO *** */
//DigitalIn pc_1(PTC1); /* *** TODO *** */


/* ****************************************** */
/* ***** Basic App and Network Parameters *** */
/* ****************************************** */
// Hybrid Mode must be defined in lmic.h      //
// DevEUI and Keys defined by Activation type //
#define APP_DATA_SIZE               11
#define APP_ACK                     0
#define MS_DELAY_NEXT_TX               400
#ifdef SMTC
#define OVER_THE_AIR_ACTIVATION     1 //0
#else
#define OVER_THE_AIR_ACTIVATION     1
#endif /* SMTC */

/* ***************************************** */

#define LED_RED         PTA1
#define LED_YEL         PTA2

static DigitalOut led1(LED_RED);
static DigitalOut led2(LED_YEL);

/*  gps(tx, rx, en); */
//GPS gps(PTC1, PTC1, PTC1); /* *** TODO *** */

I2C i2c(PTB3,PTB2);
//DigitalIn i2c_int_pin(PTC1);
//MPL3115A2 mpl3115a2(i2c, i2c_int_pin); /* *** TODO *** */
AnalogIn *bat;
#define LOW_BAT_THRESHOLD   3.45

//////////////////////////////////////////////////
// CONFIGURATION (FOR APPLICATION CALLBACKS BELOW)
//////////////////////////////////////////////////
#ifdef SENET_F
// application router ID (LSBF)
//static const u1_t APPEUI[8]  = { 0x01, 0x00, 0x01, 0x00, 0x00, 0x0c, 0x25, 0x00  };
static const u1_t reverse_APPEUI[8]  = { 0x00, 0x25, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x01 };

// unique device ID (LSBF)
//static const u1_t DEVEUI[8]  = { 0x0f, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x25, 0x00 };
static const u1_t reverse_DEVEUI[8]  = { 0x00, 0x25, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x0F };

// device-specific AES key (derived from device EUI)
static const u1_t DEVKEY[16] = { 0xe4, 0x72, 0x71, 0xc5, 0xf5, 0x30, 0xa9, 0x9f, 0xcf, 0xc4, 0x0e, 0xab, 0xea, 0xd7, 0x19, 0x42, };
                             //    E4   -72   -71   -C5   -F5   -30   -A9   -9F   -CF   -C4   -0E   -AB   -EA   -D7   -19   -42
#endif /* SENET_F */

#ifdef SMTC
// Semtech Activation (v1.x server)
// application router ID (LSBF)
static const u1_t reverse_APPEUI[8]  = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    //AA-AA-AA-AA-FF-FF-FF-FF
//static const u1_t APPEUI[8]  = { 0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xaa };   
//static const u1_t reverse_APPEUI[8]  = { 0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff };  

// unique device ID (LSBF)
//static const u1_t DEVEUI[8]  = { 0x21, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x25, 0x00 };
static const u1_t reverse_DEVEUI[8]  = { 0x00, 0x25, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x20 };
//static const u1_t DEVEUI[8]  = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
//static const u1_t reverse_DEVEUI[8]  = { 0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01 };

// device-specific AES key (derived from device EUI)
static const u1_t DEVKEY[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff  };
//static const u1_t DEVKEY[16] = { 0xab, 0x89, 0xef, 0xcd, 0x23, 0x01, 0x67, 0x45, 0x54, 0x76, 0x10, 0x32, 0xdc, 0xfe, 0x98, 0xba };

/*static uint8_t NwkSKey[] = 
{ 
    0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
    0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
};

static uint8_t ArtSKey[] = 
{ 
    0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
    0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
};*/

#endif /* SMTC */

//////////////////////////////////////////////////
// APPLICATION CALLBACKS
//////////////////////////////////////////////////

// provide application router ID (8 bytes, LSBF)
void os_getArtEui (u1_t* buf) 
{
    debug("os_getArtEui Enter\r\n");
    for(int i=0; i < 8; i++)
        debug("%02X ",reverse_APPEUI[i]);
    debug("\r\n");
    //memcpy(buf, APPEUI, 8);
    LMIC_reverse_memcpy(buf, reverse_APPEUI, 8);
}

// provide device ID (8 bytes, LSBF)
void os_getDevEui (u1_t* buf) {
    debug("os_getDevEui Enter\r\n");
    for(int i=0; i < 8; i++)
        debug("%02X ",reverse_DEVEUI[i]);
    debug("\r\n");
    //memcpy(buf, DEVEUI, 8);
    LMIC_reverse_memcpy(buf, reverse_DEVEUI, 8);
}

// provide device key (16 bytes)
void os_getDevKey (u1_t* buf) {
    debug("os_getDevKey Enter\r\n");
    for(int i=0; i < 16; i++)
        debug("%02X ",DEVKEY[i]);
    debug("\r\n");
    for(int i=0; i < 16; i++)
        debug("%c ",DEVKEY[i]);
    debug("\r\n");
   memcpy(buf, DEVKEY, 16);
}

//////////////////////////////////////////////////
// MAIN - INITIALIZATION AND STARTUP
//////////////////////////////////////////////////
void get_mote_version()
{
//    char first;
      
//    pc_7 = 1;
//    first = pc_1;
//    pc_7 = 0;
//    if (first && !pc_1) {
//        mote_version = MOTE_V2;
//        printf("v2\r\n");
//        bat = new AnalogIn(PA_0);
//    } else {
//        mote_version = MOTE_V3;
//        printf("v3\r\n");
//        bat = new AnalogIn(PA_1);
//    }
}

#if 0
// initial job
static void initfunc (osjob_t* j) {
    debug_str("B: INITFUNC\n");
    // reset MAC state
    LMIC_reset();
    // start joining
#if( OVER_THE_AIR_ACTIVATION != 0 )
    LMIC_startJoining();
#else
    devaddr_t *serial_id = (devaddr_t *) 0x1FF800d0;        // cat3 device stm32l152rc
    LMIC_setSession( 0, *serial_id, NwkSKey, ArtSKey );
    debug_val("SN = ", *serial_id);
#endif
     //init done - onEvent() callback will be invoked...

    //DEBUG_STR("E: INITFUNC");
    get_mote_version();
//    if (mote_version == MOTE_V3)
//        gps.en_invert = false;
//    else
//        gps.en_invert = true;
        
//    gps.init();
//    gps.enable(1);
    //gps.verbose = 1;

//    mpl3115a2.init();
}
#endif

#if 1
// counter static 
int cnt = 0; 
// log text to USART and toggle LED
static void initfunc (osjob_t* job) 
{ 
    // say hello 
    debug_str("Hello World!\r\n");
    // log counter 
    debug_val("cnt = ", cnt); 
    // toggle LED 
    debug_led(++cnt & 1); 
    // reschedule job every second 
    os_setTimedCallback(job, os_getTime()+sec2osticks(1), initfunc);
}
#endif


int main(void)
{
    osjob_t initjob;
 
    // initialize runtime env
    debug_init();
    os_init();
    // setup initial job
    os_setCallback(&initjob, initfunc);
    // execute scheduled jobs and events
    os_runloop();
    // (not reached)
}

//////////////////////////////////////////////////
// LMIC EVENT CALLBACK
//////////////////////////////////////////////////
osjob_t rxLedJob;
osjob_t txLedJob;
osjob_t sendFrameJob;

static void onRxLed (osjob_t* j) {
    debug_val("LED2 = ", 1 );
    led2 = 1;
}

static void onTxLed (osjob_t* j) {
    debug_val("LED1 = ", 1 );
    led1 = 1;
}

static void
restore_hsi()
{
//    RCC_OscInitTypeDef osc_init;
    /* if HSI was shut off in deep sleep (needed for AnalogIn) */
//    HAL_RCC_GetOscConfig(&osc_init);
//    if (osc_init.HSIState != RCC_HSI_ON) {
//        // Enable the HSI (to clock the ADC)
//        osc_init.OscillatorType = RCC_OSCILLATORTYPE_HSI;
//        osc_init.HSIState       = RCC_HSI_ON;
//        osc_init.PLL.PLLState   = RCC_PLL_NONE;
//        HAL_RCC_OscConfig(&osc_init);    
//    }    
}

static bool AppLedStateOn = false;

#define AIN_VREF        3.3     // stm32 internal refernce
#define AIN_VBAT_DIV    2       // resistor divider
static void PrepareDataFrame( void )
{
    uint16_t altitudeGps;
    
    restore_hsi();

//    gps.service();
    //printf("lat:%f  long:%f\r\n", gps.Latitude, gps.Longitude);
//    mpl3115a2.ReadTemperature();

    // immediately prepare next transmission
    //LMIC.frame[0] = LMIC.rxq.snr;
    LMIC.frame[0] = AppLedStateOn; // (bit 0 == 1) => LED on
//    LMIC.frame[1] = (int)mpl3115a2.Temperature; // Signed degrees Celcius in half degree units. So,  +/-63 C
    LMIC.frame[2] = (bat->read_u16() >> 8) + (bat->read_u16() >> 9) ; // per LoRaMAC spec; 0=Charging; 1...254 = level, 255 = N/A
    
//    LMIC.frame[3] = ( gps.LatitudeBinary >> 16 ) & 0xFF;
//    LMIC.frame[4] = ( gps.LatitudeBinary >> 8 ) & 0xFF;
//    LMIC.frame[5] = gps.LatitudeBinary & 0xFF;
//    LMIC.frame[6] = ( gps.LongitudeBinary >> 16 ) & 0xFF;
//    LMIC.frame[7] = ( gps.LongitudeBinary >> 8 ) & 0xFF;
//    LMIC.frame[8] = gps.LongitudeBinary & 0xFF;

//    altitudeGps = atoi(gps.NmeaGpsData.NmeaAltitude);
    //printf("alt:%d\r\n", altitudeGps);
    LMIC.frame[9] = ( altitudeGps >> 8 ) & 0xFF;
    LMIC.frame[10] = altitudeGps & 0xFF;
    

    //printf("bat:%.2f\r\n", volts);
#ifndef CHNL_HYBRID
    float volts = bat->read()*AIN_VREF*AIN_VBAT_DIV;
    if (volts < LOW_BAT_THRESHOLD)
        LMIC.txpow_limit = 20;
    else
        LMIC.txpow_limit = 30;
#endif /* !CHNL_HYBRID */  
}

static void onSendFrame (osjob_t* j)
{
    if (LMIC.opmode & OP_TXRXPEND)
        return;
        
    PrepareDataFrame( );
    // schedule transmission (port 1, data[], datalen 1, ACK requested)
    // (will be sent as soon as duty cycle permits)
             
    LMIC_setTxData2(5, LMIC.frame, APP_DATA_SIZE, APP_ACK);
}

void onEvent (ev_t ev) {

    debug_event(ev);

//    gps.service();

    switch(ev) 
    {
    // network joined, session established
    case EV_JOINED:
        debug_val("Net ID = ", LMIC.netid);
        goto tx;
    // scheduled data sent (optionally data received)
    case EV_TXCOMPLETE:
        if(LMIC.dataLen) 
        { // data received in rx slot after tx
            debug_buf(LMIC.frame+LMIC.dataBeg, LMIC.dataLen);
            if(LMIC.dataLen == 1) { // set LED state if exactly one byte is received
                AppLedStateOn = LMIC.frame[LMIC.dataBeg] & 0x01;
                debug_val("LED3 = ", AppLedStateOn ? 0 : 1 );
            }
        }
        if((LMIC.txrxFlags & (TXRX_DNW1|TXRX_DNW2) )!= 0 )
        {
            debug_val("LED2 = ", 0 );
            led2 = 0;
            os_setTimedCallback( &rxLedJob, os_getTime() + ms2osticks(15), onRxLed );
        }
tx:
        os_setTimedCallback( &sendFrameJob, os_getTime() + ms2osticks(MS_DELAY_NEXT_TX), onSendFrame ); // Change the Tx periodicity
        //onSendFrame(NULL);
        
        // Blink Tx LED
        debug_val("LED1 = ", 0 );
        led1 = 0;
        
        os_setTimedCallback( &txLedJob, os_getTime() + ms2osticks(25), onTxLed );
        break;
    default:
        break;
    }
}