pzheng 20151201

Dependencies:   LoRaMacLib SX1276Lib mbed Chainable_RGB_LED DigitDisplay

Fork of LoRaWAN by LoRa All

main.cpp

Committer:
pzheng
Date:
2015-12-03
Revision:
18:0ffbe03c5542
Parent:
17:60af095c8763
Child:
19:9ae3b9b57ae0

File content as of revision 18:0ffbe03c5542:

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

Description: LoRaMac classA device implementation

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

Maintainer: Miguel Luis and Gregory Cristian
*/
#include "mbed.h"
#include "board.h"
#include "LoRaMac.h"
#include "utilities.h"
#include "DigitDisplay.h"
#include "ChainableLED.h"

//commented in 20151130
/*//Added by pzheng 20151111
static uint16_t counter_preparetxframe_log = 0;*/
/*!
 * When set to 1 the application uses the Over-the-Air activation procedure
 * When set to 0 the application uses the Personalization activation procedure
 */
#define OVER_THE_AIR_ACTIVATION                     0
/*!
 * Mote device IEEE EUI
 */
static uint8_t DevEui[] =
{
    0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10                  /// <<< Change here
};

#if( OVER_THE_AIR_ACTIVATION != 0 )

#define OVER_THE_AIR_ACTIVATION_DUTYCYCLE          10000000  // 10 [s] value in us

/*!
 * Application IEEE EUI
 */
static uint8_t AppEui[] =
{
    0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

/*!
 * AES encryption/decryption cipher application key
 */
static uint8_t AppKey[] = 
{ 
    0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
    0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
};

#else
/*!
 * Device address
 */
static uint32_t DevAddr;// = 0x00001002;                               /// <<< Change here

/*!
 * AES encryption/decryption cipher network session key
 */
static uint8_t NwkSKey[] = 
{ 
    0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
    0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
};

/*!
 * AES encryption/decryption cipher application session key
 */
static uint8_t AppSKey[] = 
{ 
    0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
    0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
};

//static uint8_t NwkSKey[] = 
//{ 
//    0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
//    0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00
//};

///*!
// * AES encryption/decryption cipher application session key
// */
//static uint8_t AppSKey[] = 
//{ 
//    0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
//    0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00
//};
#endif


/*!
 * Indicates if the MAC layer has already joined a network.
 */
static bool IsNetworkJoined = false;

/*!
 * Defines the application data transmission duty cycle
 */
#define APP_TX_DUTYCYCLE                             5000000  // 5 [s] value in us (minimum 10s)
#define APP_TX_DUTYCYCLE_RND                         1000000  // 1 [s] value in us (minimum 3s)

/*!
 * User application data buffer size
 */
#define APP_DATA_SIZE                               5

/*!
 * User application data
 */
static uint8_t AppData[APP_DATA_SIZE];

/*!
 * Defines the application data transmission duty cycle
 */
static uint32_t TxDutyCycleTime;

Ticker TxNextPacketTimer;

#if( OVER_THE_AIR_ACTIVATION != 0 )

/*!
 * Defines the join request timer
 */
Ticker JoinReqTimer;

#endif

/*!
 * Indicates if a new packet can be sent
 */
static bool TxNextPacket = true;
static bool TxDone = false;

static uint8_t AppPort = 2;
static uint8_t AppDataSize = APP_DATA_SIZE;

static LoRaMacEvent_t LoRaMacEvents;

static float LightValue = 0.0; 
static uint8_t LightMode = 0;  // 0:automatic, 1:manual

Ticker Led1Timer;
Ticker Led2Timer;
Ticker BuzTimer;

#define NUM_LED 3


AnalogIn LightSens( A1 ); 
ChainableLED color_led(D6, D7, NUM_LED);
//commented in 20151130
/*DigitDisplay display(D8, D9);
DigitalOut buzzer(A2);*/

//commented in 20151130
/*static void OnBuzTimerEvent( void )
{
    buzzer = 0;
    BuzTimer.detach( );
}*/

/*!
 *
 */
static void PrepareTxFrame( uint8_t port )
{
    uint32_t tempValue = (uint32_t)(LightValue*1000000.0);    
    debug( "[Tx] LightValue=%d 0x%x\n\r" , tempValue, tempValue);
    
    AppData[0] = LightMode;
    AppData[1] = ((tempValue&0xFF000000)>>24)&0xFF;
    AppData[2] = ((tempValue&0x00FF0000)>>16)&0xFF;
    AppData[3] = ((tempValue&0x0000FF00)>>8)&0xFF;
    AppData[4] = (tempValue&0x000000FF);    
    //commented in 20151130
    /*counter_preparetxframe_log++;    
    display.write( counter_preparetxframe_log );*/    
}

static void ProcessRxFrame( LoRaMacEventFlags_t *flags, LoRaMacEventInfo_t *info )
{
    debug( "[Rx] Port=%d\n\r" , info->RxPort);
    switch( info->RxPort ) // Check Rx port number
    {
        case 10: 
            //commented in 20151130
            /*display.write( 0, info->RxBuffer[0] );
            display.write( 1, info->RxBuffer[1] );
            display.write( 2, info->RxBuffer[2] );
            display.write( 3, info->RxBuffer[3] ); 
            break;*/
            
        case 20:
            LightMode = info->RxBuffer[0];
            debug( "[Rx] LightMode=%x - R G B= 0x%x 0x%x 0x%x\n\r" , LightMode, info->RxBuffer[1], info->RxBuffer[2], info->RxBuffer[3]);
            if( LightMode )
            {
                color_led.setColorRGB(0, info->RxBuffer[1], info->RxBuffer[2], info->RxBuffer[3] );
            }
            break;
            
        case 30:
            //commented in 20151130
            /*BuzTimer.attach_us( &OnBuzTimerEvent, 500000 );
            buzzer = 1;*/
            break;
            
        default:
            break;
    }
}

static bool SendFrame( void )
{
    uint8_t sendFrameStatus = 0;

    if( LoRaMacGetUpLinkTestOn() == false)
    {
        sendFrameStatus = LoRaMacSendFrame( AppPort, AppData, AppDataSize );
    }
    else
    {
        sendFrameStatus = LoRaMacSendConfirmedFrame( AppPort, AppData, AppDataSize, 8 );
    }
    switch( sendFrameStatus )
    {
    case 5: // NO_FREE_CHANNEL
        // Try again later
        return true;
    default:
        return false;
    }
}


#if( OVER_THE_AIR_ACTIVATION != 0 )
/*!
 * \brief Function executed on JoinReq Timeout event
 */
static void OnJoinReqTimerEvent( void )
{
    TxNextPacket = true;
    JoinReqTimer.detach( );
}
#endif


/*!
 * \brief Function executed on TxNextPacket Timeout event
 */
static void OnTxNextPacketTimerEvent( void )
{    
    TxNextPacket = true;
    TxNextPacketTimer.detach( );
}


/*!
 * \brief Function to be executed on MAC layer event
 */
static void OnMacEvent( LoRaMacEventFlags_t *flags, LoRaMacEventInfo_t *info )
{
    if( flags->Bits.JoinAccept == 1 )
    {
#if( OVER_THE_AIR_ACTIVATION != 0 )
        JoinReqTimer.detach( );
#endif
        IsNetworkJoined = true;
    }
    
    if( flags->Bits.Tx == 1 )
    {
    }

    if( flags->Bits.Rx == 1 )
    {
        if( flags->Bits.RxData == true )
        {
            ProcessRxFrame( flags, info );
        }
    }

    // Schedule a new transmission
    TxDone = true;
}

/**
 * Main application entry point.
 */
int main( void )
{
#if( OVER_THE_AIR_ACTIVATION != 0 )
    uint8_t sendFrameStatus = 0;
#endif
    bool trySendingFrameAgain = false;
    float tempLightValue = 0;   
     
    LightMode = 0;      // 0: manual,   1: automatic
    
    //comment in 20151130
    //buzzer = 0;         // 0: OFF,      1: ON
    ///*Added by pzheng 20151111*/
    //display.write( counter_preparetxframe_log );
    
    debug( "\n\n\r    LoRaWAN Class A Demo code  \n\n\r" );
    
    BoardInitMcu( );
    BoardInitPeriph( );

    // Initialize LoRaMac device unique ID
    BoardGetUniqueId( DevEui );
    
    LoRaMacEvents.MacEvent = OnMacEvent;
    LoRaMacInit( &LoRaMacEvents );

    //Added by pzheng 20151111
    float hue = 0.0;
    bool up = true;
    for(int i = 0; i<16; i++)
    {
        for (int i=0; i<NUM_LED; i++)
        color_led.setColorHSB(i, hue, 1.0, 0.5);
    
    
        if (up)
            hue+= 0.025;
        else
            hue-= 0.025;
    
        if (hue>=1.0 && up)
            up = false;
        else if (hue<=0.0 && !up)
            up = true;   
    }
    
    IsNetworkJoined = false;

#if( OVER_THE_AIR_ACTIVATION == 0 )        
    // Random seed initialization
    srand1( RAND_SEED );
    // Choose a random device address
    // NwkID = 0
    // NwkAddr rand [0, 33554431]
    if( ( DevAddr == 0 ) || ( DevAddr == 0xFFFFFFFF ) )
    {
        // Generate random DevAddr if it does not exist
        debug("Generate random DevAddr\n\r");
        DevAddr = randr( 0, 0x01FFFFFF );
    }
    debug( "- DevAddr = 0x%x\n\r" , DevAddr);    
    LoRaMacInitNwkIds( 0x000000, DevAddr, NwkSKey, AppSKey );  
    
    for(int i = 0; i<16; i++)
    {
        debug( "- NwkSKey[%d] = 0x%x\n\r" , i, NwkSKey[i]);
    }
    for(int i = 0; i<16; i++)
    {
        debug( "- AppSKey[%d] = 0x%x\n\r" , i, AppSKey[i]);
    }
    IsNetworkJoined = true;
#endif

    TxNextPacket = true;

    LoRaMacSetAdrOn( true );
    
    LoRaMacSetDutyCycleOn( false );    
    
    //Added by pzheng 20151111
    LoRaMacSetUpLinkTestOn( false );
        
    while( 1 )
    {
        while( IsNetworkJoined == false )
        {
#if( OVER_THE_AIR_ACTIVATION != 0 )
            if( TxNextPacket == true )
            {
                TxNextPacket = false;
                
                //Added by pzheng 20151111 
                for(int i = 0; i<8; i++)
                {
                    //DevEui[i] = 0x10;
                    debug( "- DevEui[%d] = 0x%x\n\r" , i, DevEui[i]);
                }
                for(int i = 0; i<8; i++)
                {
                    debug( "- AppEui[%d] = 0x%x\n\r" , i, AppEui[i]);
                }
                for(int i = 0; i<16; i++)
                {
                    debug( "- AppKey[%d] = 0x%x\n\r" , i, AppKey[i]);
                }
                sendFrameStatus = LoRaMacJoinReq( DevEui, AppEui, AppKey );
                debug("Req Sent\n\r");
                switch( sendFrameStatus )
                {
                case 1: // BUSY
                    break;
                case 0: // OK
                case 2: // NO_NETWORK_JOINED
                case 3: // LENGTH_PORT_ERROR
                case 4: // MAC_CMD_ERROR
                case 6: // DEVICE_OFF
                default:
                    // Relaunch timer for next trial
                    JoinReqTimer.attach_us( &OnJoinReqTimerEvent, OVER_THE_AIR_ACTIVATION_DUTYCYCLE );
                    break;
                }
            }
//            TimerLowPowerHandler( );
#endif
        }

        if( TxDone == true )
        {
            for(int i = 0; i<8; i++)
            {
                debug( "- DevEui[%d] = 0x%x\n\r" , i, DevEui[i]);
            }
            TxDone = false;
            
            debug( "TxDone \n\n\r" );
            // Schedule next packet transmission
            TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND );
            TxNextPacketTimer.attach_us( &OnTxNextPacketTimerEvent, TxDutyCycleTime );
        }

        if( trySendingFrameAgain == true )
        {
            trySendingFrameAgain = SendFrame( );
        }
        
        if( TxNextPacket == true )
        {       
            TxNextPacketTimer.detach( );
            
            TxNextPacket = false;
        
            PrepareTxFrame( AppPort );
            
            trySendingFrameAgain = SendFrame( );
        }

        // Read light sensor
        tempLightValue = LightSens.read( ) * 1.65;
        
        LightValue = ( 1 - tempLightValue );
        
        // Set automatic RGB from light sensor
        if( LightMode == 0 )
        {
            color_led.setColorRGB( 0, ( uint8_t )( 255 * LightValue ), ( uint8_t )( 255 * LightValue ), ( uint8_t )( 255 * LightValue ) );
        }
//        TimerLowPowerHandler( );
    }
}