Andriy Makukha / Mbed 2 deprecated football_project_wo_output

Dependencies:   mbed

Fork of football_project by MZJ

Revision:
67:5650f461722a
Parent:
54:2878d62714d6
Child:
68:0c96bb3d73a7
diff -r 18c214707b0c -r 5650f461722a TA.cpp
--- a/TA.cpp	Tue Jan 19 07:25:15 2016 +0000
+++ b/TA.cpp	Thu Feb 11 17:47:28 2016 +0000
@@ -1,4 +1,5 @@
 #include "TA.h"
+#include "Radio.hh"
 
 #include <nrf51.h>
 #include <mbed.h>
@@ -21,25 +22,22 @@
 #else
 #define DEBUG(...) /* nothing */
 #endif /* #if NEED_CONSOLE_OUTPUT */
-extern "C" void writeToPhone(char *format, ...);
  
 
 extern unsigned long millis();
 extern unsigned long micros();
 extern int random(int numberone, int numbertwo);
 
-extern void radio_send(Message *m);
-extern bool radio_receive(Message *m);
-extern bool radio_ack_received(int cone);
-extern bool radio_receive_complete();
+uint8_t TA::msg_id = 0;  // Message ID which replaces '%' in radio send packet for duplicate message detection.
 
 ByteBuffer TA::send_buffer;
 ByteBuffer TA::receive_buffer;
 
+//// These are currently no longer used...
 uint8_t TA::node_id;//        1  //network ID used for this unit
 uint8_t TA::network_id;//    99  //network ID used for this network
 uint8_t TA::gateway_id;//     1  //the ID of the network controller
-uint8_t TA::ack_time;//      50  // # of ms to wait for an ack
+uint8_t TA::ack_time;     // 50  // # of ms to wait for an ack
 
 //encryption is OPTIONAL
 //to enable encryption you will need to:
@@ -56,6 +54,7 @@
 
 //neopixels_spi TA::neopixels;
 
+bool gotACK = false;  //// If we got an ACK between retrying attempts.
 
 unsigned long millis();
 
@@ -240,34 +239,157 @@
     return send_buffer.getSize();    
 }
 
-bool TA::send(Message *m)
+bool TA::send( Message *m ) //// Restored existing architecture to use buffer.
 {
-    send_immediate(m); 
-    return true;   
+  int s = (int)send_buffer.getCapacity() - (int)send_buffer.getSize();
+  //DEBUG( "buffer space: %d\r\n", s );
+  if( s < 7 )
+  {
+    DEBUG( "Warning, radio buffer overflow!" );
+    return  false;
+  }
+  //DEBUG( "queued" );
+  send_buffer.put(     (byte)m->command );
+  send_buffer.putLong( (long)m->value   );
+  send_buffer.put(     (byte)m->cone    );
+  send_buffer.put(     '%'              );
+ /*
+  DEBUG( "Sent: \r\n" );
+  DEBUG( "%d\r\n", m->cone );
+  DEBUG( "%c\r\n", (char)m->command );
+  DEBUG( "%d\r\n", m->value );
+  DEBUG( "%%\r\n" );
+  DEBUG( "\r\n" );
+
+  DEBUG( "Raw send:\r\n" );
+  DBITS( (byte)m->cone,        8 );  DEBUG( "\r\n" );
+  DBITS( (byte)m->command,     8 );  DEBUG( "\r\n" );
+  DBITS( (byte)(m->value>>24), 8 );  DEBUG( "\r\n" );
+  DBITS( (byte)(m->value>>16), 8 );  DEBUG( "\r\n" );
+  DBITS( (byte)(m->value>>8),  8 );  DEBUG( "\r\n" );
+  DBITS( (byte)m->value,       8 );  DEBUG( "\r\n" );
+  DBITS( '%',                  8 );  DEBUG( "\r\n" );
+ */
+ /*
+  DBITS( receive_buffer.peek(0), 8 );  DEBUG( "\r\n" ); //<-cone?
+  DBITS( send_buffer.peek(1),    8 );  DEBUG( "\r\n" ); //<-command
+  DBITS( send_buffer.peek(2),    8 );  DEBUG( "\r\n" ); // value byte4
+  DBITS( send_buffer.peek(3),    8 );  DEBUG( "\r\n" ); // value byte2
+  DBITS( send_buffer.peek(4),    8 );  DEBUG( "\r\n" ); // value byte1
+  DBITS( send_buffer.peek(5),    8 );  DEBUG( "\r\n" ); // value byte0 (lsb)
+  DBITS( send_buffer.peek(6),    8 );  DEBUG( "\r\n" ); //<-%
+ */
+  //DEBUG( "\r\n" );
+ /*
+  int i = 0;
+  DEBUG( "\r\n" );
+  DEBUG( "Sent\r\n" );
+  for( i=0; i<8; i++ ){  DBITS( send_buffer.peek(i), 8 );  DEBUG( "\r\n" );  }
+  DEBUG( "\r\n" );
+ */
+
+  return  true;
 }
 
-void TA::send_immediate(Message *m)
+void TA::send_immediate(Message *m)  //// Does not req. ACK.
 {
-    radio_send(m);
+    radio_send( m, false );
 }
 
-bool TA::sendRaw(uint8_t *message, uint8_t len, uint8_t cone)
+bool TA::sendRaw(uint8_t *message, uint8_t len, uint8_t cone)  //// Currently not used.
 {
     radio.send(cone, message, len);
     return true;    
 }
 
+// Restored existing architecture to use buffer.
 bool TA::recieve(Message *m)
 {
-    return radio_receive(m);
+ /*
+  if( receive_buffer.getSize() > 1 )
+  {
+    DEBUG( "buffer size is: %d\r\n", receive_buffer.getSize() );
+  }
+ */
+  if( receive_buffer.getSize() < 7 )  return  false;
+  int i = 0;
+  // DEBUG( "\r\n" );
+  // DEBUG( "Received\r\n" );
+  // for( i=0; i<8; i++ )  DBITS( receive_buffer.peek(i), 8 );
+  // DEBUG( "\r\n" );
+
+ /*
+  DEBUG( "%d\r\n", receive_buffer.peek(0) );
+  DEBUG( "%d\r\n", receive_buffer.peek(1) );
+  DEBUG( "%d\r\n", receive_buffer.peek(2) );
+  DEBUG( "%d\r\n", receive_buffer.peek(3) );
+  DEBUG( "%d\r\n", receive_buffer.peek(4) );
+  DEBUG( "%d\r\n", receive_buffer.peek(5) );
+ */
+  
+  //DEBUG( "%d\r\n", receive_buffer.getSize() );
+  while( (receive_buffer.getSize() > 7) && ((char)receive_buffer.peek(6) != '%') )  receive_buffer.get();
+  //DEBUG( "%d\r\n", receive_buffer.getSize() );
+
+  if( receive_buffer.getSize() > 6 )// && receive_buffer.peek(6) == '%')
+  {
+    //DEBUG( "\r\n" );
+   /*
+    DEBUG( "Received:\r\n" );
+    DBITS( receive_buffer.peek(0), 8 );  DEBUG( "\r\n" ); //<-cone?
+    DBITS( receive_buffer.peek(1), 8 );  DEBUG( "\r\n" ); //<-command
+    DBITS( receive_buffer.peek(2), 8 );  DEBUG( "\r\n" ); // value byte4
+    DBITS( receive_buffer.peek(3), 8 );  DEBUG( "\r\n" ); // value byte2
+    DBITS( receive_buffer.peek(4), 8 );  DEBUG( "\r\n" ); // value byte1
+    DBITS( receive_buffer.peek(5), 8 );  DEBUG( "\r\n" ); // value byte0 (lsb)
+    DBITS( receive_buffer.peek(6), 8 );  DEBUG( "\r\n" ); //<-%
+   */
+    m->cone    = receive_buffer.get();
+    m->command = receive_buffer.get();
+    m->value   = (uint32_t)receive_buffer.get();
+    m->value   = m->value << 8;
+    m->value  += (uint32_t)receive_buffer.get();
+    m->value   = m->value << 8;
+    m->value  += (uint32_t)receive_buffer.get();
+    m->value   = m->value << 8;
+    m->value  += (uint32_t)receive_buffer.get();
+
+ /*
+  DEBUG( "Raw receive:\r\n" );
+  DBITS( (byte)m->cone,        8 );  DEBUG( "\r\n" );
+  DBITS( (byte)m->command,     8 );  DEBUG( "\r\n" );
+  DBITS( (byte)(m->value>>24), 8 );  DEBUG( "\r\n" );
+  DBITS( (byte)(m->value>>16), 8 );  DEBUG( "\r\n" );
+  DBITS( (byte)(m->value>>8),  8 );  DEBUG( "\r\n" );
+  DBITS( (byte)m->value,       8 );  DEBUG( "\r\n" );
+  DBITS( '%',                  8 );  DEBUG( "\r\n" );
+ */
+
+   /*
+    DEBUG( "\r\n" );
+    DEBUG( "Received:\r\n" );
+    DEBUG( "%d\r\n", m->cone );
+    DEBUG( "%c\r\n", (char)m->command );
+    DEBUG( "%d\r\n", m->value );
+    DEBUG( "\r\n" );
+   */
+    return  true;
+
+  } else
+    {
+      DEBUG( "Bad Packet, size is: %d\r\n", receive_buffer.getSize() );
+      while( receive_buffer.getSize() )  DEBUG( "%c", (char)receive_buffer.get() );
+      DEBUG( "\r\n" );
+      return  false;
+    }
 }
 
-bool TA::waitForAck(int cone) 
+bool TA::waitForAck(int cone)  //// Currently not used.
 {
     long start = micros();
     long timeout = ack_time;// + random(0,2000);
   while (micros() - start < timeout){
-    if (radio_ack_received(cone)){
+    if( radio_ack_received( cone ) ){
       //Serial.println(millis() - now);
       return true;
     }
@@ -283,6 +405,8 @@
     cap_enable = 0;
 }
 
+#define MAXSENDTRIES  15
+
 void TA::spin(void)
 {
   static byte payload [6];
@@ -297,6 +421,8 @@
   static unsigned long random_wait_start = 0;
   static unsigned long mem_monitor_start = 0;
 
+  static Message m; ////
+
   static unsigned long last_touch = 0;
 
   if (last_touch == 0 || millis()-last_touch > 3000)
@@ -362,131 +488,192 @@
     }
   }
 
-#if 1  // Foo
-/*
-  if(!waiting_for_ack && radio_receive_complete())
+  gotACK = false;  ////
+  if( !waiting_for_ack && radio_receive( &m ) )  ////
   {
-    //if(radio.CRCPass())
+    if( get_crc_ok() )
     {
-      receive_buffer.put(radio.SENDERID);
-      
-      for(byte i = 0; i < radio.DATALEN; i++)
-      {
-        receive_buffer.put(radio.DATA[i]);
-      }
-    }
-    
-    if(radio.ACKRequested())
-    {
-      wait_ms(1300);
-      radio.sendACK();
-      //Serial.println(F("Sent ACK"));
-    }
+      if( radio.ACK_RECEIVED )  gotACK = true;  ////
+        else
+        {
+          receive_buffer.put( radio.SENDERID );
+
+          for( byte i=0; i < radio.DATALEN-1; i++ )
+          {
+            receive_buffer.put( radio.DATA[i] );
+          }
+          receive_buffer.put( '%' );
+         /*
+          DEBUG( "\r\n" );
+          DEBUG( "Recieved: \r\n" );
+          for( byte i=0; i < radio.DATALEN; i++ )
+          {
+            DBITS( radio.DATA[i], 8 );  DEBUG( "\r\n" );
+          }
+          DEBUG( "\r\n" );
+         */
+          if( radio.ACKRequested() )
+          {
+////           wait_us( 1300 );
+            radio_send_ack();
+            //DEBUG( "Sent ACK\r\n" );
+          }
+        }
+
+    } else writeToPhone( "BAD-CRC\r\n" );
   }
-  */
 
   //if(index > 4999 || waiting_for_ack){
-  if(waiting_for_ack){
-    //Serial.println(F("Waiting for ack"));
-    bool success = radio.ACKReceived(dest_cone);
-    if(success || send_tries > 15){
-      //Serial.print(F("dequeued: "));
-      //Serial.println((uint16_t)payload[1]<<8 + payload[2]);
+  if( waiting_for_ack )
+  {
+    //DEBUG( "Waiting for ack\r\n" );
+    bool success = radio_ack_received( dest_cone );
+    if( success || (send_tries > MAXSENDTRIES) )
+    {
+      //DEBUG( "dequeued: %u\r\n", (uint16_t)payload[1]<<8 + payload[2] );
       message_in_queue = false;
-      waiting_for_ack = false;
+      waiting_for_ack  = false;
       unsigned long t = micros() - ack_start;
-      //Serial.print(F("Received ACK, microseconds: "));
-      //Serial.println(t);
+      //DEBUG( "Received ACK, microseconds: %u\r\n", t );
       //ack_tries = 0;
- 
+      if( !success )
+      {
+        //// DEBUG( "Failed to deliver message to cone %d\r\n", dest_cone );
+        RA_DEBUG( "Fail msg to cone %d\r\n", dest_cone );  ////
+
+      } else
+        {
+          if( send_tries > 1 )
+          {
+           /*
+            DEBUG( "Sent message to cone %d, tries = %d\r\n", dest_cone, send_tries );
+           */
+            RA_DEBUG( "Rcvd ACK cone %d try %d, %uus\r\n", dest_cone, send_tries, t );
+
+          } else
+            {
+              RA_DEBUG( "Rcvd ACK, %uus\r\n", t );  ////
+            }
+        }
+
       message_in_queue = false;
-      send_tries = 0;
-      /*Serial.print(F("Sent "));
-    Serial.print((char)payload[0]);
-    Serial.print(F(", to cone "));
-    Serial.println(dest_cone);*/
-    }
-    else{
-      if(micros() - ack_start > 10000){
-    //Serial.println(F("no ACK"));
-    waiting_for_ack = false;
-    random_wait_start = micros();
-    random_wait = random(1500,3000);
-    /*if(send_tries > 15){
-      Serial.print(F("Failed to deliver message to cone "));
-      Serial.println(dest_cone);
-      message_in_queue = false;
-      send_tries = 0;
-      }*/
-    if(send_tries > 4) random_wait = random(3000,9000);
-    //Serial.print(F("Failed to deliver message, waiting "));
-    //Serial.println(random_wait);
-    //ack_tries = 0;
-    
-    /*if(send_tries%50 == 0){
-      Serial.print(send_tries);
-      Serial.println(F(" tries"));
-      }*/
+      send_tries       = 0;
+     /*
+      DEBUG( "Sent %c, to cone %d\r\n", (char)payload[0], dest_cone );
+     */
+
+    } else  // Still trying to get an ACK...
+      {
+        if( micros() - ack_start > 15000 /* 10000 */ )  ////
+        {
+          RA_DEBUG( "No ACK after 15ms\r\n" );
+          waiting_for_ack   = false;
+          random_wait_start = micros();
+          random_wait       = random( 1500, 3000 );
+         /*
+          if( send_tries > MAXSENDTRIES )
+          {
+            DEBUG( "Failed to deliver message to cone %d\r\n", dest_cone );
+            message_in_queue = false;
+            send_tries       = 0;
+          }
+         */
+          if( send_tries > 4 )  random_wait = random( 3000, 9000 );
+          //DEBUG( "Failed to deliver message, waiting %d\r\n", random_wait );
+          //ack_tries = 0;
+
+         /*
+          if( send_tries%50 == 0 )
+          {
+            DEBUG( "%d tries\r\n", send_tries );
+          }
+         */
+        }
       }
-    }
     // ack_tries++;
-  }
-  else if(message_in_queue && micros() - random_wait > random_wait_start){// && index%64 == 0){
-    requestACK = true;
-    //Serial.println(F("sending"));
-///    writeToPhone("Sending message to: %d\r\n", dest_cone);
-    radio.send(dest_cone, payload, 6, requestACK);
-    //Serial.println(F("sent"));
-    //Serial.print(F("Trying to send: "));
-    //uint16_t temp = (uint16_t)payload[1]<<8;
-    //temp += (uint8_t)payload[2];
-    //Serial.println((uint8_t)payload[0]);
-    send_tries++;
-    ack_start = micros();
-    if(!radio.ACKReceived(dest_cone)) waiting_for_ack = true; // the 'if' is here to prevent the radio from going to sleep and missing the ACK
-    else message_in_queue = false;
-  }
-  else {
-    /*if(send_buffer.getSize() > 0 && message_in_queue == false){
-      payload[0] = send_buffer.get();
-      //Serial.print(F("Got from queue: "));
-      //Serial.println((char)payload[0]);
-      message_in_queue = true;
-    }*/
-    while(send_buffer.getSize() > 4 && message_in_queue == false){
-      payload[0] = send_buffer.get();
-      payload[1] = send_buffer.get();
-      payload[2] = send_buffer.get();
-      payload[3] = send_buffer.get();
-      payload[4] = send_buffer.get();
-      dest_cone = send_buffer.get();
-      payload[5] = send_buffer.get();
-      /*Serial.println(F(""));
-      Serial.println(F("sending..."));
-      Serial.println(payload[0], BIN);
-      Serial.println(payload[1], BIN);
-      Serial.println(payload[2], BIN);
-      Serial.println(payload[3], BIN);
-      Serial.println(payload[4], BIN);
-      Serial.println(dest_cone, BIN);      
-      Serial.println(payload[5], BIN);
-      Serial.println(F(""));*/
-      if((char)payload[5] == '%')message_in_queue = true;
-      else {
-    //Serial.println(F("bad message format"));
-    while(send_buffer.getSize() > 0 && send_buffer.get() != '%'); // if we didn't land on the end of a message, peel stuff off until we are
+
+  } else if( message_in_queue && (micros() - random_wait > random_wait_start) )// && index%64 == 0)
+    { //// Continued from ack timeout in a previous spin()...
+      if( gotACK )  ////
+      {
+          message_in_queue = false;
+          send_tries       = 0;
+          RA_DEBUG( "Rcvd B ACK %uus\r\n", micros() -ack_start );  ////
+
+      } else
+        {
+            requestACK = true;
+            //DEBUG( "sending\r\n" );
+///          writeToPhone("Sending message to: %d\r\n", dest_cone);
+            radio.send( dest_cone, payload, 6, requestACK );
+            //DEBUG( "sent\r\n" );
+            //DEBUG( "Trying to send: %d\r\n", (uint8_t)payload[0] );
+            //uint16_t temp = (uint16_t)payload[1]<<8;
+            //temp += (uint8_t)payload[2];
+            send_tries++;
+            ack_start = micros();
+            if( !radio_receive_complete() /* !radio_ack_received( dest_cone ) */ ) // the 'if' is here to prevent the radio from going to sleep and missing the ACK
+            {
+                waiting_for_ack = true;  //// Check for ack on next spin()
+
+            } else  // Shouldn't happen.
+              {
+                  if( radio.ACK_RECEIVED )  message_in_queue = false;
+                  RA_DEBUG( "Rcvd Immed %uus\r\n", micros() -ack_start );  ////
+              }
+        }
+
+    } else
+      {
+       /*
+        if( (send_buffer.getSize() > 0) && !message_in_queue )
+        {
+          payload[0] = send_buffer.get();
+          //DEBUG( "Got from queue: %c\r\n", (char)payload[0] );
+          message_in_queue = true;
+        }
+       */
+        while( (send_buffer.getSize() > 4) && !message_in_queue )
+        {
+          payload[0] = send_buffer.get();
+          payload[1] = send_buffer.get();
+          payload[2] = send_buffer.get();
+          payload[3] = send_buffer.get();
+          payload[4] = send_buffer.get();
+          dest_cone  = send_buffer.get();
+          payload[5] = send_buffer.get();
+         /*
+          DEBUG( "\r\n" );
+          DEBUG( "sending...\r\n" );
+          DBITS( payload[0], 8 );  DEBUG( "\r\n" );
+          DBITS( payload[1], 8 );  DEBUG( "\r\n" );
+          DBITS( payload[2], 8 );  DEBUG( "\r\n" );
+          DBITS( payload[3], 8 );  DEBUG( "\r\n" );
+          DBITS( payload[4], 8 );  DEBUG( "\r\n" );
+          DBITS( dest_cone,  8 );  DEBUG( "\r\n" );
+          DBITS( payload[5], 8 );  DEBUG( "\r\n" );
+          DEBUG( "\r\n" );
+         */
+          if( (char)payload[5] == '%' )
+          {
+              message_in_queue = true;
+              payload[5] = ++msg_id;  //// Message ID used for duplicate message check.
+
+          } else
+            {
+              //DEBUG( "bad message format\r\n" );
+              while( (send_buffer.getSize() > 0) && (send_buffer.get() != '%') ) ; // if we didn't land on the end of a message, peel stuff off until we are
+            }
+        }
       }
-    }
-  }
-#endif  // Foo
 }
 
 bool TA::activated(void)
 {
-    bool retval = ((((buttons() | buttonsRising) & mask) ||
-                    /* Default to enabling activation on disabled--Except if mask has DIS_ON_DARK set */
-                    (!(mask & TOUCHLIGHTS) != !!(mask & DIS_ON_DARK))
-                   ) ? true : false);
+    /* Default to enabling activation on disabled--Except if mask has DIS_ON_DARK set */
+    uint8_t maskOrDark = ((!(mask & TOUCHLIGHTS) != !!(mask & DIS_ON_DARK)) ? TOUCHLIGHTS : mask);
+
+    bool retval = (((buttons() | buttonsRising) & maskOrDark) ? true : false);
 
     TA::buttonsRising = 0;
 
@@ -533,6 +720,16 @@
 
 void TA::initialize(uint8_t address)
 {
+  send_buffer.init(96); //48//64//128 is too big, seems to corrupt the data, WTF????
+  receive_buffer.init(96);
+
+  resetTouch();
+
+  ack_time = ACK_TIME;  //// Currently not used.
+
+  radio_init();
+
+  beep(50);
 }
 
 /* Can't find a way of implementing this function.