From: Drew Fisher Date: Wed, 24 Feb 2010 18:38:40 +0000 (-0500) Subject: Correct interrupt usage. X-Git-Url: http://git.zarvox.org/static/%7Bwebsite%7D?a=commitdiff_plain;h=231bf1a70259b9cf357979fc81f8fc90062687c5;p=usbsnes.git Correct interrupt usage. This patch corrects usage of usbDeviceDisconnect() and usbDeviceConnect(). In addition, we allow SNES interrupts to be further interrupted, so the USB interrupts always get serviced. To prevent stack overflow, we enforce completion of one SNES poll before the next one can be triggered. Rather than crash the chip, we take a (tiny) hit in latency. --- diff --git a/main.c b/main.c index bf3f5e4..e34a7cf 100644 --- a/main.c +++ b/main.c @@ -38,6 +38,7 @@ typedef struct { static report_t buttonState; static report_t reportBuffer; +static uint8_t pollInProgress = 0; usbMsgLen_t usbFunctionSetup(uchar data[8]) { usbRequest_t *rq = (void *)data; @@ -59,7 +60,12 @@ usbMsgLen_t usbFunctionSetup(uchar data[8]) { } ISR(TIMER1_COMPA_vect) { + if(pollInProgress) // Mutex, to prevent infinite recursion if terribly many USB interrupts (shouldn't happen, but safety net) + return; // We've already started polling the SNES controller, return up the stack so that the original ISR can finish + pollInProgress = 1; // Acquire lock + sei(); // Allow for nested interrupts - namely, USB interrupts. buttonState.buttons = pollSnes(); + pollInProgress = 0; // Release lock } static void initPins() { @@ -101,6 +107,8 @@ int main(void) /* Even if you don't use the watchdog, turn it off here. On newer devices, * the status of the watchdog (on/off, period) is PRESERVED OVER RESET! */ + + cli(); // Disable interrupts //DBG1(0x00, 0, 0); /* debug output: main starts */ @@ -131,7 +139,7 @@ int main(void) _delay_ms(1); } usbDeviceConnect(); - sei(); // Enable interrupts + sei(); // Enable interrupts (after device reconnect) //DBG1(0x01, 0, 0); /* debug output: main loop starts */ uchar counter = 0;