Browse Source

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.
pull/5/head
Raphael Assenat 6 years ago
parent
commit
bbefc8203c
  1. 21
      main.c

21
main.c

@ -583,28 +583,19 @@ int main(void) @@ -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;

Loading…
Cancel
Save