]> git.zarvox.org Git - usbsnes.git/commitdiff
Correct interrupt usage.
authorDrew Fisher <drew.m.fisher@gmail.com>
Wed, 24 Feb 2010 18:38:40 +0000 (13:38 -0500)
committerDrew Fisher <drew.m.fisher@gmail.com>
Wed, 24 Feb 2010 18:57:49 +0000 (13:57 -0500)
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

diff --git a/main.c b/main.c
index bf3f5e414531c415c694e4ed2e747c9fa57a1ce0..e34a7cfd49065207d1806b2088330a3552cd7cdd 100644 (file)
--- 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;