Fork from LoRa Alliance program. available here: https://developer.mbed.org/users/Alliance/code/LoRaWAN/
Dependencies: LoRaMacLib SX1276Lib mbed Chainable_RGB_LED DigitDisplay
Fork of LoRaWAN by
main.cpp
- Committer:
- Alliance
- Date:
- 2015-09-22
- Revision:
- 1:1ef4f6cd800c
- Parent:
- 0:fc538717c96e
- Child:
- 3:db6ad4aa790d
File content as of revision 1:1ef4f6cd800c:
/* / _____) _ | | ( (____ _____ ____ _| |_ _____ ____| |__ \____ \| ___ | (_ _) ___ |/ ___) _ \ _____) ) ____| | | || |_| ____( (___| | | | (______/|_____)_|_|_| \__)_____)\____)_| |_| (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" /*! * 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[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; #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[] = { 0x00, 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 /*! * 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 }; /*! * Device address */ static uint32_t DevAddr; #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 #define APP_TX_DUTYCYCLE_RND 1000000 // 1 [s] value in us /*! * User application data buffer size */ #define APP_DATA_SIZE 8 /*! * 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 = 1; static uint8_t AppDataSize = APP_DATA_SIZE; static bool AppLedStateOn = false; static LoRaMacEvent_t LoRaMacEvents; Ticker Led1Timer; Ticker Led2Timer; Ticker BuzTimer; #define NUM_LED 3 // ChainableLED(clk, data, number_of_leds) ChainableLED color_led(D8, D9, NUM_LED); DigitDisplay display(D6, D7); DigitalOut buzzer(A2); static void OnBuzTimerEvent( void ) { buzzer = 0; BuzTimer.detach( ); } /*! * */ static void PrepareTxFrame( uint8_t port ) { AppData[0] = 0x01; AppData[1] = 0x77; AppData[2] = 0x77; AppData[3] = 0x77; AppData[4] = 0x77; AppData[5] = 0x77; AppData[6] = 0x77; AppData[7] = 0x77; } static void ProcessRxFrame( LoRaMacEventFlags_t *flags, LoRaMacEventInfo_t *info ) { switch( info->RxPort ) // Check Rx port number { case 10: 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: color_led.setColorRGB(0, info->RxBuffer[0], info->RxBuffer[0], info->RxBuffer[0] ); break; case 30: BuzTimer.attach_us( &OnBuzTimerEvent, 500000 ); buzzer = 1; break; default: break; } } static bool SendFrame( void ) { uint8_t sendFrameStatus = 0; sendFrameStatus = LoRaMacSendFrame( AppPort, AppData, AppDataSize ); // 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; buzzer = 0; 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 ); IsNetworkJoined = false; #if( OVER_THE_AIR_ACTIVATION == 0 ) // Random seed initialization srand( RAND_SEED ); // Choose a random device address // NwkID = 0 // NwkAddr rand [0, 33554431] DevAddr = randr( 0, 0x01FFFFFF ); LoRaMacInitNwkIds( 0x000000, DevAddr, NwkSKey, AppSKey ); IsNetworkJoined = true; #endif TxNextPacket = true; LoRaMacSetAdrOn( false ); LoRaMacSetDutyCycleOn( false ); while( 1 ) { while( IsNetworkJoined == false ) { #if( OVER_THE_AIR_ACTIVATION != 0 ) if( TxNextPacket == true ) { TxNextPacket = false; sendFrameStatus = LoRaMacJoinReq( DevEui, AppEui, AppKey ); 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 ) { 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( ); } // TimerLowPowerHandler( ); } }