]> git.zarvox.org Git - usbsnes.git/commitdiff
Functional code for SNES port 2. master
authorDrew Fisher <drew.m.fisher@gmail.com>
Mon, 21 Jun 2010 00:49:36 +0000 (17:49 -0700)
committerDrew Fisher <drew.m.fisher@gmail.com>
Mon, 21 Jun 2010 00:49:36 +0000 (17:49 -0700)
The assembly routine doesn't work.  No idea why; I'll rework it later.
In the meantime, it's a bad idea to poll the SNES in an interrupt
routine, so the interrupt now sets readyToPollSnes every 1/60th of a
second instead, and the actual polling code has been placed in
getButtons().

This will likely all need a rework when I move to support polling two
controllers simultaneously.

main.c

diff --git a/main.c b/main.c
index b08d0945562082d40c926958801ed6f90c17184d..44b3cd3292e597c74a398fce9ddefca10995b2d5 100644 (file)
--- a/main.c
+++ b/main.c
@@ -41,7 +41,7 @@ typedef struct {
        //uchar id;
        char x;
        char y;
-       uchar buttons;
+       uchar buttons; // Note: bitstream goes [8...1]
 } report_t;
 
 static report_t buttonState;
@@ -49,6 +49,7 @@ static report_t reportBuffer;
 static uint8_t pollInProgress = 0;
 static unsigned char idleRate;
 static uint8_t interrupt_count = 0;
+static uint8_t readyToPollSnes = 0;
 
 usbMsgLen_t usbFunctionSetup(uchar data[8]) {
 
@@ -69,7 +70,7 @@ usbMsgLen_t usbFunctionSetup(uchar data[8]) {
                } else if (rq->bRequest == USBRQ_HID_SET_IDLE){
                        idleRate = rq->wValue.bytes[1];
                }
-       }else{
+       } else {
                /* no vendor specific requests implemented */
        }
        return 0;   /* default for not implemented requests: return no data back to host */
@@ -77,18 +78,42 @@ 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
-*/
-       if (interrupt_count++ == 60) {
-               reportBuffer.buttons++;
-               interrupt_count = 0;
+       readyToPollSnes = 1; // Set flag for mainloop to poll SNES (better not to do this in an ISR)
+}
+
+static void getButtons() { // Poll the SNES for the button states, arrange bytes appropriately for the descriptor
+       uint16_t temp= 0x0000;
+       uint8_t counter = 16;
+
+       PORTC |= _BV(PINC1);
+       _delay_us(12);
+
+       PORTC &= ~_BV(PINC1);
+
+       for(counter = 0; counter != 16; counter++) {
+               _delay_us(6);
+               temp = temp << 1 ;
+               temp |= (PINC & _BV(PINC2)) ? 0 : 1;
+               PORTC &= ~_BV(PINC0);
+               _delay_us(6);
+               PORTC |= _BV(PINC0);
        }
+
+       if (temp & 0x0800)
+               buttonState.y = -127;
+               //buttonState.x = 127;
+       else if (temp & 0x0400)
+               buttonState.y = 127;
+               //buttonState.x = -127;
+       else buttonState.y = 0;
+
+       if (temp & 0x0200)
+               buttonState.x = -127;
+       else if (temp & 0x0100)
+               buttonState.x = 127;
+       else buttonState.x = 0;
+       buttonState.buttons = ((temp & 0xf000) >> 8) | ((temp & 0x00f0) >> 4) ;
+       readyToPollSnes = 0;
 }
 
 static void initPins() {
@@ -174,10 +199,15 @@ int main(void)
                //DBG1(0x02, 0, 0);   /* debug output: main loop iterates */
                wdt_reset();
                usbPoll();
+               if(readyToPollSnes) {
+                       getButtons();
+               }
                if(usbInterruptIsReady()){
                        /* called after every poll of the interrupt endpoint */
                        // Actual code to be executed - updates the HID report with the status of the SNES controller
-                       //reportBuffer.buttons = buttonState.buttons;
+                       reportBuffer.x = buttonState.x;
+                       reportBuffer.y = buttonState.y;
+                       reportBuffer.buttons = buttonState.buttons;
 
                        // Testing USB reports - change button state every second, incrementing the report buffer by 1.
                        //if(counter++ == 10) {