From: Drew Fisher Date: Mon, 22 Feb 2010 19:44:40 +0000 (-0500) Subject: Convert SNES polling to a timer interrupt-based routine, update comments. X-Git-Url: https://git.zarvox.org/shortlog/month?a=commitdiff_plain;h=8d593537dd5c74d9c41dd963f594b3874fb1420f;p=usbsnes.git Convert SNES polling to a timer interrupt-based routine, update comments. --- diff --git a/main.c b/main.c index 6a8ff6b..236766c 100644 --- a/main.c +++ b/main.c @@ -27,11 +27,16 @@ PROGMEM char usbHidReportDescriptor[28] = { 0xc0, // END_COLLECTION 0xc0 // END_COLLECTION }; - +/* typedef struct { uchar buttons[2]; } report_t; +*/ +typedef struct { + uint16_t buttons; +} report_t; +static report_t buttonState; static report_t reportBuffer; usbMsgLen_t usbFunctionSetup(uchar data[8]) { @@ -53,10 +58,31 @@ usbMsgLen_t usbFunctionSetup(uchar data[8]) { return 0; /* default for not implemented requests: return no data back to host */ } +ISR(TIMER1_COMPA) { + buttonState.buttons = pollSnes(); +} + +void initTimer() { + // See section 15.11 for reference + // Using CTC mode (non-PWM) + + // TCCR1A = 0b00000000 (No timer output, no PWM) + // TCCR1B = 0b00001010 (CTC mode, ckli_o/8) + // TCCR1C = 0b00000000 (No output compare) + TCCR1A = 0b00000000; + TCCR1B = 0b00001010; + TCCR1C = 0b00000000; + // {OCR1AH, OCR1AL} = 37500 = 10010010 01111100 + // 37500 * 8 * 60 = 18MHz + OCR1AH = 0b10010010; + OCR1AL = 0b01111000; + // TIMSK1 = 0b00000010 (Enable interrupt on Output Compare A Match) + TIMSK1 = 0b00000010; +} + int main(void) { uchar i; - wdt_enable(WDTO_1S); // Enable watchdog with 1s reset time /* 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! @@ -66,9 +92,18 @@ int main(void) /* RESET status: all port bits are inputs without pull-up. * That's the way we need D+ and D-. Therefore we don't need any - * additional hardware initialization. + * additional hardware initialization on the USB side. */ + // We need to setup the pin configuration for D3, which is an output pin + + + // Set up the clock prescaler to CLKI_O/8, which gives us 2250000 ticks per second + // This makes 37500 such ticks give us a 60Hz signal, which is exactly how we set up + // the timer interrupt to poll the SNES controller + + + //odDebugInit(); usbInit(); @@ -86,7 +121,7 @@ int main(void) wdt_reset(); usbPoll(); if(usbInterruptIsReady()){ - pollSnes(); + reportBuffer.buttons = buttonState.buttons; /* called after every poll of the interrupt endpoint */ //advanceCircleByFixedAngle(); //DBG1(0x03, 0, 0); /* debug output: interrupt report prepared */ diff --git a/snes.S b/snes.S index 02e385b..bac54a0 100644 --- a/snes.S +++ b/snes.S @@ -153,8 +153,8 @@ readbitsecond8: invertvalues: ldi temp2, 0xff ; for xor - eor resL, temp2 ; Invert for negative logic - eor resH, temp2 ; Remember, low indicates button pressed. + eor resL, temp2 ; Invert for negative logic - to the SNES controller, + eor resH, temp2 ; low indicates button pressed. To USB HID, the opposite. ret ; return to caller unconnected: ; Controller was disconnected