From bbefc8203c778ff8794d5a6264f277313e354a0e Mon Sep 17 00:00:00 2001 From: Raphael Assenat Date: Wed, 2 Nov 2016 21:46:52 -0400 Subject: [PATCH] Prevent freeze if host only polls one endpoint Each joystick has its own interrupt endpoint, and the main loop used to wait until each became ready (i.e. Serviced) in turn. On some systems, when only one joystick is in use, only one endpoint is polled. The inactive endpoint therefore never became ready and the mainloop would freeze. Rewrote part of the loop to prevent this. New flow: 1) Wait until it is time to poll the controllers (based on current poll frequency setting) 2) Wait until either endpoints is ready. 3) Write data to first endpoint if ready, otherwise skip. 4) Write data to second endpoint if ready, otherwise skip. --- main.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/main.c b/main.c index dc97641..ff9c472 100644 --- a/main.c +++ b/main.c @@ -583,28 +583,19 @@ int main(void) break; case STATE_WAIT_INTERRUPT_READY: - if (usb_interruptReady_ep1()) { + /* Wait until one of the interrupt endpoint is ready */ + if (usb_interruptReady_ep1() || (num_players>1 && usb_interruptReady_ep3())) { state = STATE_TRANSMIT; } break; case STATE_TRANSMIT: - usb_interruptSend_ep1(usbpad_getReportBuffer(&usbpads[0]), usbpad_getReportSize()); - if (num_players > 1) { - state = STATE_WAIT_INTERRUPT_READY_P2; - } else { - state = STATE_WAIT_POLLTIME; + if (usb_interruptReady_ep1()) { + usb_interruptSend_ep1(usbpad_getReportBuffer(&usbpads[0]), usbpad_getReportSize()); } - break; - - case STATE_WAIT_INTERRUPT_READY_P2: - if (usb_interruptReady_ep3()) { - state = STATE_TRANSMIT_P2; + if (num_players>1 && usb_interruptReady_ep3()) { + usb_interruptSend_ep3(usbpad_getReportBuffer(&usbpads[1]), usbpad_getReportSize()); } - break; - - case STATE_TRANSMIT_P2: - usb_interruptSend_ep3(usbpad_getReportBuffer(&usbpads[1]), usbpad_getReportSize()); state = STATE_WAIT_POLLTIME; break;