thien huynh / Mbed 2 deprecated LoRaWAN-lmic-app_huynh

Dependencies:   LMiC SX1276Lib mbed

Fork of LoRaWAN-lmic-app by Semtech

Files at this revision

API Documentation at this revision

Comitter:
mluis
Date:
Tue Mar 31 13:38:08 2015 +0000
Parent:
0:a2929fa6e4f0
Child:
2:4eb7f3e46f44
Commit message:
Updated main application.; Moved debug and hal files from LMiC to main application.

Changed in this revision

LMiC.lib Show annotated file Show diff for this revision Revisions of this file
SX1276Lib.lib Show annotated file Show diff for this revision Revisions of this file
debug.cpp Show annotated file Show diff for this revision Revisions of this file
debug.h Show annotated file Show diff for this revision Revisions of this file
hal.cpp Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- a/LMiC.lib	Thu Jan 22 13:02:55 2015 +0000
+++ b/LMiC.lib	Tue Mar 31 13:38:08 2015 +0000
@@ -1,1 +1,1 @@
-http://developer.mbed.org/users/mluis/code/LMiC/#62d1edcc13d1
+http://developer.mbed.org/users/mluis/code/LMiC/#d3b7bde3995c
--- a/SX1276Lib.lib	Thu Jan 22 13:02:55 2015 +0000
+++ b/SX1276Lib.lib	Tue Mar 31 13:38:08 2015 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/GregCr/code/SX1276Lib/#04374b1c33fa
+http://mbed.org/users/GregCr/code/SX1276Lib/#d447f8d2d2d6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debug.cpp	Tue Mar 31 13:38:08 2015 +0000
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2014-2015 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    IBM Zurich Research Lab - initial API, implementation and documentation
+ *    Semtech Apps Team       - Adapted for MBED
+ *******************************************************************************/
+#include <stdio.h>
+#include "lmic.h"
+#include "debug.h"
+
+void debug_init () {
+    // print banner
+    debug_str("\r\n============== DEBUG STARTED ==============\r\n");
+}
+
+void debug_led (u1_t val) {
+    debug_val( "LED = ", val );
+}
+
+void debug_char (u1_t c) {
+    fprintf(stderr, "%c", c );
+}
+
+void debug_hex (u1_t b) {
+    fprintf(stderr, "%02X", b );
+}
+
+void debug_buf (const u1_t* buf, u2_t len) {
+    while( len-- ) {
+        debug_hex( *buf++ );
+        debug_char( ' ' );
+    }
+    debug_char( '\r' );
+    debug_char( '\n' );
+}
+
+void debug_uint (u4_t v) {
+    for( s1_t n = 24; n >= 0; n -= 8 ) {
+        debug_hex( v >> n );
+    }
+}
+
+void debug_str (const u1_t* str) {
+    while( *str ) {
+        debug_char( *str++ );
+    }
+}
+
+void debug_val (const u1_t* label, u4_t val) {
+    debug_str( label );
+    debug_uint( val );
+    debug_char( '\r' );
+    debug_char( '\n' );
+}
+
+void debug_event (int ev) {
+    static const u1_t* evnames[] = {
+        [EV_SCAN_TIMEOUT]   = "SCAN_TIMEOUT",
+        [EV_BEACON_FOUND]   = "BEACON_FOUND",
+        [EV_BEACON_MISSED]  = "BEACON_MISSED",
+        [EV_BEACON_TRACKED] = "BEACON_TRACKED",
+        [EV_JOINING]        = "JOINING",
+        [EV_JOINED]         = "JOINED",
+        [EV_RFU1]           = "RFU1",
+        [EV_JOIN_FAILED]    = "JOIN_FAILED",
+        [EV_REJOIN_FAILED]  = "REJOIN_FAILED",
+        [EV_TXCOMPLETE]     = "TXCOMPLETE",
+        [EV_LOST_TSYNC]     = "LOST_TSYNC",
+        [EV_RESET]          = "RESET",
+        [EV_RXCOMPLETE]     = "RXCOMPLETE",
+        [EV_LINK_DEAD]      = "LINK_DEAD",
+        [EV_LINK_ALIVE]     = "LINK_ALIVE",
+    };
+    debug_str(evnames[ev]);
+    debug_char('\r');
+    debug_char('\n');
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debug.h	Tue Mar 31 13:38:08 2015 +0000
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2014-2015 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    IBM Zurich Research Lab - initial API, implementation and documentation
+ *    Semtech Apps Team       - Adapted for MBED
+ *******************************************************************************/
+#ifndef _debug_hpp_
+#define _debug_hpp_
+
+// intialize debug library
+void debug_init (void);
+
+// set LED state
+void debug_led (u1_t val);
+
+// write character to USART
+void debug_char (u1_t c);
+
+// write byte as two hex digits to USART
+void debug_hex (u1_t b);
+
+// write buffer as hex dump to USART
+void debug_buf (const u1_t* buf, u2_t len);
+
+// write 32-bit integer as eight hex digits to USART
+void debug_uint (u4_t v);
+
+// write nul-terminated string to USART
+void debug_str (const u1_t* str);
+
+// write LMiC event name to USART
+void debug_event (int ev);
+
+// write label and 32-bit value as hex to USART
+void debug_val (const u1_t* label, u4_t val);
+
+#endif // _debug_hpp_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hal.cpp	Tue Mar 31 13:38:08 2015 +0000
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    IBM Zurich Research Lab - initial API, implementation and documentation
+ *    Semtech Apps Team       - Modified to support the MBED sx1276 driver
+ *                              library.
+ *                              Possibility to use original or Semtech's MBED
+ *                              radio driver. The selection is done by setting
+ *                              USE_SMTC_RADIO_DRIVER preprocessing directive
+ *                              in lmic.h
+ *******************************************************************************/
+#include "mbed.h"
+#include "lmic.h"
+#include "mbed_debug.h"
+
+#if !USE_SMTC_RADIO_DRIVER
+
+extern void radio_irq_handler( u1_t dio );
+
+static DigitalOut nss( D10 );
+static SPI spi( D11, D12, D13 ); // ( mosi, miso, sclk )
+ 
+static DigitalInOut rst( A0 );
+static DigitalOut rxtx( A4 );
+ 
+static InterruptIn dio0( D2 );
+static InterruptIn dio1( D3 );
+static InterruptIn dio2( D4 ); 
+
+static void dio0Irq( void ) {
+    radio_irq_handler( 0 );
+}
+
+static void dio1Irq( void ) {
+    radio_irq_handler( 1 );
+}
+
+static void dio2Irq( void ) {
+    radio_irq_handler( 2 );
+}
+
+#endif
+
+static u1_t irqlevel = 0;
+static u4_t ticks = 0;
+
+static Timer timer;
+static Ticker ticker;
+
+static void reset_timer( void ) {
+    ticks += timer.read_us( ) >> 6;
+    timer.reset( );
+}
+
+void hal_init( void ) {
+     __disable_irq( );
+     irqlevel = 0;
+
+#if !USE_SMTC_RADIO_DRIVER
+    // configure input lines
+    dio0.mode( PullDown );
+    dio0.rise( dio0Irq );
+    dio0.enable_irq( );
+    dio1.mode( PullDown );   
+    dio1.rise( dio1Irq );
+    dio1.enable_irq( );
+    dio2.mode( PullDown );
+    dio2.rise( dio2Irq );
+    dio2.enable_irq( );
+    // configure reset line
+    rst.input( );
+    // configure spi
+    spi.frequency( 8000000 );
+    spi.format( 8, 0 );
+    nss = 1;
+#endif
+    // configure timer
+    timer.start( );
+    ticker.attach_us( reset_timer, 10000000 ); // reset timer every 10sec
+     __enable_irq( );
+}
+
+#if !USE_SMTC_RADIO_DRIVER
+
+void hal_pin_rxtx( u1_t val ) {
+    rxtx = !val;
+}
+
+void hal_pin_nss( u1_t val ) {
+    nss = val;
+}
+
+void hal_pin_rst( u1_t val ) {
+    if( val == 0 || val == 1 )
+    { // drive pin
+        rst.output( );
+        rst = val;
+    } 
+    else
+    { // keep pin floating
+        rst.input( );
+    }
+}
+
+u1_t hal_spi( u1_t out ) {
+    return spi.write( out );
+}
+
+#endif
+
+void hal_disableIRQs( void ) {
+    __disable_irq( );
+    irqlevel++;
+}
+
+void hal_enableIRQs( void ) {
+    if( --irqlevel == 0 )
+    {
+        __enable_irq( );
+    }
+}
+
+void hal_sleep( void ) {
+    // NOP
+}
+
+u4_t hal_ticks( void ) {
+    hal_disableIRQs( );
+    int t = ticks + ( timer.read_us( ) >> 6 );
+    hal_enableIRQs( );
+    return t;
+}
+
+static u2_t deltaticks( u4_t time ) {
+    u4_t t = hal_ticks( );
+    s4_t d = time - t;
+    if( d <= 0 ) {
+        return 0;    // in the past
+    }
+    if( ( d >> 16 ) != 0 ) {
+        return 0xFFFF; // far ahead
+    }
+    return ( u2_t )d;
+}
+
+void hal_waitUntil( u4_t time ) {
+    while( deltaticks( time ) != 0 ); // busy wait until timestamp is reached
+}
+
+u1_t hal_checkTimer( u4_t time ) {
+    return ( deltaticks( time ) < 2 );
+}
+
+void hal_failed( void ) {
+    while( 1 );
+}
--- a/main.cpp	Thu Jan 22 13:02:55 2015 +0000
+++ b/main.cpp	Tue Mar 31 13:38:08 2015 +0000
@@ -4,15 +4,18 @@
  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
  _____) ) ____| | | || |_| ____( (___| | | |
 (______/|_____)_|_|_| \__)_____)\____)_| |_|
-    (C)2013 Semtech
+    (C)2015 Semtech
 
-Description: MBED example application
+Description: MBED LoRaWAN 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 "debug.h"
 
 /*!
  * When set to 1 the application uses the Over-the-Air activation procedure
@@ -20,16 +23,60 @@
  */
 #define OVER_THE_AIR_ACTIVATION                     0
 
-#define APP_DATA_SIZE                               1
+#if( OVER_THE_AIR_ACTIVATION == 0 )
+
+/*!
+ * Defines the network ID when using personalization activation procedure
+ */
+#define LORAWAN_NET_ID                              ( uint32_t )0x00000000
+
+/*!
+ * Defines the device address when using personalization activation procedure
+ */
+#define LORAWAN_DEV_ADDR                            ( uint32_t )0x12345678
+
+#endif
+
+/*!
+ * Defines the application data transmission duty cycle
+ */
+#define APP_TX_DUTYCYCLE                            5000 // 5 [s] value in ms
+#define APP_TX_DUTYCYCLE_RND                        1000 // 1 [s] value in ms
+
+/*!
+ * LoRaWAN Adaptative Data Rate
+ */
+#define LORAWAN_ADR_ON                              1
+
+/*!
+ * LoRaWAN confirmed messages
+ */
+#define LORAWAN_CONFIRMED_MSG_ON                    1
+
+/*!
+ * LoRaWAN application port
+ */
+#define LORAWAN_APP_PORT                            15
+
+/*!
+ * User application data buffer size
+ */
+#if ( LORAWAN_CONFIRMED_MSG_ON == 1 )
+#define LORAWAN_APP_DATA_SIZE                       6
+
+#else
+#define LORAWAN_APP_DATA_SIZE                       1
+
+#endif
 
 //////////////////////////////////////////////////
 // CONFIGURATION (FOR APPLICATION CALLBACKS BELOW)
 //////////////////////////////////////////////////
 
 // application router ID (LSBF)
-static const u1_t AppEui[8] =
+static const uint8_t AppEui[8] =
 {
-    0xAA, 0xCC, 0x11, 0x00, 0xCC, 0xEE, 0x77, 0xEE
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
 
 // unique device ID (LSBF)
@@ -39,49 +86,70 @@
 };
 
 // device-specific AES key (derived from device EUI)
-static const u1_t DevKey[16] =
+static const uint8_t DevKey[16] = 
 {
-    0xAB, 0x89, 0xEF, 0xCD, 0x23, 0x01, 0x67, 0x45,
-    0x54, 0x76, 0x10, 0x32, 0xDC, 0xFE, 0x98, 0xBA
+    0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
+    0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
 };
 
+#if( OVER_THE_AIR_ACTIVATION == 0 )
+// network session key
 static uint8_t NwkSKey[] = 
 { 
     0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
     0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
 };
 
+// application session key
 static uint8_t ArtSKey[] = 
 { 
     0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
     0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
 };
 
+#endif
+
 // LEDs and Frame jobs
 osjob_t rxLedJob;
 osjob_t txLedJob;
 osjob_t sendFrameJob;
 
+// LED state
 static bool AppLedStateOn = false;
 
 //////////////////////////////////////////////////
+// Utility functions
+//////////////////////////////////////////////////
+/*!
+ * \brief Computes a random number between min and max
+ *
+ * \param [IN] min range minimum value
+ * \param [IN] max range maximum value
+ * \retval random random value in range min..max
+ */
+int32_t randr( int32_t min, int32_t max )
+{
+    return ( int32_t )rand( ) % ( max - min + 1 ) + min;
+}
+
+//////////////////////////////////////////////////
 // APPLICATION CALLBACKS
 //////////////////////////////////////////////////
 
 // provide application router ID (8 bytes, LSBF)
-void os_getArtEui( u1_t* buf )
+void os_getArtEui( uint8_t *buf )
 {
     memcpy( buf, AppEui, 8 );
 }
 
 // provide device ID (8 bytes, LSBF)
-void os_getDevEui( u1_t* buf )
+void os_getDevEui( uint8_t *buf )
 {
     memcpy( buf, DevEui, 8 );
 }
 
 // provide device key (16 bytes)
-void os_getDevKey( u1_t* buf )
+void os_getDevKey( uint8_t *buf )
 {
     memcpy( buf, DevKey, 16 );
 }
@@ -90,35 +158,26 @@
 // MAIN - INITIALIZATION AND STARTUP
 //////////////////////////////////////////////////
 
-// Initialization job
-static void onInit( osjob_t* j )
-{
-    // reset MAC state
-    LMIC_reset( );
-    LMIC_setAdrMode( 1 );
-    LMIC_setDrTxpow( DR_FSK, 14 );
-    // start joining
-#if( OVER_THE_AIR_ACTIVATION != 0 )
-    LMIC_startJoining( );
-#else    
-    LMIC_startABP( 0, 0x44332211, NwkSKey, ArtSKey );
-#endif
-    // init done - onEvent() callback will be invoked...
-}
-
 static void onRxLed( osjob_t* j )
 {
-    DEBUG_VAL("LED2 = ", 1 );
+    debug_val("LED2 = ", 0 );
 }
 
 static void onTxLed( osjob_t* j )
 {
-    DEBUG_VAL("LED1 = ", 1 );
+    debug_val("LED1 = ", 0 );
 }
 
 static void prepareTxFrame( void )
 {
     LMIC.frame[0] = AppLedStateOn;
+#if ( LORAWAN_CONFIRMED_MSG_ON == 1 )
+    LMIC.frame[1] = LMIC.seqnoDn >> 8;
+    LMIC.frame[2] = LMIC.seqnoDn;
+    LMIC.frame[3] = LMIC.rssi >> 8;
+    LMIC.frame[4] = LMIC.rssi;
+    LMIC.frame[5] = LMIC.snr;
+#endif    
 }
 
 void processRxFrame( void )
@@ -130,7 +189,7 @@
             if( LMIC.dataLen == 1 )
             {
                 AppLedStateOn = LMIC.frame[LMIC.dataBeg] & 0x01;
-                DEBUG_VAL( "LED3 = ", AppLedStateOn ? 0 : 1 );
+                debug_val( "LED3 = ", AppLedStateOn );
             }
             break;
         default:
@@ -141,10 +200,32 @@
 static void onSendFrame( osjob_t* j )
 {
     prepareTxFrame( );
-    LMIC_setTxData2( 1, LMIC.frame, APP_DATA_SIZE, 1 );
+    LMIC_setTxData2( LORAWAN_APP_PORT, LMIC.frame, LORAWAN_APP_DATA_SIZE, LORAWAN_CONFIRMED_MSG_ON );
+
+    // Blink Tx LED
+    debug_val( "LED1 = ", 1 );
+    os_setTimedCallback( &txLedJob, os_getTime( ) + ms2osticks( 25 ), onTxLed );
 }
 
-int main(void)
+// Initialization job
+static void onInit( osjob_t* j )
+{
+    // reset MAC state
+    LMIC_reset( );
+    LMIC_setAdrMode( LORAWAN_ADR_ON );
+    LMIC_setDrTxpow( DR_SF12, 14 );
+
+    // start joining
+#if( OVER_THE_AIR_ACTIVATION != 0 )
+    LMIC_startJoining( );
+#else
+    LMIC_setSession( LORAWAN_NET_ID, LORAWAN_DEV_ADDR, NwkSKey, ArtSKey );
+    onSendFrame( NULL );
+#endif
+    // init done - onEvent( ) callback will be invoked...
+}
+
+int main( void )
 {
     osjob_t initjob;
 
@@ -163,27 +244,27 @@
 void onEvent( ev_t ev )
 {
     bool txOn = false;
-
-    DEBUG_EVENT( ev );
+    debug_event( ev );
 
     switch( ev ) 
     {
     // network joined, session established
     case EV_JOINED:
-        DEBUG_VAL( "Net ID = ", LMIC.netid );
+        debug_val( "Net ID = ", LMIC.netid );
         txOn = true;
         break;
     // scheduled data sent (optionally data received)
     case EV_TXCOMPLETE:
+        debug_val( "Datarate = ", LMIC.datarate );
         // Check if we have a downlink on either Rx1 or Rx2 windows
-        if( ( LMIC.txrxFlags & ( TXRX_DNW1 | TXRX_DNW2 ) )!= 0 )
+        if( ( LMIC.txrxFlags & ( TXRX_DNW1 | TXRX_DNW2 ) ) != 0 )
         {
-            DEBUG_VAL( "LED2 = ", 0 );
-            os_setTimedCallback( &rxLedJob, os_getTime( ) + ms2osticks( 15 ), onRxLed );
+            debug_val( "LED2 = ", 1 );
+            os_setTimedCallback( &rxLedJob, os_getTime( ) + ms2osticks( 25 ), onRxLed );
 
-            if( LMIC.dataLen != 0 ) 
+            if( LMIC.dataLen != 0 )
             { // data received in rx slot after tx
-                DEBUG_BUF( LMIC.frame + LMIC.dataBeg, LMIC.dataLen );
+                debug_buf( LMIC.frame + LMIC.dataBeg, LMIC.dataLen );
                 processRxFrame( );
             }
         }
@@ -194,11 +275,12 @@
     }
     if( txOn == true )
     {
-        //os_setTimedCallback( &sendFrameJob, os_getTime( ) + sec2osticks( 5 ), onSendFrame );
-        onSendFrame( NULL );
+        //Sends frame every APP_TX_DUTYCYCLE +/- APP_TX_DUTYCYCLE_RND random time (if not duty cycle limited)
+        os_setTimedCallback( &sendFrameJob,
+                             os_getTime( ) + ms2osticks( APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ) ),
+                             onSendFrame );
         
-        // Blink Tx LED
-        DEBUG_VAL( "LED1 = ", 0 );
-        os_setTimedCallback( &txLedJob, os_getTime( ) + ms2osticks( 25 ), onTxLed );
+        ////Sends frame as soon as possible (duty cylce limitations)
+        //onSendFrame( NULL );
     }
 }
--- a/mbed.bld	Thu Jan 22 13:02:55 2015 +0000
+++ b/mbed.bld	Tue Mar 31 13:38:08 2015 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/4fc01daae5a5
\ No newline at end of file
+http://mbed.org/users/mbed_official/code/mbed/builds/487b796308b0
\ No newline at end of file