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 football_project by
Diff: TA.cpp
- 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.
