1
0
mirror of https://github.com/raphnet/gc_n64_usb-v3 synced 2024-12-21 23:08:53 -05:00

Implement main in state machine form

- Check if interrupt send would block
This commit is contained in:
Raphael Assenat 2015-10-17 17:44:14 -04:00
parent 7d8cf00a14
commit 5502bfd418

75
main.c
View File

@ -231,6 +231,7 @@ Gamepad *detectPad(void)
return NULL; return NULL;
} }
/* Called after eeprom content is loaded. */
void eeprom_app_ready(void) void eeprom_app_ready(void)
{ {
static wchar_t serial_from_eeprom[SERIAL_NUM_LEN+1]; static wchar_t serial_from_eeprom[SERIAL_NUM_LEN+1];
@ -253,11 +254,17 @@ void pollDelay(void)
} }
} }
#define STATE_WAIT_POLLTIME 0
#define STATE_POLL_PAD 1
#define STATE_WAIT_INTERRUPT_READY 2
#define STATE_TRANSMIT 3
int main(void) int main(void)
{ {
Gamepad *pad = NULL; Gamepad *pad = NULL;
gamepad_data pad_data; gamepad_data pad_data;
unsigned char gamepad_vibrate = 0; unsigned char gamepad_vibrate = 0;
unsigned char state = STATE_WAIT_POLLTIME;
hwinit(); hwinit();
usart1_init(); usart1_init();
@ -273,21 +280,49 @@ int main(void)
{ {
static char last_v = 0; static char last_v = 0;
/* Try to auto-detect controller if none*/
if (!pad) {
pad = detectPad();
}
usb_doTasks(); usb_doTasks();
// Todo : The _delay_ms used to poll the controller at
// a fixed interval is slowing down the frequency of
// hiddata_doTask calls. Rework this code to use a timer
// for polling the controller...
hiddata_doTask(); hiddata_doTask();
if (!g_polling_suspended) { switch(state)
pollDelay(); {
case STATE_WAIT_POLLTIME:
if (!g_polling_suspended) {
pollDelay();
state = STATE_POLL_PAD;
}
break;
case STATE_POLL_PAD:
/* Try to auto-detect controller if none*/
if (!pad) {
pad = detectPad();
}
if (pad) {
pad->update();
if (pad->changed()) {
pad->getReport(&pad_data);
usbpad_update(&pad_data);
state = STATE_WAIT_INTERRUPT_READY;
}
} else {
/* Just make sure the gamepad state holds valid data
* to appear inactive (no buttons and axes in neutral) */
usbpad_update(NULL);
}
break;
case STATE_WAIT_INTERRUPT_READY:
if (usb_interruptReady()) {
state = STATE_TRANSMIT;
}
break;
case STATE_TRANSMIT:
usb_interruptSend(usbpad_getReportBuffer(), usbpad_getReportSize());
state = STATE_WAIT_POLLTIME;
break;
} }
gamepad_vibrate = usbpad_mustVibrate(); gamepad_vibrate = usbpad_mustVibrate();
@ -297,22 +332,6 @@ int main(void)
} }
last_v = gamepad_vibrate; last_v = gamepad_vibrate;
} }
if (pad && !g_polling_suspended) {
pad->update();
if (pad->changed()) {
pad->getReport(&pad_data);
usbpad_update(&pad_data);
usb_interruptSend(usbpad_getReportBuffer(), usbpad_getReportSize());
}
} else {
/* Just make sure the gamepad state holds valid data
* to appear inactive (no buttons and axes in neutral) */
usbpad_update(NULL);
}
} }
return 0; return 0;