Пример #1
0
u32 InputWait() {
    static u64 delay = 0;
    u32 pad_state_old = HID_STATE;
    delay = (delay) ? 72 : 128;
    timer_start();
    while (true) {
        u32 pad_state = HID_STATE;
        if (!(pad_state & BUTTON_ANY)) { // no buttons pressed
            u32 special_key = i2cReadRegister(I2C_DEV_MCU, 0x10);
            if (special_key == 0x01)
                return pad_state | BUTTON_POWER;
            else if (special_key == 0x04)
                return pad_state | BUTTON_HOME;
            pad_state_old = pad_state;
            delay = 0;
            continue;
        }
        if ((pad_state == pad_state_old) &&
            (!(pad_state & BUTTON_ARROW) ||
            (delay && (timer_msec() < delay))))
            continue;
        // make sure the key is pressed
        u32 t_pressed = 0;
        for(; (t_pressed < 0x13000) && (pad_state == HID_STATE); t_pressed++);
        if (t_pressed >= 0x13000)
            return pad_state;
    }
}
Пример #2
0
bool uart_consume_timeout(uint8_t* buffer, uint16_t timeout) {
	timer_reset();
	while (uart_rx_start == uart_rx_end) {
		if (timer_msec() >= timeout) { return false; }
	}
	*buffer = uart_rx_buf[uart_rx_start];
	uart_rx_start = (uart_rx_start +1) % UART_RING_LEN;
	return true;
}
Пример #3
0
/**
 * 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;
}