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.
This commit is contained in:
Raphael Assenat 2016-11-02 21:46:52 -04:00
parent 1659d2d106
commit bbefc8203c
1 changed files with 6 additions and 15 deletions

21
main.c
View File

@ -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;