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
Diff: main.cpp
- Revision:
- 0:fc538717c96e
- Child:
- 1:1ef4f6cd800c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Sep 21 07:55:43 2015 +0000 @@ -0,0 +1,351 @@ +/* + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (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; + + +#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 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] / 10 ); + display.write( 1, info->RxBuffer[1] % 10 ); + display.write( 2, info->RxBuffer[2] / 10 ); + display.write( 3, info->RxBuffer[3] % 10 ); + break; + + + case 20: + color_led.setColorRGB(0, info->RxBuffer[0], info->RxBuffer[1], 0x00 ); + 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; +} +#endif + + +/*! + * \brief Function executed on TxNextPacket Timeout event + */ +static void OnTxNextPacketTimerEvent( void ) +{ + debug( "OnTxNextPacketTimerEvent\n\n\r" ); + + TxNextPacket = true; +} + + +/*! + * \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 ) +{ + debug( "\n\n\r LoRaWAN Class A Demo code \n\n\r" ); + +#if( OVER_THE_AIR_ACTIVATION != 0 ) + uint8_t sendFrameStatus = 0; +#endif + bool trySendingFrameAgain = false; + + 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( true ); + + 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" ); + color_led.setColorRGB(0, randr( 0, 255 ), randr( 0, 255 ), randr( 0, 255 ) ); + // 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( ); + } +} +