James Coleman / lmic_MOTE_L152RC

Fork of lmic_MOTE_L152RC by Timothy Mulrooney

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;