diff --git a/C64_1351_Mouse/c64_usb_mouse.ino b/C64_1351_Mouse/c64_usb_mouse.ino index a8d070b..e46e51a 100644 --- a/C64_1351_Mouse/c64_usb_mouse.ino +++ b/C64_1351_Mouse/c64_usb_mouse.ino @@ -1,27 +1,16 @@ +#define USBHOST + +#ifdef USBHOST #include #include +#endif -/*#define SENSEPORT PORTD ///< SID sense port -#define SENSEDDR DDRD ///< SID sense data direction -#define SENSEPIN PIND ///< SID sense input*/ -#define POTSENSE 3 ///< INT1 attached to PORTD.3, +#define POTSENSE 4 //ICP1 (Arduino Pro Micro: pin4, Arduino Uno: pin8) -/*#define POTPORT PORTB ///< POT-controlling outputs X and Y -#define POTDDR DDRB ///< POT outputs data direction -#define POTPIN PINB ///< POT outputs input ;)*/ #define POTX 9 ///< X-line, also OC1A #define POTY 10 ///< Y-line, also OC1B -#define LBTN 4 ///< Joystick FIRE switch -#define RBTN 5 ///< Joystick UP switch - -/*#define JOYPORT PORTC ///< Joystick pins -#define JOYDDR DDRC ///< Joystick pins data direction (out = switch closed to gnd) -#define JOYPIN PINC ///< Joystick in*/ -/*#define JOYUP 5 ///< Joystick UP switch -#define JOYDOWN 6 ///< Joystick DOWN switch -#define JOYLEFT 7 ///< Joystick LEFT switch -#define JOYRIGHT 8 ///< Joystick RIGHT switch -#define JOYFIRE 9 ///< Joystick FIRE switch*/ +#define LBTN 5 ///< Joystick FIRE switch +#define RBTN 6 ///< Joystick UP switch //#define DEBUG @@ -30,18 +19,17 @@ int16_t dy=0; uint8_t buttons=0; uint8_t update = 0; -#define FIX_START 90 -int16_t fix = FIX_START; +#ifdef USBHOST class MouseRptParser : public MouseReportParser { protected: - void OnMouseMove(MOUSEINFO *mi); - void OnLeftButtonUp(MOUSEINFO *mi); - void OnLeftButtonDown(MOUSEINFO *mi); - void OnRightButtonUp(MOUSEINFO *mi); - void OnRightButtonDown(MOUSEINFO *mi); - void OnMiddleButtonUp(MOUSEINFO *mi); - void OnMiddleButtonDown(MOUSEINFO *mi); + void OnMouseMove(MOUSEINFO *mi); + void OnLeftButtonUp(MOUSEINFO *mi); + void OnLeftButtonDown(MOUSEINFO *mi); + void OnRightButtonUp(MOUSEINFO *mi); + void OnRightButtonDown(MOUSEINFO *mi); + void OnMiddleButtonUp(MOUSEINFO *mi); + void OnMiddleButtonDown(MOUSEINFO *mi); }; void MouseRptParser::OnMouseMove(MOUSEINFO *mi) { #ifdef DEBUG @@ -67,7 +55,6 @@ void MouseRptParser::OnLeftButtonDown(MOUSEINFO *mi) { #endif buttons |= 1; update = 1; - fix++; }; void MouseRptParser::OnRightButtonUp(MOUSEINFO *mi) { #ifdef DEBUG @@ -82,7 +69,6 @@ void MouseRptParser::OnRightButtonDown(MOUSEINFO *mi) { #endif buttons |= 2; update = 1; - fix--; }; void MouseRptParser::OnMiddleButtonUp(MOUSEINFO *mi) { #ifdef DEBUG @@ -93,7 +79,6 @@ void MouseRptParser::OnMiddleButtonDown(MOUSEINFO *mi) { #ifdef DEBUG Serial.println("M Butt Dn"); #endif - fix = FIX_START; }; USB Usb; @@ -101,13 +86,7 @@ USBHub Hub(&Usb); HIDBoot HidMouse(&Usb); MouseRptParser Prs; - - -enum _potmode { - POTMOUSE_C1351 = 0, //>6) & 077; // modulo 64 - //potmouse_ycounter = (millis()>>6) & 077; - /*(button & 001) ? (JOYDDR |= _BV(JOYFIRE)) : (JOYDDR &= ~_BV(JOYFIRE)); - (button & 002) ? (JOYDDR |= _BV(JOYUP)) : (JOYDDR &= ~_BV(JOYUP)); - (button & 004) ? (JOYDDR |= _BV(JOYDOWN)) : (JOYDDR &= ~_BV(JOYDOWN));*/ - - (button & 001) ? pinMode(LBTN, OUTPUT) : pinMode(LBTN, INPUT); - (button & 002) ? pinMode(RBTN, OUTPUT) : pinMode(RBTN, INPUT); - - - // scale should be 2x here, but for this particular chip, 66 counts work better where - // 64 counds should be. so 66/64=100/96 and times two - //a = (OCR_ZERO + potmouse_xcounter*200/96)*2; // "*2" because 16MHz, not 8MHz //yli - //b = (OCR_ZERO + potmouse_ycounter*200/96)*2; // "*2" because 16MHz, not 8MHz - //a = OCR_ZERO + potmouse_xcounter*2; // "*2" because 16MHz, not 8MHz - //b = OCR_ZERO + potmouse_ycounter*2; // "*2" because 16MHz, not 8MHz - //a = (OCR_ZERO + potmouse_xcounter*200/90)*2; // "*2" because 16MHz, not 8MHz - //b = (OCR_ZERO + potmouse_ycounter*200/90)*2; // "*2" because 16MHz, not 8MHz - //a = OCR_ZERO*2 + potmouse_xcounter*400/85; // "*2" because 16MHz, not 8MHz - //b = OCR_ZERO*2 + potmouse_ycounter*400/85; // "*2" because 16MHz, not 8MHz - //a = OCR_ZERO*2 + potmouse_xcounter*400/80; // "*2" because 16MHz, not 8MHz //ali - //b = OCR_ZERO*2 + potmouse_ycounter*400/80; // "*2" because 16MHz, not 8MHz - //a = OCR_ZERO*2 + potmouse_xcounter*400/93; // "*2" because 16MHz, not 8MHz //vois olla lähellä - //b = OCR_ZERO*2 + potmouse_ycounter*400/93; // "*2" because 16MHz, not 8MHz - //a = OCR_ZERO*2 + potmouse_xcounter*400/91; // "*2" because 16MHz, not 8MHz //vois olla lähellä - //b = OCR_ZERO*2 + potmouse_ycounter*400/91; // "*2" because 16MHz, not 8MHz - //a = OCR_ZERO*2-1 + potmouse_xcounter*400/94; // "*2" because 16MHz, not 8MHz - //b = OCR_ZERO*2-1 + potmouse_ycounter*400/94; // "*2" because 16MHz, not 8MHz - //a = OCR_ZERO*2-2 + potmouse_xcounter*400/92; // "*2" because 16MHz, not 8MHz - //b = OCR_ZERO*2-2 + potmouse_ycounter*400/92; // "*2" because 16MHz, not 8MHz - //a = OCR_ZERO*2+2 + potmouse_xcounter*400/92; // "*2" because 16MHz, not 8MHz //valuu vasemmalle alas - //b = OCR_ZERO*2+2 + potmouse_ycounter*400/92; // "*2" because 16MHz, not 8MHz - - //a = OCR_ZERO*2 + potmouse_xcounter*400/fix; // "*2" because 16MHz, not 8MHz - //b = OCR_ZERO*2 + potmouse_ycounter*400/fix; // "*2" because 16MHz, not 8MHz - - //a = OCR_ZERO*2-20 + potmouse_xcounter*400/fix; // "*2" because 16MHz, not 8MHz - //b = OCR_ZERO*2-20 + potmouse_ycounter*400/fix; // "*2" because 16MHz, not 8MHz - - a = OCR_ZERO*2 + potmouse_xcounter*400/92; // "*2" because 16MHz, not 8MHz - b = OCR_ZERO*2 + potmouse_ycounter*400/92; // "*2" because 16MHz, not 8MHz - - ocr1a_load = a; - ocr1b_load = b; - break; - case POTMOUSE_JOYSTICK: - /*JOYDDR &= ~(_BV(JOYFIRE) | _BV(JOYUP) | _BV(JOYDOWN) | _BV(JOYLEFT) | _BV(JOYRIGHT)); - - (dx < 0) ? (JOYDDR |= _BV(JOYLEFT)) : (JOYDDR &= ~_BV(JOYLEFT)); - (dx > 0) ? (JOYDDR |= _BV(JOYRIGHT)): (JOYDDR &= ~_BV(JOYRIGHT)); - (dy < 0) ? (JOYDDR |= _BV(JOYDOWN)) : (JOYDDR &= ~_BV(JOYDOWN)); - (dy > 0) ? (JOYDDR |= _BV(JOYUP)) : (JOYDDR &= ~_BV(JOYUP)); - (button & 001) ? (JOYDDR |= _BV(JOYFIRE)) : (JOYDDR &= ~_BV(JOYFIRE)); - (button & 002) ? (POTDDR |= _BV(POTX)) : (POTDDR &= ~_BV(POTX)); - - TCNT1 = 65535-256; - TCCR1A = 0; - TCCR1B = _BV(CS12)|_BV(CS10); - TIFR |= _BV(TOV1); - TIMSK |= _BV(TOIE1);*/ - break; + #ifndef USBHOST + if (upd) { + potmouse_xcounter++; + potmouse_ycounter++; + upd = 0; } + #endif + + potmouse_xcounter = (potmouse_xcounter + (dx/2)) & 0177; // modulo 128 + potmouse_ycounter = (potmouse_ycounter - (dy/2)) & 0177; + + //for testing + //potmouse_xcounter = (millis()>>6) & 077; // modulo 64 + //potmouse_ycounter = (millis()>>6) & 077; + + (button & 001) ? pinMode(LBTN, OUTPUT) : pinMode(LBTN, INPUT); + (button & 002) ? pinMode(RBTN, OUTPUT) : pinMode(RBTN, INPUT); + + // scale should be 2x here, but for this particular chip, 66 counts work better where + // 64 counds should be. so 66/64=100/96 and times two + //a = 320*2 + ((uint32_t)potmouse_xcounter)*200/fix; + //b = 320*2 + ((uint32_t)potmouse_ycounter)*200/fix; + //a = 320*200/fix + potmouse_xcounter*2; + //b = 320*200/fix + potmouse_ycounter*2; + a = 320*2 + potmouse_xcounter*2; + b = 320*2 + potmouse_ycounter*2; + + ocr1a_load = a; + ocr1b_load = b; } -/// SID measuring cycle detected. -/// -/// 1. SID pulls POTX low\n -/// 2. SID waits 256 cycles us\n -/// 3. SID releases POTX\n -/// 4. 0 to 255 cycles until the cap is charged\n -/// -/// This handler stops the Timer1, clears OC1A/OC1B outputs, -/// loads the timer with values precalculated in potmouse_movt() -/// and starts the timer. -/// -/// OC1A/OC1B (YPOT/XPOT) lines will go up by hardware. -/// Normal SID cycle is 512us. Timer will overflow not before 65535us. -/// Next cycle will begin before that so there's no need to stop the timer. -/// Output compare match interrupts are thus not used. - -void potSenseInt() { +inline void startTimers() { #ifdef DEBUG - Serial.println("PotSenseInt"); Serial.flush(); + Serial.println("startTimers"); Serial.flush(); #endif - // SID started to measure the pots, uuu + cli(); + + // Prepare TIMER1 + //TCCR1A = 0; + + // ICIE1: Timer/Counter Input Capture Interrupt Enable, ISR(TIMER1_CAPT_vect) + // TOIE1: Timer/Counter Overflow Interrupt Enable + TIMSK1 = _BV(ICIE1); // ICIE1: Timer/Counter1, Input Capture Interrupt Enable + + // Start timer1, Input Capture setup + // ICNC1: Input Capture Noise Canceller (Bit 7 of register TCCR1B) + // ICES1: Input Capture Edge Select (Bit 6 of register TCCR1B) 0 = FALLING, 1 = RISING + // CS12, CS11, CS10: Set prescaler (CS11 TIMER1: F_CPU/8) + TCCR1B = _BV(ICNC1) | _BV(CS11); + //TCCR1B = _BV(CS11); + + TIFR1 = 0xff; // Clear all pending TIMER1 interrupt flags + + sei(); +} + + + +ISR(TIMER1_CAPT_vect) { + // Now we little after start of SID reading process + // SID trigger pulse timer value is in ICR1 + + uint16_t a = ICR1; - // disable INT1 until the measurement cycle is complete - // stop the timer - TCCR1B = 0; - - // clear OC1A/OC1B: + #ifdef DEBUG + Serial.println("TIMER1_CAPT_vect:"); + #endif + + #ifndef USBHOST + counter++; + counter &= 63; + if (counter == 0) upd = 1; + #endif + + // clear OC1A/OC1B (9 and 10 to LOW): // 1. set output compare to clear OC1A/OC1B ("10" in table 37 on page 97) - TCCR1A = _BV(COM1A1) | _BV(COM1B1); - // 2. force output compare to make it happen - TCCR1C |= _BV(FOC1A) | _BV(FOC1B); + TCCR1A = _BV(COM1A1) | _BV(COM1B1); // Clear OC1A / OC1B on Compare Match (Set output to low level). + // 2. force output compare to make it happen (doesn't raise interrupts) + TCCR1C |= _BV(FOC1A) | _BV(FOC1B); // FOC1A / FOC1B Force Output Compare A and B (that are in register TCCR1C) + + // OCIE1A: Timer/Counter Output Compare Match Interrupt Enable A, ISR(TIMER1_COMPA_vect) // disable ICIE1, Input Capture Interrupt + TIMSK1 = _BV(OCIE1A); + + // init the output compare values + OCR1A = ocr1a_load + a; + OCR1B = ocr1b_load + a; // Set OC1A/OC1B on Compare Match (Set output to high level) // WGM13:0 = 00, normal mode: count from BOTTOM to MAX - TCCR1A = _BV(COM1A1) | _BV(COM1A0) | _BV(COM1B1) | _BV(COM1B0); + TCCR1A = _BV(COM1A1) | _BV(COM1A0) | _BV(COM1B1) | _BV(COM1B0); // Set OC1A / OC1B on Compare Match (Set output to high level). - // load the timer - TCNT1 = 0; - - // init the output compare values - OCR1A = ocr1a_load; - OCR1B = ocr1b_load; - - // start timer with prescaler clk/8 (1 count = 1us) // (with 16MHz, 1 count = 0.5us) - TCCR1B = _BV(CS11); - - // TEST!!! - //TCCR1B = _BV(CS12) | _BV(CS10); // Prescaler clock/1024 - - //TEST!!!: - /*OCR1A = 15625*2; // 16 000 000 / 1024 / 15625 = 1s - OCR1B = 15625/2; - TCCR1B = _BV(CS12) | _BV(CS10); // Prescaler clock/1024*/ + #ifdef DEBUG + Serial.print(c); Serial.print(" "); Serial.print(a); Serial.print(" "); Serial.println(b); + Serial.flush(); + #endif + TIFR1 = 0xff; //clear all timer1 interrupt flags } -/* -/// TIMER1 Overflow vector -/// -/// Ends joystick emulator pulse. -ISR(TIMER1_OVF_vect) { - //JOYDDR &= ~(_BV(JOYFIRE) | _BV(JOYUP) | _BV(JOYDOWN) | _BV(JOYLEFT) | _BV(JOYRIGHT)); - //POTDDR &= ~_BV(POTX); - TIMSK1 &= ~_BV(TOIE1); -}*/ +ISR(TIMER1_COMPA_vect) { + // now potx are sent. we don't know if poty is still in progress. + // POTX is HIGH from OC1A TIMER1 compare match. POTY is ?. + + #ifdef DEBUG + Serial.println("TIMER1_COMPA_vect"); Serial.flush(); + #endif + TIMSK1 = _BV(ICIE1); // ICIE1: Timer/Counter1, Input Capture Interrupt Enable // disable TIMER1 interrupts (Compare Match Interrupt A) + TIFR1 = 0xff; //clear all timer1 interrupt flags +}