Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of lmic_MOTE_L152RC by
Diff: lmic.cpp
- Revision:
- 7:9095e54e381f
- Parent:
- 5:e4ba433f0ac1
- Child:
- 8:0faa1bb768b5
--- a/lmic.cpp	Sat Jul 18 00:18:44 2015 +0000
+++ b/lmic.cpp	Mon Sep 21 17:59:42 2015 +0000
@@ -731,11 +731,17 @@
 static void initDefaultChannels (void)
 {
 #ifdef CHNL_HYBRID
-        LMIC.channelMap[0] = 0xFF;
-        LMIC.channelMap[1] = 0x0;
-        LMIC.channelMap[2] = 0x0;
-        LMIC.channelMap[3] = 0x0;
-        LMIC.channelMap[4] = 0x01;
+        int idx = CHNL_HYBRID >> 1;
+        LMIC.channelMap[0] = 0x0000;
+        LMIC.channelMap[1] = 0x0000;
+        LMIC.channelMap[2] = 0x0000;
+        LMIC.channelMap[3] = 0x0000;
+        if (CHNL_HYBRID & 1)
+            LMIC.channelMap[idx] = 0xff00;
+        else
+            LMIC.channelMap[idx] = 0x00ff;
+            
+        LMIC.channelMap[4] = 1 << CHNL_HYBRID;
         LMIC.txpow_limit = 20;
 #else
     for( u1_t i=0; i<4; i++ )
@@ -809,29 +815,72 @@
     }
 }
 
+int count_bits(u2_t v)
+{
+    int c;
+    
+    for (c = 0; v; c++) {
+        v &= v - 1; // clear the last significant bit set
+    }
+
+    return c;
+}
+
 // US does not have duty cycling - return now as earliest TX time
 #define nextTx(now) (_nextTx(),(now))
 static void _nextTx (void) {
-    if( LMIC.chRnd==0 )
-        LMIC.chRnd = os_getRndU1() & 0x3F;
+    u1_t prev_ch = LMIC.txChnl;
+    u1_t tries = 0;
+    u1_t en_cnt;
+    
     if( LMIC.datarate >= DR_SF8C ) { // 500kHz
-        u1_t map = LMIC.channelMap[64/16]&0xFF;
-        for( u1_t i=0; i<8; i++ ) {
-            if( (map & (1<<(++LMIC.chRnd & 7))) != 0 ) {
-                LMIC.txChnl = 64 + (LMIC.chRnd & 7);
-                return;
-            }
-        }
+#ifdef CHNL_HYBRID
+        LMIC.txChnl = 1 << CHNL_HYBRID; // only one channel possible
+#else
+        en_cnt = count_bits(LMIC.channelMap[4]);
+        do {
+            do {
+                LMIC.chRnd = os_getRndU1() & 7;
+                if (++tries > 48)
+                    return;
+            } while ( !(LMIC.channelMap[4] & (1 << LMIC.chRnd)) );
+            LMIC.txChnl = 64 + LMIC.chRnd;
+            if (en_cnt < 2)
+                prev_ch = LMIC.txChnl + 1;  // not enough enabled, skip the following test
+                
+        } while (prev_ch == LMIC.txChnl);
+#endif
     } else { // 125kHz
-        for( u1_t i=0; i<64; i++ ) {
-            u1_t chnl = ++LMIC.chRnd & 0x3F;
-            if( (LMIC.channelMap[(chnl >> 4)] & (1<<(chnl & 0xF))) != 0 ) {
-                LMIC.txChnl = chnl;
-                return;
-            }
-        }
+#ifdef CHNL_HYBRID
+        u1_t idx = CHNL_HYBRID >> 1;
+        en_cnt = count_bits(LMIC.channelMap[idx]);
+        do {
+            do {
+                LMIC.chRnd = os_getRndU1() & 15;
+                if (++tries > 96)
+                    return;
+            } while ( !(LMIC.channelMap[idx] & (1 << LMIC.chRnd)) );
+            LMIC.txChnl = (idx << 4) + LMIC.chRnd;
+            if (en_cnt < 2)
+                prev_ch = LMIC.txChnl + 1;  // not enough enabled, skip the following test
+                            
+        } while (prev_ch == LMIC.txChnl);
+#else
+        en_cnt = count_bits(LMIC.channelMap[0]);
+        en_cnt += count_bits(LMIC.channelMap[1]);
+        en_cnt += count_bits(LMIC.channelMap[2]);
+        en_cnt += count_bits(LMIC.channelMap[3]);
+        do {
+            do {
+                LMIC.chRnd = os_getRndU1() & 63;
+            } while ( !(LMIC.channelMap[LMIC.chRnd >> 4] & (1 << (LMIC.chRnd & 15))) );
+            LMIC.txChnl = LMIC.chRnd;
+            if (en_cnt < 2)
+                prev_ch = LMIC.txChnl + 1;  // not enough enabled, skip the following test
+                
+        } while (prev_ch == LMIC.txChnl);
+#endif
     }
-    // No feasible channel  found! Keep old one.
 }
 
 static void setBcnRxParams (void) {
@@ -851,7 +900,7 @@
 
 static void initJoinLoop (void) {
     LMIC.chRnd = 0;
-    LMIC.txChnl = 0;
+    _nextTx();  //LMIC.txChnl = 0;
     LMIC.adrTxPow = 20;
     ASSERT((LMIC.opmode & OP_NEXTCHNL)==0);
     LMIC.txend = os_getTime();
@@ -865,10 +914,12 @@
     //
     u1_t failed = 0;
     if( LMIC.datarate != DR_SF8C ) {
-        LMIC.txChnl = 64+(LMIC.txChnl&7);
+        //LMIC._txChnl = 64+(LMIC.txChnl&7);
+        _nextTx();
         setDrJoin(DRCHG_SET, DR_SF8C);
     } else {
-        LMIC.txChnl = os_getRndU1() & 0x3F;
+        //LMIC._txChnl = os_getRndU1() & 0x3F;
+        _nextTx();
         s1_t dr = DR_SF7 - ++LMIC.txCnt;
         if( dr < DR_SF10 ) {
             dr = DR_SF10;
    