Permalink
Browse files

finally got the timing right: USB end is always master in twinned boa…

…rds; breaking out code to make the whole shebang a little more readable.
  • Loading branch information...
phooky committed Mar 7, 2014
1 parent a8a9d14 commit 7ca4a475d11a069ba2b55a5c2f3ade54948b2efa
Showing with 79 additions and 40 deletions.
  1. +62 −21 code/SnapPadv1/main.c
  2. +17 −19 code/SnapPadv1/uarts.c
View
@@ -63,6 +63,11 @@ void process_usb();
ConnectionState cs;
+void do_factory_reset_mode();
+void do_twinned_master_mode();
+void do_twinned_slave_mode();
+void do_single_mode();
+
void main (void)
{
// Set up clocks/IOs. initPorts()/initClocks() will need to be customized
@@ -99,42 +104,55 @@ void main (void)
// First, scan the USB connection for ~100ms to see if the device is being enumerated.
bool usb_attached = false;
timer_reset();
- while (timer_msec() < 1000) {
+ while (timer_msec() < 600) {
uint8_t s = USB_connectionState();
- if (s == ST_ENUM_ACTIVE) {
+ if (s == ST_ENUM_ACTIVE || s == ST_ENUM_SUSPENDED) {
usb_attached = true;
break;
}
}
- cs = uart_determine_state(usb_attached);
-
+ cs = uart_determine_state(usb_attached || button_pressed_on_startup);
if (cs == CS_TWINNED_MASTER) {
if (button_pressed_on_startup) {
- // Don't bother entering the main loop; go directly to reset confirmation mode
- uint8_t i;
- // Alternating side slow blink: confirm reset
- for (i = 0; i < LED_COUNT; i++) leds_set_led(i,LED_SLOW_0);
- uart_factory_reset_confirm();
- // Alternating leds on board: reset in process
- for (i = 0; i < LED_COUNT; i++) leds_set_led(i,(i%2 == 0)?LED_FAST_0:LED_FAST_1);
- otp_factory_reset();
- // Lights off: reset done
- for (i = 0; i < LED_COUNT; i++) leds_set_led(i,LED_OFF);
- while (1){} // Loop forever
+ do_factory_reset_mode();
+ } else {
+ do_twinned_master_mode();
}
+ } else if (cs == CS_TWINNED_SLAVE) {
+ leds_set_led(0,0x55);
+ do_twinned_slave_mode();
+ } else if (cs == CS_SINGLE) {
+ leds_set_led(0,0xff);
+ //do_single_mode();
}
- if (cs != CS_SINGLE) {
- // Go ahead to attract mode
- leds_set_larson();
+}
+
+void do_single_mode() {
+ // Go ahead to attract mode
+ leds_set_larson();
+ while (1) // main loop
+ {
+ switch(USB_connectionState())
+ {
+ case ST_ENUM_ACTIVE:
+ process_usb();
+ break;
+ case ST_USB_DISCONNECTED: // physically disconnected from the host
+ case ST_ENUM_SUSPENDED: // connecte d/enumerated, but suspended
+ case ST_NOENUM_SUSPENDED: // connected, enum started, but the host is unresponsive
+ case ST_ENUM_IN_PROGRESS:
+ default:;
+ }
}
+}
+void do_twinned_master_mode() {
+ // Go ahead to attract mode
+ leds_set_larson();
while (1) // main loop
{
- if (cs == CS_TWINNED_SLAVE) {
- uart_process(); // process uart commands
- }
switch(USB_connectionState())
{
case ST_ENUM_ACTIVE:
@@ -149,6 +167,29 @@ void main (void)
}
}
+void do_twinned_slave_mode() {
+ // Go ahead to attract mode
+ //leds_set_larson();
+ while (1) // main loop
+ {
+ uart_process(); // process uart commands
+ }
+}
+
+void do_factory_reset_mode() {
+ // Don't bother entering the main loop; go directly to reset confirmation mode
+ uint8_t i;
+ // Alternating side slow blink: confirm reset
+ for (i = 0; i < LED_COUNT; i++) leds_set_led(i,LED_SLOW_0);
+ uart_factory_reset_confirm();
+ // Alternating leds on board: reset in process
+ for (i = 0; i < LED_COUNT; i++) leds_set_led(i,(i%2 == 0)?LED_FAST_0:LED_FAST_1);
+ otp_factory_reset();
+ // Lights off: reset done
+ for (i = 0; i < LED_COUNT; i++) leds_set_led(i,LED_OFF);
+ while (1){} // Loop forever
+}
+
char hex(uint8_t v) {
v &= 0x0f;
if (v < 10) return '0'+v;
View
@@ -10,6 +10,7 @@
#include "leds.h"
#include "hwrng.h"
#include "onetimepad.h"
+#include "timer.h"
#include <stdbool.h>
// Pins:
@@ -104,42 +105,39 @@ enum {
* been snapped and is disconnected from its twin.
*/
ConnectionState uart_play_round(bool force_master) {
- uint8_t remain = 100; // 100 ms total timeout
+ timer_reset();
uint16_t ms = 0;
- uart_clear_buf();
- __delay_cycles(8000); // allow uarts on both ends to come up
+ while (timer_msec() < 1) {} // let uarts settle
if (!force_master) {
hwrng_start();
- __delay_cycles(16000); // wait 2 ms
- while (!hwrng_done());
- ms = hwrng_bits()[0] & 0x3f; // wait up to 64 ms
- remain -= (ms + 2);
+ timer_reset(); while (timer_msec() < 2) {} // wait 2 ms
+ while (!hwrng_done()) {} // wait for random data to become available
+ ms = 2+(hwrng_bits()[0] & 0x3f); // additional delay of 2-66 ms
}
- // scale both timing numbers by a factor of 10 to reduce the chance of jabber condition
- // when force_master is asserted on one or both boards
- remain *= 10;
- ms *= 10;
- while (ms--) {
+ timer_reset();
+ while (timer_msec() < ms) {
if (uart_has_data()) {
- if (uart_consume() == UTOK_GAME_PING) {
+ uint8_t b = uart_consume();
+ if (b == UTOK_GAME_PING) {
UCA1TXBUF = UTOK_GAME_ACK;
return CS_TWINNED_SLAVE;
- } else {
+ } else if (b == UTOK_GAME_ACK) {
return CS_TWINNED_COLLISION;
}
}
- __delay_cycles(800);
}
UCA1TXBUF = UTOK_GAME_PING;
- while (remain--) {
+ timer_reset();
+ ms = 1000 - ms;
+ while (timer_msec() < ms) {
if (uart_has_data()) {
- if (uart_consume() == UTOK_GAME_ACK) {
+ uint8_t b = uart_consume();
+ if (b == UTOK_GAME_ACK) {
return CS_TWINNED_MASTER;
- } else {
+ } else if (b == UTOK_GAME_PING) {
return CS_TWINNED_COLLISION;
}
}
- __delay_cycles(800);
}
return CS_SINGLE;
}

0 comments on commit 7ca4a47

Please sign in to comment.