bdk: input: make joycon detection more robust

There's a hw bug on the gpio controller that can latch the last value on reads.
Mitigate that by reading once to unlatch the input value.

Also actually allow sio to be polled every 8ms.
This commit is contained in:
CTCaer 2024-05-19 10:19:25 +03:00
parent 547a3542ee
commit 7af343dd6c

View file

@ -1,7 +1,7 @@
/* /*
* Joy-Con UART driver for Nintendo Switch * Joy-Con UART driver for Nintendo Switch
* *
* Copyright (c) 2019-2023 CTCaer * Copyright (c) 2019-2024 CTCaer
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@ -407,12 +407,16 @@ static void _jc_detect()
if (!jc_gamepad.sio_mode) if (!jc_gamepad.sio_mode)
{ {
// Turn on Joy-Con detect. (UARTB/C TX). UART CTS also if HW flow control and irq is enabled. // Turn on Joy-Con detect. (UARTB/C TX). UART CTS also if HW flow control and irq is enabled.
PINMUX_AUX(PINMUX_AUX_UART2_TX) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE; PINMUX_AUX(PINMUX_AUX_UART2_TX) = PINMUX_INPUT_ENABLE;
PINMUX_AUX(PINMUX_AUX_UART3_TX) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE; PINMUX_AUX(PINMUX_AUX_UART3_TX) = PINMUX_INPUT_ENABLE;
gpio_direction_input(GPIO_PORT_G, GPIO_PIN_0); gpio_direction_input(GPIO_PORT_G, GPIO_PIN_0);
gpio_direction_input(GPIO_PORT_D, GPIO_PIN_1); gpio_direction_input(GPIO_PORT_D, GPIO_PIN_1);
usleep(20); usleep(20);
//! HW BUG: Unlatch gpio buffer.
(void)gpio_read(GPIO_PORT_H, GPIO_PIN_6);
(void)gpio_read(GPIO_PORT_E, GPIO_PIN_6);
// Read H6/E6 which are shared with UART TX pins. // Read H6/E6 which are shared with UART TX pins.
jc_r.detected = !gpio_read(GPIO_PORT_H, GPIO_PIN_6); jc_r.detected = !gpio_read(GPIO_PORT_H, GPIO_PIN_6);
jc_l.detected = !gpio_read(GPIO_PORT_E, GPIO_PIN_6); jc_l.detected = !gpio_read(GPIO_PORT_E, GPIO_PIN_6);
@ -842,7 +846,7 @@ static void _jc_req_nx_pad_status(joycon_ctxt_t *jc)
else else
_joycon_send_raw(jc->uart, hori_pad_status, sizeof(hori_pad_status)); _joycon_send_raw(jc->uart, hori_pad_status, sizeof(hori_pad_status));
jc->last_status_req_time = get_tmr_ms() + 15; jc->last_status_req_time = get_tmr_ms() + (!jc->sio_mode ? 15 : 7);
} }
static bool _jc_validate_pairing_info(u8 *buf, bool *is_hos) static bool _jc_validate_pairing_info(u8 *buf, bool *is_hos)