Andriy Makukha / Mbed 2 deprecated football_project_wo_output

Dependencies:   mbed

Fork of football_project by MZJ

Revision:
67:5650f461722a
Parent:
65:7addf8506bdb
Child:
68:0c96bb3d73a7
--- a/Radio.cpp	Tue Jan 19 07:25:15 2016 +0000
+++ b/Radio.cpp	Thu Feb 11 17:47:28 2016 +0000
@@ -3,6 +3,7 @@
 #include "types.h"
 #include "TA.h"
 #include "DataStore.hh"
+#include "Radio.hh"
 
 #define RADIO_STARTUP_ID 99
 #define NETWORKID     101   //the same on all nodes that talk to each other
@@ -11,7 +12,6 @@
 
 //#define IS_RFM69HW   //NOTE: uncomment this ONLY for RFM69HW or RFM69HCW
 #define ENCRYPT_KEY    "EncryptKey123456"  // use same 16byte encryption key for all devices on net
-#define ACK_TIME       50                  // max msec for ACK wait
 #define LED            9                   // Anardino miniWireless has LEDs on D9
 #define SERIAL_BAUD    115200
 #define VERSION  "1.0"
@@ -23,7 +23,6 @@
 RFM69 radio(P0_24,P0_23,P0_25,P0_28,P0_7);
 
 static bool promiscuousMode = true; // set 'true' to sniff all packets on the same network
-extern "C" void writeToPhone(char *format, ...);
 extern unsigned long millis();
 
 extern bool is_master;
@@ -40,6 +39,12 @@
     int mac;    
 };
 
+struct prev_message  // maybe TODO we could have an array of NUM_CONES of these.
+{
+    Message m;
+    uint8_t msgid;
+};
+
 /*
 int get_node_id()
 {
@@ -47,7 +52,7 @@
 }
 */
 
-static node_id_mapping nodes[10] = {0};
+static node_id_mapping nodes[NUM_CONES] = {0};
 static int node_idx = 0;
 static int my_mac = 0;
 
@@ -92,6 +97,7 @@
         if( Dbg )  writeToPhone("NID: %d\r\n", datastore_node_id());
         
         // Now reset the radio :)
+    /// promiscuousMode = false;
         radio_init();
     }
 }
@@ -132,7 +138,7 @@
             node_id = node_found;    
         }
         
-        // Send the cone it's ID
+        // Send the cone its ID
         extended_message em;
         em.m.cone    = 99;
         em.m.command = 'R';
@@ -150,14 +156,15 @@
         payload[7] = (byte)(em.mac >> 8);
         payload[6] = (byte)(em.mac >> 16);
         payload[5] = (byte)(em.mac >> 24);
-        
-        radio.send(em.m.cone, payload, sizeof(payload));
+
+        radio.send( em.m.cone, payload, sizeof(payload), false );  //// NO ACK req.
+    /// radio.send(em.m.cone, payload, sizeof(payload));
         
         if( Dbg )  writeToPhone("SND: %d %d 0x%x\r\n", em.m.cone, node_id, em.mac);
     }
 }
 
-void radio_send(Message *m)
+void radio_send( Message *m, bool requestACK )  ////
 {
     static byte payload [6] = {0};
  
@@ -165,7 +172,7 @@
     {
         return;    
     }
-    
+
     //if( Dbg )  writeToPhone("SM: %c to: %d frm: %d (%d)\r\n", m->command, m->cone, NODE_ID, m->value);
 
     payload[0] = (byte)m->command;
@@ -174,10 +181,19 @@
     payload[3] = (byte)(m->value >> 8);
     payload[2] = (byte)(m->value >> 16);
     payload[1] = (byte)(m->value >> 24);
-    
-    payload[5] = (byte)'%';
- 
-    radio.send(m->cone, payload, sizeof(payload));     
+
+    payload[5] = (byte)++TA::msg_id;  //// Msg ID,  was: = (byte)'%';
+
+    radio.send( m->cone, payload, sizeof(payload), requestACK );  ////
+}
+
+void stompage_check()
+{
+    if( --radio.INCNT != 0 )
+    {
+        writeToPhone( "LOST MSGS: %d\r\n", radio.INCNT );
+        radio.INCNT = 0;
+    }
 }
 
 bool radio_receive_complete()
@@ -187,71 +203,128 @@
 
 bool radio_receive(Message *m)
 {
+   bool retval = false;
+
+   //// For msg id feature...
+   static prev_message mPrev;
+   static long    lastMsgAt = millis();
+
     Message lm;
     extended_message em;
-    
-    if (m == NULL)
+
+    do
     {
-        return false;    
-    }
-    
-    if (radio.receiveDone())
-    {   
-        if (radio.DATALEN < 6)
-        {
-            return false;    
-        }
-        
-        lm.cone     = radio.SENDERID;
-        lm.command  = radio.DATA[0];
+      if( m == NULL )  break;
+
+      if (radio.receiveDone())
+      {
+          if( radio.TARGETID == datastore_node_id() )  //// Check for stompage...
+          {
+              stompage_check();
+
+              if( radio.ACK_RECEIVED )
+              {
+                  // We've received an ACK between retries.
+                  retval = true;
+                  break;
+              }
+          }
+          if( !get_crc_ok() )  // CRC error will be rechecked/sent from caller.
+          {
+              retval = true;
+              break;
+          }
+          if( radio.DATALEN < 6 )
+          {
+              RA_DEBUG( "Warn: Short packet\r\n" );
+              RA_DEBUG( "Warn: Data len %d\r\n", radio.DATALEN );
+              RA_DEBUG( "Warn: Cmd %c, Frm %d\r\n", radio.DATA[0], radio.SENDERID );
+              break;
+          }
+
+          lm.cone     = radio.SENDERID;
+          lm.command  = radio.DATA[0];
+
+          lm.value    = ((int)radio.DATA[1] << 24);
+          lm.value   |= ((int)radio.DATA[2] << 16);
+          lm.value   |= (((int)radio.DATA[3]) << 8);
+          lm.value   |= (radio.DATA[4]);
+
+          if (is_master && lm.command == 'S')
+          {
+              // Don't pass on radio startup messages
+              master_process(&lm);
+              break;
+          }
+          else if (!is_master && (NODE_ID == 99) && radio.TARGETID == RADIO_STARTUP_ID)  //// NODE_ID check allows not using auto node IDs
+          {
+              em.mac  = (int)radio.DATA[8] & 0xff;
+              em.mac |= (int)radio.DATA[7] << 8;
+              em.mac |= (int)radio.DATA[6] << 16;
+              em.mac |= (int)radio.DATA[5] << 24;
             
-        lm.value    = ((int)radio.DATA[1] << 24);
-        lm.value   |= ((int)radio.DATA[2] << 16);
-        lm.value   |= (((int)radio.DATA[3]) << 8);
-        lm.value   |= (radio.DATA[4]);
-        
-        if (is_master && lm.command == 'S')
-        {
-            // Don't pass on radio startup messages
-            master_process(&lm);    
-            return false;
-        }
-        else if (!is_master && radio.TARGETID == RADIO_STARTUP_ID)
-        {
+              if( Dbg )  writeToPhone("RP: 0x%x\r\n", em.mac);
             
-            em.mac  = (int)radio.DATA[8] & 0xff;
-            em.mac |= (int)radio.DATA[7] << 8;
-            em.mac |= (int)radio.DATA[6] << 16;
-            em.mac |= (int)radio.DATA[5] << 24;
-            
-            if( Dbg )  writeToPhone("RP: 0x%x\r\n", em.mac);
+              if (em.mac != my_mac)
+              {
+                  if( Dbg )  writeToPhone("DM 0x%x\r\n", em.mac);
+                  break; // This message was meant for someone else
+              }
             
-            if (em.mac != my_mac)
-            {
-                if( Dbg )  writeToPhone("DM 0x%x\r\n", em.mac);
-                return false; // This message was meant for someone else
-            }
-            
-            memcpy(&em.m, &lm, sizeof(Message));
-            slave_process(&em);    
-            
-        }
-        else if (radio.TARGETID == datastore_node_id())
-        {
-            memcpy(m, &lm, sizeof(Message));
-            
-            if( Dbg )  writeToPhone("GM: %d %c %d\r\n", radio.SENDERID, m->command, m->value);
+              memcpy(&em.m, &lm, sizeof(Message));
+              slave_process(&em);                
+          }
+          else if (radio.TARGETID == datastore_node_id())
+          {
+              memcpy(m, &lm, sizeof(Message));
+
+              //// Check if sender missed an ACK (Got duplicate of last msg, so ignore dup.)
+              if( (millis() -lastMsgAt < 100) &&    //// Only consider as dup if w/in 100ms of prev.
+                  (mPrev.m.cone == m->cone)   &&
+                  (mPrev.msgid  == radio.DATA[5]) )
+              {                                     ////  ASS-U-ME [for now] last msg is from same cone.
+                  RA_DEBUG( "Ignored dup cmd\r\n" );
+                  radio_send_ack();
+                  break;
+              }
 
-            return true;
-        }
+              memcpy( &mPrev.m, m, sizeof( Message ) );  ////
+              mPrev.msgid = radio.DATA[5];               ////
+              lastMsgAt = millis();                      ////
+
+              if( Dbg )  writeToPhone("GM: %d %c %d\r\n", radio.SENDERID, m->command, m->value);
+              retval = true;
+          }
+      }
+
+    } while( false );
+
+    if( retval )
+    {
+        if( get_crc_ok() )
+          RA_DEBUG( "M: %c %d  r:%d\r\n", m->command, m->value, get_rssi() );
+        if( get_fifo_ov() )
+          RA_DEBUG( "Radio FIFO Overflow\r\n" );
     }
-    
-    return false;
+
+    return  retval;
 }
 
-bool radio_ack_received(int cone)
+void radio_send_ack()  ////
+{
+    radio.sendACK( "K", 1 );
+}
+
+bool radio_ack_received( int cone )
 {
-    return radio.ACKReceived(cone);
+    bool retval = radio.ACKReceived(cone);
+
+    if( retval && (radio.TARGETID == datastore_node_id()) )
+    {
+        stompage_check();
+    }
+
+    return  retval;
 }
 
 /* This is only needed for the slave cones, the master
@@ -270,14 +343,14 @@
     
     if (my_mac == 0)
     {
-        my_mac = mac;    
+        my_mac = mac;
     }
     
     if (is_master)
     {
         return; // Only needed for slave cones    
     }
-    
+
     if (datastore_node_id() != RADIO_STARTUP_ID && current - last_send > 1000L)
     {
         if( Dbg )  writeToPhone("NID: %d\r\n", datastore_node_id());
@@ -298,6 +371,30 @@
     
     last_send = current;
     
-    radio_send(&m);
+    radio_send( &m, false );  ////
+    /// radio_send(&m);
+}
+
+
+
+int16_t get_rssi()
+{
+    return  radio.RSSI;
 }
 
+bool    get_crc_ok()
+{
+    return  radio.CRCOK;
+}
+
+bool    get_fifo_ov()
+{
+    return  radio.FIFOV;
+}
+
+// for debugging
+void read_all_regs()
+{
+    radio.readAllRegs();
+}
+