From 231bf1a70259b9cf357979fc81f8fc90062687c5 Mon Sep 17 00:00:00 2001 From: Drew Fisher Date: Wed, 24 Feb 2010 13:38:40 -0500 Subject: [PATCH] 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. --- main.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) 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; -- 2.39.2