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 LoRa All

Committer:
Alliance
Date:
Wed Sep 23 08:11:40 2015 +0000
Revision:
3:db6ad4aa790d
Parent:
1:1ef4f6cd800c
Child:
4:0c164d628006
Demo Version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
GregCr 0:fc538717c96e 1 /*
GregCr 0:fc538717c96e 2 / _____) _ | |
GregCr 0:fc538717c96e 3 ( (____ _____ ____ _| |_ _____ ____| |__
GregCr 0:fc538717c96e 4 \____ \| ___ | (_ _) ___ |/ ___) _ \
GregCr 0:fc538717c96e 5 _____) ) ____| | | || |_| ____( (___| | | |
GregCr 0:fc538717c96e 6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
GregCr 0:fc538717c96e 7 (C)2015 Semtech
GregCr 0:fc538717c96e 8
GregCr 0:fc538717c96e 9 Description: LoRaMac classA device implementation
GregCr 0:fc538717c96e 10
GregCr 0:fc538717c96e 11 License: Revised BSD License, see LICENSE.TXT file include in the project
GregCr 0:fc538717c96e 12
GregCr 0:fc538717c96e 13 Maintainer: Miguel Luis and Gregory Cristian
GregCr 0:fc538717c96e 14 */
GregCr 0:fc538717c96e 15 #include "mbed.h"
GregCr 0:fc538717c96e 16 #include "board.h"
GregCr 0:fc538717c96e 17 #include "LoRaMac.h"
GregCr 0:fc538717c96e 18 #include "utilities.h"
GregCr 0:fc538717c96e 19 #include "DigitDisplay.h"
GregCr 0:fc538717c96e 20 #include "ChainableLED.h"
GregCr 0:fc538717c96e 21
GregCr 0:fc538717c96e 22 /*!
GregCr 0:fc538717c96e 23 * When set to 1 the application uses the Over-the-Air activation procedure
GregCr 0:fc538717c96e 24 * When set to 0 the application uses the Personalization activation procedure
GregCr 0:fc538717c96e 25 */
Alliance 3:db6ad4aa790d 26 #define OVER_THE_AIR_ACTIVATION 1
GregCr 0:fc538717c96e 27
GregCr 0:fc538717c96e 28 /*!
GregCr 0:fc538717c96e 29 * Mote device IEEE EUI
GregCr 0:fc538717c96e 30 */
GregCr 0:fc538717c96e 31 static uint8_t DevEui[] =
GregCr 0:fc538717c96e 32 {
Alliance 3:db6ad4aa790d 33 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
GregCr 0:fc538717c96e 34 };
GregCr 0:fc538717c96e 35
GregCr 0:fc538717c96e 36 #if( OVER_THE_AIR_ACTIVATION != 0 )
GregCr 0:fc538717c96e 37
GregCr 0:fc538717c96e 38 #define OVER_THE_AIR_ACTIVATION_DUTYCYCLE 10000000 // 10 [s] value in us
GregCr 0:fc538717c96e 39
GregCr 0:fc538717c96e 40 /*!
GregCr 0:fc538717c96e 41 * Application IEEE EUI
GregCr 0:fc538717c96e 42 */
GregCr 0:fc538717c96e 43 static uint8_t AppEui[] =
GregCr 0:fc538717c96e 44 {
GregCr 0:fc538717c96e 45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
GregCr 0:fc538717c96e 46 };
GregCr 0:fc538717c96e 47
GregCr 0:fc538717c96e 48 /*!
GregCr 0:fc538717c96e 49 * AES encryption/decryption cipher application key
GregCr 0:fc538717c96e 50 */
GregCr 0:fc538717c96e 51 static uint8_t AppKey[] =
GregCr 0:fc538717c96e 52 {
Alliance 3:db6ad4aa790d 53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Alliance 3:db6ad4aa790d 54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x19
GregCr 0:fc538717c96e 55 };
GregCr 0:fc538717c96e 56
GregCr 0:fc538717c96e 57 #else
GregCr 0:fc538717c96e 58
GregCr 0:fc538717c96e 59 /*!
GregCr 0:fc538717c96e 60 * AES encryption/decryption cipher network session key
GregCr 0:fc538717c96e 61 */
GregCr 0:fc538717c96e 62 static uint8_t NwkSKey[] =
GregCr 0:fc538717c96e 63 {
Alliance 3:db6ad4aa790d 64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Alliance 3:db6ad4aa790d 65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x19
GregCr 0:fc538717c96e 66 };
GregCr 0:fc538717c96e 67
GregCr 0:fc538717c96e 68 /*!
GregCr 0:fc538717c96e 69 * AES encryption/decryption cipher application session key
GregCr 0:fc538717c96e 70 */
GregCr 0:fc538717c96e 71 static uint8_t AppSKey[] =
GregCr 0:fc538717c96e 72 {
Alliance 3:db6ad4aa790d 73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Alliance 3:db6ad4aa790d 74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x19
GregCr 0:fc538717c96e 75 };
GregCr 0:fc538717c96e 76
GregCr 0:fc538717c96e 77 /*!
GregCr 0:fc538717c96e 78 * Device address
GregCr 0:fc538717c96e 79 */
GregCr 0:fc538717c96e 80 static uint32_t DevAddr;
GregCr 0:fc538717c96e 81
GregCr 0:fc538717c96e 82 #endif
GregCr 0:fc538717c96e 83
GregCr 0:fc538717c96e 84 /*!
GregCr 0:fc538717c96e 85 * Indicates if the MAC layer has already joined a network.
GregCr 0:fc538717c96e 86 */
GregCr 0:fc538717c96e 87 static bool IsNetworkJoined = false;
GregCr 0:fc538717c96e 88
GregCr 0:fc538717c96e 89 /*!
GregCr 0:fc538717c96e 90 * Defines the application data transmission duty cycle
GregCr 0:fc538717c96e 91 */
Alliance 3:db6ad4aa790d 92 #define APP_TX_DUTYCYCLE 10000000 // 10 [s] value in us
Alliance 3:db6ad4aa790d 93 #define APP_TX_DUTYCYCLE_RND 2000000 // 2 [s] value in us
GregCr 0:fc538717c96e 94
GregCr 0:fc538717c96e 95 /*!
GregCr 0:fc538717c96e 96 * User application data buffer size
GregCr 0:fc538717c96e 97 */
GregCr 0:fc538717c96e 98 #define APP_DATA_SIZE 8
GregCr 0:fc538717c96e 99
GregCr 0:fc538717c96e 100 /*!
GregCr 0:fc538717c96e 101 * User application data
GregCr 0:fc538717c96e 102 */
GregCr 0:fc538717c96e 103 static uint8_t AppData[APP_DATA_SIZE];
GregCr 0:fc538717c96e 104
GregCr 0:fc538717c96e 105 /*!
GregCr 0:fc538717c96e 106 * Defines the application data transmission duty cycle
GregCr 0:fc538717c96e 107 */
GregCr 0:fc538717c96e 108 static uint32_t TxDutyCycleTime;
GregCr 0:fc538717c96e 109
GregCr 0:fc538717c96e 110 Ticker TxNextPacketTimer;
GregCr 0:fc538717c96e 111
GregCr 0:fc538717c96e 112 #if( OVER_THE_AIR_ACTIVATION != 0 )
GregCr 0:fc538717c96e 113
GregCr 0:fc538717c96e 114 /*!
GregCr 0:fc538717c96e 115 * Defines the join request timer
GregCr 0:fc538717c96e 116 */
GregCr 0:fc538717c96e 117 Ticker JoinReqTimer;
GregCr 0:fc538717c96e 118
GregCr 0:fc538717c96e 119 #endif
GregCr 0:fc538717c96e 120
GregCr 0:fc538717c96e 121 /*!
GregCr 0:fc538717c96e 122 * Indicates if a new packet can be sent
GregCr 0:fc538717c96e 123 */
GregCr 0:fc538717c96e 124 static bool TxNextPacket = true;
GregCr 0:fc538717c96e 125 static bool TxDone = false;
GregCr 0:fc538717c96e 126
Alliance 3:db6ad4aa790d 127 static uint8_t AppPort = 3;
GregCr 0:fc538717c96e 128 static uint8_t AppDataSize = APP_DATA_SIZE;
GregCr 0:fc538717c96e 129
GregCr 0:fc538717c96e 130 static LoRaMacEvent_t LoRaMacEvents;
GregCr 0:fc538717c96e 131
GregCr 0:fc538717c96e 132 Ticker Led1Timer;
GregCr 0:fc538717c96e 133 Ticker Led2Timer;
Alliance 1:1ef4f6cd800c 134 Ticker BuzTimer;
GregCr 0:fc538717c96e 135
GregCr 0:fc538717c96e 136 #define NUM_LED 3
GregCr 0:fc538717c96e 137
Alliance 3:db6ad4aa790d 138
GregCr 0:fc538717c96e 139 // ChainableLED(clk, data, number_of_leds)
GregCr 0:fc538717c96e 140 ChainableLED color_led(D8, D9, NUM_LED);
GregCr 0:fc538717c96e 141
GregCr 0:fc538717c96e 142 DigitDisplay display(D6, D7);
GregCr 0:fc538717c96e 143
GregCr 0:fc538717c96e 144 DigitalOut buzzer(A2);
GregCr 0:fc538717c96e 145
Alliance 3:db6ad4aa790d 146
Alliance 1:1ef4f6cd800c 147 static void OnBuzTimerEvent( void )
Alliance 1:1ef4f6cd800c 148 {
Alliance 1:1ef4f6cd800c 149 buzzer = 0;
Alliance 1:1ef4f6cd800c 150 BuzTimer.detach( );
Alliance 1:1ef4f6cd800c 151 }
GregCr 0:fc538717c96e 152
GregCr 0:fc538717c96e 153 /*!
GregCr 0:fc538717c96e 154 *
GregCr 0:fc538717c96e 155 */
GregCr 0:fc538717c96e 156 static void PrepareTxFrame( uint8_t port )
GregCr 0:fc538717c96e 157 {
Alliance 3:db6ad4aa790d 158 AppData[0] = 0x99;
Alliance 3:db6ad4aa790d 159 AppData[1] = 0x99;
Alliance 3:db6ad4aa790d 160 AppData[2] = 0x99;
Alliance 3:db6ad4aa790d 161 AppData[3] = 0x99;
Alliance 3:db6ad4aa790d 162 AppData[4] = 0x99;
Alliance 3:db6ad4aa790d 163 AppData[5] = 0x99;
Alliance 3:db6ad4aa790d 164 AppData[6] = 0x99;
Alliance 3:db6ad4aa790d 165 AppData[7] = 0x99;
GregCr 0:fc538717c96e 166 }
GregCr 0:fc538717c96e 167
GregCr 0:fc538717c96e 168 static void ProcessRxFrame( LoRaMacEventFlags_t *flags, LoRaMacEventInfo_t *info )
GregCr 0:fc538717c96e 169 {
GregCr 0:fc538717c96e 170 switch( info->RxPort ) // Check Rx port number
GregCr 0:fc538717c96e 171 {
GregCr 0:fc538717c96e 172 case 10:
Alliance 3:db6ad4aa790d 173 /* display.write( 0, info->RxBuffer[0] );
Alliance 1:1ef4f6cd800c 174 display.write( 1, info->RxBuffer[1] );
Alliance 1:1ef4f6cd800c 175 display.write( 2, info->RxBuffer[2] );
Alliance 3:db6ad4aa790d 176 display.write( 3, info->RxBuffer[3] ); */
GregCr 0:fc538717c96e 177 break;
GregCr 0:fc538717c96e 178
Alliance 1:1ef4f6cd800c 179 case 20:
Alliance 3:db6ad4aa790d 180 // color_led.setColorRGB(0, info->RxBuffer[0], info->RxBuffer[0], info->RxBuffer[0] );
Alliance 1:1ef4f6cd800c 181 break;
GregCr 0:fc538717c96e 182
Alliance 1:1ef4f6cd800c 183 case 30:
Alliance 1:1ef4f6cd800c 184 BuzTimer.attach_us( &OnBuzTimerEvent, 500000 );
Alliance 1:1ef4f6cd800c 185 buzzer = 1;
GregCr 0:fc538717c96e 186 break;
GregCr 0:fc538717c96e 187
GregCr 0:fc538717c96e 188 default:
GregCr 0:fc538717c96e 189 break;
GregCr 0:fc538717c96e 190 }
GregCr 0:fc538717c96e 191 }
GregCr 0:fc538717c96e 192
GregCr 0:fc538717c96e 193 static bool SendFrame( void )
GregCr 0:fc538717c96e 194 {
GregCr 0:fc538717c96e 195 uint8_t sendFrameStatus = 0;
GregCr 0:fc538717c96e 196
GregCr 0:fc538717c96e 197 sendFrameStatus = LoRaMacSendFrame( AppPort, AppData, AppDataSize );
GregCr 0:fc538717c96e 198 // sendFrameStatus = LoRaMacSendConfirmedFrame( AppPort, AppData, AppDataSize, 8 );
GregCr 0:fc538717c96e 199 switch( sendFrameStatus )
GregCr 0:fc538717c96e 200 {
GregCr 0:fc538717c96e 201 case 5: // NO_FREE_CHANNEL
GregCr 0:fc538717c96e 202 // Try again later
GregCr 0:fc538717c96e 203 return true;
GregCr 0:fc538717c96e 204 default:
GregCr 0:fc538717c96e 205 return false;
GregCr 0:fc538717c96e 206 }
GregCr 0:fc538717c96e 207 }
GregCr 0:fc538717c96e 208
GregCr 0:fc538717c96e 209
GregCr 0:fc538717c96e 210 #if( OVER_THE_AIR_ACTIVATION != 0 )
GregCr 0:fc538717c96e 211 /*!
GregCr 0:fc538717c96e 212 * \brief Function executed on JoinReq Timeout event
GregCr 0:fc538717c96e 213 */
GregCr 0:fc538717c96e 214 static void OnJoinReqTimerEvent( void )
GregCr 0:fc538717c96e 215 {
GregCr 0:fc538717c96e 216 TxNextPacket = true;
Alliance 1:1ef4f6cd800c 217 JoinReqTimer.detach( );
GregCr 0:fc538717c96e 218 }
GregCr 0:fc538717c96e 219 #endif
GregCr 0:fc538717c96e 220
GregCr 0:fc538717c96e 221
GregCr 0:fc538717c96e 222 /*!
GregCr 0:fc538717c96e 223 * \brief Function executed on TxNextPacket Timeout event
GregCr 0:fc538717c96e 224 */
GregCr 0:fc538717c96e 225 static void OnTxNextPacketTimerEvent( void )
Alliance 1:1ef4f6cd800c 226 {
GregCr 0:fc538717c96e 227 TxNextPacket = true;
Alliance 1:1ef4f6cd800c 228 TxNextPacketTimer.detach( );
GregCr 0:fc538717c96e 229 }
GregCr 0:fc538717c96e 230
GregCr 0:fc538717c96e 231
GregCr 0:fc538717c96e 232 /*!
GregCr 0:fc538717c96e 233 * \brief Function to be executed on MAC layer event
GregCr 0:fc538717c96e 234 */
GregCr 0:fc538717c96e 235 static void OnMacEvent( LoRaMacEventFlags_t *flags, LoRaMacEventInfo_t *info )
GregCr 0:fc538717c96e 236 {
GregCr 0:fc538717c96e 237 if( flags->Bits.JoinAccept == 1 )
GregCr 0:fc538717c96e 238 {
GregCr 0:fc538717c96e 239 #if( OVER_THE_AIR_ACTIVATION != 0 )
GregCr 0:fc538717c96e 240 JoinReqTimer.detach( );
GregCr 0:fc538717c96e 241 #endif
GregCr 0:fc538717c96e 242 IsNetworkJoined = true;
GregCr 0:fc538717c96e 243 }
GregCr 0:fc538717c96e 244
GregCr 0:fc538717c96e 245 if( flags->Bits.Tx == 1 )
GregCr 0:fc538717c96e 246 {
GregCr 0:fc538717c96e 247 }
GregCr 0:fc538717c96e 248
GregCr 0:fc538717c96e 249 if( flags->Bits.Rx == 1 )
GregCr 0:fc538717c96e 250 {
GregCr 0:fc538717c96e 251 if( flags->Bits.RxData == true )
GregCr 0:fc538717c96e 252 {
GregCr 0:fc538717c96e 253 ProcessRxFrame( flags, info );
GregCr 0:fc538717c96e 254 }
GregCr 0:fc538717c96e 255 }
GregCr 0:fc538717c96e 256
GregCr 0:fc538717c96e 257 // Schedule a new transmission
GregCr 0:fc538717c96e 258 TxDone = true;
GregCr 0:fc538717c96e 259 }
GregCr 0:fc538717c96e 260
GregCr 0:fc538717c96e 261 /**
GregCr 0:fc538717c96e 262 * Main application entry point.
GregCr 0:fc538717c96e 263 */
GregCr 0:fc538717c96e 264 int main( void )
GregCr 0:fc538717c96e 265 {
GregCr 0:fc538717c96e 266 #if( OVER_THE_AIR_ACTIVATION != 0 )
GregCr 0:fc538717c96e 267 uint8_t sendFrameStatus = 0;
GregCr 0:fc538717c96e 268 #endif
GregCr 0:fc538717c96e 269 bool trySendingFrameAgain = false;
GregCr 0:fc538717c96e 270
Alliance 1:1ef4f6cd800c 271 buzzer = 0;
Alliance 1:1ef4f6cd800c 272
Alliance 1:1ef4f6cd800c 273 debug( "\n\n\r LoRaWAN Class A Demo code \n\n\r" );
Alliance 1:1ef4f6cd800c 274
GregCr 0:fc538717c96e 275 BoardInitMcu( );
GregCr 0:fc538717c96e 276 BoardInitPeriph( );
GregCr 0:fc538717c96e 277
GregCr 0:fc538717c96e 278 // Initialize LoRaMac device unique ID
Alliance 3:db6ad4aa790d 279 // BoardGetUniqueId( DevEui );
Alliance 3:db6ad4aa790d 280
GregCr 0:fc538717c96e 281 LoRaMacEvents.MacEvent = OnMacEvent;
GregCr 0:fc538717c96e 282 LoRaMacInit( &LoRaMacEvents );
GregCr 0:fc538717c96e 283
GregCr 0:fc538717c96e 284 IsNetworkJoined = false;
GregCr 0:fc538717c96e 285
GregCr 0:fc538717c96e 286 #if( OVER_THE_AIR_ACTIVATION == 0 )
GregCr 0:fc538717c96e 287 // Random seed initialization
GregCr 0:fc538717c96e 288 srand( RAND_SEED );
GregCr 0:fc538717c96e 289 // Choose a random device address
GregCr 0:fc538717c96e 290 // NwkID = 0
GregCr 0:fc538717c96e 291 // NwkAddr rand [0, 33554431]
GregCr 0:fc538717c96e 292 DevAddr = randr( 0, 0x01FFFFFF );
Alliance 3:db6ad4aa790d 293
GregCr 0:fc538717c96e 294 LoRaMacInitNwkIds( 0x000000, DevAddr, NwkSKey, AppSKey );
GregCr 0:fc538717c96e 295 IsNetworkJoined = true;
GregCr 0:fc538717c96e 296 #endif
GregCr 0:fc538717c96e 297
GregCr 0:fc538717c96e 298 TxNextPacket = true;
GregCr 0:fc538717c96e 299
Alliance 1:1ef4f6cd800c 300 LoRaMacSetAdrOn( false );
Alliance 1:1ef4f6cd800c 301
Alliance 1:1ef4f6cd800c 302 LoRaMacSetDutyCycleOn( false );
GregCr 0:fc538717c96e 303
GregCr 0:fc538717c96e 304 while( 1 )
GregCr 0:fc538717c96e 305 {
GregCr 0:fc538717c96e 306 while( IsNetworkJoined == false )
GregCr 0:fc538717c96e 307 {
GregCr 0:fc538717c96e 308 #if( OVER_THE_AIR_ACTIVATION != 0 )
GregCr 0:fc538717c96e 309 if( TxNextPacket == true )
GregCr 0:fc538717c96e 310 {
GregCr 0:fc538717c96e 311 TxNextPacket = false;
GregCr 0:fc538717c96e 312
GregCr 0:fc538717c96e 313 sendFrameStatus = LoRaMacJoinReq( DevEui, AppEui, AppKey );
Alliance 3:db6ad4aa790d 314 debug("Req Sent\n\r");
GregCr 0:fc538717c96e 315 switch( sendFrameStatus )
GregCr 0:fc538717c96e 316 {
GregCr 0:fc538717c96e 317 case 1: // BUSY
GregCr 0:fc538717c96e 318 break;
GregCr 0:fc538717c96e 319 case 0: // OK
GregCr 0:fc538717c96e 320 case 2: // NO_NETWORK_JOINED
GregCr 0:fc538717c96e 321 case 3: // LENGTH_PORT_ERROR
GregCr 0:fc538717c96e 322 case 4: // MAC_CMD_ERROR
GregCr 0:fc538717c96e 323 case 6: // DEVICE_OFF
GregCr 0:fc538717c96e 324 default:
GregCr 0:fc538717c96e 325 // Relaunch timer for next trial
GregCr 0:fc538717c96e 326 JoinReqTimer.attach_us( &OnJoinReqTimerEvent, OVER_THE_AIR_ACTIVATION_DUTYCYCLE );
GregCr 0:fc538717c96e 327 break;
GregCr 0:fc538717c96e 328 }
GregCr 0:fc538717c96e 329 }
GregCr 0:fc538717c96e 330 // TimerLowPowerHandler( );
GregCr 0:fc538717c96e 331 #endif
GregCr 0:fc538717c96e 332 }
GregCr 0:fc538717c96e 333
GregCr 0:fc538717c96e 334 if( TxDone == true )
GregCr 0:fc538717c96e 335 {
GregCr 0:fc538717c96e 336
GregCr 0:fc538717c96e 337 TxDone = false;
GregCr 0:fc538717c96e 338
GregCr 0:fc538717c96e 339 debug( "TxDone \n\n\r" );
GregCr 0:fc538717c96e 340 // Schedule next packet transmission
GregCr 0:fc538717c96e 341 TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND );
GregCr 0:fc538717c96e 342 TxNextPacketTimer.attach_us( &OnTxNextPacketTimerEvent, TxDutyCycleTime );
GregCr 0:fc538717c96e 343 }
GregCr 0:fc538717c96e 344
GregCr 0:fc538717c96e 345 if( trySendingFrameAgain == true )
GregCr 0:fc538717c96e 346 {
GregCr 0:fc538717c96e 347 trySendingFrameAgain = SendFrame( );
GregCr 0:fc538717c96e 348 }
GregCr 0:fc538717c96e 349
GregCr 0:fc538717c96e 350 if( TxNextPacket == true )
GregCr 0:fc538717c96e 351 {
GregCr 0:fc538717c96e 352 TxNextPacketTimer.detach( );
GregCr 0:fc538717c96e 353
GregCr 0:fc538717c96e 354 TxNextPacket = false;
GregCr 0:fc538717c96e 355
GregCr 0:fc538717c96e 356 PrepareTxFrame( AppPort );
GregCr 0:fc538717c96e 357
GregCr 0:fc538717c96e 358 trySendingFrameAgain = SendFrame( );
GregCr 0:fc538717c96e 359 }
GregCr 0:fc538717c96e 360
GregCr 0:fc538717c96e 361 // TimerLowPowerHandler( );
GregCr 0:fc538717c96e 362 }
GregCr 0:fc538717c96e 363 }
GregCr 0:fc538717c96e 364