void loop(){ if(uart_has_data()) { uart_receive_data(); data++; uart_send_data(); } }
/** * Play one round of the contention game. If neither side received the force_master flag, * they each wait a random amount of time before sending the ping packet. The first to acknowledge * the other side's ping is the slave. If the two packets conflict, the came ends in a conflict and * must be run again. * If after a timeout passes no token has been received, the device assumes that the pad has * been snapped and is disconnected from its twin. * @param usb_present gives the usb-connected side precedence if force_master is not set. */ ConnectionState uart_play_round(bool force_master, bool usb_present) { timer_reset(); uint16_t ms = 0; while (timer_msec() < 1) {} // let uarts settle if (!force_master) { hwrng_start(); timer_reset(); while (timer_msec() < 2) {} // wait 2 ms while (!hwrng_done()) {} // wait for random data to become available if (!usb_present) { ms = 3+(hwrng_bits()[0] & 0x3f); // additional delay of 3-67 ms } else { ms = 0; // skip additional delay on usb-connected end } } timer_reset(); while (timer_msec() < ms) { if (uart_has_data()) { uint8_t b = uart_consume(); if (b == UTOK_GAME_PING) { uart_send_byte(UTOK_GAME_ACK); return CS_TWINNED_SLAVE; } else if (b == UTOK_GAME_ACK) { return CS_TWINNED_COLLISION; } } } uart_send_byte(UTOK_GAME_PING); timer_reset(); ms = 1000 - ms; while (timer_msec() < ms) { if (uart_has_data()) { uint8_t b = uart_consume(); if (b == UTOK_GAME_ACK) { return CS_TWINNED_MASTER; } else if (b == UTOK_GAME_PING) { return CS_TWINNED_COLLISION; } } } return CS_SINGLE; }
void uart_factory_reset_confirm() { uart_send_byte(UTOK_RST_PROPOSE); while (1) { if (uart_has_data() && (uart_consume() == UTOK_RST_CONFIRM)) return; } }
void uart_receive_data(){ while(!uart_has_data()); data = UDR0;; }